@@ -83,22 +83,22 @@ use default::Default;
83
83
use fmt;
84
84
85
85
/// 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 " ) ) ]
87
87
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
88
88
pub struct AtomicBool {
89
- v : UnsafeCell < usize > ,
89
+ v : UnsafeCell < u8 > ,
90
90
}
91
91
92
- #[ cfg( any( stage0, target_has_atomic = "ptr " ) ) ]
92
+ #[ cfg( any( stage0, target_has_atomic = "8 " ) ) ]
93
93
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
94
94
impl Default for AtomicBool {
95
95
fn default ( ) -> Self {
96
- Self :: new ( Default :: default ( ) )
96
+ Self :: new ( false )
97
97
}
98
98
}
99
99
100
100
// Send is implicitly implemented for AtomicBool.
101
- #[ cfg( any( stage0, target_has_atomic = "ptr " ) ) ]
101
+ #[ cfg( any( stage0, target_has_atomic = "8 " ) ) ]
102
102
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
103
103
unsafe impl Sync for AtomicBool { }
104
104
@@ -162,15 +162,11 @@ pub enum Ordering {
162
162
}
163
163
164
164
/// An `AtomicBool` initialized to `false`.
165
- #[ cfg( any( stage0, target_has_atomic = "ptr " ) ) ]
165
+ #[ cfg( any( stage0, target_has_atomic = "8 " ) ) ]
166
166
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
167
167
pub const ATOMIC_BOOL_INIT : AtomicBool = AtomicBool :: new ( false ) ;
168
168
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" ) ) ]
174
170
impl AtomicBool {
175
171
/// Creates a new `AtomicBool`.
176
172
///
@@ -185,7 +181,7 @@ impl AtomicBool {
185
181
#[ inline]
186
182
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
187
183
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 ) }
189
185
}
190
186
191
187
/// Loads a value from the bool.
@@ -208,7 +204,7 @@ impl AtomicBool {
208
204
#[ inline]
209
205
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
210
206
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 }
212
208
}
213
209
214
210
/// Stores a value into the bool.
@@ -232,9 +228,7 @@ impl AtomicBool {
232
228
#[ inline]
233
229
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
234
230
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) ; }
238
232
}
239
233
240
234
/// Stores a value into the bool, returning the old value.
@@ -254,9 +248,7 @@ impl AtomicBool {
254
248
#[ inline]
255
249
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
256
250
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 }
260
252
}
261
253
262
254
/// Stores a value into the `bool` if the current value is the same as the `current` value.
@@ -327,12 +319,10 @@ impl AtomicBool {
327
319
new : bool ,
328
320
success : Ordering ,
329
321
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 ) ,
336
326
}
337
327
}
338
328
@@ -373,13 +363,10 @@ impl AtomicBool {
373
363
new : bool ,
374
364
success : Ordering ,
375
365
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 ,
380
367
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 ) ,
383
370
}
384
371
}
385
372
@@ -410,9 +397,7 @@ impl AtomicBool {
410
397
#[ inline]
411
398
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
412
399
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 }
416
401
}
417
402
418
403
/// Logical "nand" with a boolean value.
@@ -443,9 +428,20 @@ impl AtomicBool {
443
428
#[ inline]
444
429
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
445
430
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
449
445
}
450
446
451
447
/// Logical "or" with a boolean value.
@@ -475,9 +471,7 @@ impl AtomicBool {
475
471
#[ inline]
476
472
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
477
473
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 }
481
475
}
482
476
483
477
/// Logical "xor" with a boolean value.
@@ -507,9 +501,7 @@ impl AtomicBool {
507
501
#[ inline]
508
502
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
509
503
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 }
513
505
}
514
506
}
515
507
@@ -1263,18 +1255,6 @@ unsafe fn atomic_and<T>(dst: *mut T, val: T, order: Ordering) -> T {
1263
1255
}
1264
1256
}
1265
1257
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
-
1278
1258
#[ inline]
1279
1259
unsafe fn atomic_or < T > ( dst : * mut T , val : T , order : Ordering ) -> T {
1280
1260
match order {
@@ -1286,7 +1266,6 @@ unsafe fn atomic_or<T>(dst: *mut T, val: T, order: Ordering) -> T {
1286
1266
}
1287
1267
}
1288
1268
1289
-
1290
1269
#[ inline]
1291
1270
unsafe fn atomic_xor < T > ( dst : * mut T , val : T , order : Ordering ) -> T {
1292
1271
match order {
@@ -1298,7 +1277,6 @@ unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
1298
1277
}
1299
1278
}
1300
1279
1301
-
1302
1280
/// An atomic fence.
1303
1281
///
1304
1282
/// A fence 'A' which has `Release` ordering semantics, synchronizes with a
@@ -1334,7 +1312,7 @@ pub fn fence(order: Ordering) {
1334
1312
}
1335
1313
1336
1314
1337
- #[ cfg( any( stage0, target_has_atomic = "ptr " ) ) ]
1315
+ #[ cfg( any( stage0, target_has_atomic = "8 " ) ) ]
1338
1316
#[ stable( feature = "atomic_debug" , since = "1.3.0" ) ]
1339
1317
impl fmt:: Debug for AtomicBool {
1340
1318
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
0 commit comments