4 predicate_tree_initialized(false),
11 /* Check whether FuncInst with the same type, position, and location
12 * as act has been added to func_inst_map or not. If so, return it;
13 * if not, add it and return it.
15 * @return FuncInst with the same type, position, and location as act */
16 FuncInst * FuncNode::get_or_add_inst(ModelAction *act)
19 const char * position = act->get_position();
21 /* Actions THREAD_CREATE, THREAD_START, THREAD_YIELD, THREAD_JOIN,
22 * THREAD_FINISH, PTHREAD_CREATE, PTHREAD_JOIN,
23 * ATOMIC_LOCK, ATOMIC_TRYLOCK, and ATOMIC_UNLOCK are not tagged with their
29 if ( func_inst_map.contains(position) ) {
30 FuncInst * inst = func_inst_map.get(position);
32 if (inst->get_type() != act->get_type() ) {
33 // model_print("action with a different type occurs at line number %s\n", position);
34 FuncInst * func_inst = inst->search_in_collision(act);
36 if (func_inst != NULL) {
37 // return the FuncInst found in the collision list
41 func_inst = new FuncInst(act, this);
42 inst->get_collisions()->push_back(func_inst);
43 inst_list.push_back(func_inst); // delete?
51 FuncInst * func_inst = new FuncInst(act, this);
53 func_inst_map.put(position, func_inst);
54 inst_list.push_back(func_inst);
59 void FuncNode::add_entry_inst(FuncInst * inst)
64 mllnode<FuncInst*>* it;
65 for (it = entry_insts.begin(); it != NULL; it = it->getNext()) {
66 if (inst == it->getVal())
70 entry_insts.push_back(inst);
73 /* @param act_list a list of ModelActions; this argument comes from ModelExecution
74 * convert act_inst to inst_list do linking - add one FuncInst to another's predecessors and successors
76 void FuncNode::update_inst_tree(action_list_t * act_list)
80 else if (act_list->size() == 0)
83 /* build inst_list from act_list for later processing */
84 func_inst_list_t inst_list;
85 for (sllnode<ModelAction *> * it = act_list->begin(); it != NULL; it = it->getNext()) {
86 ModelAction * act = it->getVal();
87 FuncInst * func_inst = get_or_add_inst(act);
89 if (func_inst != NULL)
90 inst_list.push_back(func_inst);
94 sllnode<FuncInst *>* it = inst_list.begin();
95 sllnode<FuncInst *>* prev;
97 /* add the first instruction to the list of entry insts */
98 FuncInst * entry_inst = it->getVal();
99 add_entry_inst(entry_inst);
103 prev = it->getPrev();
105 FuncInst * prev_inst = prev->getVal();
106 FuncInst * curr_inst = it->getVal();
108 prev_inst->add_succ(curr_inst);
109 curr_inst->add_pred(prev_inst);
115 /* @param tid thread id
116 * Store the values read by atomic read actions into thrd_read_map */
117 void FuncNode::store_read(ModelAction * act, uint32_t tid)
121 void * location = act->get_location();
122 uint64_t read_from_val = act->get_reads_from_value();
124 /* resize and initialize */
125 uint32_t old_size = thrd_read_map.size();
126 if (old_size <= tid) {
127 thrd_read_map.resize(tid + 1);
128 for (uint32_t i = old_size; i < tid + 1;i++)
129 thrd_read_map[i] = new read_map_t();
132 read_map_t * read_map = thrd_read_map[tid];
133 read_map->put(location, read_from_val);
135 /* Store the memory locations where atomic reads happen */
136 // read_locations.add(location);
139 uint64_t FuncNode::query_last_read(void * location, uint32_t tid)
141 if (thrd_read_map.size() <= tid)
144 read_map_t * read_map = thrd_read_map[tid];
146 /* last read value not found */
147 if ( !read_map->contains(location) )
150 uint64_t read_val = read_map->get(location);
154 /* @param tid thread id
155 * Reset read map for a thread. This function shall only be called
156 * when a thread exits a function
158 void FuncNode::clear_read_map(uint32_t tid)
160 if (thrd_read_map.size() <= tid)
163 thrd_read_map[tid]->reset();
166 void FuncNode::init_predicate_tree(func_inst_list_t * inst_list)
168 if (inst_list == NULL || inst_list->size() == 0)
171 if (predicate_tree_initialized)
174 predicate_tree_initialized = true;
176 // maybe restrict the size of hashtable to save calloc time
177 HashTable<void *, FuncInst *, uintptr_t, 4> loc_inst_map;
179 sllnode<FuncInst *> *it = inst_list->begin();
180 sllnode<FuncInst *> *prev;
182 FuncInst * entry_inst = it->getVal();
184 /* entry instruction has no predicate expression */
185 Predicate * pred_entry = new Predicate(entry_inst);
186 loc_inst_map.put(entry_inst->get_location(), entry_inst);
190 prev = it->getPrev();
192 FuncInst * curr_inst = it->getVal();
193 FuncInst * prev_inst = prev->getVal();
195 if ( loc_inst_map.contains(curr_inst->get_location()) ) {
196 Predicate * pred1 = new Predicate(curr_inst);
197 pred1->add_predicate(EQUALITY, curr_inst->get_location(), 0);
199 Predicate * pred2 = new Predicate(curr_inst);
200 pred2->add_predicate(EQUALITY, curr_inst->get_location(), 1);
203 loc_inst_map.put(curr_inst->get_location(), curr_inst);
210 void FuncNode::generate_predicate(FuncInst *func_inst)
215 /* @param tid thread id
216 * Print the values read by the last read actions for each memory location
218 void FuncNode::print_last_read(uint32_t tid)
220 ASSERT(thrd_read_map.size() > tid);
221 read_map_t * read_map = thrd_read_map[tid];
223 mllnode<void *> * it;
224 for (it = read_locations.begin();it != NULL;it=it->getNext()) {
225 if ( !read_map->contains(it->getVal()) )
228 uint64_t read_val = read_map->get(it->getVal());
229 model_print("last read of thread %d at %p: 0x%x\n", tid, it->getVal(), read_val);