159
159
mod tests;
160
160
161
161
use crate :: any:: Any ;
162
+ use crate :: cell:: SyncUnsafeCell ;
162
163
use crate :: cell:: { OnceCell , UnsafeCell } ;
163
164
use crate :: ffi:: { CStr , CString } ;
164
165
use crate :: fmt;
165
166
use crate :: io;
166
167
use crate :: marker:: PhantomData ;
168
+ use crate :: mem:: MaybeUninit ;
167
169
use crate :: mem:: { self , forget} ;
168
170
use crate :: num:: NonZero ;
169
171
use crate :: panic;
@@ -511,7 +513,7 @@ impl Builder {
511
513
512
514
let f = MaybeDangling :: new ( f) ;
513
515
let main = move || {
514
- if let Some ( name) = their_thread. cname ( ) {
516
+ if let Some ( name) = their_thread. 0 . name ( ) {
515
517
imp:: Thread :: set_name ( name) ;
516
518
}
517
519
@@ -1143,7 +1145,7 @@ pub fn park_timeout(dur: Duration) {
1143
1145
let guard = PanicGuard ;
1144
1146
// SAFETY: park_timeout is called on the parker owned by this thread.
1145
1147
unsafe {
1146
- current ( ) . inner . as_ref ( ) . parker ( ) . park_timeout ( dur) ;
1148
+ current ( ) . 0 . parker ( ) . park_timeout ( dur) ;
1147
1149
}
1148
1150
// No panic occurred, do not abort.
1149
1151
forget ( guard) ;
@@ -1182,7 +1184,12 @@ pub fn park_timeout(dur: Duration) {
1182
1184
pub struct ThreadId ( NonZero < u64 > ) ;
1183
1185
1184
1186
impl ThreadId {
1185
- // Generate a new unique thread ID.
1187
+ /// Generate a new unique thread ID.
1188
+ ///
1189
+ /// The current implementation starts at 2 and increments from there.
1190
+ ///
1191
+ /// This is as `1` is the value for the main thread, so std::thread::Thread does not
1192
+ /// have to store this value when creating the main thread's information.
1186
1193
fn new ( ) -> ThreadId {
1187
1194
#[ cold]
1188
1195
fn exhausted ( ) -> ! {
@@ -1193,7 +1200,7 @@ impl ThreadId {
1193
1200
if #[ cfg( target_has_atomic = "64" ) ] {
1194
1201
use crate :: sync:: atomic:: { AtomicU64 , Ordering :: Relaxed } ;
1195
1202
1196
- static COUNTER : AtomicU64 = AtomicU64 :: new( 0 ) ;
1203
+ static COUNTER : AtomicU64 = AtomicU64 :: new( 1 ) ;
1197
1204
1198
1205
let mut last = COUNTER . load( Relaxed ) ;
1199
1206
loop {
@@ -1209,7 +1216,7 @@ impl ThreadId {
1209
1216
} else {
1210
1217
use crate :: sync:: { Mutex , PoisonError } ;
1211
1218
1212
- static COUNTER : Mutex <u64 > = Mutex :: new( 0 ) ;
1219
+ static COUNTER : Mutex <u64 > = Mutex :: new( 1 ) ;
1213
1220
1214
1221
let mut counter = COUNTER . lock( ) . unwrap_or_else( PoisonError :: into_inner) ;
1215
1222
let Some ( id) = counter. checked_add( 1 ) else {
@@ -1226,6 +1233,11 @@ impl ThreadId {
1226
1233
}
1227
1234
}
1228
1235
1236
+ /// Creates a ThreadId with the ID of the main thread.
1237
+ fn new_main ( ) -> Self {
1238
+ Self ( NonZero :: < u64 > :: MIN )
1239
+ }
1240
+
1229
1241
/// This returns a numeric identifier for the thread identified by this
1230
1242
/// `ThreadId`.
1231
1243
///
@@ -1245,23 +1257,54 @@ impl ThreadId {
1245
1257
// Thread
1246
1258
////////////////////////////////////////////////////////////////////////////////
1247
1259
1248
- /// The internal representation of a `Thread`'s name.
1249
- enum ThreadName {
1250
- Main ,
1251
- Other ( CString ) ,
1252
- Unnamed ,
1253
- }
1260
+ /// The parker for the main thread. This avoids having to allocate an Arc in `fn main() {}`.
1261
+ static MAIN_PARKER : SyncUnsafeCell < MaybeUninit < Parker > > =
1262
+ SyncUnsafeCell :: new ( MaybeUninit :: uninit ( ) ) ;
1254
1263
1255
- /// The internal representation of a `Thread` handle
1256
- struct Inner {
1257
- name : ThreadName , // Guaranteed to be UTF-8
1264
+ /// The internal representation of a `Thread` that is not the main thread.
1265
+ struct OtherInner {
1266
+ name : Option < CString > , // Guaranteed to be UTF-8
1258
1267
id : ThreadId ,
1259
1268
parker : Parker ,
1260
1269
}
1261
1270
1271
+ /// The internal representation of a `Thread` handle.
1272
+ #[ derive( Clone ) ]
1273
+ enum Inner {
1274
+ Main ,
1275
+ Other ( Pin < Arc < OtherInner > > ) ,
1276
+ }
1277
+
1262
1278
impl Inner {
1263
- fn parker ( self : Pin < & Self > ) -> Pin < & Parker > {
1264
- unsafe { Pin :: map_unchecked ( self , |inner| & inner. parker ) }
1279
+ fn id ( & self ) -> ThreadId {
1280
+ match self {
1281
+ Self :: Main => ThreadId :: new_main ( ) ,
1282
+ Self :: Other ( other) => other. id ,
1283
+ }
1284
+ }
1285
+
1286
+ fn name ( & self ) -> Option < & CStr > {
1287
+ match self {
1288
+ Self :: Main => Some ( c"main" ) ,
1289
+ Self :: Other ( other) => other. name . as_deref ( ) ,
1290
+ }
1291
+ }
1292
+
1293
+ fn parker ( & self ) -> Pin < & Parker > {
1294
+ match self {
1295
+ Self :: Main => {
1296
+ // Safety: MAIN_PARKER only ever has a mutable reference when Inner::Main is initialised.
1297
+ let uninit_ref: & ' static MaybeUninit < Parker > = unsafe { & * MAIN_PARKER . get ( ) } ;
1298
+
1299
+ // Safety: MAIN_PARKER is initialised when Inner::Main is initialised.
1300
+ let parker_ref = unsafe { uninit_ref. assume_init_ref ( ) } ;
1301
+
1302
+ Pin :: static_ref ( parker_ref)
1303
+ }
1304
+ Self :: Other ( inner) => unsafe {
1305
+ Pin :: map_unchecked ( inner. as_ref ( ) , |inner| & inner. parker )
1306
+ } ,
1307
+ }
1265
1308
}
1266
1309
}
1267
1310
@@ -1285,41 +1328,37 @@ impl Inner {
1285
1328
/// docs of [`Builder`] and [`spawn`] for more details.
1286
1329
///
1287
1330
/// [`thread::current`]: current
1288
- pub struct Thread {
1289
- inner : Pin < Arc < Inner > > ,
1290
- }
1331
+ pub struct Thread ( Inner ) ;
1291
1332
1292
1333
impl Thread {
1293
1334
// Used only internally to construct a thread object without spawning
1294
1335
pub ( crate ) fn new ( name : Option < CString > ) -> Thread {
1295
- if let Some ( name) = name {
1296
- Self :: new_inner ( ThreadName :: Other ( name) )
1297
- } else {
1298
- Self :: new_inner ( ThreadName :: Unnamed )
1299
- }
1300
- }
1301
-
1302
- // Used in runtime to construct main thread
1303
- pub ( crate ) fn new_main ( ) -> Thread {
1304
- Self :: new_inner ( ThreadName :: Main )
1305
- }
1306
-
1307
- fn new_inner ( name : ThreadName ) -> Thread {
1308
1336
// We have to use `unsafe` here to construct the `Parker` in-place,
1309
1337
// which is required for the UNIX implementation.
1310
1338
//
1311
1339
// SAFETY: We pin the Arc immediately after creation, so its address never
1312
1340
// changes.
1313
1341
let inner = unsafe {
1314
- let mut arc = Arc :: < Inner > :: new_uninit ( ) ;
1342
+ let mut arc = Arc :: < OtherInner > :: new_uninit ( ) ;
1315
1343
let ptr = Arc :: get_mut_unchecked ( & mut arc) . as_mut_ptr ( ) ;
1316
1344
addr_of_mut ! ( ( * ptr) . name) . write ( name) ;
1317
1345
addr_of_mut ! ( ( * ptr) . id) . write ( ThreadId :: new ( ) ) ;
1318
1346
Parker :: new_in_place ( addr_of_mut ! ( ( * ptr) . parker) ) ;
1319
1347
Pin :: new_unchecked ( arc. assume_init ( ) )
1320
1348
} ;
1321
1349
1322
- Thread { inner }
1350
+ Self ( Inner :: Other ( inner) )
1351
+ }
1352
+
1353
+ /// # Safety
1354
+ ///
1355
+ /// This must only ever be called once, and must be called on the main thread.
1356
+ pub ( crate ) unsafe fn new_main ( ) -> Thread {
1357
+ // Safety: Caller responsible for holding the mutable invariant and
1358
+ // Parker::new_in_place does not read from the uninit value.
1359
+ unsafe { Parker :: new_in_place ( MAIN_PARKER . get ( ) . cast ( ) ) }
1360
+
1361
+ Self ( Inner :: Main )
1323
1362
}
1324
1363
1325
1364
/// Like the public [`park`], but callable on any handle. This is used to
@@ -1328,7 +1367,7 @@ impl Thread {
1328
1367
/// # Safety
1329
1368
/// May only be called from the thread to which this handle belongs.
1330
1369
pub ( crate ) unsafe fn park ( & self ) {
1331
- unsafe { self . inner . as_ref ( ) . parker ( ) . park ( ) }
1370
+ unsafe { self . 0 . parker ( ) . park ( ) }
1332
1371
}
1333
1372
1334
1373
/// Atomically makes the handle's token available if it is not already.
@@ -1364,7 +1403,7 @@ impl Thread {
1364
1403
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1365
1404
#[ inline]
1366
1405
pub fn unpark ( & self ) {
1367
- self . inner . as_ref ( ) . parker ( ) . unpark ( ) ;
1406
+ self . 0 . parker ( ) . unpark ( ) ;
1368
1407
}
1369
1408
1370
1409
/// Gets the thread's unique identifier.
@@ -1384,7 +1423,7 @@ impl Thread {
1384
1423
#[ stable( feature = "thread_id" , since = "1.19.0" ) ]
1385
1424
#[ must_use]
1386
1425
pub fn id ( & self ) -> ThreadId {
1387
- self . inner . id
1426
+ self . 0 . id ( )
1388
1427
}
1389
1428
1390
1429
/// Gets the thread's name.
@@ -1427,15 +1466,7 @@ impl Thread {
1427
1466
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1428
1467
#[ must_use]
1429
1468
pub fn name ( & self ) -> Option < & str > {
1430
- self . cname ( ) . map ( |s| unsafe { str:: from_utf8_unchecked ( s. to_bytes ( ) ) } )
1431
- }
1432
-
1433
- fn cname ( & self ) -> Option < & CStr > {
1434
- match & self . inner . name {
1435
- ThreadName :: Main => Some ( c"main" ) ,
1436
- ThreadName :: Other ( other) => Some ( & other) ,
1437
- ThreadName :: Unnamed => None ,
1438
- }
1469
+ self . 0 . name ( ) . map ( |s| unsafe { str:: from_utf8_unchecked ( s. to_bytes ( ) ) } )
1439
1470
}
1440
1471
}
1441
1472
0 commit comments