Skip to content

Commit 3b0cbae

Browse files
committed
Revert "Remove the Arc rt::init allocation for thread info"
This reverts commit 0747f28.
1 parent 96477c5 commit 3b0cbae

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
@@ -365,7 +365,6 @@
365365
#![feature(std_internals)]
366366
#![feature(str_internals)]
367367
#![feature(strict_provenance_atomic_ptr)]
368-
#![feature(sync_unsafe_cell)]
369368
#![feature(ub_checks)]
370369
// tidy-alphabetical-end
371370
//

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;
@@ -1128,7 +1125,7 @@ pub fn park_timeout(dur: Duration) {
11281125
let guard = PanicGuard;
11291126
// SAFETY: park_timeout is called on the parker owned by this thread.
11301127
unsafe {
1131-
current().0.parker().park_timeout(dur);
1128+
current().inner.as_ref().parker().park_timeout(dur);
11321129
}
11331130
// No panic occurred, do not abort.
11341131
forget(guard);
@@ -1235,114 +1232,65 @@ impl ThreadId {
12351232
// Thread
12361233
////////////////////////////////////////////////////////////////////////////////
12371234

1235+
/// The internal representation of a `Thread`'s name.
1236+
enum ThreadName {
1237+
Main,
1238+
Other(ThreadNameString),
1239+
Unnamed,
1240+
}
1241+
12381242
// This module ensures private fields are kept private, which is necessary to enforce the safety requirements.
12391243
mod thread_name_string {
12401244
use core::str;
12411245

1246+
use super::ThreadName;
12421247
use crate::ffi::{CStr, CString};
12431248

12441249
/// Like a `String` it's guaranteed UTF-8 and like a `CString` it's null terminated.
12451250
pub(crate) struct ThreadNameString {
12461251
inner: CString,
12471252
}
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-
12561253
impl core::ops::Deref for ThreadNameString {
12571254
type Target = CStr;
12581255
fn deref(&self) -> &CStr {
12591256
&self.inner
12601257
}
12611258
}
1262-
12631259
impl From<String> for ThreadNameString {
12641260
fn from(s: String) -> Self {
12651261
Self {
12661262
inner: CString::new(s).expect("thread name may not contain interior null bytes"),
12671263
}
12681264
}
12691265
}
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+
}
12701281
}
12711282
pub(crate) use thread_name_string::ThreadNameString;
12721283

1273-
static MAIN_THREAD_INFO: SyncUnsafeCell<(MaybeUninit<ThreadId>, MaybeUninit<Parker>)> =
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<ThreadNameString>,
1284+
/// The internal representation of a `Thread` handle
1285+
struct Inner {
1286+
name: ThreadName, // Guaranteed to be UTF-8
12791287
id: ThreadId,
12801288
parker: Parker,
12811289
}
12821290

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<OtherInner>>),
1290-
}
1291-
12921291
impl Inner {
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-
}
1292+
fn parker(self: Pin<&Self>) -> Pin<&Parker> {
1293+
unsafe { Pin::map_unchecked(self, |inner| &inner.parker) }
13461294
}
13471295
}
13481296

@@ -1366,55 +1314,41 @@ impl Inner {
13661314
/// docs of [`Builder`] and [`spawn`] for more details.
13671315
///
13681316
/// [`thread::current`]: current::current
1369-
pub struct Thread(Inner);
1317+
pub struct Thread {
1318+
inner: Pin<Arc<Inner>>,
1319+
}
13701320

13711321
impl Thread {
13721322
/// Used only internally to construct a thread object without spawning.
13731323
pub(crate) fn new(id: ThreadId, name: String) -> Thread {
1374-
Self::new_inner(id, Some(ThreadNameString::from(name)))
1324+
Self::new_inner(id, ThreadName::Other(name.into()))
13751325
}
13761326

13771327
pub(crate) fn new_unnamed(id: ThreadId) -> Thread {
1378-
Self::new_inner(id, None)
1328+
Self::new_inner(id, ThreadName::Unnamed)
13791329
}
13801330

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() }))
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)
14001334
}
14011335

1402-
fn new_inner(id: ThreadId, name: Option<ThreadNameString>) -> Thread {
1336+
fn new_inner(id: ThreadId, name: ThreadName) -> Thread {
14031337
// We have to use `unsafe` here to construct the `Parker` in-place,
14041338
// which is required for the UNIX implementation.
14051339
//
14061340
// SAFETY: We pin the Arc immediately after creation, so its address never
14071341
// changes.
14081342
let inner = unsafe {
1409-
let mut arc = Arc::<OtherInner>::new_uninit();
1343+
let mut arc = Arc::<Inner>::new_uninit();
14101344
let ptr = Arc::get_mut_unchecked(&mut arc).as_mut_ptr();
14111345
(&raw mut (*ptr).name).write(name);
14121346
(&raw mut (*ptr).id).write(id);
14131347
Parker::new_in_place(&raw mut (*ptr).parker);
14141348
Pin::new_unchecked(arc.assume_init())
14151349
};
14161350

1417-
Self(Inner::Other(inner))
1351+
Thread { inner }
14181352
}
14191353

14201354
/// Like the public [`park`], but callable on any handle. This is used to
@@ -1423,7 +1357,7 @@ impl Thread {
14231357
/// # Safety
14241358
/// May only be called from the thread to which this handle belongs.
14251359
pub(crate) unsafe fn park(&self) {
1426-
unsafe { self.0.parker().park() }
1360+
unsafe { self.inner.as_ref().parker().park() }
14271361
}
14281362

14291363
/// Atomically makes the handle's token available if it is not already.
@@ -1459,7 +1393,7 @@ impl Thread {
14591393
#[stable(feature = "rust1", since = "1.0.0")]
14601394
#[inline]
14611395
pub fn unpark(&self) {
1462-
self.0.parker().unpark();
1396+
self.inner.as_ref().parker().unpark();
14631397
}
14641398

14651399
/// Gets the thread's unique identifier.
@@ -1479,7 +1413,7 @@ impl Thread {
14791413
#[stable(feature = "thread_id", since = "1.19.0")]
14801414
#[must_use]
14811415
pub fn id(&self) -> ThreadId {
1482-
self.0.id()
1416+
self.inner.id
14831417
}
14841418

14851419
/// Gets the thread's name.
@@ -1522,11 +1456,7 @@ impl Thread {
15221456
#[stable(feature = "rust1", since = "1.0.0")]
15231457
#[must_use]
15241458
pub fn name(&self) -> Option<&str> {
1525-
self.0.name()
1526-
}
1527-
1528-
fn cname(&self) -> Option<&CStr> {
1529-
self.0.cname()
1459+
self.inner.name.as_str()
15301460
}
15311461

15321462
/// Consumes the `Thread`, returning a raw pointer.
@@ -1550,7 +1480,9 @@ impl Thread {
15501480
/// ```
15511481
#[unstable(feature = "thread_raw", issue = "97523")]
15521482
pub fn into_raw(self) -> *const () {
1553-
self.0.into_raw()
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 ()
15541486
}
15551487

15561488
/// Constructs a `Thread` from a raw pointer.
@@ -1572,7 +1504,11 @@ impl Thread {
15721504
#[unstable(feature = "thread_raw", issue = "97523")]
15731505
pub unsafe fn from_raw(ptr: *const ()) -> Thread {
15741506
// Safety: Upheld by caller.
1575-
unsafe { Thread(Inner::from_raw(ptr)) }
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()
15761512
}
15771513
}
15781514

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)