diff options
| author | Brian Anderson <banderson@mozilla.com> | 2011-11-18 14:45:48 -0800 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2011-11-18 14:45:48 -0800 |
| commit | 792068d871f2a8f7184a6f109db1d65c73bf63da (patch) | |
| tree | 4250b4b01f7837ef34f05d9be8c53e89533f82f6 | |
| parent | 0f339b481a8ae255f012f2218c8f5b5fc3d451ce (diff) | |
| download | rust-792068d871f2a8f7184a6f109db1d65c73bf63da.tar.gz rust-792068d871f2a8f7184a6f109db1d65c73bf63da.zip | |
rt: Remove unblock call from rust_task::yield
| -rw-r--r-- | src/lib/comm.rs | 20 | ||||
| -rw-r--r-- | src/rt/rust_builtin.cpp | 13 | ||||
| -rw-r--r-- | src/rt/rust_task.cpp | 6 |
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. |
