diff options
| author | Brian Anderson <banderson@mozilla.com> | 2012-03-29 17:07:50 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2012-03-31 19:51:29 -0700 |
| commit | 771c1be6a64225d416ad99a860f1c8d34ce3a18b (patch) | |
| tree | 707af1e6c74a8434f9500f040dade8e9a1fb83b3 /src | |
| parent | 243790836a40fd3f23d8bd16d8f45430d19aae61 (diff) | |
| download | rust-771c1be6a64225d416ad99a860f1c8d34ce3a18b.tar.gz rust-771c1be6a64225d416ad99a860f1c8d34ce3a18b.zip | |
rt: Refactor the scheduler loop so that it can be driven from without
Diffstat (limited to 'src')
| -rw-r--r-- | src/rt/rust_sched_loop.cpp | 61 | ||||
| -rw-r--r-- | src/rt/rust_sched_loop.h | 12 |
2 files changed, 53 insertions, 20 deletions
diff --git a/src/rt/rust_sched_loop.cpp b/src/rt/rust_sched_loop.cpp index efc1883ecae..3ddf23cd9a1 100644 --- a/src/rt/rust_sched_loop.cpp +++ b/src/rt/rust_sched_loop.cpp @@ -182,6 +182,7 @@ rust_sched_loop::log_state() { } } } + /** * Starts the main scheduler loop which performs task scheduling for this * domain. @@ -191,11 +192,29 @@ rust_sched_loop::log_state() { */ void rust_sched_loop::start_main_loop() { + DLOG(this, dom, "started domain loop %d", id); + + rust_sched_loop_state state = sched_loop_state_keep_going; + while (state != sched_loop_state_exit) { + state = run_single_turn(); + + scoped_lock with(lock); + if (!should_exit && running_tasks.length() == 0) { + lock.wait(); + } + DLOG(this, task, + "scheduler %d resuming ...", id); + } +} + +rust_sched_loop_state +rust_sched_loop::run_single_turn() { lock.lock(); - DLOG(this, dom, "started domain loop %d", id); + if (!should_exit) { + A(this, dead_task == NULL, + "Tasks should only die after running"); - while (!should_exit) { DLOG(this, dom, "worker %d, number_of_live_tasks = %d", id, number_of_live_tasks()); @@ -206,12 +225,9 @@ rust_sched_loop::start_main_loop() { DLOG(this, task, "all tasks are blocked, scheduler id %d yielding ...", id); - lock.wait(); - A(this, dead_task == NULL, - "Tasks should only die after running"); - DLOG(this, task, - "scheduler %d resuming ...", id); - continue; + + lock.unlock(); + return sched_loop_state_block; } I(this, scheduled_task->running()); @@ -239,23 +255,27 @@ rust_sched_loop::start_main_loop() { id); reap_dead_tasks(); - } - A(this, running_tasks.is_empty(), "Should have no running tasks"); - A(this, blocked_tasks.is_empty(), "Should have no blocked tasks"); - A(this, dead_task == NULL, "Should have no dead tasks"); + lock.unlock(); + return sched_loop_state_keep_going; + } else { + A(this, running_tasks.is_empty(), "Should have no running tasks"); + A(this, blocked_tasks.is_empty(), "Should have no blocked tasks"); + A(this, dead_task == NULL, "Should have no dead tasks"); - DLOG(this, dom, "finished main-loop %d", id); + DLOG(this, dom, "finished main-loop %d", id); - lock.unlock(); + lock.unlock(); - I(this, !extra_c_stack); - if (cached_c_stack) { - destroy_stack(kernel->region(), cached_c_stack); - cached_c_stack = NULL; - } + I(this, !extra_c_stack); + if (cached_c_stack) { + destroy_stack(kernel->region(), cached_c_stack); + cached_c_stack = NULL; + } - sched->release_task_thread(); + sched->release_task_thread(); + return sched_loop_state_exit; + } } rust_task * @@ -360,6 +380,7 @@ rust_sched_loop::place_task_in_tls(rust_task *task) { void rust_sched_loop::exit() { scoped_lock with(lock); + DLOG(this, dom, "Requesting exit for thread %d", id); should_exit = true; lock.signal(); } diff --git a/src/rt/rust_sched_loop.h b/src/rt/rust_sched_loop.h index 0b221e3c6f4..c21dc9b0c34 100644 --- a/src/rt/rust_sched_loop.h +++ b/src/rt/rust_sched_loop.h @@ -12,6 +12,16 @@ enum rust_task_state { task_state_dead }; +/* +The result of every turn of the scheduler loop. Instructs the loop +driver how to proceed. + */ +enum rust_sched_loop_state { + sched_loop_state_keep_going, + sched_loop_state_block, + sched_loop_state_exit +}; + typedef indexed_list<rust_task> rust_task_list; struct rust_sched_loop @@ -49,6 +59,8 @@ private: rust_task_list *state_list(rust_task_state state); const char *state_name(rust_task_state state); + rust_sched_loop_state run_single_turn(); + public: rust_kernel *kernel; rust_scheduler *sched; |
