Make AtomicBool the same size as bool
This commit is contained in:
parent
e37f8593e4
commit
915fa57a93
@ -83,22 +83,22 @@
|
||||
use fmt;
|
||||
|
||||
/// A boolean type which can be safely shared between threads.
|
||||
#[cfg(any(stage0, target_has_atomic = "ptr"))]
|
||||
#[cfg(any(stage0, target_has_atomic = "8"))]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct AtomicBool {
|
||||
v: UnsafeCell<usize>,
|
||||
v: UnsafeCell<u8>,
|
||||
}
|
||||
|
||||
#[cfg(any(stage0, target_has_atomic = "ptr"))]
|
||||
#[cfg(any(stage0, target_has_atomic = "8"))]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Default for AtomicBool {
|
||||
fn default() -> Self {
|
||||
Self::new(Default::default())
|
||||
Self::new(false)
|
||||
}
|
||||
}
|
||||
|
||||
// Send is implicitly implemented for AtomicBool.
|
||||
#[cfg(any(stage0, target_has_atomic = "ptr"))]
|
||||
#[cfg(any(stage0, target_has_atomic = "8"))]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
unsafe impl Sync for AtomicBool {}
|
||||
|
||||
@ -162,15 +162,11 @@ pub enum Ordering {
|
||||
}
|
||||
|
||||
/// An `AtomicBool` initialized to `false`.
|
||||
#[cfg(any(stage0, target_has_atomic = "ptr"))]
|
||||
#[cfg(any(stage0, target_has_atomic = "8"))]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
// NB: Needs to be -1 (0b11111111...) to make fetch_nand work correctly
|
||||
#[cfg(any(stage0, target_has_atomic = "ptr"))]
|
||||
const UINT_TRUE: usize = !0;
|
||||
|
||||
#[cfg(any(stage0, target_has_atomic = "ptr"))]
|
||||
#[cfg(any(stage0, target_has_atomic = "8"))]
|
||||
impl AtomicBool {
|
||||
/// Creates a new `AtomicBool`.
|
||||
///
|
||||
@ -185,7 +181,7 @@ impl AtomicBool {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub const fn new(v: bool) -> AtomicBool {
|
||||
AtomicBool { v: UnsafeCell::new(-(v as isize) as usize) }
|
||||
AtomicBool { v: UnsafeCell::new(v as u8) }
|
||||
}
|
||||
|
||||
/// Loads a value from the bool.
|
||||
@ -208,7 +204,7 @@ pub const fn new(v: bool) -> AtomicBool {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn load(&self, order: Ordering) -> bool {
|
||||
unsafe { atomic_load(self.v.get(), order) > 0 }
|
||||
unsafe { atomic_load(self.v.get(), order) != 0 }
|
||||
}
|
||||
|
||||
/// Stores a value into the bool.
|
||||
@ -232,9 +228,7 @@ pub fn load(&self, order: Ordering) -> bool {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn store(&self, val: bool, order: Ordering) {
|
||||
let val = if val { UINT_TRUE } else { 0 };
|
||||
|
||||
unsafe { atomic_store(self.v.get(), val, order); }
|
||||
unsafe { atomic_store(self.v.get(), val as u8, order); }
|
||||
}
|
||||
|
||||
/// Stores a value into the bool, returning the old value.
|
||||
@ -254,9 +248,7 @@ pub fn store(&self, val: bool, order: Ordering) {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn swap(&self, val: bool, order: Ordering) -> bool {
|
||||
let val = if val { UINT_TRUE } else { 0 };
|
||||
|
||||
unsafe { atomic_swap(self.v.get(), val, order) > 0 }
|
||||
unsafe { atomic_swap(self.v.get(), val as u8, order) != 0 }
|
||||
}
|
||||
|
||||
/// Stores a value into the `bool` if the current value is the same as the `current` value.
|
||||
@ -327,12 +319,10 @@ pub fn compare_exchange(&self,
|
||||
new: bool,
|
||||
success: Ordering,
|
||||
failure: Ordering) -> Result<bool, bool> {
|
||||
let current = if current { UINT_TRUE } else { 0 };
|
||||
let new = if new { UINT_TRUE } else { 0 };
|
||||
|
||||
match unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) } {
|
||||
Ok(x) => Ok(x > 0),
|
||||
Err(x) => Err(x > 0),
|
||||
match unsafe { atomic_compare_exchange(self.v.get(), current as u8, new as u8,
|
||||
success, failure) } {
|
||||
Ok(x) => Ok(x != 0),
|
||||
Err(x) => Err(x != 0),
|
||||
}
|
||||
}
|
||||
|
||||
@ -373,13 +363,10 @@ pub fn compare_exchange_weak(&self,
|
||||
new: bool,
|
||||
success: Ordering,
|
||||
failure: Ordering) -> Result<bool, bool> {
|
||||
let current = if current { UINT_TRUE } else { 0 };
|
||||
let new = if new { UINT_TRUE } else { 0 };
|
||||
|
||||
match unsafe { atomic_compare_exchange_weak(self.v.get(), current, new,
|
||||
match unsafe { atomic_compare_exchange_weak(self.v.get(), current as u8, new as u8,
|
||||
success, failure) } {
|
||||
Ok(x) => Ok(x > 0),
|
||||
Err(x) => Err(x > 0),
|
||||
Ok(x) => Ok(x != 0),
|
||||
Err(x) => Err(x != 0),
|
||||
}
|
||||
}
|
||||
|
||||
@ -410,9 +397,7 @@ pub fn compare_exchange_weak(&self,
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn fetch_and(&self, val: bool, order: Ordering) -> bool {
|
||||
let val = if val { UINT_TRUE } else { 0 };
|
||||
|
||||
unsafe { atomic_and(self.v.get(), val, order) > 0 }
|
||||
unsafe { atomic_and(self.v.get(), val as u8, order) != 0 }
|
||||
}
|
||||
|
||||
/// Logical "nand" with a boolean value.
|
||||
@ -443,9 +428,20 @@ pub fn fetch_and(&self, val: bool, order: Ordering) -> bool {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool {
|
||||
let val = if val { UINT_TRUE } else { 0 };
|
||||
|
||||
unsafe { atomic_nand(self.v.get(), val, order) > 0 }
|
||||
// We can't use atomic_nand here because it can result in a bool with
|
||||
// an invalid value. This happens because the atomic operation is done
|
||||
// with an 8-bit integer internally, which would set the upper 7 bits.
|
||||
// So we just use a compare-exchange loop instead, which is what the
|
||||
// intrinsic actually expands to anyways on many platforms.
|
||||
let mut old = self.load(Relaxed);
|
||||
loop {
|
||||
let new = !(old && val);
|
||||
match self.compare_exchange_weak(old, new, order, Relaxed) {
|
||||
Ok(_) => break,
|
||||
Err(x) => old = x,
|
||||
}
|
||||
}
|
||||
old
|
||||
}
|
||||
|
||||
/// Logical "or" with a boolean value.
|
||||
@ -475,9 +471,7 @@ pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn fetch_or(&self, val: bool, order: Ordering) -> bool {
|
||||
let val = if val { UINT_TRUE } else { 0 };
|
||||
|
||||
unsafe { atomic_or(self.v.get(), val, order) > 0 }
|
||||
unsafe { atomic_or(self.v.get(), val as u8, order) != 0 }
|
||||
}
|
||||
|
||||
/// Logical "xor" with a boolean value.
|
||||
@ -507,9 +501,7 @@ pub fn fetch_or(&self, val: bool, order: Ordering) -> bool {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
|
||||
let val = if val { UINT_TRUE } else { 0 };
|
||||
|
||||
unsafe { atomic_xor(self.v.get(), val, order) > 0 }
|
||||
unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 }
|
||||
}
|
||||
}
|
||||
|
||||
@ -1263,18 +1255,6 @@ unsafe fn atomic_and<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn atomic_nand<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
match order {
|
||||
Acquire => intrinsics::atomic_nand_acq(dst, val),
|
||||
Release => intrinsics::atomic_nand_rel(dst, val),
|
||||
AcqRel => intrinsics::atomic_nand_acqrel(dst, val),
|
||||
Relaxed => intrinsics::atomic_nand_relaxed(dst, val),
|
||||
SeqCst => intrinsics::atomic_nand(dst, val)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[inline]
|
||||
unsafe fn atomic_or<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
match order {
|
||||
@ -1286,7 +1266,6 @@ unsafe fn atomic_or<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[inline]
|
||||
unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
match order {
|
||||
@ -1298,7 +1277,6 @@ unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// An atomic fence.
|
||||
///
|
||||
/// A fence 'A' which has `Release` ordering semantics, synchronizes with a
|
||||
@ -1334,7 +1312,7 @@ pub fn fence(order: Ordering) {
|
||||
}
|
||||
|
||||
|
||||
#[cfg(any(stage0, target_has_atomic = "ptr"))]
|
||||
#[cfg(any(stage0, target_has_atomic = "8"))]
|
||||
#[stable(feature = "atomic_debug", since = "1.3.0")]
|
||||
impl fmt::Debug for AtomicBool {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
|
Loading…
Reference in New Issue
Block a user