commit stuff before merge
[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                         if (func_inst->is_read())
43                                 group_reads_by_loc(func_inst);
44
45                         return func_inst;
46                 }
47
48                 return inst;
49         }
50
51         FuncInst * func_inst = new FuncInst(act, this);
52         func_inst_map.put(position, func_inst);
53         inst_list.push_back(func_inst);
54
55         if (func_inst->is_read())
56                 group_reads_by_loc(func_inst);
57
58         return func_inst;
59 }
60
61 void FuncNode::add_entry_inst(FuncInst * inst)
62 {
63         if (inst == NULL)
64                 return;
65
66         func_inst_list_mt::iterator it;
67         for (it = entry_insts.begin(); it != entry_insts.end(); it++) {
68                 if (inst == *it)
69                         return;
70         }
71
72         entry_insts.push_back(inst);
73 }
74
75 /* group atomic read actions by memory location */
76 void FuncNode::group_reads_by_loc(FuncInst * inst)
77 {
78         ASSERT(inst);
79         if ( !inst->is_read() )
80                 return;
81
82         void * location = inst->get_location();
83
84         func_inst_list_mt * reads;
85         if ( !reads_by_loc.contains(location) ) {
86                 reads = new func_inst_list_mt();
87                 reads->push_back(inst);
88                 reads_by_loc.put(location, reads);
89                 return;
90         }
91
92         reads = reads_by_loc.get(location);
93         func_inst_list_mt::iterator it;
94         for (it = reads->begin(); it != reads->end(); it++) {
95                 if (inst == *it)
96                         return;
97         }
98
99         reads->push_back(inst);
100 }