Skip to content

Commit 99fc7db

Browse files
authored
Revert "Remove deprecated spinlock API in Deferred (#4873)" (#4886)
This reverts commit 4252965.
1 parent aac1dd2 commit 99fc7db

File tree

1 file changed

+37
-26
lines changed

1 file changed

+37
-26
lines changed

ThirdParty/Deferred/Deferred/ReadWriteLock.swift

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -35,28 +35,30 @@ public final class GCDReadWriteLock: ReadWriteLock {
3535
}
3636
}
3737

38-
public class AtomicInt {
39-
private var mutex = pthread_mutex_t()
40-
private(set) var value: Int32 = 0
38+
public final class SpinLock: ReadWriteLock {
39+
private var lock: UnsafeMutablePointer<Int32>
4140

42-
init() {
43-
pthread_mutex_init(&mutex, nil)
41+
public init() {
42+
lock = UnsafeMutablePointer.allocate(capacity: 1)
43+
lock.pointee = OS_SPINLOCK_INIT
4444
}
4545

4646
deinit {
47-
pthread_mutex_destroy(&mutex)
47+
lock.deallocate()
4848
}
4949

50-
func compareAndSwap(oldValue: Int32, newValue: Int32) -> Bool {
51-
pthread_mutex_lock(&mutex)
52-
defer {
53-
pthread_mutex_unlock(&mutex)
54-
}
55-
if oldValue != value {
56-
return false
57-
}
58-
value = newValue
59-
return true
50+
public func withReadLock<T>(block: () -> T) -> T {
51+
OSSpinLockLock(lock)
52+
let result = block()
53+
OSSpinLockUnlock(lock)
54+
return result
55+
}
56+
57+
public func withWriteLock<T>(block: () -> T) -> T {
58+
OSSpinLockLock(lock)
59+
let result = block()
60+
OSSpinLockUnlock(lock)
61+
return result
6062
}
6163
}
6264

@@ -69,24 +71,33 @@ public final class CASSpinLock: ReadWriteLock {
6971
static let MASK_READER_BITS = ~MASK_WRITER_BITS
7072
}
7173

72-
private let _state = AtomicInt()
74+
private var _state: UnsafeMutablePointer<Int32>
75+
76+
public init() {
77+
_state = UnsafeMutablePointer.allocate(capacity: 1)
78+
_state.pointee = 0
79+
}
80+
81+
deinit {
82+
_state.deallocate()
83+
}
7384

7485
public func withWriteLock<T>(block: () -> T) -> T {
7586
// spin until we acquire write lock
7687
repeat {
77-
let state = _state.value
88+
let state = _state.pointee
7889

7990
// if there are no readers and no one holds the write lock, try to grab the write lock immediately
8091
if (state == 0 || state == Masks.WRITER_WAITING_BIT) &&
81-
_state.compareAndSwap(oldValue: state, newValue: Masks.WRITER_BIT) {
92+
OSAtomicCompareAndSwap32Barrier(state, Masks.WRITER_BIT, _state) {
8293
break
8394
}
8495

8596
// If we get here, someone is reading or writing. Set the WRITER_WAITING_BIT if
8697
// it isn't already to block any new readers, then wait a bit before
8798
// trying again. Ignore CAS failure - we'll just try again next iteration
8899
if state & Masks.WRITER_WAITING_BIT == 0 {
89-
_ = _state.compareAndSwap(oldValue: state, newValue: state | Masks.WRITER_WAITING_BIT)
100+
OSAtomicCompareAndSwap32Barrier(state, state | Masks.WRITER_WAITING_BIT, _state)
90101
}
91102
} while true
92103

@@ -95,11 +106,11 @@ public final class CASSpinLock: ReadWriteLock {
95106

96107
// unlock
97108
repeat {
98-
let state = _state.value
109+
let state = _state.pointee
99110

100111
// clear everything except (possibly) WRITER_WAITING_BIT, which will only be set
101112
// if another writer is already here and waiting (which will keep out readers)
102-
if _state.compareAndSwap(oldValue: state, newValue: state & Masks.WRITER_WAITING_BIT) {
113+
if OSAtomicCompareAndSwap32Barrier(state, state & Masks.WRITER_WAITING_BIT, _state) {
103114
break
104115
}
105116
} while true
@@ -110,11 +121,11 @@ public final class CASSpinLock: ReadWriteLock {
110121
public func withReadLock<T>(block: () -> T) -> T {
111122
// spin until we acquire read lock
112123
repeat {
113-
let state = _state.value
124+
let state = _state.pointee
114125

115126
// if there is no writer and no writer waiting, try to increment reader count
116127
if (state & Masks.MASK_WRITER_BITS) == 0 &&
117-
_state.compareAndSwap(oldValue: state, newValue: state + 1) {
128+
OSAtomicCompareAndSwap32Barrier(state, state + 1, _state) {
118129
break
119130
}
120131
} while true
@@ -124,7 +135,7 @@ public final class CASSpinLock: ReadWriteLock {
124135

125136
// decrement reader count
126137
repeat {
127-
let state = _state.value
138+
let state = _state.pointee
128139

129140
// sanity check that we have a positive reader count before decrementing it
130141
assert((state & Masks.MASK_READER_BITS) > 0, "unlocking read lock - invalid reader count")
@@ -133,7 +144,7 @@ public final class CASSpinLock: ReadWriteLock {
133144
let newState = ((state & Masks.MASK_READER_BITS) - 1) |
134145
(state & Masks.WRITER_WAITING_BIT)
135146

136-
if _state.compareAndSwap(oldValue: state, newValue: newState) {
147+
if OSAtomicCompareAndSwap32Barrier(state, newState, _state) {
137148
break
138149
}
139150
} while true

0 commit comments

Comments
 (0)