Skip to content

Commit

Permalink
Thread stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
terrarier2111 committed Jul 20, 2023
1 parent 3f6ed91 commit eeaac1b
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 8 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ once_cell = "1.5.2"
cfg-if = "1.0.0"
crossbeam-utils = "0.8.15"
likely_stable = "0.1.2"
memoffset = "0.9.0"

[dev-dependencies]
criterion = "0.4.0"
Expand Down
36 changes: 28 additions & 8 deletions src/thread_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use std::mem::MaybeUninit;
use std::num::NonZeroUsize;
use std::ptr::{addr_of, null};
use likely_stable::likely;
use memoffset::offset_of;

/// Thread ID manager which allocates thread IDs. It attempts to aggressively
/// reuse thread IDs where possible to avoid cases where a ThreadLocal grows
Expand Down Expand Up @@ -55,7 +56,6 @@ static THREAD_ID_MANAGER: Lazy<Mutex<ThreadIdManager>> =
#[derive(Clone, Copy)]
#[repr(C)]
pub(crate) struct Thread {
self_ptr: *const Thread,
id: usize,
bucket: usize,
index: usize,
Expand All @@ -68,7 +68,6 @@ impl Thread {
let bucket_size = 1 << bucket;
let index = id - (bucket_size - 1);
Self {
self_ptr: THREAD.get().cast_const(),
id,
bucket,
index,
Expand Down Expand Up @@ -108,11 +107,13 @@ cfg_if::cfg_if! {
//
// This makes the fast path smaller.
#[thread_local]
static THREAD: UnsafeCell<Thread> = UnsafeCell::new(Thread {
static THREAD: UnsafeCell<ThreadWrapper> = UnsafeCell::new(ThreadWrapper {
self_ptr: null(),
id: 0,
index: 0,
bucket: 0,
thread: Thread {
id: 0,
index: 0,
bucket: 0,
},
});
thread_local! { static THREAD_GUARD: ThreadGuard = const { ThreadGuard { id: Cell::new(0) } }; }

Expand All @@ -136,6 +137,25 @@ cfg_if::cfg_if! {
}
}

/// Data which is unique to the current thread while it is running.
/// A thread ID may be reused after a thread exits.
#[derive(Clone, Copy)]
#[repr(C)]
struct ThreadWrapper {
self_ptr: *const Thread,
thread: Thread,
}

impl ThreadWrapper {
#[inline]
fn new(id: usize) -> Self {
Self {
self_ptr: ((THREAD.get().cast_const() as usize) + offset_of!(ThreadWrapper, thread)) as *const Thread,
thread: Thread::new(id),
}
}
}

/// Returns a thread ID for the current thread, allocating one if needed.
#[inline]
pub(crate) fn get() -> Thread {
Expand All @@ -150,12 +170,12 @@ cfg_if::cfg_if! {
/// Out-of-line slow path for allocating a thread ID.
#[cold]
fn get_slow() -> Thread {
let new = Thread::new(THREAD_ID_MANAGER.lock().alloc());
let new = ThreadWrapper::new(THREAD_ID_MANAGER.lock().alloc());
unsafe {
*THREAD.get() = new;
}
THREAD_GUARD.with(|guard| guard.id.set(new.id()));
new
new.thread
}
} else {
// This is split into 2 thread-local variables so that we can check whether the
Expand Down

0 comments on commit eeaac1b

Please sign in to comment.