//! println!("live threads: {}", old_thread_count + 1);
//! ```
-// ignore-tidy-undocumented-unsafe
-
#![stable(feature = "rust1", since = "1.0.0")]
#![cfg_attr(not(target_has_atomic_load_store = "8"), allow(dead_code))]
#![cfg_attr(not(target_has_atomic_load_store = "8"), allow(unused_imports))]
#[inline]
#[stable(feature = "atomic_access", since = "1.15.0")]
pub fn get_mut(&mut self) -> &mut bool {
+ // SAFETY: the mutable reference guarantees unique ownership.
unsafe { &mut *(self.v.get() as *mut bool) }
}
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn load(&self, order: Ordering) -> bool {
+ // SAFETY: any data races are prevented by atomic intrinsics and the raw
+ // pointer passed in is valid because we got it from a reference.
unsafe { atomic_load(self.v.get(), order) != 0 }
}
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn store(&self, val: bool, order: Ordering) {
+ // SAFETY: any data races are prevented by atomic intrinsics and the raw
+ // pointer passed in is valid because we got it from a reference.
unsafe {
atomic_store(self.v.get(), val as u8, order);
}
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg(target_has_atomic = "8")]
pub fn swap(&self, val: bool, order: Ordering) -> bool {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_swap(self.v.get(), val as u8, order) != 0 }
}
success: Ordering,
failure: Ordering,
) -> Result<bool, bool> {
+ // SAFETY: data races are prevented by atomic intrinsics.
match unsafe {
atomic_compare_exchange(self.v.get(), current as u8, new as u8, success, failure)
} {
success: Ordering,
failure: Ordering,
) -> Result<bool, bool> {
+ // SAFETY: data races are prevented by atomic intrinsics.
match unsafe {
atomic_compare_exchange_weak(self.v.get(), current as u8, new as u8, success, failure)
} {
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg(target_has_atomic = "8")]
pub fn fetch_and(&self, val: bool, order: Ordering) -> bool {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_and(self.v.get(), val as u8, order) != 0 }
}
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg(target_has_atomic = "8")]
pub fn fetch_or(&self, val: bool, order: Ordering) -> bool {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_or(self.v.get(), val as u8, order) != 0 }
}
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg(target_has_atomic = "8")]
pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 }
}
#[inline]
#[stable(feature = "atomic_access", since = "1.15.0")]
pub fn get_mut(&mut self) -> &mut *mut T {
+ // SAFETY: the mutable reference guarantees unique ownership.
unsafe { &mut *self.p.get() }
}
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn load(&self, order: Ordering) -> *mut T {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_load(self.p.get() as *mut usize, order) as *mut T }
}
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn store(&self, ptr: *mut T, order: Ordering) {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe {
atomic_store(self.p.get() as *mut usize, ptr as usize, order);
}
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg(target_has_atomic = "ptr")]
pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_swap(self.p.get() as *mut usize, ptr as usize, order) as *mut T }
}
success: Ordering,
failure: Ordering,
) -> Result<*mut T, *mut T> {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe {
let res = atomic_compare_exchange(
self.p.get() as *mut usize,
success: Ordering,
failure: Ordering,
) -> Result<*mut T, *mut T> {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe {
let res = atomic_compare_exchange_weak(
self.p.get() as *mut usize,
#[inline]
#[$stable_access]
pub fn get_mut(&mut self) -> &mut $int_type {
+ // SAFETY: the mutable reference guarantees unique ownership.
unsafe { &mut *self.v.get() }
}
}
#[inline]
#[$stable]
pub fn load(&self, order: Ordering) -> $int_type {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_load(self.v.get(), order) }
}
}
#[inline]
#[$stable]
pub fn store(&self, val: $int_type, order: Ordering) {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_store(self.v.get(), val, order); }
}
}
#[$stable]
#[$cfg_cas]
pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_swap(self.v.get(), val, order) }
}
}
new: $int_type,
success: Ordering,
failure: Ordering) -> Result<$int_type, $int_type> {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) }
}
}
new: $int_type,
success: Ordering,
failure: Ordering) -> Result<$int_type, $int_type> {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe {
atomic_compare_exchange_weak(self.v.get(), current, new, success, failure)
}
#[$stable]
#[$cfg_cas]
pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_add(self.v.get(), val, order) }
}
}
#[$stable]
#[$cfg_cas]
pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_sub(self.v.get(), val, order) }
}
}
#[$stable]
#[$cfg_cas]
pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_and(self.v.get(), val, order) }
}
}
#[$stable_nand]
#[$cfg_cas]
pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_nand(self.v.get(), val, order) }
}
}
#[$stable]
#[$cfg_cas]
pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_or(self.v.get(), val, order) }
}
}
#[$stable]
#[$cfg_cas]
pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_xor(self.v.get(), val, order) }
}
}
issue = "48655")]
#[$cfg_cas]
pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { $max_fn(self.v.get(), val, order) }
}
}
issue = "48655")]
#[$cfg_cas]
pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { $min_fn(self.v.get(), val, order) }
}
}
}
let mut atomic = ", stringify!($atomic_type), "::new(1);
-unsafe {
+",
+// SAFETY: Safe as long as `my_atomic_op` is atomic.
+"unsafe {
my_atomic_op(atomic.as_mut_ptr());
}
# }
// https://github.com/WebAssembly/tool-conventions/issues/59. We should
// follow that discussion and implement a solution when one comes about!
#[cfg(not(target_arch = "wasm32"))]
+ // SAFETY: using an atomic fence is safe.
unsafe {
match order {
Acquire => intrinsics::atomic_fence_acq(),
#[inline]
#[stable(feature = "compiler_fences", since = "1.21.0")]
pub fn compiler_fence(order: Ordering) {
+ // SAFETY: using an atomic fence is safe.
unsafe {
match order {
Acquire => intrinsics::atomic_singlethreadfence_acq(),