class ModelAction;
class ModelChecker;
class ModelExecution;
+class ModelHistory;
class Node;
class NodeStack;
class Scheduler;
#include <stdio.h>
+#include <string>
+
#include "model.h"
+#include "execution.h"
#include "action.h"
+#include "history.h"
#include "cmodelint.h"
#include "threads-model.h"
*/
void cds_func_entry(const char * funcName) {
+ if (!model) return;
+
Thread * th = thread_current();
- printf("thread %d Enter function %s\n", th->get_id(), funcName);
+ uint32_t func_id;
+
+ ModelHistory *history = model->get_history();
+ if ( !history->getFuncMap()->contains(funcName) ) {
+ func_id = history->get_func_counter();
+ history->incr_func_counter();
+
+ history->getFuncMap()->put(funcName, func_id);
+ } else {
+ func_id = history->getFuncMap()->get(funcName);
+ }
+
+ history->enter_function(func_id, th->get_id());
}
void cds_func_exit(const char * funcName) {
+ if (!model) return;
+
Thread * th = thread_current();
- printf("thread %d Exit from function %s\n", th->get_id(), funcName);
+ uint32_t func_id;
+
+ ModelHistory *history = model->get_history();
+ func_id = history->getFuncMap()->get(funcName);
+
+ history->exit_function(func_id, th->get_id());
}
--- /dev/null
+#include <inttypes.h>
+#include "history.h"
+#include "action.h"
+
+ModelHistory::ModelHistory() :
+ func_id(1), /* function id starts with 1 */
+ func_map(),
+ func_history(),
+ work_list()
+{}
+
+void ModelHistory::enter_function(const uint32_t func_id, thread_id_t tid)
+{
+ if ( !work_list.contains(tid) ) {
+ // This thread has not been pushed to work_list
+ SnapList<uint32_t> * func_list = new SnapList<uint32_t>();
+ func_list->push_back(func_id);
+ work_list.put(tid, func_list);
+ } else {
+ SnapList<uint32_t> * func_list = work_list.get(tid);
+ func_list->push_back(func_id);
+ }
+}
+
+void ModelHistory::exit_function(const uint32_t func_id, thread_id_t tid)
+{
+ SnapList<uint32_t> * func_list = work_list.get(tid);
+ uint32_t last_func_id = func_list->back();
+
+ if (last_func_id == func_id) {
+ func_list->pop_back();
+ } else {
+ model_print("trying to exit with a wrong function id\n");
+ model_print("--- last_func: %d, func_id: %d\n", last_func_id, func_id);
+ }
+}
--- /dev/null
+#include "stl-model.h"
+#include "common.h"
+#include "hashtable.h"
+#include "modeltypes.h"
+
+/* forward declaration */
+class ModelAction;
+
+typedef ModelList<ModelAction *> action_mlist_t;
+
+class ModelHistory {
+public:
+ ModelHistory();
+
+ void enter_function(const uint32_t func_id, thread_id_t tid);
+ void exit_function(const uint32_t func_id, thread_id_t tid);
+
+ uint32_t get_func_counter() { return func_id; }
+ void incr_func_counter() { func_id++; }
+
+ HashTable<const char *, uint32_t, uintptr_t, 4> * getFuncMap() { return &func_map; }
+ HashTable<uint32_t, action_mlist_t *, uintptr_t, 4> * getFuncHistory() { return &func_history; }
+
+ void print();
+
+private:
+ uint32_t func_id;
+
+ /* map function names to integer ids */
+ HashTable<const char *, uint32_t, uintptr_t, 4> func_map;
+
+ HashTable<uint32_t, action_mlist_t *, uintptr_t, 4> func_history;
+
+ /* work_list stores a list of function ids for each thread
+ * SnapList<uint32_t> is intended to be used as a stack storing
+ * the functions that thread i has entered and yet to exit from
+ */
+ HashTable<thread_id_t, SnapList<uint32_t> *, uintptr_t, 4> work_list;
+};
#include "output.h"
#include "traceanalysis.h"
#include "execution.h"
+#include "history.h"
#include "bugmessage.h"
ModelChecker *model;
scheduler(new Scheduler()),
node_stack(new NodeStack()),
execution(new ModelExecution(this, scheduler, node_stack)),
+ history(new ModelHistory()),
execution_number(1),
trace_analyses(),
inspect_plugin(NULL)
ucontext_t * get_system_context() { return &system_context; }
ModelExecution * get_execution() const { return execution; }
+ ModelHistory * get_history() const { return history; }
int get_execution_number() const { return execution_number; }
model_params params;
void add_trace_analysis(TraceAnalysis *a) { trace_analyses.push_back(a); }
void set_inspect_plugin(TraceAnalysis *a) { inspect_plugin=a; }
+
MEMALLOC
private:
/** Flag indicates whether to restart the model checker. */
Scheduler * const scheduler;
NodeStack * const node_stack;
ModelExecution *execution;
+ ModelHistory *history;
int execution_number;