use core::cell::UnsafeCell;
use core::ops::{Deref, DerefMut};
use core::sync::atomic::{AtomicBool, Ordering};
pub(crate) struct Mutex<T> {
data: UnsafeCell<T>,
lock: AtomicBool,
}
impl<T> Mutex<T> {
pub const fn new(data: T) -> Self {
Self {
data: UnsafeCell::new(data),
lock: AtomicBool::new(false),
}
}
pub fn get_mut(&mut self) -> &mut T {
debug_assert!(!*self.lock.get_mut());
self.data.get_mut()
}
pub fn lock(&self) -> Lock<'_, T> {
while self.lock.swap(true, Ordering::SeqCst) {
core::hint::spin_loop();
}
Lock(self)
}
}
pub(crate) struct Lock<'mutex, T>(&'mutex Mutex<T>);
impl<T> Deref for Lock<'_, T> {
type Target = T;
fn deref(&self) -> &T {
unsafe { &*self.0.data.get() }
}
}
impl<T> DerefMut for Lock<'_, T> {
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut *self.0.data.get() }
}
}
impl<T> Drop for Lock<'_, T> {
fn drop(&mut self) {
self.0.lock.store(false, Ordering::SeqCst);
}
}
unsafe impl<T> Sync for Mutex<T> {}