diff --git a/Sources/Atomics/atomics-bool.swift b/Sources/Atomics/atomics-bool.swift deleted file mode 100644 index cf74b7c..0000000 --- a/Sources/Atomics/atomics-bool.swift +++ /dev/null @@ -1,82 +0,0 @@ -// -// atomics-bool.swift -// Atomics -// -// Created by Guillaume Lessard on 10/06/2016. -// Copyright © 2016-2017 Guillaume Lessard. All rights reserved. -// This file is distributed under the BSD 3-clause license. See LICENSE for details. -// - -import CAtomics - -public struct AtomicBool -{ - @_versioned var val = CAtomicsBoolean() - - public init(_ value: Bool = false) - { - CAtomicsBooleanInit(value, &val) - } - - public var value: Bool { - @inline(__always) - mutating get { return CAtomicsBooleanLoad(&val, .relaxed) } - } -} - -extension AtomicBool -{ - @inline(__always) - public mutating func load(order: LoadMemoryOrder = .relaxed)-> Bool - { - return CAtomicsBooleanLoad(&val, order) - } - - @inline(__always) - public mutating func store(_ value: Bool, order: StoreMemoryOrder = .relaxed) - { - CAtomicsBooleanStore(value, &val, order) - } - - @inline(__always) @discardableResult - public mutating func swap(_ value: Bool, order: MemoryOrder = .relaxed)-> Bool - { - return CAtomicsBooleanSwap(value, &val, order) - } - - @inline(__always) @discardableResult - public mutating func or(_ value: Bool, order: MemoryOrder = .relaxed)-> Bool - { - return CAtomicsBooleanOr(value, &val, order) - } - - @inline(__always) @discardableResult - public mutating func xor(_ value: Bool, order: MemoryOrder = .relaxed)-> Bool - { - return CAtomicsBooleanXor(value, &val, order) - } - - @inline(__always) @discardableResult - public mutating func and(_ value: Bool, order: MemoryOrder = .relaxed)-> Bool - { - return CAtomicsBooleanAnd(value, &val, order) - } - - @inline(__always) @discardableResult - public mutating func loadCAS(current: UnsafeMutablePointer, future: Bool, - type: CASType = .weak, - orderSwap: MemoryOrder = .relaxed, - orderLoad: LoadMemoryOrder = .relaxed) -> Bool - { - return CAtomicsBooleanCAS(current, future, &val, type, orderSwap, orderLoad) - } - - @inline(__always) @discardableResult - public mutating func CAS(current: Bool, future: Bool, - type: CASType = .weak, - order: MemoryOrder = .relaxed) -> Bool - { - var expect = current - return loadCAS(current: &expect, future: future, type: type, orderSwap: order, orderLoad: .relaxed) - } -} diff --git a/Sources/Atomics/atomics-integer.swift b/Sources/Atomics/atomics-integer.swift index ce19f09..9cc75fd 100644 --- a/Sources/Atomics/atomics-integer.swift +++ b/Sources/Atomics/atomics-integer.swift @@ -9,81 +9,76 @@ import CAtomics -public struct AtomicInt -{ - @_versioned var val = CAtomicsInt() +@_exported import struct CAtomics.AtomicInt - public init(_ value: Int = 0) - { - CAtomicsIntInit(value, &val) - } +extension AtomicInt +{ + @available(*, unavailable, message: "If needed, use initialize(_ value: Int) after the default initializer, as long as the instance is unshared") + public init(_ value: Int) {} public var value: Int { @inline(__always) - mutating get { return CAtomicsIntLoad(&val, .relaxed) } + mutating get { return load(.relaxed) } } -} -extension AtomicInt -{ @inline(__always) public mutating func load(order: LoadMemoryOrder = .relaxed) -> Int { - return CAtomicsIntLoad(&val, order) + return load(order) } @inline(__always) public mutating func store(_ value: Int, order: StoreMemoryOrder = .relaxed) { - CAtomicsIntStore(value, &val, order) + store(value, order) } @inline(__always) public mutating func swap(_ value: Int, order: MemoryOrder = .relaxed) -> Int { - return CAtomicsIntSwap(value, &val, order) + return swap(value, order) } @inline(__always) @discardableResult public mutating func add(_ delta: Int, order: MemoryOrder = .relaxed) -> Int { - return CAtomicsIntAdd(delta, &val, order) + return fetch_add(delta, order) } @inline(__always) @discardableResult public mutating func subtract(_ delta: Int, order: MemoryOrder = .relaxed) -> Int { - return CAtomicsIntSub(delta, &val, order) + return fetch_sub(delta, order) } @inline(__always) @discardableResult public mutating func bitwiseOr(_ bits: Int, order: MemoryOrder = .relaxed) -> Int { - return CAtomicsIntOr(bits, &val, order) + return fetch_or(bits, order) } @inline(__always) @discardableResult public mutating func bitwiseXor(_ bits: Int, order: MemoryOrder = .relaxed) -> Int { - return CAtomicsIntXor(bits, &val, order) + return fetch_xor(bits, order) } @inline(__always) @discardableResult public mutating func bitwiseAnd(_ bits: Int, order: MemoryOrder = .relaxed) -> Int { - return CAtomicsIntAnd(bits, &val, order) + return fetch_and(bits, order) } @inline(__always) @discardableResult public mutating func increment(order: MemoryOrder = .relaxed) -> Int { - return CAtomicsIntAdd(1, &val, order) + return fetch_add(1, order) } @inline(__always) @discardableResult public mutating func decrement(order: MemoryOrder = .relaxed) -> Int { - return CAtomicsIntSub(1, &val, order) + return fetch_sub(1, order) } @inline(__always) @discardableResult @@ -92,94 +87,88 @@ extension AtomicInt orderSwap: MemoryOrder = .relaxed, orderLoad: LoadMemoryOrder = .relaxed) -> Bool { - return CAtomicsIntCAS(current, future, &val, type, orderSwap, orderLoad) + return loadCAS(current, future, type, orderSwap, orderLoad) } @inline(__always) @discardableResult public mutating func CAS(current: Int, future: Int, - type: CASType = .weak, + type: CASType = .strong, order: MemoryOrder = .relaxed) -> Bool { - var expect = current - return loadCAS(current: &expect, future: future, type: type, orderSwap: order, orderLoad: .relaxed) + return CAS(current, future, type, order) } } -public struct AtomicUInt -{ - @_versioned var val = CAtomicsUInt() +@_exported import struct CAtomics.AtomicUInt - public init(_ value: UInt = 0) - { - CAtomicsUIntInit(value, &val) - } +extension AtomicUInt +{ + @available(*, unavailable, message: "If needed, use initialize(_ value: UInt) after the default initializer, as long as the instance is unshared") + public init(_ value: UInt) {} public var value: UInt { @inline(__always) - mutating get { return CAtomicsUIntLoad(&val, .relaxed) } + mutating get { return load(.relaxed) } } -} -extension AtomicUInt -{ @inline(__always) public mutating func load(order: LoadMemoryOrder = .relaxed) -> UInt { - return CAtomicsUIntLoad(&val, order) + return load(order) } @inline(__always) public mutating func store(_ value: UInt, order: StoreMemoryOrder = .relaxed) { - CAtomicsUIntStore(value, &val, order) + store(value, order) } @inline(__always) public mutating func swap(_ value: UInt, order: MemoryOrder = .relaxed) -> UInt { - return CAtomicsUIntSwap(value, &val, order) + return swap(value, order) } @inline(__always) @discardableResult public mutating func add(_ delta: UInt, order: MemoryOrder = .relaxed) -> UInt { - return CAtomicsUIntAdd(delta, &val, order) + return fetch_add(delta, order) } @inline(__always) @discardableResult public mutating func subtract(_ delta: UInt, order: MemoryOrder = .relaxed) -> UInt { - return CAtomicsUIntSub(delta, &val, order) + return fetch_sub(delta, order) } @inline(__always) @discardableResult public mutating func bitwiseOr(_ bits: UInt, order: MemoryOrder = .relaxed) -> UInt { - return CAtomicsUIntOr(bits, &val, order) + return fetch_or(bits, order) } @inline(__always) @discardableResult public mutating func bitwiseXor(_ bits: UInt, order: MemoryOrder = .relaxed) -> UInt { - return CAtomicsUIntXor(bits, &val, order) + return fetch_xor(bits, order) } @inline(__always) @discardableResult public mutating func bitwiseAnd(_ bits: UInt, order: MemoryOrder = .relaxed) -> UInt { - return CAtomicsUIntAnd(bits, &val, order) + return fetch_and(bits, order) } @inline(__always) @discardableResult public mutating func increment(order: MemoryOrder = .relaxed) -> UInt { - return CAtomicsUIntAdd(1, &val, order) + return fetch_add(1, order) } @inline(__always) @discardableResult public mutating func decrement(order: MemoryOrder = .relaxed) -> UInt { - return CAtomicsUIntSub(1, &val, order) + return fetch_sub(1, order) } @inline(__always) @discardableResult @@ -188,94 +177,88 @@ extension AtomicUInt orderSwap: MemoryOrder = .relaxed, orderLoad: LoadMemoryOrder = .relaxed) -> Bool { - return CAtomicsUIntCAS(current, future, &val, type, orderSwap, orderLoad) + return loadCAS(current, future, type, orderSwap, orderLoad) } @inline(__always) @discardableResult public mutating func CAS(current: UInt, future: UInt, - type: CASType = .weak, + type: CASType = .strong, order: MemoryOrder = .relaxed) -> Bool { - var expect = current - return loadCAS(current: &expect, future: future, type: type, orderSwap: order, orderLoad: .relaxed) + return CAS(current, future, type, order) } } -public struct AtomicInt8 -{ - @_versioned var val = CAtomicsInt8() +@_exported import struct CAtomics.AtomicInt8 - public init(_ value: Int8 = 0) - { - CAtomicsInt8Init(value, &val) - } +extension AtomicInt8 +{ + @available(*, unavailable, message: "If needed, use initialize(_ value: Int8) after the default initializer, as long as the instance is unshared") + public init(_ value: Int8) {} public var value: Int8 { @inline(__always) - mutating get { return CAtomicsInt8Load(&val, .relaxed) } + mutating get { return load(.relaxed) } } -} -extension AtomicInt8 -{ @inline(__always) public mutating func load(order: LoadMemoryOrder = .relaxed) -> Int8 { - return CAtomicsInt8Load(&val, order) + return load(order) } @inline(__always) public mutating func store(_ value: Int8, order: StoreMemoryOrder = .relaxed) { - CAtomicsInt8Store(value, &val, order) + store(value, order) } @inline(__always) public mutating func swap(_ value: Int8, order: MemoryOrder = .relaxed) -> Int8 { - return CAtomicsInt8Swap(value, &val, order) + return swap(value, order) } @inline(__always) @discardableResult public mutating func add(_ delta: Int8, order: MemoryOrder = .relaxed) -> Int8 { - return CAtomicsInt8Add(delta, &val, order) + return fetch_add(delta, order) } @inline(__always) @discardableResult public mutating func subtract(_ delta: Int8, order: MemoryOrder = .relaxed) -> Int8 { - return CAtomicsInt8Sub(delta, &val, order) + return fetch_sub(delta, order) } @inline(__always) @discardableResult public mutating func bitwiseOr(_ bits: Int8, order: MemoryOrder = .relaxed) -> Int8 { - return CAtomicsInt8Or(bits, &val, order) + return fetch_or(bits, order) } @inline(__always) @discardableResult public mutating func bitwiseXor(_ bits: Int8, order: MemoryOrder = .relaxed) -> Int8 { - return CAtomicsInt8Xor(bits, &val, order) + return fetch_xor(bits, order) } @inline(__always) @discardableResult public mutating func bitwiseAnd(_ bits: Int8, order: MemoryOrder = .relaxed) -> Int8 { - return CAtomicsInt8And(bits, &val, order) + return fetch_and(bits, order) } @inline(__always) @discardableResult public mutating func increment(order: MemoryOrder = .relaxed) -> Int8 { - return CAtomicsInt8Add(1, &val, order) + return fetch_add(1, order) } @inline(__always) @discardableResult public mutating func decrement(order: MemoryOrder = .relaxed) -> Int8 { - return CAtomicsInt8Sub(1, &val, order) + return fetch_sub(1, order) } @inline(__always) @discardableResult @@ -284,94 +267,88 @@ extension AtomicInt8 orderSwap: MemoryOrder = .relaxed, orderLoad: LoadMemoryOrder = .relaxed) -> Bool { - return CAtomicsInt8CAS(current, future, &val, type, orderSwap, orderLoad) + return loadCAS(current, future, type, orderSwap, orderLoad) } @inline(__always) @discardableResult public mutating func CAS(current: Int8, future: Int8, - type: CASType = .weak, + type: CASType = .strong, order: MemoryOrder = .relaxed) -> Bool { - var expect = current - return loadCAS(current: &expect, future: future, type: type, orderSwap: order, orderLoad: .relaxed) + return CAS(current, future, type, order) } } -public struct AtomicUInt8 -{ - @_versioned var val = CAtomicsUInt8() +@_exported import struct CAtomics.AtomicUInt8 - public init(_ value: UInt8 = 0) - { - CAtomicsUInt8Init(value, &val) - } +extension AtomicUInt8 +{ + @available(*, unavailable, message: "If needed, use initialize(_ value: UInt8) after the default initializer, as long as the instance is unshared") + public init(_ value: UInt8) {} public var value: UInt8 { @inline(__always) - mutating get { return CAtomicsUInt8Load(&val, .relaxed) } + mutating get { return load(.relaxed) } } -} -extension AtomicUInt8 -{ @inline(__always) public mutating func load(order: LoadMemoryOrder = .relaxed) -> UInt8 { - return CAtomicsUInt8Load(&val, order) + return load(order) } @inline(__always) public mutating func store(_ value: UInt8, order: StoreMemoryOrder = .relaxed) { - CAtomicsUInt8Store(value, &val, order) + store(value, order) } @inline(__always) public mutating func swap(_ value: UInt8, order: MemoryOrder = .relaxed) -> UInt8 { - return CAtomicsUInt8Swap(value, &val, order) + return swap(value, order) } @inline(__always) @discardableResult public mutating func add(_ delta: UInt8, order: MemoryOrder = .relaxed) -> UInt8 { - return CAtomicsUInt8Add(delta, &val, order) + return fetch_add(delta, order) } @inline(__always) @discardableResult public mutating func subtract(_ delta: UInt8, order: MemoryOrder = .relaxed) -> UInt8 { - return CAtomicsUInt8Sub(delta, &val, order) + return fetch_sub(delta, order) } @inline(__always) @discardableResult public mutating func bitwiseOr(_ bits: UInt8, order: MemoryOrder = .relaxed) -> UInt8 { - return CAtomicsUInt8Or(bits, &val, order) + return fetch_or(bits, order) } @inline(__always) @discardableResult public mutating func bitwiseXor(_ bits: UInt8, order: MemoryOrder = .relaxed) -> UInt8 { - return CAtomicsUInt8Xor(bits, &val, order) + return fetch_xor(bits, order) } @inline(__always) @discardableResult public mutating func bitwiseAnd(_ bits: UInt8, order: MemoryOrder = .relaxed) -> UInt8 { - return CAtomicsUInt8And(bits, &val, order) + return fetch_and(bits, order) } @inline(__always) @discardableResult public mutating func increment(order: MemoryOrder = .relaxed) -> UInt8 { - return CAtomicsUInt8Add(1, &val, order) + return fetch_add(1, order) } @inline(__always) @discardableResult public mutating func decrement(order: MemoryOrder = .relaxed) -> UInt8 { - return CAtomicsUInt8Sub(1, &val, order) + return fetch_sub(1, order) } @inline(__always) @discardableResult @@ -380,94 +357,88 @@ extension AtomicUInt8 orderSwap: MemoryOrder = .relaxed, orderLoad: LoadMemoryOrder = .relaxed) -> Bool { - return CAtomicsUInt8CAS(current, future, &val, type, orderSwap, orderLoad) + return loadCAS(current, future, type, orderSwap, orderLoad) } @inline(__always) @discardableResult public mutating func CAS(current: UInt8, future: UInt8, - type: CASType = .weak, + type: CASType = .strong, order: MemoryOrder = .relaxed) -> Bool { - var expect = current - return loadCAS(current: &expect, future: future, type: type, orderSwap: order, orderLoad: .relaxed) + return CAS(current, future, type, order) } } -public struct AtomicInt16 -{ - @_versioned var val = CAtomicsInt16() +@_exported import struct CAtomics.AtomicInt16 - public init(_ value: Int16 = 0) - { - CAtomicsInt16Init(value, &val) - } +extension AtomicInt16 +{ + @available(*, unavailable, message: "If needed, use initialize(_ value: Int16) after the default initializer, as long as the instance is unshared") + public init(_ value: Int16) {} public var value: Int16 { @inline(__always) - mutating get { return CAtomicsInt16Load(&val, .relaxed) } + mutating get { return load(.relaxed) } } -} -extension AtomicInt16 -{ @inline(__always) public mutating func load(order: LoadMemoryOrder = .relaxed) -> Int16 { - return CAtomicsInt16Load(&val, order) + return load(order) } @inline(__always) public mutating func store(_ value: Int16, order: StoreMemoryOrder = .relaxed) { - CAtomicsInt16Store(value, &val, order) + store(value, order) } @inline(__always) public mutating func swap(_ value: Int16, order: MemoryOrder = .relaxed) -> Int16 { - return CAtomicsInt16Swap(value, &val, order) + return swap(value, order) } @inline(__always) @discardableResult public mutating func add(_ delta: Int16, order: MemoryOrder = .relaxed) -> Int16 { - return CAtomicsInt16Add(delta, &val, order) + return fetch_add(delta, order) } @inline(__always) @discardableResult public mutating func subtract(_ delta: Int16, order: MemoryOrder = .relaxed) -> Int16 { - return CAtomicsInt16Sub(delta, &val, order) + return fetch_sub(delta, order) } @inline(__always) @discardableResult public mutating func bitwiseOr(_ bits: Int16, order: MemoryOrder = .relaxed) -> Int16 { - return CAtomicsInt16Or(bits, &val, order) + return fetch_or(bits, order) } @inline(__always) @discardableResult public mutating func bitwiseXor(_ bits: Int16, order: MemoryOrder = .relaxed) -> Int16 { - return CAtomicsInt16Xor(bits, &val, order) + return fetch_xor(bits, order) } @inline(__always) @discardableResult public mutating func bitwiseAnd(_ bits: Int16, order: MemoryOrder = .relaxed) -> Int16 { - return CAtomicsInt16And(bits, &val, order) + return fetch_and(bits, order) } @inline(__always) @discardableResult public mutating func increment(order: MemoryOrder = .relaxed) -> Int16 { - return CAtomicsInt16Add(1, &val, order) + return fetch_add(1, order) } @inline(__always) @discardableResult public mutating func decrement(order: MemoryOrder = .relaxed) -> Int16 { - return CAtomicsInt16Sub(1, &val, order) + return fetch_sub(1, order) } @inline(__always) @discardableResult @@ -476,94 +447,88 @@ extension AtomicInt16 orderSwap: MemoryOrder = .relaxed, orderLoad: LoadMemoryOrder = .relaxed) -> Bool { - return CAtomicsInt16CAS(current, future, &val, type, orderSwap, orderLoad) + return loadCAS(current, future, type, orderSwap, orderLoad) } @inline(__always) @discardableResult public mutating func CAS(current: Int16, future: Int16, - type: CASType = .weak, + type: CASType = .strong, order: MemoryOrder = .relaxed) -> Bool { - var expect = current - return loadCAS(current: &expect, future: future, type: type, orderSwap: order, orderLoad: .relaxed) + return CAS(current, future, type, order) } } -public struct AtomicUInt16 -{ - @_versioned var val = CAtomicsUInt16() +@_exported import struct CAtomics.AtomicUInt16 - public init(_ value: UInt16 = 0) - { - CAtomicsUInt16Init(value, &val) - } +extension AtomicUInt16 +{ + @available(*, unavailable, message: "If needed, use initialize(_ value: UInt16) after the default initializer, as long as the instance is unshared") + public init(_ value: UInt16) {} public var value: UInt16 { @inline(__always) - mutating get { return CAtomicsUInt16Load(&val, .relaxed) } + mutating get { return load(.relaxed) } } -} -extension AtomicUInt16 -{ @inline(__always) public mutating func load(order: LoadMemoryOrder = .relaxed) -> UInt16 { - return CAtomicsUInt16Load(&val, order) + return load(order) } @inline(__always) public mutating func store(_ value: UInt16, order: StoreMemoryOrder = .relaxed) { - CAtomicsUInt16Store(value, &val, order) + store(value, order) } @inline(__always) public mutating func swap(_ value: UInt16, order: MemoryOrder = .relaxed) -> UInt16 { - return CAtomicsUInt16Swap(value, &val, order) + return swap(value, order) } @inline(__always) @discardableResult public mutating func add(_ delta: UInt16, order: MemoryOrder = .relaxed) -> UInt16 { - return CAtomicsUInt16Add(delta, &val, order) + return fetch_add(delta, order) } @inline(__always) @discardableResult public mutating func subtract(_ delta: UInt16, order: MemoryOrder = .relaxed) -> UInt16 { - return CAtomicsUInt16Sub(delta, &val, order) + return fetch_sub(delta, order) } @inline(__always) @discardableResult public mutating func bitwiseOr(_ bits: UInt16, order: MemoryOrder = .relaxed) -> UInt16 { - return CAtomicsUInt16Or(bits, &val, order) + return fetch_or(bits, order) } @inline(__always) @discardableResult public mutating func bitwiseXor(_ bits: UInt16, order: MemoryOrder = .relaxed) -> UInt16 { - return CAtomicsUInt16Xor(bits, &val, order) + return fetch_xor(bits, order) } @inline(__always) @discardableResult public mutating func bitwiseAnd(_ bits: UInt16, order: MemoryOrder = .relaxed) -> UInt16 { - return CAtomicsUInt16And(bits, &val, order) + return fetch_and(bits, order) } @inline(__always) @discardableResult public mutating func increment(order: MemoryOrder = .relaxed) -> UInt16 { - return CAtomicsUInt16Add(1, &val, order) + return fetch_add(1, order) } @inline(__always) @discardableResult public mutating func decrement(order: MemoryOrder = .relaxed) -> UInt16 { - return CAtomicsUInt16Sub(1, &val, order) + return fetch_sub(1, order) } @inline(__always) @discardableResult @@ -572,94 +537,88 @@ extension AtomicUInt16 orderSwap: MemoryOrder = .relaxed, orderLoad: LoadMemoryOrder = .relaxed) -> Bool { - return CAtomicsUInt16CAS(current, future, &val, type, orderSwap, orderLoad) + return loadCAS(current, future, type, orderSwap, orderLoad) } @inline(__always) @discardableResult public mutating func CAS(current: UInt16, future: UInt16, - type: CASType = .weak, + type: CASType = .strong, order: MemoryOrder = .relaxed) -> Bool { - var expect = current - return loadCAS(current: &expect, future: future, type: type, orderSwap: order, orderLoad: .relaxed) + return CAS(current, future, type, order) } } -public struct AtomicInt32 -{ - @_versioned var val = CAtomicsInt32() +@_exported import struct CAtomics.AtomicInt32 - public init(_ value: Int32 = 0) - { - CAtomicsInt32Init(value, &val) - } +extension AtomicInt32 +{ + @available(*, unavailable, message: "If needed, use initialize(_ value: Int32) after the default initializer, as long as the instance is unshared") + public init(_ value: Int32) {} public var value: Int32 { @inline(__always) - mutating get { return CAtomicsInt32Load(&val, .relaxed) } + mutating get { return load(.relaxed) } } -} -extension AtomicInt32 -{ @inline(__always) public mutating func load(order: LoadMemoryOrder = .relaxed) -> Int32 { - return CAtomicsInt32Load(&val, order) + return load(order) } @inline(__always) public mutating func store(_ value: Int32, order: StoreMemoryOrder = .relaxed) { - CAtomicsInt32Store(value, &val, order) + store(value, order) } @inline(__always) public mutating func swap(_ value: Int32, order: MemoryOrder = .relaxed) -> Int32 { - return CAtomicsInt32Swap(value, &val, order) + return swap(value, order) } @inline(__always) @discardableResult public mutating func add(_ delta: Int32, order: MemoryOrder = .relaxed) -> Int32 { - return CAtomicsInt32Add(delta, &val, order) + return fetch_add(delta, order) } @inline(__always) @discardableResult public mutating func subtract(_ delta: Int32, order: MemoryOrder = .relaxed) -> Int32 { - return CAtomicsInt32Sub(delta, &val, order) + return fetch_sub(delta, order) } @inline(__always) @discardableResult public mutating func bitwiseOr(_ bits: Int32, order: MemoryOrder = .relaxed) -> Int32 { - return CAtomicsInt32Or(bits, &val, order) + return fetch_or(bits, order) } @inline(__always) @discardableResult public mutating func bitwiseXor(_ bits: Int32, order: MemoryOrder = .relaxed) -> Int32 { - return CAtomicsInt32Xor(bits, &val, order) + return fetch_xor(bits, order) } @inline(__always) @discardableResult public mutating func bitwiseAnd(_ bits: Int32, order: MemoryOrder = .relaxed) -> Int32 { - return CAtomicsInt32And(bits, &val, order) + return fetch_and(bits, order) } @inline(__always) @discardableResult public mutating func increment(order: MemoryOrder = .relaxed) -> Int32 { - return CAtomicsInt32Add(1, &val, order) + return fetch_add(1, order) } @inline(__always) @discardableResult public mutating func decrement(order: MemoryOrder = .relaxed) -> Int32 { - return CAtomicsInt32Sub(1, &val, order) + return fetch_sub(1, order) } @inline(__always) @discardableResult @@ -668,94 +627,88 @@ extension AtomicInt32 orderSwap: MemoryOrder = .relaxed, orderLoad: LoadMemoryOrder = .relaxed) -> Bool { - return CAtomicsInt32CAS(current, future, &val, type, orderSwap, orderLoad) + return loadCAS(current, future, type, orderSwap, orderLoad) } @inline(__always) @discardableResult public mutating func CAS(current: Int32, future: Int32, - type: CASType = .weak, + type: CASType = .strong, order: MemoryOrder = .relaxed) -> Bool { - var expect = current - return loadCAS(current: &expect, future: future, type: type, orderSwap: order, orderLoad: .relaxed) + return CAS(current, future, type, order) } } -public struct AtomicUInt32 -{ - @_versioned var val = CAtomicsUInt32() +@_exported import struct CAtomics.AtomicUInt32 - public init(_ value: UInt32 = 0) - { - CAtomicsUInt32Init(value, &val) - } +extension AtomicUInt32 +{ + @available(*, unavailable, message: "If needed, use initialize(_ value: UInt32) after the default initializer, as long as the instance is unshared") + public init(_ value: UInt32) {} public var value: UInt32 { @inline(__always) - mutating get { return CAtomicsUInt32Load(&val, .relaxed) } + mutating get { return load(.relaxed) } } -} -extension AtomicUInt32 -{ @inline(__always) public mutating func load(order: LoadMemoryOrder = .relaxed) -> UInt32 { - return CAtomicsUInt32Load(&val, order) + return load(order) } @inline(__always) public mutating func store(_ value: UInt32, order: StoreMemoryOrder = .relaxed) { - CAtomicsUInt32Store(value, &val, order) + store(value, order) } @inline(__always) public mutating func swap(_ value: UInt32, order: MemoryOrder = .relaxed) -> UInt32 { - return CAtomicsUInt32Swap(value, &val, order) + return swap(value, order) } @inline(__always) @discardableResult public mutating func add(_ delta: UInt32, order: MemoryOrder = .relaxed) -> UInt32 { - return CAtomicsUInt32Add(delta, &val, order) + return fetch_add(delta, order) } @inline(__always) @discardableResult public mutating func subtract(_ delta: UInt32, order: MemoryOrder = .relaxed) -> UInt32 { - return CAtomicsUInt32Sub(delta, &val, order) + return fetch_sub(delta, order) } @inline(__always) @discardableResult public mutating func bitwiseOr(_ bits: UInt32, order: MemoryOrder = .relaxed) -> UInt32 { - return CAtomicsUInt32Or(bits, &val, order) + return fetch_or(bits, order) } @inline(__always) @discardableResult public mutating func bitwiseXor(_ bits: UInt32, order: MemoryOrder = .relaxed) -> UInt32 { - return CAtomicsUInt32Xor(bits, &val, order) + return fetch_xor(bits, order) } @inline(__always) @discardableResult public mutating func bitwiseAnd(_ bits: UInt32, order: MemoryOrder = .relaxed) -> UInt32 { - return CAtomicsUInt32And(bits, &val, order) + return fetch_and(bits, order) } @inline(__always) @discardableResult public mutating func increment(order: MemoryOrder = .relaxed) -> UInt32 { - return CAtomicsUInt32Add(1, &val, order) + return fetch_add(1, order) } @inline(__always) @discardableResult public mutating func decrement(order: MemoryOrder = .relaxed) -> UInt32 { - return CAtomicsUInt32Sub(1, &val, order) + return fetch_sub(1, order) } @inline(__always) @discardableResult @@ -764,94 +717,88 @@ extension AtomicUInt32 orderSwap: MemoryOrder = .relaxed, orderLoad: LoadMemoryOrder = .relaxed) -> Bool { - return CAtomicsUInt32CAS(current, future, &val, type, orderSwap, orderLoad) + return loadCAS(current, future, type, orderSwap, orderLoad) } @inline(__always) @discardableResult public mutating func CAS(current: UInt32, future: UInt32, - type: CASType = .weak, + type: CASType = .strong, order: MemoryOrder = .relaxed) -> Bool { - var expect = current - return loadCAS(current: &expect, future: future, type: type, orderSwap: order, orderLoad: .relaxed) + return CAS(current, future, type, order) } } -public struct AtomicInt64 -{ - @_versioned var val = CAtomicsInt64() +@_exported import struct CAtomics.AtomicInt64 - public init(_ value: Int64 = 0) - { - CAtomicsInt64Init(value, &val) - } +extension AtomicInt64 +{ + @available(*, unavailable, message: "If needed, use initialize(_ value: Int64) after the default initializer, as long as the instance is unshared") + public init(_ value: Int64) {} public var value: Int64 { @inline(__always) - mutating get { return CAtomicsInt64Load(&val, .relaxed) } + mutating get { return load(.relaxed) } } -} -extension AtomicInt64 -{ @inline(__always) public mutating func load(order: LoadMemoryOrder = .relaxed) -> Int64 { - return CAtomicsInt64Load(&val, order) + return load(order) } @inline(__always) public mutating func store(_ value: Int64, order: StoreMemoryOrder = .relaxed) { - CAtomicsInt64Store(value, &val, order) + store(value, order) } @inline(__always) public mutating func swap(_ value: Int64, order: MemoryOrder = .relaxed) -> Int64 { - return CAtomicsInt64Swap(value, &val, order) + return swap(value, order) } @inline(__always) @discardableResult public mutating func add(_ delta: Int64, order: MemoryOrder = .relaxed) -> Int64 { - return CAtomicsInt64Add(delta, &val, order) + return fetch_add(delta, order) } @inline(__always) @discardableResult public mutating func subtract(_ delta: Int64, order: MemoryOrder = .relaxed) -> Int64 { - return CAtomicsInt64Sub(delta, &val, order) + return fetch_sub(delta, order) } @inline(__always) @discardableResult public mutating func bitwiseOr(_ bits: Int64, order: MemoryOrder = .relaxed) -> Int64 { - return CAtomicsInt64Or(bits, &val, order) + return fetch_or(bits, order) } @inline(__always) @discardableResult public mutating func bitwiseXor(_ bits: Int64, order: MemoryOrder = .relaxed) -> Int64 { - return CAtomicsInt64Xor(bits, &val, order) + return fetch_xor(bits, order) } @inline(__always) @discardableResult public mutating func bitwiseAnd(_ bits: Int64, order: MemoryOrder = .relaxed) -> Int64 { - return CAtomicsInt64And(bits, &val, order) + return fetch_and(bits, order) } @inline(__always) @discardableResult public mutating func increment(order: MemoryOrder = .relaxed) -> Int64 { - return CAtomicsInt64Add(1, &val, order) + return fetch_add(1, order) } @inline(__always) @discardableResult public mutating func decrement(order: MemoryOrder = .relaxed) -> Int64 { - return CAtomicsInt64Sub(1, &val, order) + return fetch_sub(1, order) } @inline(__always) @discardableResult @@ -860,94 +807,88 @@ extension AtomicInt64 orderSwap: MemoryOrder = .relaxed, orderLoad: LoadMemoryOrder = .relaxed) -> Bool { - return CAtomicsInt64CAS(current, future, &val, type, orderSwap, orderLoad) + return loadCAS(current, future, type, orderSwap, orderLoad) } @inline(__always) @discardableResult public mutating func CAS(current: Int64, future: Int64, - type: CASType = .weak, + type: CASType = .strong, order: MemoryOrder = .relaxed) -> Bool { - var expect = current - return loadCAS(current: &expect, future: future, type: type, orderSwap: order, orderLoad: .relaxed) + return CAS(current, future, type, order) } } -public struct AtomicUInt64 -{ - @_versioned var val = CAtomicsUInt64() +@_exported import struct CAtomics.AtomicUInt64 - public init(_ value: UInt64 = 0) - { - CAtomicsUInt64Init(value, &val) - } +extension AtomicUInt64 +{ + @available(*, unavailable, message: "If needed, use initialize(_ value: UInt64) after the default initializer, as long as the instance is unshared") + public init(_ value: UInt64) {} public var value: UInt64 { @inline(__always) - mutating get { return CAtomicsUInt64Load(&val, .relaxed) } + mutating get { return load(.relaxed) } } -} -extension AtomicUInt64 -{ @inline(__always) public mutating func load(order: LoadMemoryOrder = .relaxed) -> UInt64 { - return CAtomicsUInt64Load(&val, order) + return load(order) } @inline(__always) public mutating func store(_ value: UInt64, order: StoreMemoryOrder = .relaxed) { - CAtomicsUInt64Store(value, &val, order) + store(value, order) } @inline(__always) public mutating func swap(_ value: UInt64, order: MemoryOrder = .relaxed) -> UInt64 { - return CAtomicsUInt64Swap(value, &val, order) + return swap(value, order) } @inline(__always) @discardableResult public mutating func add(_ delta: UInt64, order: MemoryOrder = .relaxed) -> UInt64 { - return CAtomicsUInt64Add(delta, &val, order) + return fetch_add(delta, order) } @inline(__always) @discardableResult public mutating func subtract(_ delta: UInt64, order: MemoryOrder = .relaxed) -> UInt64 { - return CAtomicsUInt64Sub(delta, &val, order) + return fetch_sub(delta, order) } @inline(__always) @discardableResult public mutating func bitwiseOr(_ bits: UInt64, order: MemoryOrder = .relaxed) -> UInt64 { - return CAtomicsUInt64Or(bits, &val, order) + return fetch_or(bits, order) } @inline(__always) @discardableResult public mutating func bitwiseXor(_ bits: UInt64, order: MemoryOrder = .relaxed) -> UInt64 { - return CAtomicsUInt64Xor(bits, &val, order) + return fetch_xor(bits, order) } @inline(__always) @discardableResult public mutating func bitwiseAnd(_ bits: UInt64, order: MemoryOrder = .relaxed) -> UInt64 { - return CAtomicsUInt64And(bits, &val, order) + return fetch_and(bits, order) } @inline(__always) @discardableResult public mutating func increment(order: MemoryOrder = .relaxed) -> UInt64 { - return CAtomicsUInt64Add(1, &val, order) + return fetch_add(1, order) } @inline(__always) @discardableResult public mutating func decrement(order: MemoryOrder = .relaxed) -> UInt64 { - return CAtomicsUInt64Sub(1, &val, order) + return fetch_sub(1, order) } @inline(__always) @discardableResult @@ -956,15 +897,80 @@ extension AtomicUInt64 orderSwap: MemoryOrder = .relaxed, orderLoad: LoadMemoryOrder = .relaxed) -> Bool { - return CAtomicsUInt64CAS(current, future, &val, type, orderSwap, orderLoad) + return loadCAS(current, future, type, orderSwap, orderLoad) } @inline(__always) @discardableResult public mutating func CAS(current: UInt64, future: UInt64, - type: CASType = .weak, + type: CASType = .strong, + order: MemoryOrder = .relaxed) -> Bool + { + return CAS(current, future, type, order) + } +} + +@_exported import struct CAtomics.AtomicBool + +extension AtomicBool +{ + @available(*, unavailable, message: "If needed, use initialize(_ value: Bool) after the default initializer, as long as the instance is unshared") + public init(_ value: Bool) {} + + public var value: Bool { + @inline(__always) + mutating get { return load(.relaxed) } + } + + @inline(__always) + public mutating func load(order: LoadMemoryOrder = .relaxed) -> Bool + { + return load(order) + } + + @inline(__always) + public mutating func store(_ value: Bool, order: StoreMemoryOrder = .relaxed) + { + store(value, order) + } + + @inline(__always) + public mutating func swap(_ value: Bool, order: MemoryOrder = .relaxed) -> Bool + { + return swap(value, order) + } + + @inline(__always) @discardableResult + public mutating func or(_ value: Bool, order: MemoryOrder = .relaxed) -> Bool + { + return fetch_or(value, order) + } + + @inline(__always) @discardableResult + public mutating func xor(_ value: Bool, order: MemoryOrder = .relaxed) -> Bool + { + return fetch_xor(value, order) + } + + @inline(__always) @discardableResult + public mutating func and(_ value: Bool, order: MemoryOrder = .relaxed) -> Bool + { + return fetch_and(value, order) + } + + @inline(__always) @discardableResult + public mutating func loadCAS(current: UnsafeMutablePointer, future: Bool, + type: CASType = .weak, + orderSwap: MemoryOrder = .relaxed, + orderLoad: LoadMemoryOrder = .relaxed) -> Bool + { + return loadCAS(current, future, type, orderSwap, orderLoad) + } + + @inline(__always) @discardableResult + public mutating func CAS(current: Bool, future: Bool, + type: CASType = .strong, order: MemoryOrder = .relaxed) -> Bool { - var expect = current - return loadCAS(current: &expect, future: future, type: type, orderSwap: order, orderLoad: .relaxed) + return CAS(current, future, type, order) } } diff --git a/Sources/Atomics/atomics-integer.swift.gyb b/Sources/Atomics/atomics-integer.swift.gyb index 68b6d2e..498c5a6 100644 --- a/Sources/Atomics/atomics-integer.swift.gyb +++ b/Sources/Atomics/atomics-integer.swift.gyb @@ -8,77 +8,81 @@ // import CAtomics -% for IntType in ['Int', 'UInt', 'Int8', 'UInt8', 'Int16', 'UInt16', 'Int32', 'UInt32', 'Int64', 'UInt64']: +% for IntType in ['Int', 'UInt', 'Int8', 'UInt8', 'Int16', 'UInt16', 'Int32', 'UInt32', 'Int64', 'UInt64', 'Bool']: % AtomicType = 'Atomic' + IntType -% CAtomicsType = 'CAtomics' + IntType -public struct ${AtomicType} -{ - @_versioned var val = ${CAtomicsType}() +@_exported import struct CAtomics.${AtomicType} - public init(_ value: ${IntType} = 0) - { - ${CAtomicsType}Init(value, &val) - } +extension ${AtomicType} +{ + @available(*, unavailable, message: "If needed, use initialize(_ value: ${IntType}) after the default initializer, as long as the instance is unshared") + public init(_ value: ${IntType}) {} public var value: ${IntType} { @inline(__always) - mutating get { return ${CAtomicsType}Load(&val, .relaxed) } + mutating get { return load(.relaxed) } } -} -extension ${AtomicType} -{ @inline(__always) public mutating func load(order: LoadMemoryOrder = .relaxed) -> ${IntType} { - return ${CAtomicsType}Load(&val, order) + return load(order) } @inline(__always) public mutating func store(_ value: ${IntType}, order: StoreMemoryOrder = .relaxed) { - ${CAtomicsType}Store(value, &val, order) + store(value, order) } @inline(__always) public mutating func swap(_ value: ${IntType}, order: MemoryOrder = .relaxed) -> ${IntType} { - return ${CAtomicsType}Swap(value, &val, order) + return swap(value, order) + } + +% if IntType == 'Bool': +% for (rmwMethod, rmwFunc, rmwParam) in [('or', 'fetch_or', 'value'), ('xor', 'fetch_xor', 'value'), ('and', 'fetch_and', 'value')]: + @inline(__always) @discardableResult + public mutating func ${rmwMethod}(_ ${rmwParam}: ${IntType}, order: MemoryOrder = .relaxed) -> ${IntType} + { + return ${rmwFunc}(${rmwParam}, order) } -% for (rmwMethod, rmwFunc, rmwParam) in [('add', 'Add', 'delta'), ('subtract', 'Sub', 'delta'), ('bitwiseOr', 'Or', 'bits'), ('bitwiseXor', 'Xor', 'bits'), ('bitwiseAnd', 'And', 'bits')]: +% end # for +% else: +% for (rmwMethod, rmwFunc, rmwParam) in [('add', 'fetch_add', 'delta'), ('subtract', 'fetch_sub', 'delta'), ('bitwiseOr', 'fetch_or', 'bits'), ('bitwiseXor', 'fetch_xor', 'bits'), ('bitwiseAnd', 'fetch_and', 'bits')]: @inline(__always) @discardableResult public mutating func ${rmwMethod}(_ ${rmwParam}: ${IntType}, order: MemoryOrder = .relaxed) -> ${IntType} { - return ${CAtomicsType}${rmwFunc}(${rmwParam}, &val, order) + return ${rmwFunc}(${rmwParam}, order) } -% end -% for (inc, op) in [('increment', 'Add'), ('decrement', 'Sub')]: +% end # for +% for (inc, op) in [('increment', 'fetch_add'), ('decrement', 'fetch_sub')]: @inline(__always) @discardableResult public mutating func ${inc}(order: MemoryOrder = .relaxed) -> ${IntType} { - return ${CAtomicsType}${op}(1, &val, order) + return ${op}(1, order) } -% end +% end # for +% end # if IntType == 'Bool' @inline(__always) @discardableResult public mutating func loadCAS(current: UnsafeMutablePointer<${IntType}>, future: ${IntType}, type: CASType = .weak, orderSwap: MemoryOrder = .relaxed, orderLoad: LoadMemoryOrder = .relaxed) -> Bool { - return ${CAtomicsType}CAS(current, future, &val, type, orderSwap, orderLoad) + return loadCAS(current, future, type, orderSwap, orderLoad) } @inline(__always) @discardableResult public mutating func CAS(current: ${IntType}, future: ${IntType}, - type: CASType = .weak, + type: CASType = .strong, order: MemoryOrder = .relaxed) -> Bool { - var expect = current - return loadCAS(current: &expect, future: future, type: type, orderSwap: order, orderLoad: .relaxed) + return CAS(current, future, type, order) } } % end # for AtomicType diff --git a/Sources/Atomics/atomics-pointer.swift b/Sources/Atomics/atomics-pointer.swift index 88ff2bc..8d47d0a 100644 --- a/Sources/Atomics/atomics-pointer.swift +++ b/Sources/Atomics/atomics-pointer.swift @@ -9,262 +9,258 @@ import CAtomics -public struct AtomicMutableRawPointer +public struct AtomicPointer { - @_versioned var ptr = CAtomicsMutablePointer() + @_versioned var ptr = AtomicRawPointer() - public init(_ pointer: UnsafeMutableRawPointer? = nil) + public init(_ pointer: UnsafePointer? = nil) { - CAtomicsMutablePointerInit(UnsafeMutableRawPointer(pointer), &ptr) + self.initialize(pointer) } - public var pointer: UnsafeMutableRawPointer? { + public mutating func initialize(_ pointer: UnsafePointer?) + { + ptr.initialize(UnsafeRawPointer(pointer)) + } + + public var pointer: UnsafePointer? { @inline(__always) mutating get { - return UnsafeMutableRawPointer(CAtomicsMutablePointerLoad(&ptr, .relaxed)) + return UnsafePointer(ptr.load(.relaxed)?.assumingMemoryBound(to: Pointee.self)) } } @inline(__always) - public mutating func load(order: LoadMemoryOrder = .sequential) -> UnsafeMutableRawPointer? + public mutating func load(order: LoadMemoryOrder = .sequential) -> UnsafePointer? { - return UnsafeMutableRawPointer(CAtomicsMutablePointerLoad(&ptr, order)) + return UnsafePointer(ptr.load(order)?.assumingMemoryBound(to: Pointee.self)) } @inline(__always) - public mutating func store(_ pointer: UnsafeMutableRawPointer?, order: StoreMemoryOrder = .sequential) + public mutating func store(_ pointer: UnsafePointer?, order: StoreMemoryOrder = .sequential) { - CAtomicsMutablePointerStore(UnsafeMutableRawPointer(pointer), &ptr, order) + ptr.store(UnsafeRawPointer(pointer), order) } @inline(__always) - public mutating func swap(_ pointer: UnsafeMutableRawPointer?, order: MemoryOrder = .sequential) -> UnsafeMutableRawPointer? + public mutating func swap(_ pointer: UnsafePointer?, order: MemoryOrder = .sequential) -> UnsafePointer? { - return UnsafeMutableRawPointer(CAtomicsMutablePointerSwap(UnsafeMutableRawPointer(pointer), &ptr, order)) + return UnsafePointer(ptr.swap(UnsafeRawPointer(pointer), order)?.assumingMemoryBound(to: Pointee.self)) } @inline(__always) @discardableResult - public mutating func loadCAS(current: UnsafeMutablePointer, - future: UnsafeMutableRawPointer?, + public mutating func loadCAS(current: UnsafeMutablePointer?>, + future: UnsafePointer?, type: CASType = .weak, orderSwap: MemoryOrder = .sequential, orderLoad: LoadMemoryOrder = .sequential) -> Bool { - return current.withMemoryRebound(to: Optional.self, capacity: 1) { - CAtomicsMutablePointerCAS($0, UnsafeMutableRawPointer(future), &ptr, type, orderSwap, orderLoad) + return current.withMemoryRebound(to: Optional.self, capacity: 1) { + ptr.loadCAS($0, UnsafeRawPointer(future), type, orderSwap, orderLoad) } } @inline(__always) @discardableResult - public mutating func CAS(current: UnsafeMutableRawPointer?, future: UnsafeMutableRawPointer?, - type: CASType = .weak, + public mutating func CAS(current: UnsafePointer?, future: UnsafePointer?, + type: CASType = .strong, order: MemoryOrder = .sequential) -> Bool { - var expect = current - return loadCAS(current: &expect, future: future, type: type, orderSwap: order, orderLoad: .relaxed) + return ptr.CAS(current, future, type, order) } } -public struct AtomicRawPointer +public struct AtomicMutablePointer { - @_versioned var ptr = CAtomicsPointer() + @_versioned var ptr = AtomicMutableRawPointer() + + public init(_ pointer: UnsafeMutablePointer? = nil) + { + self.initialize(pointer) + } - public init(_ pointer: UnsafeRawPointer? = nil) + public mutating func initialize(_ pointer: UnsafeMutablePointer?) { - CAtomicsPointerInit(UnsafeRawPointer(pointer), &ptr) + ptr.initialize(UnsafeMutableRawPointer(pointer)) } - public var pointer: UnsafeRawPointer? { + public var pointer: UnsafeMutablePointer? { @inline(__always) mutating get { - return UnsafeRawPointer(CAtomicsPointerLoad(&ptr, .relaxed)) + return UnsafeMutablePointer(ptr.load(.relaxed)?.assumingMemoryBound(to: Pointee.self)) } } @inline(__always) - public mutating func load(order: LoadMemoryOrder = .sequential) -> UnsafeRawPointer? + public mutating func load(order: LoadMemoryOrder = .sequential) -> UnsafeMutablePointer? { - return UnsafeRawPointer(CAtomicsPointerLoad(&ptr, order)) + return UnsafeMutablePointer(ptr.load(order)?.assumingMemoryBound(to: Pointee.self)) } @inline(__always) - public mutating func store(_ pointer: UnsafeRawPointer?, order: StoreMemoryOrder = .sequential) + public mutating func store(_ pointer: UnsafeMutablePointer?, order: StoreMemoryOrder = .sequential) { - CAtomicsPointerStore(UnsafeRawPointer(pointer), &ptr, order) + ptr.store(UnsafeMutableRawPointer(pointer), order) } @inline(__always) - public mutating func swap(_ pointer: UnsafeRawPointer?, order: MemoryOrder = .sequential) -> UnsafeRawPointer? + public mutating func swap(_ pointer: UnsafeMutablePointer?, order: MemoryOrder = .sequential) -> UnsafeMutablePointer? { - return UnsafeRawPointer(CAtomicsPointerSwap(UnsafeRawPointer(pointer), &ptr, order)) + return UnsafeMutablePointer(ptr.swap(UnsafeMutableRawPointer(pointer), order)?.assumingMemoryBound(to: Pointee.self)) } @inline(__always) @discardableResult - public mutating func loadCAS(current: UnsafeMutablePointer, - future: UnsafeRawPointer?, + public mutating func loadCAS(current: UnsafeMutablePointer?>, + future: UnsafeMutablePointer?, type: CASType = .weak, orderSwap: MemoryOrder = .sequential, orderLoad: LoadMemoryOrder = .sequential) -> Bool { - return current.withMemoryRebound(to: Optional.self, capacity: 1) { - CAtomicsPointerCAS($0, UnsafeRawPointer(future), &ptr, type, orderSwap, orderLoad) + return current.withMemoryRebound(to: Optional.self, capacity: 1) { + ptr.loadCAS($0, UnsafeMutableRawPointer(future), type, orderSwap, orderLoad) } } @inline(__always) @discardableResult - public mutating func CAS(current: UnsafeRawPointer?, future: UnsafeRawPointer?, - type: CASType = .weak, + public mutating func CAS(current: UnsafeMutablePointer?, future: UnsafeMutablePointer?, + type: CASType = .strong, order: MemoryOrder = .sequential) -> Bool { - var expect = current - return loadCAS(current: &expect, future: future, type: type, orderSwap: order, orderLoad: .relaxed) + return ptr.CAS(current, future, type, order) } } -public struct AtomicMutablePointer -{ - @_versioned var ptr = CAtomicsMutablePointer() +@_exported import struct CAtomics.AtomicRawPointer - public init(_ pointer: UnsafeMutablePointer? = nil) - { - CAtomicsMutablePointerInit(UnsafeMutableRawPointer(pointer), &ptr) - } +extension AtomicRawPointer +{ + @available(*, unavailable, message: "If needed, use initialize(_ pointer: UnsafeRawPointer?) after the default initializer, as long as the instance is unshared") + public init(_ pointer: UnsafeRawPointer?) {} - public var pointer: UnsafeMutablePointer? { + public var pointer: UnsafeRawPointer? { @inline(__always) mutating get { - return UnsafeMutablePointer(CAtomicsMutablePointerLoad(&ptr, .relaxed)?.assumingMemoryBound(to: Pointee.self)) + return load(.relaxed) } } @inline(__always) - public mutating func load(order: LoadMemoryOrder = .sequential) -> UnsafeMutablePointer? + public mutating func load(order: LoadMemoryOrder = .sequential) -> UnsafeRawPointer? { - return UnsafeMutablePointer(CAtomicsMutablePointerLoad(&ptr, order)?.assumingMemoryBound(to: Pointee.self)) + return load(order) } @inline(__always) - public mutating func store(_ pointer: UnsafeMutablePointer?, order: StoreMemoryOrder = .sequential) + public mutating func store(_ pointer: UnsafeRawPointer?, order: StoreMemoryOrder = .sequential) { - CAtomicsMutablePointerStore(UnsafeMutableRawPointer(pointer), &ptr, order) + store(pointer, order) } @inline(__always) - public mutating func swap(_ pointer: UnsafeMutablePointer?, order: MemoryOrder = .sequential) -> UnsafeMutablePointer? + public mutating func swap(_ pointer: UnsafeRawPointer?, order: MemoryOrder = .sequential) -> UnsafeRawPointer? { - return UnsafeMutablePointer(CAtomicsMutablePointerSwap(UnsafeMutableRawPointer(pointer), &ptr, order)?.assumingMemoryBound(to: Pointee.self)) + return swap(pointer, order) } @inline(__always) @discardableResult - public mutating func loadCAS(current: UnsafeMutablePointer?>, - future: UnsafeMutablePointer?, + public mutating func loadCAS(current: UnsafeMutablePointer, + future: UnsafeRawPointer?, type: CASType = .weak, orderSwap: MemoryOrder = .sequential, orderLoad: LoadMemoryOrder = .sequential) -> Bool { - return current.withMemoryRebound(to: Optional.self, capacity: 1) { - CAtomicsMutablePointerCAS($0, UnsafeMutableRawPointer(future), &ptr, type, orderSwap, orderLoad) - } + return loadCAS(current, future, type, orderSwap, orderLoad) } @inline(__always) @discardableResult - public mutating func CAS(current: UnsafeMutablePointer?, future: UnsafeMutablePointer?, - type: CASType = .weak, + public mutating func CAS(current: UnsafeRawPointer?, future: UnsafeRawPointer?, + type: CASType = .strong, order: MemoryOrder = .sequential) -> Bool { - var expect = current - return loadCAS(current: &expect, future: future, type: type, orderSwap: order, orderLoad: .relaxed) + return CAS(current, future, type, order) } } -public struct AtomicPointer -{ - @_versioned var ptr = CAtomicsPointer() +@_exported import struct CAtomics.AtomicMutableRawPointer - public init(_ pointer: UnsafePointer? = nil) - { - CAtomicsPointerInit(UnsafeRawPointer(pointer), &ptr) - } +extension AtomicMutableRawPointer +{ + @available(*, unavailable, message: "If needed, use initialize(_ pointer: UnsafeMutableRawPointer?) after the default initializer, as long as the instance is unshared") + public init(_ pointer: UnsafeMutableRawPointer?) {} - public var pointer: UnsafePointer? { + public var pointer: UnsafeMutableRawPointer? { @inline(__always) mutating get { - return UnsafePointer(CAtomicsPointerLoad(&ptr, .relaxed)?.assumingMemoryBound(to: Pointee.self)) + return load(.relaxed) } } @inline(__always) - public mutating func load(order: LoadMemoryOrder = .sequential) -> UnsafePointer? + public mutating func load(order: LoadMemoryOrder = .sequential) -> UnsafeMutableRawPointer? { - return UnsafePointer(CAtomicsPointerLoad(&ptr, order)?.assumingMemoryBound(to: Pointee.self)) + return load(order) } @inline(__always) - public mutating func store(_ pointer: UnsafePointer?, order: StoreMemoryOrder = .sequential) + public mutating func store(_ pointer: UnsafeMutableRawPointer?, order: StoreMemoryOrder = .sequential) { - CAtomicsPointerStore(UnsafeRawPointer(pointer), &ptr, order) + store(pointer, order) } @inline(__always) - public mutating func swap(_ pointer: UnsafePointer?, order: MemoryOrder = .sequential) -> UnsafePointer? + public mutating func swap(_ pointer: UnsafeMutableRawPointer?, order: MemoryOrder = .sequential) -> UnsafeMutableRawPointer? { - return UnsafePointer(CAtomicsPointerSwap(UnsafeRawPointer(pointer), &ptr, order)?.assumingMemoryBound(to: Pointee.self)) + return swap(pointer, order) } @inline(__always) @discardableResult - public mutating func loadCAS(current: UnsafeMutablePointer?>, - future: UnsafePointer?, + public mutating func loadCAS(current: UnsafeMutablePointer, + future: UnsafeMutableRawPointer?, type: CASType = .weak, orderSwap: MemoryOrder = .sequential, orderLoad: LoadMemoryOrder = .sequential) -> Bool { - return current.withMemoryRebound(to: Optional.self, capacity: 1) { - CAtomicsPointerCAS($0, UnsafeRawPointer(future), &ptr, type, orderSwap, orderLoad) - } + return loadCAS(current, future, type, orderSwap, orderLoad) } @inline(__always) @discardableResult - public mutating func CAS(current: UnsafePointer?, future: UnsafePointer?, - type: CASType = .weak, + public mutating func CAS(current: UnsafeMutableRawPointer?, future: UnsafeMutableRawPointer?, + type: CASType = .strong, order: MemoryOrder = .sequential) -> Bool { - var expect = current - return loadCAS(current: &expect, future: future, type: type, orderSwap: order, orderLoad: .relaxed) + return CAS(current, future, type, order) } } -public struct AtomicOpaquePointer -{ - @_versioned var ptr = CAtomicsPointer() +@_exported import struct CAtomics.AtomicOpaquePointer - public init(_ pointer: OpaquePointer? = nil) - { - CAtomicsPointerInit(UnsafeRawPointer(pointer), &ptr) - } +extension AtomicOpaquePointer +{ + @available(*, unavailable, message: "If needed, use initialize(_ pointer: OpaquePointer?) after the default initializer, as long as the instance is unshared") + public init(_ pointer: OpaquePointer?) {} public var pointer: OpaquePointer? { @inline(__always) mutating get { - return OpaquePointer(CAtomicsPointerLoad(&ptr, .relaxed)) + return load(.relaxed) } } @inline(__always) public mutating func load(order: LoadMemoryOrder = .sequential) -> OpaquePointer? { - return OpaquePointer(CAtomicsPointerLoad(&ptr, order)) + return load(order) } @inline(__always) public mutating func store(_ pointer: OpaquePointer?, order: StoreMemoryOrder = .sequential) { - CAtomicsPointerStore(UnsafeRawPointer(pointer), &ptr, order) + store(pointer, order) } @inline(__always) public mutating func swap(_ pointer: OpaquePointer?, order: MemoryOrder = .sequential) -> OpaquePointer? { - return OpaquePointer(CAtomicsPointerSwap(UnsafeRawPointer(pointer), &ptr, order)) + return swap(pointer, order) } @inline(__always) @discardableResult @@ -274,17 +270,14 @@ public struct AtomicOpaquePointer orderSwap: MemoryOrder = .sequential, orderLoad: LoadMemoryOrder = .sequential) -> Bool { - return current.withMemoryRebound(to: Optional.self, capacity: 1) { - CAtomicsPointerCAS($0, UnsafeRawPointer(future), &ptr, type, orderSwap, orderLoad) - } + return loadCAS(current, future, type, orderSwap, orderLoad) } @inline(__always) @discardableResult public mutating func CAS(current: OpaquePointer?, future: OpaquePointer?, - type: CASType = .weak, + type: CASType = .strong, order: MemoryOrder = .sequential) -> Bool { - var expect = current - return loadCAS(current: &expect, future: future, type: type, orderSwap: order, orderLoad: .relaxed) + return CAS(current, future, type, order) } } diff --git a/Sources/Atomics/atomics-pointer.swift.gyb b/Sources/Atomics/atomics-pointer.swift.gyb index 6d0cef3..0f7c33e 100644 --- a/Sources/Atomics/atomics-pointer.swift.gyb +++ b/Sources/Atomics/atomics-pointer.swift.gyb @@ -8,40 +8,100 @@ // import CAtomics -% for (AtomicType, PointerType, MemoryBinding, Mutable) in [('AtomicMutableRawPointer', 'UnsafeMutableRawPointer', '', 'Mutable'), ('AtomicRawPointer', 'UnsafeRawPointer', '', ''), ('AtomicMutablePointer', 'UnsafeMutablePointer', '?.assumingMemoryBound(to: Pointee.self)', 'Mutable'), ('AtomicPointer', 'UnsafePointer', '?.assumingMemoryBound(to: Pointee.self)', ''), ('AtomicOpaquePointer', 'OpaquePointer', '', '')]: +% for Mutable in ['', 'Mutable']: -public struct ${AtomicType} +public struct Atomic${Mutable}Pointer { - @_versioned var ptr = CAtomics${Mutable}Pointer() + @_versioned var ptr = Atomic${Mutable}RawPointer() - public init(_ pointer: ${PointerType}? = nil) + public init(_ pointer: Unsafe${Mutable}Pointer? = nil) { - CAtomics${Mutable}PointerInit(Unsafe${Mutable}RawPointer(pointer), &ptr) + self.initialize(pointer) } + public mutating func initialize(_ pointer: Unsafe${Mutable}Pointer?) + { + ptr.initialize(Unsafe${Mutable}RawPointer(pointer)) + } + + public var pointer: Unsafe${Mutable}Pointer? { + @inline(__always) + mutating get { + return Unsafe${Mutable}Pointer(ptr.load(.relaxed)?.assumingMemoryBound(to: Pointee.self)) + } + } + + @inline(__always) + public mutating func load(order: LoadMemoryOrder = .sequential) -> Unsafe${Mutable}Pointer? + { + return Unsafe${Mutable}Pointer(ptr.load(order)?.assumingMemoryBound(to: Pointee.self)) + } + + @inline(__always) + public mutating func store(_ pointer: Unsafe${Mutable}Pointer?, order: StoreMemoryOrder = .sequential) + { + ptr.store(Unsafe${Mutable}RawPointer(pointer), order) + } + + @inline(__always) + public mutating func swap(_ pointer: Unsafe${Mutable}Pointer?, order: MemoryOrder = .sequential) -> Unsafe${Mutable}Pointer? + { + return Unsafe${Mutable}Pointer(ptr.swap(Unsafe${Mutable}RawPointer(pointer), order)?.assumingMemoryBound(to: Pointee.self)) + } + + @inline(__always) @discardableResult + public mutating func loadCAS(current: UnsafeMutablePointer?>, + future: Unsafe${Mutable}Pointer?, + type: CASType = .weak, + orderSwap: MemoryOrder = .sequential, + orderLoad: LoadMemoryOrder = .sequential) -> Bool + { + return current.withMemoryRebound(to: Optional.self, capacity: 1) { + ptr.loadCAS($0, Unsafe${Mutable}RawPointer(future), type, orderSwap, orderLoad) + } + } + + @inline(__always) @discardableResult + public mutating func CAS(current: Unsafe${Mutable}Pointer?, future: Unsafe${Mutable}Pointer?, + type: CASType = .strong, + order: MemoryOrder = .sequential) -> Bool + { + return ptr.CAS(current, future, type, order) + } +} +% end +% for (AtomicType, PointerType) in [('AtomicRawPointer', 'UnsafeRawPointer'), ('AtomicMutableRawPointer', 'UnsafeMutableRawPointer'), ('AtomicOpaquePointer', 'OpaquePointer')]: + +@_exported import struct CAtomics.${AtomicType} + +extension ${AtomicType} +{ + @available(*, unavailable, message: "If needed, use initialize(_ pointer: ${PointerType}?) after the default initializer, as long as the instance is unshared") + public init(_ pointer: ${PointerType}?) {} + public var pointer: ${PointerType}? { @inline(__always) mutating get { - return ${PointerType}(CAtomics${Mutable}PointerLoad(&ptr, .relaxed)${MemoryBinding}) + return load(.relaxed) } } @inline(__always) public mutating func load(order: LoadMemoryOrder = .sequential) -> ${PointerType}? { - return ${PointerType}(CAtomics${Mutable}PointerLoad(&ptr, order)${MemoryBinding}) + return load(order) } @inline(__always) public mutating func store(_ pointer: ${PointerType}?, order: StoreMemoryOrder = .sequential) { - CAtomics${Mutable}PointerStore(Unsafe${Mutable}RawPointer(pointer), &ptr, order) + store(pointer, order) } @inline(__always) public mutating func swap(_ pointer: ${PointerType}?, order: MemoryOrder = .sequential) -> ${PointerType}? { - return ${PointerType}(CAtomics${Mutable}PointerSwap(Unsafe${Mutable}RawPointer(pointer), &ptr, order)${MemoryBinding}) + return swap(pointer, order) } @inline(__always) @discardableResult @@ -51,18 +111,15 @@ public struct ${AtomicType} orderSwap: MemoryOrder = .sequential, orderLoad: LoadMemoryOrder = .sequential) -> Bool { - return current.withMemoryRebound(to: Optional.self, capacity: 1) { - CAtomics${Mutable}PointerCAS($0, Unsafe${Mutable}RawPointer(future), &ptr, type, orderSwap, orderLoad) - } + return loadCAS(current, future, type, orderSwap, orderLoad) } @inline(__always) @discardableResult public mutating func CAS(current: ${PointerType}?, future: ${PointerType}?, - type: CASType = .weak, + type: CASType = .strong, order: MemoryOrder = .sequential) -> Bool { - var expect = current - return loadCAS(current: &expect, future: future, type: type, orderSwap: order, orderLoad: .relaxed) + return CAS(current, future, type, order) } } % end diff --git a/Sources/Atomics/atomics-reference.swift b/Sources/Atomics/atomics-reference.swift index 8b7c852..f7fb7ca 100644 --- a/Sources/Atomics/atomics-reference.swift +++ b/Sources/Atomics/atomics-reference.swift @@ -11,12 +11,12 @@ import CAtomics public struct AtomicReference { - @_versioned internal var ptr = CAtomicsPointer() + @_versioned internal var ptr = AtomicMutableRawPointer() public init(_ ref: T? = nil) { let u = Unmanaged.tryRetain(ref)?.toOpaque() - CAtomicsPointerInit(u, &ptr) + ptr.initialize(u) } } @@ -26,7 +26,7 @@ extension AtomicReference public mutating func swap(_ ref: T?, order: MemoryOrder = .sequential) -> T? { let u = Unmanaged.tryRetain(ref)?.toOpaque() - if let pointer = CAtomicsPointerSwap(u, &ptr, order) + if let pointer = ptr.swap(u, order) { return Unmanaged.fromOpaque(pointer).takeRetainedValue() } @@ -37,8 +37,7 @@ extension AtomicReference public mutating func swapIfNil(_ ref: T, order: MemoryOrder = .sequential) -> Bool { let u = Unmanaged.passUnretained(ref) - var null: UnsafeRawPointer? = nil - if CAtomicsPointerCAS(&null, u.toOpaque(), &ptr, .strong, order, .relaxed) + if ptr.CAS(nil, u.toOpaque(), .strong, order) { _ = u.retain() return true @@ -49,7 +48,7 @@ extension AtomicReference @inline(__always) public mutating func take(order: MemoryOrder = .sequential) -> T? { - if let pointer = CAtomicsPointerSwap(nil, &ptr, order) + if let pointer = ptr.swap(nil, order) { return Unmanaged.fromOpaque(pointer).takeRetainedValue() } diff --git a/Sources/CAtomics/include/CAtomics.h b/Sources/CAtomics/include/CAtomics.h index cdb1db5..9192371 100644 --- a/Sources/CAtomics/include/CAtomics.h +++ b/Sources/CAtomics/include/CAtomics.h @@ -59,15 +59,23 @@ SWIFT_ENUM(StoreMemoryOrder, open) StoreMemoryOrder_sequential = __ATOMIC_SEQ_CST }; -#define CAS_TYPE_STRONG 0 -#define CAS_TYPE_WEAK 1 +// form of compare-and-swap operation + +#define __ATOMIC_CAS_TYPE_STRONG 0 +#define __ATOMIC_CAS_TYPE_WEAK 1 SWIFT_ENUM(CASType, closed) { - CASType_strong = CAS_TYPE_STRONG, - CASType_weak = CAS_TYPE_WEAK + CASType_strong = __ATOMIC_CAS_TYPE_STRONG, + CASType_weak = __ATOMIC_CAS_TYPE_WEAK }; +#if __has_attribute(swift_name) +# define SWIFT_NAME(_name) __attribute__((swift_name(#_name))) +#else +# define SWIFT_NAME(_name) +#endif + // atomic integer generation #define CLANG_ATOMICS_STRUCT(sType, aType) \ @@ -75,35 +83,54 @@ SWIFT_ENUM(CASType, closed) #define CLANG_ATOMICS_INIT(sType, pType) \ static __inline__ __attribute__((__always_inline__)) \ - void sType##Init(pType value, sType *_Nonnull ptr) \ + SWIFT_NAME(sType.initialize(self:_:)) \ + void sType##Init(sType *_Nonnull ptr, pType value) \ { atomic_init(&(ptr->a), value); } #define CLANG_ATOMICS_LOAD(sType, pType) \ static __inline__ __attribute__((__always_inline__)) \ + SWIFT_NAME(sType.load(self:_:)) \ pType sType##Load(sType *_Nonnull ptr, enum LoadMemoryOrder order) \ { return atomic_load_explicit(&(ptr->a), order); } #define CLANG_ATOMICS_STORE(sType, pType) \ static __inline__ __attribute__((__always_inline__)) \ - void sType##Store(pType value, sType *_Nonnull ptr, enum StoreMemoryOrder order) \ + SWIFT_NAME(sType.store(self:_:_:)) \ + void sType##Store(sType *_Nonnull ptr, pType value, enum StoreMemoryOrder order) \ { atomic_store_explicit(&(ptr->a), value, order); } +#define CLANG_ATOMICS_SWAP(sType, pType) \ + static __inline__ __attribute__((__always_inline__)) \ + SWIFT_NAME(sType.swap(self:_:_:)) \ + pType sType##Swap(sType *_Nonnull ptr, pType value, enum MemoryOrder order) \ + { return atomic_exchange_explicit(&(ptr->a), value, order); } + #define CLANG_ATOMICS_RMW(sType, pType, pName, op, opName) \ static __inline__ __attribute__((__always_inline__)) \ - pType sType##opName(pType pName, sType *_Nonnull ptr, enum MemoryOrder order) \ + SWIFT_NAME(sType.op(self:_:_:)) \ + pType sType##opName(sType *_Nonnull ptr, pType pName, enum MemoryOrder order) \ { return atomic_##op##_explicit(&(ptr->a), pName, order); } #define CLANG_ATOMICS_CAS(sType, pType) \ static __inline__ __attribute__((__always_inline__)) \ - _Bool sType##CAS(pType *_Nonnull current, pType future, sType *_Nonnull ptr, \ - enum CASType type, enum MemoryOrder succ, enum LoadMemoryOrder fail) \ + SWIFT_NAME(sType.loadCAS(self:_:_:_:_:_:)) \ + _Bool sType##LoadCAS(sType *_Nonnull ptr, pType *_Nonnull current, pType future, \ + enum CASType type, enum MemoryOrder orderSwap, enum LoadMemoryOrder orderLoad) \ { \ - assert((unsigned int)fail <= (unsigned int)succ); \ - assert(succ == __ATOMIC_RELEASE ? fail == __ATOMIC_RELAXED : true); \ - if(type == CAS_TYPE_STRONG) \ - return atomic_compare_exchange_strong_explicit(&(ptr->a), current, future, succ, fail); \ + assert((unsigned int)orderLoad <= (unsigned int)orderSwap); \ + assert(orderSwap == __ATOMIC_RELEASE ? orderLoad == __ATOMIC_RELAXED : true); \ + if(type == __ATOMIC_CAS_TYPE_STRONG) \ + return atomic_compare_exchange_strong_explicit(&(ptr->a), current, future, orderSwap, orderLoad); \ else \ - return atomic_compare_exchange_weak_explicit(&(ptr->a), current, future, succ, fail); \ + return atomic_compare_exchange_weak_explicit(&(ptr->a), current, future, orderSwap, orderLoad); \ + } \ + static __inline__ __attribute__((__always_inline__)) \ + SWIFT_NAME(sType.CAS(self:_:_:_:_:)) \ + _Bool sType##CAS(sType *_Nonnull ptr, pType current, pType future, \ + enum CASType type, enum MemoryOrder order) \ + { \ + pType expect = current; \ + return sType##LoadCAS(ptr, &expect, future, type, order, LoadMemoryOrder_relaxed); \ } #define CLANG_ATOMICS_GENERATE(sType, aType, pType) \ @@ -111,7 +138,7 @@ SWIFT_ENUM(CASType, closed) CLANG_ATOMICS_INIT(sType, pType) \ CLANG_ATOMICS_LOAD(sType, pType) \ CLANG_ATOMICS_STORE(sType, pType) \ - CLANG_ATOMICS_RMW(sType, pType, value, exchange, Swap) \ + CLANG_ATOMICS_SWAP(sType, pType) \ CLANG_ATOMICS_RMW(sType, pType, increment, fetch_add, Add) \ CLANG_ATOMICS_RMW(sType, pType, increment, fetch_sub, Sub) \ CLANG_ATOMICS_RMW(sType, pType, bits, fetch_or, Or) \ @@ -121,81 +148,103 @@ SWIFT_ENUM(CASType, closed) // integer atomics -CLANG_ATOMICS_GENERATE(CAtomicsInt, atomic_long, long) -CLANG_ATOMICS_GENERATE(CAtomicsUInt, atomic_ulong, unsigned long) +CLANG_ATOMICS_GENERATE(AtomicInt, atomic_long, long) +CLANG_ATOMICS_GENERATE(AtomicUInt, atomic_ulong, unsigned long) -CLANG_ATOMICS_GENERATE(CAtomicsInt8, atomic_schar, signed char) -CLANG_ATOMICS_GENERATE(CAtomicsUInt8, atomic_uchar, unsigned char) +CLANG_ATOMICS_GENERATE(AtomicInt8, atomic_schar, signed char) +CLANG_ATOMICS_GENERATE(AtomicUInt8, atomic_uchar, unsigned char) -CLANG_ATOMICS_GENERATE(CAtomicsInt16, atomic_short, short) -CLANG_ATOMICS_GENERATE(CAtomicsUInt16, atomic_ushort, unsigned short) +CLANG_ATOMICS_GENERATE(AtomicInt16, atomic_short, short) +CLANG_ATOMICS_GENERATE(AtomicUInt16, atomic_ushort, unsigned short) -CLANG_ATOMICS_GENERATE(CAtomicsInt32, atomic_int, int) -CLANG_ATOMICS_GENERATE(CAtomicsUInt32, atomic_uint, unsigned int) +CLANG_ATOMICS_GENERATE(AtomicInt32, atomic_int, int) +CLANG_ATOMICS_GENERATE(AtomicUInt32, atomic_uint, unsigned int) -CLANG_ATOMICS_GENERATE(CAtomicsInt64, atomic_llong, long long) -CLANG_ATOMICS_GENERATE(CAtomicsUInt64, atomic_ullong, unsigned long long) +CLANG_ATOMICS_GENERATE(AtomicInt64, atomic_llong, long long) +CLANG_ATOMICS_GENERATE(AtomicUInt64, atomic_ullong, unsigned long long) // bool atomics -CLANG_ATOMICS_STRUCT(CAtomicsBoolean, atomic_bool) -CLANG_ATOMICS_INIT(CAtomicsBoolean, _Bool) -CLANG_ATOMICS_LOAD(CAtomicsBoolean, _Bool) -CLANG_ATOMICS_STORE(CAtomicsBoolean, _Bool) -CLANG_ATOMICS_RMW(CAtomicsBoolean, _Bool, value, exchange, Swap) -CLANG_ATOMICS_RMW(CAtomicsBoolean, _Bool, value, fetch_or, Or) -CLANG_ATOMICS_RMW(CAtomicsBoolean, _Bool, value, fetch_xor, Xor) -CLANG_ATOMICS_RMW(CAtomicsBoolean, _Bool, value, fetch_and, And) -CLANG_ATOMICS_CAS(CAtomicsBoolean, _Bool) +CLANG_ATOMICS_STRUCT(AtomicBool, atomic_bool) +CLANG_ATOMICS_INIT(AtomicBool, _Bool) +CLANG_ATOMICS_LOAD(AtomicBool, _Bool) +CLANG_ATOMICS_STORE(AtomicBool, _Bool) +CLANG_ATOMICS_SWAP(AtomicBool, _Bool) +CLANG_ATOMICS_RMW(AtomicBool, _Bool, value, fetch_or, Or) +CLANG_ATOMICS_RMW(AtomicBool, _Bool, value, fetch_xor, Xor) +CLANG_ATOMICS_RMW(AtomicBool, _Bool, value, fetch_and, And) +CLANG_ATOMICS_CAS(AtomicBool, _Bool) // pointer atomics #define CLANG_ATOMICS_POINTER_INIT(sType, pType) \ static __inline__ __attribute__((__always_inline__)) \ - void sType##Init(pType _Nullable value, sType *_Nonnull ptr) \ + SWIFT_NAME(sType.initialize(self:_:)) \ + void sType##Init(sType *_Nonnull ptr, pType _Nullable value) \ { atomic_init(&(ptr->a), (uintptr_t)value); } #define CLANG_ATOMICS_POINTER_LOAD(sType, pType) \ static __inline__ __attribute__((__always_inline__)) \ + SWIFT_NAME(sType.load(self:_:)) \ pType _Nullable sType##Load(sType *_Nonnull ptr, enum LoadMemoryOrder order) \ { return (pType) atomic_load_explicit(&(ptr->a), order); } #define CLANG_ATOMICS_POINTER_STORE(sType, pType) \ static __inline__ __attribute__((__always_inline__)) \ - void sType##Store(pType _Nullable value, sType *_Nonnull ptr, enum StoreMemoryOrder order) \ + SWIFT_NAME(sType.store(self:_:_:)) \ + void sType##Store(sType *_Nonnull ptr, pType _Nullable value, enum StoreMemoryOrder order) \ { atomic_store_explicit(&(ptr->a), (uintptr_t)value, order); } #define CLANG_ATOMICS_POINTER_SWAP(sType, pType) \ static __inline__ __attribute__((__always_inline__)) \ - pType _Nullable sType##Swap(pType _Nullable value, sType *_Nonnull ptr, enum MemoryOrder order) \ + SWIFT_NAME(sType.swap(self:_:_:)) \ + pType _Nullable sType##Swap(sType *_Nonnull ptr, pType _Nullable value, enum MemoryOrder order) \ { return (pType) atomic_exchange_explicit(&(ptr->a), (uintptr_t)value, order); } #define CLANG_ATOMICS_POINTER_CAS(sType, pType) \ static __inline__ __attribute__((__always_inline__)) \ - _Bool sType##CAS(pType _Nullable* _Nonnull current, pType _Nullable future, sType *_Nonnull ptr, \ - enum CASType type, enum MemoryOrder succ, enum LoadMemoryOrder fail) \ + SWIFT_NAME(sType.loadCAS(self:_:_:_:_:_:)) \ + _Bool sType##LoadCAS(sType *_Nonnull ptr, pType _Nullable* _Nonnull current, pType _Nullable future, \ + enum CASType type, enum MemoryOrder orderSwap, enum LoadMemoryOrder orderLoad) \ { \ - assert((unsigned int)fail <= (unsigned int)succ); \ - assert(succ == __ATOMIC_RELEASE ? fail == __ATOMIC_RELAXED : true); \ - if(type == CAS_TYPE_STRONG) \ - return atomic_compare_exchange_strong_explicit(&(ptr->a), (uintptr_t*)current, (uintptr_t)future, succ, fail); \ + assert((unsigned int)orderLoad <= (unsigned int)orderSwap); \ + assert(orderSwap == __ATOMIC_RELEASE ? orderLoad == __ATOMIC_RELAXED : true); \ + if(type == __ATOMIC_CAS_TYPE_STRONG) \ + return atomic_compare_exchange_strong_explicit(&(ptr->a), (uintptr_t*)current, (uintptr_t)future, orderSwap, orderLoad); \ else \ - return atomic_compare_exchange_weak_explicit(&(ptr->a), (uintptr_t*)current, (uintptr_t)future, succ, fail); \ + return atomic_compare_exchange_weak_explicit(&(ptr->a), (uintptr_t*)current, (uintptr_t)future, orderSwap, orderLoad); \ + } \ + static __inline__ __attribute__((__always_inline__)) \ + SWIFT_NAME(sType.CAS(self:_:_:_:_:)) \ + _Bool sType##CAS(sType *_Nonnull ptr, pType _Nullable current, pType _Nullable future, \ + enum CASType type, enum MemoryOrder order) \ + { \ + pType expect = current; \ + return sType##LoadCAS(ptr, &expect, future, type, order, LoadMemoryOrder_relaxed); \ } -CLANG_ATOMICS_STRUCT(CAtomicsMutablePointer, atomic_uintptr_t) -CLANG_ATOMICS_POINTER_INIT(CAtomicsMutablePointer, void*) -CLANG_ATOMICS_POINTER_LOAD(CAtomicsMutablePointer, void*) -CLANG_ATOMICS_POINTER_STORE(CAtomicsMutablePointer, void*) -CLANG_ATOMICS_POINTER_SWAP(CAtomicsMutablePointer, void*) -CLANG_ATOMICS_POINTER_CAS(CAtomicsMutablePointer, void*) - -CLANG_ATOMICS_STRUCT(CAtomicsPointer, atomic_uintptr_t) -CLANG_ATOMICS_POINTER_INIT(CAtomicsPointer, const void*) -CLANG_ATOMICS_POINTER_LOAD(CAtomicsPointer, const void*) -CLANG_ATOMICS_POINTER_STORE(CAtomicsPointer, const void*) -CLANG_ATOMICS_POINTER_SWAP(CAtomicsPointer, const void*) -CLANG_ATOMICS_POINTER_CAS(CAtomicsPointer, const void*) +CLANG_ATOMICS_STRUCT(AtomicMutableRawPointer, atomic_uintptr_t) +CLANG_ATOMICS_POINTER_INIT(AtomicMutableRawPointer, void*) +CLANG_ATOMICS_POINTER_LOAD(AtomicMutableRawPointer, void*) +CLANG_ATOMICS_POINTER_STORE(AtomicMutableRawPointer, void*) +CLANG_ATOMICS_POINTER_SWAP(AtomicMutableRawPointer, void*) +CLANG_ATOMICS_POINTER_CAS(AtomicMutableRawPointer, void*) + +CLANG_ATOMICS_STRUCT(AtomicRawPointer, atomic_uintptr_t) +CLANG_ATOMICS_POINTER_INIT(AtomicRawPointer, const void*) +CLANG_ATOMICS_POINTER_LOAD(AtomicRawPointer, const void*) +CLANG_ATOMICS_POINTER_STORE(AtomicRawPointer, const void*) +CLANG_ATOMICS_POINTER_SWAP(AtomicRawPointer, const void*) +CLANG_ATOMICS_POINTER_CAS(AtomicRawPointer, const void*) + +struct opaque; + +CLANG_ATOMICS_STRUCT(AtomicOpaquePointer, atomic_uintptr_t) +CLANG_ATOMICS_POINTER_INIT(AtomicOpaquePointer, struct opaque*) +CLANG_ATOMICS_POINTER_LOAD(AtomicOpaquePointer, struct opaque*) +CLANG_ATOMICS_POINTER_STORE(AtomicOpaquePointer, struct opaque*) +CLANG_ATOMICS_POINTER_SWAP(AtomicOpaquePointer, struct opaque*) +CLANG_ATOMICS_POINTER_CAS(AtomicOpaquePointer, struct opaque*) // fence diff --git a/Tests/AtomicsTests/AtomicsRaceTests.swift b/Tests/AtomicsTests/AtomicsRaceTests.swift index 20b0503..ea1798f 100644 --- a/Tests/AtomicsTests/AtomicsRaceTests.swift +++ b/Tests/AtomicsTests/AtomicsRaceTests.swift @@ -65,7 +65,7 @@ public class AtomicsRaceTests: XCTestCase for _ in 1...iterations { var p: Optional = UnsafeMutablePointer.allocate(capacity: 1) - var lock = AtomicInt(0) + var lock = AtomicInt() let closure = { while true { diff --git a/Tests/AtomicsTests/AtomicsTests.swift b/Tests/AtomicsTests/AtomicsTests.swift index c441dc5..25b56c0 100644 --- a/Tests/AtomicsTests/AtomicsTests.swift +++ b/Tests/AtomicsTests/AtomicsTests.swift @@ -79,6 +79,7 @@ public class AtomicsTests: XCTestCase public func testInt() { var i = AtomicInt() + i.initialize(0) XCTAssert(i.value == 0) #if swift(>=4.0) @@ -144,6 +145,7 @@ public class AtomicsTests: XCTestCase public func testUInt() { var i = AtomicUInt() + i.initialize(0) XCTAssert(i.value == 0) #if swift(>=4.0) @@ -209,6 +211,7 @@ public class AtomicsTests: XCTestCase public func testInt8() { var i = AtomicInt8() + i.initialize(0) XCTAssert(i.value == 0) #if swift(>=4.0) @@ -274,6 +277,7 @@ public class AtomicsTests: XCTestCase public func testUInt8() { var i = AtomicUInt8() + i.initialize(0) XCTAssert(i.value == 0) #if swift(>=4.0) @@ -339,6 +343,7 @@ public class AtomicsTests: XCTestCase public func testInt16() { var i = AtomicInt16() + i.initialize(0) XCTAssert(i.value == 0) #if swift(>=4.0) @@ -404,6 +409,7 @@ public class AtomicsTests: XCTestCase public func testUInt16() { var i = AtomicUInt16() + i.initialize(0) XCTAssert(i.value == 0) #if swift(>=4.0) @@ -469,6 +475,7 @@ public class AtomicsTests: XCTestCase public func testInt32() { var i = AtomicInt32() + i.initialize(0) XCTAssert(i.value == 0) #if swift(>=4.0) @@ -534,6 +541,7 @@ public class AtomicsTests: XCTestCase public func testUInt32() { var i = AtomicUInt32() + i.initialize(0) XCTAssert(i.value == 0) #if swift(>=4.0) @@ -599,6 +607,7 @@ public class AtomicsTests: XCTestCase public func testInt64() { var i = AtomicInt64() + i.initialize(0) XCTAssert(i.value == 0) #if swift(>=4.0) @@ -664,6 +673,7 @@ public class AtomicsTests: XCTestCase public func testUInt64() { var i = AtomicUInt64() + i.initialize(0) XCTAssert(i.value == 0) #if swift(>=4.0) @@ -864,8 +874,8 @@ public class AtomicsTests: XCTestCase public func testBool() { - var boolean = AtomicBool(false) - _ = AtomicBool(true) + var boolean = AtomicBool() + boolean.initialize(false) XCTAssert(boolean.value == false) boolean.store(false) @@ -896,15 +906,16 @@ public class AtomicsTests: XCTestCase boolean.xor(true) XCTAssert(boolean.value == true) - let old = boolean.swap(false) + var old = boolean.swap(false) XCTAssert(old == true) XCTAssert(boolean.swap(true) == false) boolean.CAS(current: true, future: false) if boolean.CAS(current: false, future: true, type: .strong) { - boolean.CAS(current: true, future: false, type: .weak) - boolean.CAS(current: false, future: true, type: .weak) + XCTAssert(boolean.CAS(current: true, future: false, type: .strong)) + XCTAssert(boolean.loadCAS(current: &old, future: false, type: .strong) == false) + XCTAssert(boolean.CAS(current: old, future: true, type: .strong)) } } diff --git a/Tests/AtomicsTests/AtomicsTests.swift.gyb b/Tests/AtomicsTests/AtomicsTests.swift.gyb index 06944e0..e134fc0 100644 --- a/Tests/AtomicsTests/AtomicsTests.swift.gyb +++ b/Tests/AtomicsTests/AtomicsTests.swift.gyb @@ -74,6 +74,7 @@ public class AtomicsTests: XCTestCase public func test${i}() { var i = Atomic${i}() + i.initialize(0) XCTAssert(i.value == 0) #if swift(>=4.0) @@ -172,8 +173,8 @@ public class AtomicsTests: XCTestCase public func testBool() { - var boolean = AtomicBool(false) - _ = AtomicBool(true) + var boolean = AtomicBool() + boolean.initialize(false) XCTAssert(boolean.value == false) boolean.store(false) @@ -204,15 +205,16 @@ public class AtomicsTests: XCTestCase boolean.xor(true) XCTAssert(boolean.value == true) - let old = boolean.swap(false) + var old = boolean.swap(false) XCTAssert(old == true) XCTAssert(boolean.swap(true) == false) boolean.CAS(current: true, future: false) if boolean.CAS(current: false, future: true, type: .strong) { - boolean.CAS(current: true, future: false, type: .weak) - boolean.CAS(current: false, future: true, type: .weak) + XCTAssert(boolean.CAS(current: true, future: false, type: .strong)) + XCTAssert(boolean.loadCAS(current: &old, future: false, type: .strong) == false) + XCTAssert(boolean.CAS(current: old, future: true, type: .strong)) } } diff --git a/Tests/CAtomicsTests/CAtomicsRaceTests.swift b/Tests/CAtomicsTests/CAtomicsRaceTests.swift index 6736034..66fe280 100644 --- a/Tests/CAtomicsTests/CAtomicsRaceTests.swift +++ b/Tests/CAtomicsTests/CAtomicsRaceTests.swift @@ -64,16 +64,16 @@ public class CAtomicsRaceTests: XCTestCase for _ in 1...iterations { var p: Optional = UnsafeMutablePointer.allocate(capacity: 1) - var lock = CAtomicsInt() - CAtomicsIntInit(0, &lock) + var lock = AtomicInt() + lock.initialize(0) let closure = { while true { var current = 0 - if CAtomicsIntCAS(¤t, 1, &lock, .weak, .sequential, .relaxed) + if lock.loadCAS(¤t, 1, .weak, .sequential, .relaxed) { - defer { CAtomicsIntStore(0, &lock, .sequential) } + defer { lock.store(0, .sequential) } if let c = p { p = nil @@ -100,14 +100,14 @@ public class CAtomicsRaceTests: XCTestCase for _ in 1...iterations { - var p = CAtomicsPointer() - CAtomicsPointerInit(UnsafeMutablePointer.allocate(capacity: 1), &p) + var p = AtomicMutableRawPointer() + p.initialize(UnsafeMutablePointer.allocate(capacity: 1)) let closure = { - var c = UnsafeRawPointer(bitPattern: 0x1) + var c = UnsafeMutableRawPointer(bitPattern: 0x1) while true { - if CAtomicsPointerCAS(&c, nil, &p, .weak, .release, .relaxed) + if p.loadCAS(&c, nil, .weak, .release, .relaxed) { if let c = UnsafeMutableRawPointer(mutating: c) { @@ -136,13 +136,13 @@ public class CAtomicsRaceTests: XCTestCase for _ in 1...iterations { - var p = CAtomicsPointer() - CAtomicsPointerInit(UnsafeMutablePointer.allocate(capacity: 1), &p) + var p = AtomicMutableRawPointer() + p.initialize(UnsafeMutablePointer.allocate(capacity: 1)) let closure = { while true { - if let c = CAtomicsPointerSwap(nil, &p, .acquire) + if let c = p.swap(nil, .acquire) { let pointer = UnsafeMutableRawPointer(mutating: c).assumingMemoryBound(to: Point.self) pointer.deallocate(capacity: 1) diff --git a/Tests/CAtomicsTests/CAtomicsTests.swift b/Tests/CAtomicsTests/CAtomicsTests.swift index 338e01c..6b02c70 100644 --- a/Tests/CAtomicsTests/CAtomicsTests.swift +++ b/Tests/CAtomicsTests/CAtomicsTests.swift @@ -55,17 +55,18 @@ extension UInt public class CAtomicsTests: XCTestCase { public static var allTests = [ - ("testMutablePointer", testMutablePointer), - ("testPointer", testPointer), + ("testRawPointer", testRawPointer), + ("testMutableRawPointer", testMutableRawPointer), + ("testOpaquePointer", testOpaquePointer), ("testBool", testBool), ("testFence", testFence), ] public func testInt() { - var i = CAtomicsInt() - CAtomicsIntInit(0, &i) - XCTAssert(CAtomicsIntLoad(&i, .relaxed) == 0) + var i = AtomicInt() + i.initialize(0) + XCTAssert(i.load(.relaxed) == 0) #if swift(>=4.0) let r1 = Int.randomPositive() @@ -77,53 +78,53 @@ public class CAtomicsTests: XCTestCase let r3 = Int(UInt.randomPositive()) #endif - CAtomicsIntStore(r1, &i, .relaxed) - XCTAssert(r1 == CAtomicsIntLoad(&i, .relaxed)) + i.store(r1, .relaxed) + XCTAssert(r1 == i.load(.relaxed)) - var j = CAtomicsIntSwap(r2, &i, .relaxed) + var j = i.swap(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r2, CAtomicsIntLoad(&i, .relaxed)) + XCTAssertEqual(r2, i.load(.relaxed)) - j = CAtomicsIntAdd(r1, &i, .relaxed) + j = i.fetch_add(r1, .relaxed) XCTAssertEqual(r2, j) - XCTAssertEqual(r1 &+ r2, CAtomicsIntLoad(&i, .relaxed)) + XCTAssertEqual(r1 &+ r2, i.load(.relaxed)) - j = CAtomicsIntSub(r2, &i, .relaxed) + j = i.fetch_sub(r2, .relaxed) XCTAssertEqual(r1 &+ r2, j) - XCTAssertEqual(r1, CAtomicsIntLoad(&i, .relaxed)) + XCTAssertEqual(r1, i.load(.relaxed)) - CAtomicsIntStore(r1, &i, .relaxed) - j = CAtomicsIntOr(r2, &i, .relaxed) + i.store(r1, .relaxed) + j = i.fetch_or(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r1 | r2, CAtomicsIntLoad(&i, .relaxed)) + XCTAssertEqual(r1 | r2, i.load(.relaxed)) - CAtomicsIntStore(r2, &i, .relaxed) - j = CAtomicsIntXor(r1, &i, .relaxed) + i.store(r2, .relaxed) + j = i.fetch_xor(r1, .relaxed) XCTAssertEqual(r2, j) - XCTAssertEqual(r1 ^ r2, CAtomicsIntLoad(&i, .relaxed)) + XCTAssertEqual(r1 ^ r2, i.load(.relaxed)) - CAtomicsIntStore(r1, &i, .relaxed) - j = CAtomicsIntAnd(r2, &i, .relaxed) + i.store(r1, .relaxed) + j = i.fetch_and(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r1 & r2, CAtomicsIntLoad(&i, .relaxed)) + XCTAssertEqual(r1 & r2, i.load(.relaxed)) j = r1 - CAtomicsIntStore(r1, &i, .relaxed) - XCTAssertTrue(CAtomicsIntCAS(&j, r2, &i, .strong, .relaxed, .relaxed)) - XCTAssertEqual(r2, CAtomicsIntLoad(&i, .relaxed)) + i.store(r1, .relaxed) + XCTAssertTrue(i.loadCAS(&j, r2, .strong, .relaxed, .relaxed)) + XCTAssertEqual(r2, i.load(.relaxed)) j = r2 - CAtomicsIntStore(r1, &i, .relaxed) - while(!CAtomicsIntCAS(&j, r3, &i, .weak, .relaxed, .relaxed)) {} + i.store(r1, .relaxed) + while(!i.loadCAS(&j, r3, .weak, .relaxed, .relaxed)) {} XCTAssertEqual(r1, j) - XCTAssertEqual(r3, CAtomicsIntLoad(&i, .relaxed)) + XCTAssertEqual(r3, i.load(.relaxed)) } public func testUInt() { - var i = CAtomicsUInt() - CAtomicsUIntInit(0, &i) - XCTAssert(CAtomicsUIntLoad(&i, .relaxed) == 0) + var i = AtomicUInt() + i.initialize(0) + XCTAssert(i.load(.relaxed) == 0) #if swift(>=4.0) let r1 = UInt.randomPositive() @@ -135,53 +136,53 @@ public class CAtomicsTests: XCTestCase let r3 = UInt(UInt.randomPositive()) #endif - CAtomicsUIntStore(r1, &i, .relaxed) - XCTAssert(r1 == CAtomicsUIntLoad(&i, .relaxed)) + i.store(r1, .relaxed) + XCTAssert(r1 == i.load(.relaxed)) - var j = CAtomicsUIntSwap(r2, &i, .relaxed) + var j = i.swap(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r2, CAtomicsUIntLoad(&i, .relaxed)) + XCTAssertEqual(r2, i.load(.relaxed)) - j = CAtomicsUIntAdd(r1, &i, .relaxed) + j = i.fetch_add(r1, .relaxed) XCTAssertEqual(r2, j) - XCTAssertEqual(r1 &+ r2, CAtomicsUIntLoad(&i, .relaxed)) + XCTAssertEqual(r1 &+ r2, i.load(.relaxed)) - j = CAtomicsUIntSub(r2, &i, .relaxed) + j = i.fetch_sub(r2, .relaxed) XCTAssertEqual(r1 &+ r2, j) - XCTAssertEqual(r1, CAtomicsUIntLoad(&i, .relaxed)) + XCTAssertEqual(r1, i.load(.relaxed)) - CAtomicsUIntStore(r1, &i, .relaxed) - j = CAtomicsUIntOr(r2, &i, .relaxed) + i.store(r1, .relaxed) + j = i.fetch_or(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r1 | r2, CAtomicsUIntLoad(&i, .relaxed)) + XCTAssertEqual(r1 | r2, i.load(.relaxed)) - CAtomicsUIntStore(r2, &i, .relaxed) - j = CAtomicsUIntXor(r1, &i, .relaxed) + i.store(r2, .relaxed) + j = i.fetch_xor(r1, .relaxed) XCTAssertEqual(r2, j) - XCTAssertEqual(r1 ^ r2, CAtomicsUIntLoad(&i, .relaxed)) + XCTAssertEqual(r1 ^ r2, i.load(.relaxed)) - CAtomicsUIntStore(r1, &i, .relaxed) - j = CAtomicsUIntAnd(r2, &i, .relaxed) + i.store(r1, .relaxed) + j = i.fetch_and(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r1 & r2, CAtomicsUIntLoad(&i, .relaxed)) + XCTAssertEqual(r1 & r2, i.load(.relaxed)) j = r1 - CAtomicsUIntStore(r1, &i, .relaxed) - XCTAssertTrue(CAtomicsUIntCAS(&j, r2, &i, .strong, .relaxed, .relaxed)) - XCTAssertEqual(r2, CAtomicsUIntLoad(&i, .relaxed)) + i.store(r1, .relaxed) + XCTAssertTrue(i.loadCAS(&j, r2, .strong, .relaxed, .relaxed)) + XCTAssertEqual(r2, i.load(.relaxed)) j = r2 - CAtomicsUIntStore(r1, &i, .relaxed) - while(!CAtomicsUIntCAS(&j, r3, &i, .weak, .relaxed, .relaxed)) {} + i.store(r1, .relaxed) + while(!i.loadCAS(&j, r3, .weak, .relaxed, .relaxed)) {} XCTAssertEqual(r1, j) - XCTAssertEqual(r3, CAtomicsUIntLoad(&i, .relaxed)) + XCTAssertEqual(r3, i.load(.relaxed)) } public func testInt8() { - var i = CAtomicsInt8() - CAtomicsInt8Init(0, &i) - XCTAssert(CAtomicsInt8Load(&i, .relaxed) == 0) + var i = AtomicInt8() + i.initialize(0) + XCTAssert(i.load(.relaxed) == 0) #if swift(>=4.0) let r1 = Int8.randomPositive() @@ -193,53 +194,53 @@ public class CAtomicsTests: XCTestCase let r3 = Int8(truncatingBitPattern: UInt.randomPositive()) #endif - CAtomicsInt8Store(r1, &i, .relaxed) - XCTAssert(r1 == CAtomicsInt8Load(&i, .relaxed)) + i.store(r1, .relaxed) + XCTAssert(r1 == i.load(.relaxed)) - var j = CAtomicsInt8Swap(r2, &i, .relaxed) + var j = i.swap(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r2, CAtomicsInt8Load(&i, .relaxed)) + XCTAssertEqual(r2, i.load(.relaxed)) - j = CAtomicsInt8Add(r1, &i, .relaxed) + j = i.fetch_add(r1, .relaxed) XCTAssertEqual(r2, j) - XCTAssertEqual(r1 &+ r2, CAtomicsInt8Load(&i, .relaxed)) + XCTAssertEqual(r1 &+ r2, i.load(.relaxed)) - j = CAtomicsInt8Sub(r2, &i, .relaxed) + j = i.fetch_sub(r2, .relaxed) XCTAssertEqual(r1 &+ r2, j) - XCTAssertEqual(r1, CAtomicsInt8Load(&i, .relaxed)) + XCTAssertEqual(r1, i.load(.relaxed)) - CAtomicsInt8Store(r1, &i, .relaxed) - j = CAtomicsInt8Or(r2, &i, .relaxed) + i.store(r1, .relaxed) + j = i.fetch_or(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r1 | r2, CAtomicsInt8Load(&i, .relaxed)) + XCTAssertEqual(r1 | r2, i.load(.relaxed)) - CAtomicsInt8Store(r2, &i, .relaxed) - j = CAtomicsInt8Xor(r1, &i, .relaxed) + i.store(r2, .relaxed) + j = i.fetch_xor(r1, .relaxed) XCTAssertEqual(r2, j) - XCTAssertEqual(r1 ^ r2, CAtomicsInt8Load(&i, .relaxed)) + XCTAssertEqual(r1 ^ r2, i.load(.relaxed)) - CAtomicsInt8Store(r1, &i, .relaxed) - j = CAtomicsInt8And(r2, &i, .relaxed) + i.store(r1, .relaxed) + j = i.fetch_and(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r1 & r2, CAtomicsInt8Load(&i, .relaxed)) + XCTAssertEqual(r1 & r2, i.load(.relaxed)) j = r1 - CAtomicsInt8Store(r1, &i, .relaxed) - XCTAssertTrue(CAtomicsInt8CAS(&j, r2, &i, .strong, .relaxed, .relaxed)) - XCTAssertEqual(r2, CAtomicsInt8Load(&i, .relaxed)) + i.store(r1, .relaxed) + XCTAssertTrue(i.loadCAS(&j, r2, .strong, .relaxed, .relaxed)) + XCTAssertEqual(r2, i.load(.relaxed)) j = r2 - CAtomicsInt8Store(r1, &i, .relaxed) - while(!CAtomicsInt8CAS(&j, r3, &i, .weak, .relaxed, .relaxed)) {} + i.store(r1, .relaxed) + while(!i.loadCAS(&j, r3, .weak, .relaxed, .relaxed)) {} XCTAssertEqual(r1, j) - XCTAssertEqual(r3, CAtomicsInt8Load(&i, .relaxed)) + XCTAssertEqual(r3, i.load(.relaxed)) } public func testUInt8() { - var i = CAtomicsUInt8() - CAtomicsUInt8Init(0, &i) - XCTAssert(CAtomicsUInt8Load(&i, .relaxed) == 0) + var i = AtomicUInt8() + i.initialize(0) + XCTAssert(i.load(.relaxed) == 0) #if swift(>=4.0) let r1 = UInt8.randomPositive() @@ -251,53 +252,53 @@ public class CAtomicsTests: XCTestCase let r3 = UInt8(truncatingBitPattern: UInt.randomPositive()) #endif - CAtomicsUInt8Store(r1, &i, .relaxed) - XCTAssert(r1 == CAtomicsUInt8Load(&i, .relaxed)) + i.store(r1, .relaxed) + XCTAssert(r1 == i.load(.relaxed)) - var j = CAtomicsUInt8Swap(r2, &i, .relaxed) + var j = i.swap(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r2, CAtomicsUInt8Load(&i, .relaxed)) + XCTAssertEqual(r2, i.load(.relaxed)) - j = CAtomicsUInt8Add(r1, &i, .relaxed) + j = i.fetch_add(r1, .relaxed) XCTAssertEqual(r2, j) - XCTAssertEqual(r1 &+ r2, CAtomicsUInt8Load(&i, .relaxed)) + XCTAssertEqual(r1 &+ r2, i.load(.relaxed)) - j = CAtomicsUInt8Sub(r2, &i, .relaxed) + j = i.fetch_sub(r2, .relaxed) XCTAssertEqual(r1 &+ r2, j) - XCTAssertEqual(r1, CAtomicsUInt8Load(&i, .relaxed)) + XCTAssertEqual(r1, i.load(.relaxed)) - CAtomicsUInt8Store(r1, &i, .relaxed) - j = CAtomicsUInt8Or(r2, &i, .relaxed) + i.store(r1, .relaxed) + j = i.fetch_or(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r1 | r2, CAtomicsUInt8Load(&i, .relaxed)) + XCTAssertEqual(r1 | r2, i.load(.relaxed)) - CAtomicsUInt8Store(r2, &i, .relaxed) - j = CAtomicsUInt8Xor(r1, &i, .relaxed) + i.store(r2, .relaxed) + j = i.fetch_xor(r1, .relaxed) XCTAssertEqual(r2, j) - XCTAssertEqual(r1 ^ r2, CAtomicsUInt8Load(&i, .relaxed)) + XCTAssertEqual(r1 ^ r2, i.load(.relaxed)) - CAtomicsUInt8Store(r1, &i, .relaxed) - j = CAtomicsUInt8And(r2, &i, .relaxed) + i.store(r1, .relaxed) + j = i.fetch_and(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r1 & r2, CAtomicsUInt8Load(&i, .relaxed)) + XCTAssertEqual(r1 & r2, i.load(.relaxed)) j = r1 - CAtomicsUInt8Store(r1, &i, .relaxed) - XCTAssertTrue(CAtomicsUInt8CAS(&j, r2, &i, .strong, .relaxed, .relaxed)) - XCTAssertEqual(r2, CAtomicsUInt8Load(&i, .relaxed)) + i.store(r1, .relaxed) + XCTAssertTrue(i.loadCAS(&j, r2, .strong, .relaxed, .relaxed)) + XCTAssertEqual(r2, i.load(.relaxed)) j = r2 - CAtomicsUInt8Store(r1, &i, .relaxed) - while(!CAtomicsUInt8CAS(&j, r3, &i, .weak, .relaxed, .relaxed)) {} + i.store(r1, .relaxed) + while(!i.loadCAS(&j, r3, .weak, .relaxed, .relaxed)) {} XCTAssertEqual(r1, j) - XCTAssertEqual(r3, CAtomicsUInt8Load(&i, .relaxed)) + XCTAssertEqual(r3, i.load(.relaxed)) } public func testInt16() { - var i = CAtomicsInt16() - CAtomicsInt16Init(0, &i) - XCTAssert(CAtomicsInt16Load(&i, .relaxed) == 0) + var i = AtomicInt16() + i.initialize(0) + XCTAssert(i.load(.relaxed) == 0) #if swift(>=4.0) let r1 = Int16.randomPositive() @@ -309,53 +310,53 @@ public class CAtomicsTests: XCTestCase let r3 = Int16(truncatingBitPattern: UInt.randomPositive()) #endif - CAtomicsInt16Store(r1, &i, .relaxed) - XCTAssert(r1 == CAtomicsInt16Load(&i, .relaxed)) + i.store(r1, .relaxed) + XCTAssert(r1 == i.load(.relaxed)) - var j = CAtomicsInt16Swap(r2, &i, .relaxed) + var j = i.swap(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r2, CAtomicsInt16Load(&i, .relaxed)) + XCTAssertEqual(r2, i.load(.relaxed)) - j = CAtomicsInt16Add(r1, &i, .relaxed) + j = i.fetch_add(r1, .relaxed) XCTAssertEqual(r2, j) - XCTAssertEqual(r1 &+ r2, CAtomicsInt16Load(&i, .relaxed)) + XCTAssertEqual(r1 &+ r2, i.load(.relaxed)) - j = CAtomicsInt16Sub(r2, &i, .relaxed) + j = i.fetch_sub(r2, .relaxed) XCTAssertEqual(r1 &+ r2, j) - XCTAssertEqual(r1, CAtomicsInt16Load(&i, .relaxed)) + XCTAssertEqual(r1, i.load(.relaxed)) - CAtomicsInt16Store(r1, &i, .relaxed) - j = CAtomicsInt16Or(r2, &i, .relaxed) + i.store(r1, .relaxed) + j = i.fetch_or(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r1 | r2, CAtomicsInt16Load(&i, .relaxed)) + XCTAssertEqual(r1 | r2, i.load(.relaxed)) - CAtomicsInt16Store(r2, &i, .relaxed) - j = CAtomicsInt16Xor(r1, &i, .relaxed) + i.store(r2, .relaxed) + j = i.fetch_xor(r1, .relaxed) XCTAssertEqual(r2, j) - XCTAssertEqual(r1 ^ r2, CAtomicsInt16Load(&i, .relaxed)) + XCTAssertEqual(r1 ^ r2, i.load(.relaxed)) - CAtomicsInt16Store(r1, &i, .relaxed) - j = CAtomicsInt16And(r2, &i, .relaxed) + i.store(r1, .relaxed) + j = i.fetch_and(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r1 & r2, CAtomicsInt16Load(&i, .relaxed)) + XCTAssertEqual(r1 & r2, i.load(.relaxed)) j = r1 - CAtomicsInt16Store(r1, &i, .relaxed) - XCTAssertTrue(CAtomicsInt16CAS(&j, r2, &i, .strong, .relaxed, .relaxed)) - XCTAssertEqual(r2, CAtomicsInt16Load(&i, .relaxed)) + i.store(r1, .relaxed) + XCTAssertTrue(i.loadCAS(&j, r2, .strong, .relaxed, .relaxed)) + XCTAssertEqual(r2, i.load(.relaxed)) j = r2 - CAtomicsInt16Store(r1, &i, .relaxed) - while(!CAtomicsInt16CAS(&j, r3, &i, .weak, .relaxed, .relaxed)) {} + i.store(r1, .relaxed) + while(!i.loadCAS(&j, r3, .weak, .relaxed, .relaxed)) {} XCTAssertEqual(r1, j) - XCTAssertEqual(r3, CAtomicsInt16Load(&i, .relaxed)) + XCTAssertEqual(r3, i.load(.relaxed)) } public func testUInt16() { - var i = CAtomicsUInt16() - CAtomicsUInt16Init(0, &i) - XCTAssert(CAtomicsUInt16Load(&i, .relaxed) == 0) + var i = AtomicUInt16() + i.initialize(0) + XCTAssert(i.load(.relaxed) == 0) #if swift(>=4.0) let r1 = UInt16.randomPositive() @@ -367,53 +368,53 @@ public class CAtomicsTests: XCTestCase let r3 = UInt16(truncatingBitPattern: UInt.randomPositive()) #endif - CAtomicsUInt16Store(r1, &i, .relaxed) - XCTAssert(r1 == CAtomicsUInt16Load(&i, .relaxed)) + i.store(r1, .relaxed) + XCTAssert(r1 == i.load(.relaxed)) - var j = CAtomicsUInt16Swap(r2, &i, .relaxed) + var j = i.swap(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r2, CAtomicsUInt16Load(&i, .relaxed)) + XCTAssertEqual(r2, i.load(.relaxed)) - j = CAtomicsUInt16Add(r1, &i, .relaxed) + j = i.fetch_add(r1, .relaxed) XCTAssertEqual(r2, j) - XCTAssertEqual(r1 &+ r2, CAtomicsUInt16Load(&i, .relaxed)) + XCTAssertEqual(r1 &+ r2, i.load(.relaxed)) - j = CAtomicsUInt16Sub(r2, &i, .relaxed) + j = i.fetch_sub(r2, .relaxed) XCTAssertEqual(r1 &+ r2, j) - XCTAssertEqual(r1, CAtomicsUInt16Load(&i, .relaxed)) + XCTAssertEqual(r1, i.load(.relaxed)) - CAtomicsUInt16Store(r1, &i, .relaxed) - j = CAtomicsUInt16Or(r2, &i, .relaxed) + i.store(r1, .relaxed) + j = i.fetch_or(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r1 | r2, CAtomicsUInt16Load(&i, .relaxed)) + XCTAssertEqual(r1 | r2, i.load(.relaxed)) - CAtomicsUInt16Store(r2, &i, .relaxed) - j = CAtomicsUInt16Xor(r1, &i, .relaxed) + i.store(r2, .relaxed) + j = i.fetch_xor(r1, .relaxed) XCTAssertEqual(r2, j) - XCTAssertEqual(r1 ^ r2, CAtomicsUInt16Load(&i, .relaxed)) + XCTAssertEqual(r1 ^ r2, i.load(.relaxed)) - CAtomicsUInt16Store(r1, &i, .relaxed) - j = CAtomicsUInt16And(r2, &i, .relaxed) + i.store(r1, .relaxed) + j = i.fetch_and(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r1 & r2, CAtomicsUInt16Load(&i, .relaxed)) + XCTAssertEqual(r1 & r2, i.load(.relaxed)) j = r1 - CAtomicsUInt16Store(r1, &i, .relaxed) - XCTAssertTrue(CAtomicsUInt16CAS(&j, r2, &i, .strong, .relaxed, .relaxed)) - XCTAssertEqual(r2, CAtomicsUInt16Load(&i, .relaxed)) + i.store(r1, .relaxed) + XCTAssertTrue(i.loadCAS(&j, r2, .strong, .relaxed, .relaxed)) + XCTAssertEqual(r2, i.load(.relaxed)) j = r2 - CAtomicsUInt16Store(r1, &i, .relaxed) - while(!CAtomicsUInt16CAS(&j, r3, &i, .weak, .relaxed, .relaxed)) {} + i.store(r1, .relaxed) + while(!i.loadCAS(&j, r3, .weak, .relaxed, .relaxed)) {} XCTAssertEqual(r1, j) - XCTAssertEqual(r3, CAtomicsUInt16Load(&i, .relaxed)) + XCTAssertEqual(r3, i.load(.relaxed)) } public func testInt32() { - var i = CAtomicsInt32() - CAtomicsInt32Init(0, &i) - XCTAssert(CAtomicsInt32Load(&i, .relaxed) == 0) + var i = AtomicInt32() + i.initialize(0) + XCTAssert(i.load(.relaxed) == 0) #if swift(>=4.0) let r1 = Int32.randomPositive() @@ -425,53 +426,53 @@ public class CAtomicsTests: XCTestCase let r3 = Int32(truncatingBitPattern: UInt.randomPositive()) #endif - CAtomicsInt32Store(r1, &i, .relaxed) - XCTAssert(r1 == CAtomicsInt32Load(&i, .relaxed)) + i.store(r1, .relaxed) + XCTAssert(r1 == i.load(.relaxed)) - var j = CAtomicsInt32Swap(r2, &i, .relaxed) + var j = i.swap(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r2, CAtomicsInt32Load(&i, .relaxed)) + XCTAssertEqual(r2, i.load(.relaxed)) - j = CAtomicsInt32Add(r1, &i, .relaxed) + j = i.fetch_add(r1, .relaxed) XCTAssertEqual(r2, j) - XCTAssertEqual(r1 &+ r2, CAtomicsInt32Load(&i, .relaxed)) + XCTAssertEqual(r1 &+ r2, i.load(.relaxed)) - j = CAtomicsInt32Sub(r2, &i, .relaxed) + j = i.fetch_sub(r2, .relaxed) XCTAssertEqual(r1 &+ r2, j) - XCTAssertEqual(r1, CAtomicsInt32Load(&i, .relaxed)) + XCTAssertEqual(r1, i.load(.relaxed)) - CAtomicsInt32Store(r1, &i, .relaxed) - j = CAtomicsInt32Or(r2, &i, .relaxed) + i.store(r1, .relaxed) + j = i.fetch_or(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r1 | r2, CAtomicsInt32Load(&i, .relaxed)) + XCTAssertEqual(r1 | r2, i.load(.relaxed)) - CAtomicsInt32Store(r2, &i, .relaxed) - j = CAtomicsInt32Xor(r1, &i, .relaxed) + i.store(r2, .relaxed) + j = i.fetch_xor(r1, .relaxed) XCTAssertEqual(r2, j) - XCTAssertEqual(r1 ^ r2, CAtomicsInt32Load(&i, .relaxed)) + XCTAssertEqual(r1 ^ r2, i.load(.relaxed)) - CAtomicsInt32Store(r1, &i, .relaxed) - j = CAtomicsInt32And(r2, &i, .relaxed) + i.store(r1, .relaxed) + j = i.fetch_and(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r1 & r2, CAtomicsInt32Load(&i, .relaxed)) + XCTAssertEqual(r1 & r2, i.load(.relaxed)) j = r1 - CAtomicsInt32Store(r1, &i, .relaxed) - XCTAssertTrue(CAtomicsInt32CAS(&j, r2, &i, .strong, .relaxed, .relaxed)) - XCTAssertEqual(r2, CAtomicsInt32Load(&i, .relaxed)) + i.store(r1, .relaxed) + XCTAssertTrue(i.loadCAS(&j, r2, .strong, .relaxed, .relaxed)) + XCTAssertEqual(r2, i.load(.relaxed)) j = r2 - CAtomicsInt32Store(r1, &i, .relaxed) - while(!CAtomicsInt32CAS(&j, r3, &i, .weak, .relaxed, .relaxed)) {} + i.store(r1, .relaxed) + while(!i.loadCAS(&j, r3, .weak, .relaxed, .relaxed)) {} XCTAssertEqual(r1, j) - XCTAssertEqual(r3, CAtomicsInt32Load(&i, .relaxed)) + XCTAssertEqual(r3, i.load(.relaxed)) } public func testUInt32() { - var i = CAtomicsUInt32() - CAtomicsUInt32Init(0, &i) - XCTAssert(CAtomicsUInt32Load(&i, .relaxed) == 0) + var i = AtomicUInt32() + i.initialize(0) + XCTAssert(i.load(.relaxed) == 0) #if swift(>=4.0) let r1 = UInt32.randomPositive() @@ -483,53 +484,53 @@ public class CAtomicsTests: XCTestCase let r3 = UInt32(truncatingBitPattern: UInt.randomPositive()) #endif - CAtomicsUInt32Store(r1, &i, .relaxed) - XCTAssert(r1 == CAtomicsUInt32Load(&i, .relaxed)) + i.store(r1, .relaxed) + XCTAssert(r1 == i.load(.relaxed)) - var j = CAtomicsUInt32Swap(r2, &i, .relaxed) + var j = i.swap(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r2, CAtomicsUInt32Load(&i, .relaxed)) + XCTAssertEqual(r2, i.load(.relaxed)) - j = CAtomicsUInt32Add(r1, &i, .relaxed) + j = i.fetch_add(r1, .relaxed) XCTAssertEqual(r2, j) - XCTAssertEqual(r1 &+ r2, CAtomicsUInt32Load(&i, .relaxed)) + XCTAssertEqual(r1 &+ r2, i.load(.relaxed)) - j = CAtomicsUInt32Sub(r2, &i, .relaxed) + j = i.fetch_sub(r2, .relaxed) XCTAssertEqual(r1 &+ r2, j) - XCTAssertEqual(r1, CAtomicsUInt32Load(&i, .relaxed)) + XCTAssertEqual(r1, i.load(.relaxed)) - CAtomicsUInt32Store(r1, &i, .relaxed) - j = CAtomicsUInt32Or(r2, &i, .relaxed) + i.store(r1, .relaxed) + j = i.fetch_or(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r1 | r2, CAtomicsUInt32Load(&i, .relaxed)) + XCTAssertEqual(r1 | r2, i.load(.relaxed)) - CAtomicsUInt32Store(r2, &i, .relaxed) - j = CAtomicsUInt32Xor(r1, &i, .relaxed) + i.store(r2, .relaxed) + j = i.fetch_xor(r1, .relaxed) XCTAssertEqual(r2, j) - XCTAssertEqual(r1 ^ r2, CAtomicsUInt32Load(&i, .relaxed)) + XCTAssertEqual(r1 ^ r2, i.load(.relaxed)) - CAtomicsUInt32Store(r1, &i, .relaxed) - j = CAtomicsUInt32And(r2, &i, .relaxed) + i.store(r1, .relaxed) + j = i.fetch_and(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r1 & r2, CAtomicsUInt32Load(&i, .relaxed)) + XCTAssertEqual(r1 & r2, i.load(.relaxed)) j = r1 - CAtomicsUInt32Store(r1, &i, .relaxed) - XCTAssertTrue(CAtomicsUInt32CAS(&j, r2, &i, .strong, .relaxed, .relaxed)) - XCTAssertEqual(r2, CAtomicsUInt32Load(&i, .relaxed)) + i.store(r1, .relaxed) + XCTAssertTrue(i.loadCAS(&j, r2, .strong, .relaxed, .relaxed)) + XCTAssertEqual(r2, i.load(.relaxed)) j = r2 - CAtomicsUInt32Store(r1, &i, .relaxed) - while(!CAtomicsUInt32CAS(&j, r3, &i, .weak, .relaxed, .relaxed)) {} + i.store(r1, .relaxed) + while(!i.loadCAS(&j, r3, .weak, .relaxed, .relaxed)) {} XCTAssertEqual(r1, j) - XCTAssertEqual(r3, CAtomicsUInt32Load(&i, .relaxed)) + XCTAssertEqual(r3, i.load(.relaxed)) } public func testInt64() { - var i = CAtomicsInt64() - CAtomicsInt64Init(0, &i) - XCTAssert(CAtomicsInt64Load(&i, .relaxed) == 0) + var i = AtomicInt64() + i.initialize(0) + XCTAssert(i.load(.relaxed) == 0) #if swift(>=4.0) let r1 = Int64.randomPositive() @@ -541,53 +542,53 @@ public class CAtomicsTests: XCTestCase let r3 = Int64(UInt.randomPositive()) #endif - CAtomicsInt64Store(r1, &i, .relaxed) - XCTAssert(r1 == CAtomicsInt64Load(&i, .relaxed)) + i.store(r1, .relaxed) + XCTAssert(r1 == i.load(.relaxed)) - var j = CAtomicsInt64Swap(r2, &i, .relaxed) + var j = i.swap(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r2, CAtomicsInt64Load(&i, .relaxed)) + XCTAssertEqual(r2, i.load(.relaxed)) - j = CAtomicsInt64Add(r1, &i, .relaxed) + j = i.fetch_add(r1, .relaxed) XCTAssertEqual(r2, j) - XCTAssertEqual(r1 &+ r2, CAtomicsInt64Load(&i, .relaxed)) + XCTAssertEqual(r1 &+ r2, i.load(.relaxed)) - j = CAtomicsInt64Sub(r2, &i, .relaxed) + j = i.fetch_sub(r2, .relaxed) XCTAssertEqual(r1 &+ r2, j) - XCTAssertEqual(r1, CAtomicsInt64Load(&i, .relaxed)) + XCTAssertEqual(r1, i.load(.relaxed)) - CAtomicsInt64Store(r1, &i, .relaxed) - j = CAtomicsInt64Or(r2, &i, .relaxed) + i.store(r1, .relaxed) + j = i.fetch_or(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r1 | r2, CAtomicsInt64Load(&i, .relaxed)) + XCTAssertEqual(r1 | r2, i.load(.relaxed)) - CAtomicsInt64Store(r2, &i, .relaxed) - j = CAtomicsInt64Xor(r1, &i, .relaxed) + i.store(r2, .relaxed) + j = i.fetch_xor(r1, .relaxed) XCTAssertEqual(r2, j) - XCTAssertEqual(r1 ^ r2, CAtomicsInt64Load(&i, .relaxed)) + XCTAssertEqual(r1 ^ r2, i.load(.relaxed)) - CAtomicsInt64Store(r1, &i, .relaxed) - j = CAtomicsInt64And(r2, &i, .relaxed) + i.store(r1, .relaxed) + j = i.fetch_and(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r1 & r2, CAtomicsInt64Load(&i, .relaxed)) + XCTAssertEqual(r1 & r2, i.load(.relaxed)) j = r1 - CAtomicsInt64Store(r1, &i, .relaxed) - XCTAssertTrue(CAtomicsInt64CAS(&j, r2, &i, .strong, .relaxed, .relaxed)) - XCTAssertEqual(r2, CAtomicsInt64Load(&i, .relaxed)) + i.store(r1, .relaxed) + XCTAssertTrue(i.loadCAS(&j, r2, .strong, .relaxed, .relaxed)) + XCTAssertEqual(r2, i.load(.relaxed)) j = r2 - CAtomicsInt64Store(r1, &i, .relaxed) - while(!CAtomicsInt64CAS(&j, r3, &i, .weak, .relaxed, .relaxed)) {} + i.store(r1, .relaxed) + while(!i.loadCAS(&j, r3, .weak, .relaxed, .relaxed)) {} XCTAssertEqual(r1, j) - XCTAssertEqual(r3, CAtomicsInt64Load(&i, .relaxed)) + XCTAssertEqual(r3, i.load(.relaxed)) } public func testUInt64() { - var i = CAtomicsUInt64() - CAtomicsUInt64Init(0, &i) - XCTAssert(CAtomicsUInt64Load(&i, .relaxed) == 0) + var i = AtomicUInt64() + i.initialize(0) + XCTAssert(i.load(.relaxed) == 0) #if swift(>=4.0) let r1 = UInt64.randomPositive() @@ -599,154 +600,183 @@ public class CAtomicsTests: XCTestCase let r3 = UInt64(UInt.randomPositive()) #endif - CAtomicsUInt64Store(r1, &i, .relaxed) - XCTAssert(r1 == CAtomicsUInt64Load(&i, .relaxed)) + i.store(r1, .relaxed) + XCTAssert(r1 == i.load(.relaxed)) - var j = CAtomicsUInt64Swap(r2, &i, .relaxed) + var j = i.swap(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r2, CAtomicsUInt64Load(&i, .relaxed)) + XCTAssertEqual(r2, i.load(.relaxed)) - j = CAtomicsUInt64Add(r1, &i, .relaxed) + j = i.fetch_add(r1, .relaxed) XCTAssertEqual(r2, j) - XCTAssertEqual(r1 &+ r2, CAtomicsUInt64Load(&i, .relaxed)) + XCTAssertEqual(r1 &+ r2, i.load(.relaxed)) - j = CAtomicsUInt64Sub(r2, &i, .relaxed) + j = i.fetch_sub(r2, .relaxed) XCTAssertEqual(r1 &+ r2, j) - XCTAssertEqual(r1, CAtomicsUInt64Load(&i, .relaxed)) + XCTAssertEqual(r1, i.load(.relaxed)) - CAtomicsUInt64Store(r1, &i, .relaxed) - j = CAtomicsUInt64Or(r2, &i, .relaxed) + i.store(r1, .relaxed) + j = i.fetch_or(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r1 | r2, CAtomicsUInt64Load(&i, .relaxed)) + XCTAssertEqual(r1 | r2, i.load(.relaxed)) - CAtomicsUInt64Store(r2, &i, .relaxed) - j = CAtomicsUInt64Xor(r1, &i, .relaxed) + i.store(r2, .relaxed) + j = i.fetch_xor(r1, .relaxed) XCTAssertEqual(r2, j) - XCTAssertEqual(r1 ^ r2, CAtomicsUInt64Load(&i, .relaxed)) + XCTAssertEqual(r1 ^ r2, i.load(.relaxed)) - CAtomicsUInt64Store(r1, &i, .relaxed) - j = CAtomicsUInt64And(r2, &i, .relaxed) + i.store(r1, .relaxed) + j = i.fetch_and(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r1 & r2, CAtomicsUInt64Load(&i, .relaxed)) + XCTAssertEqual(r1 & r2, i.load(.relaxed)) j = r1 - CAtomicsUInt64Store(r1, &i, .relaxed) - XCTAssertTrue(CAtomicsUInt64CAS(&j, r2, &i, .strong, .relaxed, .relaxed)) - XCTAssertEqual(r2, CAtomicsUInt64Load(&i, .relaxed)) + i.store(r1, .relaxed) + XCTAssertTrue(i.loadCAS(&j, r2, .strong, .relaxed, .relaxed)) + XCTAssertEqual(r2, i.load(.relaxed)) j = r2 - CAtomicsUInt64Store(r1, &i, .relaxed) - while(!CAtomicsUInt64CAS(&j, r3, &i, .weak, .relaxed, .relaxed)) {} + i.store(r1, .relaxed) + while(!i.loadCAS(&j, r3, .weak, .relaxed, .relaxed)) {} XCTAssertEqual(r1, j) - XCTAssertEqual(r3, CAtomicsUInt64Load(&i, .relaxed)) + XCTAssertEqual(r3, i.load(.relaxed)) } - public func testMutablePointer() + public func testRawPointer() { - var p = CAtomicsMutablePointer() - CAtomicsMutablePointerInit(nil, &p) - XCTAssert(CAtomicsMutablePointerLoad(&p, .relaxed) == nil) + var p = AtomicRawPointer() + p.initialize(nil) + XCTAssert(p.load(.relaxed) == nil) + + let r1 = UnsafeRawPointer(bitPattern: UInt.randomPositive()) + let r2 = UnsafeRawPointer(bitPattern: UInt.randomPositive()) + let r3 = UnsafeRawPointer(bitPattern: UInt.randomPositive()) + + p.store(r1, .relaxed) + XCTAssert(r1 == p.load(.relaxed)) + + var j = p.swap(r2, .relaxed) + XCTAssertEqual(r1, j) + XCTAssertEqual(r2, p.load(.relaxed)) + + XCTAssertTrue(p.CAS(r2, r3, .strong, .relaxed)) + XCTAssertEqual(r3, p.load(.relaxed)) + + XCTAssertFalse(p.CAS(j, r2, .strong, .relaxed)) + XCTAssertTrue(p.CAS(r3, r2, .strong, .relaxed)) + j = p.load(.relaxed) + XCTAssertTrue(p.CAS(r2, r1, .strong, .relaxed)) + while !p.loadCAS(&j, r3, .weak, .relaxed, .relaxed) {} + XCTAssertEqual(r1, j) + XCTAssertEqual(r3, p.load(.relaxed)) + } + + public func testMutableRawPointer() + { + var p = AtomicMutableRawPointer() + p.initialize(nil) + XCTAssert(p.load(.relaxed) == nil) let r1 = UnsafeMutableRawPointer(bitPattern: UInt.randomPositive()) let r2 = UnsafeMutableRawPointer(bitPattern: UInt.randomPositive()) let r3 = UnsafeMutableRawPointer(bitPattern: UInt.randomPositive()) - CAtomicsMutablePointerStore(r1, &p, .relaxed) - XCTAssert(r1 == CAtomicsMutablePointerLoad(&p, .relaxed)) + p.store(r1, .relaxed) + XCTAssert(r1 == p.load(.relaxed)) - var j = CAtomicsMutablePointerSwap(r2, &p, .relaxed) + var j = p.swap(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r2, CAtomicsMutablePointerLoad(&p, .relaxed)) + XCTAssertEqual(r2, p.load(.relaxed)) - j = r1 - CAtomicsMutablePointerStore(r1, &p, .relaxed) - XCTAssertTrue(CAtomicsMutablePointerCAS(&j, r2, &p, .strong, .relaxed, .relaxed)) - XCTAssertEqual(r2, CAtomicsMutablePointerLoad(&p, .relaxed)) + XCTAssertTrue(p.CAS(r2, r3, .strong, .relaxed)) + XCTAssertEqual(r3, p.load(.relaxed)) - j = r2 - CAtomicsMutablePointerStore(r1, &p, .relaxed) - while(!CAtomicsMutablePointerCAS(&j, r3, &p, .weak, .relaxed, .relaxed)) {} + XCTAssertFalse(p.CAS(j, r2, .strong, .relaxed)) + XCTAssertTrue(p.CAS(r3, r2, .strong, .relaxed)) + j = p.load(.relaxed) + XCTAssertTrue(p.CAS(r2, r1, .strong, .relaxed)) + while !p.loadCAS(&j, r3, .weak, .relaxed, .relaxed) {} XCTAssertEqual(r1, j) - XCTAssertEqual(r3, CAtomicsMutablePointerLoad(&p, .relaxed)) + XCTAssertEqual(r3, p.load(.relaxed)) } - public func testPointer() + public func testOpaquePointer() { - var p = CAtomicsPointer() - CAtomicsPointerInit(nil, &p) - XCTAssert(CAtomicsPointerLoad(&p, .relaxed) == nil) + var p = AtomicOpaquePointer() + p.initialize(nil) + XCTAssert(p.load(.relaxed) == nil) - let r1 = UnsafeRawPointer(bitPattern: UInt.randomPositive()) - let r2 = UnsafeRawPointer(bitPattern: UInt.randomPositive()) - let r3 = UnsafeRawPointer(bitPattern: UInt.randomPositive()) + let r1 = OpaquePointer(bitPattern: UInt.randomPositive()) + let r2 = OpaquePointer(bitPattern: UInt.randomPositive()) + let r3 = OpaquePointer(bitPattern: UInt.randomPositive()) - CAtomicsPointerStore(r1, &p, .relaxed) - XCTAssert(r1 == CAtomicsPointerLoad(&p, .relaxed)) + p.store(r1, .relaxed) + XCTAssert(r1 == p.load(.relaxed)) - var j = CAtomicsPointerSwap(r2, &p, .relaxed) + var j = p.swap(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r2, CAtomicsPointerLoad(&p, .relaxed)) + XCTAssertEqual(r2, p.load(.relaxed)) - j = r1 - CAtomicsPointerStore(r1, &p, .relaxed) - XCTAssertTrue(CAtomicsPointerCAS(&j, r2, &p, .strong, .relaxed, .relaxed)) - XCTAssertEqual(r2, CAtomicsPointerLoad(&p, .relaxed)) + XCTAssertTrue(p.CAS(r2, r3, .strong, .relaxed)) + XCTAssertEqual(r3, p.load(.relaxed)) - j = r2 - CAtomicsPointerStore(r1, &p, .relaxed) - while(!CAtomicsPointerCAS(&j, r3, &p, .weak, .relaxed, .relaxed)) {} + XCTAssertFalse(p.CAS(j, r2, .strong, .relaxed)) + XCTAssertTrue(p.CAS(r3, r2, .strong, .relaxed)) + j = p.load(.relaxed) + XCTAssertTrue(p.CAS(r2, r1, .strong, .relaxed)) + while !p.loadCAS(&j, r3, .weak, .relaxed, .relaxed) {} XCTAssertEqual(r1, j) - XCTAssertEqual(r3, CAtomicsPointerLoad(&p, .relaxed)) + XCTAssertEqual(r3, p.load(.relaxed)) } public func testBool() { - var boolean = CAtomicsBoolean() - CAtomicsBooleanInit(false, &boolean) - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == false) - - CAtomicsBooleanStore(false, &boolean, .relaxed) - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == false) - - CAtomicsBooleanStore(true, &boolean, .relaxed) - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == true) - - CAtomicsBooleanStore(false, &boolean, .relaxed) - CAtomicsBooleanOr(true, &boolean, .relaxed) - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == true) - CAtomicsBooleanOr(false, &boolean, .relaxed) - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == true) - CAtomicsBooleanStore(false, &boolean, .relaxed) - CAtomicsBooleanOr(false, &boolean, .relaxed) - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == false) - CAtomicsBooleanOr(true, &boolean, .relaxed) - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == true) - - CAtomicsBooleanAnd(false, &boolean, .relaxed) - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == false) - CAtomicsBooleanAnd(true, &boolean, .relaxed) - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == false) - - CAtomicsBooleanXor(false, &boolean, .relaxed) - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == false) - CAtomicsBooleanXor(true, &boolean, .relaxed) - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == true) - - let old = CAtomicsBooleanSwap(false, &boolean, .relaxed) + var boolean = AtomicBool() + boolean.initialize(false) + XCTAssert(boolean.load(.relaxed) == false) + + boolean.store(false, .relaxed) + XCTAssert(boolean.load(.relaxed) == false) + + boolean.store(true, .relaxed) + XCTAssert(boolean.load(.relaxed) == true) + + boolean.store(false, .relaxed) + boolean.fetch_or(true, .relaxed) + XCTAssert(boolean.load(.relaxed) == true) + boolean.fetch_or(false, .relaxed) + XCTAssert(boolean.load(.relaxed) == true) + boolean.store(false, .relaxed) + boolean.fetch_or(false, .relaxed) + XCTAssert(boolean.load(.relaxed) == false) + boolean.fetch_or(true, .relaxed) + XCTAssert(boolean.load(.relaxed) == true) + + boolean.fetch_and(false, .relaxed) + XCTAssert(boolean.load(.relaxed) == false) + boolean.fetch_and(true, .relaxed) + XCTAssert(boolean.load(.relaxed) == false) + + boolean.fetch_xor(false, .relaxed) + XCTAssert(boolean.load(.relaxed) == false) + boolean.fetch_xor(true, .relaxed) + XCTAssert(boolean.load(.relaxed) == true) + + let old = boolean.swap(false, .relaxed) XCTAssert(old == true) - XCTAssert(CAtomicsBooleanSwap(true, &boolean, .relaxed) == false) + XCTAssert(boolean.swap(true, .relaxed) == false) var current = true - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == current) - CAtomicsBooleanCAS(¤t, false, &boolean, .strong, .relaxed, .relaxed) - current = CAtomicsBooleanLoad(&boolean, .relaxed) + XCTAssert(boolean.load(.relaxed) == current) + boolean.loadCAS(¤t, false, .strong, .relaxed, .relaxed) + current = boolean.load(.relaxed) XCTAssert(current == false) - if CAtomicsBooleanCAS(¤t, true, &boolean, .strong, .relaxed, .relaxed) + if boolean.loadCAS(¤t, true, .strong, .relaxed, .relaxed) { current = !current - XCTAssert(CAtomicsBooleanCAS(¤t, false, &boolean, .weak, .relaxed, .relaxed)) + XCTAssert(boolean.loadCAS(¤t, false, .weak, .relaxed, .relaxed)) current = !current - XCTAssert(CAtomicsBooleanCAS(¤t, true, &boolean, .weak, .relaxed, .relaxed)) + XCTAssert(boolean.loadCAS(¤t, true, .weak, .relaxed, .relaxed)) } } diff --git a/Tests/CAtomicsTests/CAtomicsTests.swift.gyb b/Tests/CAtomicsTests/CAtomicsTests.swift.gyb index f405048..fbbd7e9 100644 --- a/Tests/CAtomicsTests/CAtomicsTests.swift.gyb +++ b/Tests/CAtomicsTests/CAtomicsTests.swift.gyb @@ -52,15 +52,15 @@ extension UInt } #endif % integers = ['Int', 'UInt', 'Int8', 'UInt8', 'Int16', 'UInt16', 'Int32', 'UInt32', 'Int64', 'UInt64'] -% pointers = ['Mutable', ''] +% pointers = ['Raw', 'MutableRaw', 'Opaque'] public class CAtomicsTests: XCTestCase { public static var allTests = [ % for integer in integers: % end -% for mutable in pointers: - ("test${mutable}Pointer", test${mutable}Pointer), +% for type in pointers: + ("test${type}Pointer", test${type}Pointer), % end ("testBool", testBool), ("testFence", testFence), @@ -69,9 +69,9 @@ public class CAtomicsTests: XCTestCase % for i in integers: public func test${i}() { - var i = CAtomics${i}() - CAtomics${i}Init(0, &i) - XCTAssert(CAtomics${i}Load(&i, .relaxed) == 0) + var i = Atomic${i}() + i.initialize(0) + XCTAssert(i.load(.relaxed) == 0) #if swift(>=4.0) let r1 = ${i}.randomPositive() @@ -84,128 +84,129 @@ public class CAtomicsTests: XCTestCase let r3 = ${i}(${truncating}UInt.randomPositive()) #endif - CAtomics${i}Store(r1, &i, .relaxed) - XCTAssert(r1 == CAtomics${i}Load(&i, .relaxed)) + i.store(r1, .relaxed) + XCTAssert(r1 == i.load(.relaxed)) - var j = CAtomics${i}Swap(r2, &i, .relaxed) + var j = i.swap(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r2, CAtomics${i}Load(&i, .relaxed)) + XCTAssertEqual(r2, i.load(.relaxed)) - j = CAtomics${i}Add(r1, &i, .relaxed) + j = i.fetch_add(r1, .relaxed) XCTAssertEqual(r2, j) - XCTAssertEqual(r1 &+ r2, CAtomics${i}Load(&i, .relaxed)) + XCTAssertEqual(r1 &+ r2, i.load(.relaxed)) - j = CAtomics${i}Sub(r2, &i, .relaxed) + j = i.fetch_sub(r2, .relaxed) XCTAssertEqual(r1 &+ r2, j) - XCTAssertEqual(r1, CAtomics${i}Load(&i, .relaxed)) + XCTAssertEqual(r1, i.load(.relaxed)) - CAtomics${i}Store(r1, &i, .relaxed) - j = CAtomics${i}Or(r2, &i, .relaxed) + i.store(r1, .relaxed) + j = i.fetch_or(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r1 | r2, CAtomics${i}Load(&i, .relaxed)) + XCTAssertEqual(r1 | r2, i.load(.relaxed)) - CAtomics${i}Store(r2, &i, .relaxed) - j = CAtomics${i}Xor(r1, &i, .relaxed) + i.store(r2, .relaxed) + j = i.fetch_xor(r1, .relaxed) XCTAssertEqual(r2, j) - XCTAssertEqual(r1 ^ r2, CAtomics${i}Load(&i, .relaxed)) + XCTAssertEqual(r1 ^ r2, i.load(.relaxed)) - CAtomics${i}Store(r1, &i, .relaxed) - j = CAtomics${i}And(r2, &i, .relaxed) + i.store(r1, .relaxed) + j = i.fetch_and(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r1 & r2, CAtomics${i}Load(&i, .relaxed)) + XCTAssertEqual(r1 & r2, i.load(.relaxed)) j = r1 - CAtomics${i}Store(r1, &i, .relaxed) - XCTAssertTrue(CAtomics${i}CAS(&j, r2, &i, .strong, .relaxed, .relaxed)) - XCTAssertEqual(r2, CAtomics${i}Load(&i, .relaxed)) + i.store(r1, .relaxed) + XCTAssertTrue(i.loadCAS(&j, r2, .strong, .relaxed, .relaxed)) + XCTAssertEqual(r2, i.load(.relaxed)) j = r2 - CAtomics${i}Store(r1, &i, .relaxed) - while(!CAtomics${i}CAS(&j, r3, &i, .weak, .relaxed, .relaxed)) {} + i.store(r1, .relaxed) + while(!i.loadCAS(&j, r3, .weak, .relaxed, .relaxed)) {} XCTAssertEqual(r1, j) - XCTAssertEqual(r3, CAtomics${i}Load(&i, .relaxed)) + XCTAssertEqual(r3, i.load(.relaxed)) } % end -% for mutable in pointers: - public func test${mutable}Pointer() +% for type in pointers: + public func test${type}Pointer() { - var p = CAtomics${mutable}Pointer() - CAtomics${mutable}PointerInit(nil, &p) - XCTAssert(CAtomics${mutable}PointerLoad(&p, .relaxed) == nil) + var p = Atomic${type}Pointer() + p.initialize(nil) + XCTAssert(p.load(.relaxed) == nil) - let r1 = Unsafe${mutable}RawPointer(bitPattern: UInt.randomPositive()) - let r2 = Unsafe${mutable}RawPointer(bitPattern: UInt.randomPositive()) - let r3 = Unsafe${mutable}RawPointer(bitPattern: UInt.randomPositive()) +% native = type if (type == 'Opaque') else "Unsafe" + type + let r1 = ${native}Pointer(bitPattern: UInt.randomPositive()) + let r2 = ${native}Pointer(bitPattern: UInt.randomPositive()) + let r3 = ${native}Pointer(bitPattern: UInt.randomPositive()) - CAtomics${mutable}PointerStore(r1, &p, .relaxed) - XCTAssert(r1 == CAtomics${mutable}PointerLoad(&p, .relaxed)) + p.store(r1, .relaxed) + XCTAssert(r1 == p.load(.relaxed)) - var j = CAtomics${mutable}PointerSwap(r2, &p, .relaxed) + var j = p.swap(r2, .relaxed) XCTAssertEqual(r1, j) - XCTAssertEqual(r2, CAtomics${mutable}PointerLoad(&p, .relaxed)) + XCTAssertEqual(r2, p.load(.relaxed)) - j = r1 - CAtomics${mutable}PointerStore(r1, &p, .relaxed) - XCTAssertTrue(CAtomics${mutable}PointerCAS(&j, r2, &p, .strong, .relaxed, .relaxed)) - XCTAssertEqual(r2, CAtomics${mutable}PointerLoad(&p, .relaxed)) + XCTAssertTrue(p.CAS(r2, r3, .strong, .relaxed)) + XCTAssertEqual(r3, p.load(.relaxed)) - j = r2 - CAtomics${mutable}PointerStore(r1, &p, .relaxed) - while(!CAtomics${mutable}PointerCAS(&j, r3, &p, .weak, .relaxed, .relaxed)) {} + XCTAssertFalse(p.CAS(j, r2, .strong, .relaxed)) + XCTAssertTrue(p.CAS(r3, r2, .strong, .relaxed)) + j = p.load(.relaxed) + XCTAssertTrue(p.CAS(r2, r1, .strong, .relaxed)) + while !p.loadCAS(&j, r3, .weak, .relaxed, .relaxed) {} XCTAssertEqual(r1, j) - XCTAssertEqual(r3, CAtomics${mutable}PointerLoad(&p, .relaxed)) + XCTAssertEqual(r3, p.load(.relaxed)) } % end public func testBool() { - var boolean = CAtomicsBoolean() - CAtomicsBooleanInit(false, &boolean) - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == false) - - CAtomicsBooleanStore(false, &boolean, .relaxed) - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == false) - - CAtomicsBooleanStore(true, &boolean, .relaxed) - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == true) - - CAtomicsBooleanStore(false, &boolean, .relaxed) - CAtomicsBooleanOr(true, &boolean, .relaxed) - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == true) - CAtomicsBooleanOr(false, &boolean, .relaxed) - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == true) - CAtomicsBooleanStore(false, &boolean, .relaxed) - CAtomicsBooleanOr(false, &boolean, .relaxed) - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == false) - CAtomicsBooleanOr(true, &boolean, .relaxed) - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == true) - - CAtomicsBooleanAnd(false, &boolean, .relaxed) - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == false) - CAtomicsBooleanAnd(true, &boolean, .relaxed) - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == false) - - CAtomicsBooleanXor(false, &boolean, .relaxed) - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == false) - CAtomicsBooleanXor(true, &boolean, .relaxed) - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == true) - - let old = CAtomicsBooleanSwap(false, &boolean, .relaxed) + var boolean = AtomicBool() + boolean.initialize(false) + XCTAssert(boolean.load(.relaxed) == false) + + boolean.store(false, .relaxed) + XCTAssert(boolean.load(.relaxed) == false) + + boolean.store(true, .relaxed) + XCTAssert(boolean.load(.relaxed) == true) + + boolean.store(false, .relaxed) + boolean.fetch_or(true, .relaxed) + XCTAssert(boolean.load(.relaxed) == true) + boolean.fetch_or(false, .relaxed) + XCTAssert(boolean.load(.relaxed) == true) + boolean.store(false, .relaxed) + boolean.fetch_or(false, .relaxed) + XCTAssert(boolean.load(.relaxed) == false) + boolean.fetch_or(true, .relaxed) + XCTAssert(boolean.load(.relaxed) == true) + + boolean.fetch_and(false, .relaxed) + XCTAssert(boolean.load(.relaxed) == false) + boolean.fetch_and(true, .relaxed) + XCTAssert(boolean.load(.relaxed) == false) + + boolean.fetch_xor(false, .relaxed) + XCTAssert(boolean.load(.relaxed) == false) + boolean.fetch_xor(true, .relaxed) + XCTAssert(boolean.load(.relaxed) == true) + + let old = boolean.swap(false, .relaxed) XCTAssert(old == true) - XCTAssert(CAtomicsBooleanSwap(true, &boolean, .relaxed) == false) + XCTAssert(boolean.swap(true, .relaxed) == false) var current = true - XCTAssert(CAtomicsBooleanLoad(&boolean, .relaxed) == current) - CAtomicsBooleanCAS(¤t, false, &boolean, .strong, .relaxed, .relaxed) - current = CAtomicsBooleanLoad(&boolean, .relaxed) + XCTAssert(boolean.load(.relaxed) == current) + boolean.loadCAS(¤t, false, .strong, .relaxed, .relaxed) + current = boolean.load(.relaxed) XCTAssert(current == false) - if CAtomicsBooleanCAS(¤t, true, &boolean, .strong, .relaxed, .relaxed) + if boolean.loadCAS(¤t, true, .strong, .relaxed, .relaxed) { current = !current - XCTAssert(CAtomicsBooleanCAS(¤t, false, &boolean, .weak, .relaxed, .relaxed)) + XCTAssert(boolean.loadCAS(¤t, false, .weak, .relaxed, .relaxed)) current = !current - XCTAssert(CAtomicsBooleanCAS(¤t, true, &boolean, .weak, .relaxed, .relaxed)) + XCTAssert(boolean.loadCAS(¤t, true, .weak, .relaxed, .relaxed)) } } diff --git a/Xcode/Atomics.xcodeproj/project.pbxproj b/Xcode/Atomics.xcodeproj/project.pbxproj index d5b7bc5..cfa14b3 100644 --- a/Xcode/Atomics.xcodeproj/project.pbxproj +++ b/Xcode/Atomics.xcodeproj/project.pbxproj @@ -28,7 +28,6 @@ 03CF24BF1F39870D00F4B44B /* .travis.yml in Resources */ = {isa = PBXBuildFile; fileRef = 03CF24BE1F39870D00F4B44B /* .travis.yml */; }; 03D6A82D1DF20AAB00F4B44B /* CAtomics.c in Sources */ = {isa = PBXBuildFile; fileRef = 03D6A82B1DF20AAB00F4B44B /* CAtomics.c */; }; 03D6A82F1DF20AAB00F4B44B /* CAtomics.h in Headers */ = {isa = PBXBuildFile; fileRef = 03D6A82C1DF20AAB00F4B44B /* CAtomics.h */; }; - 03D6A8371DF20AF700F4B44B /* atomics-bool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03D6A8321DF20AF700F4B44B /* atomics-bool.swift */; }; 03D6A83B1DF20AF700F4B44B /* atomics-pointer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03D6A8341DF20AF700F4B44B /* atomics-pointer.swift */; }; 03D6A8421DF20B2700F4B44B /* AtomicsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03D6A8411DF20B2700F4B44B /* AtomicsTests.swift */; }; 03DB46F61B4C7AFC00F4B44B /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03DB46F51B4C7AFC00F4B44B /* AppDelegate.swift */; }; @@ -97,7 +96,6 @@ 03CF24BE1F39870D00F4B44B /* .travis.yml */ = {isa = PBXFileReference; lastKnownFileType = text; name = .travis.yml; path = ../.travis.yml; sourceTree = ""; }; 03D6A82B1DF20AAB00F4B44B /* CAtomics.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = CAtomics.c; path = ../../Sources/CAtomics/CAtomics.c; sourceTree = ""; }; 03D6A82C1DF20AAB00F4B44B /* CAtomics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CAtomics.h; path = ../../Sources/CAtomics/include/CAtomics.h; sourceTree = ""; }; - 03D6A8321DF20AF700F4B44B /* atomics-bool.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "atomics-bool.swift"; path = "../../Sources/Atomics/atomics-bool.swift"; sourceTree = ""; }; 03D6A8341DF20AF700F4B44B /* atomics-pointer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "atomics-pointer.swift"; path = "../../Sources/Atomics/atomics-pointer.swift"; sourceTree = ""; }; 03D6A8411DF20B2700F4B44B /* AtomicsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AtomicsTests.swift; path = ../../Tests/AtomicsTests/AtomicsTests.swift; sourceTree = ""; }; 03D6A8441DF20B3600F4B44B /* LinuxMain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LinuxMain.swift; path = ../../Tests/LinuxMain.swift; sourceTree = ""; }; @@ -178,7 +176,6 @@ children = ( 030110F41B4B896700F4B44B /* Info.plist */, 03D6A8311DF20AC400F4B44B /* CAtomics */, - 03D6A8321DF20AF700F4B44B /* atomics-bool.swift */, 031D7C431ECF59B100F4B44B /* atomics-integer.swift.gyb */, 031D7C451ECF61A800F4B44B /* atomics-integer.swift */, 030F599E1ED04A4600F4B44B /* atomics-pointer.swift.gyb */, @@ -455,7 +452,6 @@ 03D6A83B1DF20AF700F4B44B /* atomics-pointer.swift in Sources */, 03157DAB1E4C4C6D00F4B44B /* atomics-fence.swift in Sources */, 03433D941EC2150200F4B44B /* atomics-reference.swift in Sources */, - 03D6A8371DF20AF700F4B44B /* atomics-bool.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Xcode/AtomicsTests/AtomicsPerformanceTests.swift b/Xcode/AtomicsTests/AtomicsPerformanceTests.swift index 3b367c8..dd060b7 100644 --- a/Xcode/AtomicsTests/AtomicsPerformanceTests.swift +++ b/Xcode/AtomicsTests/AtomicsPerformanceTests.swift @@ -27,7 +27,7 @@ public class AtomicsPerformanceTests: XCTestCase public func testPerformanceStore() { let c = testLoopCount - var m = AtomicInt(0) + var m = AtomicInt() measure { m.store(0) for i in 0..