use core::ptr::NonNull;
use crate::task::TaskHeader;
#[derive(Copy, Clone)]
pub(crate) struct Packed(u64);
impl From<Unpacked> for Packed {
#[inline]
fn from(value: Unpacked) -> Self {
match value {
Unpacked::New => Self(0),
Unpacked::Submitted { task } => {
let val = task.as_ptr() as u64;
debug_assert_eq!(val >> 63, 0, "high bit is set in pointer");
Self(val)
}
Unpacked::Completed { ret } => Self(0b1 << 63 | u64::from(ret as u32)),
}
}
}
impl From<Packed> for Unpacked {
#[inline]
fn from(value: Packed) -> Self {
if (value.0 >> 63) != 0 {
Unpacked::Completed {
ret: value.0 as u32 as i32,
}
} else if let Some(task) = NonNull::new(value.0 as *mut TaskHeader) {
Unpacked::Submitted { task }
} else {
Unpacked::New
}
}
}
pub(crate) enum Unpacked {
New,
Submitted { task: NonNull<TaskHeader> },
Completed { ret: i32 },
}