promise: move constructor out of header
[c11tester.git] / model.cc
index 906416cd90a1aadf8c13eb6cb48c17882d5002d9..0bccd833ff843e40fd700f8ea3f198b1a2f4e065 100644 (file)
--- a/model.cc
+++ b/model.cc
@@ -211,11 +211,14 @@ Node * ModelChecker::get_curr_node() const
  * adjacency of read/write portions of a RMW action, force THREAD_CREATE to be
  * followed by a THREAD_START, or it can enforce execution replay/backtracking.
  * The model-checker may have no preference regarding the next thread (i.e.,
- * when exploring a new execution ordering), in which case this will return
- * NULL.
- * @param curr The current ModelAction. This action might guide the choice of
- * next thread.
- * @return The next thread to run. If the model-checker has no preference, NULL.
+ * when exploring a new execution ordering), in which case we defer to the
+ * scheduler.
+ *
+ * @param curr Optional: The current ModelAction. Only used if non-NULL and it
+ * might guide the choice of next thread (i.e., THREAD_CREATE should be
+ * followed by THREAD_START, or ATOMIC_RMWR followed by ATOMIC_{RMW,RMWC})
+ * @return The next chosen thread to run, if any exist. Or else if no threads
+ * remain to be executed, return NULL.
  */
 Thread * ModelChecker::get_next_thread(ModelAction *curr)
 {
@@ -229,9 +232,12 @@ Thread * ModelChecker::get_next_thread(ModelAction *curr)
                        return curr->get_thread_operand();
        }
 
-       /* Have we completed exploring the preselected path? */
+       /*
+        * Have we completed exploring the preselected path? Then let the
+        * scheduler decide
+        */
        if (diverge == NULL)
-               return NULL;
+               return scheduler->select_next_thread();
 
        /* Else, we are trying to replay an execution */
        ModelAction *next = node_stack->get_next()->get_action();
@@ -2667,6 +2673,19 @@ bool ModelChecker::is_enabled(thread_id_t tid) const
        return scheduler->is_enabled(tid);
 }
 
+/**
+ * Switch from a model-checker context to a user-thread context. This is the
+ * complement of ModelChecker::switch_to_master and must be called from the
+ * model-checker context
+ *
+ * @param thread The user-thread to switch to
+ */
+void ModelChecker::switch_from_master(Thread *thread)
+{
+       scheduler->set_current_thread(thread);
+       Thread::swap(&system_context, thread);
+}
+
 /**
  * Switch from a user-context to the "master thread" context (a.k.a. system
  * context). This switch is made with the intention of exploring a particular
@@ -2719,10 +2738,6 @@ Thread * ModelChecker::take_step(ModelAction *curr)
                scheduler->remove_thread(curr_thrd);
 
        Thread *next_thrd = get_next_thread(curr);
-       /* Only ask for the next thread from Scheduler if we haven't chosen one
-        * already */
-       if (!next_thrd)
-               next_thrd = scheduler->next_thread(next_thrd);
 
        DEBUG("(%d, %d)\n", curr_thrd ? id_to_int(curr_thrd->get_id()) : -1,
                        next_thrd ? id_to_int(next_thrd->get_id()) : -1);
@@ -2755,8 +2770,7 @@ void ModelChecker::run()
                                thread_id_t tid = int_to_id(i);
                                Thread *thr = get_thread(tid);
                                if (!thr->is_model_thread() && !thr->is_complete() && !thr->get_pending()) {
-                                       scheduler->next_thread(thr);
-                                       Thread::swap(&system_context, thr);
+                                       switch_from_master(thr);
                                }
                        }
 
@@ -2793,5 +2807,6 @@ void ModelChecker::run()
                };
        } while (next_execution());
 
+       model_print("******* Model-checking complete: *******\n");
        print_stats();
 }