From e08f46db68b43334e5932ac5eac308ce74f0771e Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 2 Mar 2012 00:55:27 -0800 Subject: [PATCH] rt: Move receive code into rust_port --- src/rt/rust_builtin.cpp | 24 +----------------------- src/rt/rust_port.cpp | 26 ++++++++++++++++++++++---- src/rt/rust_port.h | 2 +- 3 files changed, 24 insertions(+), 28 deletions(-) diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index d37245c29a41..b6ad9397e9c0 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -544,29 +544,7 @@ rust_task_yield(rust_task *task, bool *killed) { extern "C" CDECL void port_recv(uintptr_t *dptr, rust_port *port, uintptr_t *yield) { - *yield = false; - rust_task *task = rust_task_thread::get_task(); - { - scoped_lock with(port->lock); - - LOG(task, comm, "port: 0x%" PRIxPTR ", dptr: 0x%" PRIxPTR - ", size: 0x%" PRIxPTR, - (uintptr_t) port, (uintptr_t) dptr, port->unit_sz); - - if (port->receive(dptr)) { - return; - } - - // No data was buffered on any incoming channel, so block this task on - // the port. Remember the rendezvous location so that any sender task - // can write to it before waking up this task. - - LOG(task, comm, "<=== waiting for rendezvous data ==="); - task->rendezvous_ptr = dptr; - task->block(port, "waiting for rendezvous data"); - } - *yield = true; - return; + port->receive(dptr, yield); } extern "C" CDECL void diff --git a/src/rt/rust_port.cpp b/src/rt/rust_port.cpp index f4843971e425..41884f8f60c9 100644 --- a/src/rt/rust_port.cpp +++ b/src/rt/rust_port.cpp @@ -63,14 +63,32 @@ void rust_port::send(void *sptr) { } } -bool rust_port::receive(void *dptr) { - I(task->thread, lock.lock_held_by_current_thread()); +void rust_port::receive(void *dptr, uintptr_t *yield) { + I(task->thread, !lock.lock_held_by_current_thread()); + + LOG(task, comm, "port: 0x%" PRIxPTR ", dptr: 0x%" PRIxPTR + ", size: 0x%" PRIxPTR, + (uintptr_t) this, (uintptr_t) dptr, unit_sz); + + scoped_lock with(lock); + + *yield = false; + if (buffer.is_empty() == false) { buffer.dequeue(dptr); LOG(task, comm, "<=== read data ==="); - return true; + return; } - return false; + + // No data was buffered on any incoming channel, so block this task on + // the port. Remember the rendezvous location so that any sender task + // can write to it before waking up this task. + + LOG(task, comm, "<=== waiting for rendezvous data ==="); + task->rendezvous_ptr = (uintptr_t*) dptr; + task->block(this, "waiting for rendezvous data"); + + *yield = true; } size_t rust_port::size() { diff --git a/src/rt/rust_port.h b/src/rt/rust_port.h index 92ece8a7841e..0fbfeeac2ece 100644 --- a/src/rt/rust_port.h +++ b/src/rt/rust_port.h @@ -20,7 +20,7 @@ public: ~rust_port(); void log_state(); void send(void *sptr); - bool receive(void *dptr); + void receive(void *dptr, uintptr_t *yield); size_t size(); void detach(); };