@@ -795,6 +795,103 @@ struct AtomicInitializeARCRefRaceTest : RaceTestWithPerTrialData {
795
795
}
796
796
}
797
797
798
+ struct AtomicAcquiringARCRefRaceTest : RaceTestWithPerTrialData {
799
+ typealias DummyObject = AtomicInitializeARCRefRaceTest . DummyObject
800
+
801
+ class RaceData {
802
+ var _atomicReference : DummyObject ? = nil
803
+
804
+ var atomicReferencePtr : UnsafeMutablePointer < DummyObject ? > {
805
+ _getUnsafePointerToStoredProperties ( self ) . assumingMemoryBound (
806
+ to: Optional< DummyObject> . self )
807
+ }
808
+
809
+ init ( ) { }
810
+ }
811
+
812
+ typealias ThreadLocalData = _stdlib_ShardedAtomicCounter . PRNG
813
+ typealias Observation = Observation4UInt
814
+
815
+ func makeRaceData( ) -> RaceData {
816
+ RaceData ( )
817
+ }
818
+
819
+ func makeThreadLocalData( ) -> ThreadLocalData {
820
+ ThreadLocalData ( )
821
+ }
822
+
823
+ func thread1(
824
+ _ raceData: RaceData , _ threadLocalData: inout ThreadLocalData
825
+ ) -> Observation {
826
+ var observation = Observation4UInt ( 0 , 0 , 0 , 0 )
827
+ let initializerDestroyed = HeapBool ( false )
828
+ do {
829
+ let object = DummyObject (
830
+ destroyedFlag: initializerDestroyed,
831
+ randomInt: threadLocalData. randomInt ( ) )
832
+ let value = Unmanaged . passUnretained ( object)
833
+ let result = _stdlib_atomicAcquiringInitializeARCRef (
834
+ object: raceData. atomicReferencePtr, desired: object)
835
+ observation. data1 = ( result. toOpaque ( ) == value. toOpaque ( ) ? 1 : 0 )
836
+ if let loaded =
837
+ _stdlib_atomicAcquiringLoadARCRef ( object: raceData. atomicReferencePtr) {
838
+ observation. data2 = UInt ( bitPattern: loaded. toOpaque ( ) )
839
+ observation. data3 = loaded. _withUnsafeGuaranteedRef { $0. payload }
840
+ }
841
+ }
842
+ observation. data4 = initializerDestroyed. value ? 1 : 0
843
+ return observation
844
+ }
845
+
846
+ func evaluateObservations(
847
+ _ observations: [ Observation ] ,
848
+ _ sink: ( RaceTestObservationEvaluation ) -> Void
849
+ ) {
850
+ let ref = observations [ 0 ] . data2
851
+ if observations. contains ( where: { $0. data2 != ref } ) {
852
+ for observation in observations {
853
+ sink ( . failureInteresting( " mismatched reference, expected \( ref) : \( observation) " ) )
854
+ }
855
+ return
856
+ }
857
+ if observations. contains ( where: { $0. data3 != 0x12345678 } ) {
858
+ for observation in observations {
859
+ sink ( . failureInteresting( " wrong data: \( observation) " ) )
860
+ }
861
+ return
862
+ }
863
+
864
+ var wonRace = 0
865
+ var lostRace = 0
866
+ for observation in observations {
867
+ switch ( observation. data1, observation. data4) {
868
+ case ( 1 , 0 ) :
869
+ // Won race, value not destroyed.
870
+ wonRace += 1
871
+ case ( 0 , 1 ) :
872
+ // Lost race, value destroyed.
873
+ lostRace += 1
874
+ default :
875
+ sink ( . failureInteresting( String ( describing: observation) ) )
876
+ }
877
+ }
878
+ if wonRace != 1 {
879
+ for observation in observations {
880
+ sink ( . failureInteresting( " zero or more than one thread won race: \( observation) " ) )
881
+ }
882
+ return
883
+ }
884
+ if lostRace < 1 {
885
+ for observation in observations {
886
+ sink ( . failureInteresting( " no thread lost race: \( observation) " ) )
887
+ }
888
+ return
889
+ }
890
+
891
+ sink ( . pass)
892
+ }
893
+ }
894
+
798
895
var AtomicIntTestSuite = TestSuite ( " AtomicInt " )
799
896
800
897
AtomicIntTestSuite . test ( " fetchAndAdd/1 " ) {
@@ -841,11 +938,16 @@ AtomicIntTestSuite.test("fetchAndXor/1") {
841
938
842
939
var AtomicARCRefTestSuite = TestSuite ( " AtomicARCRef " )
843
940
844
- AtomicARCRefTestSuite . test ( " initialize ,load" ) {
941
+ AtomicARCRefTestSuite . test ( " seqcst_initialize ,load" ) {
845
942
runRaceTest ( AtomicInitializeARCRefRaceTest . self,
846
943
operations: 25600 , timeoutInSeconds: 60 )
847
944
expectEqual ( 0 , dummyObjectCount. getSum ( ) )
848
945
}
849
946
850
- runAllTests ( )
947
+ AtomicARCRefTestSuite . test ( " acquire_initialize,load " ) {
948
+ runRaceTest ( AtomicAcquiringARCRefRaceTest . self,
949
+ operations: 25600 , timeoutInSeconds: 60 )
950
+ expectEqual ( 0 , dummyObjectCount. getSum ( ) )
951
+ }
851
952
953
+ runAllTests ( )
0 commit comments