about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-11-18 14:45:48 -0800
committerBrian Anderson <banderson@mozilla.com>2011-11-18 14:45:48 -0800
commit792068d871f2a8f7184a6f109db1d65c73bf63da (patch)
tree4250b4b01f7837ef34f05d9be8c53e89533f82f6
parent0f339b481a8ae255f012f2218c8f5b5fc3d451ce (diff)
downloadrust-792068d871f2a8f7184a6f109db1d65c73bf63da.tar.gz
rust-792068d871f2a8f7184a6f109db1d65c73bf63da.zip
rt: Remove unblock call from rust_task::yield
-rw-r--r--src/lib/comm.rs20
-rw-r--r--src/rt/rust_builtin.cpp13
-rw-r--r--src/rt/rust_task.cpp6
3 files changed, 27 insertions, 12 deletions
diff --git a/src/lib/comm.rs b/src/lib/comm.rs
index eb96ed546b1..9acee18c8cc 100644
--- a/src/lib/comm.rs
+++ b/src/lib/comm.rs
@@ -49,7 +49,8 @@ native mod rustrt {
     fn get_port_id(po: *rust_port) -> port_id;
     fn rust_port_size(po: *rust_port) -> ctypes::size_t;
     fn port_recv(dptr: *uint, po: *rust_port,
-                 yield: *ctypes::uintptr_t);
+                 yield: *ctypes::uintptr_t,
+                 killed: *ctypes::uintptr_t);
 }
 
 #[abi = "rust-intrinsic"]
@@ -152,13 +153,18 @@ fn recv_<send T>(p: *rustrt::rust_port) -> T {
     // that will grab the value of the return pointer, then call this
     // function, which we will then use to call the runtime.
     fn recv(dptr: *uint, port: *rustrt::rust_port,
-                    yield: *ctypes::uintptr_t) unsafe {
-        rustrt::port_recv(dptr,
-                          port, yield);
+            yield: *ctypes::uintptr_t,
+            killed: *ctypes::uintptr_t) unsafe {
+        rustrt::port_recv(dptr, port, yield, killed);
     }
     let yield = 0u;
     let yieldp = ptr::addr_of(yield);
-    let res = rusti::call_with_retptr(bind recv(_, p, yieldp));
+    let killed = 0u;
+    let killedp = ptr::addr_of(killed);
+    let res = rusti::call_with_retptr(bind recv(_, p, yieldp, killedp));
+    if killed != 0u {
+        fail_killed();
+    }
     if yield != 0u {
         // Data isn't available yet, so res has not been initialized.
         task::yield();
@@ -166,6 +172,10 @@ fn recv_<send T>(p: *rustrt::rust_port) -> T {
     ret res;
 }
 
+fn fail_killed() -> ! {
+    fail "killed";
+}
+
 /*
 Function: chan
 
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index 3460d460900..ff83cb7ec6b 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -516,7 +516,10 @@ rust_task_sleep(rust_task *task, size_t time_in_us) {
 }
 
 extern "C" CDECL void
-port_recv(uintptr_t *dptr, rust_port *port, uintptr_t *yield) {
+port_recv(uintptr_t *dptr, rust_port *port,
+          uintptr_t *yield, uintptr_t *killed) {
+    *yield = false;
+    *killed = false;
     rust_task *task = rust_scheduler::get_task();
     {
         scoped_lock with(port->lock);
@@ -526,7 +529,13 @@ port_recv(uintptr_t *dptr, rust_port *port, uintptr_t *yield) {
             (uintptr_t) port, (uintptr_t) dptr, port->unit_sz);
 
         if (port->receive(dptr)) {
-            *yield = false;
+            return;
+        }
+
+        // If this task has been killed then we're not going to bother
+        // blocking, we have to unwind.
+        if (task->killed) {
+            *killed = true;
             return;
         }
 
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index 848086dd368..39f8488e784 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -272,14 +272,10 @@ rust_task::yield(size_t time_in_us) {
         name, this, time_in_us);
 
     if (killed) {
-        // Receive may have blocked before yielding
-        unblock();
+        A(sched, !blocked(), "Shouldn't be blocked before failing");
         fail();
     }
 
-    // FIXME: If we are blocked, and get killed right here then we may never
-    // know it.
-
     yield_timer.reset_us(time_in_us);
 
     // Return to the scheduler.