use crate::{Cores, ExceptionLock, PerCore};
use alloc::boxed::Box;
use core::iter::repeat_with;
unsafe impl<V: Send, C: Cores> Sync for PerCore<Box<[ExceptionLock<V>]>, C> {}
impl<T, C: Cores> PerCore<Box<[T]>, C> {
pub fn get(&self) -> &T {
&self.values[C::core_index()]
}
pub fn get_mut(&mut self) -> &mut T {
&mut self.values[C::core_index()]
}
}
impl<T: Default, C: Cores> PerCore<Box<[T]>, C> {
pub fn new_with_default(core_count: usize) -> Self {
let boxed_slice = repeat_with(|| Default::default())
.take(core_count)
.collect();
Self::new(boxed_slice)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{ExceptionFree, tests::FakeCoresImpl};
use alloc::boxed::Box;
use core::{cell::RefCell, iter::repeat_with};
use spin::{Lazy, once::Once};
#[test]
fn percore_boxed_slice() {
static STATE: Once<PerCore<Box<[ExceptionLock<RefCell<u32>>]>, FakeCoresImpl>> =
Once::new();
STATE.call_once(|| {
let boxed_slice: Box<[ExceptionLock<RefCell<u32>>]> =
repeat_with(|| ExceptionLock::new(RefCell::new(42)))
.take(4)
.collect();
PerCore::<Box<[_]>, _>::new(boxed_slice)
});
{
let token = unsafe { ExceptionFree::new() };
assert_eq!(*STATE.get().unwrap().get().borrow_mut(token), 42);
*STATE.get().unwrap().get().borrow_mut(token) += 1;
assert_eq!(*STATE.get().unwrap().get().borrow_mut(token), 43);
}
}
#[test]
fn percore_boxed_slice_default() {
static STATE: Lazy<PerCore<Box<[ExceptionLock<RefCell<u32>>]>, FakeCoresImpl>> =
Lazy::new(|| PerCore::new_with_default(4));
{
let token = unsafe { ExceptionFree::new() };
assert_eq!(*STATE.get().borrow_mut(token), 0);
*STATE.get().borrow_mut(token) += 1;
assert_eq!(*STATE.get().borrow_mut(token), 1);
}
}
}