about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorStephen M. Coakley <me@stephencoakley.com>2016-10-05 18:11:28 -0500
committerStephen M. Coakley <me@stephencoakley.com>2016-10-05 18:11:28 -0500
commite80fd2531bbb8d2ca30e4036d7be5bcfcaefb6c0 (patch)
tree35fd75566b66664d43d166566c725c38840946a8 /src
parent894ef966c631facd13cd0d021acca43e37c8510e (diff)
downloadrust-e80fd2531bbb8d2ca30e4036d7be5bcfcaefb6c0.tar.gz
rust-e80fd2531bbb8d2ca30e4036d7be5bcfcaefb6c0.zip
Use mutex to guard thread ID counter
Diffstat (limited to 'src')
-rw-r--r--src/libstd/thread/mod.rs38
1 files changed, 8 insertions, 30 deletions
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index a20c2c5002b..c8b6046bb8d 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -165,8 +165,8 @@ use panic;
 use panicking;
 use str;
 use sync::{Mutex, Condvar, Arc};
-use sync::atomic::{AtomicBool, Ordering};
 use sys::thread as imp;
+use sys_common::mutex;
 use sys_common::thread_info;
 use sys_common::util;
 use sys_common::{AsInner, IntoInner};
@@ -539,34 +539,14 @@ pub fn park_timeout(dur: Duration) {
 pub struct ThreadId(u64);
 
 impl ThreadId {
-    // Generate a new unique thread ID. Since this function is called every
-    // time a thread is created, this is optimized to generate unique values
-    // as quickly as possible.
+    // Generate a new unique thread ID.
     fn new() -> ThreadId {
-        // 64-bit operations are not atomic on all systems, so use an atomic
-        // flag as a guard around a 64-bit global counter. The window for
-        // contention on the counter is rather narrow since the general case
-        // should be compiled down to three instructions between locking and
-        // unlocking the guard. Since contention on the guard is low, use a
-        // spinlock that optimizes for the fast path of the guard being
-        // unlocked.
-        static GUARD: AtomicBool = AtomicBool::new(false);
+        static GUARD: mutex::Mutex = mutex::Mutex::new();
         static mut COUNTER: u64 = 0;
 
-        // Get exclusive access to the counter.
-        while GUARD.compare_exchange_weak(
-            false,
-            true,
-            Ordering::Acquire,
-            Ordering::Relaxed
-        ).is_err() {
-            // Give up the rest of our thread quantum if another thread is
-            // using the counter. This is the slow_er_ path.
-            yield_now();
-        }
+        unsafe {
+            GUARD.lock();
 
-        // We have exclusive access to the counter, so use it fast and get out.
-        let id = unsafe {
             // If we somehow use up all our bits, panic so that we're not
             // covering up subtle bugs of IDs being reused.
             if COUNTER == ::u64::MAX {
@@ -575,13 +555,11 @@ impl ThreadId {
 
             let id = COUNTER;
             COUNTER += 1;
-            id
-        };
 
-        // Unlock the guard.
-        GUARD.store(false, Ordering::Release);
+            GUARD.unlock();
 
-        ThreadId(id)
+            ThreadId(id)
+        }
     }
 }