diff options
| author | Eric Holk <eric.holk@gmail.com> | 2012-06-06 15:06:24 -0700 |
|---|---|---|
| committer | Eric Holk <eric.holk@gmail.com> | 2012-06-15 22:00:24 -0400 |
| commit | e394ebda37bf6bbe4c516e2b9381aac8bd964dcc (patch) | |
| tree | 58128171af062efa394ee0d0697bcb52c29bb21e /src/rt | |
| parent | 5c9f414a85ae8f3448a27f56274afc861974cffe (diff) | |
| download | rust-e394ebda37bf6bbe4c516e2b9381aac8bd964dcc.tar.gz rust-e394ebda37bf6bbe4c516e2b9381aac8bd964dcc.zip | |
Adding a lock/condition variable to libcore.
Diffstat (limited to 'src/rt')
| -rw-r--r-- | src/rt/rust_builtin.cpp | 55 | ||||
| -rw-r--r-- | src/rt/rust_cond_lock.cpp | 6 | ||||
| -rw-r--r-- | src/rt/rust_cond_lock.h | 15 | ||||
| -rw-r--r-- | src/rt/rustrt.def.in | 6 |
4 files changed, 82 insertions, 0 deletions
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 2a65012b52a..25da500cb23 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -7,6 +7,7 @@ #include "sync/timer.h" #include "rust_abi.h" #include "rust_port.h" +#include "rust_cond_lock.h" #include <time.h> @@ -862,6 +863,60 @@ rust_task_allow_kill() { task->allow_kill(); } +extern "C" rust_cond_lock* +rust_create_cond_lock() { + return new rust_cond_lock(); +} + +extern "C" void +rust_destroy_cond_lock(rust_cond_lock *lock) { + delete lock; +} + +extern "C" void +rust_lock_cond_lock(rust_cond_lock *lock) { + lock->lock.lock(); +} + +extern "C" void +rust_unlock_cond_lock(rust_cond_lock *lock) { + lock->lock.unlock(); +} + +// The next two functions do not use the built in condition variable features +// because the Rust schedule is not aware of them, and they can block the +// scheduler thread. + +extern "C" void +rust_wait_cond_lock(rust_cond_lock *lock) { + rust_task *task = rust_get_current_task(); +#ifdef DEBUG_LOCKS + assert(lock->lock.lock_held_by_current_thread()); +#endif + assert(NULL == lock->waiting); + lock->waiting = task; + lock->lock.unlock(); + task->block(lock, "waiting for signal"); + lock->lock.lock(); + lock->waiting = NULL; +} + +extern "C" bool +rust_signal_cond_lock(rust_cond_lock *lock) { +#ifdef DEBUG_LOCKS + assert(lock->lock.lock_held_by_current_thread()); +#endif + if(NULL == lock->waiting) { + return false; + } + else { + lock->waiting->wakeup(lock); + return true; + } +} + + + // // Local Variables: // mode: C++ diff --git a/src/rt/rust_cond_lock.cpp b/src/rt/rust_cond_lock.cpp new file mode 100644 index 00000000000..cdeccfdc26c --- /dev/null +++ b/src/rt/rust_cond_lock.cpp @@ -0,0 +1,6 @@ +#include "rust_cond_lock.h" + +rust_cond_lock::rust_cond_lock() + : waiting(NULL) +{ +} diff --git a/src/rt/rust_cond_lock.h b/src/rt/rust_cond_lock.h new file mode 100644 index 00000000000..0adafd59678 --- /dev/null +++ b/src/rt/rust_cond_lock.h @@ -0,0 +1,15 @@ +// -*- c++ -*- +// A lock and condition variable pair that is useable from Rust. + +#pragma once + +#include "sync/lock_and_signal.h" +#include "rust_globals.h" +#include "rust_task.h" + +struct rust_cond_lock : public rust_cond { + rust_cond_lock(); + + lock_and_signal lock; + rust_task *waiting; +}; diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 7977c42cfa4..5cf6ee61773 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -163,3 +163,9 @@ rust_port_drop rust_port_task rust_task_inhibit_kill rust_task_allow_kill +rust_create_cond_lock +rust_destroy_cond_lock +rust_lock_cond_lock +rust_unlock_cond_lock +rust_wait_cond_lock +rust_signal_cond_lock |
