Skip to content

Commit 7ad0ee7

Browse files
committed
Revert "Remove the Arc rt::init allocation for thread info"
This reverts commit 0747f28.
1 parent da43f89 commit 7ad0ee7

File tree

2 files changed

+54
-118
lines changed

2 files changed

+54
-118
lines changed

std/src/rt.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
110110
// handle does not match the current ID, we should attempt to use the
111111
// current thread ID here instead of unconditionally creating a new
112112
// one. Also see #130210.
113-
let thread = unsafe { Thread::new_main(thread::current_id()) };
113+
let thread = Thread::new_main(thread::current_id());
114114
if let Err(_thread) = thread::set_current(thread) {
115115
// `thread::current` will create a new handle if none has been set yet.
116116
// Thus, if someone uses it before main, this call will fail. That's a

std/src/thread/mod.rs

+53-117
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,9 @@
158158
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
159159
mod tests;
160160

161-
use core::cell::SyncUnsafeCell;
162-
use core::ffi::CStr;
163-
use core::mem::MaybeUninit;
164-
165161
use crate::any::Any;
166162
use crate::cell::UnsafeCell;
163+
use crate::ffi::CStr;
167164
use crate::marker::PhantomData;
168165
use crate::mem::{self, ManuallyDrop, forget};
169166
use crate::num::NonZero;
@@ -1259,114 +1256,65 @@ impl ThreadId {
12591256
// Thread
12601257
////////////////////////////////////////////////////////////////////////////////
12611258

1259+
/// The internal representation of a `Thread`'s name.
1260+
enum ThreadName {
1261+
Main,
1262+
Other(ThreadNameString),
1263+
Unnamed,
1264+
}
1265+
12621266
// This module ensures private fields are kept private, which is necessary to enforce the safety requirements.
12631267
mod thread_name_string {
12641268
use core::str;
12651269

1270+
use super::ThreadName;
12661271
use crate::ffi::{CStr, CString};
12671272

12681273
/// Like a `String` it's guaranteed UTF-8 and like a `CString` it's null terminated.
12691274
pub(crate) struct ThreadNameString {
12701275
inner: CString,
12711276
}
1272-
1273-
impl ThreadNameString {
1274-
pub fn as_str(&self) -> &str {
1275-
// SAFETY: `self.inner` is only initialised via `String`, which upholds the validity invariant of `str`.
1276-
unsafe { str::from_utf8_unchecked(self.inner.to_bytes()) }
1277-
}
1278-
}
1279-
12801277
impl core::ops::Deref for ThreadNameString {
12811278
type Target = CStr;
12821279
fn deref(&self) -> &CStr {
12831280
&self.inner
12841281
}
12851282
}
1286-
12871283
impl From<String> for ThreadNameString {
12881284
fn from(s: String) -> Self {
12891285
Self {
12901286
inner: CString::new(s).expect("thread name may not contain interior null bytes"),
12911287
}
12921288
}
12931289
}
1290+
impl ThreadName {
1291+
pub fn as_cstr(&self) -> Option<&CStr> {
1292+
match self {
1293+
ThreadName::Main => Some(c"main"),
1294+
ThreadName::Other(other) => Some(other),
1295+
ThreadName::Unnamed => None,
1296+
}
1297+
}
1298+
1299+
pub fn as_str(&self) -> Option<&str> {
1300+
// SAFETY: `as_cstr` can only return `Some` for a fixed CStr or a `ThreadNameString`,
1301+
// which is guaranteed to be UTF-8.
1302+
self.as_cstr().map(|s| unsafe { str::from_utf8_unchecked(s.to_bytes()) })
1303+
}
1304+
}
12941305
}
12951306
pub(crate) use thread_name_string::ThreadNameString;
12961307

1297-
static MAIN_THREAD_INFO: SyncUnsafeCell<(MaybeUninit<ThreadId>, MaybeUninit<Parker>)> =
1298-
SyncUnsafeCell::new((MaybeUninit::uninit(), MaybeUninit::uninit()));
1299-
1300-
/// The internal representation of a `Thread` that is not the main thread.
1301-
struct OtherInner {
1302-
name: Option<ThreadNameString>,
1308+
/// The internal representation of a `Thread` handle
1309+
struct Inner {
1310+
name: ThreadName, // Guaranteed to be UTF-8
13031311
id: ThreadId,
13041312
parker: Parker,
13051313
}
13061314

1307-
/// The internal representation of a `Thread` handle.
1308-
#[derive(Clone)]
1309-
enum Inner {
1310-
/// Represents the main thread. May only be constructed by Thread::new_main.
1311-
Main(&'static (ThreadId, Parker)),
1312-
/// Represents any other thread.
1313-
Other(Pin<Arc<OtherInner>>),
1314-
}
1315-
13161315
impl Inner {
1317-
fn id(&self) -> ThreadId {
1318-
match self {
1319-
Self::Main((thread_id, _)) => *thread_id,
1320-
Self::Other(other) => other.id,
1321-
}
1322-
}
1323-
1324-
fn cname(&self) -> Option<&CStr> {
1325-
match self {
1326-
Self::Main(_) => Some(c"main"),
1327-
Self::Other(other) => other.name.as_deref(),
1328-
}
1329-
}
1330-
1331-
fn name(&self) -> Option<&str> {
1332-
match self {
1333-
Self::Main(_) => Some("main"),
1334-
Self::Other(other) => other.name.as_ref().map(ThreadNameString::as_str),
1335-
}
1336-
}
1337-
1338-
fn into_raw(self) -> *const () {
1339-
match self {
1340-
// Just return the pointer to `MAIN_THREAD_INFO`.
1341-
Self::Main(ptr) => crate::ptr::from_ref(ptr).cast(),
1342-
Self::Other(arc) => {
1343-
// Safety: We only expose an opaque pointer, which maintains the `Pin` invariant.
1344-
let inner = unsafe { Pin::into_inner_unchecked(arc) };
1345-
Arc::into_raw(inner) as *const ()
1346-
}
1347-
}
1348-
}
1349-
1350-
/// # Safety
1351-
///
1352-
/// See [`Thread::from_raw`].
1353-
unsafe fn from_raw(ptr: *const ()) -> Self {
1354-
// If the pointer is to `MAIN_THREAD_INFO`, we know it is the `Main` variant.
1355-
if crate::ptr::eq(ptr.cast(), &MAIN_THREAD_INFO) {
1356-
Self::Main(unsafe { &*ptr.cast() })
1357-
} else {
1358-
// Safety: Upheld by caller
1359-
Self::Other(unsafe { Pin::new_unchecked(Arc::from_raw(ptr as *const OtherInner)) })
1360-
}
1361-
}
1362-
1363-
fn parker(&self) -> Pin<&Parker> {
1364-
match self {
1365-
Self::Main((_, parker_ref)) => Pin::static_ref(parker_ref),
1366-
Self::Other(inner) => unsafe {
1367-
Pin::map_unchecked(inner.as_ref(), |inner| &inner.parker)
1368-
},
1369-
}
1316+
fn parker(self: Pin<&Self>) -> Pin<&Parker> {
1317+
unsafe { Pin::map_unchecked(self, |inner| &inner.parker) }
13701318
}
13711319
}
13721320

@@ -1390,55 +1338,41 @@ impl Inner {
13901338
/// docs of [`Builder`] and [`spawn`] for more details.
13911339
///
13921340
/// [`thread::current`]: current::current
1393-
pub struct Thread(Inner);
1341+
pub struct Thread {
1342+
inner: Pin<Arc<Inner>>,
1343+
}
13941344

13951345
impl Thread {
13961346
/// Used only internally to construct a thread object without spawning.
13971347
pub(crate) fn new(id: ThreadId, name: String) -> Thread {
1398-
Self::new_inner(id, Some(ThreadNameString::from(name)))
1348+
Self::new_inner(id, ThreadName::Other(name.into()))
13991349
}
14001350

14011351
pub(crate) fn new_unnamed(id: ThreadId) -> Thread {
1402-
Self::new_inner(id, None)
1352+
Self::new_inner(id, ThreadName::Unnamed)
14031353
}
14041354

1405-
/// Used in runtime to construct main thread
1406-
///
1407-
/// # Safety
1408-
///
1409-
/// This must only ever be called once, and must be called on the main thread.
1410-
pub(crate) unsafe fn new_main(thread_id: ThreadId) -> Thread {
1411-
// Safety: As this is only called once and on the main thread, nothing else is accessing MAIN_THREAD_INFO
1412-
// as the only other read occurs in `main_thread_info` *after* the main thread has been constructed,
1413-
// and this function is the only one that constructs the main thread.
1414-
//
1415-
// Pre-main thread spawning cannot hit this either, as the caller promises that this is only called on the main thread.
1416-
let main_thread_info = unsafe { &mut *MAIN_THREAD_INFO.get() };
1417-
1418-
unsafe { Parker::new_in_place((&raw mut main_thread_info.1).cast()) };
1419-
main_thread_info.0.write(thread_id);
1420-
1421-
// Store a `'static` ref to the initialised ThreadId and Parker,
1422-
// to avoid having to repeatedly prove initialisation.
1423-
Self(Inner::Main(unsafe { &*MAIN_THREAD_INFO.get().cast() }))
1355+
/// Constructs the thread handle for the main thread.
1356+
pub(crate) fn new_main(id: ThreadId) -> Thread {
1357+
Self::new_inner(id, ThreadName::Main)
14241358
}
14251359

1426-
fn new_inner(id: ThreadId, name: Option<ThreadNameString>) -> Thread {
1360+
fn new_inner(id: ThreadId, name: ThreadName) -> Thread {
14271361
// We have to use `unsafe` here to construct the `Parker` in-place,
14281362
// which is required for the UNIX implementation.
14291363
//
14301364
// SAFETY: We pin the Arc immediately after creation, so its address never
14311365
// changes.
14321366
let inner = unsafe {
1433-
let mut arc = Arc::<OtherInner>::new_uninit();
1367+
let mut arc = Arc::<Inner>::new_uninit();
14341368
let ptr = Arc::get_mut_unchecked(&mut arc).as_mut_ptr();
14351369
(&raw mut (*ptr).name).write(name);
14361370
(&raw mut (*ptr).id).write(id);
14371371
Parker::new_in_place(&raw mut (*ptr).parker);
14381372
Pin::new_unchecked(arc.assume_init())
14391373
};
14401374

1441-
Self(Inner::Other(inner))
1375+
Thread { inner }
14421376
}
14431377

14441378
/// Like the public [`park`], but callable on any handle. This is used to
@@ -1447,7 +1381,7 @@ impl Thread {
14471381
/// # Safety
14481382
/// May only be called from the thread to which this handle belongs.
14491383
pub(crate) unsafe fn park(&self) {
1450-
unsafe { self.0.parker().park() }
1384+
unsafe { self.inner.as_ref().parker().park() }
14511385
}
14521386

14531387
/// Like the public [`park_timeout`], but callable on any handle. This is
@@ -1456,7 +1390,7 @@ impl Thread {
14561390
/// # Safety
14571391
/// May only be called from the thread to which this handle belongs.
14581392
pub(crate) unsafe fn park_timeout(&self, dur: Duration) {
1459-
unsafe { self.0.parker().park_timeout(dur) }
1393+
unsafe { self.inner.as_ref().parker().park_timeout(dur) }
14601394
}
14611395

14621396
/// Atomically makes the handle's token available if it is not already.
@@ -1492,7 +1426,7 @@ impl Thread {
14921426
#[stable(feature = "rust1", since = "1.0.0")]
14931427
#[inline]
14941428
pub fn unpark(&self) {
1495-
self.0.parker().unpark();
1429+
self.inner.as_ref().parker().unpark();
14961430
}
14971431

14981432
/// Gets the thread's unique identifier.
@@ -1512,7 +1446,7 @@ impl Thread {
15121446
#[stable(feature = "thread_id", since = "1.19.0")]
15131447
#[must_use]
15141448
pub fn id(&self) -> ThreadId {
1515-
self.0.id()
1449+
self.inner.id
15161450
}
15171451

15181452
/// Gets the thread's name.
@@ -1555,11 +1489,7 @@ impl Thread {
15551489
#[stable(feature = "rust1", since = "1.0.0")]
15561490
#[must_use]
15571491
pub fn name(&self) -> Option<&str> {
1558-
self.0.name()
1559-
}
1560-
1561-
fn cname(&self) -> Option<&CStr> {
1562-
self.0.cname()
1492+
self.inner.name.as_str()
15631493
}
15641494

15651495
/// Consumes the `Thread`, returning a raw pointer.
@@ -1583,7 +1513,9 @@ impl Thread {
15831513
/// ```
15841514
#[unstable(feature = "thread_raw", issue = "97523")]
15851515
pub fn into_raw(self) -> *const () {
1586-
self.0.into_raw()
1516+
// Safety: We only expose an opaque pointer, which maintains the `Pin` invariant.
1517+
let inner = unsafe { Pin::into_inner_unchecked(self.inner) };
1518+
Arc::into_raw(inner) as *const ()
15871519
}
15881520

15891521
/// Constructs a `Thread` from a raw pointer.
@@ -1605,7 +1537,11 @@ impl Thread {
16051537
#[unstable(feature = "thread_raw", issue = "97523")]
16061538
pub unsafe fn from_raw(ptr: *const ()) -> Thread {
16071539
// Safety: Upheld by caller.
1608-
unsafe { Thread(Inner::from_raw(ptr)) }
1540+
unsafe { Thread { inner: Pin::new_unchecked(Arc::from_raw(ptr as *const Inner)) } }
1541+
}
1542+
1543+
fn cname(&self) -> Option<&CStr> {
1544+
self.inner.name.as_cstr()
16091545
}
16101546
}
16111547

0 commit comments

Comments
 (0)