mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-29 03:37:26 +03:00
57 lines
2.1 KiB
Rust
57 lines
2.1 KiB
Rust
//! Store the ID of the main thread.
|
||
//!
|
||
//! The thread handle for the main thread is created lazily, and this might even
|
||
//! happen pre-main. Since not every platform has a way to identify the main
|
||
//! thread when that happens – macOS's `pthread_main_np` function being a notable
|
||
//! exception – we cannot assign it the right name right then. Instead, in our
|
||
//! runtime startup code, we remember the thread ID of the main thread (through
|
||
//! this modules `set` function) and use it to identify the main thread from then
|
||
//! on. This works reliably and has the additional advantage that we can report
|
||
//! the right thread name on main even after the thread handle has been destroyed.
|
||
//! Note however that this also means that the name reported in pre-main functions
|
||
//! will be incorrect, but that's just something we have to live with.
|
||
|
||
cfg_select! {
|
||
target_has_atomic = "64" => {
|
||
use super::id::ThreadId;
|
||
use crate::sync::atomic::{Atomic, AtomicU64};
|
||
use crate::sync::atomic::Ordering::Relaxed;
|
||
|
||
static MAIN: Atomic<u64> = AtomicU64::new(0);
|
||
|
||
pub(super) fn get() -> Option<ThreadId> {
|
||
ThreadId::from_u64(MAIN.load(Relaxed))
|
||
}
|
||
|
||
/// # Safety
|
||
/// May only be called once.
|
||
pub(crate) unsafe fn set(id: ThreadId) {
|
||
MAIN.store(id.as_u64().get(), Relaxed)
|
||
}
|
||
}
|
||
_ => {
|
||
use super::id::ThreadId;
|
||
use crate::mem::MaybeUninit;
|
||
use crate::sync::atomic::{Atomic, AtomicBool};
|
||
use crate::sync::atomic::Ordering::{Acquire, Release};
|
||
|
||
static INIT: Atomic<bool> = AtomicBool::new(false);
|
||
static mut MAIN: MaybeUninit<ThreadId> = MaybeUninit::uninit();
|
||
|
||
pub(super) fn get() -> Option<ThreadId> {
|
||
if INIT.load(Acquire) {
|
||
Some(unsafe { MAIN.assume_init() })
|
||
} else {
|
||
None
|
||
}
|
||
}
|
||
|
||
/// # Safety
|
||
/// May only be called once.
|
||
pub(crate) unsafe fn set(id: ThreadId) {
|
||
unsafe { MAIN = MaybeUninit::new(id) };
|
||
INIT.store(true, Release);
|
||
}
|
||
}
|
||
}
|