about summary refs log tree commit diff
path: root/src/rt/rust_task.cpp
diff options
context:
space:
mode:
authorEric Holk <eholk@mozilla.com>2011-06-22 15:44:47 -0700
committerGraydon Hoare <graydon@mozilla.com>2011-06-27 09:58:39 -0700
commit681c063ec02ce9fc6bdcd99b0b73f016a9839d59 (patch)
tree24f775ba4dda57790e7c8ecb5cf9abdfc4209ee8 /src/rt/rust_task.cpp
parent6367bcf4276c06d41b0d66f10711ca3b076ae547 (diff)
downloadrust-681c063ec02ce9fc6bdcd99b0b73f016a9839d59.tar.gz
rust-681c063ec02ce9fc6bdcd99b0b73f016a9839d59.zip
Conservatively serialize nearly all upcalls. Successfuly ran make check with RUST_THREADS=8, so we're probably fairly safe now. In the future we can relax the synchronization to get better performance.
Diffstat (limited to 'src/rt/rust_task.cpp')
-rw-r--r--src/rt/rust_task.cpp30
1 files changed, 19 insertions, 11 deletions
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index c26e793b979..4b300c1a524 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -131,19 +131,24 @@ void task_start_wrapper(spawn_args *a)
     int rval = 42;
     
     a->f(&rval, task, a->a3, a->a4);
-
+    
     LOG(task, task, "task exited with value %d", rval);
 
-    // TODO: the old exit glue does some magical argument copying stuff. This
-    // is probably still needed.
+    {
+        scoped_lock with(task->dom->scheduler_lock);
+        
+        // TODO: the old exit glue does some magical argument copying
+        // stuff. This is probably still needed.
+
+        // This is duplicated from upcall_exit, which is probably dead code by
+        // now.
+        LOG(task, task, "task ref_count: %d", task->ref_count);
+        A(task->dom, task->ref_count >= 0,
+          "Task ref_count should not be negative on exit!");
+        task->die();
+        task->notify_tasks_waiting_to_join();
 
-    // This is duplicated from upcall_exit, which is probably dead code by
-    // now.
-    LOG(task, task, "task ref_count: %d", task->ref_count);
-    A(task->dom, task->ref_count >= 0,
-      "Task ref_count should not be negative on exit!");
-    task->die();
-    task->notify_tasks_waiting_to_join();
+    }
     task->yield(1);
 }
 
@@ -154,6 +159,9 @@ rust_task::start(uintptr_t spawnee_fn,
     LOGPTR(dom, "from spawnee", spawnee_fn);
 
     I(dom, stk->data != NULL);
+    I(dom, !dom->scheduler_lock.lock_held_by_current_thread());
+    
+    scoped_lock with(dom->scheduler_lock);
 
     char *sp = (char *)rust_sp;
 
@@ -405,7 +413,7 @@ rust_task::free(void *p, bool is_gc)
 
 void
 rust_task::transition(rust_task_list *src, rust_task_list *dst) {
-    scoped_lock sync(dom->scheduler_lock);
+    I(dom, dom->scheduler_lock.lock_held_by_current_thread());
     DLOG(dom, task,
          "task %s " PTR " state change '%s' -> '%s' while in '%s'",
          name, (uintptr_t)this, src->name, dst->name, state->name);