@@ -14,65 +14,118 @@ import MachO
1414/// A simple, generic lock-free finite state machine.
1515///
1616/// - warning: `deinitialize` must be called to dispose of the consumed memory.
17- internal struct UnsafeAtomicState < State: RawRepresentable > where State. RawValue == Int32 {
18- internal typealias Transition = ( expected: State , next: State )
19- #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
20- private let value : UnsafeMutablePointer < Int32 >
17+ internal struct UnsafeAtomicInt32 {
18+ #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
19+ private let _value : UnsafeMutablePointer < Int32 >
20+
21+ internal var value : Int32 {
22+ return _value. pointee
23+ }
2124
2225 /// Create a finite state machine with the specified initial state.
2326 ///
2427 /// - parameters:
2528 /// - initial: The desired initial state.
26- internal init ( _ initial: State ) {
27- value = UnsafeMutablePointer< Int32> . allocate( capacity: 1 )
28- value . initialize ( to: initial. rawValue )
29+ internal init ( _ initial: Int32 ) {
30+ _value = UnsafeMutablePointer< Int32> . allocate( capacity: 1 )
31+ _value . initialize ( to: initial)
2932 }
3033
3134 /// Deinitialize the finite state machine.
3235 internal func deinitialize( ) {
33- value . deinitialize ( )
34- value . deallocate ( capacity: 1 )
36+ _value . deinitialize ( )
37+ _value . deallocate ( capacity: 1 )
3538 }
3639
37- /// Compare the current state with the specified state.
40+ internal func swap( from expected: Int32 , to next: Int32 ) -> Bool {
41+ return OSAtomicCompareAndSwap32Barrier ( expected, next, _value)
42+ }
43+
44+ /// Increment the atomic integer.
3845 ///
39- /// - parameters:
40- /// - expected: The expected state.
46+ /// - returns: The new value.
47+ @discardableResult
48+ internal func increment( ) -> Int32 {
49+ return OSAtomicIncrement32Barrier ( _value)
50+ }
51+
52+ /// Decrement the atomic integer.
4153 ///
42- /// - returns: `true` if the current state matches the expected state.
43- /// `false` otherwise.
44- internal func `is`( _ expected: State ) -> Bool {
45- return OSAtomicCompareAndSwap32Barrier ( expected. rawValue,
46- expected. rawValue,
47- value)
54+ /// - returns: The new value.
55+ @discardableResult
56+ internal func decrement( ) -> Int32 {
57+ return OSAtomicDecrement32Barrier ( _value)
4858 }
59+ #else
60+ private let _value : Atomic < Int32 >
4961
50- /// Try to transition from the expected current state to the specified next
51- /// state.
62+ private var value : Int32 {
63+ return _value. pointee
64+ }
65+
66+ /// Create a finite state machine with the specified initial state.
5267 ///
5368 /// - parameters:
54- /// - expected: The expected state.
55- /// - next: The state to transition to.
69+ /// - initial: The desired initial state.
70+ internal init ( _ initial: Int32 ) {
71+ _value = Atomic ( initial)
72+ }
73+
74+ /// Deinitialize the finite state machine.
75+ internal func deinitialize( ) { }
76+
77+ internal func swap( from expected: Int32 , to next: Int32 ) -> Bool {
78+ return _value. modify { value in
79+ guard value == expected else { return false }
80+ value = next
81+ return true
82+ }
83+ }
84+
85+ /// Increment the atomic integer.
5686 ///
57- /// - returns: `true` if the transition succeeds. `false` otherwise.
58- internal func tryTransition( from expected: State , to next: State ) -> Bool {
59- return OSAtomicCompareAndSwap32Barrier ( expected. rawValue,
60- next. rawValue,
61- value)
87+ /// - returns: The new value.
88+ @discardableResult
89+ internal func increment( ) -> Int32 {
90+ return _value. modify { value in
91+ value += 1
92+ return value
93+ }
6294 }
63- #else
64- private let value : Atomic < Int32 >
95+
96+ /// Decrement the atomic integer.
97+ ///
98+ /// - returns: The new value.
99+ @discardableResult
100+ internal func decrement( ) -> Int32 {
101+ return _value. modify { value in
102+ value -= 1
103+ return value
104+ }
105+ }
106+ #endif
107+ }
108+
109+ /// A simple, generic lock-free finite state machine.
110+ ///
111+ /// - warning: `deinitialize` must be called to dispose of the consumed memory.
112+ internal struct UnsafeAtomicState < State: RawRepresentable > where State. RawValue == Int32 {
113+ internal typealias Transition = ( expected: State , next: State )
114+
115+ private let value : UnsafeAtomicInt32
65116
66117 /// Create a finite state machine with the specified initial state.
67118 ///
68119 /// - parameters:
69120 /// - initial: The desired initial state.
70121 internal init ( _ initial: State ) {
71- value = Atomic ( initial. rawValue)
122+ value = UnsafeAtomicInt32 ( initial. rawValue)
72123 }
73124
74125 /// Deinitialize the finite state machine.
75- internal func deinitialize( ) { }
126+ internal func deinitialize( ) {
127+ value. deinitialize ( )
128+ }
76129
77130 /// Compare the current state with the specified state.
78131 ///
@@ -82,26 +135,20 @@ internal struct UnsafeAtomicState<State: RawRepresentable> where State.RawValue
82135 /// - returns: `true` if the current state matches the expected state.
83136 /// `false` otherwise.
84137 internal func `is`( _ expected: State ) -> Bool {
85- return value. modify { $0 == expected. rawValue }
138+ return value. swap ( from : expected . rawValue , to : expected. rawValue)
86139 }
87140
88141 /// Try to transition from the expected current state to the specified next
89142 /// state.
90143 ///
91144 /// - parameters:
92145 /// - expected: The expected state.
146+ /// - next: The state to transition to.
93147 ///
94148 /// - returns: `true` if the transition succeeds. `false` otherwise.
95149 internal func tryTransition( from expected: State , to next: State ) -> Bool {
96- return value. modify { value in
97- if value == expected. rawValue {
98- value = next. rawValue
99- return true
100- }
101- return false
102- }
150+ return value. swap ( from: expected. rawValue, to: next. rawValue)
103151 }
104- #endif
105152}
106153
107154/// `Lock` exposes `os_unfair_lock` on supported platforms, with pthread mutex as the
0 commit comments