about summary refs log tree commit diff
path: root/library/std/src/thread/mod.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-08-12 16:32:24 +0000
committerbors <bors@rust-lang.org>2022-08-12 16:32:24 +0000
commitf22819bcce4abaff7d1246a56eec493418f9f4ee (patch)
tree2fc9ac8d3bfe8d748c4b0971b05b472efca99120 /library/std/src/thread/mod.rs
parent0068b8bf4b150b506ef0871be4e8652fd4308f84 (diff)
parent3bc30bb012889eeeb08d5241dfe64fc47ed33537 (diff)
downloadrust-f22819bcce4abaff7d1246a56eec493418f9f4ee.tar.gz
rust-f22819bcce4abaff7d1246a56eec493418f9f4ee.zip
Auto merge of #100456 - Dylan-DPC:rollup-fn17z9f, r=Dylan-DPC
Rollup of 9 pull requests

Successful merges:

 - #100022 (Optimize thread ID generation)
 - #100030 (cleanup code w/ pointers in std a little)
 - #100229 (add -Zextra-const-ub-checks to enable more UB checking in const-eval)
 - #100247 (Generalize trait object generic param check to aliases.)
 - #100255 (Adding more verbose documentation for `std::fmt::Write`)
 - #100366 (errors: don't fail on broken primary translations)
 - #100396 (Suggest const and static for global variable)
 - #100409 (rustdoc: don't generate DOM element for operator)
 - #100443 (Add two let else regression tests)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'library/std/src/thread/mod.rs')
-rw-r--r--library/std/src/thread/mod.rs59
1 files changed, 41 insertions, 18 deletions
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index 44c8a50fd86..479669647c1 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -170,7 +170,6 @@ use crate::ptr::addr_of_mut;
 use crate::str;
 use crate::sync::Arc;
 use crate::sys::thread as imp;
-use crate::sys_common::mutex;
 use crate::sys_common::thread;
 use crate::sys_common::thread_info;
 use crate::sys_common::thread_parker::Parker;
@@ -1033,24 +1032,48 @@ pub struct ThreadId(NonZeroU64);
 impl ThreadId {
     // Generate a new unique thread ID.
     fn new() -> ThreadId {
-        // It is UB to attempt to acquire this mutex reentrantly!
-        static GUARD: mutex::StaticMutex = mutex::StaticMutex::new();
-        static mut COUNTER: u64 = 1;
-
-        unsafe {
-            let guard = GUARD.lock();
-
-            // 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 {
-                drop(guard); // in case the panic handler ends up calling `ThreadId::new()`, avoid reentrant lock acquire.
-                panic!("failed to generate unique thread ID: bitspace exhausted");
-            }
-
-            let id = COUNTER;
-            COUNTER += 1;
+        #[cold]
+        fn exhausted() -> ! {
+            panic!("failed to generate unique thread ID: bitspace exhausted")
+        }
 
-            ThreadId(NonZeroU64::new(id).unwrap())
+        cfg_if::cfg_if! {
+            if #[cfg(target_has_atomic = "64")] {
+                use crate::sync::atomic::{AtomicU64, Ordering::Relaxed};
+
+                static COUNTER: AtomicU64 = AtomicU64::new(0);
+
+                let mut last = COUNTER.load(Relaxed);
+                loop {
+                    let Some(id) = last.checked_add(1) else {
+                        exhausted();
+                    };
+
+                    match COUNTER.compare_exchange_weak(last, id, Relaxed, Relaxed) {
+                        Ok(_) => return ThreadId(NonZeroU64::new(id).unwrap()),
+                        Err(id) => last = id,
+                    }
+                }
+            } else {
+                use crate::sys_common::mutex::StaticMutex;
+
+                // It is UB to attempt to acquire this mutex reentrantly!
+                static GUARD: StaticMutex = StaticMutex::new();
+                static mut COUNTER: u64 = 0;
+
+                unsafe {
+                    let guard = GUARD.lock();
+
+                    let Some(id) = COUNTER.checked_add(1) else {
+                        drop(guard); // in case the panic handler ends up calling `ThreadId::new()`, avoid reentrant lock acquire.
+                        exhausted();
+                    };
+
+                    COUNTER = id;
+                    drop(guard);
+                    ThreadId(NonZeroU64::new(id).unwrap())
+                }
+            }
         }
     }