@@ -83,22 +83,22 @@ use default::Default;
8383use fmt;
8484
8585/// A boolean type which can be safely shared between threads.
86- #[ cfg( any( stage0, target_has_atomic = "ptr " ) ) ]
86+ #[ cfg( any( stage0, target_has_atomic = "8 " ) ) ]
8787#[ stable( feature = "rust1" , since = "1.0.0" ) ]
8888pub struct AtomicBool {
89- v : UnsafeCell < usize > ,
89+ v : UnsafeCell < u8 > ,
9090}
9191
92- #[ cfg( any( stage0, target_has_atomic = "ptr " ) ) ]
92+ #[ cfg( any( stage0, target_has_atomic = "8 " ) ) ]
9393#[ stable( feature = "rust1" , since = "1.0.0" ) ]
9494impl Default for AtomicBool {
9595 fn default ( ) -> Self {
96- Self :: new ( Default :: default ( ) )
96+ Self :: new ( false )
9797 }
9898}
9999
100100// Send is implicitly implemented for AtomicBool.
101- #[ cfg( any( stage0, target_has_atomic = "ptr " ) ) ]
101+ #[ cfg( any( stage0, target_has_atomic = "8 " ) ) ]
102102#[ stable( feature = "rust1" , since = "1.0.0" ) ]
103103unsafe impl Sync for AtomicBool { }
104104
@@ -162,15 +162,11 @@ pub enum Ordering {
162162}
163163
164164/// An `AtomicBool` initialized to `false`.
165- #[ cfg( any( stage0, target_has_atomic = "ptr " ) ) ]
165+ #[ cfg( any( stage0, target_has_atomic = "8 " ) ) ]
166166#[ stable( feature = "rust1" , since = "1.0.0" ) ]
167167pub const ATOMIC_BOOL_INIT : AtomicBool = AtomicBool :: new ( false ) ;
168168
169- // NB: Needs to be -1 (0b11111111...) to make fetch_nand work correctly
170- #[ cfg( any( stage0, target_has_atomic = "ptr" ) ) ]
171- const UINT_TRUE : usize = !0 ;
172-
173- #[ cfg( any( stage0, target_has_atomic = "ptr" ) ) ]
169+ #[ cfg( any( stage0, target_has_atomic = "8" ) ) ]
174170impl AtomicBool {
175171 /// Creates a new `AtomicBool`.
176172 ///
@@ -185,7 +181,7 @@ impl AtomicBool {
185181 #[ inline]
186182 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
187183 pub const fn new ( v : bool ) -> AtomicBool {
188- AtomicBool { v : UnsafeCell :: new ( - ( v as isize ) as usize ) }
184+ AtomicBool { v : UnsafeCell :: new ( v as u8 ) }
189185 }
190186
191187 /// Loads a value from the bool.
@@ -208,7 +204,7 @@ impl AtomicBool {
208204 #[ inline]
209205 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
210206 pub fn load ( & self , order : Ordering ) -> bool {
211- unsafe { atomic_load ( self . v . get ( ) , order) > 0 }
207+ unsafe { atomic_load ( self . v . get ( ) , order) != 0 }
212208 }
213209
214210 /// Stores a value into the bool.
@@ -232,9 +228,7 @@ impl AtomicBool {
232228 #[ inline]
233229 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
234230 pub fn store ( & self , val : bool , order : Ordering ) {
235- let val = if val { UINT_TRUE } else { 0 } ;
236-
237- unsafe { atomic_store ( self . v . get ( ) , val, order) ; }
231+ unsafe { atomic_store ( self . v . get ( ) , val as u8 , order) ; }
238232 }
239233
240234 /// Stores a value into the bool, returning the old value.
@@ -254,9 +248,7 @@ impl AtomicBool {
254248 #[ inline]
255249 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
256250 pub fn swap ( & self , val : bool , order : Ordering ) -> bool {
257- let val = if val { UINT_TRUE } else { 0 } ;
258-
259- unsafe { atomic_swap ( self . v . get ( ) , val, order) > 0 }
251+ unsafe { atomic_swap ( self . v . get ( ) , val as u8 , order) != 0 }
260252 }
261253
262254 /// Stores a value into the `bool` if the current value is the same as the `current` value.
@@ -327,12 +319,10 @@ impl AtomicBool {
327319 new : bool ,
328320 success : Ordering ,
329321 failure : Ordering ) -> Result < bool , bool > {
330- let current = if current { UINT_TRUE } else { 0 } ;
331- let new = if new { UINT_TRUE } else { 0 } ;
332-
333- match unsafe { atomic_compare_exchange ( self . v . get ( ) , current, new, success, failure) } {
334- Ok ( x) => Ok ( x > 0 ) ,
335- Err ( x) => Err ( x > 0 ) ,
322+ match unsafe { atomic_compare_exchange ( self . v . get ( ) , current as u8 , new as u8 ,
323+ success, failure) } {
324+ Ok ( x) => Ok ( x != 0 ) ,
325+ Err ( x) => Err ( x != 0 ) ,
336326 }
337327 }
338328
@@ -373,13 +363,10 @@ impl AtomicBool {
373363 new : bool ,
374364 success : Ordering ,
375365 failure : Ordering ) -> Result < bool , bool > {
376- let current = if current { UINT_TRUE } else { 0 } ;
377- let new = if new { UINT_TRUE } else { 0 } ;
378-
379- match unsafe { atomic_compare_exchange_weak ( self . v . get ( ) , current, new,
366+ match unsafe { atomic_compare_exchange_weak ( self . v . get ( ) , current as u8 , new as u8 ,
380367 success, failure) } {
381- Ok ( x) => Ok ( x > 0 ) ,
382- Err ( x) => Err ( x > 0 ) ,
368+ Ok ( x) => Ok ( x != 0 ) ,
369+ Err ( x) => Err ( x != 0 ) ,
383370 }
384371 }
385372
@@ -410,9 +397,7 @@ impl AtomicBool {
410397 #[ inline]
411398 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
412399 pub fn fetch_and ( & self , val : bool , order : Ordering ) -> bool {
413- let val = if val { UINT_TRUE } else { 0 } ;
414-
415- unsafe { atomic_and ( self . v . get ( ) , val, order) > 0 }
400+ unsafe { atomic_and ( self . v . get ( ) , val as u8 , order) != 0 }
416401 }
417402
418403 /// Logical "nand" with a boolean value.
@@ -443,9 +428,20 @@ impl AtomicBool {
443428 #[ inline]
444429 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
445430 pub fn fetch_nand ( & self , val : bool , order : Ordering ) -> bool {
446- let val = if val { UINT_TRUE } else { 0 } ;
447-
448- unsafe { atomic_nand ( self . v . get ( ) , val, order) > 0 }
431+ // We can't use atomic_nand here because it can result in a bool with
432+ // an invalid value. This happens because the atomic operation is done
433+ // with an 8-bit integer internally, which would set the upper 7 bits.
434+ // So we just use a compare-exchange loop instead, which is what the
435+ // intrinsic actually expands to anyways on many platforms.
436+ let mut old = self . load ( Relaxed ) ;
437+ loop {
438+ let new = !( old && val) ;
439+ match self . compare_exchange_weak ( old, new, order, Relaxed ) {
440+ Ok ( _) => break ,
441+ Err ( x) => old = x,
442+ }
443+ }
444+ old
449445 }
450446
451447 /// Logical "or" with a boolean value.
@@ -475,9 +471,7 @@ impl AtomicBool {
475471 #[ inline]
476472 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
477473 pub fn fetch_or ( & self , val : bool , order : Ordering ) -> bool {
478- let val = if val { UINT_TRUE } else { 0 } ;
479-
480- unsafe { atomic_or ( self . v . get ( ) , val, order) > 0 }
474+ unsafe { atomic_or ( self . v . get ( ) , val as u8 , order) != 0 }
481475 }
482476
483477 /// Logical "xor" with a boolean value.
@@ -507,9 +501,7 @@ impl AtomicBool {
507501 #[ inline]
508502 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
509503 pub fn fetch_xor ( & self , val : bool , order : Ordering ) -> bool {
510- let val = if val { UINT_TRUE } else { 0 } ;
511-
512- unsafe { atomic_xor ( self . v . get ( ) , val, order) > 0 }
504+ unsafe { atomic_xor ( self . v . get ( ) , val as u8 , order) != 0 }
513505 }
514506}
515507
@@ -1263,18 +1255,6 @@ unsafe fn atomic_and<T>(dst: *mut T, val: T, order: Ordering) -> T {
12631255 }
12641256}
12651257
1266- #[ inline]
1267- unsafe fn atomic_nand < T > ( dst : * mut T , val : T , order : Ordering ) -> T {
1268- match order {
1269- Acquire => intrinsics:: atomic_nand_acq ( dst, val) ,
1270- Release => intrinsics:: atomic_nand_rel ( dst, val) ,
1271- AcqRel => intrinsics:: atomic_nand_acqrel ( dst, val) ,
1272- Relaxed => intrinsics:: atomic_nand_relaxed ( dst, val) ,
1273- SeqCst => intrinsics:: atomic_nand ( dst, val)
1274- }
1275- }
1276-
1277-
12781258#[ inline]
12791259unsafe fn atomic_or < T > ( dst : * mut T , val : T , order : Ordering ) -> T {
12801260 match order {
@@ -1286,7 +1266,6 @@ unsafe fn atomic_or<T>(dst: *mut T, val: T, order: Ordering) -> T {
12861266 }
12871267}
12881268
1289-
12901269#[ inline]
12911270unsafe fn atomic_xor < T > ( dst : * mut T , val : T , order : Ordering ) -> T {
12921271 match order {
@@ -1298,7 +1277,6 @@ unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
12981277 }
12991278}
13001279
1301-
13021280/// An atomic fence.
13031281///
13041282/// A fence 'A' which has `Release` ordering semantics, synchronizes with a
@@ -1334,7 +1312,7 @@ pub fn fence(order: Ordering) {
13341312}
13351313
13361314
1337- #[ cfg( any( stage0, target_has_atomic = "ptr " ) ) ]
1315+ #[ cfg( any( stage0, target_has_atomic = "8 " ) ) ]
13381316#[ stable( feature = "atomic_debug" , since = "1.3.0" ) ]
13391317impl fmt:: Debug for AtomicBool {
13401318 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
0 commit comments