@@ -114,35 +114,36 @@ use cast;
114
114
use std:: kinds:: marker;
115
115
use option:: { Option , Some , None } ;
116
116
use ops:: Drop ;
117
+ use ty:: Unsafe ;
117
118
118
119
/// An atomic boolean type.
119
120
pub struct AtomicBool {
120
- priv v: uint ,
121
+ priv v: Unsafe < uint > ,
121
122
priv nopod : marker:: NoPod
122
123
}
123
124
124
125
/// A signed atomic integer type, supporting basic atomic arithmetic operations
125
126
pub struct AtomicInt {
126
- priv v: int ,
127
+ priv v: Unsafe < int > ,
127
128
priv nopod : marker:: NoPod
128
129
}
129
130
130
131
/// An unsigned atomic integer type, supporting basic atomic arithmetic operations
131
132
pub struct AtomicUint {
132
- priv v: uint ,
133
+ priv v: Unsafe < uint > ,
133
134
priv nopod : marker:: NoPod
134
135
}
135
136
136
137
/// An unsigned atomic integer type that is forced to be 64-bits. This does not
137
138
/// support all operations.
138
139
pub struct AtomicU64 {
139
- priv v: u64 ,
140
+ priv v: Unsafe < u64 > ,
140
141
priv nopod : marker:: NoPod
141
142
}
142
143
143
144
/// An unsafe atomic pointer. Only supports basic atomic operations
144
145
pub struct AtomicPtr < T > {
145
- priv p: uint ,
146
+ priv p: Unsafe < uint > ,
146
147
priv nopod : marker:: NoPod
147
148
}
148
149
@@ -152,7 +153,7 @@ pub struct AtomicPtr<T> {
152
153
/// owned heap objects across tasks.
153
154
#[ unsafe_no_drop_flag]
154
155
pub struct AtomicOption < T > {
155
- priv p: uint ,
156
+ priv p: Unsafe < uint > ,
156
157
}
157
158
158
159
/// Atomic memory orderings
@@ -186,13 +187,21 @@ pub enum Ordering {
186
187
}
187
188
188
189
/// An `AtomicBool` initialized to `false`
189
- pub static INIT_ATOMIC_BOOL : AtomicBool = AtomicBool { v : 0 , nopod : marker:: NoPod } ;
190
+ pub static INIT_ATOMIC_BOOL : AtomicBool = AtomicBool { v : Unsafe { value : 0 ,
191
+ marker1 : marker:: InvariantType } ,
192
+ nopod : marker:: NoPod } ;
190
193
/// An `AtomicInt` initialized to `0`
191
- pub static INIT_ATOMIC_INT : AtomicInt = AtomicInt { v : 0 , nopod : marker:: NoPod } ;
194
+ pub static INIT_ATOMIC_INT : AtomicInt = AtomicInt { v : Unsafe { value : 0 ,
195
+ marker1 : marker:: InvariantType } ,
196
+ nopod : marker:: NoPod } ;
192
197
/// An `AtomicUint` initialized to `0`
193
- pub static INIT_ATOMIC_UINT : AtomicUint = AtomicUint { v : 0 , nopod : marker:: NoPod } ;
198
+ pub static INIT_ATOMIC_UINT : AtomicUint = AtomicUint { v : Unsafe { value : 0 ,
199
+ marker1 : marker:: InvariantType } ,
200
+ nopod : marker:: NoPod } ;
194
201
/// An `AtomicU64` initialized to `0`
195
- pub static INIT_ATOMIC_U64 : AtomicU64 = AtomicU64 { v : 0 , nopod : marker:: NoPod } ;
202
+ pub static INIT_ATOMIC_U64 : AtomicU64 = AtomicU64 { v : Unsafe { value : 0 ,
203
+ marker1 : marker:: InvariantType } ,
204
+ nopod : marker:: NoPod } ;
196
205
197
206
198
207
// NB: Needs to be -1 (0b11111111...) to make fetch_nand work correctly
@@ -201,29 +210,30 @@ static UINT_TRUE: uint = -1;
201
210
impl AtomicBool {
202
211
/// Create a new `AtomicBool`
203
212
pub fn new ( v : bool ) -> AtomicBool {
204
- AtomicBool { v : if v { UINT_TRUE } else { 0 } , nopod : marker:: NoPod }
213
+ let val = if v { UINT_TRUE } else { 0 } ;
214
+ AtomicBool { v : Unsafe :: new ( val) , nopod : marker:: NoPod }
205
215
}
206
216
207
217
/// Load the value
208
218
#[ inline]
209
219
pub fn load ( & self , order : Ordering ) -> bool {
210
- unsafe { atomic_load ( & self . v , order) > 0 }
220
+ unsafe { atomic_load ( & * self . v . get ( ) , order) > 0 }
211
221
}
212
222
213
223
/// Store the value
214
224
#[ inline]
215
225
pub fn store ( & mut self , val : bool , order : Ordering ) {
216
226
let val = if val { UINT_TRUE } else { 0 } ;
217
227
218
- unsafe { atomic_store ( & mut self . v , val, order) ; }
228
+ unsafe { atomic_store ( & mut * self . v . get ( ) , val, order) ; }
219
229
}
220
230
221
231
/// Store a value, returning the old value
222
232
#[ inline]
223
233
pub fn swap ( & mut self , val : bool , order : Ordering ) -> bool {
224
234
let val = if val { UINT_TRUE } else { 0 } ;
225
235
226
- unsafe { atomic_swap ( & mut self . v , val, order) > 0 }
236
+ unsafe { atomic_swap ( & mut * self . v . get ( ) , val, order) > 0 }
227
237
}
228
238
229
239
/// If the current value is the same as expected, store a new value
@@ -276,7 +286,7 @@ impl AtomicBool {
276
286
let old = if old { UINT_TRUE } else { 0 } ;
277
287
let new = if new { UINT_TRUE } else { 0 } ;
278
288
279
- unsafe { atomic_compare_and_swap ( & mut self . v , old, new, order) > 0 }
289
+ unsafe { atomic_compare_and_swap ( & mut * self . v . get ( ) , old, new, order) > 0 }
280
290
}
281
291
282
292
/// A logical "and" operation
@@ -306,7 +316,7 @@ impl AtomicBool {
306
316
pub fn fetch_and ( & mut self , val : bool , order : Ordering ) -> bool {
307
317
let val = if val { UINT_TRUE } else { 0 } ;
308
318
309
- unsafe { atomic_and ( & mut self . v , val, order) > 0 }
319
+ unsafe { atomic_and ( & mut * self . v . get ( ) , val, order) > 0 }
310
320
}
311
321
312
322
/// A logical "nand" operation
@@ -337,7 +347,7 @@ impl AtomicBool {
337
347
pub fn fetch_nand ( & mut self , val : bool , order : Ordering ) -> bool {
338
348
let val = if val { UINT_TRUE } else { 0 } ;
339
349
340
- unsafe { atomic_nand ( & mut self . v , val, order) > 0 }
350
+ unsafe { atomic_nand ( & mut * self . v . get ( ) , val, order) > 0 }
341
351
}
342
352
343
353
/// A logical "or" operation
@@ -367,7 +377,7 @@ impl AtomicBool {
367
377
pub fn fetch_or ( & mut self , val : bool , order : Ordering ) -> bool {
368
378
let val = if val { UINT_TRUE } else { 0 } ;
369
379
370
- unsafe { atomic_or ( & mut self . v , val, order) > 0 }
380
+ unsafe { atomic_or ( & mut * self . v . get ( ) , val, order) > 0 }
371
381
}
372
382
373
383
/// A logical "xor" operation
@@ -397,32 +407,32 @@ impl AtomicBool {
397
407
pub fn fetch_xor ( & mut self , val : bool , order : Ordering ) -> bool {
398
408
let val = if val { UINT_TRUE } else { 0 } ;
399
409
400
- unsafe { atomic_xor ( & mut self . v , val, order) > 0 }
410
+ unsafe { atomic_xor ( & mut * self . v . get ( ) , val, order) > 0 }
401
411
}
402
412
}
403
413
404
414
impl AtomicInt {
405
415
/// Create a new `AtomicInt`
406
416
pub fn new ( v : int ) -> AtomicInt {
407
- AtomicInt { v : v , nopod : marker:: NoPod }
417
+ AtomicInt { v : Unsafe :: new ( v ) , nopod : marker:: NoPod }
408
418
}
409
419
410
420
/// Load the value
411
421
#[ inline]
412
422
pub fn load ( & self , order : Ordering ) -> int {
413
- unsafe { atomic_load ( & self . v , order) }
423
+ unsafe { atomic_load ( & * self . v . get ( ) , order) }
414
424
}
415
425
416
426
/// Store the value
417
427
#[ inline]
418
428
pub fn store ( & mut self , val : int , order : Ordering ) {
419
- unsafe { atomic_store ( & mut self . v , val, order) ; }
429
+ unsafe { atomic_store ( & mut * self . v . get ( ) , val, order) ; }
420
430
}
421
431
422
432
/// Store a value, returning the old value
423
433
#[ inline]
424
434
pub fn swap ( & mut self , val : int , order : Ordering ) -> int {
425
- unsafe { atomic_swap ( & mut self . v , val, order) }
435
+ unsafe { atomic_swap ( & mut * self . v . get ( ) , val, order) }
426
436
}
427
437
428
438
/// If the current value is the same as expected, store a new value
@@ -432,7 +442,7 @@ impl AtomicInt {
432
442
/// If the return value is equal to `old` then the value was updated.
433
443
#[ inline]
434
444
pub fn compare_and_swap ( & mut self , old : int , new : int , order : Ordering ) -> int {
435
- unsafe { atomic_compare_and_swap ( & mut self . v , old, new, order) }
445
+ unsafe { atomic_compare_and_swap ( & mut * self . v . get ( ) , old, new, order) }
436
446
}
437
447
438
448
/// Add to the current value, returning the previous
@@ -448,7 +458,7 @@ impl AtomicInt {
448
458
/// ```
449
459
#[ inline]
450
460
pub fn fetch_add ( & mut self , val : int , order : Ordering ) -> int {
451
- unsafe { atomic_add ( & mut self . v , val, order) }
461
+ unsafe { atomic_add ( & mut * self . v . get ( ) , val, order) }
452
462
}
453
463
454
464
/// Subtract from the current value, returning the previous
@@ -464,7 +474,7 @@ impl AtomicInt {
464
474
/// ```
465
475
#[ inline]
466
476
pub fn fetch_sub ( & mut self , val : int , order : Ordering ) -> int {
467
- unsafe { atomic_sub ( & mut self . v , val, order) }
477
+ unsafe { atomic_sub ( & mut * self . v . get ( ) , val, order) }
468
478
}
469
479
}
470
480
@@ -474,62 +484,62 @@ impl AtomicInt {
474
484
#[ cfg( not( target_arch = "mips" ) ) ]
475
485
impl AtomicU64 {
476
486
pub fn new ( v : u64 ) -> AtomicU64 {
477
- AtomicU64 { v : v , nopod : marker:: NoPod }
487
+ AtomicU64 { v : Unsafe :: new ( v ) , nopod : marker:: NoPod }
478
488
}
479
489
480
490
#[ inline]
481
491
pub fn load ( & self , order : Ordering ) -> u64 {
482
- unsafe { atomic_load ( & self . v , order) }
492
+ unsafe { atomic_load ( & * self . v . get ( ) , order) }
483
493
}
484
494
485
495
#[ inline]
486
496
pub fn store ( & mut self , val : u64 , order : Ordering ) {
487
- unsafe { atomic_store ( & mut self . v , val, order) ; }
497
+ unsafe { atomic_store ( & mut * self . v . get ( ) , val, order) ; }
488
498
}
489
499
490
500
#[ inline]
491
501
pub fn swap ( & mut self , val : u64 , order : Ordering ) -> u64 {
492
- unsafe { atomic_swap ( & mut self . v , val, order) }
502
+ unsafe { atomic_swap ( & mut * self . v . get ( ) , val, order) }
493
503
}
494
504
495
505
#[ inline]
496
506
pub fn compare_and_swap ( & mut self , old : u64 , new : u64 , order : Ordering ) -> u64 {
497
- unsafe { atomic_compare_and_swap ( & mut self . v , old, new, order) }
507
+ unsafe { atomic_compare_and_swap ( & mut * self . v . get ( ) , old, new, order) }
498
508
}
499
509
500
510
#[ inline]
501
511
pub fn fetch_add ( & mut self , val : u64 , order : Ordering ) -> u64 {
502
- unsafe { atomic_add ( & mut self . v , val, order) }
512
+ unsafe { atomic_add ( & mut * self . v . get ( ) , val, order) }
503
513
}
504
514
505
515
#[ inline]
506
516
pub fn fetch_sub ( & mut self , val : u64 , order : Ordering ) -> u64 {
507
- unsafe { atomic_sub ( & mut self . v , val, order) }
517
+ unsafe { atomic_sub ( & mut * self . v . get ( ) , val, order) }
508
518
}
509
519
}
510
520
511
521
impl AtomicUint {
512
522
/// Create a new `AtomicUint`
513
523
pub fn new ( v : uint ) -> AtomicUint {
514
- AtomicUint { v : v , nopod : marker:: NoPod }
524
+ AtomicUint { v : Unsafe :: new ( v ) , nopod : marker:: NoPod }
515
525
}
516
526
517
527
/// Load the value
518
528
#[ inline]
519
529
pub fn load ( & self , order : Ordering ) -> uint {
520
- unsafe { atomic_load ( & self . v , order) }
530
+ unsafe { atomic_load ( & * self . v . get ( ) , order) }
521
531
}
522
532
523
533
/// Store the value
524
534
#[ inline]
525
535
pub fn store ( & mut self , val : uint , order : Ordering ) {
526
- unsafe { atomic_store ( & mut self . v , val, order) ; }
536
+ unsafe { atomic_store ( & mut * self . v . get ( ) , val, order) ; }
527
537
}
528
538
529
539
/// Store a value, returning the old value
530
540
#[ inline]
531
541
pub fn swap ( & mut self , val : uint , order : Ordering ) -> uint {
532
- unsafe { atomic_swap ( & mut self . v , val, order) }
542
+ unsafe { atomic_swap ( & mut * self . v . get ( ) , val, order) }
533
543
}
534
544
535
545
/// If the current value is the same as expected, store a new value
@@ -539,7 +549,7 @@ impl AtomicUint {
539
549
/// If the return value is equal to `old` then the value was updated.
540
550
#[ inline]
541
551
pub fn compare_and_swap ( & mut self , old : uint , new : uint , order : Ordering ) -> uint {
542
- unsafe { atomic_compare_and_swap ( & mut self . v , old, new, order) }
552
+ unsafe { atomic_compare_and_swap ( & mut * self . v . get ( ) , old, new, order) }
543
553
}
544
554
545
555
/// Add to the current value, returning the previous
@@ -555,7 +565,7 @@ impl AtomicUint {
555
565
/// ```
556
566
#[ inline]
557
567
pub fn fetch_add ( & mut self , val : uint , order : Ordering ) -> uint {
558
- unsafe { atomic_add ( & mut self . v , val, order) }
568
+ unsafe { atomic_add ( & mut * self . v . get ( ) , val, order) }
559
569
}
560
570
561
571
/// Subtract from the current value, returning the previous
@@ -571,34 +581,34 @@ impl AtomicUint {
571
581
/// ```
572
582
#[ inline]
573
583
pub fn fetch_sub ( & mut self , val : uint , order : Ordering ) -> uint {
574
- unsafe { atomic_sub ( & mut self . v , val, order) }
584
+ unsafe { atomic_sub ( & mut * self . v . get ( ) , val, order) }
575
585
}
576
586
}
577
587
578
588
impl < T > AtomicPtr < T > {
579
589
/// Create a new `AtomicPtr`
580
590
pub fn new ( p : * mut T ) -> AtomicPtr < T > {
581
- AtomicPtr { p : p as uint , nopod : marker:: NoPod }
591
+ AtomicPtr { p : Unsafe :: new ( p as uint ) , nopod : marker:: NoPod }
582
592
}
583
593
584
594
/// Load the value
585
595
#[ inline]
586
596
pub fn load ( & self , order : Ordering ) -> * mut T {
587
597
unsafe {
588
- atomic_load ( & self . p , order) as * mut T
598
+ atomic_load ( & * self . p . get ( ) , order) as * mut T
589
599
}
590
600
}
591
601
592
602
/// Store the value
593
603
#[ inline]
594
604
pub fn store ( & mut self , ptr : * mut T , order : Ordering ) {
595
- unsafe { atomic_store ( & mut self . p , ptr as uint , order) ; }
605
+ unsafe { atomic_store ( & mut * self . p . get ( ) , ptr as uint , order) ; }
596
606
}
597
607
598
608
/// Store a value, returning the old value
599
609
#[ inline]
600
610
pub fn swap ( & mut self , ptr : * mut T , order : Ordering ) -> * mut T {
601
- unsafe { atomic_swap ( & mut self . p , ptr as uint , order) as * mut T }
611
+ unsafe { atomic_swap ( & mut * self . p . get ( ) , ptr as uint , order) as * mut T }
602
612
}
603
613
604
614
/// If the current value is the same as expected, store a new value
@@ -609,7 +619,7 @@ impl<T> AtomicPtr<T> {
609
619
#[ inline]
610
620
pub fn compare_and_swap ( & mut self , old : * mut T , new : * mut T , order : Ordering ) -> * mut T {
611
621
unsafe {
612
- atomic_compare_and_swap ( & mut self . p , old as uint ,
622
+ atomic_compare_and_swap ( & mut * self . p . get ( ) , old as uint ,
613
623
new as uint , order) as * mut T
614
624
}
615
625
}
@@ -618,19 +628,19 @@ impl<T> AtomicPtr<T> {
618
628
impl < T > AtomicOption < T > {
619
629
/// Create a new `AtomicOption`
620
630
pub fn new ( p : ~T ) -> AtomicOption < T > {
621
- unsafe { AtomicOption { p : cast:: transmute ( p) } }
631
+ unsafe { AtomicOption { p : Unsafe :: new ( cast:: transmute ( p) ) } }
622
632
}
623
633
624
634
/// Create a new `AtomicOption` that doesn't contain a value
625
- pub fn empty ( ) -> AtomicOption < T > { AtomicOption { p : 0 } }
635
+ pub fn empty ( ) -> AtomicOption < T > { AtomicOption { p : Unsafe :: new ( 0 ) } }
626
636
627
637
/// Store a value, returning the old value
628
638
#[ inline]
629
639
pub fn swap ( & mut self , val : ~T , order : Ordering ) -> Option < ~T > {
630
640
unsafe {
631
641
let val = cast:: transmute ( val) ;
632
642
633
- let p = atomic_swap ( & mut self . p , val, order) ;
643
+ let p = atomic_swap ( & mut * self . p . get ( ) , val, order) ;
634
644
if p as uint == 0 {
635
645
None
636
646
} else {
@@ -655,7 +665,7 @@ impl<T> AtomicOption<T> {
655
665
unsafe {
656
666
let val = cast:: transmute ( val) ;
657
667
let expected = cast:: transmute ( 0 ) ;
658
- let oldval = atomic_compare_and_swap ( & mut self . p , expected, val, order) ;
668
+ let oldval = atomic_compare_and_swap ( & mut * self . p . get ( ) , expected, val, order) ;
659
669
if oldval == expected {
660
670
None
661
671
} else {
@@ -670,7 +680,7 @@ impl<T> AtomicOption<T> {
670
680
/// result does not get invalidated by another task after this returns.
671
681
#[ inline]
672
682
pub fn is_empty ( & mut self , order : Ordering ) -> bool {
673
- unsafe { atomic_load ( & self . p , order) as uint == 0 }
683
+ unsafe { atomic_load ( & * self . p . get ( ) , order) as uint == 0 }
674
684
}
675
685
}
676
686
0 commit comments