13 /* Check whether FuncInst with the same type, position, and location
14 * as act has been added to func_inst_map or not. If so, return it;
15 * if not, add it and return it.
17 * @return FuncInst with the same type, position, and location as act */
18 FuncInst * FuncNode::get_or_add_action(ModelAction *act)
21 const char * position = act->get_position();
23 /* Actions THREAD_CREATE, THREAD_START, THREAD_YIELD, THREAD_JOIN,
24 * THREAD_FINISH, PTHREAD_CREATE, PTHREAD_JOIN,
25 * ATOMIC_LOCK, ATOMIC_TRYLOCK, and ATOMIC_UNLOCK are not tagged with their
31 if ( func_inst_map.contains(position) ) {
32 FuncInst * inst = func_inst_map.get(position);
34 if (inst->get_type() != act->get_type() ) {
35 // model_print("action with a different type occurs at line number %s\n", position);
36 FuncInst * func_inst = inst->search_in_collision(act);
38 if (func_inst != NULL) {
39 // return the FuncInst found in the collision list
43 func_inst = new FuncInst(act, this);
44 inst->get_collisions()->push_back(func_inst);
45 inst_list.push_back(func_inst); // delete?
53 FuncInst * func_inst = new FuncInst(act, this);
55 func_inst_map.put(position, func_inst);
56 inst_list.push_back(func_inst);
61 void FuncNode::add_entry_inst(FuncInst * inst)
66 func_inst_list_mt::iterator it;
67 for (it = entry_insts.begin();it != entry_insts.end();it++) {
72 entry_insts.push_back(inst);
75 /* @param inst_list a list of FuncInsts; this argument comes from ModelExecution
76 * Link FuncInsts in a list - add one FuncInst to another's predecessors and successors
78 void FuncNode::link_insts(func_inst_list_t * inst_list)
80 if (inst_list == NULL)
83 func_inst_list_t::iterator it = inst_list->begin();
84 func_inst_list_t::iterator prev;
86 if (inst_list->size() == 0)
89 /* add the first instruction to the list of entry insts */
90 FuncInst * entry_inst = *it;
91 add_entry_inst(entry_inst);
94 while (it != inst_list->end()) {
98 FuncInst * prev_inst = *prev;
99 FuncInst * curr_inst = *it;
101 prev_inst->add_succ(curr_inst);
102 curr_inst->add_pred(prev_inst);
108 /* @param tid thread id
109 * Store the values read by atomic read actions into thrd_read_map */
110 void FuncNode::store_read(ModelAction * act, uint32_t tid)
114 void * location = act->get_location();
115 uint64_t read_from_val = act->get_reads_from_value();
117 /* resize and initialize */
118 uint32_t old_size = thrd_read_map.size();
119 if (old_size <= tid) {
120 thrd_read_map.resize(tid + 1);
121 for (uint32_t i = old_size; i < tid + 1; i++)
122 thrd_read_map[i] = new read_map_t();
125 read_map_t * read_map = thrd_read_map[tid];
126 read_map->put(location, read_from_val);
128 /* Store the memory locations where atomic reads happen */
129 // read_locations.add(location);
132 uint64_t FuncNode::query_last_read(void * location, uint32_t tid)
134 if (thrd_read_map.size() <= tid)
137 read_map_t * read_map = thrd_read_map[tid];
139 /* last read value not found */
140 if ( !read_map->contains(location) )
143 uint64_t read_val = read_map->get(location);
147 /* @param tid thread id
148 * Reset read map for a thread. This function shall only be called
149 * when a thread exits a function
151 void FuncNode::clear_read_map(uint32_t tid)
153 if (thrd_read_map.size() <= tid)
156 thrd_read_map[tid]->reset();
159 void FuncNode::add_to_write_history(void * location, uint64_t write_val)
161 write_set_t * write_set = write_history.get(location);
163 if (write_set == NULL) {
164 write_set = new write_set_t();
165 write_history.put(location, write_set);
168 write_set->add(write_val);
169 write_locations.add(location);
172 void FuncNode::generate_predicate(FuncInst *func_inst)
177 /* @param tid thread id
178 * Print the values read by the last read actions for each memory location
180 void FuncNode::print_last_read(uint32_t tid)
182 ASSERT(thrd_read_map.size() > tid);
183 read_map_t * read_map = thrd_read_map[tid];
185 ModelList<void *>::iterator it;
186 for (it = read_locations.begin();it != read_locations.end();it++) {
187 if ( !read_map->contains(*it) )
190 uint64_t read_val = read_map->get(*it);
191 model_print("last read of thread %d at %p: 0x%x\n", tid, *it, read_val);
196 void FuncNode::print_write()
198 HSIterator<void *, uintptr_t, 4, model_malloc, model_calloc, model_free> * iter;
199 HSIterator<uint64_t, uint64_t, 0, model_malloc, model_calloc, model_free> * write_iter;
200 iter = write_locations.iterator();
202 if (write_locations.getSize() > 10) {
203 while (iter->hasNext()) {
204 void * location = iter->next();
205 write_set_t * write_set = write_history.get(location);
207 // model_print("location: %p contains %d writes\n", location, write_set->getSize());
208 if (write_set->getSize() > 5) {
209 model_print("location %p has writes: ", location);
210 write_iter = write_set->iterator();
212 while (write_iter->hasNext()) {
213 uint64_t val = write_iter->next();
214 model_print("%lx ", val);