From 792068d871f2a8f7184a6f109db1d65c73bf63da Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 18 Nov 2011 14:45:48 -0800 Subject: [PATCH] rt: Remove unblock call from rust_task::yield --- src/lib/comm.rs | 20 +++++++++++++++----- src/rt/rust_builtin.cpp | 13 +++++++++++-- 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 @@ fn chan_id_send(t: *sys::type_desc, 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_(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(dptr: *uint, port: *rustrt::rust_port, 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.