promise: rename increment_threads() -> eliminate_thread()
[model-checker.git] / model.cc
index f2d40fe6f724022ee2b50c783df310ce0b47ff99..e46d36d76c3d3ede34cca70c32d562be3a327b0e 100644 (file)
--- a/model.cc
+++ b/model.cc
@@ -614,7 +614,7 @@ void ModelChecker::set_backtracking(ModelAction *act)
        Node *node = prev->get_node()->get_parent();
 
        int low_tid, high_tid;
-       if (node->is_enabled(t)) {
+       if (node->enabled_status(t->get_id()) == THREAD_ENABLED) {
                low_tid = id_to_int(act->get_tid());
                high_tid = low_tid + 1;
        } else {
@@ -730,15 +730,15 @@ bool ModelChecker::process_read(ModelAction *curr, bool second_part_of_rmw)
 
                        read_from(curr, reads_from);
                        mo_graph->commitChanges();
-                       mo_check_promises(curr->get_tid(), reads_from);
+                       mo_check_promises(curr->get_tid(), reads_from, NULL);
 
                        updated |= r_status;
                } else if (!second_part_of_rmw) {
                        /* Read from future value */
-                       value = curr->get_node()->get_future_value();
-                       modelclock_t expiration = curr->get_node()->get_future_value_expiration();
+                       struct future_value fv = curr->get_node()->get_future_value();
+                       value = fv.value;
                        curr->set_read_from(NULL);
-                       Promise *valuepromise = new Promise(curr, value, expiration);
+                       Promise *valuepromise = new Promise(curr, fv);
                        promises->push_back(valuepromise);
                }
                get_thread(curr)->set_return_value(value);
@@ -857,7 +857,7 @@ void ModelChecker::add_future_value(const ModelAction *writer, ModelAction *read
 {
        /* Do more ambitious checks now that mo is more complete */
        if (mo_may_allow(writer, reader) &&
-                       reader->get_node()->add_future_value(writer->get_value(),
+                       reader->get_node()->add_future_value(writer,
                                writer->get_seq_number() + params.maxfuturedelay))
                set_latest_backtrack(reader);
 }
@@ -881,7 +881,7 @@ bool ModelChecker::process_write(ModelAction *curr)
        }
 
        mo_graph->commitChanges();
-       mo_check_promises(curr->get_tid(), curr);
+       mo_check_promises(curr->get_tid(), curr, NULL);
 
        get_thread(curr)->set_return_value(VALUE_NONE);
        return updated_mod_order || updated_promises;
@@ -1361,7 +1361,7 @@ void ModelChecker::print_infeasibility(const char *prefix) const
        if (promises_expired())
                ptr += sprintf(ptr, "[promise expired]");
        if (promises->size() != 0)
-               ptr += sprintf(ptr, "[unrevolved promise]");
+               ptr += sprintf(ptr, "[unresolved promise]");
        if (ptr != buf)
                model_print("%s: %s\n", prefix ? prefix : "Infeasible", buf);
 }
@@ -2310,7 +2310,7 @@ ClockVector * ModelChecker::get_cv(thread_id_t tid) const
 bool ModelChecker::resolve_promises(ModelAction *write)
 {
        bool resolved = false;
-       std::vector< thread_id_t, ModelAlloc<thread_id_t> > threads_to_check;
+       std::vector< ModelAction *, ModelAlloc<ModelAction *> > actions_to_check;
 
        for (unsigned int i = 0, promise_index = 0; promise_index < promises->size(); i++) {
                Promise *promise = (*promises)[promise_index];
@@ -2331,7 +2331,7 @@ bool ModelChecker::resolve_promises(ModelAction *write)
                        delete(promise);
 
                        promises->erase(promises->begin() + promise_index);
-                       threads_to_check.push_back(read->get_tid());
+                       actions_to_check.push_back(read);
 
                        resolved = true;
                } else
@@ -2341,8 +2341,10 @@ bool ModelChecker::resolve_promises(ModelAction *write)
        //Check whether reading these writes has made threads unable to
        //resolve promises
 
-       for (unsigned int i = 0; i < threads_to_check.size(); i++)
-               mo_check_promises(threads_to_check[i], write);
+       for (unsigned int i = 0; i < actions_to_check.size(); i++) {
+               ModelAction *read=actions_to_check[i];
+               mo_check_promises(read->get_tid(), write, read);
+       }
 
        return resolved;
 }
@@ -2377,7 +2379,7 @@ void ModelChecker::check_promises(thread_id_t tid, ClockVector *old_cv, ClockVec
                const ModelAction *act = promise->get_action();
                if ((old_cv == NULL || !old_cv->synchronized_since(act)) &&
                                merge_cv->synchronized_since(act)) {
-                       if (promise->increment_threads(tid)) {
+                       if (promise->eliminate_thread(tid)) {
                                //Promise has failed
                                priv->failed_promise = true;
                                return;
@@ -2421,8 +2423,9 @@ void ModelChecker::check_promises_thread_disabled() {
  *     write, or actually did the model action write.
  *
  *     @param write The ModelAction representing the relevant write.
+ *  @param read  The ModelAction that reads a promised write, or NULL otherwise.
  */
-void ModelChecker::mo_check_promises(thread_id_t tid, const ModelAction *write)
+void ModelChecker::mo_check_promises(thread_id_t tid, const ModelAction *write, const ModelAction *read)
 {
        void *location = write->get_location();
        for (unsigned int i = 0; i < promises->size(); i++) {
@@ -2435,20 +2438,23 @@ void ModelChecker::mo_check_promises(thread_id_t tid, const ModelAction *write)
 
                //same thread as the promise
                if (act->get_tid() == tid) {
-
-                       //do we have a pwrite for the promise, if not, set it
-                       if (promise->get_write() == NULL) {
-                               promise->set_write(write);
-                               //The pwrite cannot happen before the promise
-                               if (write->happens_before(act) && (write != act)) {
+                       //make sure that the reader of this write happens after the promise
+                       if (( read == NULL ) || ( promise->get_action() -> happens_before(read))) {
+                               //do we have a pwrite for the promise, if not, set it
+                               if (promise->get_write() == NULL) {
+                                       promise->set_write(write);
+                                       //The pwrite cannot happen before the promise
+                                       if (write->happens_before(act) && (write != act)) {
+                                               priv->failed_promise = true;
+                                               return;
+                                       }
+                               }
+                       
+                               if (mo_graph->checkPromise(write, promise)) {
                                        priv->failed_promise = true;
                                        return;
                                }
                        }
-                       if (mo_graph->checkPromise(write, promise)) {
-                               priv->failed_promise = true;
-                               return;
-                       }
                }
 
                //Don't do any lookups twice for the same thread
@@ -2456,7 +2462,7 @@ void ModelChecker::mo_check_promises(thread_id_t tid, const ModelAction *write)
                        continue;
 
                if (promise->get_write() && mo_graph->checkReachable(promise->get_write(), write)) {
-                       if (promise->increment_threads(tid)) {
+                       if (promise->eliminate_thread(tid)) {
                                priv->failed_promise = true;
                                return;
                        }
@@ -2576,13 +2582,11 @@ ModelAction * ModelChecker::new_uninitialized_action(void *location) const
        return act;
 }
 
-static void print_list(action_list_t *list, int exec_num = -1)
+static void print_list(action_list_t *list)
 {
        action_list_t::iterator it;
 
        model_print("---------------------------------------------------------------------\n");
-       if (exec_num >= 0)
-               model_print("Execution %d:\n", exec_num);
 
        unsigned int hash = 0;
 
@@ -2635,9 +2639,12 @@ void ModelChecker::print_summary() const
        dumpGraph(buffername);
 #endif
 
-       if (!isfeasibleprefix())
-               print_infeasibility("INFEASIBLE EXECUTION");
-       print_list(action_trace, stats.num_total);
+       model_print("Execution %d:", stats.num_total);
+       if (isfeasibleprefix())
+               model_print("\n");
+       else
+               print_infeasibility(" INFEASIBLE");
+       print_list(action_trace);
        model_print("\n");
 }