pub use self::inner::*;
pub trait AtomicMut<T> {
fn read_mut(&mut self) -> T;
fn write_mut(&mut self, value: T);
}
#[cfg(loom)]
mod inner {
pub use loom::{cell, sync::atomic};
impl super::AtomicMut<bool> for atomic::AtomicBool {
fn read_mut(&mut self) -> bool {
self.load(atomic::Ordering::Relaxed)
}
fn write_mut(&mut self, value: bool) {
self.store(value, atomic::Ordering::Relaxed)
}
}
impl super::AtomicMut<usize> for atomic::AtomicUsize {
fn read_mut(&mut self) -> usize {
self.load(atomic::Ordering::Relaxed)
}
fn write_mut(&mut self, value: usize) {
self.store(value, atomic::Ordering::Relaxed)
}
}
impl<T> super::AtomicMut<*mut T> for atomic::AtomicPtr<T> {
fn read_mut(&mut self) -> *mut T {
self.load(atomic::Ordering::Relaxed)
}
fn write_mut(&mut self, value: *mut T) {
self.store(value, atomic::Ordering::Relaxed)
}
}
}
#[cfg(not(loom))]
mod inner {
pub use core::sync::atomic;
impl super::AtomicMut<bool> for atomic::AtomicBool {
#[inline(always)]
fn read_mut(&mut self) -> bool {
*self.get_mut()
}
#[inline(always)]
fn write_mut(&mut self, value: bool) {
*self.get_mut() = value;
}
}
impl super::AtomicMut<usize> for atomic::AtomicUsize {
#[inline(always)]
fn read_mut(&mut self) -> usize {
*self.get_mut()
}
#[inline(always)]
fn write_mut(&mut self, value: usize) {
*self.get_mut() = value;
}
}
impl<T> super::AtomicMut<*mut T> for atomic::AtomicPtr<T> {
#[inline(always)]
fn read_mut(&mut self) -> *mut T {
*self.get_mut()
}
#[inline(always)]
fn write_mut(&mut self, value: *mut T) {
*self.get_mut() = value;
}
}
pub mod cell {
pub struct UnsafeCell<T>(core::cell::UnsafeCell<T>);
impl<T> UnsafeCell<T> {
#[inline(always)]
pub fn new(val: T) -> Self {
Self(core::cell::UnsafeCell::new(val))
}
#[inline(always)]
pub fn into_inner(self) -> T {
self.0.into_inner()
}
#[inline(always)]
pub fn with<F, R>(&self, f: F) -> R
where
F: FnOnce(*const T) -> R,
{
f(self.0.get())
}
#[inline(always)]
pub fn with_mut<F, R>(&self, f: F) -> R
where
F: FnOnce(*mut T) -> R,
{
f(self.0.get())
}
}
}
}