rt: Run a single-threaded scheduler on the main thread
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user