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