diff --git a/Sources/Concurrency/AtomicReference.swift b/Sources/Concurrency/AtomicReference.swift index c857386..8a1856e 100644 --- a/Sources/Concurrency/AtomicReference.swift +++ b/Sources/Concurrency/AtomicReference.swift @@ -16,6 +16,7 @@ import Foundation import libkern +import ObjCBridges /// A concurrency utility class that supports locking-free synchronization on mutating an object /// reference. Unlike using a lock, concurrent read and write accesses to this class is allowed. At @@ -28,7 +29,7 @@ public class AtomicReference { get { // Create a memory barrier to ensure the entire memory stack is in sync so we // can safely retrieve the value. This guarantees the initial value is in sync. - OSMemoryBarrier() + atomic_thread_fence(memory_order_seq_cst) return wrappedValue } set { @@ -59,7 +60,7 @@ public class AtomicReference { let expectPointer = unsafePassUnretainedPointer(value: expect) let newValuePointer = unsafePassUnretainedPointer(value: newValue) - if OSAtomicCompareAndSwapPtrBarrier(expectPointer, newValuePointer, pointer) { + if AtomicBridges.comparePointer(pointer, withExpectedPointer: expectPointer, andSwapPointer: newValuePointer) { // If pointer swap succeeded, a memory berrier is created, so we can safely write the new // value. wrappedValue = newValue diff --git a/Sources/ObjCBridges/AtomicBridges.m b/Sources/ObjCBridges/AtomicBridges.m index e5a74e6..cc25ddd 100644 --- a/Sources/ObjCBridges/AtomicBridges.m +++ b/Sources/ObjCBridges/AtomicBridges.m @@ -30,4 +30,8 @@ + (bool)compare:(_Atomic(long) *)value withExpected:(long *)expected andSwap:(lo return atomic_compare_exchange_strong(value, expected, desired); } ++ (bool)comparePointer:(void * volatile *)value withExpectedPointer:(void *)expected andSwapPointer:(void *)desired { + return __sync_bool_compare_and_swap(value, expected, desired); +} + @end diff --git a/Sources/ObjCBridges/include/AtomicBridges.h b/Sources/ObjCBridges/include/AtomicBridges.h index 0cd77fe..3b2fc71 100644 --- a/Sources/ObjCBridges/include/AtomicBridges.h +++ b/Sources/ObjCBridges/include/AtomicBridges.h @@ -27,6 +27,8 @@ NS_ASSUME_NONNULL_BEGIN + (bool)compare:(_Atomic(long) *)value withExpected:(long *)expected andSwap:(long)desired; ++ (bool)comparePointer:(void * _Nullable volatile * _Nonnull)value withExpectedPointer:(void *)expected andSwapPointer:(void *)desired; + @end NS_ASSUME_NONNULL_END diff --git a/Tests/ConcurrencyTests/AtomicIntTests.swift b/Tests/ConcurrencyTests/AtomicIntTests.swift index fc4b5bd..60f8877 100644 --- a/Tests/ConcurrencyTests/AtomicIntTests.swift +++ b/Tests/ConcurrencyTests/AtomicIntTests.swift @@ -19,18 +19,6 @@ import XCTest class AtomicIntTests: XCTestCase { - static var allTests = [ - ("test_init_verifyInitialValue", test_init_verifyInitialValue), - ("test_initGetSet_verifySetToNewValue", test_initGetSet_verifySetToNewValue), - ("test_compareAndSet_verifySettingNewValue", test_compareAndSet_verifySettingNewValue), - ("test_compareAndSet_withFalseExpectValue_verifyNotSettingNewValue", test_compareAndSet_withFalseExpectValue_verifyNotSettingNewValue), - ("test_getAndSet_verifySettingNewValueReturningOldValue", test_getAndSet_verifySettingNewValueReturningOldValue), - ("test_incrementAndGet_verifyNewValue", test_incrementAndGet_verifyNewValue), - ("test_decrementAndGet_verifyNewValue", test_decrementAndGet_verifyNewValue), - ("test_getAndIncrement_verifyNewValue", test_getAndIncrement_verifyNewValue), - ("test_getAndDecrement_verifyNewValue", test_getAndDecrement_verifyNewValue), - ] - func test_init_verifyInitialValue() { let initialValue = 123 let atomicInt = AtomicInt(initialValue: initialValue) diff --git a/Tests/ConcurrencyTests/AtomicReferenceTests.swift b/Tests/ConcurrencyTests/AtomicReferenceTests.swift index c589ba1..8dc540b 100644 --- a/Tests/ConcurrencyTests/AtomicReferenceTests.swift +++ b/Tests/ConcurrencyTests/AtomicReferenceTests.swift @@ -19,16 +19,6 @@ import XCTest class AtomicReferenceTests: XCTestCase { - static var allTests = [ - ("test_init_verifyInitialValue", test_init_verifyInitialValue), - ("test_initGetSet_verifySetToNewValue", test_initGetSet_verifySetToNewValue), - ("test_compareAndSet_verifySettingNewValue", test_compareAndSet_verifySettingNewValue), - ("test_compareAndSet_withFalseExpectValue_verifyNotSettingNewValue", test_compareAndSet_withFalseExpectValue_verifyNotSettingNewValue), - ("test_compareAndSet_withNil_verifySettingNewValue", test_compareAndSet_withNil_verifySettingNewValue), - ("test_getAndSet_verifySettingNewValueReturningOldValue", test_getAndSet_verifySettingNewValueReturningOldValue), - ("test_compareAndSet_initialNilThenResetToNil_verifySuccess", test_compareAndSet_initialNilThenResetToNil_verifySuccess), - ] - func test_init_verifyInitialValue() { let initialValue = NSObject() let atomicRef = AtomicReference(initialValue: initialValue) diff --git a/Tests/ConcurrencyTests/CountDownLatchTests.swift b/Tests/ConcurrencyTests/CountDownLatchTests.swift index b0a0457..ee24609 100644 --- a/Tests/ConcurrencyTests/CountDownLatchTests.swift +++ b/Tests/ConcurrencyTests/CountDownLatchTests.swift @@ -19,14 +19,6 @@ import XCTest class CountDownLatchTests: XCTestCase { - static var allTests = [ - ("test_countDown_await_verifyCompletionWithTrue", test_countDown_await_verifyCompletionWithTrue), - ("test_countDown_await_withTimeout_verifyCompletionWithFalse", test_countDown_await_withTimeout_verifyCompletionWithFalse), - ("test_countDown_await_verifyDuplicateCountDown_verifyDuplicateAwaitCompletesWithTrue", test_countDown_await_verifyDuplicateCountDown_verifyDuplicateAwaitCompletesWithTrue), - ("test_multipleAwaitBeforeCountDown_verifyCompletesWithTrue", test_multipleAwaitBeforeCountDown_verifyCompletesWithTrue), - ("test_multipleAsyncAwaitBeforeCountDown_verifyCompletesWithTrue", test_multipleAsyncAwaitBeforeCountDown_verifyCompletesWithTrue), - ] - func test_countDown_await_verifyCompletionWithTrue() { let latch = CountDownLatch(count: 3)