Skip to content

Commit 598fc75

Browse files
committed
Make atomics interior Unsafe<T>
1 parent 68a3ec0 commit 598fc75

File tree

1 file changed

+60
-50
lines changed

1 file changed

+60
-50
lines changed

src/libstd/sync/atomics.rs

Lines changed: 60 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -114,35 +114,36 @@ use cast;
114114
use std::kinds::marker;
115115
use option::{Option,Some,None};
116116
use ops::Drop;
117+
use ty::Unsafe;
117118

118119
/// An atomic boolean type.
119120
pub 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
125126
pub 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
131132
pub 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.
138139
pub 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
144145
pub 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]
154155
pub 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;
201210
impl 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

404414
impl 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"))]
475485
impl 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

511521
impl 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

578588
impl<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> {
618628
impl<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

Comments
 (0)