use core::ops::Range;
use sel4::{init_thread, with_ipc_buffer_mut};
use sel4_kit::slot_manager::{LeafSlot, SlotManager};
use spin::{Mutex, once::Once};
static SLOT_MANAGER: Mutex<SlotManager> = Mutex::new(SlotManager::empty());
static SLOT_EDGE_HANDLER: Once<fn(LeafSlot)> = Once::new();
pub fn init(empty_slots: Range<usize>) {
SLOT_MANAGER.lock().init_empty_slots(empty_slots);
}
pub fn init_slot_edge_handler(handler: fn(LeafSlot)) {
SLOT_EDGE_HANDLER.call_once(|| handler);
}
#[inline]
pub fn alloc_slot() -> LeafSlot {
let mut slot_manager = SLOT_MANAGER.lock();
if slot_manager.available() == 0 {
SLOT_EDGE_HANDLER.get().unwrap()(LeafSlot::new(slot_manager.next_range_start()));
slot_manager.extend(0x1000);
}
slot_manager.alloc_slot()
}
#[inline]
pub fn alloc_slots(num: usize) -> LeafSlot {
SLOT_MANAGER.lock().alloc_slots(num).next().unwrap()
}
#[cfg(feature = "alloc")]
pub fn recycle_slot(slot: LeafSlot) {
SLOT_MANAGER.lock().recycle_slot(slot);
}
pub fn init_recv_slot() {
with_ipc_buffer_mut(|ipc_buffer| {
ipc_buffer.set_recv_slot(
&init_thread::slot::CNODE
.cap()
.absolute_cptr_from_bits_with_depth(0, 64),
);
})
}