ModelHistory *history = model->get_history();
if ( !history->getFuncMap()->contains(funcName) ) {
+ /* add func id to func map */
func_id = history->get_func_counter();
history->incr_func_counter();
-
history->getFuncMap()->put(funcName, func_id);
+
+ /* add func id to reverse func map */
+ ModelVector<const char *> * func_map_rev = history->getFuncMapRev();
+ if ( func_map_rev->size() <= func_id )
+ func_map_rev->resize( func_id + 1 );
+ func_map_rev->at(func_id) = funcName;
} else {
func_id = history->getFuncMap()->get(funcName);
}
#include "funcnode.h"
-FuncInst::FuncInst(ModelAction *act)
+FuncInst::FuncInst(ModelAction *act) :
+ collisions()
{
ASSERT(act);
this->position = act->get_position();
}
FuncNode::FuncNode() :
- func_insts()
+ func_insts(),
+ inst_list(),
+ entry_insts()
{}
void FuncNode::add_action(ModelAction *act)
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);
+ if (inst->get_type() != act->get_type() ) {
+ model_print("action with a different type occurs at line number %s\n", position);
+ FuncInst * func_inst = inst->search_in_collision(act);
+
+ if (func_inst != NULL)
+ return;
+
+ func_inst = new FuncInst(act);
+ inst->get_collisions()->push_back(func_inst);
+ inst_list.push_back(func_inst); // delete?
+ model_print("collision added\n");
}
return;
FuncInst * func_inst = new FuncInst(act);
func_insts.put(position, func_inst);
+
inst_list.push_back(func_inst);
}
void * get_location() const { return location; }
action_type get_type() const { return type; }
+ func_inst_list_t * get_collisions() { return &collisions; }
+
+ FuncInst * search_in_collision(ModelAction *act) {
+ action_type type = act->get_type();
+
+ func_inst_list_t::iterator it;
+ for (it = collisions.begin(); it != collisions.end(); it++) {
+ FuncInst * inst = *it;
+ if ( inst->get_type() == type )
+ return inst;
+ }
+ return NULL;
+ }
+
MEMALLOC
private:
//ModelAction * const action;
const char * position;
void *location;
action_type type;
+
+ func_inst_list_t collisions;
};
class FuncNode {
HashTable<const char *, FuncInst *, uintptr_t, 4, model_malloc, model_calloc, model_free> * getFuncInsts() { return &func_insts; }
func_inst_list_t * get_inst_list() { return &inst_list; }
+ uint32_t get_func_id() { return func_id; }
+ const char * get_func_name() { return func_name; }
+ void set_func_id(uint32_t id) { func_id = id; }
+ void set_func_name(const char * name) { func_name = name; }
+
MEMALLOC
private:
- /* Use source line number as the key of hashtable
+ uint32_t func_id;
+ const char * func_name;
+
+ /* Use source line number as the key of hashtable, to check if
+ * atomic operation with this line number has been added or not
*
* 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, model_malloc, model_calloc, model_free> func_insts;
+ /* list of all atomic instructions in this function */
func_inst_list_t inst_list;
+
+ /* possible entry (atomic) instructions in this function */
+ func_inst_list_t entry_insts;
};
ModelHistory::ModelHistory() :
func_counter(0), /* function id starts with 0 */
func_map(),
+ func_map_rev(),
func_atomics()
{}
void ModelHistory::enter_function(const uint32_t func_id, thread_id_t tid)
{
+ //model_print("thread %d entering func %d\n", tid, func_id);
uint32_t id = id_to_int(tid);
SnapVector<func_id_list_t *> * thrd_func_list = model->get_execution()->get_thrd_func_list();
thrd_func_list->resize( id + 1 );
func_id_list_t * func_list = thrd_func_list->at(id);
+
if (func_list == NULL) {
func_list = new func_id_list_t();
thrd_func_list->at(id) = func_list;
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("thread %d exiting func %d\n", tid, func_id);
}
void ModelHistory::add_func_atomic(ModelAction *act, thread_id_t tid)
FuncNode * func_node = func_atomics[func_id];
if (func_node == NULL) {
+ const char * func_name = func_map_rev[func_id];
func_node = new FuncNode();
+ func_node->set_func_id(func_id);
+ func_node->set_func_name(func_name);
+
func_atomics[func_id] = func_node;
}
if (funcNode == NULL)
continue;
- model_print("function with id: %d has following actions\n", i);
+ model_print("function %s has following actions\n", funcNode->get_func_name());
func_inst_list_t::iterator it;
for (it = inst_list->begin(); it != inst_list->end(); it++) {
FuncInst *inst = *it;
void add_func_atomic(ModelAction *act, thread_id_t tid);
HashTable<const char *, uint32_t, uintptr_t, 4, model_malloc, model_calloc, model_free> * getFuncMap() { return &func_map; }
+ ModelVector<const char *> * getFuncMapRev() { return &func_map_rev; }
+
ModelVector<FuncNode *> * getFuncAtomics() { return &func_atomics; }
void print();
/* map function names to integer ids */
HashTable<const char *, uint32_t, uintptr_t, 4, model_malloc, model_calloc, model_free> func_map;
+ /* map integer ids to function names */
+ ModelVector<const char *> func_map_rev;
ModelVector<FuncNode *> func_atomics;
};