1 | use std::num::NonZeroU64; |
2 | |
3 | #[derive (Eq, PartialEq, Clone, Copy, Hash, Debug)] |
4 | pub(crate) struct ThreadId(NonZeroU64); |
5 | |
6 | impl 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)] |
29 | fn exhausted() -> ! { |
30 | panic!("failed to generate unique thread ID: bitspace exhausted" ) |
31 | } |
32 | |