@@ -170,7 +170,6 @@ use crate::ptr::addr_of_mut;
170
170
use crate :: str;
171
171
use crate :: sync:: Arc ;
172
172
use crate :: sys:: thread as imp;
173
- use crate :: sys_common:: mutex;
174
173
use crate :: sys_common:: thread;
175
174
use crate :: sys_common:: thread_info;
176
175
use crate :: sys_common:: thread_parker:: Parker ;
@@ -1033,24 +1032,48 @@ pub struct ThreadId(NonZeroU64);
1033
1032
impl ThreadId {
1034
1033
// Generate a new unique thread ID.
1035
1034
fn new ( ) -> ThreadId {
1036
- // It is UB to attempt to acquire this mutex reentrantly!
1037
- static GUARD : mutex:: StaticMutex = mutex:: StaticMutex :: new ( ) ;
1038
- static mut COUNTER : u64 = 1 ;
1039
-
1040
- unsafe {
1041
- let guard = GUARD . lock ( ) ;
1042
-
1043
- // If we somehow use up all our bits, panic so that we're not
1044
- // covering up subtle bugs of IDs being reused.
1045
- if COUNTER == u64:: MAX {
1046
- drop ( guard) ; // in case the panic handler ends up calling `ThreadId::new()`, avoid reentrant lock acquire.
1047
- panic ! ( "failed to generate unique thread ID: bitspace exhausted" ) ;
1048
- }
1049
-
1050
- let id = COUNTER ;
1051
- COUNTER += 1 ;
1035
+ #[ cold]
1036
+ fn exhausted ( ) -> ! {
1037
+ panic ! ( "failed to generate unique thread ID: bitspace exhausted" )
1038
+ }
1052
1039
1053
- ThreadId ( NonZeroU64 :: new ( id) . unwrap ( ) )
1040
+ cfg_if:: cfg_if! {
1041
+ if #[ cfg( target_has_atomic = "64" ) ] {
1042
+ use crate :: sync:: atomic:: { AtomicU64 , Ordering :: Relaxed } ;
1043
+
1044
+ static COUNTER : AtomicU64 = AtomicU64 :: new( 0 ) ;
1045
+
1046
+ let mut last = COUNTER . load( Relaxed ) ;
1047
+ loop {
1048
+ let Some ( id) = last. checked_add( 1 ) else {
1049
+ exhausted( ) ;
1050
+ } ;
1051
+
1052
+ match COUNTER . compare_exchange_weak( last, id, Relaxed , Relaxed ) {
1053
+ Ok ( _) => return ThreadId ( NonZeroU64 :: new( id) . unwrap( ) ) ,
1054
+ Err ( id) => last = id,
1055
+ }
1056
+ }
1057
+ } else {
1058
+ use crate :: sys_common:: mutex:: StaticMutex ;
1059
+
1060
+ // It is UB to attempt to acquire this mutex reentrantly!
1061
+ static GUARD : StaticMutex = StaticMutex :: new( ) ;
1062
+ static mut COUNTER : u64 = 0 ;
1063
+
1064
+ unsafe {
1065
+ let guard = GUARD . lock( ) ;
1066
+
1067
+ let Some ( id) = COUNTER . checked_add( 1 ) else {
1068
+ drop( guard) ; // in case the panic handler ends up calling `ThreadId::new()`, avoid reentrant lock acquire.
1069
+ exhausted( ) ;
1070
+ } ;
1071
+
1072
+ COUNTER = id;
1073
+ drop( guard) ;
1074
+ ThreadId ( NonZeroU64 :: new( id) . unwrap( ) )
1075
+ }
1076
+ }
1054
1077
}
1055
1078
}
1056
1079
0 commit comments