diff --git a/Cargo.toml b/Cargo.toml index c42e7f46..3bc04c47 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,7 +42,7 @@ memmap = "0.7.0" term-painter = "0.3.0" libc = "0.2.82" impl-trait-for-tuples = "0.2.0" -crndm_derive = "0.1.1" +crndm_derive = { path="./crndm_derive"} num_cpus = "1.13.0" # examples diff --git a/crndm_derive/src/cbinding.rs b/crndm_derive/src/cbinding.rs index 8ba27ee0..b9f4d07b 100644 --- a/crndm_derive/src/cbinding.rs +++ b/crndm_derive/src/cbinding.rs @@ -6,7 +6,7 @@ use syn::spanned::Spanned; use syn::*; use syn::punctuated::Punctuated; use std::collections::HashMap; -use std::lazy::SyncLazy; +use std::sync::LazyLock; use std::sync::Mutex; use std::io::*; use std::fs::{File,create_dir_all,read_to_string}; @@ -36,11 +36,11 @@ pub struct Attributes { concurrent: bool } -pub static mut TYPES: SyncLazy>> = SyncLazy::new(|| { +pub static mut TYPES: LazyLock>> = LazyLock::new(|| { Mutex::new(HashMap::new()) }); -pub static mut POOLS: SyncLazy>> = SyncLazy::new(|| { +pub static mut POOLS: LazyLock>> = LazyLock::new(|| { Mutex::new(HashMap::new()) }); @@ -280,7 +280,7 @@ pub fn derive_cbindgen(input: TokenStream) -> TokenStream { Ok(g) => g, Err(p) => p.into_inner() } }; - let mut entry = all_types.entry(name_str.clone()).or_insert(Contents::default()); + let entry = all_types.entry(name_str.clone()).or_insert(Contents::default()); entry.generics = generics.iter().map(|v| v.to_string()).collect(); let new_sizes: Vec = generics.iter().map(|v| format_ident!("{}_size", v.to_string())).collect(); diff --git a/crndm_derive/src/lib.rs b/crndm_derive/src/lib.rs index c81ea81e..734ccfba 100644 --- a/crndm_derive/src/lib.rs +++ b/crndm_derive/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(once_cell)] -#![feature(type_name_of_val)] #![feature(proc_macro_span)] use proc_macro2::Group; diff --git a/examples/mapcli/map/mod.rs b/examples/mapcli/map/mod.rs index 03075b2a..74c3e611 100644 --- a/examples/mapcli/map/mod.rs +++ b/examples/mapcli/map/mod.rs @@ -8,11 +8,8 @@ mod vbtree; pub use btree::*; pub use ctree::*; -pub use pbtree::*; pub use rbtree::*; pub use rtree::*; -pub use ubtree::*; -pub use vbtree::*; use corundum::default::*; diff --git a/examples/mapcli/map/rtree.rs b/examples/mapcli/map/rtree.rs index bcdc4ac0..37d35b4e 100644 --- a/examples/mapcli/map/rtree.rs +++ b/examples/mapcli/map/rtree.rs @@ -1,17 +1,17 @@ use crate::map::Map; use corundum::default::*; -use std::collections::BTreeMap; +use std::{cell::UnsafeCell, collections::BTreeMap}; type P = Allocator; pub struct RTree { - btree: BTreeMap, + btree: UnsafeCell>, } impl RTree { - fn self_mut(&self) -> &mut Self { - unsafe { &mut *(self as *const Self as *mut Self) } + fn get(&self) -> &mut BTreeMap { + unsafe { &mut *self.btree.get() } } } @@ -20,32 +20,32 @@ where K: std::cmp::Ord, { fn clear(&self) { - self.self_mut().btree.clear(); + self.get().clear(); } fn insert(&self, key: K, val: V) { - self.self_mut().btree.insert(key, val); + self.get().insert(key, val); } fn remove(&self, key: K) { - self.self_mut().btree.remove(&key); + self.get().remove(&key); } fn is_empty(&self) -> bool { - self.btree.is_empty() + self.get().is_empty() } fn foreach bool>(&self, f: F) -> bool { - for (k, v) in &self.btree { + for (k, v) in self.get() { f(k, v); } true } fn lookup(&self, key: K) -> bool { - self.btree.get(&key).is_some() + self.get().get(&key).is_some() } } impl Default for RTree { fn default() -> Self { Self { - btree: BTreeMap::new(), + btree: UnsafeCell::new(BTreeMap::new()), } } } diff --git a/examples/microbench.rs b/examples/microbench.rs index 8f813aa2..d6a1dd43 100644 --- a/examples/microbench.rs +++ b/examples/microbench.rs @@ -6,6 +6,7 @@ mod run { use corundum::stat::*; use corundum::open_flags::*; use corundum::stm::{Log, Logger, Notifier}; + use std::arch::asm; type P = Allocator; const CNT: usize = 50000; @@ -28,7 +29,7 @@ mod run { }; } - fn main() { + pub fn main() { use std::env; use std::vec::Vec as StdVec; @@ -282,7 +283,7 @@ mod run { let layout = std::alloc::Layout::from_size_align(*s * 8, 4).unwrap(); measure!(format!("malloc({})", *s * 8), cnt, { for _ in 0..cnt { - unsafe{ std::alloc::alloc(layout); } + unsafe{ let _ = std::alloc::alloc(layout); } } }); } diff --git a/examples/simplekv.rs b/examples/simplekv.rs index 782ca2c1..37b57f3a 100644 --- a/examples/simplekv.rs +++ b/examples/simplekv.rs @@ -6,7 +6,6 @@ #![allow(dead_code)] #![allow(incomplete_features)] -#![feature(type_name_of_val)] use std::mem::MaybeUninit; use corundum::default::*; diff --git a/src/alloc/alg/buddy.rs b/src/alloc/alg/buddy.rs index f2657de6..9d325d87 100644 --- a/src/alloc/alg/buddy.rs +++ b/src/alloc/alg/buddy.rs @@ -5,6 +5,7 @@ use std::ops::{Index,IndexMut}; use std::marker::PhantomData; use std::mem; + #[repr(transparent)] #[derive(Clone, Debug)] /// Buddy memory block @@ -176,7 +177,7 @@ impl BuddyAlg { #[cfg(any(feature = "no_pthread", windows))] { let tid = std::thread::current().id().as_u64().get(); - while std::intrinsics::atomic_cxchg_acqrel(&mut self.mutex, 0, tid).0 != tid {} + while std::intrinsics::atomic_cxchg_acqrel_acquire(&mut self.mutex, 0, tid).0 != tid {} } } } @@ -188,7 +189,7 @@ impl BuddyAlg { libc::pthread_mutex_unlock(&mut self.mutex.0); #[cfg(any(feature = "no_pthread", windows))] - std::intrinsics::atomic_store_rel(&mut self.mutex, 0); + std::intrinsics::atomic_store_release(&mut self.mutex, 0); } } @@ -232,7 +233,7 @@ impl BuddyAlg { self.aux.clear(); self.log64.foreach(|(off, data)| unsafe { let n = Self::buddy(off); - std::intrinsics::atomic_store_rel(&mut n.next, data); + std::intrinsics::atomic_store_release(&mut n.next, data); }); self.log64.clear(); self.available = self.available_log; @@ -1003,6 +1004,7 @@ macro_rules! pool { ($mod:ident, $name:ident) => { /// The default allocator module pub mod $mod { + #![allow(unused_imports)] use memmap::*; use std::collections::hash_map::DefaultHasher; use std::collections::{HashMap,HashSet}; diff --git a/src/alloc/heap.rs b/src/alloc/heap.rs index af59af7e..89e8bdb2 100644 --- a/src/alloc/heap.rs +++ b/src/alloc/heap.rs @@ -149,7 +149,7 @@ unsafe impl MemPoolTraits for Heap { unsafe fn journals_head() -> &'static u64 { static mut HEAD: u64 = u64::MAX; - &HEAD + &*std::ptr::addr_of!(HEAD) } unsafe fn close() -> Result<()> { diff --git a/src/cell/cell.rs b/src/cell/cell.rs index b63da4ee..512d0c32 100644 --- a/src/cell/cell.rs +++ b/src/cell/cell.rs @@ -272,11 +272,6 @@ impl PCell { self.value.into_inner().1 } } - - #[inline] - fn self_mut(&self) -> &mut Self { - unsafe { &mut *(self as *const Self as *mut Self) } - } } impl PCell { diff --git a/src/cell/refcell.rs b/src/cell/refcell.rs index bfe986af..f89b82c7 100644 --- a/src/cell/refcell.rs +++ b/src/cell/refcell.rs @@ -208,15 +208,6 @@ impl Debug for PRefCell { } impl PRefCell { - #[inline(always)] - #[allow(clippy::mut_from_ref)] - fn self_mut(&self) -> &mut Self { - unsafe { - let ptr: *const Self = self; - &mut *(ptr as *mut Self) - } - } - #[inline] #[allow(clippy::mut_from_ref)] /// Takes a log and returns a mutable reference to the underlying data. @@ -476,7 +467,7 @@ impl PRefCell { *borrow = 1; } RefMut { - value: unsafe { &mut *(self as *const Self as *mut Self) }, + value: self as *const Self as *mut Self, journal, phantom: PhantomData } diff --git a/src/cell/tcell.rs b/src/cell/tcell.rs index bff582f0..84ff6a4d 100644 --- a/src/cell/tcell.rs +++ b/src/cell/tcell.rs @@ -79,7 +79,7 @@ impl TCell { #[inline] pub(crate) fn as_mut(&self) -> &mut T { - unsafe { &mut *(self.deref() as *const T as *mut T) } + unsafe { utils::as_mut(self).force() } } #[inline] diff --git a/src/cell/vcell.rs b/src/cell/vcell.rs index ed777506..7efbc9d9 100644 --- a/src/cell/vcell.rs +++ b/src/cell/vcell.rs @@ -1,5 +1,6 @@ use crate::alloc::MemPool; use crate::{PSafe, VSafe, utils}; +use std::cell::UnsafeCell; use std::cmp::*; use std::mem::*; use std::marker::PhantomData; @@ -37,7 +38,7 @@ use std::ops::{Deref, DerefMut}; pub struct VCell { phantom: PhantomData<(A, T)>, gen: u32, - value: T, + value: UnsafeCell, } /// Safe to transfer between thread boundaries @@ -52,14 +53,18 @@ impl VCell { pub fn new(v: T) -> Self { Self { gen: A::gen(), - value: v, + value: UnsafeCell::new(v), phantom: PhantomData, } } + fn get_value(&self) -> &mut T { + unsafe { &mut *self.value.get() } + } + #[inline] pub(crate) fn as_mut(&self) -> &mut T { - unsafe { &mut *(self.deref() as *const T as *mut T) } + unsafe { utils::as_mut(self).force() } } #[inline] @@ -67,7 +72,7 @@ impl VCell { pub const fn new_invalid(v: T) -> Self { Self { gen: 0, - value: v, + value: UnsafeCell::new(v), phantom: PhantomData, } } @@ -86,12 +91,12 @@ impl VCell { let z = A::zone(off); A::prepare(z); // Used as a global lock if self.gen != gen { - forget(replace(&mut self.value, T::default())); + forget(replace(&mut self.value, UnsafeCell::new(T::default()))); self.gen = gen; } A::perform(z); } - &mut self.value + self.value.get_mut() } } } @@ -100,7 +105,7 @@ impl Default for VCell { fn default() -> Self { Self { gen: A::gen(), - value: T::default(), + value: UnsafeCell::new(T::default()), phantom: PhantomData, } } @@ -125,7 +130,7 @@ impl DerefMut for VCell { impl PartialEq for VCell { #[inline] fn eq(&self, other: &VCell) -> bool { - self.value == other.value + self.get_value() == other.get_value() } } @@ -134,67 +139,67 @@ impl Eq for VCell {} impl PartialOrd for VCell { #[inline] fn partial_cmp(&self, other: &VCell) -> Option { - self.value.partial_cmp(&other.value) + self.get_value().partial_cmp(&other.get_value()) } #[inline] fn lt(&self, other: &VCell) -> bool { - self.value < other.value + self.get_value() < other.get_value() } #[inline] fn le(&self, other: &VCell) -> bool { - self.value <= other.value + self.get_value() <= other.get_value() } #[inline] fn gt(&self, other: &VCell) -> bool { - self.value > other.value + self.get_value() > other.get_value() } #[inline] fn ge(&self, other: &VCell) -> bool { - self.value >= other.value + self.get_value() >= other.get_value() } } impl Ord for VCell { #[inline] fn cmp(&self, other: &VCell) -> Ordering { - self.value.cmp(&other.value) + self.get_value().cmp(&other.get_value()) } } impl PartialEq for VCell { #[inline] fn eq(&self, other: &T) -> bool { - self.value == *other + *self.get_value() == *other } } impl PartialOrd for VCell { #[inline] fn partial_cmp(&self, other: &T) -> Option { - self.value.partial_cmp(&other) + (*self.get_value()).partial_cmp(&other) } #[inline] fn lt(&self, other: &T) -> bool { - self.value < *other + *self.get_value() < *other } #[inline] fn le(&self, other: &T) -> bool { - self.value <= *other + *self.get_value() <= *other } #[inline] fn gt(&self, other: &T) -> bool { - self.value > *other + *self.get_value() > *other } #[inline] fn ge(&self, other: &T) -> bool { - self.value >= *other + *self.get_value() >= *other } } \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index dffbd02d..8104bc51 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -102,13 +102,11 @@ //! [`open()`]: ./alloc/struct.MemPool.html#method.open #![feature(auto_traits)] -#![feature(untagged_unions)] #![feature(specialization)] #![feature(concat_idents)] #![feature(core_intrinsics)] #![feature(thread_id_value)] #![feature(negative_impls)] -#![feature(backtrace)] #![feature(trusted_len)] #![feature(exact_size_is_empty)] #![feature(alloc_layout_extra)] @@ -118,22 +116,21 @@ #![feature(trait_alias)] #![feature(slice_concat_trait)] #![feature(slice_partition_dedup)] -#![feature(type_name_of_val)] #![feature(pattern)] #![feature(str_internals)] -#![feature(toowned_clone_into)] #![feature(fn_traits)] #![feature(unboxed_closures)] #![feature(let_chains)] #![feature(c_variadic)] #![feature(rustc_attrs)] #![feature(allocator_api)] -#![feature(associated_type_bounds)] // #![feature(async_stream)] #![allow(dead_code)] #![allow(incomplete_features)] #![allow(type_alias_bounds)] +#![allow(internal_features)] +#![allow(unexpected_cfgs)] pub(crate) const PAGE_LOG_SLOTS: usize = 128; diff --git a/src/ll.rs b/src/ll.rs index ea859477..b8bc1c5d 100644 --- a/src/ll.rs +++ b/src/ll.rs @@ -45,7 +45,7 @@ pub fn persist(ptr: *const T, len: usize, fence: bool) { let off = (off >> 12) << 12; let len = end - off; let ptr = off as *const u8; - if libc::persist( + if libc::msync( ptr as *mut libc::c_void, len, libc::MS_SYNC | libc::MS_INVALIDATE, @@ -133,6 +133,6 @@ pub fn sfence() { #[inline] pub fn mfence() { unsafe { - std::intrinsics::atomic_fence() + std::intrinsics::atomic_fence_seqcst() } } diff --git a/src/marker.rs b/src/marker.rs index a0b14145..6c126e59 100644 --- a/src/marker.rs +++ b/src/marker.rs @@ -126,7 +126,7 @@ pub unsafe auto trait TxInSafe {} pub unsafe auto trait LooseTxInUnsafe {} /// Any type is okay to be transferred to a transaction -unsafe impl LooseTxInUnsafe for dyn std::any::Any {} +//unsafe impl LooseTxInUnsafe for dyn std::any::Any {} unsafe impl<'a, T> LooseTxInUnsafe for &'a mut T {} unsafe impl LooseTxInUnsafe for *const T {} unsafe impl LooseTxInUnsafe for *mut T {} diff --git a/src/prc.rs b/src/prc.rs index 1e62aada..2a54b43c 100644 --- a/src/prc.rs +++ b/src/prc.rs @@ -145,6 +145,7 @@ //! //! [`pclone`]: ./struct.Prc.html#method.pclone //! +use std::cell::UnsafeCell; use std::panic::RefUnwindSafe; use std::panic::UnwindSafe; use crate::alloc::{MemPool, PmemUsage}; @@ -197,7 +198,7 @@ impl Debug for Counter { } pub struct PrcBox { - counter: Counter, + counter: UnsafeCell>, #[cfg(not(feature = "no_volatile_pointers"))] vlist: VCell, @@ -292,6 +293,9 @@ pub struct Prc { phantom: PhantomData, } +unsafe impl TxInSafe for Prc {} +impl UnwindSafe for Prc {} +impl RefUnwindSafe for Prc {} impl !TxOutSafe for Prc {} impl !Send for Prc {} impl !Sync for Prc {} @@ -319,7 +323,7 @@ impl Prc { unsafe { let ptr = Ptr::new_unchecked(A::new( PrcBox:: { - counter: Counter { + counter: UnsafeCell::new(Counter { strong: 1, weak: 1, @@ -334,7 +338,7 @@ impl Prc { temp: TCell::new_invalid(None), phantom: PhantomData - }, + }), #[cfg(not(feature = "no_volatile_pointers"))] vlist: VCell::new(VWeakList::default()), @@ -376,7 +380,7 @@ impl Prc { unsafe { Prc::from_inner(Ptr::from_mut(A::new( PrcBox { - counter: Counter { + counter: UnsafeCell::new(Counter { strong: 1, weak: 1, @@ -391,7 +395,7 @@ impl Prc { temp: TCell::new_invalid(None), phantom: PhantomData - }, + }), #[cfg(not(feature = "no_volatile_pointers"))] vlist: VCell::new(VWeakList::default()), @@ -435,7 +439,7 @@ impl Prc { /// Owns contents of `p` without cloning, leaving `p` untouched pub fn from(p: Prc) -> Self { - let res = Self::from_inner(p.ptr); + let res = Self::from_inner(p.ptr.clone()); mem::forget(p); res } @@ -602,7 +606,7 @@ impl Prc { pub fn downgrade(this: &Self, journal: &Journal) -> Weak { this.inc_weak(journal); debug_assert!(!this.ptr.is_dangling()); - Weak { ptr: this.ptr } + Weak { ptr: this.ptr.clone() } } /// Creates a new `Weak` volatile to this allocation. @@ -776,7 +780,7 @@ impl Prc { unsafe { let new = A::atomic_new( PrcBox:: { - counter: Counter { + counter: UnsafeCell::new(Counter { strong: 1, weak: 1, @@ -791,7 +795,7 @@ impl Prc { temp: TCell::new_invalid(None), phantom: PhantomData - }, + }), #[cfg(not(feature = "no_volatile_pointers"))] vlist: VCell::new(VWeakList::default()), @@ -897,7 +901,7 @@ impl PClone for Prc { /// ``` fn pclone(&self, journal: &Journal) -> Prc { self.inc_strong(journal); - Self::from_inner(self.ptr) + Self::from_inner(self.ptr.clone()) } } @@ -1027,6 +1031,9 @@ pub struct Weak { ptr: Ptr, A>, } +unsafe impl TxInSafe for Weak {} +impl UnwindSafe for Weak {} +impl RefUnwindSafe for Weak {} impl !TxOutSafe for Weak {} impl !Send for Weak {} impl !Sync for Weak {} @@ -1085,7 +1092,7 @@ impl Weak { None } else { inner.inc_strong(journal); - Some(Prc::from_inner(self.ptr)) + Some(Prc::from_inner(self.ptr.clone())) } } @@ -1145,7 +1152,7 @@ impl PClone for Weak { if let Some(inner) = self.inner() { inner.inc_weak(journal) } - Weak { ptr: self.ptr } + Weak { ptr: self.ptr.clone() } } } @@ -1275,15 +1282,17 @@ trait PrcBoxPtr { impl PrcBoxPtr for Prc { #[inline(always)] fn count(&self) -> &mut Counter { - let ret = &mut self.ptr.get_mut().counter; + unsafe { + let ret = &mut *self.ptr.get_mut().counter.get(); - #[cfg(any(feature = "use_pspd", feature = "use_vspd"))] unsafe { - if let Some(inner) = *ret.temp { - return &mut *inner; + #[cfg(any(feature = "use_pspd", feature = "use_vspd"))] unsafe { + if let Some(inner) = *ret.temp { + return &mut *inner; + } } - } - ret + ret + } } } @@ -1291,10 +1300,7 @@ impl PrcBoxPtr for PrcBox { #[inline(always)] fn count(&self) -> &mut Counter { let ret = unsafe { - let ptr: *const Self = self; - let ptr: *mut Self = ptr as *mut Self; - let rcbox: &mut Self = &mut *ptr; - &mut rcbox.counter + &mut *self.counter.get() }; #[cfg(any(feature = "use_pspd", feature = "use_vspd"))] unsafe { @@ -1397,12 +1403,14 @@ impl VWeak { } pub fn promote(&self, journal: &Journal) -> Option> { - let inner = self.inner()?; - let strong = inner.counter.strong; - if strong == 0 { - None - } else { - unsafe { Some(Prc::from_ptr(self.ptr as *const _ as *mut _, journal)) } + unsafe { + let inner = self.inner()?; + let strong = (*inner.counter.get()).strong; + if strong == 0 { + None + } else { + Some(Prc::from_ptr(self.ptr as *const _ as *mut _, journal)) + } } } diff --git a/src/ptr/non_null.rs b/src/ptr/non_null.rs index 1adab7a1..a993da6c 100644 --- a/src/ptr/non_null.rs +++ b/src/ptr/non_null.rs @@ -37,7 +37,7 @@ impl !Sync for NonNull {} impl PartialEq for NonNull { #[inline] fn eq(&self, other: &Self) -> bool { - self.ptr == other.ptr + std::ptr::addr_eq(self.ptr, other.ptr) } } @@ -170,7 +170,7 @@ impl !Sync for LogNonNull {} impl PartialEq for LogNonNull { #[inline] fn eq(&self, other: &Self) -> bool { - self.ptr == other.ptr + std::ptr::addr_eq(self.ptr, other.ptr) } } diff --git a/src/ptr/ptr.rs b/src/ptr/ptr.rs index a2490cbb..8ab096a4 100644 --- a/src/ptr/ptr.rs +++ b/src/ptr/ptr.rs @@ -1,12 +1,12 @@ use crate::alloc::MemPool; use crate::alloc::PmemUsage; use crate::{PSafe, TxOutSafe}; +use std::cell::UnsafeCell; use std::fmt::{Debug, Display, Formatter}; use std::marker::PhantomData; use std::ops::*; use std::ptr::NonNull; -#[derive(Eq)] /// A wrapper around a raw persistent pointer that indicates that the possessor /// of this wrapper owns the referent. Useful for building abstractions like /// [`Pbox`], [`Vec`], and [`String

`]. @@ -22,7 +22,7 @@ use std::ptr::NonNull; /// [`String

`]: ../str/struct.String.html /// pub struct Ptr { - off: u64, + off: UnsafeCell, marker: PhantomData<(A, T)>, } @@ -66,7 +66,7 @@ impl Ptr { pub(crate) fn new(p: &T) -> Option> { if let Ok(off) = A::off(p) { Some(Self { - off, + off: UnsafeCell::new(off), marker: PhantomData, }) } else { @@ -77,38 +77,38 @@ impl Ptr { #[inline] /// Returns the mutable reference of the value pub(crate) fn as_mut(&mut self) -> &mut T { - unsafe { A::get_mut_unchecked(self.off) } + unsafe { A::get_mut_unchecked(*self.off.get()) } } #[inline] /// Returns the reference of the value pub(crate) fn as_ref(&self) -> &T { - unsafe { A::get_unchecked(self.off) } + unsafe { A::get_unchecked(*self.off.get()) } } #[inline] /// Returns the mutable raw pointer of the value pub(crate) fn as_mut_ptr(&mut self) -> *mut T { - unsafe { A::get_mut_unchecked(self.off) } + unsafe { A::get_mut_unchecked(*self.off.get()) } } #[inline] /// Returns the mutable raw pointer of the value pub(crate) fn get_mut_ptr(&self) -> *mut T { - unsafe { A::get_mut_unchecked(self.off) } + unsafe { A::get_mut_unchecked(*self.off.get()) } } #[inline] /// Returns the mutable raw pointer of the value pub(crate) fn as_ptr(&self) -> *const T { - unsafe { A::get_mut_unchecked(self.off) } + unsafe { A::get_mut_unchecked(*self.off.get()) } } #[inline] #[allow(clippy::mut_from_ref)] /// Returns the mutable reference of the value pub(crate) fn get_mut(&self) -> &mut T { - unsafe { A::get_mut_unchecked(self.off) } + unsafe { A::get_mut_unchecked(*self.off.get()) } } /// Creates a new copy of data and returns a `Ptr` pointer @@ -134,33 +134,35 @@ impl Ptr { #[inline] /// Checks if this pointer is dangling pub fn is_dangling(&self) -> bool { - self.off == u64::MAX + unsafe { *self.off.get() == u64::MAX } } #[inline] /// Returns the file offset pub fn off(&self) -> u64 { - self.off + unsafe { *self.off.get() } } #[inline] /// Returns a reference to the file offset pub fn off_ref(&self) -> &u64 { - &self.off + unsafe { &*self.off.get() } } #[inline] /// Returns a reference to the file offset pub(crate) fn off_mut(&self) -> &mut u64 { - unsafe { &mut *(&self.off as *const u64 as *mut u64) } + unsafe { &mut *(self.off.get() as *const u64 as *mut u64) } } #[inline] pub(crate) fn replace(&self, new: u64) -> u64 { - let old = self.off; - *self.off_mut() = new; - old + unsafe { + let old = *self.off.get(); + *self.off_mut() = new; + old + } } /// Creates a new `Ptr`. @@ -171,7 +173,7 @@ impl Ptr { #[inline] pub(crate) unsafe fn new_unchecked(ptr: *const T) -> Self { Self { - off: A::off_unchecked(ptr), + off: UnsafeCell::new(A::off_unchecked(ptr)), marker: PhantomData, } } @@ -180,7 +182,7 @@ impl Ptr { /// Creates a new `Ptr` that is dangling. pub(crate) const fn dangling() -> Ptr { Self { - off: u64::MAX, + off: UnsafeCell::new(u64::MAX), marker: PhantomData, } } @@ -193,7 +195,7 @@ impl Ptr { /// `off` should be valid pub(crate) const unsafe fn from_off_unchecked(off: u64) -> Ptr { Self { - off, + off: UnsafeCell::new(off), marker: PhantomData, } } @@ -238,7 +240,7 @@ impl Ptr { /// Casts to a pointer of another type. pub(crate) fn cast(&self) -> Ptr { Ptr:: { - off: self.off, + off: unsafe { UnsafeCell::new(*self.off.get()) }, marker: PhantomData, } } @@ -252,12 +254,12 @@ impl Ptr { unsafe impl PSafe for Ptr<[T], A> {} -impl Copy for Ptr {} +//impl Copy for Ptr {} impl Clone for Ptr { fn clone(&self) -> Self { Self { - off: self.off, + off: unsafe { UnsafeCell::new(*self.off.get()) }, marker: PhantomData, } } @@ -279,7 +281,7 @@ impl Ptr { 0 }; Self { - off, + off: UnsafeCell::new(off), marker: PhantomData, } } @@ -288,7 +290,7 @@ impl Ptr { #[track_caller] pub(crate) fn from_ref(other: &T) -> Self { Self { - off: A::off(other as *const T).unwrap(), + off: UnsafeCell::new(A::off(other as *const T).unwrap()), marker: PhantomData, } } @@ -297,7 +299,7 @@ impl Ptr { #[track_caller] pub(crate) fn from_mut(other: &mut T) -> Self { Self { - off: A::off(other as *const T).unwrap(), + off: UnsafeCell::new(A::off(other as *const T).unwrap()), marker: PhantomData, } } @@ -306,7 +308,7 @@ impl Ptr { #[track_caller] pub(crate) fn from_non_null(other: NonNull) -> Self { Self { - off: A::off(other.as_ptr()).unwrap(), + off: UnsafeCell::new(A::off(other.as_ptr()).unwrap()), marker: PhantomData, } } @@ -329,10 +331,12 @@ impl Ptr { impl PartialEq for Ptr { #[inline] fn eq(&self, other: &Self) -> bool { - self.off == other.off + unsafe {*self.off.get() == *other.off.get()} } } +impl Eq for Ptr {} + // impl PartialOrd for Ptr { // #[inline] // fn partial_cmp(&self, other: &u64) -> Option { diff --git a/src/stat.rs b/src/stat.rs index 2337fc95..abbf3371 100644 --- a/src/stat.rs +++ b/src/stat.rs @@ -93,7 +93,7 @@ static mut STAT: LazyCell>> = #[inline] fn hist_enabled() -> bool { unsafe { - if let Some(hist) = &mut HIST { + if let Some(hist) = &mut *std::ptr::addr_of_mut!(HIST) { *hist } else { if let Some(val) = std::env::var_os("HIST") { @@ -110,7 +110,7 @@ fn hist_enabled() -> bool { #[inline] fn points_enabled() -> bool { unsafe { - if let Some(points) = &mut POINTS { + if let Some(points) = &mut *std::ptr::addr_of_mut!(POINTS) { *points } else { if let Some(val) = std::env::var_os("POINTS") { diff --git a/src/stm/journal.rs b/src/stm/journal.rs index b9e73d97..5e1aab94 100644 --- a/src/stm/journal.rs +++ b/src/stm/journal.rs @@ -6,6 +6,7 @@ use crate::stm::*; use crate::*; use std::collections::HashMap; use std::fmt::{self, Debug, Formatter}; +use std::array; #[cfg(feature = "check_double_free")] use std::collections::HashSet; @@ -82,7 +83,7 @@ impl !LooseTxInUnsafe for Journal {} impl !std::panic::RefUnwindSafe for Journal {} impl !std::panic::UnwindSafe for Journal {} -#[derive(Clone, Copy)] +#[derive(Clone)] struct Page { len: usize, head: usize, @@ -169,7 +170,8 @@ impl Page { unsafe fn ignore(&mut self) { self.len = 0; self.head = 0; - self.logs = [Default::default(); PAGE_LOG_SLOTS]; + self.logs = array::from_fn(|_| Default::default()); + } unsafe fn clear(&mut self, @@ -192,7 +194,7 @@ impl Page { } fn into_iter(&self) -> std::vec::IntoIter> { - Vec::from(self.logs).into_iter() + Vec::from(self.logs.clone()).into_iter() } } @@ -275,7 +277,7 @@ impl Journal { if page.is_dangling() { self.new_page() } else if page.is_full() { - self.next_page(page.next) + self.next_page(page.next.clone()) } else { page } @@ -284,7 +286,7 @@ impl Journal { /// Writes a new log to the journal #[cfg(feature = "pin_journals")] pub(crate) fn write(&self, log: LogEnum, notifier: Notifier) -> Ptr, A> { - let mut page = self.next_page(self.current); + let mut page = self.next_page(self.current.clone()); page.as_mut().write(log, notifier) } @@ -296,8 +298,8 @@ impl Journal { let page = Page:: { len: 0, head: 0, - next: self.pages, - logs: [Default::default(); PAGE_LOG_SLOTS] + next: self.pages.clone(), + logs: array::from_fn(|_| Default::default()) }; let (_, off, _, z) = A::atomic_new(page); A::log64(A::off_unchecked(self.pages.off_ref()), off, z); @@ -309,7 +311,7 @@ impl Journal { A::perform(z); - self.pages + self.pages.clone() } } @@ -321,7 +323,7 @@ impl Journal { } else if self.pages.is_full() { self.new_page() } else { - self.pages + self.pages.clone() }; page.as_mut().write(log, notifier) } @@ -330,7 +332,7 @@ impl Journal { #[cfg(feature = "pin_journals")] pub unsafe fn drop_pages(&mut self) { while let Some(page) = self.pages.clone().as_option() { - let nxt = page.next; + let nxt = page.next.clone(); let z = A::pre_dealloc(page.as_mut_ptr() as *mut u8, std::mem::size_of::>()); A::log64(A::off_unchecked(self.pages.off_ref()), nxt.off(), z); A::perform(z); @@ -357,7 +359,7 @@ impl Journal { let mut i = 1; let mut _cidx = 1; let mut log_cnt = HashMap::::new(); - let mut curr = self.pages; + let mut curr = self.pages.clone(); let mut pgs = vec![]; while let Some(page) = curr.as_option() { if info_level > 2 { @@ -379,7 +381,7 @@ impl Journal { } i += 1; - curr = page.next; + curr = page.next.clone(); } let mut total_logs = 0; @@ -428,23 +430,23 @@ impl Journal { #[cfg(any(feature = "use_pspd", feature = "use_vspd"))] { self.spd.commit(); } - let mut curr = self.pages; + let mut curr = self.pages.clone(); while let Some(page) = curr.as_option() { page.notify(); - curr = page.next; + curr = page.next.clone(); } - let mut curr = self.pages; + let mut curr = self.pages.clone(); while let Some(page) = curr.as_option() { page.commit_data(); - curr = page.next; + curr = page.next.clone(); } - let mut curr = self.pages; + let mut curr = self.pages.clone(); while let Some(page) = curr.as_option() { page.commit_dealloc( #[cfg(feature = "check_double_free")] check_double_free ); - curr = page.next; + curr = page.next.clone(); } sfence(); self.set(JOURNAL_COMMITTED); @@ -458,23 +460,23 @@ impl Journal { #[cfg(any(feature = "use_pspd", feature = "use_vspd"))] { self.spd.rollback(); } - let mut curr = self.pages; + let mut curr = self.pages.clone(); while let Some(page) = curr.as_option() { page.notify(); - curr = page.next; + curr = page.next.clone(); } - let mut curr = self.pages; + let mut curr = self.pages.clone(); while let Some(page) = curr.as_option() { page.rollback(); - curr = page.next; + curr = page.next.clone(); } - let mut curr = self.pages; + let mut curr = self.pages.clone(); while let Some(page) = curr.as_option() { page.rollback_dealloc( #[cfg(feature = "check_double_free")] check_double_free ); - curr = page.next; + curr = page.next.clone(); } sfence(); self.set(JOURNAL_COMMITTED); @@ -485,12 +487,12 @@ impl Journal { #[cfg(feature = "check_double_free")] check_double_free: &mut HashSet ) { - let mut curr = self.pages; + let mut curr = self.pages.clone(); while let Some(page) = curr.as_option() { page.notify(); - curr = page.next; + curr = page.next.clone(); } - let mut curr = self.pages; + let mut curr = self.pages.clone(); let resume = self.resume(); if !self.is_set(JOURNAL_COMMITTED) || resume { let rollback = !resume || !self.is_set(JOURNAL_COMMITTED); @@ -506,7 +508,7 @@ impl Journal { #[cfg(feature = "check_double_free")] check_double_free ); - curr = page.next; + curr = page.next.clone(); } self.set(JOURNAL_COMMITTED); } @@ -530,12 +532,12 @@ impl Journal { ); page = p.next.as_option(); } - self.current = self.pages; + self.current = self.pages.clone(); } #[cfg(not(feature = "pin_journals"))] { while let Some(page) = self.pages.as_option() { - let nxt = page.next; + let nxt = page.next.clone(); page.clear( #[cfg(feature = "check_double_free")] check_double_free @@ -741,7 +743,7 @@ impl Debug for Journal { let mut curr = self.pages.clone(); while let Some(page) = curr.as_option() { page.fmt(f)?; - curr = page.next; + curr = page.next.clone(); } Ok(()) } diff --git a/src/stm/log.rs b/src/stm/log.rs index 766ef053..c6b32a33 100644 --- a/src/stm/log.rs +++ b/src/stm/log.rs @@ -85,8 +85,6 @@ pub enum Notifier { None, } -impl Copy for Notifier {} - impl Clone for Notifier { fn clone(&self) -> Self { use Notifier::*; @@ -107,7 +105,7 @@ impl Notifier { match self { Atomic(n) => { if let Some(n) = n.as_option() { - unsafe { std::intrinsics::atomic_store_rel(n.as_mut_ptr(), v) } + unsafe { std::intrinsics::atomic_store_release(n.as_mut_ptr(), v) } } } NonAtomic(n) => { @@ -154,11 +152,9 @@ impl Notifier { /// pub struct Log(LogEnum, Notifier); -impl Copy for Log {} - impl Clone for Log { fn clone(&self) -> Self { - Self(self.0, self.1) + Self(self.0, self.1.clone()) } } diff --git a/src/stm/pspd.rs b/src/stm/pspd.rs index c6ca44d5..9846abf7 100644 --- a/src/stm/pspd.rs +++ b/src/stm/pspd.rs @@ -43,7 +43,7 @@ impl Page { let pg = utils::read::>(p); pg.cap = cap - mem::size_of::>(); pg.len = 0; - pg.next = self.next; + pg.next = self.next.clone(); A::log64(A::off_unchecked(self.next.off_mut()), off, z); A::perform(z); pg.write(val, org_off) diff --git a/src/sync/mutex.rs b/src/sync/mutex.rs index b683b8c8..bd123795 100644 --- a/src/sync/mutex.rs +++ b/src/sync/mutex.rs @@ -178,15 +178,6 @@ impl PMutex { &mut inner.1 } } - - #[inline] - #[allow(clippy::mut_from_ref)] - fn self_mut(&self) -> &mut Self { - unsafe { - let ptr: *const Self = self; - &mut *(ptr as *mut Self) - } - } } impl PMutex { @@ -200,7 +191,7 @@ impl PMutex { } #[cfg(any(feature = "no_pthread", windows))] { let tid = std::thread::current().id().as_u64().get(); - while intrinsics::atomic_cxchg_acqrel(lock, 0, tid).0 != tid {} + while intrinsics::atomic_cxchg_acqrel_acquire(lock, 0, tid).0 != tid {} } if self.inner.acquire() { Log::unlock_on_commit(&self.inner.lock as *const _ as u64, journal); @@ -209,7 +200,7 @@ impl PMutex { libc::pthread_mutex_unlock(lock); #[cfg(any(feature = "no_pthread", windows))] - intrinsics::atomic_store_rel(lock, 0); + intrinsics::atomic_store_release(lock, 0); panic!("Cannot have multiple instances of MutexGuard"); } @@ -271,7 +262,7 @@ impl PMutex { #[cfg(any(feature = "no_pthread", windows))] let result = { let tid = std::thread::current().id().as_u64().get(); - intrinsics::atomic_cxchg_acqrel(lock, 0, tid).0 == tid + intrinsics::atomic_cxchg_acqrel_acquire(lock, 0, tid).0 == tid }; if result { @@ -283,7 +274,7 @@ impl PMutex { libc::pthread_mutex_unlock(lock); #[cfg(any(feature = "no_pthread", windows))] - intrinsics::atomic_store_rel(lock, 0); + intrinsics::atomic_store_release(lock, 0); panic!("Cannot have multiple instances of MutexGuard"); } diff --git a/src/sync/parc.rs b/src/sync/parc.rs index 65a4face..a7db0d26 100644 --- a/src/sync/parc.rs +++ b/src/sync/parc.rs @@ -740,7 +740,7 @@ impl PClone for Parc { std::process::abort(); } - Self::from_inner(self.ptr) + Self::from_inner(self.ptr.clone()) } } @@ -964,7 +964,7 @@ impl Weak { } lock_free_fetch_inc(&mut inner.counter.strong, j); - Some(Parc::from_inner(self.ptr)) + Some(Parc::from_inner(self.ptr.clone())) } /// Gets the number of strong (`Parc`) pointers pointing to this allocation. @@ -1068,7 +1068,7 @@ impl PClone for Weak { let inner = if let Some(inner) = self.inner() { inner } else { - return Weak { ptr: self.ptr }; + return Weak { ptr: self.ptr.clone() }; }; // See comments in Arc::clone() for why this is relaxed. This can use a @@ -1083,7 +1083,7 @@ impl PClone for Weak { std::process::abort(); } - Weak { ptr: self.ptr } + Weak { ptr: self.ptr.clone() } } } diff --git a/src/tests.rs b/src/tests.rs index 8af4fdce..519c0e52 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1159,7 +1159,7 @@ pub(crate) mod test { if IDX == 16 { IDX = 0; let mut f = File::open("/dev/urandom").unwrap(); - f.read_exact(&mut BUF).unwrap(); + f.read_exact(&mut *std::ptr::addr_of_mut!(BUF)).unwrap(); } BUF[IDX] } @@ -1383,13 +1383,8 @@ pub(crate) mod test { impl<'a> std::ops::AddAssign<&'a str> for MyString<'a> { fn add_assign(&mut self, other: &'a str) { - unsafe { - let m: *const [u8] = self.value; - let m: *mut [u8] = m as *mut [u8]; - let m: &mut [u8] = &mut *m; - let mut v = m.to_vec(); - v.append(&mut other.as_bytes().to_vec()); - } + let mut v = self.value.to_vec(); + v.append(&mut other.as_bytes().to_vec()); } } impl<'a> From<&'a str> for MyString<'a> { diff --git a/src/utils.rs b/src/utils.rs index 18454023..d522302c 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -280,14 +280,14 @@ pub struct SpinLock { impl SpinLock { pub fn acquire(lock: *mut u8) -> Self { - unsafe { while std::intrinsics::atomic_cxchg_acqrel(lock, 0, 1).0 == 1 {} } + unsafe { while std::intrinsics::atomic_cxchg_acqrel_acquire(lock, 0, 1).0 == 1 {} } Self { lock } } } impl Drop for SpinLock { fn drop(&mut self) { - unsafe { std::intrinsics::atomic_store_rel(self.lock, 0); } + unsafe { std::intrinsics::atomic_store_release(self.lock, 0); } } }