diff options
Diffstat (limited to 'src/rt/rust_kernel.cpp')
| -rw-r--r-- | src/rt/rust_kernel.cpp | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/src/rt/rust_kernel.cpp b/src/rt/rust_kernel.cpp index 5062e4de3c3..d65837a47d6 100644 --- a/src/rt/rust_kernel.cpp +++ b/src/rt/rust_kernel.cpp @@ -1,6 +1,7 @@ #include "rust_internal.h" #include "rust_util.h" #include "rust_scheduler.h" +#include "rust_sched_launcher.h" #include <vector> @@ -18,8 +19,15 @@ rust_kernel::rust_kernel(rust_srv *srv) : rval(0), max_sched_id(0), sched_reaper(this), + osmain_driver(NULL), env(srv->env) { + // Create the single threaded scheduler that will run on the platform's + // main thread + rust_manual_sched_launcher_factory launchfac; + osmain_scheduler = create_scheduler(&launchfac, 1, false); + osmain_driver = launchfac.get_driver(); + sched_reaper.start(); } void @@ -59,24 +67,25 @@ void rust_kernel::free(void *mem) { rust_sched_id rust_kernel::create_scheduler(size_t num_threads) { + rust_thread_sched_launcher_factory launchfac; + return create_scheduler(&launchfac, num_threads, true); +} + +rust_sched_id +rust_kernel::create_scheduler(rust_sched_launcher_factory *launchfac, + size_t num_threads, bool allow_exit) { rust_sched_id id; rust_scheduler *sched; { scoped_lock with(sched_lock); - // If this is the first scheduler then we need to launch - // the scheduler reaper. - bool start_reaper = sched_table.empty(); id = max_sched_id++; K(srv, id != INTPTR_MAX, "Hit the maximum scheduler id"); sched = new (this, "rust_scheduler") - rust_scheduler(this, srv, num_threads, id, true); + rust_scheduler(this, srv, num_threads, id, allow_exit, launchfac); bool is_new = sched_table .insert(std::pair<rust_sched_id, rust_scheduler*>(id, sched)).second; A(this, is_new, "Reusing a sched id?"); - if (start_reaper) { - sched_reaper.start(); - } } sched->start_task_threads(); return id; @@ -123,6 +132,15 @@ rust_kernel::wait_for_schedulers() sched_table.erase(iter); sched->join_task_threads(); delete sched; + if (sched_table.size() == 1) { + KLOG_("Allowing osmain scheduler to exit"); + sched_lock.unlock(); + // It's only the osmain scheduler left. Tell it to exit + rust_scheduler *sched = get_scheduler_by_id(osmain_scheduler); + assert(sched != NULL); + sched_lock.lock(); + sched->allow_exit(); + } } if (!sched_table.empty()) { sched_lock.wait(); @@ -130,9 +148,12 @@ rust_kernel::wait_for_schedulers() } } -/* Called on the main thread to wait for the kernel to exit */ +/* Called on the main thread to run the osmain scheduler to completion, + then wait for schedulers to exit */ int -rust_kernel::wait_for_exit() { +rust_kernel::run() { + assert(osmain_driver != NULL); + osmain_driver->start_main_loop(); sched_reaper.join(); return rval; } |
