use crate::object_tag::ObjectTag; pub const NONE_SENTINEL: u16 = 0xFFFF; #[derive(Debug, Clone, Copy)] #[repr(C)] pub struct KernelObjectHeader { pub tag: u8, pub _pad: [u8; 3], pub generation: u32, pub ref_count: u32, pub parent_untyped: u16, pub next_child: u16, pub object_size: u16, pub _reserved: [u8; 14], } const _: () = assert!(core::mem::size_of::() == 32); impl KernelObjectHeader { pub const fn new(tag: ObjectTag, generation: u32, object_size: u16) -> Self { Self { tag: tag as u8, _pad: [0; 3], generation, ref_count: 1, parent_untyped: NONE_SENTINEL, next_child: NONE_SENTINEL, object_size, _reserved: [0; 14], } } pub const fn tag_byte(&self) -> u8 { self.tag } pub const fn generation(&self) -> u32 { self.generation } pub const fn ref_count(&self) -> u32 { self.ref_count } pub const fn parent_untyped(&self) -> u16 { self.parent_untyped } pub const fn next_child(&self) -> u16 { self.next_child } pub const fn object_size(&self) -> u16 { self.object_size } pub fn inc_ref(&mut self) -> Option { match self.ref_count.checked_add(1) { Some(new) => { self.ref_count = new; Some(new) } None => None, } } pub fn dec_ref(&mut self) -> u32 { self.ref_count = self.ref_count.saturating_sub(1); self.ref_count } pub const fn is_stale(&self, expected_gen: u32) -> bool { self.generation != expected_gen } pub fn set_parent_untyped(&mut self, idx: u16) { self.parent_untyped = idx; } pub fn set_next_child(&mut self, idx: u16) { self.next_child = idx; } }