fix bug
[c11tester.git] / funcnode.cc
index ce91815f7c8ac2ff860f22287a5e8b649465ce31..2b2525466d24652e4f7d703f8caf1ceed63077cb 100644 (file)
@@ -1,12 +1,14 @@
 #include "funcnode.h"
+#include "predicate.h"
 
 FuncNode::FuncNode() :
        func_inst_map(),
        inst_list(),
-       entry_insts()
+       entry_insts(),
+       thrd_read_map()
 {}
 
-/* Check whether FuncInst with the same type, position, and location 
+/* Check whether FuncInst with the same type, position, and location
  * as act has been added to func_inst_map or not. If so, return it;
  * if not, add it and return it.
  *
@@ -38,9 +40,7 @@ FuncInst * FuncNode::get_or_add_action(ModelAction *act)
 
                        func_inst = new FuncInst(act, this);
                        inst->get_collisions()->push_back(func_inst);
-                       inst_list.push_back(func_inst);         // delete?
-                       if (func_inst->is_read())
-                               group_reads_by_loc(func_inst);
+                       inst_list.push_back(func_inst); // delete?
 
                        return func_inst;
                }
@@ -49,12 +49,10 @@ FuncInst * FuncNode::get_or_add_action(ModelAction *act)
        }
 
        FuncInst * func_inst = new FuncInst(act, this);
+
        func_inst_map.put(position, func_inst);
        inst_list.push_back(func_inst);
 
-       if (func_inst->is_read())
-               group_reads_by_loc(func_inst);
-
        return func_inst;
 }
 
@@ -63,38 +61,119 @@ 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)
+       mllnode<FuncInst*>* it;
+       for (it = entry_insts.begin();it != NULL;it=it->getNext()) {
+               if (inst == it->getVal())
                        return;
        }
 
        entry_insts.push_back(inst);
 }
 
-/* group atomic read actions by memory location */
-void FuncNode::group_reads_by_loc(FuncInst * inst)
+/* @param inst_list a list of FuncInsts; this argument comes from ModelExecution
+ * Link FuncInsts in a list - add one FuncInst to another's predecessors and successors
+ */
+void FuncNode::link_insts(func_inst_list_t * inst_list)
 {
-       ASSERT(inst);
-       if ( !inst->is_read() )
+       if (inst_list == NULL)
                return;
 
-       void * location = inst->get_location();
+       sllnode<FuncInst *>* it = inst_list->begin();
+       sllnode<FuncInst *>* prev;
 
-       func_inst_list_mt * reads;
-       if ( !reads_by_loc.contains(location) ) {
-               reads = new func_inst_list_mt();
-               reads->push_back(inst);
-               reads_by_loc.put(location, reads);
+       if (inst_list->size() == 0)
                return;
+
+       /* add the first instruction to the list of entry insts */
+       FuncInst * entry_inst = it->getVal();
+       add_entry_inst(entry_inst);
+
+       it=it->getNext();
+       while (it != NULL) {
+               prev = it;
+               prev = it->getPrev();
+
+               FuncInst * prev_inst = prev->getVal();
+               FuncInst * curr_inst = it->getVal();
+
+               prev_inst->add_succ(curr_inst);
+               curr_inst->add_pred(prev_inst);
+
+               it=it->getNext();
        }
+}
 
-       reads = reads_by_loc.get(location);
-       func_inst_list_mt::iterator it;
-       for (it = reads->begin(); it != reads->end(); it++) {
-               if (inst == *it)
-                       return;
+/* @param tid thread id
+ * Store the values read by atomic read actions into thrd_read_map */
+void FuncNode::store_read(ModelAction * act, uint32_t tid)
+{
+       ASSERT(act);
+
+       void * location = act->get_location();
+       uint64_t read_from_val = act->get_reads_from_value();
+
+       /* resize and initialize */
+       uint32_t old_size = thrd_read_map.size();
+       if (old_size <= tid) {
+               thrd_read_map.resize(tid + 1);
+               for (uint32_t i = old_size;i < tid + 1;i++)
+                       thrd_read_map[i] = new read_map_t();
        }
 
-       reads->push_back(inst);
+       read_map_t * read_map = thrd_read_map[tid];
+       read_map->put(location, read_from_val);
+
+       /* Store the memory locations where atomic reads happen */
+       // read_locations.add(location);
+}
+
+uint64_t FuncNode::query_last_read(void * location, uint32_t tid)
+{
+       if (thrd_read_map.size() <= tid)
+               return 0xdeadbeef;
+
+       read_map_t * read_map = thrd_read_map[tid];
+
+       /* last read value not found */
+       if ( !read_map->contains(location) )
+               return 0xdeadbeef;
+
+       uint64_t read_val = read_map->get(location);
+       return read_val;
+}
+
+/* @param tid thread id
+ * Reset read map for a thread. This function shall only be called
+ * when a thread exits a function
+ */
+void FuncNode::clear_read_map(uint32_t tid)
+{
+       if (thrd_read_map.size() <= tid)
+               return;
+
+       thrd_read_map[tid]->reset();
+}
+
+void FuncNode::generate_predicate(FuncInst *func_inst)
+{
+
+}
+
+/* @param tid thread id
+ * Print the values read by the last read actions for each memory location
+ */
+void FuncNode::print_last_read(uint32_t tid)
+{
+       ASSERT(thrd_read_map.size() > tid);
+       read_map_t * read_map = thrd_read_map[tid];
+/*
+       mllnode<void *> * it;
+       for (it = read_locations.begin();it != NULL;it=it->getNext()) {
+               if ( !read_map->contains(it->getVal()) )
+                       break;
+
+               uint64_t read_val = read_map->get(it->getVal());
+               model_print("last read of thread %d at %p: 0x%x\n", tid, it->getVal(), read_val);
+       }
+*/
 }