Add RawCell<T> wrapper.
This commit is contained in:
@@ -67,6 +67,7 @@ pub mod ld_so;
|
||||
pub mod out;
|
||||
pub mod platform;
|
||||
pub mod pthread;
|
||||
pub mod raw_cell;
|
||||
pub mod start;
|
||||
pub mod sync;
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
use core::cell::UnsafeCell;
|
||||
|
||||
/// Wrapper over `UnsafeCell` that can directly be used in statics, where all modifications require
|
||||
/// unsafe.
|
||||
#[repr(transparent)]
|
||||
pub struct RawCell<T> {
|
||||
inner: UnsafeCell<T>,
|
||||
}
|
||||
impl<T> RawCell<T> {
|
||||
#[inline]
|
||||
pub const fn new(t: T) -> Self {
|
||||
Self {
|
||||
inner: UnsafeCell::new(t),
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub unsafe fn get(&self) -> T {
|
||||
self.inner.get().read()
|
||||
}
|
||||
#[inline]
|
||||
pub unsafe fn set(&self, t: T) {
|
||||
self.inner.get().write(t)
|
||||
}
|
||||
#[inline]
|
||||
pub fn as_mut_ptr(&self) -> *mut T {
|
||||
self.inner.get()
|
||||
}
|
||||
#[inline]
|
||||
pub fn get_mut(&mut self) -> &mut T {
|
||||
self.inner.get_mut()
|
||||
}
|
||||
#[inline]
|
||||
pub fn into_inner(self) -> T {
|
||||
self.inner.into_inner()
|
||||
}
|
||||
}
|
||||
|
||||
// SAFETY: Sync requires that no safe interface be allowed to act on &self in a way that is
|
||||
// undefined behavior when accessed concurrently. The interface above only allows get, set, and
|
||||
// as_mut_ptr, where the former two that access memory are unsafe anyway.
|
||||
unsafe impl<T> Sync for RawCell<T> {}
|
||||
|
||||
const _: () = {
|
||||
// Check that RawCell works for non-Sync types.
|
||||
static X: RawCell<*mut ()> = RawCell::new(core::ptr::null_mut());
|
||||
};
|
||||
Reference in New Issue
Block a user