change cds checker to accomdate llvm pass
[c11tester.git] / schedule.cc
index 136f4622fb3ff1d16aa59a8b9d41a6c62df2f930..2a02e307cf69f3a6a35058254bcafd046300645e 100644 (file)
@@ -6,6 +6,7 @@
 #include "common.h"
 #include "model.h"
 #include "nodestack.h"
+#include "execution.h"
 
 /**
  * Format an "enabled_type_t" for printing
@@ -35,6 +36,7 @@ void enabled_type_to_string(enabled_type_t e, char *str)
 
 /** Constructor */
 Scheduler::Scheduler() :
+       execution(NULL),
        enabled(NULL),
        enabled_len(0),
        curr_thread_index(0),
@@ -42,6 +44,15 @@ Scheduler::Scheduler() :
 {
 }
 
+/**
+ * @brief Register the ModelExecution engine
+ * @param execution The ModelExecution which is controlling execution
+ */
+void Scheduler::register_engine(ModelExecution *execution)
+{
+       this->execution = execution;
+}
+
 void Scheduler::set_enabled(Thread *t, enabled_type_t enabled_status) {
        int threadid = id_to_int(t->get_id());
        if (threadid >= enabled_len) {
@@ -56,7 +67,7 @@ void Scheduler::set_enabled(Thread *t, enabled_type_t enabled_status) {
        }
        enabled[threadid] = enabled_status;
        if (enabled_status == THREAD_DISABLED)
-               model->check_promises_thread_disabled();
+               execution->check_promises_thread_disabled();
 }
 
 /**
@@ -203,8 +214,6 @@ void Scheduler::wake(Thread *t)
  */
 Thread * Scheduler::select_next_thread(Node *n)
 {
-       int old_curr_thread = curr_thread_index;
-
        bool have_enabled_thread_with_priority = false;
        if (model->params.fairwindow != 0) {
                for (int i = 0; i < enabled_len; i++) {
@@ -217,8 +226,17 @@ Thread * Scheduler::select_next_thread(Node *n)
                }
        }       
 
-       for (int i = 0; i < enabled_len; i++) {
-               curr_thread_index = (old_curr_thread + i + 1) % enabled_len;
+       int avail_threads = enabled_len;        // number of available threads
+       int thread_list[enabled_len];   // keep a list of threads to select from
+       for (int i = 0; i< enabled_len; i++){
+               thread_list[i] = i;
+       }
+
+       while (avail_threads > 0) {
+               int random_index = rand() % avail_threads;
+               curr_thread_index = thread_list[random_index];  // randomly select a thread from available threads
+               
+               // curr_thread_index = (curr_thread_index + i + 1) % enabled_len;
                thread_id_t curr_tid = int_to_id(curr_thread_index);
                if (model->params.yieldon) {
                        bool bad_thread = false;
@@ -229,13 +247,20 @@ Thread * Scheduler::select_next_thread(Node *n)
                                        break;
                                }
                        }
-                       if (bad_thread)
+                       if (bad_thread) {
+                               thread_list[random_index] = thread_list[avail_threads - 1]; // remove this threads from available threads 
+                               avail_threads--;
+
                                continue;
+                       }
                }
                
                if (enabled[curr_thread_index] == THREAD_ENABLED &&
                                (!have_enabled_thread_with_priority || n->has_priority(curr_tid))) {
                        return model->get_thread(curr_tid);
+               } else {        // remove this threads from available threads 
+                       thread_list[random_index] = thread_list[avail_threads - 1]; 
+                       avail_threads--;
                }
        }