@@ -75,6 +75,10 @@ pub enum Ordering {
75
75
SeqCst
76
76
}
77
77
78
+ pub static INIT_ATOMIC_FLAG : AtomicFlag = AtomicFlag { v : 0 } ;
79
+ pub static INIT_ATOMIC_BOOL : AtomicBool = AtomicBool { v : 0 } ;
80
+ pub static INIT_ATOMIC_INT : AtomicInt = AtomicInt { v : 0 } ;
81
+ pub static INIT_ATOMIC_UINT : AtomicUint = AtomicUint { v : 0 } ;
78
82
79
83
impl AtomicFlag {
80
84
@@ -569,6 +573,35 @@ pub unsafe fn atomic_umin<T>(dst: &mut T, val: T, order: Ordering) -> T {
569
573
} )
570
574
}
571
575
576
+ /**
577
+ * An atomic fence.
578
+ *
579
+ * A fence 'A' which has `Release` ordering semantics, synchronizes with a
580
+ * fence 'B' with (at least) `Acquire` semantics, if and only if there exists
581
+ * atomic operations X and Y, both operating on some atomic object 'M' such
582
+ * that A is sequenced before X, Y is synchronized before B and Y obsevers
583
+ * the change to M. This provides a happens-before dependence between A and B.
584
+ *
585
+ * Atomic operations with `Release` or `Acquire` semantics can also synchronize
586
+ * with a fence.
587
+ *
588
+ * A fence with has `SeqCst` ordering, in addition to having both `Acquire` and
589
+ * `Release` semantics, participates in the global program order of the other
590
+ * `SeqCst` operations and/or fences.
591
+ *
592
+ * Accepts `Acquire`, `Release`, `AcqRel` and `SeqCst` orderings.
593
+ */
594
+ #[ inline] #[ cfg( not( stage0) ) ]
595
+ pub fn fence ( order : Ordering ) {
596
+ unsafe {
597
+ match order {
598
+ Acquire => intrinsics:: atomic_fence_acq ( ) ,
599
+ Release => intrinsics:: atomic_fence_rel ( ) ,
600
+ AcqRel => intrinsics:: atomic_fence_rel ( ) ,
601
+ _ => intrinsics:: atomic_fence ( ) ,
602
+ }
603
+ }
604
+ }
572
605
573
606
#[ cfg( test) ]
574
607
mod test {
@@ -630,4 +663,19 @@ mod test {
630
663
assert_eq ! ( a. fetch_and( false , SeqCst ) , true ) ;
631
664
assert_eq ! ( a. load( SeqCst ) , false ) ;
632
665
}
666
+
667
+ static mut S_FLAG : AtomicFlag = INIT_ATOMIC_FLAG ;
668
+ static mut S_BOOL : AtomicBool = INIT_ATOMIC_BOOL ;
669
+ static mut S_INT : AtomicInt = INIT_ATOMIC_INT ;
670
+ static mut S_UINT : AtomicUint = INIT_ATOMIC_UINT ;
671
+
672
+ #[ test]
673
+ fn static_init ( ) {
674
+ unsafe {
675
+ assert ! ( !S_FLAG . test_and_set( SeqCst ) ) ;
676
+ assert ! ( !S_BOOL . load( SeqCst ) ) ;
677
+ assert ! ( S_INT . load( SeqCst ) == 0 ) ;
678
+ assert ! ( S_UINT . load( SeqCst ) == 0 ) ;
679
+ }
680
+ }
633
681
}
0 commit comments