Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Sources/Concurrency/AtomicReference.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -28,7 +29,7 @@ public class AtomicReference<ValueType> {
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 {
Expand Down Expand Up @@ -59,7 +60,7 @@ public class AtomicReference<ValueType> {
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
Expand Down
4 changes: 4 additions & 0 deletions Sources/ObjCBridges/AtomicBridges.m
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 2 additions & 0 deletions Sources/ObjCBridges/include/AtomicBridges.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
12 changes: 0 additions & 12 deletions Tests/ConcurrencyTests/AtomicIntTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
10 changes: 0 additions & 10 deletions Tests/ConcurrencyTests/AtomicReferenceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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<NSObject>(initialValue: initialValue)
Expand Down
8 changes: 0 additions & 8 deletions Tests/ConcurrencyTests/CountDownLatchTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down