use core::sync::atomic::Ordering;
use arbitrary_int::u3;
use portable_atomic::AtomicU32;
pub struct ExecutorRegistry {
slots: [AtomicU32; 8],
}
impl ExecutorRegistry {
pub const fn new() -> Self {
ExecutorRegistry {
slots: [const { AtomicU32::new(0) }; 8],
}
}
pub fn lookup_or_register(&self, executor_id: u32) -> Option<u3> {
self.slots.iter().enumerate().find_map(|(i, slot)| {
let item_id = slot.load(Ordering::Relaxed);
if item_id == executor_id {
return Some(u3::new(i as u8));
}
if item_id == 0 {
let res =
slot.compare_exchange(0, executor_id, Ordering::SeqCst, Ordering::Relaxed);
match res {
Ok(_) => {
return Some(u3::new(i as u8));
}
Err(actual) => {
if actual == executor_id {
return Some(u3::new(i as u8));
}
}
}
}
None
})
}
}