use crate::runtime::context;
use std::{fmt, num::NonZeroU64};
#[cfg_attr(docsrs, doc(cfg(all(feature = "rt"))))]
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
pub struct Id(pub(crate) NonZeroU64);
#[track_caller]
pub fn id() -> Id {
context::current_task_id().expect("Can't get a task id when not inside a task")
}
#[track_caller]
pub fn try_id() -> Option<Id> {
context::current_task_id()
}
impl fmt::Display for Id {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl Id {
pub(crate) fn next() -> Self {
use crate::loom::sync::atomic::Ordering::Relaxed;
use crate::loom::sync::atomic::StaticAtomicU64;
#[cfg(all(test, loom))]
crate::loom::lazy_static! {
static ref NEXT_ID: StaticAtomicU64 = StaticAtomicU64::new(1);
}
#[cfg(not(all(test, loom)))]
static NEXT_ID: StaticAtomicU64 = StaticAtomicU64::new(1);
loop {
let id = NEXT_ID.fetch_add(1, Relaxed);
if let Some(id) = NonZeroU64::new(id) {
return Self(id);
}
}
}
pub(crate) fn as_u64(&self) -> u64 {
self.0.get()
}
}