action: add get_mutex()
[model-checker.git] / model.cc
index e016ae49bc9cb212638cbff3ae59ea22b7faa8f6..7741760025162b786b48c903aaf86937bb4cb0f1 100644 (file)
--- a/model.cc
+++ b/model.cc
@@ -853,7 +853,6 @@ ModelAction * ModelChecker::get_next_backtrack()
 bool ModelChecker::process_read(ModelAction *curr)
 {
        Node *node = curr->get_node();
-       uint64_t value = VALUE_NONE;
        while (true) {
                bool updated = false;
                switch (node->get_read_from_status()) {
@@ -874,7 +873,6 @@ bool ModelChecker::process_read(ModelAction *curr)
                        }
 
                        updated = r_modification_order(curr, rf);
-                       value = rf->get_value();
                        read_from(curr, rf);
                        mo_graph->commitChanges();
                        mo_check_promises(curr, true);
@@ -882,8 +880,8 @@ bool ModelChecker::process_read(ModelAction *curr)
                }
                case READ_FROM_PROMISE: {
                        Promise *promise = curr->get_node()->get_read_from_promise();
-                       promise->add_reader(curr);
-                       value = promise->get_value();
+                       if (promise->add_reader(curr))
+                               priv->failed_promise = true;
                        curr->set_read_from_promise(promise);
                        mo_graph->startChanges();
                        if (!check_recency(curr, promise))
@@ -896,7 +894,6 @@ bool ModelChecker::process_read(ModelAction *curr)
                        /* Read from future value */
                        struct future_value fv = node->get_future_value();
                        Promise *promise = new Promise(curr, fv);
-                       value = fv.value;
                        curr->set_read_from_promise(promise);
                        promises->push_back(promise);
                        mo_graph->startChanges();
@@ -907,7 +904,7 @@ bool ModelChecker::process_read(ModelAction *curr)
                default:
                        ASSERT(false);
                }
-               get_thread(curr)->set_return_value(value);
+               get_thread(curr)->set_return_value(curr->get_return_value());
                return updated;
        }
 }
@@ -930,16 +927,11 @@ bool ModelChecker::process_read(ModelAction *curr)
  */
 bool ModelChecker::process_mutex(ModelAction *curr)
 {
-       std::mutex *mutex = NULL;
+       std::mutex *mutex = curr->get_mutex();
        struct std::mutex_state *state = NULL;
 
-       if (curr->is_trylock() || curr->is_lock() || curr->is_unlock()) {
-               mutex = (std::mutex *)curr->get_location();
-               state = mutex->get_state();
-       } else if (curr->is_wait()) {
-               mutex = (std::mutex *)curr->get_value();
+       if (mutex)
                state = mutex->get_state();
-       }
 
        switch (curr->get_type()) {
        case ATOMIC_TRYLOCK: {
@@ -2524,11 +2516,19 @@ bool ModelChecker::resolve_promise(ModelAction *write, unsigned int promise_idx)
                priv->failed_promise = true;
 
        promises->erase(promises->begin() + promise_idx);
-       delete promise;
+       /**
+        * @todo  It is possible to end up in an inconsistent state, where a
+        * "resolved" promise may still be referenced if
+        * CycleGraph::resolvePromise() failed, so don't delete 'promise'.
+        *
+        * Note that the inconsistency only matters when dumping mo_graph to
+        * file.
+        *
+        * delete promise;
+        */
 
        //Check whether reading these writes has made threads unable to
        //resolve promises
-
        for (unsigned int i = 0; i < actions_to_check.size(); i++) {
                ModelAction *read = actions_to_check[i];
                mo_check_promises(read, true);