add a data structure to store the values read by last read actions of each thread...
[c11tester.git] / funcnode.cc
1 #include "funcnode.h"
2
3 FuncNode::FuncNode() :
4         func_inst_map(),
5         inst_list(),
6         entry_insts()
7 {}
8
9 /* Check whether FuncInst with the same type, position, and location 
10  * as act has been added to func_inst_map or not. If so, return it;
11  * if not, add it and return it.
12  *
13  * @return FuncInst with the same type, position, and location as act */
14 FuncInst * FuncNode::get_or_add_action(ModelAction *act)
15 {
16         ASSERT(act);
17         const char * position = act->get_position();
18
19         /* Actions THREAD_CREATE, THREAD_START, THREAD_YIELD, THREAD_JOIN,
20          * THREAD_FINISH, PTHREAD_CREATE, PTHREAD_JOIN,
21          * ATOMIC_LOCK, ATOMIC_TRYLOCK, and ATOMIC_UNLOCK are not tagged with their
22          * source line numbers
23          */
24         if (position == NULL)
25                 return NULL;
26
27         if ( func_inst_map.contains(position) ) {
28                 FuncInst * inst = func_inst_map.get(position);
29
30                 if (inst->get_type() != act->get_type() ) {
31                         // model_print("action with a different type occurs at line number %s\n", position);
32                         FuncInst * func_inst = inst->search_in_collision(act);
33
34                         if (func_inst != NULL) {
35                                 // return the FuncInst found in the collision list
36                                 return func_inst;
37                         }
38
39                         func_inst = new FuncInst(act, this);
40                         inst->get_collisions()->push_back(func_inst);
41                         inst_list.push_back(func_inst);         // delete?
42
43                         return func_inst;
44                 }
45
46                 return inst;
47         }
48
49         FuncInst * func_inst = new FuncInst(act, this);
50
51         func_inst_map.put(position, func_inst);
52         inst_list.push_back(func_inst);
53
54         return func_inst;
55 }
56
57 void FuncNode::add_entry_inst(FuncInst * inst)
58 {
59         if (inst == NULL)
60                 return;
61
62         func_inst_list_mt::iterator it;
63         for (it = entry_insts.begin(); it != entry_insts.end(); it++) {
64                 if (inst == *it)
65                         return;
66         }
67
68         entry_insts.push_back(inst);
69 }
70
71 /* Store the values read by atomic read actions into loc_thrd_read_map */
72 void FuncNode::store_read(ModelAction * act, uint32_t tid)
73 {
74         ASSERT(act);
75
76         void * location = act->get_location();
77         uint64_t read_from_val = act->get_reads_from_value();
78
79         ModelVector<uint64_t> * read_vals = loc_thrd_read_map.get(location);
80         if (read_vals == NULL) {
81                 read_vals = new ModelVector<uint64_t>();
82                 loc_thrd_read_map.put(location, read_vals);
83         }
84
85         if (read_vals->size() <= tid) {
86                 read_vals->resize(tid + 1);
87         }
88         read_vals->at(tid) = read_from_val;
89
90         /* Store keys of loc_thrd_read_map into read_locations */
91         bool push_loc = true;
92         ModelList<void *>::iterator it;
93         for (it = read_locations.begin(); it != read_locations.end(); it++) {
94                 if (location == *it) {
95                         push_loc = false;
96                         break;
97                 }
98         }
99
100         if (push_loc)
101                 read_locations.push_back(location);
102 }
103
104 /* @param tid thread id
105  * Print the values read by the last read actions per memory location
106  */
107 void FuncNode::print_last_read(uint32_t tid)
108 {
109         ModelList<void *>::iterator it;
110         for (it = read_locations.begin(); it != read_locations.end(); it++) {
111                 ModelVector<uint64_t> * read_vals = loc_thrd_read_map.get(*it);
112                 if (read_vals->size() <= tid)
113                         break;
114
115                 int64_t read_val = read_vals->at(tid);
116                 model_print("last read of thread %d at %p: 0x%x\n", tid, *it, read_val);
117         }
118 }