about summary refs log tree commit diff
path: root/src/rt/rust_kernel.cpp
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-02-04 14:54:10 -0800
committerBrian Anderson <banderson@mozilla.com>2012-02-08 15:33:40 -0800
commitf39e64d56ab4929be5985d4a64020d2223706d96 (patch)
tree0c3c810c87372216986d47eadd9476a0d9150117 /src/rt/rust_kernel.cpp
parent6eafe5d772131c644a40ae1013a6016dcba037c4 (diff)
downloadrust-f39e64d56ab4929be5985d4a64020d2223706d96.tar.gz
rust-f39e64d56ab4929be5985d4a64020d2223706d96.zip
rt: Change the scheme used for terminating the kernel
Instead of joining on the scheduler threads, instead keep a count of active
schedulers. When there are no more schedulers raise a signal for the main
thread to continue.

This will be required once schedulers can be added and removed from the
running kernel.
Diffstat (limited to 'src/rt/rust_kernel.cpp')
-rw-r--r--src/rt/rust_kernel.cpp30
1 files changed, 25 insertions, 5 deletions
diff --git a/src/rt/rust_kernel.cpp b/src/rt/rust_kernel.cpp
index f8e7e41971e..004e42a8138 100644
--- a/src/rt/rust_kernel.cpp
+++ b/src/rt/rust_kernel.cpp
@@ -18,6 +18,11 @@ rust_kernel::rust_kernel(rust_srv *srv, size_t num_threads) :
 {
     sched = new (this, "rust_scheduler")
         rust_scheduler(this, srv, num_threads);
+    live_schedulers = 1;
+}
+
+rust_kernel::~rust_kernel() {
+    delete sched;
 }
 
 void
@@ -41,10 +46,6 @@ rust_kernel::fatal(char const *fmt, ...) {
     va_end(args);
 }
 
-rust_kernel::~rust_kernel() {
-    delete sched;
-}
-
 void *
 rust_kernel::malloc(size_t size, const char *tag) {
     return _region.malloc(size, tag);
@@ -61,8 +62,16 @@ void rust_kernel::free(void *mem) {
 
 int rust_kernel::start_schedulers()
 {
+    I(this, !sched_lock.lock_held_by_current_thread());
     sched->start_task_threads();
-    return rval;
+    {
+        scoped_lock with(sched_lock);
+        // Schedulers could possibly have already exited
+        if (live_schedulers != 0) {
+            sched_lock.wait();
+        }
+        return rval;
+    }
 }
 
 rust_scheduler *
@@ -71,6 +80,17 @@ rust_kernel::get_default_scheduler() {
 }
 
 void
+rust_kernel::release_scheduler() {
+    I(this, !sched_lock.lock_held_by_current_thread());
+    scoped_lock with(sched_lock);
+    --live_schedulers;
+    if (live_schedulers == 0) {
+        // We're all done. Tell the main thread to continue
+        sched_lock.signal();
+    }
+}
+
+void
 rust_kernel::fail() {
     // FIXME: On windows we're getting "Application has requested the
     // Runtime to terminate it in an unusual way" when trying to shutdown