rt: Simplify the recv interface

This commit is contained in:
Brian Anderson
2012-03-02 00:31:14 -08:00
parent 8e0efce0da
commit 77295c56c5
2 changed files with 13 additions and 21 deletions

View File

@@ -46,8 +46,7 @@ native mod rustrt {
fn get_port_id(po: *rust_port) -> port_id; fn get_port_id(po: *rust_port) -> port_id;
fn rust_port_size(po: *rust_port) -> ctypes::size_t; fn rust_port_size(po: *rust_port) -> ctypes::size_t;
fn port_recv(dptr: *uint, po: *rust_port, fn port_recv(dptr: *uint, po: *rust_port,
yield: *ctypes::uintptr_t, yield: *ctypes::uintptr_t);
killed: *ctypes::uintptr_t);
fn rust_port_select(dptr: **rust_port, ports: **rust_port, fn rust_port_select(dptr: **rust_port, ports: **rust_port,
n_ports: ctypes::size_t, n_ports: ctypes::size_t,
yield: *ctypes::uintptr_t); yield: *ctypes::uintptr_t);
@@ -142,21 +141,19 @@ fn recv_<T: send>(p: *rust_port) -> T {
// that will grab the value of the return pointer, then call this // that will grab the value of the return pointer, then call this
// function, which we will then use to call the runtime. // function, which we will then use to call the runtime.
fn recv(dptr: *uint, port: *rust_port, fn recv(dptr: *uint, port: *rust_port,
yield: *ctypes::uintptr_t, yield: *ctypes::uintptr_t) unsafe {
killed: *ctypes::uintptr_t) unsafe { rustrt::port_recv(dptr, port, yield);
rustrt::port_recv(dptr, port, yield, killed);
} }
let yield = 0u; let yield = 0u;
let yieldp = ptr::addr_of(yield); let yieldp = ptr::addr_of(yield);
let killed = 0u; let res = rusti::call_with_retptr(bind recv(_, p, yieldp));
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 { if yield != 0u {
// Data isn't available yet, so res has not been initialized. // Data isn't available yet, so res has not been initialized.
task::yield(); task::yield();
} else {
// In the absense of compiler-generated preemption points
// this is a good place to yield
task::yield();
} }
ret res; ret res;
} }
@@ -186,6 +183,10 @@ fn select2<A: send, B: send>(
if yield != 0u { if yield != 0u {
// Wait for data // Wait for data
task::yield(); task::yield();
} else {
// As in recv, this is a good place to yield anyway until
// the compiler generates yield calls
task::yield();
} }
// Now we know the port we're supposed to receive from // Now we know the port we're supposed to receive from

View File

@@ -543,10 +543,8 @@ rust_task_yield(rust_task *task, bool *killed) {
} }
extern "C" CDECL void extern "C" CDECL void
port_recv(uintptr_t *dptr, rust_port *port, port_recv(uintptr_t *dptr, rust_port *port, uintptr_t *yield) {
uintptr_t *yield, uintptr_t *killed) {
*yield = false; *yield = false;
*killed = false;
rust_task *task = rust_task_thread::get_task(); rust_task *task = rust_task_thread::get_task();
{ {
scoped_lock with(port->lock); scoped_lock with(port->lock);
@@ -559,13 +557,6 @@ port_recv(uintptr_t *dptr, rust_port *port,
return; return;
} }
// If this task has been killed then we're not going to bother
// blocking, we have to unwind.
if (task->must_fail_from_being_killed()) {
*killed = true;
return;
}
// No data was buffered on any incoming channel, so block this task on // No data was buffered on any incoming channel, so block this task on
// the port. Remember the rendezvous location so that any sender task // the port. Remember the rendezvous location so that any sender task
// can write to it before waking up this task. // can write to it before waking up this task.