move codes around in history.cc, and NewFuzzer::selectWrite is half working
[c11tester.git] / newfuzzer.cc
index df3f2ca6c9ea6eaf62858667e2898dec53e14635..8bef9cc40f0e2762241455b3eee14f66d3eba4e4 100644 (file)
@@ -5,6 +5,8 @@
 #include "execution.h"
 #include "funcnode.h"
 
+typedef HashTable<FuncInst *, ModelAction *, uintptr_t, 0> inst_act_map_t;
+
 NewFuzzer::NewFuzzer() :
        thrd_last_read_act(),
        thrd_curr_pred(),
@@ -30,14 +32,15 @@ int NewFuzzer::selectWrite(ModelAction *read, SnapVector<ModelAction *> * rf_set
        if (thrd_last_read_act.size() <= (uint) thread_id)
                thrd_last_read_act.resize(thread_id + 1);
 
+       SnapVector<func_id_list_t> * thrd_func_list = execution->get_thrd_func_list();
+       uint32_t func_id = (*thrd_func_list)[thread_id].back();
+       FuncNode * func_node = history->get_func_node(func_id);
+       inst_act_map_t * inst_act_map = func_node->get_inst_act_map(tid);
+
        // A new read action is encountered, select a random child branch of current predicate
        if (read != thrd_last_read_act[thread_id]) {
                thrd_last_read_act[thread_id] = read;
 
-               SnapVector<func_id_list_t> * thrd_func_list = execution->get_thrd_func_list();
-               uint32_t func_id = (*thrd_func_list)[thread_id].back();
-
-               FuncNode * func_node = history->get_func_node(func_id);
                FuncInst * read_inst = func_node->get_inst(read);
                Predicate * curr_pred = func_node->get_predicate_tree_position(tid);
                selectBranch(thread_id, curr_pred, read_inst);
@@ -47,38 +50,67 @@ int NewFuzzer::selectWrite(ModelAction *read, SnapVector<ModelAction *> * rf_set
        if (selected_branch == NULL)
                return random_index;
 
-       FuncInst * read_inst = selected_branch->get_func_inst();
        PredExprSet * pred_expressions = selected_branch->get_pred_expressions();
 
-       model_print("thread %d ", tid);
-       read_inst->print();
+//     FuncInst * read_inst = selected_branch->get_func_inst();
+//     model_print("thread %d ", tid);
+//     read_inst->print();
 
        // unset predicates
        if (pred_expressions->getSize() == 0)
                return random_index;
-/*
-       PredExprSetIter * pred_expr_it = pred_expressions->iterator();
-       while (pred_expr_it->hasNext()) {
-               struct pred_expr * expression = pred_expr_it->next();
-
-               switch(expression->token) {
-                       case NOPREDICATE:
-                               read_inst->print();
-                               read->print();
-                               model_print("no predicate\n");
+
+       for (uint index = 0; index < rf_set->size(); index++) {
+               ModelAction * write_act = (*rf_set)[index];
+               bool satisfy_predicate = true;
+
+               PredExprSetIter * pred_expr_it = pred_expressions->iterator();
+               while (pred_expr_it->hasNext()) {
+                       struct pred_expr * expression = pred_expr_it->next();
+                       uint64_t last_read, write_val;
+                       bool equality;
+
+                       if (expression->token == NOPREDICATE)
                                return random_index;
-                       case EQUALITY:
-                               model_print("equality predicate, under construction\n");
-                               break;
-                       case NULLITY:
-                               model_print("nullity predicate, under construction\n");
-                               break;
-                       default:
-                               model_print("unknown predicate token\n");
+
+                       switch(expression->token) {
+                               case EQUALITY:
+                                       FuncInst * to_be_compared;
+                                       ModelAction * last_act;
+
+                                       to_be_compared = expression->func_inst;
+                                       last_act = inst_act_map->get(to_be_compared);
+
+                                       last_read = last_act->get_reads_from_value();
+                                       write_val = write_act->get_write_value();
+
+                                       equality = (last_read == write_val);
+                                       if (equality != expression->value)
+                                               satisfy_predicate = false;
+
+                                       model_print("equality predicate\n");
+                                       break;
+                               case NULLITY:
+                                       model_print("nullity predicate, under construction\n");
+                                       break;
+                               default:
+                                       model_print("unknown predicate token\n");
+                                       break;
+                       }
+
+                       if (!satisfy_predicate)
                                break;
                }
+
+               /* TODO: collect all writes that satisfy predicate; if some of them violate
+                * modification graph, others can be chosen */
+               if (satisfy_predicate) {
+                       model_print("^_^ satisfy predicate\n");
+                       return index;
+               }
        }
-*/
+
+       // TODO: make this thread sleep if no write satisfies the chosen predicate
        return random_index;
 }
 
@@ -87,7 +119,7 @@ void NewFuzzer::selectBranch(int thread_id, Predicate * curr_pred, FuncInst * re
        if ( thrd_selected_child_branch.size() <= (uint) thread_id)
                thrd_selected_child_branch.resize(thread_id + 1);
 
-       if (read_inst == NULL) {
+       if (curr_pred == NULL || read_inst == NULL) {
                thrd_selected_child_branch[thread_id] = NULL;
                return;
        }
@@ -112,3 +144,12 @@ void NewFuzzer::selectBranch(int thread_id, Predicate * curr_pred, FuncInst * re
        Predicate * random_branch = branches[ random_index ];
        thrd_selected_child_branch[thread_id] = random_branch;
 }
+
+Predicate * NewFuzzer::get_selected_child_branch(thread_id_t tid)
+{
+       int thread_id = id_to_int(tid);
+       if (thrd_selected_child_branch.size() <= (uint) thread_id)
+               return NULL;
+
+       return thrd_selected_child_branch[thread_id];
+}