1use std::num::NonZeroU64;
2
3#[derive(Eq, PartialEq, Clone, Copy, Hash, Debug)]
4pub(crate) struct ThreadId(NonZeroU64);
5
6impl ThreadId {
7 pub(crate) fn next() -> Self {
8 use crate::loom::sync::atomic::{Ordering::Relaxed, StaticAtomicU64};
9
10 static NEXT_ID: StaticAtomicU64 = StaticAtomicU64::new(0);
11
12 let mut last: u64 = NEXT_ID.load(order:Relaxed);
13 loop {
14 let id: u64 = match last.checked_add(1) {
15 Some(id: u64) => id,
16 None => exhausted(),
17 };
18
19 match NEXT_ID.compare_exchange_weak(current:last, new:id, success:Relaxed, failure:Relaxed) {
20 Ok(_) => return ThreadId(NonZeroU64::new(id).unwrap()),
21 Err(id: u64) => last = id,
22 }
23 }
24 }
25}
26
27#[cold]
28#[allow(dead_code)]
29fn exhausted() -> ! {
30 panic!("failed to generate unique thread ID: bitspace exhausted")
31}
32