| 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 | |