only select a new predicate branch when new read actions are processed
[c11tester.git] / newfuzzer.cc
1 #include "newfuzzer.h"
2 #include "threads-model.h"
3 #include "model.h"
4 #include "action.h"
5 #include "execution.h"
6 #include "funcnode.h"
7
8 NewFuzzer::NewFuzzer() :
9         thrd_last_read_act(),
10         thrd_curr_pred(),
11         thrd_selected_child_branch()
12 {}
13
14 /**
15  * @brief Register the ModelHistory and ModelExecution engine
16  */
17 void NewFuzzer::register_engine(ModelHistory * history, ModelExecution *execution)
18 {
19         this->history = history;
20         this->execution = execution;
21 }
22
23 int NewFuzzer::selectWrite(ModelAction *read, SnapVector<ModelAction *> * rf_set)
24 {
25         int random_index = random() % rf_set->size();
26
27         thread_id_t tid = read->get_tid();
28         int thread_id = id_to_int(tid);
29
30         if (thrd_last_read_act.size() <= (uint) thread_id)
31                 thrd_last_read_act.resize(thread_id + 1);
32
33         // A new read action is encountered, select a random child branch of current predicate
34         if (read != thrd_last_read_act[thread_id]) {
35                 thrd_last_read_act[thread_id] = read;
36
37                 SnapVector<func_id_list_t> * thrd_func_list = execution->get_thrd_func_list();
38                 uint32_t func_id = (*thrd_func_list)[thread_id].back();
39
40                 FuncNode * func_node = history->get_func_node(func_id);
41                 FuncInst * read_inst = func_node->get_inst(read);
42                 Predicate * curr_pred = func_node->get_predicate_tree_position(tid);
43                 selectBranch(thread_id, curr_pred, read_inst);
44         }
45
46         Predicate * selected_branch = thrd_selected_child_branch[thread_id];
47         if (selected_branch == NULL)
48                 return random_index;
49
50         FuncInst * read_inst = selected_branch->get_func_inst();
51         PredExprSet * pred_expressions = selected_branch->get_pred_expressions();
52
53         model_print("thread %d ", tid);
54         read_inst->print();
55
56         // unset predicates
57         if (pred_expressions->getSize() == 0)
58                 return random_index;
59 /*
60         PredExprSetIter * pred_expr_it = pred_expressions->iterator();
61         while (pred_expr_it->hasNext()) {
62                 struct pred_expr * expression = pred_expr_it->next();
63
64                 switch(expression->token) {
65                         case NOPREDICATE:
66                                 read_inst->print();
67                                 read->print();
68                                 model_print("no predicate\n");
69                                 return random_index;
70                         case EQUALITY:
71                                 model_print("equality predicate, under construction\n");
72                                 break;
73                         case NULLITY:
74                                 model_print("nullity predicate, under construction\n");
75                                 break;
76                         default:
77                                 model_print("unknown predicate token\n");
78                                 break;
79                 }
80         }
81 */
82         return random_index;
83 }
84
85 void NewFuzzer::selectBranch(int thread_id, Predicate * curr_pred, FuncInst * read_inst)
86 {
87         if ( thrd_selected_child_branch.size() <= (uint) thread_id)
88                 thrd_selected_child_branch.resize(thread_id + 1);
89
90         if (read_inst == NULL) {
91                 thrd_selected_child_branch[thread_id] = NULL;
92                 return;
93         }
94
95         ModelVector<Predicate *> * children = curr_pred->get_children();
96         SnapVector<Predicate *> branches;
97
98         for (uint i = 0; i < children->size(); i++) {
99                 Predicate * child = (*children)[i];
100                 if (child->get_func_inst() == read_inst)
101                         branches.push_back(child);
102         }
103
104         // predicate children have not been generated
105         if (branches.size() == 0) {
106                 thrd_selected_child_branch[thread_id] = NULL;
107                 return;
108         }
109
110         // randomly select a branch
111         int random_index = random() % branches.size();
112         Predicate * random_branch = branches[ random_index ];
113         thrd_selected_child_branch[thread_id] = random_branch;
114 }