159159mod tests;
160160
161161use crate :: any:: Any ;
162+ use crate :: cell:: SyncUnsafeCell ;
162163use crate :: cell:: { OnceCell , UnsafeCell } ;
163164use crate :: env;
164165use crate :: ffi:: { CStr , CString } ;
165166use crate :: fmt;
166167use crate :: io;
167168use crate :: marker:: PhantomData ;
169+ use crate :: mem:: MaybeUninit ;
168170use crate :: mem:: { self , forget} ;
169171use crate :: num:: NonZero ;
170172use crate :: panic;
@@ -530,7 +532,7 @@ impl Builder {
530532
531533 let f = MaybeDangling :: new ( f) ;
532534 let main = move || {
533- if let Some ( name) = their_thread. cname ( ) {
535+ if let Some ( name) = their_thread. 0 . name ( ) {
534536 imp:: Thread :: set_name ( name) ;
535537 }
536538
@@ -1162,7 +1164,7 @@ pub fn park_timeout(dur: Duration) {
11621164 let guard = PanicGuard ;
11631165 // SAFETY: park_timeout is called on the parker owned by this thread.
11641166 unsafe {
1165- current ( ) . inner . as_ref ( ) . parker ( ) . park_timeout ( dur) ;
1167+ current ( ) . 0 . parker ( ) . park_timeout ( dur) ;
11661168 }
11671169 // No panic occurred, do not abort.
11681170 forget ( guard) ;
@@ -1201,7 +1203,12 @@ pub fn park_timeout(dur: Duration) {
12011203pub struct ThreadId ( NonZero < u64 > ) ;
12021204
12031205impl ThreadId {
1204- // Generate a new unique thread ID.
1206+ /// Generate a new unique thread ID.
1207+ ///
1208+ /// The current implementation starts at 2 and increments from there.
1209+ ///
1210+ /// This is as `1` is the value for the main thread, so std::thread::Thread does not
1211+ /// have to store this value when creating the main thread's information.
12051212 fn new ( ) -> ThreadId {
12061213 #[ cold]
12071214 fn exhausted ( ) -> ! {
@@ -1212,7 +1219,7 @@ impl ThreadId {
12121219 if #[ cfg( target_has_atomic = "64" ) ] {
12131220 use crate :: sync:: atomic:: AtomicU64 ;
12141221
1215- static COUNTER : AtomicU64 = AtomicU64 :: new( 0 ) ;
1222+ static COUNTER : AtomicU64 = AtomicU64 :: new( 1 ) ;
12161223
12171224 let mut last = COUNTER . load( Ordering :: Relaxed ) ;
12181225 loop {
@@ -1228,7 +1235,7 @@ impl ThreadId {
12281235 } else {
12291236 use crate :: sync:: { Mutex , PoisonError } ;
12301237
1231- static COUNTER : Mutex <u64 > = Mutex :: new( 0 ) ;
1238+ static COUNTER : Mutex <u64 > = Mutex :: new( 1 ) ;
12321239
12331240 let mut counter = COUNTER . lock( ) . unwrap_or_else( PoisonError :: into_inner) ;
12341241 let Some ( id) = counter. checked_add( 1 ) else {
@@ -1245,6 +1252,11 @@ impl ThreadId {
12451252 }
12461253 }
12471254
1255+ /// Creates a ThreadId with the ID of the main thread.
1256+ fn new_main ( ) -> Self {
1257+ Self ( NonZero :: < u64 > :: MIN )
1258+ }
1259+
12481260 /// This returns a numeric identifier for the thread identified by this
12491261 /// `ThreadId`.
12501262 ///
@@ -1264,23 +1276,59 @@ impl ThreadId {
12641276// Thread
12651277////////////////////////////////////////////////////////////////////////////////
12661278
1267- /// The internal representation of a `Thread`'s name.
1268- enum ThreadName {
1269- Main ,
1270- Other ( CString ) ,
1271- Unnamed ,
1272- }
1279+ /// The parker for the main thread. This avoids having to allocate an Arc in `fn main() {}`.
1280+ static MAIN_PARKER : SyncUnsafeCell < MaybeUninit < Parker > > =
1281+ SyncUnsafeCell :: new ( MaybeUninit :: uninit ( ) ) ;
12731282
1274- /// The internal representation of a `Thread` handle
1275- struct Inner {
1276- name : ThreadName , // Guaranteed to be UTF-8
1283+ /// The internal representation of a `Thread` that is not the main thread.
1284+ struct OtherInner {
1285+ name : Option < CString > , // Guaranteed to be UTF-8
12771286 id : ThreadId ,
12781287 parker : Parker ,
12791288}
12801289
1290+ /// The internal representation of a `Thread` handle.
1291+ #[ derive( Clone ) ]
1292+ enum Inner {
1293+ /// Represents the main thread. May only be constructed by Thread::new_main.
1294+ Main ,
1295+ /// Represents any other thread.
1296+ Other ( Pin < Arc < OtherInner > > ) ,
1297+ }
1298+
12811299impl Inner {
1282- fn parker ( self : Pin < & Self > ) -> Pin < & Parker > {
1283- unsafe { Pin :: map_unchecked ( self , |inner| & inner. parker ) }
1300+ fn id ( & self ) -> ThreadId {
1301+ match self {
1302+ Self :: Main => ThreadId :: new_main ( ) ,
1303+ Self :: Other ( other) => other. id ,
1304+ }
1305+ }
1306+
1307+ fn name ( & self ) -> Option < & CStr > {
1308+ match self {
1309+ Self :: Main => Some ( c"main" ) ,
1310+ Self :: Other ( other) => other. name . as_deref ( ) ,
1311+ }
1312+ }
1313+
1314+ fn parker ( & self ) -> Pin < & Parker > {
1315+ match self {
1316+ Self :: Main => {
1317+ // Safety: MAIN_PARKER is only ever read in this function, which requires access
1318+ // to an existing `&Inner` value, which can only be accessed via the main thread
1319+ // giving away such an instance from `current()`, implying that initialization,
1320+ // the only write to `MAIN_PARKER`, has been completed.
1321+ let static_ref: & ' static MaybeUninit < Parker > = unsafe { & * MAIN_PARKER . get ( ) } ;
1322+
1323+ // Safety: MAIN_PARKER is initialised when Inner::Main is initialised.
1324+ let parker_ref = unsafe { static_ref. assume_init_ref ( ) } ;
1325+
1326+ Pin :: static_ref ( parker_ref)
1327+ }
1328+ Self :: Other ( inner) => unsafe {
1329+ Pin :: map_unchecked ( inner. as_ref ( ) , |inner| & inner. parker )
1330+ } ,
1331+ }
12841332 }
12851333}
12861334
@@ -1304,46 +1352,56 @@ impl Inner {
13041352/// docs of [`Builder`] and [`spawn`] for more details.
13051353///
13061354/// [`thread::current`]: current
1307- pub struct Thread {
1308- inner : Pin < Arc < Inner > > ,
1309- }
1355+ pub struct Thread ( Inner ) ;
13101356
13111357impl Thread {
13121358 /// Used only internally to construct a thread object without spawning.
13131359 ///
13141360 /// # Safety
13151361 /// `name` must be valid UTF-8.
13161362 pub ( crate ) unsafe fn new ( name : CString ) -> Thread {
1317- unsafe { Self :: new_inner ( ThreadName :: Other ( name) ) }
1363+ unsafe { Self :: new_inner ( Some ( name) ) }
13181364 }
13191365
13201366 pub ( crate ) fn new_unnamed ( ) -> Thread {
1321- unsafe { Self :: new_inner ( ThreadName :: Unnamed ) }
1367+ unsafe { Self :: new_inner ( None ) }
13221368 }
13231369
1324- // Used in runtime to construct main thread
1325- pub ( crate ) fn new_main ( ) -> Thread {
1326- unsafe { Self :: new_inner ( ThreadName :: Main ) }
1370+ /// Used in runtime to construct main thread
1371+ ///
1372+ /// # Safety
1373+ ///
1374+ /// This must only ever be called once, and must be called on the main thread.
1375+ pub ( crate ) unsafe fn new_main ( ) -> Thread {
1376+ // Safety: As this is only called once and on the main thread, nothing else is accessing MAIN_PARKER
1377+ // as the only other read occurs in Inner::parker *after* Inner::Main has been constructed,
1378+ // and this function is the only one that constructs Inner::Main.
1379+ //
1380+ // Pre-main thread spawning cannot hit this either, as the caller promises that this is only called on the main thread.
1381+ unsafe { Parker :: new_in_place ( MAIN_PARKER . get ( ) . cast ( ) ) }
1382+
1383+ Self ( Inner :: Main )
13271384 }
13281385
13291386 /// # Safety
1330- /// If `name` is `ThreadName::Other(_)`, the contained string must be valid UTF-8.
1331- unsafe fn new_inner ( name : ThreadName ) -> Thread {
1387+ ///
1388+ /// If `name` is `Some(_)`, the contained string must be valid UTF-8.
1389+ unsafe fn new_inner ( name : Option < CString > ) -> Thread {
13321390 // We have to use `unsafe` here to construct the `Parker` in-place,
13331391 // which is required for the UNIX implementation.
13341392 //
13351393 // SAFETY: We pin the Arc immediately after creation, so its address never
13361394 // changes.
13371395 let inner = unsafe {
1338- let mut arc = Arc :: < Inner > :: new_uninit ( ) ;
1396+ let mut arc = Arc :: < OtherInner > :: new_uninit ( ) ;
13391397 let ptr = Arc :: get_mut_unchecked ( & mut arc) . as_mut_ptr ( ) ;
13401398 addr_of_mut ! ( ( * ptr) . name) . write ( name) ;
13411399 addr_of_mut ! ( ( * ptr) . id) . write ( ThreadId :: new ( ) ) ;
13421400 Parker :: new_in_place ( addr_of_mut ! ( ( * ptr) . parker) ) ;
13431401 Pin :: new_unchecked ( arc. assume_init ( ) )
13441402 } ;
13451403
1346- Thread { inner }
1404+ Self ( Inner :: Other ( inner) )
13471405 }
13481406
13491407 /// Like the public [`park`], but callable on any handle. This is used to
@@ -1352,7 +1410,7 @@ impl Thread {
13521410 /// # Safety
13531411 /// May only be called from the thread to which this handle belongs.
13541412 pub ( crate ) unsafe fn park ( & self ) {
1355- unsafe { self . inner . as_ref ( ) . parker ( ) . park ( ) }
1413+ unsafe { self . 0 . parker ( ) . park ( ) }
13561414 }
13571415
13581416 /// Atomically makes the handle's token available if it is not already.
@@ -1388,7 +1446,7 @@ impl Thread {
13881446 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
13891447 #[ inline]
13901448 pub fn unpark ( & self ) {
1391- self . inner . as_ref ( ) . parker ( ) . unpark ( ) ;
1449+ self . 0 . parker ( ) . unpark ( ) ;
13921450 }
13931451
13941452 /// Gets the thread's unique identifier.
@@ -1408,7 +1466,7 @@ impl Thread {
14081466 #[ stable( feature = "thread_id" , since = "1.19.0" ) ]
14091467 #[ must_use]
14101468 pub fn id ( & self ) -> ThreadId {
1411- self . inner . id
1469+ self . 0 . id ( )
14121470 }
14131471
14141472 /// Gets the thread's name.
@@ -1451,15 +1509,7 @@ impl Thread {
14511509 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
14521510 #[ must_use]
14531511 pub fn name ( & self ) -> Option < & str > {
1454- self . cname ( ) . map ( |s| unsafe { str:: from_utf8_unchecked ( s. to_bytes ( ) ) } )
1455- }
1456-
1457- fn cname ( & self ) -> Option < & CStr > {
1458- match & self . inner . name {
1459- ThreadName :: Main => Some ( c"main" ) ,
1460- ThreadName :: Other ( other) => Some ( & other) ,
1461- ThreadName :: Unnamed => None ,
1462- }
1512+ self . 0 . name ( ) . map ( |s| unsafe { str:: from_utf8_unchecked ( s. to_bytes ( ) ) } )
14631513 }
14641514}
14651515
0 commit comments