aboutsummaryrefslogtreecommitdiff
path: root/src/rt/sync/lock_and_signal.cpp
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2010-09-08 19:13:49 -0700
committerGraydon Hoare <[email protected]>2010-09-08 19:13:49 -0700
commit616b7afb724a32df41eebfaf95402d008c60b411 (patch)
tree03e13578e8b43b9001cef983d1117800a6f93e65 /src/rt/sync/lock_and_signal.cpp
parentXFAIL many.rs since it crashes on win32, and add a time-slice sleep to the ke... (diff)
downloadrust-616b7afb724a32df41eebfaf95402d008c60b411.tar.xz
rust-616b7afb724a32df41eebfaf95402d008c60b411.zip
Tidy up the sync dir, remove dead or mis-designed code in favour of OS primitives, switch rust_kernel to use a lock/signal pair and wait rather than spin.
Diffstat (limited to 'src/rt/sync/lock_and_signal.cpp')
-rwxr-xr-xsrc/rt/sync/lock_and_signal.cpp97
1 files changed, 97 insertions, 0 deletions
diff --git a/src/rt/sync/lock_and_signal.cpp b/src/rt/sync/lock_and_signal.cpp
new file mode 100755
index 00000000..c010086e
--- /dev/null
+++ b/src/rt/sync/lock_and_signal.cpp
@@ -0,0 +1,97 @@
+#include "../globals.h"
+
+/*
+ * A "lock-and-signal" pair. These are necessarily coupled on pthreads
+ * systems, and artificially coupled (by this file) on win32. Put
+ * together here to minimize ifdefs elsewhere; you must use them as
+ * if you're using a pthreads cvar+mutex pair.
+ */
+
+#include "lock_and_signal.h"
+
+#if defined(__WIN32__)
+lock_and_signal::lock_and_signal() {
+ _event = CreateEvent(NULL, FALSE, FALSE, NULL);
+ InitializeCriticalSection(&_cs);
+}
+
+#else
+lock_and_signal::lock_and_signal() {
+ pthread_cond_init(&_cond, NULL);
+ pthread_mutex_init(&_mutex, NULL);
+}
+#endif
+
+lock_and_signal::~lock_and_signal() {
+#if defined(__WIN32__)
+ CloseHandle(_event);
+#else
+ pthread_cond_destroy(&_cond);
+ pthread_mutex_destroy(&_mutex);
+#endif
+}
+
+void lock_and_signal::lock() {
+#if defined(__WIN32__)
+ EnterCriticalSection(&_cs);
+#else
+ pthread_mutex_lock(&_mutex);
+#endif
+}
+
+void lock_and_signal::unlock() {
+#if defined(__WIN32__)
+ LeaveCriticalSection(&_cs);
+#else
+ pthread_mutex_unlock(&_mutex);
+#endif
+}
+
+
+/**
+ * Wait indefinitely until condition is signaled.
+ */
+void lock_and_signal::wait() {
+ timed_wait(0);
+}
+
+void lock_and_signal::timed_wait(size_t timeout_in_ns) {
+#if defined(__WIN32__)
+ LeaveCriticalSection(&_cs);
+ WaitForSingleObject(_event, INFINITE);
+ EnterCriticalSection(&_cs);
+#else
+ if (timeout_in_ns == 0) {
+ pthread_cond_wait(&_cond, &_mutex);
+ } else {
+ timeval time_val;
+ gettimeofday(&time_val, NULL);
+ timespec time_spec;
+ time_spec.tv_sec = time_val.tv_sec + 0;
+ time_spec.tv_nsec = time_val.tv_usec * 1000 + timeout_in_ns;
+ pthread_cond_timedwait(&_cond, &_mutex, &time_spec);
+ }
+#endif
+}
+
+/**
+ * Signal condition, and resume the waiting thread.
+ */
+void lock_and_signal::signal() {
+#if defined(__WIN32__)
+ SetEvent(_event);
+#else
+ pthread_cond_signal(&_cond);
+#endif
+}
+
+
+//
+// Local Variables:
+// mode: C++
+// fill-column: 78;
+// indent-tabs-mode: nil
+// c-basic-offset: 4
+// buffer-file-coding-system: utf-8-unix
+// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
+// End: