12 /* Check whether FuncInst with the same type, position, and location
13 * as act has been added to func_inst_map or not. If so, return it;
14 * if not, add it and return it.
16 * @return FuncInst with the same type, position, and location as act */
17 FuncInst * FuncNode::get_or_add_action(ModelAction *act)
20 const char * position = act->get_position();
22 /* Actions THREAD_CREATE, THREAD_START, THREAD_YIELD, THREAD_JOIN,
23 * THREAD_FINISH, PTHREAD_CREATE, PTHREAD_JOIN,
24 * ATOMIC_LOCK, ATOMIC_TRYLOCK, and ATOMIC_UNLOCK are not tagged with their
30 if ( func_inst_map.contains(position) ) {
31 FuncInst * inst = func_inst_map.get(position);
33 if (inst->get_type() != act->get_type() ) {
34 // model_print("action with a different type occurs at line number %s\n", position);
35 FuncInst * func_inst = inst->search_in_collision(act);
37 if (func_inst != NULL) {
38 // return the FuncInst found in the collision list
42 func_inst = new FuncInst(act, this);
43 inst->get_collisions()->push_back(func_inst);
44 inst_list.push_back(func_inst); // delete?
52 FuncInst * func_inst = new FuncInst(act, this);
54 func_inst_map.put(position, func_inst);
55 inst_list.push_back(func_inst);
60 void FuncNode::add_entry_inst(FuncInst * inst)
65 func_inst_list_mt::iterator it;
66 for (it = entry_insts.begin();it != entry_insts.end();it++) {
71 entry_insts.push_back(inst);
74 /* @param inst_list a list of FuncInsts; this argument comes from ModelExecution
75 * Link FuncInsts in a list - add one FuncInst to another's predecessors and successors
77 void FuncNode::link_insts(func_inst_list_t * inst_list)
79 if (inst_list == NULL)
82 func_inst_list_t::iterator it = inst_list->begin();
83 func_inst_list_t::iterator prev;
85 if (inst_list->size() == 0)
88 /* add the first instruction to the list of entry insts */
89 FuncInst * entry_inst = *it;
90 add_entry_inst(entry_inst);
93 while (it != inst_list->end()) {
97 FuncInst * prev_inst = *prev;
98 FuncInst * curr_inst = *it;
100 prev_inst->add_succ(curr_inst);
101 curr_inst->add_pred(prev_inst);
107 /* @param tid thread id
108 * Store the values read by atomic read actions into thrd_read_map */
109 void FuncNode::store_read(ModelAction * act, uint32_t tid)
113 void * location = act->get_location();
114 uint64_t read_from_val = act->get_reads_from_value();
116 /* resize and initialize */
117 uint32_t old_size = thrd_read_map.size();
118 if (old_size <= tid) {
119 thrd_read_map.resize(tid + 1);
120 for (uint32_t i = old_size;i < tid + 1;i++)
121 thrd_read_map[i] = new read_map_t();
124 read_map_t * read_map = thrd_read_map[tid];
125 read_map->put(location, read_from_val);
127 /* Store the memory locations where atomic reads happen */
128 bool push_loc = true;
129 ModelList<void *>::iterator it;
130 for (it = read_locations.begin();it != read_locations.end();it++) {
131 if (location == *it) {
138 read_locations.push_back(location);
141 uint64_t FuncNode::query_last_read(void * location, uint32_t tid)
143 if (thrd_read_map.size() <= tid)
146 read_map_t * read_map = thrd_read_map[tid];
148 /* last read value not found */
149 if ( !read_map->contains(location) )
152 uint64_t read_val = read_map->get(location);
156 /* @param tid thread id
157 * Reset read map for a thread. This function shall only be called
158 * when a thread exits a function
160 void FuncNode::clear_read_map(uint32_t tid)
162 if (thrd_read_map.size() <= tid)
165 thrd_read_map[tid]->reset();
168 void FuncNode::generate_predicate(FuncInst *func_inst)
173 /* @param tid thread id
174 * Print the values read by the last read actions for each memory location
176 void FuncNode::print_last_read(uint32_t tid)
178 ASSERT(thrd_read_map.size() > tid);
179 read_map_t * read_map = thrd_read_map[tid];
181 ModelList<void *>::iterator it;
182 for (it = read_locations.begin();it != read_locations.end();it++) {
183 if ( !read_map->contains(*it) )
186 uint64_t read_val = read_map->get(*it);
187 model_print("last read of thread %d at %p: 0x%x\n", tid, *it, read_val);