use super::token::{Token, TokenEpoch, TokenSlot};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) struct Udata(u64);
impl Udata {
const EPOCH_MASK: u64 = 0x00FF_FFFF;
const SLOT_SHIFT: u32 = 24;
const SLOT_MASK: u64 = 0xFFFF;
const TAG_SHIFT: u32 = 40;
const TAG_MASK: u64 = 0xFF;
pub(crate) fn pack(tag: u8, slot: u16, epoch: u32) -> Self {
let raw = (epoch as u64 & Self::EPOCH_MASK)
| ((slot as u64 & Self::SLOT_MASK) << Self::SLOT_SHIFT)
| ((tag as u64 & Self::TAG_MASK) << Self::TAG_SHIFT);
Self(raw)
}
pub(crate) fn unpack(self) -> (u8, u16, u32) {
let epoch = (self.0 & Self::EPOCH_MASK) as u32;
let slot = ((self.0 >> Self::SLOT_SHIFT) & Self::SLOT_MASK) as u16;
let tag = ((self.0 >> Self::TAG_SHIFT) & Self::TAG_MASK) as u8;
(tag, slot, epoch)
}
pub(crate) fn from_kevent(p: *mut libc::c_void) -> Self {
Self(p as usize as u64)
}
pub(crate) fn into_kevent(self) -> *mut libc::c_void {
self.0 as usize as *mut libc::c_void
}
pub(crate) fn into_token(self) -> Token {
let (_, slot, epoch) = self.unpack();
Token::new(TokenSlot::from_raw(slot), TokenEpoch::from_raw(epoch))
}
pub(crate) fn from_token(token: Token, tag: u8) -> Self {
Self::pack(tag, token.slot_raw(), token.epoch_raw())
}
}