use melinoe::sync::{thread_local_scope, ThreadLocalToken};
use melinoe::{MelinoeCell, MelinoeMut, MelinoeRef};
pub struct ThreadLocalPlacement<'brand> {
token: ThreadLocalToken<'brand>,
}
impl<'brand> ThreadLocalPlacement<'brand> {
#[must_use]
#[inline]
pub const fn cell<T>(&self, value: T) -> MelinoeCell<'brand, T> {
MelinoeCell::new(value)
}
#[inline]
pub fn read<'a, T>(&'a self, cell: &'a MelinoeCell<'brand, T>) -> MelinoeRef<'a, 'brand, T> {
cell.borrow(&self.token)
}
#[inline]
pub fn write<'a, T>(
&'a mut self,
cell: &'a MelinoeCell<'brand, T>,
) -> MelinoeMut<'a, 'brand, T> {
cell.borrow_mut(&mut self.token)
}
#[must_use]
#[inline]
pub fn pin_local(self) -> ThreadLocalNumaPlacement<'brand> {
ThreadLocalNumaPlacement {
node_id: crate::query::current_numa_node(),
token: self.token,
}
}
#[must_use]
#[inline]
pub fn pin_local_static<const NODE_ID: u32>(
self,
) -> ConstThreadLocalNumaPlacement<'brand, NODE_ID> {
ConstThreadLocalNumaPlacement { token: self.token }
}
}
pub struct ThreadLocalNumaPlacement<'brand> {
node_id: crate::law::NumaNodeId,
token: melinoe::sync::ThreadLocalToken<'brand>,
}
impl<'brand> ThreadLocalNumaPlacement<'brand> {
#[must_use]
pub const fn node_id(&self) -> crate::law::NumaNodeId {
self.node_id
}
#[inline]
pub fn read<'a, C, T>(&'a self, cell: &'a C) -> Option<MelinoeRef<'a, 'brand, T>>
where
C: crate::branded::PinnedCell<'brand, T> + ?Sized,
{
if self.node_id == cell.node_id() {
Some(cell.cell().borrow(&self.token))
} else {
None
}
}
#[inline]
pub fn write<'a, C, T>(&'a mut self, cell: &'a C) -> Option<MelinoeMut<'a, 'brand, T>>
where
C: crate::branded::PinnedCell<'brand, T> + ?Sized,
{
if self.node_id == cell.node_id() {
Some(cell.cell().borrow_mut(&mut self.token))
} else {
None
}
}
#[inline]
pub fn read_slice<'a, S, T>(&'a self, slice: &'a S) -> Option<&'a [T]>
where
S: crate::branded::PinnedSlice<'brand, T> + ?Sized,
{
if self.node_id == slice.node_id() {
use melinoe::CellSliceExt;
Some(slice.cells().borrow_slice(&self.token))
} else {
None
}
}
#[inline]
pub fn write_slice<'a, S, T>(&'a mut self, slice: &'a S) -> Option<&'a mut [T]>
where
S: crate::branded::PinnedSlice<'brand, T> + ?Sized,
{
if self.node_id == slice.node_id() {
use melinoe::CellSliceExt;
Some(slice.cells().borrow_slice_mut(&mut self.token))
} else {
None
}
}
}
pub struct ConstThreadLocalNumaPlacement<'brand, const NODE_ID: u32> {
token: ThreadLocalToken<'brand>,
}
impl<'brand, const NODE_ID: u32> ConstThreadLocalNumaPlacement<'brand, NODE_ID> {
#[must_use]
pub const fn node_id(&self) -> u32 {
NODE_ID
}
#[inline]
pub fn read<'a, C, T>(&'a self, cell: &'a C) -> MelinoeRef<'a, 'brand, T>
where
C: crate::branded::ConstPinnedCell<'brand, NODE_ID, T> + ?Sized,
{
cell.cell().borrow(&self.token)
}
#[inline]
pub fn write<'a, C, T>(&'a mut self, cell: &'a C) -> MelinoeMut<'a, 'brand, T>
where
C: crate::branded::ConstPinnedCell<'brand, NODE_ID, T> + ?Sized,
{
cell.cell().borrow_mut(&mut self.token)
}
#[inline]
pub fn read_slice<'a, S, T>(&'a self, slice: &'a S) -> &'a [T]
where
S: crate::branded::ConstPinnedSlice<'brand, NODE_ID, T> + ?Sized,
{
use melinoe::CellSliceExt;
slice.cells().borrow_slice(&self.token)
}
#[inline]
pub fn write_slice<'a, S, T>(&'a mut self, slice: &'a S) -> &'a mut [T]
where
S: crate::branded::ConstPinnedSlice<'brand, NODE_ID, T> + ?Sized,
{
use melinoe::CellSliceExt;
slice.cells().borrow_slice_mut(&mut self.token)
}
}
#[inline]
pub fn thread_local_placement_scope<R>(
f: impl for<'brand> FnOnce(ThreadLocalPlacement<'brand>) -> R,
) -> R {
thread_local_scope(|token| f(ThreadLocalPlacement { token }))
}