use core::hint::unlikely;
use semx_bitops::bitmap::BitMap;
use crate::sync::spinlock::Spinlock;
struct PidMap {
pidmap: BitMap,
next: usize,
max: usize,
}
static PIDMAP: Spinlock<PidMap> = Spinlock::new(PidMap { pidmap: BitMap::new(), next: 0, max: 0 });
pub(super) struct Pid(usize);
impl Pid {
pub(super) const fn new() -> Self {
Pid(0)
}
pub(super) fn create() -> Self {
let mut map = PIDMAP.lock_irq_save();
let mut idx = map.pidmap.bitmap_find_next_zero_bit(map.next);
if unlikely(idx == map.max) {
let nr = map.max;
map.pidmap.bitmap_extend_nr(nr);
map.max *= 2;
idx = map.pidmap.bitmap_find_next_zero_bit(idx);
debug_assert!(idx < map.max);
}
map.next = idx + 1;
map.pidmap.bitmap_set_bit(idx);
Pid(idx)
}
pub(super) fn to_value(&self) -> usize {
self.0
}
}
impl Drop for Pid {
fn drop(&mut self) {
let idx = self.0;
let mut map = PIDMAP.lock_irq_save();
map.pidmap.bitmap_clear(idx, 1);
if map.next > idx {
map.next = idx;
}
}
}
pub(super) fn pid_init() {
let mut map = PIDMAP.lock();
map.pidmap.init(1024);
map.max = 1024;
}