From e394ebda37bf6bbe4c516e2b9381aac8bd964dcc Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Wed, 6 Jun 2012 15:06:24 -0700 Subject: Adding a lock/condition variable to libcore. --- src/rt/rust_builtin.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++++++ src/rt/rust_cond_lock.cpp | 6 ++++++ src/rt/rust_cond_lock.h | 15 +++++++++++++ src/rt/rustrt.def.in | 6 ++++++ 4 files changed, 82 insertions(+) create mode 100644 src/rt/rust_cond_lock.cpp create mode 100644 src/rt/rust_cond_lock.h (limited to 'src/rt') 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 @@ -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 -- cgit 1.4.1-3-g733a5