about summary refs log tree commit diff
path: root/src/rt/rust_task.cpp
diff options
context:
space:
mode:
authorBen Blum <bblum@andrew.cmu.edu>2012-07-24 15:27:45 -0400
committerBen Blum <bblum@andrew.cmu.edu>2012-07-24 15:28:35 -0400
commitae094a7adc8e0f166ea2b137c2940afdb9396bcd (patch)
tree49d21e0d95ea214b2d3e161d2afc9a00d473032f /src/rt/rust_task.cpp
parent9103e439091fbd4e5ec7e561f007172342065340 (diff)
downloadrust-ae094a7adc8e0f166ea2b137c2940afdb9396bcd.tar.gz
rust-ae094a7adc8e0f166ea2b137c2940afdb9396bcd.zip
Add 'do atomically { .. }' for exclusives
Diffstat (limited to 'src/rt/rust_task.cpp')
-rw-r--r--src/rt/rust_task.cpp21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index c28e3350bf2..e9879525ee7 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -39,6 +39,7 @@ rust_task::rust_task(rust_sched_loop *sched_loop, rust_task_state state,
     killed(false),
     reentered_rust_stack(false),
     disallow_kill(0),
+    disallow_yield(0),
     c_stack(NULL),
     next_c_sp(0),
     next_rust_sp(0)
@@ -234,9 +235,18 @@ rust_task::must_fail_from_being_killed_inner() {
     return killed && !reentered_rust_stack && disallow_kill == 0;
 }
 
+void rust_task_yield_fail(rust_task *task) {
+    LOG_ERR(task, task, "task %" PRIxPTR " yielded in an atomic section",
+            task);
+    task->fail();
+}
+
 // Only run this on the rust stack
 void
 rust_task::yield(bool *killed) {
+    if (disallow_yield > 0) {
+        call_on_c_stack(this, (void *)rust_task_yield_fail);
+    }
     // FIXME (#2875): clean this up
     if (must_fail_from_being_killed()) {
         {
@@ -672,6 +682,17 @@ rust_task::allow_kill() {
     disallow_kill--;
 }
 
+void rust_task::inhibit_yield() {
+    scoped_lock with(lifecycle_lock);
+    disallow_yield++;
+}
+
+void rust_task::allow_yield() {
+    scoped_lock with(lifecycle_lock);
+    assert(disallow_yield > 0 && "Illegal allow_yield(): already yieldable!");
+    disallow_yield--;
+}
+
 void *
 rust_task::wait_event(bool *killed) {
     scoped_lock with(lifecycle_lock);