#include "funcinst.h"
-FuncInst::FuncInst(ModelAction *act) :
+FuncInst::FuncInst(ModelAction *act, FuncNode *func_node) :
collisions()
{
ASSERT(act);
+ ASSERT(func_node);
this->position = act->get_position();
this->location = act->get_location();
this->type = act->get_type();
+ this->func_node = func_node;
}
+/* @param other Preceding FuncInst in the same execution trace
+ * Add other to predecessors if it has been added
+ *
+ * @return false: other is already in predecessors
+ * true : other is added to precedessors
+ */
bool FuncInst::add_pred(FuncInst * other) {
func_inst_list_mt::iterator it;
for (it = predecessors.begin(); it != predecessors.end(); it++) {
class FuncInst {
public:
- FuncInst(ModelAction *act);
+ FuncInst(ModelAction *act, FuncNode *func_node);
~FuncInst();
//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; }
+ FuncNode * get_func_node() const { return func_node; }
bool add_pred(FuncInst * other);
bool add_succ(FuncInst * other);
private:
//ModelAction * const action;
const char * position;
- void *location;
+ void * location;
action_type type;
+ FuncNode * func_node;
+ /* collisions store a list of FuncInsts with the same position
+ * but different action types. For example, CAS is broken down
+ * as three different atomic operations in cmodelint.cc */
func_inst_list_mt collisions;
+
func_inst_list_mt predecessors;
func_inst_list_mt successors;
};
* ATOMIC_LOCK, ATOMIC_TRYLOCK, and ATOMIC_UNLOCK are not tagged with their
* source line numbers
*/
- if (position == NULL) {
+ if (position == NULL)
return NULL;
- }
if ( func_insts.contains(position) ) {
FuncInst * inst = func_insts.get(position);
return func_inst;
}
- func_inst = new FuncInst(act);
+ func_inst = new FuncInst(act, this);
inst->get_collisions()->push_back(func_inst);
inst_list.push_back(func_inst); // delete?
// model_print("collision added\n");
return inst;
}
- FuncInst * func_inst = new FuncInst(act);
+ FuncInst * func_inst = new FuncInst(act, this);
func_insts.put(position, func_inst);
inst_list.push_back(func_inst);
return func_inst;
}
+
+void FuncNode::add_entry_inst(FuncInst * inst)
+{
+ if (inst == NULL)
+ return;
+
+ func_inst_list_mt::iterator it;
+ for (it = entry_insts.begin(); it != entry_insts.end(); it++) {
+ if (inst == *it)
+ return;
+ }
+
+ entry_insts.push_back(inst);
+}
FuncNode();
~FuncNode();
- FuncInst * get_or_add_action(ModelAction *act);
-
- HashTable<const char *, FuncInst *, uintptr_t, 4, model_malloc, model_calloc, model_free> * getFuncInsts() { return &func_insts; }
- func_inst_list_mt * 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; }
+ FuncInst * get_or_add_action(ModelAction *act);
+
+ HashTable<const char *, FuncInst *, uintptr_t, 4, model_malloc, model_calloc, model_free> * getFuncInsts() { return &func_insts; }
+ func_inst_list_mt * get_inst_list() { return &inst_list; }
+ func_inst_list_mt * get_entry_insts() { return &entry_insts; }
+ void add_entry_inst(FuncInst * inst);
+
MEMALLOC
private:
uint32_t func_id;
/* list of all atomic instructions in this function */
func_inst_list_mt inst_list;
- /* possible entry (atomic) instructions in this function */
+ /* possible entry atomic instructions in this function */
func_inst_list_mt entry_insts;
};
return;
func_inst_list_t::iterator it = inst_list->begin();
- func_inst_list_t::iterator prev = inst_list->end();
- it++;
+ func_inst_list_t::iterator prev;
+
+ /* add the first instruction to the list of entry insts */
+ FuncInst * entry_inst = *it;
+ FuncNode * func_node = entry_inst->get_func_node();
+ func_node->add_entry_inst(entry_inst);
+ it++;
while (it != inst_list->end()) {
prev = it;
prev--;
{
for (uint32_t i = 0; i < func_atomics.size(); i++ ) {
FuncNode * funcNode = func_atomics[i];
- func_inst_list_mt * inst_list = funcNode->get_inst_list();
-
if (funcNode == NULL)
continue;
+ func_inst_list_mt * entry_insts = funcNode->get_entry_insts();
+
+ model_print("function %s has entry actions\n", funcNode->get_func_name());
+ func_inst_list_mt::iterator it;
+ for (it = entry_insts->begin(); it != entry_insts->end(); it++) {
+ FuncInst *inst = *it;
+ model_print("type: %d, at: %s\n", inst->get_type(), inst->get_position());
+ }
+
+/*
+ func_inst_list_mt * inst_list = funcNode->get_inst_list();
+
model_print("function %s has following actions\n", funcNode->get_func_name());
func_inst_list_mt::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());
}
+*/
}
}