diff options
| author | Stephen M. Coakley <me@stephencoakley.com> | 2016-10-05 18:11:28 -0500 |
|---|---|---|
| committer | Stephen M. Coakley <me@stephencoakley.com> | 2016-10-05 18:11:28 -0500 |
| commit | e80fd2531bbb8d2ca30e4036d7be5bcfcaefb6c0 (patch) | |
| tree | 35fd75566b66664d43d166566c725c38840946a8 /src | |
| parent | 894ef966c631facd13cd0d021acca43e37c8510e (diff) | |
| download | rust-e80fd2531bbb8d2ca30e4036d7be5bcfcaefb6c0.tar.gz rust-e80fd2531bbb8d2ca30e4036d7be5bcfcaefb6c0.zip | |
Use mutex to guard thread ID counter
Diffstat (limited to 'src')
| -rw-r--r-- | src/libstd/thread/mod.rs | 38 |
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) + } } } |
