From b3786419ac8bbc47f33038b1d6c595a70490e634 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 15 Feb 2013 15:33:11 -0800 Subject: [PATCH] schedule: split Scheduler::next_thread() into separate functions next_thread() is basically overloaded to perform two different functions, depending on the parameters. In one case, a caller might pass a NULL thread, which meant that Scheduler is free to select its own next thread. In another case, a caller will pass a non-NULL thread, which meant that the caller is simply informing the Scheduler of the next thread to execute (i.e., which one is "currently running"). These separate functionalities are now separate functions: Scheduler::select_next_thread() Scheduler::set_current_thread(Thread *) --- model.cc | 4 +-- schedule.cc | 76 +++++++++++++++++++++++++++-------------------------- schedule.h | 3 ++- 3 files changed, 43 insertions(+), 40 deletions(-) diff --git a/model.cc b/model.cc index b09a810..7073286 100644 --- a/model.cc +++ b/model.cc @@ -2676,7 +2676,7 @@ bool ModelChecker::is_enabled(thread_id_t tid) const */ void ModelChecker::switch_from_master(Thread *thread) { - scheduler->next_thread(thread); + scheduler->set_current_thread(thread); Thread::swap(&system_context, thread); } @@ -2735,7 +2735,7 @@ Thread * ModelChecker::take_step(ModelAction *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); + 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); diff --git a/schedule.cc b/schedule.cc index e75e7ec..d49e62b 100644 --- a/schedule.cc +++ b/schedule.cc @@ -177,56 +177,58 @@ void Scheduler::wake(Thread *t) } /** - * Select a Thread. This implementation defaults to round-robin, if a - * thread is not already provided. + * Select a Thread to run and set it as the 'current' Thread. This + * implementation defaults to round-robin * - * @param t Thread to run, if chosen by an external entity (e.g., - * ModelChecker). May be NULL to indicate no external choice. * @return The next Thread to run */ -Thread * Scheduler::next_thread(Thread *t) +Thread * Scheduler::select_next_thread() { - if (t == NULL) { - int old_curr_thread = curr_thread_index; - bool have_enabled_thread_with_priority = false; - Node *n = model->get_curr_node(); + int old_curr_thread = curr_thread_index; + bool have_enabled_thread_with_priority = false; + Node *n = model->get_curr_node(); - for (int i = 0; i < enabled_len; i++) { - thread_id_t tid = int_to_id(i); - if (n->has_priority(tid)) { - DEBUG("Node (tid %d) has priority\n", i); - //Have a thread with priority - if (enabled[i] != THREAD_DISABLED) - have_enabled_thread_with_priority = true; - } + for (int i = 0; i < enabled_len; i++) { + thread_id_t tid = int_to_id(i); + if (n->has_priority(tid)) { + DEBUG("Node (tid %d) has priority\n", i); + //Have a thread with priority + if (enabled[i] != THREAD_DISABLED) + have_enabled_thread_with_priority = true; } + } - while (true) { - curr_thread_index = (curr_thread_index + 1) % enabled_len; - thread_id_t curr_tid = int_to_id(curr_thread_index); - if (enabled[curr_thread_index] == THREAD_ENABLED && - (!have_enabled_thread_with_priority || n->has_priority(curr_tid))) { - t = model->get_thread(curr_tid); - break; - } - if (curr_thread_index == old_curr_thread) { - if (DBG_ENABLED()) - print(); - return NULL; - } + while (true) { + curr_thread_index = (curr_thread_index + 1) % enabled_len; + thread_id_t curr_tid = int_to_id(curr_thread_index); + if (enabled[curr_thread_index] == THREAD_ENABLED && + (!have_enabled_thread_with_priority || n->has_priority(curr_tid))) { + current = model->get_thread(curr_tid); + if (DBG_ENABLED()) + print(); + return current; + } + if (curr_thread_index == old_curr_thread) { + if (DBG_ENABLED()) + print(); + return NULL; } - } else if (t->is_model_thread()) { - /* model-checker threads never run */ - ASSERT(false); - t = NULL; - } else { - curr_thread_index = id_to_int(t->get_id()); } +} + +/** + * @brief Set the current "running" Thread + * @param t Thread to run + */ +void Scheduler::set_current_thread(Thread *t) +{ + ASSERT(t && !t->is_model_thread()); + + curr_thread_index = id_to_int(t->get_id()); current = t; if (DBG_ENABLED()) print(); - return t; } /** diff --git a/schedule.h b/schedule.h index 1031232..121da08 100644 --- a/schedule.h +++ b/schedule.h @@ -27,7 +27,8 @@ public: void remove_thread(Thread *t); void sleep(Thread *t); void wake(Thread *t); - Thread * next_thread(Thread *t); + Thread * select_next_thread(); + void set_current_thread(Thread *t); Thread * get_current_thread() const; void print() const; enabled_type_t * get_enabled_array() const { return enabled; }; -- 2.34.1