about summary refs log tree commit diff
path: root/src/rt/sync
diff options
context:
space:
mode:
authorEric Holk <eholk@mozilla.com>2011-07-25 18:00:37 -0700
committerEric Holk <eholk@mozilla.com>2011-07-28 10:47:28 -0700
commit5302cde188bba80dd38c58eaafa792d621b0818c (patch)
tree663ca3e81a7254548e756ea0dfef66d4362f971a /src/rt/sync
parente697a52359874c2b7387be96e664b1f94b14255b (diff)
downloadrust-5302cde188bba80dd38c58eaafa792d621b0818c.tar.gz
rust-5302cde188bba80dd38c58eaafa792d621b0818c.zip
Made task threads wait instead of sleep, so they can be woken up. This appears to give us much better parallel performance.
Also, commented out one more unsafe log and updated rust_kernel.cpp to compile under g++
Diffstat (limited to 'src/rt/sync')
-rw-r--r--src/rt/sync/lock_and_signal.cpp34
-rw-r--r--src/rt/sync/lock_and_signal.h5
2 files changed, 34 insertions, 5 deletions
diff --git a/src/rt/sync/lock_and_signal.cpp b/src/rt/sync/lock_and_signal.cpp
index 3d0d1013889..f4c3778837d 100644
--- a/src/rt/sync/lock_and_signal.cpp
+++ b/src/rt/sync/lock_and_signal.cpp
@@ -10,7 +10,9 @@
 #include "lock_and_signal.h"
 
 #if defined(__WIN32__)
-lock_and_signal::lock_and_signal() {
+lock_and_signal::lock_and_signal() 
+    : alive(true)
+{
     // FIXME: In order to match the behavior of pthread_cond_broadcast on
     // Windows, we create manual reset events. This however breaks the
     // behavior of pthread_cond_signal, fixing this is quite involved:
@@ -22,7 +24,7 @@ lock_and_signal::lock_and_signal() {
 
 #else
 lock_and_signal::lock_and_signal()
-    : _locked(false)
+    : _locked(false), alive(true)
 {
     CHECKED(pthread_cond_init(&_cond, NULL));
     CHECKED(pthread_mutex_init(&_mutex, NULL));
@@ -36,6 +38,7 @@ lock_and_signal::~lock_and_signal() {
     CHECKED(pthread_cond_destroy(&_cond));
     CHECKED(pthread_mutex_destroy(&_mutex));
 #endif
+    alive = false;
 }
 
 void lock_and_signal::lock() {
@@ -65,11 +68,14 @@ void lock_and_signal::wait() {
     timed_wait(0);
 }
 
-void lock_and_signal::timed_wait(size_t timeout_in_ns) {
+bool lock_and_signal::timed_wait(size_t timeout_in_ns) {
+    _locked = false;
+    bool rv = true;
 #if defined(__WIN32__)
     LeaveCriticalSection(&_cs);
     WaitForSingleObject(_event, INFINITE);
     EnterCriticalSection(&_cs);
+    _holding_thread = GetCurrentThreadId();
 #else
     if (timeout_in_ns == 0) {
         CHECKED(pthread_cond_wait(&_cond, &_mutex));
@@ -79,9 +85,29 @@ void lock_and_signal::timed_wait(size_t timeout_in_ns) {
         timespec time_spec;
         time_spec.tv_sec = time_val.tv_sec + 0;
         time_spec.tv_nsec = time_val.tv_usec * 1000 + timeout_in_ns;
-        CHECKED(pthread_cond_timedwait(&_cond, &_mutex, &time_spec));
+        if(time_spec.tv_nsec >= 1000000000) {
+            time_spec.tv_sec++;
+            time_spec.tv_nsec -= 1000000000;
+        }
+        int cond_wait_status
+            = pthread_cond_timedwait(&_cond, &_mutex, &time_spec);
+        switch(cond_wait_status) {
+        case 0:
+            // successfully grabbed the lock.
+            break;
+        case ETIMEDOUT:
+            // Oops, we timed out.
+            rv = false;
+            break;
+        default:
+            // Error
+            CHECKED(cond_wait_status);
+        }
     }
+    _holding_thread = pthread_self();
 #endif
+    _locked = true;
+    return rv;
 }
 
 /**
diff --git a/src/rt/sync/lock_and_signal.h b/src/rt/sync/lock_and_signal.h
index 60c22958342..6e656017115 100644
--- a/src/rt/sync/lock_and_signal.h
+++ b/src/rt/sync/lock_and_signal.h
@@ -14,6 +14,9 @@ class lock_and_signal {
     pthread_t _holding_thread;
 #endif
     bool _locked;
+
+    bool alive;
+
 public:
     lock_and_signal();
     virtual ~lock_and_signal();
@@ -21,7 +24,7 @@ public:
     void lock();
     void unlock();
     void wait();
-    void timed_wait(size_t timeout_in_ns);
+    bool timed_wait(size_t timeout_in_ns);
     void signal();
     void signal_all();