Remove the Arc rt::init allocation for thread info · qinheping/verify-rust-std@bac3891 (original) (raw)
`@@ -158,9 +158,12 @@
`
158
158
`#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
`
159
159
`mod tests;
`
160
160
``
``
161
`+
use core::cell::SyncUnsafeCell;
`
``
162
`+
use core::ffi::CStr;
`
``
163
`+
use core::mem::MaybeUninit;
`
``
164
+
161
165
`use crate::any::Any;
`
162
166
`use crate::cell::UnsafeCell;
`
163
``
`-
use crate::ffi::CStr;
`
164
167
`use crate:📑:PhantomData;
`
165
168
`use crate::mem::{self, ManuallyDrop, forget};
`
166
169
`use crate::num::NonZero;
`
`@@ -1125,7 +1128,7 @@ pub fn park_timeout(dur: Duration) {
`
1125
1128
`let guard = PanicGuard;
`
1126
1129
`// SAFETY: park_timeout is called on the parker owned by this thread.
`
1127
1130
`unsafe {
`
1128
``
`-
current().inner.as_ref().parker().park_timeout(dur);
`
``
1131
`+
current().0.parker().park_timeout(dur);
`
1129
1132
`}
`
1130
1133
`// No panic occurred, do not abort.
`
1131
1134
`forget(guard);
`
`@@ -1232,65 +1235,114 @@ impl ThreadId {
`
1232
1235
`// Thread
`
1233
1236
`////////////////////////////////////////////////////////////////////////////////
`
1234
1237
``
1235
``
`` -
/// The internal representation of a Thread
's name.
``
1236
``
`-
enum ThreadName {
`
1237
``
`-
Main,
`
1238
``
`-
Other(ThreadNameString),
`
1239
``
`-
Unnamed,
`
1240
``
`-
}
`
1241
``
-
1242
1238
`// This module ensures private fields are kept private, which is necessary to enforce the safety requirements.
`
1243
1239
`mod thread_name_string {
`
1244
1240
`use core::str;
`
1245
1241
``
1246
``
`-
use super::ThreadName;
`
1247
1242
`use crate::ffi::{CStr, CString};
`
1248
1243
``
1249
1244
`` /// Like a String
it's guaranteed UTF-8 and like a CString
it's null terminated.
``
1250
1245
`pub(crate) struct ThreadNameString {
`
1251
1246
`inner: CString,
`
1252
1247
`}
`
``
1248
+
``
1249
`+
impl ThreadNameString {
`
``
1250
`+
pub fn as_str(&self) -> &str {
`
``
1251
`` +
// SAFETY: self.inner
is only initialised via String
, which upholds the validity invariant of str
.
``
``
1252
`+
unsafe { str::from_utf8_unchecked(self.inner.to_bytes()) }
`
``
1253
`+
}
`
``
1254
`+
}
`
``
1255
+
1253
1256
`impl core::ops::Deref for ThreadNameString {
`
1254
1257
`type Target = CStr;
`
1255
1258
`fn deref(&self) -> &CStr {
`
1256
1259
`&self.inner
`
1257
1260
`}
`
1258
1261
`}
`
``
1262
+
1259
1263
`impl From for ThreadNameString {
`
1260
1264
`fn from(s: String) -> Self {
`
1261
1265
`Self {
`
1262
1266
`inner: CString::new(s).expect("thread name may not contain interior null bytes"),
`
1263
1267
`}
`
1264
1268
`}
`
1265
1269
`}
`
1266
``
`-
impl ThreadName {
`
1267
``
`-
pub fn as_cstr(&self) -> Option<&CStr> {
`
1268
``
`-
match self {
`
1269
``
`-
ThreadName::Main => Some(c"main"),
`
1270
``
`-
ThreadName::Other(other) => Some(other),
`
1271
``
`-
ThreadName::Unnamed => None,
`
1272
``
`-
}
`
1273
``
`-
}
`
1274
``
-
1275
``
`-
pub fn as_str(&self) -> Option<&str> {
`
1276
``
`` -
// SAFETY: as_cstr
can only return Some
for a fixed CStr or a ThreadNameString
,
``
1277
``
`-
// which is guaranteed to be UTF-8.
`
1278
``
`-
self.as_cstr().map(|s| unsafe { str::from_utf8_unchecked(s.to_bytes()) })
`
1279
``
`-
}
`
1280
``
`-
}
`
1281
1270
`}
`
1282
1271
`pub(crate) use thread_name_string::ThreadNameString;
`
1283
1272
``
1284
``
`` -
/// The internal representation of a Thread
handle
``
1285
``
`-
struct Inner {
`
1286
``
`-
name: ThreadName, // Guaranteed to be UTF-8
`
``
1273
`+
static MAIN_THREAD_INFO: SyncUnsafeCell<(MaybeUninit, MaybeUninit)> =
`
``
1274
`+
SyncUnsafeCell::new((MaybeUninit::uninit(), MaybeUninit::uninit()));
`
``
1275
+
``
1276
`` +
/// The internal representation of a Thread
that is not the main thread.
``
``
1277
`+
struct OtherInner {
`
``
1278
`+
name: Option,
`
1287
1279
`id: ThreadId,
`
1288
1280
`parker: Parker,
`
1289
1281
`}
`
1290
1282
``
``
1283
`` +
/// The internal representation of a Thread
handle.
``
``
1284
`+
#[derive(Clone)]
`
``
1285
`+
enum Inner {
`
``
1286
`+
/// Represents the main thread. May only be constructed by Thread::new_main.
`
``
1287
`+
Main(&'static (ThreadId, Parker)),
`
``
1288
`+
/// Represents any other thread.
`
``
1289
`+
Other(Pin<Arc>),
`
``
1290
`+
}
`
``
1291
+
1291
1292
`impl Inner {
`
1292
``
`-
fn parker(self: Pin<&Self>) -> Pin<&Parker> {
`
1293
``
`-
unsafe { Pin::map_unchecked(self, |inner| &inner.parker) }
`
``
1293
`+
fn id(&self) -> ThreadId {
`
``
1294
`+
match self {
`
``
1295
`+
Self::Main((thread_id, _)) => *thread_id,
`
``
1296
`+
Self::Other(other) => other.id,
`
``
1297
`+
}
`
``
1298
`+
}
`
``
1299
+
``
1300
`+
fn cname(&self) -> Option<&CStr> {
`
``
1301
`+
match self {
`
``
1302
`+
Self::Main(_) => Some(c"main"),
`
``
1303
`+
Self::Other(other) => other.name.as_deref(),
`
``
1304
`+
}
`
``
1305
`+
}
`
``
1306
+
``
1307
`+
fn name(&self) -> Option<&str> {
`
``
1308
`+
match self {
`
``
1309
`+
Self::Main(_) => Some("main"),
`
``
1310
`+
Self::Other(other) => other.name.as_ref().map(ThreadNameString::as_str),
`
``
1311
`+
}
`
``
1312
`+
}
`
``
1313
+
``
1314
`+
fn into_raw(self) -> *const () {
`
``
1315
`+
match self {
`
``
1316
`` +
// Just return the pointer to MAIN_THREAD_INFO
.
``
``
1317
`+
Self::Main(ptr) => crate::ptr::from_ref(ptr).cast(),
`
``
1318
`+
Self::Other(arc) => {
`
``
1319
`` +
// Safety: We only expose an opaque pointer, which maintains the Pin
invariant.
``
``
1320
`+
let inner = unsafe { Pin::into_inner_unchecked(arc) };
`
``
1321
`+
Arc::into_raw(inner) as *const ()
`
``
1322
`+
}
`
``
1323
`+
}
`
``
1324
`+
}
`
``
1325
+
``
1326
`+
/// # Safety
`
``
1327
`+
///
`
``
1328
`` +
/// See [Thread::from_raw
].
``
``
1329
`+
unsafe fn from_raw(ptr: *const ()) -> Self {
`
``
1330
`` +
// If the pointer is to MAIN_THREAD_INFO
, we know it is the Main
variant.
``
``
1331
`+
if crate::ptr::eq(ptr.cast(), &MAIN_THREAD_INFO) {
`
``
1332
`+
Self::Main(unsafe { &*ptr.cast() })
`
``
1333
`+
} else {
`
``
1334
`+
// Safety: Upheld by caller
`
``
1335
`+
Self::Other(unsafe { Pin::new_unchecked(Arc::from_raw(ptr as *const OtherInner)) })
`
``
1336
`+
}
`
``
1337
`+
}
`
``
1338
+
``
1339
`+
fn parker(&self) -> Pin<&Parker> {
`
``
1340
`+
match self {
`
``
1341
`+
Self::Main((_, parker_ref)) => Pin::static_ref(parker_ref),
`
``
1342
`+
Self::Other(inner) => unsafe {
`
``
1343
`+
Pin::map_unchecked(inner.as_ref(), |inner| &inner.parker)
`
``
1344
`+
},
`
``
1345
`+
}
`
1294
1346
`}
`
1295
1347
`}
`
1296
1348
``
`@@ -1314,41 +1366,55 @@ impl Inner {
`
1314
1366
`` /// docs of [Builder
] and [spawn
] for more details.
``
1315
1367
`///
`
1316
1368
`` /// [thread::current
]: current::current
``
1317
``
`-
pub struct Thread {
`
1318
``
`-
inner: Pin<Arc>,
`
1319
``
`-
}
`
``
1369
`+
pub struct Thread(Inner);
`
1320
1370
``
1321
1371
`impl Thread {
`
1322
1372
`/// Used only internally to construct a thread object without spawning.
`
1323
1373
`pub(crate) fn new(id: ThreadId, name: String) -> Thread {
`
1324
``
`-
Self::new_inner(id, ThreadName::Other(name.into()))
`
``
1374
`+
Self::new_inner(id, Some(ThreadNameString::from(name)))
`
1325
1375
`}
`
1326
1376
``
1327
1377
`pub(crate) fn new_unnamed(id: ThreadId) -> Thread {
`
1328
``
`-
Self::new_inner(id, ThreadName::Unnamed)
`
``
1378
`+
Self::new_inner(id, None)
`
1329
1379
`}
`
1330
1380
``
1331
``
`-
/// Constructs the thread handle for the main thread.
`
1332
``
`-
pub(crate) fn new_main(id: ThreadId) -> Thread {
`
1333
``
`-
Self::new_inner(id, ThreadName::Main)
`
``
1381
`+
/// Used in runtime to construct main thread
`
``
1382
`+
///
`
``
1383
`+
/// # Safety
`
``
1384
`+
///
`
``
1385
`+
/// This must only ever be called once, and must be called on the main thread.
`
``
1386
`+
pub(crate) unsafe fn new_main(thread_id: ThreadId) -> Thread {
`
``
1387
`+
// Safety: As this is only called once and on the main thread, nothing else is accessing MAIN_THREAD_INFO
`
``
1388
`` +
// as the only other read occurs in main_thread_info
after the main thread has been constructed,
``
``
1389
`+
// and this function is the only one that constructs the main thread.
`
``
1390
`+
//
`
``
1391
`+
// Pre-main thread spawning cannot hit this either, as the caller promises that this is only called on the main thread.
`
``
1392
`+
let main_thread_info = unsafe { &mut *MAIN_THREAD_INFO.get() };
`
``
1393
+
``
1394
`+
unsafe { Parker::new_in_place((&raw mut main_thread_info.1).cast()) };
`
``
1395
`+
main_thread_info.0.write(thread_id);
`
``
1396
+
``
1397
`` +
// Store a 'static
ref to the initialised ThreadId and Parker,
``
``
1398
`+
// to avoid having to repeatedly prove initialisation.
`
``
1399
`+
Self(Inner::Main(unsafe { &*MAIN_THREAD_INFO.get().cast() }))
`
1334
1400
`}
`
1335
1401
``
1336
``
`-
fn new_inner(id: ThreadId, name: ThreadName) -> Thread {
`
``
1402
`+
fn new_inner(id: ThreadId, name: Option) -> Thread {
`
1337
1403
`` // We have to use unsafe
here to construct the Parker
in-place,
``
1338
1404
`// which is required for the UNIX implementation.
`
1339
1405
`//
`
1340
1406
`// SAFETY: We pin the Arc immediately after creation, so its address never
`
1341
1407
`// changes.
`
1342
1408
`let inner = unsafe {
`
1343
``
`-
let mut arc = Arc::::new_uninit();
`
``
1409
`+
let mut arc = Arc::::new_uninit();
`
1344
1410
`let ptr = Arc::get_mut_unchecked(&mut arc).as_mut_ptr();
`
1345
1411
`(&raw mut (*ptr).name).write(name);
`
1346
1412
`(&raw mut (*ptr).id).write(id);
`
1347
1413
`Parker::new_in_place(&raw mut (*ptr).parker);
`
1348
1414
`Pin::new_unchecked(arc.assume_init())
`
1349
1415
`};
`
1350
1416
``
1351
``
`-
Thread { inner }
`
``
1417
`+
Self(Inner::Other(inner))
`
1352
1418
`}
`
1353
1419
``
1354
1420
`` /// Like the public [park
], but callable on any handle. This is used to
``
`@@ -1357,7 +1423,7 @@ impl Thread {
`
1357
1423
`/// # Safety
`
1358
1424
`/// May only be called from the thread to which this handle belongs.
`
1359
1425
`pub(crate) unsafe fn park(&self) {
`
1360
``
`-
unsafe { self.inner.as_ref().parker().park() }
`
``
1426
`+
unsafe { self.0.parker().park() }
`
1361
1427
`}
`
1362
1428
``
1363
1429
`/// Atomically makes the handle's token available if it is not already.
`
`@@ -1393,7 +1459,7 @@ impl Thread {
`
1393
1459
`#[stable(feature = "rust1", since = "1.0.0")]
`
1394
1460
`#[inline]
`
1395
1461
`pub fn unpark(&self) {
`
1396
``
`-
self.inner.as_ref().parker().unpark();
`
``
1462
`+
self.0.parker().unpark();
`
1397
1463
`}
`
1398
1464
``
1399
1465
`/// Gets the thread's unique identifier.
`
`@@ -1413,7 +1479,7 @@ impl Thread {
`
1413
1479
`#[stable(feature = "thread_id", since = "1.19.0")]
`
1414
1480
`#[must_use]
`
1415
1481
`pub fn id(&self) -> ThreadId {
`
1416
``
`-
self.inner.id
`
``
1482
`+
self.0.id()
`
1417
1483
`}
`
1418
1484
``
1419
1485
`/// Gets the thread's name.
`
`@@ -1456,7 +1522,11 @@ impl Thread {
`
1456
1522
`#[stable(feature = "rust1", since = "1.0.0")]
`
1457
1523
`#[must_use]
`
1458
1524
`pub fn name(&self) -> Option<&str> {
`
1459
``
`-
self.inner.name.as_str()
`
``
1525
`+
self.0.name()
`
``
1526
`+
}
`
``
1527
+
``
1528
`+
fn cname(&self) -> Option<&CStr> {
`
``
1529
`+
self.0.cname()
`
1460
1530
`}
`
1461
1531
``
1462
1532
`` /// Consumes the Thread
, returning a raw pointer.
``
`@@ -1480,9 +1550,7 @@ impl Thread {
`
1480
1550
```` /// ```
````
1481
1551
`#[unstable(feature = "thread_raw", issue = "97523")]
`
1482
1552
`pub fn into_raw(self) -> *const () {
`
1483
``
`` -
// Safety: We only expose an opaque pointer, which maintains the Pin
invariant.
``
1484
``
`-
let inner = unsafe { Pin::into_inner_unchecked(self.inner) };
`
1485
``
`-
Arc::into_raw(inner) as *const ()
`
``
1553
`+
self.0.into_raw()
`
1486
1554
`}
`
1487
1555
``
1488
1556
`` /// Constructs a Thread
from a raw pointer.
``
`@@ -1504,11 +1572,7 @@ impl Thread {
`
1504
1572
`#[unstable(feature = "thread_raw", issue = "97523")]
`
1505
1573
`pub unsafe fn from_raw(ptr: *const ()) -> Thread {
`
1506
1574
`// Safety: Upheld by caller.
`
1507
``
`-
unsafe { Thread { inner: Pin::new_unchecked(Arc::from_raw(ptr as *const Inner)) } }
`
1508
``
`-
}
`
1509
``
-
1510
``
`-
fn cname(&self) -> Option<&CStr> {
`
1511
``
`-
self.inner.name.as_cstr()
`
``
1575
`+
unsafe { Thread(Inner::from_raw(ptr)) }
`
1512
1576
`}
`
1513
1577
`}
`
1514
1578
``