class Thread;
class TraceAnalysis;
class Fuzzer;
+class FuncNode;
+class FuncInst;
struct model_snapshot_members;
struct bug_message;
#include "funcnode.h"
-FuncInst::FuncInst(ModelAction *act) :
- action(act)
+FuncInst::FuncInst(ModelAction *act)
{
ASSERT(act);
this->position = act->get_position();
+ this->location = act->get_location();
+ this->type = act->get_type();
}
FuncNode::FuncNode() :
func_insts()
{}
+void FuncNode::add_action(ModelAction *act)
+{
+ ASSERT(act);
+
+ const char * position = act->get_position();
+
+ /* Actions THREAD_CREATE, THREAD_START, THREAD_YIELD, THREAD_JOIN,
+ * THREAD_FINISH, PTHREAD_CREATE, PTHREAD_JOIN,
+ * ATOMIC_LOCK, ATOMIC_TRYLOCK, and ATOMIC_UNLOCK are not tagged with their
+ * source line numbers
+ */
+ if (position == NULL) {
+ return;
+ }
+
+ if ( func_insts.contains(position) ) {
+ FuncInst * inst = func_insts.get(position);
+
+ if (inst->get_type() != act->get_type() &&
+ inst->get_type() != ATOMIC_RMWRCAS ) {
+ model_print("action with a different type occurs at line number %s \n", position);
+ }
+
+ return;
+ }
+
+ FuncInst * func_inst = new FuncInst(act);
+ func_insts.put(position, func_inst);
+ inst_list.push_back(func_inst);
+}
class ModelAction;
-typedef ModelList<const ModelAction *> action_mlist_t;
-typedef SnapList<uint32_t> func_id_list_t;
+typedef ModelList<FuncInst *> func_inst_list_t;
class FuncInst {
-public:
+public:
FuncInst(ModelAction *act);
~FuncInst();
- ModelAction * get_action() const { return action; }
+ //ModelAction * get_action() const { return action; }
const char * get_position() const { return position; }
+ void * get_location() const { return location; }
+ action_type get_type() const { return type; }
+
+ MEMALLOC
private:
- ModelAction * const action;
+ //ModelAction * const action;
const char * position;
+ void *location;
+ action_type type;
};
class FuncNode {
FuncNode();
~FuncNode();
+ void add_action(ModelAction *act);
+
HashTable<const char *, FuncInst *, uintptr_t, 4> * getFuncInsts() { return &func_insts; }
+ func_inst_list_t * get_inst_list() { return &inst_list; }
+
+ MEMALLOC
private:
+ /* Use source line number as the key of hashtable
+ *
+ * To do: cds_atomic_compare_exchange contains three atomic operations
+ * that are feeded with the same source line number by llvm pass
+ */
HashTable<const char *, FuncInst *, uintptr_t, 4> func_insts;
-};
+ func_inst_list_t inst_list;
+};
#include <inttypes.h>
#include "history.h"
#include "action.h"
-
+#include "funcnode.h"
/** @brief Constructor */
ModelHistory::ModelHistory() :
void ModelHistory::enter_function(const uint32_t func_id, thread_id_t tid)
{
-// model_print("entering function: %d\n", func_id);
-
uint32_t id = id_to_int(tid);
if ( work_list.size() <= id )
work_list.resize( id + 1 );
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);
}
-
-// model_print("exiting function: %d\n", func_id);
}
void ModelHistory::add_func_atomic(ModelAction *act, thread_id_t tid) {
if ( func_atomics.size() <= func_id )
func_atomics.resize( func_id + 1 );
- action_mlist_t * atomic_list = func_atomics[func_id];
- if (atomic_list == NULL) {
- atomic_list = new action_mlist_t();
- func_atomics[func_id] = atomic_list;
+ FuncNode * func_node = func_atomics[func_id];
+ if (func_node == NULL) {
+ func_node = new FuncNode();
+ func_atomics[func_id] = func_node;
}
- atomic_list->push_back(act);
-
- model_print("func id: %d, added atomic acts: %d\n", func_id, act->get_type());
+ func_node->add_action(act);
}
void ModelHistory::print() {
for (uint32_t i = 0; i < func_atomics.size(); i++ ) {
- action_mlist_t * atomic_list = func_atomics[i];
+ FuncNode * funcNode = func_atomics[i];
+ func_inst_list_t * inst_list = funcNode->get_inst_list();
- if (atomic_list == NULL)
+ if (funcNode == NULL)
continue;
model_print("function with id: %d has following actions\n", i);
- action_mlist_t::iterator it;
- for (it = atomic_list->begin(); it != atomic_list->end(); it++) {
- const ModelAction *act = *it;
- act->print();
+ func_inst_list_t::iterator it;
+ for (it = inst_list->begin(); it != inst_list->end(); it++) {
+ FuncInst *inst = *it;
+ model_print("type: %d, at: %s\n", inst->get_type(), inst->get_position());
}
}
}
#include "hashtable.h"
#include "threads-model.h"
-/* forward declaration */
-class ModelAction;
-
-typedef ModelList<const ModelAction *> action_mlist_t;
typedef SnapList<uint32_t> func_id_list_t;
class ModelHistory {
void add_func_atomic(ModelAction *act, thread_id_t tid);
HashTable<const char *, uint32_t, uintptr_t, 4> * getFuncMap() { return &func_map; }
- ModelVector< action_mlist_t * > * getFuncAtomics() { return &func_atomics; }
+ ModelVector<FuncNode *> * getFuncAtomics() { return &func_atomics; }
void print();
+
+ MEMALLOC
private:
uint32_t func_counter;
/* map function names to integer ids */
HashTable<const char *, uint32_t, uintptr_t, 4> func_map;
- ModelVector< action_mlist_t * > func_atomics;
+ ModelVector<FuncNode *> func_atomics;
/* Work_list stores a list of function ids for each thread.
* Each element in work_list is intended to be used as a stack storing
* the functions that thread i has entered and yet to exit from
*/
+
+ /* todo: move work_list to execution.cc to avoid seg fault */
SnapVector< func_id_list_t * > work_list;
};