Skip to content

Commit 6e0725e

Browse files
committed
Revert "Remove the Arc rt::init allocation for thread info"
This reverts commit 0747f28.
1 parent 39cb338 commit 6e0725e

File tree

5 files changed

+58
-124
lines changed

5 files changed

+58
-124
lines changed

library/std/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,6 @@
360360
#![feature(std_internals)]
361361
#![feature(str_internals)]
362362
#![feature(strict_provenance_atomic_ptr)]
363-
#![feature(sync_unsafe_cell)]
364363
#![feature(ub_checks)]
365364
// tidy-alphabetical-end
366365
//

library/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

library/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;
@@ -1255,114 +1252,65 @@ impl ThreadId {
12551252
// Thread
12561253
////////////////////////////////////////////////////////////////////////////////
12571254

1255+
/// The internal representation of a `Thread`'s name.
1256+
enum ThreadName {
1257+
Main,
1258+
Other(ThreadNameString),
1259+
Unnamed,
1260+
}
1261+
12581262
// This module ensures private fields are kept private, which is necessary to enforce the safety requirements.
12591263
mod thread_name_string {
12601264
use core::str;
12611265

1266+
use super::ThreadName;
12621267
use crate::ffi::{CStr, CString};
12631268

12641269
/// Like a `String` it's guaranteed UTF-8 and like a `CString` it's null terminated.
12651270
pub(crate) struct ThreadNameString {
12661271
inner: CString,
12671272
}
1268-
1269-
impl ThreadNameString {
1270-
pub fn as_str(&self) -> &str {
1271-
// SAFETY: `self.inner` is only initialised via `String`, which upholds the validity invariant of `str`.
1272-
unsafe { str::from_utf8_unchecked(self.inner.to_bytes()) }
1273-
}
1274-
}
1275-
12761273
impl core::ops::Deref for ThreadNameString {
12771274
type Target = CStr;
12781275
fn deref(&self) -> &CStr {
12791276
&self.inner
12801277
}
12811278
}
1282-
12831279
impl From<String> for ThreadNameString {
12841280
fn from(s: String) -> Self {
12851281
Self {
12861282
inner: CString::new(s).expect("thread name may not contain interior null bytes"),
12871283
}
12881284
}
12891285
}
1286+
impl ThreadName {
1287+
pub fn as_cstr(&self) -> Option<&CStr> {
1288+
match self {
1289+
ThreadName::Main => Some(c"main"),
1290+
ThreadName::Other(other) => Some(other),
1291+
ThreadName::Unnamed => None,
1292+
}
1293+
}
1294+
1295+
pub fn as_str(&self) -> Option<&str> {
1296+
// SAFETY: `as_cstr` can only return `Some` for a fixed CStr or a `ThreadNameString`,
1297+
// which is guaranteed to be UTF-8.
1298+
self.as_cstr().map(|s| unsafe { str::from_utf8_unchecked(s.to_bytes()) })
1299+
}
1300+
}
12901301
}
12911302
pub(crate) use thread_name_string::ThreadNameString;
12921303

1293-
static MAIN_THREAD_INFO: SyncUnsafeCell<(MaybeUninit<ThreadId>, MaybeUninit<Parker>)> =
1294-
SyncUnsafeCell::new((MaybeUninit::uninit(), MaybeUninit::uninit()));
1295-
1296-
/// The internal representation of a `Thread` that is not the main thread.
1297-
struct OtherInner {
1298-
name: Option<ThreadNameString>,
1304+
/// The internal representation of a `Thread` handle
1305+
struct Inner {
1306+
name: ThreadName, // Guaranteed to be UTF-8
12991307
id: ThreadId,
13001308
parker: Parker,
13011309
}
13021310

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

@@ -1386,55 +1334,41 @@ impl Inner {
13861334
/// docs of [`Builder`] and [`spawn`] for more details.
13871335
///
13881336
/// [`thread::current`]: current::current
1389-
pub struct Thread(Inner);
1337+
pub struct Thread {
1338+
inner: Pin<Arc<Inner>>,
1339+
}
13901340

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

13971347
pub(crate) fn new_unnamed(id: ThreadId) -> Thread {
1398-
Self::new_inner(id, None)
1348+
Self::new_inner(id, ThreadName::Unnamed)
13991349
}
14001350

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

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

1437-
Self(Inner::Other(inner))
1371+
Thread { inner }
14381372
}
14391373

14401374
/// Like the public [`park`], but callable on any handle. This is used to
@@ -1443,7 +1377,7 @@ impl Thread {
14431377
/// # Safety
14441378
/// May only be called from the thread to which this handle belongs.
14451379
pub(crate) unsafe fn park(&self) {
1446-
unsafe { self.0.parker().park() }
1380+
unsafe { self.inner.as_ref().parker().park() }
14471381
}
14481382

14491383
/// Like the public [`park_timeout`], but callable on any handle. This is
@@ -1452,7 +1386,7 @@ impl Thread {
14521386
/// # Safety
14531387
/// May only be called from the thread to which this handle belongs.
14541388
pub(crate) unsafe fn park_timeout(&self, dur: Duration) {
1455-
unsafe { self.0.parker().park_timeout(dur) }
1389+
unsafe { self.inner.as_ref().parker().park_timeout(dur) }
14561390
}
14571391

14581392
/// Atomically makes the handle's token available if it is not already.
@@ -1488,7 +1422,7 @@ impl Thread {
14881422
#[stable(feature = "rust1", since = "1.0.0")]
14891423
#[inline]
14901424
pub fn unpark(&self) {
1491-
self.0.parker().unpark();
1425+
self.inner.as_ref().parker().unpark();
14921426
}
14931427

14941428
/// Gets the thread's unique identifier.
@@ -1508,7 +1442,7 @@ impl Thread {
15081442
#[stable(feature = "thread_id", since = "1.19.0")]
15091443
#[must_use]
15101444
pub fn id(&self) -> ThreadId {
1511-
self.0.id()
1445+
self.inner.id
15121446
}
15131447

15141448
/// Gets the thread's name.
@@ -1551,11 +1485,7 @@ impl Thread {
15511485
#[stable(feature = "rust1", since = "1.0.0")]
15521486
#[must_use]
15531487
pub fn name(&self) -> Option<&str> {
1554-
self.0.name()
1555-
}
1556-
1557-
fn cname(&self) -> Option<&CStr> {
1558-
self.0.cname()
1488+
self.inner.name.as_str()
15591489
}
15601490

15611491
/// Consumes the `Thread`, returning a raw pointer.
@@ -1579,7 +1509,9 @@ impl Thread {
15791509
/// ```
15801510
#[unstable(feature = "thread_raw", issue = "97523")]
15811511
pub fn into_raw(self) -> *const () {
1582-
self.0.into_raw()
1512+
// Safety: We only expose an opaque pointer, which maintains the `Pin` invariant.
1513+
let inner = unsafe { Pin::into_inner_unchecked(self.inner) };
1514+
Arc::into_raw(inner) as *const ()
15831515
}
15841516

15851517
/// Constructs a `Thread` from a raw pointer.
@@ -1601,7 +1533,11 @@ impl Thread {
16011533
#[unstable(feature = "thread_raw", issue = "97523")]
16021534
pub unsafe fn from_raw(ptr: *const ()) -> Thread {
16031535
// Safety: Upheld by caller.
1604-
unsafe { Thread(Inner::from_raw(ptr)) }
1536+
unsafe { Thread { inner: Pin::new_unchecked(Arc::from_raw(ptr as *const Inner)) } }
1537+
}
1538+
1539+
fn cname(&self) -> Option<&CStr> {
1540+
self.inner.name.as_cstr()
16051541
}
16061542
}
16071543

tests/debuginfo/thread.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@
1212
// cdb-check:join_handle,d [Type: std::thread::JoinHandle<tuple$<> >]
1313
// cdb-check: [...] __0 [Type: std::thread::JoinInner<tuple$<> >]
1414
//
15-
// cdb-command:dx -r3 t,d
15+
// cdb-command:dx t,d
1616
// cdb-check:t,d : [...] [Type: std::thread::Thread *]
17-
// cdb-check: [...] __0 : Other [Type: enum2$<std::thread::Inner>]
18-
// cdb-check: [...] __0 [Type: core::pin::Pin<alloc::sync::Arc<std::thread::OtherInner,[...]> >]
17+
// cdb-check:[...] inner [...][Type: core::pin::Pin<alloc::sync::Arc<std::thread::Inner,alloc::alloc::Global> >]
1918

2019
use std::thread;
2120

2221
#[allow(unused_variables)]
23-
fn main() {
22+
fn main()
23+
{
2424
let join_handle = thread::spawn(|| {
2525
println!("Initialize a thread");
2626
});

tests/rustdoc/demo-allocator-54478.rs

-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
//! }
4141
//!
4242
//! fn main() {
43-
//! drop(String::from("An allocation"));
4443
//! assert!(unsafe { HIT });
4544
//! }
4645
//! ```

0 commit comments

Comments
 (0)