@@ -114,35 +114,36 @@ use cast;
114114use std:: kinds:: marker;
115115use option:: { Option , Some , None } ;
116116use ops:: Drop ;
117+ use ty:: Unsafe ;
117118
118119/// An atomic boolean type.
119120pub struct AtomicBool {
120- priv v: uint ,
121+ priv v: Unsafe < uint > ,
121122 priv nopod : marker:: NoPod
122123}
123124
124125/// A signed atomic integer type, supporting basic atomic arithmetic operations
125126pub struct AtomicInt {
126- priv v: int ,
127+ priv v: Unsafe < int > ,
127128 priv nopod : marker:: NoPod
128129}
129130
130131/// An unsigned atomic integer type, supporting basic atomic arithmetic operations
131132pub struct AtomicUint {
132- priv v: uint ,
133+ priv v: Unsafe < uint > ,
133134 priv nopod : marker:: NoPod
134135}
135136
136137/// An unsigned atomic integer type that is forced to be 64-bits. This does not
137138/// support all operations.
138139pub struct AtomicU64 {
139- priv v: u64 ,
140+ priv v: Unsafe < u64 > ,
140141 priv nopod : marker:: NoPod
141142}
142143
143144/// An unsafe atomic pointer. Only supports basic atomic operations
144145pub struct AtomicPtr < T > {
145- priv p: uint ,
146+ priv p: Unsafe < uint > ,
146147 priv nopod : marker:: NoPod
147148}
148149
@@ -152,7 +153,7 @@ pub struct AtomicPtr<T> {
152153/// owned heap objects across tasks.
153154#[ unsafe_no_drop_flag]
154155pub struct AtomicOption < T > {
155- priv p: uint ,
156+ priv p: Unsafe < uint > ,
156157}
157158
158159/// Atomic memory orderings
@@ -186,13 +187,21 @@ pub enum Ordering {
186187}
187188
188189/// 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 } ;
190193/// 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 } ;
192197/// 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 } ;
194201/// 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 } ;
196205
197206
198207// NB: Needs to be -1 (0b11111111...) to make fetch_nand work correctly
@@ -201,29 +210,30 @@ static UINT_TRUE: uint = -1;
201210impl AtomicBool {
202211 /// Create a new `AtomicBool`
203212 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 }
205215 }
206216
207217 /// Load the value
208218 #[ inline]
209219 pub fn load ( & self , order : Ordering ) -> bool {
210- unsafe { atomic_load ( & self . v , order) > 0 }
220+ unsafe { atomic_load ( & * self . v . get ( ) , order) > 0 }
211221 }
212222
213223 /// Store the value
214224 #[ inline]
215225 pub fn store ( & mut self , val : bool , order : Ordering ) {
216226 let val = if val { UINT_TRUE } else { 0 } ;
217227
218- unsafe { atomic_store ( & mut self . v , val, order) ; }
228+ unsafe { atomic_store ( & mut * self . v . get ( ) , val, order) ; }
219229 }
220230
221231 /// Store a value, returning the old value
222232 #[ inline]
223233 pub fn swap ( & mut self , val : bool , order : Ordering ) -> bool {
224234 let val = if val { UINT_TRUE } else { 0 } ;
225235
226- unsafe { atomic_swap ( & mut self . v , val, order) > 0 }
236+ unsafe { atomic_swap ( & mut * self . v . get ( ) , val, order) > 0 }
227237 }
228238
229239 /// If the current value is the same as expected, store a new value
@@ -276,7 +286,7 @@ impl AtomicBool {
276286 let old = if old { UINT_TRUE } else { 0 } ;
277287 let new = if new { UINT_TRUE } else { 0 } ;
278288
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 }
280290 }
281291
282292 /// A logical "and" operation
@@ -306,7 +316,7 @@ impl AtomicBool {
306316 pub fn fetch_and ( & mut self , val : bool , order : Ordering ) -> bool {
307317 let val = if val { UINT_TRUE } else { 0 } ;
308318
309- unsafe { atomic_and ( & mut self . v , val, order) > 0 }
319+ unsafe { atomic_and ( & mut * self . v . get ( ) , val, order) > 0 }
310320 }
311321
312322 /// A logical "nand" operation
@@ -337,7 +347,7 @@ impl AtomicBool {
337347 pub fn fetch_nand ( & mut self , val : bool , order : Ordering ) -> bool {
338348 let val = if val { UINT_TRUE } else { 0 } ;
339349
340- unsafe { atomic_nand ( & mut self . v , val, order) > 0 }
350+ unsafe { atomic_nand ( & mut * self . v . get ( ) , val, order) > 0 }
341351 }
342352
343353 /// A logical "or" operation
@@ -367,7 +377,7 @@ impl AtomicBool {
367377 pub fn fetch_or ( & mut self , val : bool , order : Ordering ) -> bool {
368378 let val = if val { UINT_TRUE } else { 0 } ;
369379
370- unsafe { atomic_or ( & mut self . v , val, order) > 0 }
380+ unsafe { atomic_or ( & mut * self . v . get ( ) , val, order) > 0 }
371381 }
372382
373383 /// A logical "xor" operation
@@ -397,32 +407,32 @@ impl AtomicBool {
397407 pub fn fetch_xor ( & mut self , val : bool , order : Ordering ) -> bool {
398408 let val = if val { UINT_TRUE } else { 0 } ;
399409
400- unsafe { atomic_xor ( & mut self . v , val, order) > 0 }
410+ unsafe { atomic_xor ( & mut * self . v . get ( ) , val, order) > 0 }
401411 }
402412}
403413
404414impl AtomicInt {
405415 /// Create a new `AtomicInt`
406416 pub fn new ( v : int ) -> AtomicInt {
407- AtomicInt { v : v , nopod : marker:: NoPod }
417+ AtomicInt { v : Unsafe :: new ( v ) , nopod : marker:: NoPod }
408418 }
409419
410420 /// Load the value
411421 #[ inline]
412422 pub fn load ( & self , order : Ordering ) -> int {
413- unsafe { atomic_load ( & self . v , order) }
423+ unsafe { atomic_load ( & * self . v . get ( ) , order) }
414424 }
415425
416426 /// Store the value
417427 #[ inline]
418428 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) ; }
420430 }
421431
422432 /// Store a value, returning the old value
423433 #[ inline]
424434 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) }
426436 }
427437
428438 /// If the current value is the same as expected, store a new value
@@ -432,7 +442,7 @@ impl AtomicInt {
432442 /// If the return value is equal to `old` then the value was updated.
433443 #[ inline]
434444 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) }
436446 }
437447
438448 /// Add to the current value, returning the previous
@@ -448,7 +458,7 @@ impl AtomicInt {
448458 /// ```
449459 #[ inline]
450460 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) }
452462 }
453463
454464 /// Subtract from the current value, returning the previous
@@ -464,7 +474,7 @@ impl AtomicInt {
464474 /// ```
465475 #[ inline]
466476 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) }
468478 }
469479}
470480
@@ -474,62 +484,62 @@ impl AtomicInt {
474484#[ cfg( not( target_arch = "mips" ) ) ]
475485impl AtomicU64 {
476486 pub fn new ( v : u64 ) -> AtomicU64 {
477- AtomicU64 { v : v , nopod : marker:: NoPod }
487+ AtomicU64 { v : Unsafe :: new ( v ) , nopod : marker:: NoPod }
478488 }
479489
480490 #[ inline]
481491 pub fn load ( & self , order : Ordering ) -> u64 {
482- unsafe { atomic_load ( & self . v , order) }
492+ unsafe { atomic_load ( & * self . v . get ( ) , order) }
483493 }
484494
485495 #[ inline]
486496 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) ; }
488498 }
489499
490500 #[ inline]
491501 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) }
493503 }
494504
495505 #[ inline]
496506 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) }
498508 }
499509
500510 #[ inline]
501511 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) }
503513 }
504514
505515 #[ inline]
506516 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) }
508518 }
509519}
510520
511521impl AtomicUint {
512522 /// Create a new `AtomicUint`
513523 pub fn new ( v : uint ) -> AtomicUint {
514- AtomicUint { v : v , nopod : marker:: NoPod }
524+ AtomicUint { v : Unsafe :: new ( v ) , nopod : marker:: NoPod }
515525 }
516526
517527 /// Load the value
518528 #[ inline]
519529 pub fn load ( & self , order : Ordering ) -> uint {
520- unsafe { atomic_load ( & self . v , order) }
530+ unsafe { atomic_load ( & * self . v . get ( ) , order) }
521531 }
522532
523533 /// Store the value
524534 #[ inline]
525535 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) ; }
527537 }
528538
529539 /// Store a value, returning the old value
530540 #[ inline]
531541 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) }
533543 }
534544
535545 /// If the current value is the same as expected, store a new value
@@ -539,7 +549,7 @@ impl AtomicUint {
539549 /// If the return value is equal to `old` then the value was updated.
540550 #[ inline]
541551 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) }
543553 }
544554
545555 /// Add to the current value, returning the previous
@@ -555,7 +565,7 @@ impl AtomicUint {
555565 /// ```
556566 #[ inline]
557567 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) }
559569 }
560570
561571 /// Subtract from the current value, returning the previous
@@ -571,34 +581,34 @@ impl AtomicUint {
571581 /// ```
572582 #[ inline]
573583 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) }
575585 }
576586}
577587
578588impl < T > AtomicPtr < T > {
579589 /// Create a new `AtomicPtr`
580590 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 }
582592 }
583593
584594 /// Load the value
585595 #[ inline]
586596 pub fn load ( & self , order : Ordering ) -> * mut T {
587597 unsafe {
588- atomic_load ( & self . p , order) as * mut T
598+ atomic_load ( & * self . p . get ( ) , order) as * mut T
589599 }
590600 }
591601
592602 /// Store the value
593603 #[ inline]
594604 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) ; }
596606 }
597607
598608 /// Store a value, returning the old value
599609 #[ inline]
600610 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 }
602612 }
603613
604614 /// If the current value is the same as expected, store a new value
@@ -609,7 +619,7 @@ impl<T> AtomicPtr<T> {
609619 #[ inline]
610620 pub fn compare_and_swap ( & mut self , old : * mut T , new : * mut T , order : Ordering ) -> * mut T {
611621 unsafe {
612- atomic_compare_and_swap ( & mut self . p , old as uint ,
622+ atomic_compare_and_swap ( & mut * self . p . get ( ) , old as uint ,
613623 new as uint , order) as * mut T
614624 }
615625 }
@@ -618,19 +628,19 @@ impl<T> AtomicPtr<T> {
618628impl < T > AtomicOption < T > {
619629 /// Create a new `AtomicOption`
620630 pub fn new ( p : ~T ) -> AtomicOption < T > {
621- unsafe { AtomicOption { p : cast:: transmute ( p) } }
631+ unsafe { AtomicOption { p : Unsafe :: new ( cast:: transmute ( p) ) } }
622632 }
623633
624634 /// 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 ) } }
626636
627637 /// Store a value, returning the old value
628638 #[ inline]
629639 pub fn swap ( & mut self , val : ~T , order : Ordering ) -> Option < ~T > {
630640 unsafe {
631641 let val = cast:: transmute ( val) ;
632642
633- let p = atomic_swap ( & mut self . p , val, order) ;
643+ let p = atomic_swap ( & mut * self . p . get ( ) , val, order) ;
634644 if p as uint == 0 {
635645 None
636646 } else {
@@ -655,7 +665,7 @@ impl<T> AtomicOption<T> {
655665 unsafe {
656666 let val = cast:: transmute ( val) ;
657667 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) ;
659669 if oldval == expected {
660670 None
661671 } else {
@@ -670,7 +680,7 @@ impl<T> AtomicOption<T> {
670680 /// result does not get invalidated by another task after this returns.
671681 #[ inline]
672682 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 }
674684 }
675685}
676686
0 commit comments