diff options
| author | Brian Anderson <banderson@mozilla.com> | 2012-04-06 17:03:00 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2012-04-07 19:56:41 -0700 |
| commit | 01dc4a8b26d722d306a00e44a5b1ed5cf3fd24b1 (patch) | |
| tree | 7bebe6c918cd108943cd8d07b0203b25256d063f /src/rt/rust_kernel.cpp | |
| parent | a6e748a1d9795f59f9ca954dbf1ad82d238c3990 (diff) | |
| download | rust-01dc4a8b26d722d306a00e44a5b1ed5cf3fd24b1.tar.gz rust-01dc4a8b26d722d306a00e44a5b1ed5cf3fd24b1.zip | |
core: Add priv::weaken_task
Diffstat (limited to 'src/rt/rust_kernel.cpp')
| -rw-r--r-- | src/rt/rust_kernel.cpp | 81 |
1 files changed, 80 insertions, 1 deletions
diff --git a/src/rt/rust_kernel.cpp b/src/rt/rust_kernel.cpp index ff6b0e1056c..21422646f0d 100644 --- a/src/rt/rust_kernel.cpp +++ b/src/rt/rust_kernel.cpp @@ -1,11 +1,11 @@ - #include "rust_kernel.h" #include "rust_port.h" #include "rust_util.h" #include "rust_scheduler.h" #include "rust_sched_launcher.h" +#include <algorithm> #define KLOG_(...) \ KLOG(this, kern, __VA_ARGS__) @@ -21,6 +21,7 @@ rust_kernel::rust_kernel(rust_env *env) : max_sched_id(0), sched_reaper(this), osmain_driver(NULL), + non_weak_tasks(0), env(env) { // Create the single threaded scheduler that will run on the platform's @@ -286,6 +287,84 @@ rust_kernel::set_exit_status(int code) { } } +void +rust_kernel::register_task() { + KLOG_("Registering task"); + uintptr_t new_non_weak_tasks = sync::increment(non_weak_tasks); + KLOG_("New non-weak tasks %" PRIdPTR, new_non_weak_tasks); +} + +void +rust_kernel::unregister_task() { + KLOG_("Unregistering task"); + uintptr_t new_non_weak_tasks = sync::decrement(non_weak_tasks); + KLOG_("New non-weak tasks %" PRIdPTR, new_non_weak_tasks); + if (new_non_weak_tasks == 0) { + end_weak_tasks(); + } +} + +void +rust_kernel::weaken_task(rust_port_id chan) { + { + scoped_lock with(weak_task_lock); + KLOG_("Weakening task with channel %" PRIdPTR, chan); + weak_task_chans.push_back(chan); + } + uintptr_t new_non_weak_tasks = sync::decrement(non_weak_tasks); + KLOG_("New non-weak tasks %" PRIdPTR, new_non_weak_tasks); + if (new_non_weak_tasks == 0) { + end_weak_tasks(); + } +} + +void +rust_kernel::unweaken_task(rust_port_id chan) { + uintptr_t new_non_weak_tasks = sync::increment(non_weak_tasks); + KLOG_("New non-weak tasks %" PRIdPTR, new_non_weak_tasks); + { + scoped_lock with(weak_task_lock); + KLOG_("Unweakening task with channel %" PRIdPTR, chan); + std::vector<rust_port_id>::iterator iter = + std::find(weak_task_chans.begin(), weak_task_chans.end(), chan); + if (iter != weak_task_chans.end()) { + weak_task_chans.erase(iter); + } + } +} + +void +rust_kernel::end_weak_tasks() { + std::vector<rust_port_id> chancopies; + { + //scoped_lock with(weak_task_lock); + chancopies = weak_task_chans; + weak_task_chans.clear(); + } + while (!chancopies.empty()) { + rust_port_id chan = chancopies.back(); + chancopies.pop_back(); + KLOG_("Notifying weak task " PRIdPTR, chan); + uintptr_t token = 0; + send_to_port(chan, &token); + } +} + +bool +rust_kernel::send_to_port(rust_port_id chan, void *sptr) { + KLOG_("rust_port_id*_send port: 0x%" PRIxPTR, (uintptr_t) chan); + + rust_port *port = get_port_by_id(chan); + if(port) { + port->send(sptr); + port->deref(); + return true; + } else { + KLOG_("didn't get the port"); + return false; + } +} + // // Local Variables: // mode: C++ |
