model: convert while-loops to for-loops
[model-checker.git] / model.cc
index 70732868bd3114825f3ccc8c2db51bb57e339a92..a5ac71316e2f2dc69e469d9d99a6ffee941a072e 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();
@@ -539,7 +545,7 @@ bool ModelChecker::next_execution()
        return true;
 }
 
-ModelAction * ModelChecker::get_last_conflict(ModelAction *act)
+ModelAction * ModelChecker::get_last_conflict(ModelAction *act) const
 {
        switch (act->get_type()) {
        case ATOMIC_FENCE:
@@ -1864,7 +1870,7 @@ bool ModelChecker::release_seq_heads(const ModelAction *rf,
        if (mo_graph->checkForCycles())
                return false;
 
-       while (rf) {
+       for ( ; rf != NULL; rf = rf->get_reads_from()) {
                ASSERT(rf->is_write());
 
                if (rf->is_release())
@@ -1884,8 +1890,6 @@ bool ModelChecker::release_seq_heads(const ModelAction *rf,
                /* acq_rel RMW is a sufficient stopping condition */
                if (rf->is_acquire() && rf->is_release())
                        return true; /* complete */
-
-               rf = rf->get_reads_from();
        };
        if (!rf) {
                /* read from future: need to settle this later */
@@ -2511,7 +2515,7 @@ void ModelChecker::build_reads_from_past(ModelAction *curr)
 
 bool ModelChecker::sleep_can_read_from(ModelAction *curr, const ModelAction *write)
 {
-       while (true) {
+       for ( ; write != NULL; write = write->get_reads_from()) {
                /* UNINIT actions don't have a Node, and they never sleep */
                if (write->is_uninitialized())
                        return true;
@@ -2520,13 +2524,10 @@ bool ModelChecker::sleep_can_read_from(ModelAction *curr, const ModelAction *wri
                bool thread_sleep = prevnode->enabled_status(curr->get_tid()) == THREAD_SLEEP_SET;
                if (write->is_release() && thread_sleep)
                        return true;
-               if (!write->is_rmw()) {
+               if (!write->is_rmw())
                        return false;
-               }
-               if (write->get_reads_from() == NULL)
-                       return true;
-               write = write->get_reads_from();
        }
+       return true;
 }
 
 /**
@@ -2732,10 +2733,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->select_next_thread();
 
        DEBUG("(%d, %d)\n", curr_thrd ? id_to_int(curr_thrd->get_id()) : -1,
                        next_thrd ? id_to_int(next_thrd->get_id()) : -1);
@@ -2805,5 +2802,6 @@ void ModelChecker::run()
                };
        } while (next_execution());
 
+       model_print("******* Model-checking complete: *******\n");
        print_stats();
 }