fix a bug in cds_func_exit
[c11tester.git] / execution.cc
index d22f628d215bcc5f81704c058dea57d1480956d8..c5c40a91f7776d43e98dd3cc027e8b9b05db56b0 100644 (file)
@@ -13,6 +13,7 @@
 #include "datarace.h"
 #include "threads-model.h"
 #include "bugmessage.h"
+#include "history.h"
 #include "fuzzer.h"
 
 #define INITIAL_THREAD_ID       0
@@ -62,8 +63,10 @@ ModelExecution::ModelExecution(ModelChecker *m, Scheduler *scheduler) :
        thrd_last_action(1),
        thrd_last_fence_release(),
        priv(new struct model_snapshot_members ()),
-                        mo_graph(new CycleGraph()),
-       fuzzer(new Fuzzer())
+       mo_graph(new CycleGraph()),
+       fuzzer(new Fuzzer()),
+       thrd_func_list(),
+       thrd_func_inst_lists()
 {
        /* Initialize a model-checker thread, for special ModelActions */
        model_thread = new Thread(get_next_id());
@@ -96,7 +99,7 @@ static action_list_t * get_safe_ptr_action(HashTable<const void *, action_list_t
        return tmp;
 }
 
-static SnapVector<action_list_t> * get_safe_ptr_vect_action(HashTable<void *, SnapVector<action_list_t> *, uintptr_t, 4> * hash, void * ptr)
+static SnapVector<action_list_t> * get_safe_ptr_vect_action(HashTable<const void *, SnapVector<action_list_t> *, uintptr_t, 4> * hash, void * ptr)
 {
        SnapVector<action_list_t> *tmp = hash->get(ptr);
        if (tmp == NULL) {
@@ -323,8 +326,9 @@ bool ModelExecution::process_mutex(ModelAction *curr)
        }
        //otherwise fall into the lock case
        case ATOMIC_LOCK: {
-               if (curr->get_cv()->getClock(state->alloc_tid) <= state->alloc_clock)
-                       assert_bug("Lock access before initialization");
+               //TODO: FIND SOME BETTER WAY TO CHECK LOCK INITIALIZED OR NOT
+               //if (curr->get_cv()->getClock(state->alloc_tid) <= state->alloc_clock)
+               //      assert_bug("Lock access before initialization");
                state->locked = get_thread(curr);
                ModelAction *unlock = get_last_unlock(curr);
                //synchronize with the previous unlock statement
@@ -385,10 +389,7 @@ bool ModelExecution::process_mutex(ModelAction *curr)
  */
 void ModelExecution::process_write(ModelAction *curr)
 {
-
        w_modification_order(curr);
-
-
        get_thread(curr)->set_return_value(VALUE_NONE);
 }
 
@@ -649,6 +650,9 @@ ModelAction * ModelExecution::check_current_action(ModelAction *curr)
        if (!second_part_of_rmw && curr->get_type() != NOOP)
                add_action_to_lists(curr);
 
+       if (curr->is_write())
+               add_write_to_lists(curr);
+
        SnapVector<ModelAction *> * rf_set = NULL;
        /* Build may_read_from set for newly-created actions */
        if (newly_explored && curr->is_read())
@@ -949,21 +953,6 @@ void ModelExecution::w_modification_order(ModelAction *curr)
                                        mo_graph->addEdge(act->get_reads_from(), curr, force_edge);
                                }
                                break;
-                       } else if (act->is_read() && !act->could_synchronize_with(curr) &&
-                                                                !act->same_thread(curr)) {
-                               /* We have an action that:
-                                  (1) did not happen before us
-                                  (2) is a read and we are a write
-                                  (3) cannot synchronize with us
-                                  (4) is in a different thread
-                                  =>
-                                  that read could potentially read from our write.  Note that
-                                  these checks are overly conservative at this point, we'll
-                                  do more checks before actually removing the
-                                  pendingfuturevalue.
-
-                                */
-
                        }
                }
        }
@@ -1051,9 +1040,9 @@ ClockVector * ModelExecution::get_hb_from_write(ModelAction *rf) const {
                }
                i--;
                if (i >= 0) {
-                 rf = (*processset)[i];
+                       rf = (*processset)[i];
                } else
-                 break;
+                       break;
        }
        if (processset != NULL)
                delete processset;
@@ -1077,13 +1066,19 @@ void ModelExecution::add_action_to_lists(ModelAction *act)
                uninit = get_uninitialized_action(act);
                uninit_id = id_to_int(uninit->get_tid());
                list->push_front(uninit);
+               SnapVector<action_list_t> *vec = get_safe_ptr_vect_action(&obj_wr_thrd_map, act->get_location());
+               if (uninit_id >= (int)vec->size())
+                       vec->resize(uninit_id + 1);
+               (*vec)[uninit_id].push_front(uninit);
        }
        list->push_back(act);
 
+       // Update action trace, a total order of all actions
        action_trace.push_back(act);
        if (uninit)
                action_trace.push_front(uninit);
 
+       // Update obj_thrd_map, a per location, per thread, order of actions
        SnapVector<action_list_t> *vec = get_safe_ptr_vect_action(&obj_thrd_map, act->get_location());
        if (tid >= (int)vec->size())
                vec->resize(priv->next_thread_id);
@@ -1091,12 +1086,14 @@ void ModelExecution::add_action_to_lists(ModelAction *act)
        if (uninit)
                (*vec)[uninit_id].push_front(uninit);
 
+       // Update thrd_last_action, the last action taken by each thrad
        if ((int)thrd_last_action.size() <= tid)
                thrd_last_action.resize(get_num_threads());
        thrd_last_action[tid] = act;
        if (uninit)
                thrd_last_action[uninit_id] = uninit;
 
+       // Update thrd_last_fence_release, the last release fence taken by each thread
        if (act->is_fence() && act->is_release()) {
                if ((int)thrd_last_fence_release.size() <= tid)
                        thrd_last_fence_release.resize(get_num_threads());
@@ -1114,6 +1111,18 @@ void ModelExecution::add_action_to_lists(ModelAction *act)
        }
 }
 
+void ModelExecution::add_write_to_lists(ModelAction *write) {
+       // Update seq_cst map
+       if (write->is_seqcst())
+               obj_last_sc_map.put(write->get_location(), write);
+
+       SnapVector<action_list_t> *vec = get_safe_ptr_vect_action(&obj_wr_thrd_map, write->get_location());
+       int tid = id_to_int(write->get_tid());
+       if (tid >= (int)vec->size())
+               vec->resize(priv->next_thread_id);
+       (*vec)[tid].push_back(write);
+}
+
 /**
  * @brief Get the last action performed by a particular Thread
  * @param tid The thread ID of the Thread in question
@@ -1153,16 +1162,7 @@ ModelAction * ModelExecution::get_last_fence_release(thread_id_t tid) const
 ModelAction * ModelExecution::get_last_seq_cst_write(ModelAction *curr) const
 {
        void *location = curr->get_location();
-       action_list_t *list = obj_map.get(location);
-       /* Find: max({i in dom(S) | seq_cst(t_i) && isWrite(t_i) && samevar(t_i, t)}) */
-       action_list_t::reverse_iterator rit;
-       for (rit = list->rbegin();(*rit) != curr;rit++)
-               ;
-       rit++;  /* Skip past curr */
-       for ( ;rit != list->rend();rit++)
-               if ((*rit)->is_write() && (*rit)->is_seqcst())
-                       return *rit;
-       return NULL;
+       return obj_last_sc_map.get(location);
 }
 
 /**
@@ -1263,7 +1263,7 @@ bool valequals(uint64_t val1, uint64_t val2, int size) {
  */
 SnapVector<ModelAction *> *  ModelExecution::build_may_read_from(ModelAction *curr)
 {
-       SnapVector<action_list_t> *thrd_lists = obj_thrd_map.get(curr->get_location());
+       SnapVector<action_list_t> *thrd_lists = obj_wr_thrd_map.get(curr->get_location());
        unsigned int i;
        ASSERT(curr->is_read());
 
@@ -1282,18 +1282,6 @@ SnapVector<ModelAction *> *  ModelExecution::build_may_read_from(ModelAction *cu
                for (rit = list->rbegin();rit != list->rend();rit++) {
                        ModelAction *act = *rit;
 
-                       /* Only consider 'write' actions */
-                       if (!act->is_write()) {
-                               if (act != curr && act->is_read() && act->happens_before(curr)) {
-                                       ModelAction *tmp = act->get_reads_from();
-                                       if (((unsigned int) id_to_int(tmp->get_tid()))==i)
-                                               act = tmp;
-                                       else
-                                               break;
-                               } else
-                                       continue;
-                       }
-
                        if (act == curr)
                                continue;
 
@@ -1550,6 +1538,9 @@ Thread * ModelExecution::take_step(ModelAction *curr)
        curr = check_current_action(curr);
        ASSERT(curr);
 
+       // model_print("poitner loc: %p, thread: %d, type: %d, order: %d, position: %s\n", curr, curr->get_tid(), curr->get_type(), curr->get_mo(), curr->get_position() );
+       model->get_history()->add_func_atomic( curr, curr_thrd->get_id() );
+
        if (curr_thrd->is_blocked() || curr_thrd->is_complete())
                scheduler->remove_thread(curr_thrd);