about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEric Holk <eholk@mozilla.com>2011-07-06 11:10:40 -0700
committerEric Holk <eholk@mozilla.com>2011-07-06 11:30:00 -0700
commitbc5d6aefdabc2ee928cb0599c5a8c73799f191ef (patch)
tree807d489bf1280b0b9c6b4ccbc4a5dc3e186513ed
parentbbdba21b1f3c7dfc4c0bac3525cc35939ae8ca4c (diff)
downloadrust-bc5d6aefdabc2ee928cb0599c5a8c73799f191ef.tar.gz
rust-bc5d6aefdabc2ee928cb0599c5a8c73799f191ef.zip
Added a task wakeup callback. Closes #599.
The callback happens when a task moves from the "blocked" state to the
"running" state. The callback is also inherited by child tasks. There
is currently only a native API.

This code hasn't been heavily exercised yet.
-rw-r--r--src/rt/rust_scheduler.cpp4
-rw-r--r--src/rt/rust_task.cpp11
-rw-r--r--src/rt/rust_task.h9
3 files changed, 22 insertions, 2 deletions
diff --git a/src/rt/rust_scheduler.cpp b/src/rt/rust_scheduler.cpp
index 0318d9801f1..00368205de7 100644
--- a/src/rt/rust_scheduler.cpp
+++ b/src/rt/rust_scheduler.cpp
@@ -291,8 +291,10 @@ rust_scheduler::create_task(rust_task *spawner, const char *name) {
         new (this->kernel) rust_task (this, &newborn_tasks, spawner, name);
     DLOG(this, task, "created task: " PTR ", spawner: %s, name: %s",
                         task, spawner ? spawner->name : "null", name);
-    if(spawner)
+    if(spawner) {
         task->pin(spawner->pinned_on);
+        task->on_wakeup(spawner->_on_wakeup);
+    }
     newborn_tasks.append(task);
     return task;
 }
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index b2a60dc92bc..87492600524 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -73,7 +73,8 @@ rust_task::rust_task(rust_scheduler *sched, rust_task_list *state,
     running_on(-1),
     pinned_on(-1),
     local_region(&sched->srv->local_region),
-    synchronized_region(&sched->srv->synchronized_region)
+    synchronized_region(&sched->srv->synchronized_region),
+    _on_wakeup(NULL)
 {
     LOGPTR(sched, "new task", (uintptr_t)this);
     DLOG(sched, task, "sizeof(task) = %d (0x%x)", sizeof *this, sizeof *this);
@@ -431,6 +432,10 @@ rust_task::wakeup(rust_cond *from) {
     I(sched, cond == from);
     cond = NULL;
     cond_name = "none";
+
+    if(_on_wakeup) {
+        _on_wakeup->on_wakeup();
+    }
 }
 
 void
@@ -541,6 +546,10 @@ void rust_task::unpin() {
     pinned_on = -1;
 }
 
+void rust_task::on_wakeup(rust_task::wakeup_callback *callback) {
+    _on_wakeup = callback;
+}
+
 //
 // Local Variables:
 // mode: C++
diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h
index f2aa7846c54..29da8d82723 100644
--- a/src/rt/rust_task.h
+++ b/src/rt/rust_task.h
@@ -83,6 +83,13 @@ rust_task : public maybe_proxy<rust_task>,
     memory_region local_region;
     memory_region synchronized_region;
 
+    class wakeup_callback {
+    public:
+        virtual void on_wakeup() = 0;
+    };
+
+    wakeup_callback *_on_wakeup;
+
     // Only a pointer to 'name' is kept, so it must live as long as this task.
     rust_task(rust_scheduler *sched,
               rust_task_list *state,
@@ -156,6 +163,8 @@ rust_task : public maybe_proxy<rust_task>,
     void pin();
     void pin(int id);
     void unpin();
+
+    void on_wakeup(wakeup_callback *callback);
 };
 
 //