diff options
| author | Ben Blum <bblum@andrew.cmu.edu> | 2012-07-12 19:43:22 -0400 |
|---|---|---|
| committer | Ben Blum <bblum@andrew.cmu.edu> | 2012-07-12 19:49:49 -0400 |
| commit | a10f52c5793b358a16e3e98db4b16c65ba8e254b (patch) | |
| tree | 67e53933ce262ab82e2179841f9fc400db72a840 | |
| parent | 5724c6454950617c292daba89cdb9a3b4c862430 (diff) | |
| download | rust-a10f52c5793b358a16e3e98db4b16c65ba8e254b.tar.gz rust-a10f52c5793b358a16e3e98db4b16c65ba8e254b.zip | |
Revert linked failure (rust_port locking)
This reverts commit 343e9de8ef4ee9727f027c896ce99f09611b9603.
| -rw-r--r-- | src/rt/rust_port.cpp | 28 | ||||
| -rw-r--r-- | src/rt/rust_port_selector.cpp | 4 | ||||
| -rw-r--r-- | src/rt/rust_port_selector.h | 1 | ||||
| -rw-r--r-- | src/rt/rust_task.cpp | 7 | ||||
| -rw-r--r-- | src/rt/rust_task.h | 6 |
5 files changed, 22 insertions, 24 deletions
diff --git a/src/rt/rust_port.cpp b/src/rt/rust_port.cpp index 919dadd4044..f1a40508aca 100644 --- a/src/rt/rust_port.cpp +++ b/src/rt/rust_port.cpp @@ -26,11 +26,9 @@ void rust_port::deref() { scoped_lock with(ref_lock); ref_count--; if (!ref_count) { - // The port owner is waiting for the port to be detached (if it - // hasn't already been killed) - scoped_lock with(task->lifecycle_lock); if (task->blocked_on(&detach_cond)) { - task->wakeup_inner(&detach_cond); + // The port owner is waiting for the port to be detached + task->wakeup(&detach_cond); } } } @@ -66,15 +64,12 @@ void rust_port::send(void *sptr) { assert(!buffer.is_empty() && "rust_chan::transmit with nothing to send."); - { - scoped_lock with(task->lifecycle_lock); - if (task->blocked_on(this)) { - KLOG(kernel, comm, "dequeued in rendezvous_ptr"); - buffer.dequeue(task->rendezvous_ptr); - task->rendezvous_ptr = 0; - task->wakeup_inner(this); - did_rendezvous = true; - } + 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; } } @@ -83,8 +78,11 @@ void rust_port::send(void *sptr) { // it may be waiting on a group of ports rust_port_selector *port_selector = task->get_port_selector(); - // The port selector will check if the task is blocked, not us. - port_selector->msg_sent_on(this); + // 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); + } } } diff --git a/src/rt/rust_port_selector.cpp b/src/rt/rust_port_selector.cpp index 52f9e0c3a01..7b3b45788f7 100644 --- a/src/rt/rust_port_selector.cpp +++ b/src/rt/rust_port_selector.cpp @@ -75,7 +75,7 @@ rust_port_selector::msg_sent_on(rust_port *port) { // Prevent two ports from trying to wake up the task // simultaneously - scoped_lock with(task->lifecycle_lock); + scoped_lock with(rendezvous_lock); if (task->blocked_on(this)) { for (size_t i = 0; i < n_ports; i++) { @@ -85,7 +85,7 @@ rust_port_selector::msg_sent_on(rust_port *port) { n_ports = 0; *task->rendezvous_ptr = (uintptr_t) port; task->rendezvous_ptr = NULL; - task->wakeup_inner(this); + task->wakeup(this); return; } } diff --git a/src/rt/rust_port_selector.h b/src/rt/rust_port_selector.h index 73f2a9e4a0c..8dbf0c40329 100644 --- a/src/rt/rust_port_selector.h +++ b/src/rt/rust_port_selector.h @@ -9,6 +9,7 @@ class rust_port_selector : public rust_cond { private: rust_port **ports; size_t n_ports; + lock_and_signal rendezvous_lock; public: rust_port_selector(); diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index 3d88c05b3ff..fa05a713745 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -243,7 +243,7 @@ rust_task::must_fail_from_being_killed_inner() { // Only run this on the rust stack void rust_task::yield(bool *killed) { - // FIXME (#2875): clean this up + // FIXME (#2787): clean this up if (must_fail_from_being_killed()) { { scoped_lock with(lifecycle_lock); @@ -346,11 +346,12 @@ void rust_task::assert_is_running() assert(state == task_state_running); } -// FIXME (#2851) Remove this code when rust_port goes away? +// FIXME (#2851, #2787): This is only used by rust_port/rust_port selector, +// and is inherently racy. Get rid of it. bool rust_task::blocked_on(rust_cond *on) { - lifecycle_lock.must_have_lock(); + scoped_lock with(lifecycle_lock); return cond == on; } diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h index 1d87a0ed56c..ba327822c37 100644 --- a/src/rt/rust_task.h +++ b/src/rt/rust_task.h @@ -226,11 +226,8 @@ private: char const *file, size_t line); - friend class rust_port; - friend class rust_port_selector; bool block_inner(rust_cond *on, const char* name); void wakeup_inner(rust_cond *from); - bool blocked_on(rust_cond *cond); public: @@ -246,6 +243,7 @@ public: void *args); void start(); void assert_is_running(); + bool blocked_on(rust_cond *cond); // FIXME (#2851) Get rid of this. void *malloc(size_t sz, const char *tag, type_desc *td=0); void *realloc(void *data, size_t sz); @@ -437,7 +435,7 @@ rust_task::call_on_rust_stack(void *args, void *fn_ptr) { bool had_reentered_rust_stack = reentered_rust_stack; { - // FIXME (#2875) This must be racy. Figure it out. + // FIXME (#2787) This must be racy. Figure it out. scoped_lock with(lifecycle_lock); reentered_rust_stack = true; } |
