about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBen Blum <bblum@andrew.cmu.edu>2012-07-12 19:52:13 -0400
committerBen Blum <bblum@andrew.cmu.edu>2012-07-13 20:13:53 -0400
commit79a2e9a38a243d30130e32fa0741d7430fc63758 (patch)
tree0cd5655c77f99e4c1f1ef220ecc8d53079f78baf /src
parentdf2d2604ca8277634df6e38b548aa884ab387963 (diff)
downloadrust-79a2e9a38a243d30130e32fa0741d7430fc63758.tar.gz
rust-79a2e9a38a243d30130e32fa0741d7430fc63758.zip
Reintroduce linked failure (lifecycle lock)
This reverts commit 08c40c5eb7bda79850f725308b72c1451fb67a86.
Diffstat (limited to 'src')
-rw-r--r--src/rt/rust_sched_loop.cpp2
-rw-r--r--src/rt/rust_task.cpp67
-rw-r--r--src/rt/rust_task.h16
3 files changed, 38 insertions, 47 deletions
diff --git a/src/rt/rust_sched_loop.cpp b/src/rt/rust_sched_loop.cpp
index 4b94968d7c0..ccfdcb5a8ab 100644
--- a/src/rt/rust_sched_loop.cpp
+++ b/src/rt/rust_sched_loop.cpp
@@ -208,7 +208,7 @@ rust_sched_loop::run_single_turn() {
             return sched_loop_state_block;
         }
 
-        assert(scheduled_task->running());
+        scheduled_task->assert_is_running();
 
         DLOG(this, task,
              "activating task %s 0x%" PRIxPTR
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index d23d74b0ea2..250e075d2f9 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -114,7 +114,7 @@ cleanup_task(cleanup_args *args) {
     rust_task *task = a->task;
 
     {
-        scoped_lock with(task->kill_lock);
+        scoped_lock with(task->lifecycle_lock);
         if (task->killed && !threw_exception) {
             LOG(task, task, "Task killed during termination");
             threw_exception = true;
@@ -230,21 +230,25 @@ void rust_task::start()
 
 bool
 rust_task::must_fail_from_being_killed() {
-    scoped_lock with(kill_lock);
+    scoped_lock with(lifecycle_lock);
     return must_fail_from_being_killed_unlocked();
 }
 
 bool
 rust_task::must_fail_from_being_killed_unlocked() {
-    kill_lock.must_have_lock();
+    lifecycle_lock.must_have_lock();
     return killed && !reentered_rust_stack && disallow_kill == 0;
 }
 
 // Only run this on the rust stack
 void
 rust_task::yield(bool *killed) {
+    // FIXME (#2787): clean this up
     if (must_fail_from_being_killed()) {
-        assert(!blocked());
+        {
+            scoped_lock with(lifecycle_lock);
+            assert(!(state == task_state_blocked));
+        }
         *killed = true;
     }
 
@@ -258,7 +262,7 @@ rust_task::yield(bool *killed) {
 
 void
 rust_task::kill() {
-    scoped_lock with(kill_lock);
+    scoped_lock with(lifecycle_lock);
 
     // XXX: bblum: kill/kill race
 
@@ -270,8 +274,9 @@ rust_task::kill() {
     killed = true;
     // Unblock the task so it can unwind.
 
-    if (blocked() && must_fail_from_being_killed_unlocked()) {
-        wakeup(cond);
+    if (state == task_state_blocked &&
+        must_fail_from_being_killed_unlocked()) {
+        wakeup_locked(cond);
     }
 
     LOG(this, task, "preparing to unwind task: 0x%" PRIxPTR, this);
@@ -335,34 +340,21 @@ rust_task::get_frame_glue_fns(uintptr_t fp) {
     return *((frame_glue_fns**) fp);
 }
 
-bool
-rust_task::running()
-{
-    scoped_lock with(state_lock);
-    return state == task_state_running;
-}
-
-bool
-rust_task::blocked()
+void rust_task::assert_is_running()
 {
-    scoped_lock with(state_lock);
-    return state == task_state_blocked;
+    scoped_lock with(lifecycle_lock);
+    assert(state == task_state_running);
 }
 
+// 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)
 {
-    scoped_lock with(state_lock);
+    scoped_lock with(lifecycle_lock);
     return cond == on;
 }
 
-bool
-rust_task::dead()
-{
-    scoped_lock with(state_lock);
-    return state == task_state_dead;
-}
-
 void *
 rust_task::malloc(size_t sz, const char *tag, type_desc *td)
 {
@@ -384,20 +376,20 @@ rust_task::free(void *p)
 void
 rust_task::transition(rust_task_state src, rust_task_state dst,
                       rust_cond *cond, const char* cond_name) {
-    scoped_lock with(state_lock);
+    scoped_lock with(lifecycle_lock);
     transition_locked(src, dst, cond, cond_name);
 }
 
 void rust_task::transition_locked(rust_task_state src, rust_task_state dst,
                                   rust_cond *cond, const char* cond_name) {
-    state_lock.must_have_lock();
+    lifecycle_lock.must_have_lock();
     sched_loop->transition(this, src, dst, cond, cond_name);
 }
 
 void
 rust_task::set_state(rust_task_state state,
                      rust_cond *cond, const char* cond_name) {
-    state_lock.must_have_lock();
+    lifecycle_lock.must_have_lock();
     this->state = state;
     this->cond = cond;
     this->cond_name = cond_name;
@@ -405,7 +397,7 @@ rust_task::set_state(rust_task_state state,
 
 bool
 rust_task::block(rust_cond *on, const char* name) {
-    scoped_lock with(kill_lock);
+    scoped_lock with(lifecycle_lock);
     return block_locked(on, name);
 }
 
@@ -428,7 +420,7 @@ rust_task::block_locked(rust_cond *on, const char* name) {
 
 void
 rust_task::wakeup(rust_cond *from) {
-    scoped_lock with(state_lock);
+    scoped_lock with(lifecycle_lock);
     wakeup_locked(from);
 }
 
@@ -676,26 +668,27 @@ rust_task::on_rust_stack() {
 
 void
 rust_task::inhibit_kill() {
-    scoped_lock with(kill_lock);
+    scoped_lock with(lifecycle_lock);
+    // FIXME (#1868) Check here if we have to die
     disallow_kill++;
 }
 
 void
 rust_task::allow_kill() {
-    scoped_lock with(kill_lock);
+    scoped_lock with(lifecycle_lock);
     assert(disallow_kill > 0 && "Illegal allow_kill(): already killable!");
     disallow_kill--;
 }
 
 void *
 rust_task::wait_event(bool *killed) {
-    scoped_lock with(state_lock);
+    scoped_lock with(lifecycle_lock);
 
     if(!event_reject) {
         block_locked(&event_cond, "waiting on event");
-        state_lock.unlock();
+        lifecycle_lock.unlock();
         yield(killed);
-        state_lock.lock();
+        lifecycle_lock.lock();
     }
 
     event_reject = false;
@@ -704,7 +697,7 @@ rust_task::wait_event(bool *killed) {
 
 void
 rust_task::signal_event(void *event) {
-    scoped_lock with(state_lock);
+    scoped_lock with(lifecycle_lock);
 
     this->event = event;
     event_reject = true;
diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h
index 3bde5202954..82896bf27b4 100644
--- a/src/rt/rust_task.h
+++ b/src/rt/rust_task.h
@@ -170,7 +170,8 @@ rust_task : public kernel_owned<rust_task>
 private:
 
     // Protects state, cond, cond_name
-    lock_and_signal state_lock;
+    // Protects the killed flag, disallow_kill flag, reentered_rust_stack
+    lock_and_signal lifecycle_lock;
     rust_task_state state;
     rust_cond *cond;
     const char *cond_name;
@@ -179,8 +180,6 @@ private:
     rust_cond event_cond;
     void *event;
 
-    // Protects the killed flag, disallow_kill flag, reentered_rust_stack
-    lock_and_signal kill_lock;
     // Indicates that the task was killed and needs to unwind
     bool killed;
     // Indicates that we've called back into Rust from C
@@ -243,10 +242,8 @@ public:
                rust_opaque_box *env,
                void *args);
     void start();
-    bool running();
-    bool blocked();
-    bool blocked_on(rust_cond *cond);
-    bool dead();
+    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);
@@ -438,7 +435,8 @@ rust_task::call_on_rust_stack(void *args, void *fn_ptr) {
 
     bool had_reentered_rust_stack = reentered_rust_stack;
     {
-        scoped_lock with(kill_lock);
+        // FIXME (#2787) This must be racy. Figure it out.
+        scoped_lock with(lifecycle_lock);
         reentered_rust_stack = true;
     }
 
@@ -453,7 +451,7 @@ rust_task::call_on_rust_stack(void *args, void *fn_ptr) {
 
     next_c_sp = prev_c_sp;
     {
-        scoped_lock with(kill_lock);
+        scoped_lock with(lifecycle_lock);
         reentered_rust_stack = had_reentered_rust_stack;
     }