std: move thread::current TLS variable out of thread_info

This commit is contained in:
joboet 2024-03-31 11:28:24 +02:00
parent 5b9d7ab558
commit 7668418101
No known key found for this signature in database
GPG Key ID: 704E0149B0194B3C
16 changed files with 29 additions and 176 deletions

View File

@ -21,7 +21,6 @@ use crate::sync::atomic::{AtomicBool, Ordering};
use crate::sync::{PoisonError, RwLock};
use crate::sys::stdio::panic_output;
use crate::sys_common::backtrace;
use crate::sys_common::thread_info;
use crate::thread;
#[cfg(not(test))]
@ -256,7 +255,7 @@ fn default_hook(info: &PanicInfo<'_>) {
None => "Box<dyn Any>",
},
};
let thread = thread_info::current_thread();
let thread = thread::try_current();
let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>");
let write = |err: &mut dyn crate::io::Write| {

View File

@ -24,8 +24,7 @@ pub use core::panicking::{panic_display, panic_fmt};
use crate::sync::Once;
use crate::sys;
use crate::sys_common::thread_info;
use crate::thread::Thread;
use crate::thread::{self, Thread};
// Prints to the "panic output", depending on the platform this may be:
// - the standard error output
@ -96,13 +95,12 @@ unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
unsafe {
sys::init(argc, argv, sigpipe);
let main_guard = sys::thread::guard::init();
// Next, set up the current Thread with the guard information we just
// created. Note that this isn't necessary in general for new threads,
// but we just do this to name the main thread and to give it correct
// info about the stack bounds.
let thread = Thread::new(Some(rtunwrap!(Ok, CString::new("main"))));
thread_info::set(main_guard, thread);
thread::set_current(thread);
}
}

View File

@ -104,13 +104,3 @@ impl Thread {
pub fn available_parallelism() -> io::Result<NonZero<usize>> {
unsafe { Ok(NonZero::new_unchecked(abi::get_processor_count())) }
}
pub mod guard {
pub type Guard = !;
pub unsafe fn current() -> Option<Guard> {
None
}
pub unsafe fn init() -> Option<Guard> {
None
}
}

View File

@ -312,16 +312,6 @@ impl Drop for Thread {
}
}
pub mod guard {
pub type Guard = !;
pub unsafe fn current() -> Option<Guard> {
None
}
pub unsafe fn init() -> Option<Guard> {
None
}
}
/// Terminate and delete the specified task.
///
/// This function will abort if `deleted_task` refers to the calling task.

View File

@ -149,13 +149,3 @@ impl Thread {
pub fn available_parallelism() -> io::Result<NonZero<usize>> {
unsupported()
}
pub mod guard {
pub type Guard = !;
pub unsafe fn current() -> Option<Guard> {
None
}
pub unsafe fn init() -> Option<Guard> {
None
}
}

View File

@ -151,18 +151,6 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
))
}
// stub
pub mod guard {
use crate::ops::Range;
pub type Guard = Range<usize>;
pub unsafe fn current() -> Option<Guard> {
None
}
pub unsafe fn init() -> Option<Guard> {
None
}
}
fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
libc::PTHREAD_STACK_MIN.try_into().expect("Infallible")
}

View File

@ -52,13 +52,3 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
// UEFI is single threaded
Ok(NonZero::new(1).unwrap())
}
pub mod guard {
pub type Guard = !;
pub unsafe fn current() -> Option<Guard> {
None
}
pub unsafe fn init() -> Option<Guard> {
None
}
}

View File

@ -729,17 +729,6 @@ mod cgroups {
}
}
pub mod guard {
use crate::ops::Range;
pub type Guard = Range<usize>;
pub unsafe fn current() -> Option<Guard> {
None
}
pub unsafe fn init() -> Option<Guard> {
None
}
}
// glibc >= 2.15 has a __pthread_get_minstack() function that returns
// PTHREAD_STACK_MIN plus bytes needed for thread-local storage.
// We need that information to avoid blowing up when a small stack

View File

@ -38,13 +38,3 @@ impl Thread {
pub fn available_parallelism() -> io::Result<NonZero<usize>> {
unsupported()
}
pub mod guard {
pub type Guard = !;
pub unsafe fn current() -> Option<Guard> {
None
}
pub unsafe fn init() -> Option<Guard> {
None
}
}

View File

@ -193,13 +193,3 @@ impl Thread {
pub fn available_parallelism() -> io::Result<NonZero<usize>> {
unsupported()
}
pub mod guard {
pub type Guard = !;
pub unsafe fn current() -> Option<Guard> {
None
}
pub unsafe fn init() -> Option<Guard> {
None
}
}

View File

@ -144,14 +144,3 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
cpus => Ok(unsafe { NonZero::new_unchecked(cpus) }),
}
}
#[cfg_attr(test, allow(dead_code))]
pub mod guard {
pub type Guard = !;
pub unsafe fn current() -> Option<Guard> {
None
}
pub unsafe fn init() -> Option<Guard> {
None
}
}

View File

@ -140,13 +140,3 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
// We're unicore right now.
Ok(unsafe { NonZero::new_unchecked(1) })
}
pub mod guard {
pub type Guard = !;
pub unsafe fn current() -> Option<Guard> {
None
}
pub unsafe fn init() -> Option<Guard> {
None
}
}

View File

@ -115,8 +115,7 @@ use crate::sync::atomic::{
AtomicBool, AtomicPtr,
Ordering::{AcqRel, Acquire, Relaxed, Release},
};
use crate::sys_common::thread_info;
use crate::thread::Thread;
use crate::thread::{self, Thread};
// Locking uses exponential backoff. `SPIN_COUNT` indicates how many times the
// locking operation will be retried.
@ -203,8 +202,7 @@ impl Node {
fn prepare(&mut self) {
// Fall back to creating an unnamed `Thread` handle to allow locking in
// TLS destructors.
self.thread
.get_or_init(|| thread_info::current_thread().unwrap_or_else(|| Thread::new(None)));
self.thread.get_or_init(|| thread::try_current().unwrap_or_else(|| Thread::new(None)));
self.completed = AtomicBool::new(false);
}

View File

@ -26,7 +26,6 @@ pub mod io;
pub mod lazy_box;
pub mod process;
pub mod thread;
pub mod thread_info;
pub mod thread_local_dtor;
pub mod thread_parking;
pub mod wstr;

View File

@ -1,53 +0,0 @@
#![allow(dead_code)] // stack_guard isn't used right now on all platforms
use crate::cell::OnceCell;
use crate::sys;
use crate::sys::thread::guard::Guard;
use crate::thread::Thread;
struct ThreadInfo {
stack_guard: OnceCell<Guard>,
thread: OnceCell<Thread>,
}
thread_local! {
static THREAD_INFO: ThreadInfo = const { ThreadInfo {
stack_guard: OnceCell::new(),
thread: OnceCell::new()
} };
}
impl ThreadInfo {
fn with<R, F>(f: F) -> Option<R>
where
F: FnOnce(&Thread, &OnceCell<Guard>) -> R,
{
THREAD_INFO
.try_with(move |thread_info| {
let thread =
thread_info.thread.get_or_init(|| Thread::new(sys::thread::Thread::get_name()));
f(thread, &thread_info.stack_guard)
})
.ok()
}
}
pub fn current_thread() -> Option<Thread> {
ThreadInfo::with(|thread, _| thread.clone())
}
pub fn stack_guard() -> Option<Guard> {
ThreadInfo::with(|_, guard| guard.get().cloned()).flatten()
}
/// Set new thread info, panicking if it has already been initialized
#[allow(unreachable_code, unreachable_patterns)] // some platforms don't use stack_guard
pub fn set(stack_guard: Option<Guard>, thread: Thread) {
THREAD_INFO.with(move |thread_info| {
rtassert!(thread_info.stack_guard.get().is_none() && thread_info.thread.get().is_none());
if let Some(guard) = stack_guard {
thread_info.stack_guard.set(guard).unwrap();
}
thread_info.thread.set(thread).unwrap();
});
}

View File

@ -159,7 +159,7 @@
mod tests;
use crate::any::Any;
use crate::cell::UnsafeCell;
use crate::cell::{OnceCell, UnsafeCell};
use crate::ffi::{CStr, CString};
use crate::fmt;
use crate::io;
@ -174,7 +174,6 @@ use crate::str;
use crate::sync::Arc;
use crate::sys::thread as imp;
use crate::sys_common::thread;
use crate::sys_common::thread_info;
use crate::sys_common::thread_parking::Parker;
use crate::sys_common::{AsInner, IntoInner};
use crate::time::{Duration, Instant};
@ -518,12 +517,8 @@ impl Builder {
crate::io::set_output_capture(output_capture);
// SAFETY: we constructed `f` initialized.
let f = f.into_inner();
// SAFETY: the stack guard passed is the one for the current thread.
// This means the current thread's stack and the new thread's stack
// are properly set and protected from each other.
thread_info::set(unsafe { imp::guard::current() }, their_thread);
set_current(their_thread);
let try_result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
crate::sys_common::backtrace::__rust_begin_short_backtrace(f)
}));
@ -683,6 +678,27 @@ where
Builder::new().spawn(f).expect("failed to spawn thread")
}
thread_local! {
static CURRENT: OnceCell<Thread> = const { OnceCell::new() };
}
/// Sets the thread handle for the current thread.
///
/// Panics if the handle has been set already or when called from a TLS destructor.
pub(crate) fn set_current(thread: Thread) {
CURRENT.with(|current| current.set(thread).unwrap());
}
/// Gets a handle to the thread that invokes it.
///
/// In contrast to the public `current` function, this will not panic if called
/// from inside a TLS destructor.
pub(crate) fn try_current() -> Option<Thread> {
CURRENT
.try_with(|current| current.get_or_init(|| Thread::new(imp::Thread::get_name())).clone())
.ok()
}
/// Gets a handle to the thread that invokes it.
///
/// # Examples
@ -705,7 +721,7 @@ where
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn current() -> Thread {
thread_info::current_thread().expect(
try_current().expect(
"use of std::thread::current() is not possible \
after the thread's local data has been destroyed",
)