From b2cfb7ef8262ebe47514f016f59054ebcfe15d61 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 14 Feb 2012 22:23:16 -0800 Subject: rt: Add rust_port_select function --- src/rt/rust_port.cpp | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) (limited to 'src/rt/rust_port.cpp') diff --git a/src/rt/rust_port.cpp b/src/rt/rust_port.cpp index a917c12e151..5f46b9c4ca0 100644 --- a/src/rt/rust_port.cpp +++ b/src/rt/rust_port.cpp @@ -30,18 +30,34 @@ void rust_port::detach() { void rust_port::send(void *sptr) { I(task->thread, !lock.lock_held_by_current_thread()); - scoped_lock with(lock); + bool did_rendezvous = false; + { + scoped_lock with(lock); + + buffer.enqueue(sptr); - buffer.enqueue(sptr); + A(kernel, !buffer.is_empty(), + "rust_chan::transmit with nothing to send."); + + if (task->blocked_on(this)) { + KLOG(kernel, comm, "dequeued in rendezvous_ptr"); + buffer.dequeue(task->rendezvous_ptr); + task->rendezvous_ptr = 0; + task->wakeup(this); + did_rendezvous = true; + } + } - A(kernel, !buffer.is_empty(), - "rust_chan::transmit with nothing to send."); + if (!did_rendezvous) { + // If the task wasn't waiting specifically on this port, + // it may be waiting on a group of ports - if (task->blocked_on(this)) { - KLOG(kernel, comm, "dequeued in rendezvous_ptr"); - buffer.dequeue(task->rendezvous_ptr); - task->rendezvous_ptr = 0; - task->wakeup(this); + rust_port_selector *port_selector = task->get_port_selector(); + // This check is not definitive. The port selector will take a lock + // and check again whether the task is still blocked. + if (task->blocked_on(port_selector)) { + port_selector->msg_sent_on(this); + } } } -- cgit 1.4.1-3-g733a5