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 :: env;
164
165
use crate :: ffi:: { CStr , CString } ;
165
166
use crate :: fmt;
166
167
use crate :: io;
167
168
use crate :: marker:: PhantomData ;
169
+ use crate :: mem:: MaybeUninit ;
168
170
use crate :: mem:: { self , forget} ;
169
171
use crate :: num:: NonZero ;
170
172
use crate :: panic;
@@ -530,7 +532,7 @@ impl Builder {
530
532
531
533
let f = MaybeDangling :: new ( f) ;
532
534
let main = move || {
533
- if let Some ( name) = their_thread. cname ( ) {
535
+ if let Some ( name) = their_thread. 0 . name ( ) {
534
536
imp:: Thread :: set_name ( name) ;
535
537
}
536
538
@@ -1168,7 +1170,7 @@ pub fn park_timeout(dur: Duration) {
1168
1170
let guard = PanicGuard ;
1169
1171
// SAFETY: park_timeout is called on the parker owned by this thread.
1170
1172
unsafe {
1171
- current ( ) . inner . as_ref ( ) . parker ( ) . park_timeout ( dur) ;
1173
+ current ( ) . 0 . parker ( ) . park_timeout ( dur) ;
1172
1174
}
1173
1175
// No panic occurred, do not abort.
1174
1176
forget ( guard) ;
@@ -1207,7 +1209,12 @@ pub fn park_timeout(dur: Duration) {
1207
1209
pub struct ThreadId ( NonZero < u64 > ) ;
1208
1210
1209
1211
impl ThreadId {
1210
- // Generate a new unique thread ID.
1212
+ /// Generate a new unique thread ID.
1213
+ ///
1214
+ /// The current implementation starts at 2 and increments from there.
1215
+ ///
1216
+ /// This is as `1` is the value for the main thread, so std::thread::Thread does not
1217
+ /// have to store this value when creating the main thread's information.
1211
1218
fn new ( ) -> ThreadId {
1212
1219
#[ cold]
1213
1220
fn exhausted ( ) -> ! {
@@ -1218,7 +1225,7 @@ impl ThreadId {
1218
1225
if #[ cfg( target_has_atomic = "64" ) ] {
1219
1226
use crate :: sync:: atomic:: AtomicU64 ;
1220
1227
1221
- static COUNTER : AtomicU64 = AtomicU64 :: new( 0 ) ;
1228
+ static COUNTER : AtomicU64 = AtomicU64 :: new( 1 ) ;
1222
1229
1223
1230
let mut last = COUNTER . load( Ordering :: Relaxed ) ;
1224
1231
loop {
@@ -1234,7 +1241,7 @@ impl ThreadId {
1234
1241
} else {
1235
1242
use crate :: sync:: { Mutex , PoisonError } ;
1236
1243
1237
- static COUNTER : Mutex <u64 > = Mutex :: new( 0 ) ;
1244
+ static COUNTER : Mutex <u64 > = Mutex :: new( 1 ) ;
1238
1245
1239
1246
let mut counter = COUNTER . lock( ) . unwrap_or_else( PoisonError :: into_inner) ;
1240
1247
let Some ( id) = counter. checked_add( 1 ) else {
@@ -1251,6 +1258,11 @@ impl ThreadId {
1251
1258
}
1252
1259
}
1253
1260
1261
+ /// Creates a ThreadId with the ID of the main thread.
1262
+ fn new_main ( ) -> Self {
1263
+ Self ( NonZero :: < u64 > :: MIN )
1264
+ }
1265
+
1254
1266
/// This returns a numeric identifier for the thread identified by this
1255
1267
/// `ThreadId`.
1256
1268
///
@@ -1270,23 +1282,54 @@ impl ThreadId {
1270
1282
// Thread
1271
1283
////////////////////////////////////////////////////////////////////////////////
1272
1284
1273
- /// The internal representation of a `Thread`'s name.
1274
- enum ThreadName {
1275
- Main ,
1276
- Other ( CString ) ,
1277
- Unnamed ,
1278
- }
1285
+ /// The parker for the main thread. This avoids having to allocate an Arc in `fn main() {}`.
1286
+ static MAIN_PARKER : SyncUnsafeCell < MaybeUninit < Parker > > =
1287
+ SyncUnsafeCell :: new ( MaybeUninit :: uninit ( ) ) ;
1279
1288
1280
- /// The internal representation of a `Thread` handle
1281
- struct Inner {
1282
- name : ThreadName , // Guaranteed to be UTF-8
1289
+ /// The internal representation of a `Thread` that is not the main thread.
1290
+ struct OtherInner {
1291
+ name : Option < CString > , // Guaranteed to be UTF-8
1283
1292
id : ThreadId ,
1284
1293
parker : Parker ,
1285
1294
}
1286
1295
1296
+ /// The internal representation of a `Thread` handle.
1297
+ #[ derive( Clone ) ]
1298
+ enum Inner {
1299
+ Main ,
1300
+ Other ( Pin < Arc < OtherInner > > ) ,
1301
+ }
1302
+
1287
1303
impl Inner {
1288
- fn parker ( self : Pin < & Self > ) -> Pin < & Parker > {
1289
- unsafe { Pin :: map_unchecked ( self , |inner| & inner. parker ) }
1304
+ fn id ( & self ) -> ThreadId {
1305
+ match self {
1306
+ Self :: Main => ThreadId :: new_main ( ) ,
1307
+ Self :: Other ( other) => other. id ,
1308
+ }
1309
+ }
1310
+
1311
+ fn name ( & self ) -> Option < & CStr > {
1312
+ match self {
1313
+ Self :: Main => Some ( c"main" ) ,
1314
+ Self :: Other ( other) => other. name . as_deref ( ) ,
1315
+ }
1316
+ }
1317
+
1318
+ fn parker ( & self ) -> Pin < & Parker > {
1319
+ match self {
1320
+ Self :: Main => {
1321
+ // Safety: MAIN_PARKER only ever has a mutable reference when Inner::Main is initialised.
1322
+ let static_ref: & ' static MaybeUninit < Parker > = unsafe { & * MAIN_PARKER . get ( ) } ;
1323
+
1324
+ // Safety: MAIN_PARKER is initialised when Inner::Main is initialised.
1325
+ let parker_ref = unsafe { static_ref. assume_init_ref ( ) } ;
1326
+
1327
+ Pin :: static_ref ( parker_ref)
1328
+ }
1329
+ Self :: Other ( inner) => unsafe {
1330
+ Pin :: map_unchecked ( inner. as_ref ( ) , |inner| & inner. parker )
1331
+ } ,
1332
+ }
1290
1333
}
1291
1334
}
1292
1335
@@ -1310,46 +1353,53 @@ impl Inner {
1310
1353
/// docs of [`Builder`] and [`spawn`] for more details.
1311
1354
///
1312
1355
/// [`thread::current`]: current
1313
- pub struct Thread {
1314
- inner : Pin < Arc < Inner > > ,
1315
- }
1356
+ pub struct Thread ( Inner ) ;
1316
1357
1317
1358
impl Thread {
1318
1359
/// Used only internally to construct a thread object without spawning.
1319
1360
///
1320
1361
/// # Safety
1321
1362
/// `name` must be valid UTF-8.
1322
1363
pub ( crate ) unsafe fn new ( name : CString ) -> Thread {
1323
- unsafe { Self :: new_inner ( ThreadName :: Other ( name) ) }
1364
+ unsafe { Self :: new_inner ( Some ( name) ) }
1324
1365
}
1325
1366
1326
1367
pub ( crate ) fn new_unnamed ( ) -> Thread {
1327
- unsafe { Self :: new_inner ( ThreadName :: Unnamed ) }
1368
+ unsafe { Self :: new_inner ( None ) }
1328
1369
}
1329
1370
1330
- // Used in runtime to construct main thread
1331
- pub ( crate ) fn new_main ( ) -> Thread {
1332
- unsafe { Self :: new_inner ( ThreadName :: Main ) }
1371
+ /// Used in runtime to construct main thread
1372
+ ///
1373
+ /// # Safety
1374
+ ///
1375
+ /// This must only ever be called once, and must be called on the main thread.
1376
+ pub ( crate ) unsafe fn new_main ( ) -> Thread {
1377
+ // Safety: Caller responsible for holding the mutable invariant and
1378
+ // Parker::new_in_place does not read from the uninit value.
1379
+ unsafe { Parker :: new_in_place ( MAIN_PARKER . get ( ) . cast ( ) ) }
1380
+
1381
+ Self ( Inner :: Main )
1333
1382
}
1334
1383
1335
1384
/// # Safety
1336
- /// If `name` is `ThreadName::Other(_)`, the contained string must be valid UTF-8.
1337
- unsafe fn new_inner ( name : ThreadName ) -> Thread {
1385
+ ///
1386
+ /// If `name` is `Some(_)`, the contained string must be valid UTF-8.
1387
+ unsafe fn new_inner ( name : Option < CString > ) -> Thread {
1338
1388
// We have to use `unsafe` here to construct the `Parker` in-place,
1339
1389
// which is required for the UNIX implementation.
1340
1390
//
1341
1391
// SAFETY: We pin the Arc immediately after creation, so its address never
1342
1392
// changes.
1343
1393
let inner = unsafe {
1344
- let mut arc = Arc :: < Inner > :: new_uninit ( ) ;
1394
+ let mut arc = Arc :: < OtherInner > :: new_uninit ( ) ;
1345
1395
let ptr = Arc :: get_mut_unchecked ( & mut arc) . as_mut_ptr ( ) ;
1346
1396
addr_of_mut ! ( ( * ptr) . name) . write ( name) ;
1347
1397
addr_of_mut ! ( ( * ptr) . id) . write ( ThreadId :: new ( ) ) ;
1348
1398
Parker :: new_in_place ( addr_of_mut ! ( ( * ptr) . parker) ) ;
1349
1399
Pin :: new_unchecked ( arc. assume_init ( ) )
1350
1400
} ;
1351
1401
1352
- Thread { inner }
1402
+ Self ( Inner :: Other ( inner) )
1353
1403
}
1354
1404
1355
1405
/// Like the public [`park`], but callable on any handle. This is used to
@@ -1358,7 +1408,7 @@ impl Thread {
1358
1408
/// # Safety
1359
1409
/// May only be called from the thread to which this handle belongs.
1360
1410
pub ( crate ) unsafe fn park ( & self ) {
1361
- unsafe { self . inner . as_ref ( ) . parker ( ) . park ( ) }
1411
+ unsafe { self . 0 . parker ( ) . park ( ) }
1362
1412
}
1363
1413
1364
1414
/// Atomically makes the handle's token available if it is not already.
@@ -1394,7 +1444,7 @@ impl Thread {
1394
1444
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1395
1445
#[ inline]
1396
1446
pub fn unpark ( & self ) {
1397
- self . inner . as_ref ( ) . parker ( ) . unpark ( ) ;
1447
+ self . 0 . parker ( ) . unpark ( ) ;
1398
1448
}
1399
1449
1400
1450
/// Gets the thread's unique identifier.
@@ -1414,7 +1464,7 @@ impl Thread {
1414
1464
#[ stable( feature = "thread_id" , since = "1.19.0" ) ]
1415
1465
#[ must_use]
1416
1466
pub fn id ( & self ) -> ThreadId {
1417
- self . inner . id
1467
+ self . 0 . id ( )
1418
1468
}
1419
1469
1420
1470
/// Gets the thread's name.
@@ -1457,15 +1507,7 @@ impl Thread {
1457
1507
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1458
1508
#[ must_use]
1459
1509
pub fn name ( & self ) -> Option < & str > {
1460
- self . cname ( ) . map ( |s| unsafe { str:: from_utf8_unchecked ( s. to_bytes ( ) ) } )
1461
- }
1462
-
1463
- fn cname ( & self ) -> Option < & CStr > {
1464
- match & self . inner . name {
1465
- ThreadName :: Main => Some ( c"main" ) ,
1466
- ThreadName :: Other ( other) => Some ( & other) ,
1467
- ThreadName :: Unnamed => None ,
1468
- }
1510
+ self . 0 . name ( ) . map ( |s| unsafe { str:: from_utf8_unchecked ( s. to_bytes ( ) ) } )
1469
1511
}
1470
1512
}
1471
1513
0 commit comments