diff options
| author | Ben Blum <bblum@andrew.cmu.edu> | 2012-07-24 15:27:45 -0400 |
|---|---|---|
| committer | Ben Blum <bblum@andrew.cmu.edu> | 2012-07-24 15:28:35 -0400 |
| commit | ae094a7adc8e0f166ea2b137c2940afdb9396bcd (patch) | |
| tree | 49d21e0d95ea214b2d3e161d2afc9a00d473032f /src/rt/rust_task.cpp | |
| parent | 9103e439091fbd4e5ec7e561f007172342065340 (diff) | |
| download | rust-ae094a7adc8e0f166ea2b137c2940afdb9396bcd.tar.gz rust-ae094a7adc8e0f166ea2b137c2940afdb9396bcd.zip | |
Add 'do atomically { .. }' for exclusives
Diffstat (limited to 'src/rt/rust_task.cpp')
| -rw-r--r-- | src/rt/rust_task.cpp | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index c28e3350bf2..e9879525ee7 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -39,6 +39,7 @@ rust_task::rust_task(rust_sched_loop *sched_loop, rust_task_state state, killed(false), reentered_rust_stack(false), disallow_kill(0), + disallow_yield(0), c_stack(NULL), next_c_sp(0), next_rust_sp(0) @@ -234,9 +235,18 @@ rust_task::must_fail_from_being_killed_inner() { return killed && !reentered_rust_stack && disallow_kill == 0; } +void rust_task_yield_fail(rust_task *task) { + LOG_ERR(task, task, "task %" PRIxPTR " yielded in an atomic section", + task); + task->fail(); +} + // Only run this on the rust stack void rust_task::yield(bool *killed) { + if (disallow_yield > 0) { + call_on_c_stack(this, (void *)rust_task_yield_fail); + } // FIXME (#2875): clean this up if (must_fail_from_being_killed()) { { @@ -672,6 +682,17 @@ rust_task::allow_kill() { disallow_kill--; } +void rust_task::inhibit_yield() { + scoped_lock with(lifecycle_lock); + disallow_yield++; +} + +void rust_task::allow_yield() { + scoped_lock with(lifecycle_lock); + assert(disallow_yield > 0 && "Illegal allow_yield(): already yieldable!"); + disallow_yield--; +} + void * rust_task::wait_event(bool *killed) { scoped_lock with(lifecycle_lock); |
