diff --git a/Sources/Atomics/CMakeLists.txt b/Sources/Atomics/CMakeLists.txt index a2139fb..8df60ec 100644 --- a/Sources/Atomics/CMakeLists.txt +++ b/Sources/Atomics/CMakeLists.txt @@ -8,22 +8,33 @@ See https://swift.org/LICENSE.txt for license information #]] add_library(Atomics - autogenerated/AtomicBool.swift - autogenerated/AtomicLazyReference.swift - autogenerated/HighLevelTypes.swift - autogenerated/IntegerConformances.swift - autogenerated/PointerConformances.swift - autogenerated/Primitives.native.swift - autogenerated/Primitives.shims.swift - AtomicInteger.swift - AtomicMemoryOrderings.swift - AtomicOptional.swift - AtomicOptionalRawRepresentable.swift - AtomicRawRepresentable.swift - AtomicStrongReference.swift - AtomicValue.swift - DoubleWord.swift - "Unmanaged extensions.swift") + "Types/UnsafeAtomicLazyReference.swift" + "Types/IntegerOperations.swift.gyb" + "Types/DoubleWord.swift" + "Types/ManagedAtomic.swift" + "Types/ManagedAtomicLazyReference.swift" + "Types/AtomicMemoryOrderings.swift" + "Types/UnsafeAtomic.swift" + "Types/autogenerated/IntegerOperations.swift" + "Unmanaged extensions.swift" + "Primitives/Primitives.shims.swift.gyb" + "Primitives/Primitives.native.swift.gyb" + "Primitives/autogenerated/Primitives.native.swift" + "Primitives/autogenerated/Primitives.shims.swift" + "Conformances/RawRepresentable.swift" + "Conformances/AtomicBool.swift.gyb" + "Conformances/PointerConformances.swift.gyb" + "Conformances/OptionalRawRepresentable.swift" + "Conformances/IntegerConformances.swift.gyb" + "Conformances/autogenerated/IntegerConformances.swift" + "Conformances/autogenerated/PointerConformances.swift" + "Conformances/autogenerated/AtomicBool.swift" + "Protocols/AtomicInteger.swift" + "Protocols/AtomicValue.swift" + "Protocols/AtomicReference.swift" + "Protocols/AtomicOptionalWrappable.swift" + "Protocols/AtomicStorage.swift") + set_target_properties(Atomics PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64") diff --git a/Sources/Atomics/AtomicBool.swift.gyb b/Sources/Atomics/Conformances/AtomicBool.swift.gyb similarity index 99% rename from Sources/Atomics/AtomicBool.swift.gyb rename to Sources/Atomics/Conformances/AtomicBool.swift.gyb index 5d3aae9..28031c4 100644 --- a/Sources/Atomics/AtomicBool.swift.gyb +++ b/Sources/Atomics/Conformances/AtomicBool.swift.gyb @@ -232,6 +232,7 @@ extension ${construct} where Value == Bool { ordering: ordering) return original ${op} operand } + % end } % end diff --git a/Sources/Atomics/IntegerConformances.swift.gyb b/Sources/Atomics/Conformances/IntegerConformances.swift.gyb similarity index 100% rename from Sources/Atomics/IntegerConformances.swift.gyb rename to Sources/Atomics/Conformances/IntegerConformances.swift.gyb diff --git a/Sources/Atomics/AtomicOptionalRawRepresentable.swift b/Sources/Atomics/Conformances/OptionalRawRepresentable.swift similarity index 100% rename from Sources/Atomics/AtomicOptionalRawRepresentable.swift rename to Sources/Atomics/Conformances/OptionalRawRepresentable.swift diff --git a/Sources/Atomics/PointerConformances.swift.gyb b/Sources/Atomics/Conformances/PointerConformances.swift.gyb similarity index 100% rename from Sources/Atomics/PointerConformances.swift.gyb rename to Sources/Atomics/Conformances/PointerConformances.swift.gyb diff --git a/Sources/Atomics/AtomicRawRepresentable.swift b/Sources/Atomics/Conformances/RawRepresentable.swift similarity index 100% rename from Sources/Atomics/AtomicRawRepresentable.swift rename to Sources/Atomics/Conformances/RawRepresentable.swift diff --git a/Sources/Atomics/autogenerated/AtomicBool.swift b/Sources/Atomics/Conformances/autogenerated/AtomicBool.swift similarity index 99% rename from Sources/Atomics/autogenerated/AtomicBool.swift rename to Sources/Atomics/Conformances/autogenerated/AtomicBool.swift index ed89286..b3125f1 100644 --- a/Sources/Atomics/autogenerated/AtomicBool.swift +++ b/Sources/Atomics/Conformances/autogenerated/AtomicBool.swift @@ -302,6 +302,7 @@ extension UnsafeAtomic where Value == Bool { ordering: ordering) return original && operand } + /// Perform an atomic logical OR operation and return the original value, applying /// the specified memory ordering. /// @@ -320,6 +321,7 @@ extension UnsafeAtomic where Value == Bool { ordering: ordering) return original || operand } + /// Perform an atomic logical XOR operation and return the original value, applying /// the specified memory ordering. /// @@ -338,6 +340,7 @@ extension UnsafeAtomic where Value == Bool { ordering: ordering) return original != operand } + } extension ManagedAtomic where Value == Bool { /// Perform an atomic logical AND operation and return the original value, applying @@ -412,6 +415,7 @@ extension ManagedAtomic where Value == Bool { ordering: ordering) return original && operand } + /// Perform an atomic logical OR operation and return the original value, applying /// the specified memory ordering. /// @@ -430,6 +434,7 @@ extension ManagedAtomic where Value == Bool { ordering: ordering) return original || operand } + /// Perform an atomic logical XOR operation and return the original value, applying /// the specified memory ordering. /// @@ -448,4 +453,5 @@ extension ManagedAtomic where Value == Bool { ordering: ordering) return original != operand } + } diff --git a/Sources/Atomics/autogenerated/IntegerConformances.swift b/Sources/Atomics/Conformances/autogenerated/IntegerConformances.swift similarity index 99% rename from Sources/Atomics/autogenerated/IntegerConformances.swift rename to Sources/Atomics/Conformances/autogenerated/IntegerConformances.swift index a275b72..23a98cb 100644 --- a/Sources/Atomics/autogenerated/IntegerConformances.swift +++ b/Sources/Atomics/Conformances/autogenerated/IntegerConformances.swift @@ -2092,7 +2092,7 @@ extension UInt.AtomicRepresentation: AtomicIntegerStorage { -#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32) +#if (compiler(>=5.9) && _pointerBitWidth(_32)) || (compiler(<5.9) && (arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32))) extension DoubleWord: AtomicValue { @frozen public struct AtomicRepresentation { @@ -2229,7 +2229,7 @@ extension DoubleWord.AtomicRepresentation: AtomicStorage { -#else /* arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32) */ +#else /* (compiler(>=5.9) && _pointerBitWidth(_32)) || (compiler(<5.9) && (arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32))) */ extension DoubleWord: AtomicValue { @frozen public struct AtomicRepresentation { @@ -2363,5 +2363,5 @@ extension DoubleWord.AtomicRepresentation: AtomicStorage { } } -#endif /* arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32) */ +#endif /* (compiler(>=5.9) && _pointerBitWidth(_32)) || (compiler(<5.9) && (arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32))) */ diff --git a/Sources/Atomics/autogenerated/PointerConformances.swift b/Sources/Atomics/Conformances/autogenerated/PointerConformances.swift similarity index 100% rename from Sources/Atomics/autogenerated/PointerConformances.swift rename to Sources/Atomics/Conformances/autogenerated/PointerConformances.swift diff --git a/Sources/Atomics/Primitives.native.swift.gyb b/Sources/Atomics/Primitives/Primitives.native.swift.gyb similarity index 90% rename from Sources/Atomics/Primitives.native.swift.gyb rename to Sources/Atomics/Primitives/Primitives.native.swift.gyb index 2778654..6665355 100644 --- a/Sources/Atomics/Primitives.native.swift.gyb +++ b/Sources/Atomics/Primitives/Primitives.native.swift.gyb @@ -18,57 +18,9 @@ ${autogenerated_warning()} #if ATOMICS_NATIVE_BUILTINS import Builtin -#if ${ptrBitWidth32} -@frozen -@_alignment(8) -public struct DoubleWord { - @usableFromInline - internal typealias _Builtin = Builtin.Int64 - - public var first: UInt - public var second: UInt - - @inlinable @inline(__always) - public init(first: UInt, second: UInt) { - self.first = first - self.second = second - } -} -#else -@frozen -@_alignment(16) -public struct DoubleWord { - @usableFromInline - internal typealias _Builtin = Builtin.Int128 - - public var first: UInt - public var second: UInt - - @inlinable @inline(__always) - public init(first: UInt, second: UInt) { - self.first = first - self.second = second - } -} -#endif - -extension DoubleWord { - @_alwaysEmitIntoClient - @inline(__always) - internal init(_ builtin: _Builtin) { - self = unsafeBitCast(builtin, to: DoubleWord.self) - } - - @_alwaysEmitIntoClient - @inline(__always) - internal var _value: _Builtin { - unsafeBitCast(self, to: _Builtin.self) - } -} - extension Bool { @_alwaysEmitIntoClient - @inline(__always) + @_transparent internal init(_ builtin: Builtin.Int1) { self = unsafeBitCast(builtin, to: Bool.self) } diff --git a/Sources/Atomics/Primitives.shims.swift.gyb b/Sources/Atomics/Primitives/Primitives.shims.swift.gyb similarity index 100% rename from Sources/Atomics/Primitives.shims.swift.gyb rename to Sources/Atomics/Primitives/Primitives.shims.swift.gyb diff --git a/Sources/Atomics/autogenerated/Primitives.native.swift b/Sources/Atomics/Primitives/autogenerated/Primitives.native.swift similarity index 99% rename from Sources/Atomics/autogenerated/Primitives.native.swift rename to Sources/Atomics/Primitives/autogenerated/Primitives.native.swift index 2d55a15..68d9d4b 100644 --- a/Sources/Atomics/autogenerated/Primitives.native.swift +++ b/Sources/Atomics/Primitives/autogenerated/Primitives.native.swift @@ -21,57 +21,9 @@ #if ATOMICS_NATIVE_BUILTINS import Builtin -#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32) -@frozen -@_alignment(8) -public struct DoubleWord { - @usableFromInline - internal typealias _Builtin = Builtin.Int64 - - public var first: UInt - public var second: UInt - - @inlinable @inline(__always) - public init(first: UInt, second: UInt) { - self.first = first - self.second = second - } -} -#else -@frozen -@_alignment(16) -public struct DoubleWord { - @usableFromInline - internal typealias _Builtin = Builtin.Int128 - - public var first: UInt - public var second: UInt - - @inlinable @inline(__always) - public init(first: UInt, second: UInt) { - self.first = first - self.second = second - } -} -#endif - -extension DoubleWord { - @_alwaysEmitIntoClient - @inline(__always) - internal init(_ builtin: _Builtin) { - self = unsafeBitCast(builtin, to: DoubleWord.self) - } - - @_alwaysEmitIntoClient - @inline(__always) - internal var _value: _Builtin { - unsafeBitCast(self, to: _Builtin.self) - } -} - extension Bool { @_alwaysEmitIntoClient - @inline(__always) + @_transparent internal init(_ builtin: Builtin.Int1) { self = unsafeBitCast(builtin, to: Bool.self) } @@ -2150,7 +2102,7 @@ extension UnsafeMutablePointer where Pointee == Int64 { } } -#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32) +#if (compiler(>=5.9) && _pointerBitWidth(_32)) || (compiler(<5.9) && (arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32))) extension UnsafeMutablePointer where Pointee == Int { /// Atomically loads a word starting at this address with the specified /// memory ordering. @@ -2663,7 +2615,7 @@ extension UnsafeMutablePointer where Pointee == Int { } } -#else /* arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32) */ +#else /* (compiler(>=5.9) && _pointerBitWidth(_32)) || (compiler(<5.9) && (arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32))) */ extension UnsafeMutablePointer where Pointee == Int { /// Atomically loads a word starting at this address with the specified /// memory ordering. @@ -3175,8 +3127,8 @@ extension UnsafeMutablePointer where Pointee == Int { } } } -#endif /* arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32) */ -#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32) +#endif /* (compiler(>=5.9) && _pointerBitWidth(_32)) || (compiler(<5.9) && (arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32))) */ +#if (compiler(>=5.9) && _pointerBitWidth(_32)) || (compiler(<5.9) && (arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32))) extension UnsafeMutablePointer where Pointee == DoubleWord { /// Atomically loads a word starting at this address with the specified /// memory ordering. @@ -3493,7 +3445,7 @@ extension UnsafeMutablePointer where Pointee == DoubleWord { } -#else /* arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32) */ +#else /* (compiler(>=5.9) && _pointerBitWidth(_32)) || (compiler(<5.9) && (arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32))) */ extension UnsafeMutablePointer where Pointee == DoubleWord { /// Atomically loads a word starting at this address with the specified /// memory ordering. @@ -3809,5 +3761,5 @@ extension UnsafeMutablePointer where Pointee == DoubleWord { } } -#endif /* arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32) */ +#endif /* (compiler(>=5.9) && _pointerBitWidth(_32)) || (compiler(<5.9) && (arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32))) */ #endif // ATOMICS_NATIVE_BUILTINS diff --git a/Sources/Atomics/autogenerated/Primitives.shims.swift b/Sources/Atomics/Primitives/autogenerated/Primitives.shims.swift similarity index 100% rename from Sources/Atomics/autogenerated/Primitives.shims.swift rename to Sources/Atomics/Primitives/autogenerated/Primitives.shims.swift diff --git a/Sources/Atomics/AtomicInteger.swift b/Sources/Atomics/Protocols/AtomicInteger.swift similarity index 100% rename from Sources/Atomics/AtomicInteger.swift rename to Sources/Atomics/Protocols/AtomicInteger.swift diff --git a/Sources/Atomics/AtomicOptional.swift b/Sources/Atomics/Protocols/AtomicOptionalWrappable.swift similarity index 100% rename from Sources/Atomics/AtomicOptional.swift rename to Sources/Atomics/Protocols/AtomicOptionalWrappable.swift diff --git a/Sources/Atomics/AtomicStrongReference.swift b/Sources/Atomics/Protocols/AtomicReference.swift similarity index 100% rename from Sources/Atomics/AtomicStrongReference.swift rename to Sources/Atomics/Protocols/AtomicReference.swift diff --git a/Sources/Atomics/AtomicValue.swift b/Sources/Atomics/Protocols/AtomicStorage.swift similarity index 97% rename from Sources/Atomics/AtomicValue.swift rename to Sources/Atomics/Protocols/AtomicStorage.swift index 0aabb4f..d546f3d 100644 --- a/Sources/Atomics/AtomicValue.swift +++ b/Sources/Atomics/Protocols/AtomicStorage.swift @@ -10,14 +10,6 @@ // //===----------------------------------------------------------------------===// -/// A type that supports atomic operations through a separate atomic storage -/// representation. -public protocol AtomicValue { - /// The atomic storage representation for this value. - associatedtype AtomicRepresentation: AtomicStorage - /* where Self is a subtype of AtomicRepresentation.Value */ -} - /// The storage representation for an atomic value, providing pointer-based /// atomic operations. This is a low-level implementation detail of atomic /// types; instead of directly handling conforming types, it is usually better diff --git a/Sources/Atomics/Protocols/AtomicValue.swift b/Sources/Atomics/Protocols/AtomicValue.swift new file mode 100644 index 0000000..402de19 --- /dev/null +++ b/Sources/Atomics/Protocols/AtomicValue.swift @@ -0,0 +1,19 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift Atomics open source project +// +// Copyright (c) 2020 - 2023 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +/// A type that supports atomic operations through a separate atomic storage +/// representation. +public protocol AtomicValue { + /// The atomic storage representation for this value. + associatedtype AtomicRepresentation: AtomicStorage + /* where Self is a subtype of AtomicRepresentation.Value */ +} diff --git a/Sources/Atomics/AtomicMemoryOrderings.swift b/Sources/Atomics/Types/AtomicMemoryOrderings.swift similarity index 100% rename from Sources/Atomics/AtomicMemoryOrderings.swift rename to Sources/Atomics/Types/AtomicMemoryOrderings.swift diff --git a/Sources/Atomics/DoubleWord.swift b/Sources/Atomics/Types/DoubleWord.swift similarity index 65% rename from Sources/Atomics/DoubleWord.swift rename to Sources/Atomics/Types/DoubleWord.swift index 567dfcb..9a260c7 100644 --- a/Sources/Atomics/DoubleWord.swift +++ b/Sources/Atomics/Types/DoubleWord.swift @@ -10,7 +10,60 @@ // //===----------------------------------------------------------------------===// -#if !ATOMICS_NATIVE_BUILTINS +#if ATOMICS_NATIVE_BUILTINS +import Builtin + +#if _pointerBitWidth(_32) +@frozen +@_alignment(8) +public struct DoubleWord { + @usableFromInline + internal typealias _Builtin = Builtin.Int64 + + public var first: UInt + public var second: UInt + + @inlinable @inline(__always) + public init(first: UInt, second: UInt) { + self.first = first + self.second = second + } +} +#elseif _pointerBitWidth(_64) +@frozen +@_alignment(16) +public struct DoubleWord { + @usableFromInline + internal typealias _Builtin = Builtin.Int128 + + public var first: UInt + public var second: UInt + + @inlinable @inline(__always) + public init(first: UInt, second: UInt) { + self.first = first + self.second = second + } +} +#else +#error("Unexpected pointer bit width") +#endif + +extension DoubleWord { + @_alwaysEmitIntoClient + @_transparent + internal init(_ builtin: _Builtin) { + self = unsafeBitCast(builtin, to: DoubleWord.self) + } + + @_alwaysEmitIntoClient + @_transparent + internal var _value: _Builtin { + unsafeBitCast(self, to: _Builtin.self) + } +} + +#else // !ATOMICS_NATIVE_BUILTINS import _AtomicsShims public typealias DoubleWord = _AtomicsShims.DoubleWord #endif diff --git a/Sources/Atomics/Types/IntegerOperations.swift.gyb b/Sources/Atomics/Types/IntegerOperations.swift.gyb new file mode 100644 index 0000000..2251659 --- /dev/null +++ b/Sources/Atomics/Types/IntegerOperations.swift.gyb @@ -0,0 +1,111 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift Atomics open source project +// +// Copyright (c) 2020 - 2023 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +%{ + from gyb_utils import ( + autogenerated_warning, integerOperations, lowerFirst, argLabel) +}% +${autogenerated_warning()} + +% for construct in ["UnsafeAtomic", "ManagedAtomic"]: +extension ${construct} where Value: AtomicInteger { + % for (name, _, op, label, doc) in integerOperations: + /// Perform an atomic ${doc} operation and return the original value, applying + /// the specified memory ordering. + /// + % if "Wrapping" in name: + /// Note: This operation silently wraps around on overflow, like the + /// `${op}` operator does on `Int` values. + /// + % end + /// - Parameter operand: An integer value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The original value before the operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func loadThen${name}( + ${label} operand: Value${" = 1" if "crement" in name else ""}, + ordering: AtomicUpdateOrdering + ) -> Value { + _Storage.atomicLoadThen${name}( + ${argLabel(label)}operand, + at: _ptr, + ordering: ordering) + } + + % end + % for (name, _, op, label, doc) in integerOperations: + /// Perform an atomic ${doc} operation and return the new value, applying + /// the specified memory ordering. + /// + % if "Wrapping" in name: + /// Note: This operation silently wraps around on overflow, like the + /// `${op}` operator does on `Int` values. + /// + % end + /// - Parameter operand: An integer value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The new value after the operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func ${lowerFirst(name)}ThenLoad( + ${label} operand: Value${" = 1" if "crement" in name else ""}, + ordering: AtomicUpdateOrdering + ) -> Value { + let original = _Storage.atomicLoadThen${name}( + ${argLabel(label)}operand, + at: _ptr, + ordering: ordering) + return original ${op} operand + } + + % end + + /// Perform an atomic wrapping increment operation applying the + /// specified memory ordering. + /// + /// Note: This operation silently wraps around on overflow, like the + /// `&+=` operator does on `Int` values. + /// + /// - Parameter operand: The value to add to the current value. + /// - Parameter ordering: The memory ordering to apply on this operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func wrappingIncrement( + by operand: Value = 1, + ordering: AtomicUpdateOrdering + ) { + _ = _Storage.atomicLoadThenWrappingIncrement( + by: operand, + at: _ptr, + ordering: ordering) + } + + /// Perform an atomic wrapping decrement operation applying the + /// specified memory ordering. + /// + /// Note: This operation silently wraps around on overflow, like the + /// `&-=` operator does on `Int` values. + /// + /// - Parameter operand: The value to subtract from the current value. + /// - Parameter ordering: The memory ordering to apply on this operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func wrappingDecrement( + by operand: Value = 1, + ordering: AtomicUpdateOrdering + ) { + _ = _Storage.atomicLoadThenWrappingDecrement( + by: operand, + at: _ptr, + ordering: ordering) + } +} diff --git a/Sources/Atomics/Types/ManagedAtomic.swift b/Sources/Atomics/Types/ManagedAtomic.swift new file mode 100644 index 0000000..649374d --- /dev/null +++ b/Sources/Atomics/Types/ManagedAtomic.swift @@ -0,0 +1,266 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift Atomics open source project +// +// Copyright (c) 2020 - 2023 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +/// A reference type holding an atomic value, with automatic memory management. +@_fixed_layout +public class ManagedAtomic +where Value.AtomicRepresentation.Value == Value { + // Note: the Value.AtomicRepresentation.Value == Value requirement could be relaxed, + // at the cost of adding a bunch of potentially ambiguous overloads. + // (We'd need one set of implementations for the type equality condition, + // and another for `Value: AtomicReference`.) + + @usableFromInline + internal typealias _Storage = Value.AtomicRepresentation + + /// The atomic representation of the value stored inside. + /// + /// Warning: This ivar must only ever be accessed via `_ptr` after + /// its initialization. + @usableFromInline + internal var __storage: _Storage + + /// Initialize a new managed atomic instance holding the specified initial + /// value. + @inline(__always) @_alwaysEmitIntoClient + public init(_ value: Value) { + __storage = _Storage(value) + } + + deinit { + _ = _ptr.pointee.dispose() + } + + @_alwaysEmitIntoClient @inline(__always) + internal var _ptr: UnsafeMutablePointer<_Storage> { + _getUnsafePointerToStoredProperties(self) + .assumingMemoryBound(to: _Storage.self) + } +} + +extension ManagedAtomic: @unchecked Sendable where Value: Sendable {} + +extension ManagedAtomic { + /// Atomically loads and returns the current value, applying the specified + /// memory ordering. + /// + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The current value. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func load( + ordering: AtomicLoadOrdering + ) -> Value { + _Storage.atomicLoad(at: _ptr, ordering: ordering) + } + + /// Atomically sets the current value to `desired`, applying the specified + /// memory ordering. + /// + /// - Parameter desired: The desired new value. + /// - Parameter ordering: The memory ordering to apply on this operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func store( + _ desired: __owned Value, + ordering: AtomicStoreOrdering + ) { + _Storage.atomicStore(desired, at: _ptr, ordering: ordering) + } + + /// Atomically sets the current value to `desired` and returns the original + /// value, applying the specified memory ordering. + /// + /// - Parameter desired: The desired new value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The original value. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func exchange( + _ desired: __owned Value, + ordering: AtomicUpdateOrdering + ) -> Value { + _Storage.atomicExchange(desired, at: _ptr, ordering: ordering) + } + + /// Perform an atomic compare and exchange operation on the current value, + /// applying the specified memory ordering. + /// + /// This operation performs the following algorithm as a single atomic + /// transaction: + /// + /// ``` + /// atomic(self) { currentValue in + /// let original = currentValue + /// guard original == expected else { return (false, original) } + /// currentValue = desired + /// return (true, original) + /// } + /// ``` + /// + /// This method implements a "strong" compare and exchange operation + /// that does not permit spurious failures. + /// + /// - Parameter expected: The expected current value. + /// - Parameter desired: The desired new value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: A tuple `(exchanged, original)`, where `exchanged` is true if + /// the exchange was successful, and `original` is the original value. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func compareExchange( + expected: Value, + desired: __owned Value, + ordering: AtomicUpdateOrdering + ) -> (exchanged: Bool, original: Value) { + _Storage.atomicCompareExchange( + expected: expected, + desired: desired, + at: _ptr, + ordering: ordering) + } + + /// Perform an atomic compare and exchange operation on the current value, + /// applying the specified success/failure memory orderings. + /// + /// This operation performs the following algorithm as a single atomic + /// transaction: + /// + /// ``` + /// atomic(self) { currentValue in + /// let original = currentValue + /// guard original == expected else { return (false, original) } + /// currentValue = desired + /// return (true, original) + /// } + /// ``` + /// + /// The `successOrdering` argument specifies the memory ordering to use when + /// the operation manages to update the current value, while `failureOrdering` + /// will be used when the operation leaves the value intact. + /// + /// This method implements a "strong" compare and exchange operation + /// that does not permit spurious failures. + /// + /// - Parameter expected: The expected current value. + /// - Parameter desired: The desired new value. + /// - Parameter successOrdering: The memory ordering to apply if this + /// operation performs the exchange. + /// - Parameter failureOrdering: The memory ordering to apply on this + /// operation does not perform the exchange. + /// - Returns: A tuple `(exchanged, original)`, where `exchanged` is true if + /// the exchange was successful, and `original` is the original value. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func compareExchange( + expected: Value, + desired: __owned Value, + successOrdering: AtomicUpdateOrdering, + failureOrdering: AtomicLoadOrdering + ) -> (exchanged: Bool, original: Value) { + _Storage.atomicCompareExchange( + expected: expected, + desired: desired, + at: _ptr, + successOrdering: successOrdering, + failureOrdering: failureOrdering) + } + + /// Perform an atomic weak compare and exchange operation on the current + /// value, applying the memory ordering. This compare-exchange variant is + /// allowed to spuriously fail; it is designed to be called in a loop until + /// it indicates a successful exchange has happened. + /// + /// This operation performs the following algorithm as a single atomic + /// transaction: + /// + /// ``` + /// atomic(self) { currentValue in + /// let original = currentValue + /// guard original == expected else { return (false, original) } + /// currentValue = desired + /// return (true, original) + /// } + /// ``` + /// + /// (In this weak form, transient conditions may cause the `original == + /// expected` check to sometimes return false when the two values are in fact + /// the same.) + /// + /// - Parameter expected: The expected current value. + /// - Parameter desired: The desired new value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: A tuple `(exchanged, original)`, where `exchanged` is true if + /// the exchange was successful, and `original` is the original value. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func weakCompareExchange( + expected: Value, + desired: __owned Value, + ordering: AtomicUpdateOrdering + ) -> (exchanged: Bool, original: Value) { + _Storage.atomicWeakCompareExchange( + expected: expected, + desired: desired, + at: _ptr, + ordering: ordering) + } + + /// Perform an atomic weak compare and exchange operation on the current + /// value, applying the specified success/failure memory orderings. This + /// compare-exchange variant is allowed to spuriously fail; it is designed to + /// be called in a loop until it indicates a successful exchange has happened. + /// + /// This operation performs the following algorithm as a single atomic + /// transaction: + /// + /// ``` + /// atomic(self) { currentValue in + /// let original = currentValue + /// guard original == expected else { return (false, original) } + /// currentValue = desired + /// return (true, original) + /// } + /// ``` + /// + /// (In this weak form, transient conditions may cause the `original == + /// expected` check to sometimes return false when the two values are in fact + /// the same.) + /// + /// The `ordering` argument specifies the memory ordering to use when the + /// operation manages to update the current value, while `failureOrdering` + /// will be used when the operation leaves the value intact. + /// + /// - Parameter expected: The expected current value. + /// - Parameter desired: The desired new value. + /// - Parameter successOrdering: The memory ordering to apply if this + /// operation performs the exchange. + /// - Parameter failureOrdering: The memory ordering to apply on this + /// operation does not perform the exchange. + /// - Returns: A tuple `(exchanged, original)`, where `exchanged` is true if + /// the exchange was successful, and `original` is the original value. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func weakCompareExchange( + expected: Value, + desired: __owned Value, + successOrdering: AtomicUpdateOrdering, + failureOrdering: AtomicLoadOrdering + ) -> (exchanged: Bool, original: Value) { + _Storage.atomicWeakCompareExchange( + expected: expected, + desired: desired, + at: _ptr, + successOrdering: successOrdering, + failureOrdering: failureOrdering) + } +} diff --git a/Sources/Atomics/Types/ManagedAtomicLazyReference.swift b/Sources/Atomics/Types/ManagedAtomicLazyReference.swift new file mode 100644 index 0000000..104920d --- /dev/null +++ b/Sources/Atomics/Types/ManagedAtomicLazyReference.swift @@ -0,0 +1,103 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift Atomics open source project +// +// Copyright (c) 2020 - 2023 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +/// A reference type holding a lazily initializable atomic +/// strong reference, with automatic memory management. +/// +/// These values can be set (initialized) exactly once, but read many +/// times. +@_fixed_layout +public class ManagedAtomicLazyReference { + /// The value logically stored in an atomic lazy reference value. + public typealias Value = Instance? + + @usableFromInline + internal typealias _Rep = Optional>.AtomicRepresentation + + /// The atomic representation of the value stored inside. + /// + /// Warning: This ivar must only ever be accessed via `_ptr` after + /// its initialization. + @usableFromInline + internal let _storage: _Rep + + /// Initializes a new managed atomic lazy reference with a nil value. + @inlinable + public init() { + _storage = _Rep(nil) + } + + deinit { + if let unmanaged = _ptr.pointee.dispose() { + unmanaged.release() + } + } + + @_alwaysEmitIntoClient @inline(__always) + internal var _ptr: UnsafeMutablePointer<_Rep> { + _getUnsafePointerToStoredProperties(self).assumingMemoryBound(to: _Rep.self) + } +} + +extension ManagedAtomicLazyReference: @unchecked Sendable +where Instance: Sendable {} + +extension ManagedAtomicLazyReference { + /// Atomically initializes this reference if its current value is nil, then + /// returns the initialized value. If this reference is already initialized, + /// then `storeIfNilThenLoad(_:)` discards its supplied argument and returns + /// the current value without updating it. + /// + /// The following example demonstrates how this can be used to implement a + /// thread-safe lazily initialized reference: + /// + /// ``` + /// class Image { + /// var _histogram: UnsafeAtomicLazyReference = .init() + /// + /// // This is safe to call concurrently from multiple threads. + /// var atomicLazyHistogram: Histogram { + /// if let histogram = _histogram.load() { return histogram } + /// // Note that code here may run concurrently on + /// // multiple threads, but only one of them will get to + /// // succeed setting the reference. + /// let histogram = ... + /// return _histogram.storeIfNilThenLoad(histogram) + /// } + /// ``` + /// + /// This operation uses acquiring-and-releasing memory ordering. + public func storeIfNilThenLoad(_ desired: __owned Instance) -> Instance { + let desiredUnmanaged = Unmanaged.passRetained(desired) + let (exchanged, current) = _Rep.atomicCompareExchange( + expected: nil, + desired: desiredUnmanaged, + at: _ptr, + ordering: .acquiringAndReleasing) + if !exchanged { + // The reference has already been initialized. Balance the retain that + // we performed on `desired`. + desiredUnmanaged.release() + return current!.takeUnretainedValue() + } + return desiredUnmanaged.takeUnretainedValue() + } + + /// Atomically loads and returns the current value of this reference. + /// + /// The load operation is performed with the memory ordering + /// `AtomicLoadOrdering.acquiring`. + public func load() -> Instance? { + let value = _Rep.atomicLoad(at: _ptr, ordering: .acquiring) + return value?.takeUnretainedValue() + } +} diff --git a/Sources/Atomics/HighLevelTypes.swift.gyb b/Sources/Atomics/Types/UnsafeAtomic.swift similarity index 69% rename from Sources/Atomics/HighLevelTypes.swift.gyb rename to Sources/Atomics/Types/UnsafeAtomic.swift index a7f2735..1486d15 100644 --- a/Sources/Atomics/HighLevelTypes.swift.gyb +++ b/Sources/Atomics/Types/UnsafeAtomic.swift @@ -9,21 +9,16 @@ // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// -%{ - from gyb_utils import ( - autogenerated_warning, integerOperations, lowerFirst, argLabel) -}% -${autogenerated_warning()} /// An unsafe reference type holding an atomic value, requiring manual memory /// management of the underlying storage representation. @frozen public struct UnsafeAtomic where Value.AtomicRepresentation.Value == Value { - // Note: the Value.AtomicRepresentation.Value == Value requirement could be relaxed, - // at the cost of adding a bunch of potentially ambiguous overloads. - // (We'd need one set of implementations for the type equality condition, - // and another for `Value: AtomicReference`.) + // Note: the Value.AtomicRepresentation.Value == Value requirement could be + // relaxed, at the cost of adding a bunch of potentially ambiguous overloads. + // (We'd need one set of implementations for the type equality condition, and + // another for `Value: AtomicReference`.) public typealias Storage = Value.AtomicRepresentation @usableFromInline @@ -81,47 +76,7 @@ where Value.AtomicRepresentation.Value == Value { extension UnsafeAtomic: @unchecked Sendable where Value: Sendable {} -/// A reference type holding an atomic value, with automatic memory management. -@_fixed_layout -public class ManagedAtomic -where Value.AtomicRepresentation.Value == Value { - // Note: the Value.AtomicRepresentation.Value == Value requirement could be relaxed, - // at the cost of adding a bunch of potentially ambiguous overloads. - // (We'd need one set of implementations for the type equality condition, - // and another for `Value: AtomicReference`.) - - @usableFromInline - internal typealias _Storage = Value.AtomicRepresentation - - /// The atomic representation of the value stored inside. - /// - /// Warning: This ivar must only ever be accessed via `_ptr` after - /// its initialization. - @usableFromInline - internal var _storage: _Storage - - /// Initialize a new managed atomic instance holding the specified initial - /// value. - @inline(__always) @_alwaysEmitIntoClient - public init(_ value: Value) { - _storage = _Storage(value) - } - - deinit { - _ = _ptr.pointee.dispose() - } - - @_alwaysEmitIntoClient @inline(__always) - internal var _ptr: UnsafeMutablePointer<_Storage> { - _getUnsafePointerToStoredProperties(self) - .assumingMemoryBound(to: _Storage.self) - } -} - -extension ManagedAtomic: @unchecked Sendable where Value: Sendable {} - -% for type in ["UnsafeAtomic", "ManagedAtomic"]: -extension ${type} { +extension UnsafeAtomic { /// Atomically loads and returns the current value, applying the specified /// memory ordering. /// @@ -336,97 +291,3 @@ extension ${type} { failureOrdering: failureOrdering) } } - -extension ${type} where Value: AtomicInteger { - % for (name, _, op, label, doc) in integerOperations: - /// Perform an atomic ${doc} operation and return the original value, applying - /// the specified memory ordering. - /// - % if "Wrapping" in name: - /// Note: This operation silently wraps around on overflow, like the - /// `${op}` operator does on `Int` values. - /// - % end - /// - Parameter operand: An integer value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The original value before the operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func loadThen${name}( - ${label} operand: Value${" = 1" if "crement" in name else ""}, - ordering: AtomicUpdateOrdering - ) -> Value { - _Storage.atomicLoadThen${name}( - ${argLabel(label)}operand, - at: _ptr, - ordering: ordering) - } - % end - - % for (name, _, op, label, doc) in integerOperations: - /// Perform an atomic ${doc} operation and return the new value, applying - /// the specified memory ordering. - /// - % if "Wrapping" in name: - /// Note: This operation silently wraps around on overflow, like the - /// `${op}` operator does on `Int` values. - /// - % end - /// - Parameter operand: An integer value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The new value after the operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func ${lowerFirst(name)}ThenLoad( - ${label} operand: Value${" = 1" if "crement" in name else ""}, - ordering: AtomicUpdateOrdering - ) -> Value { - let original = _Storage.atomicLoadThen${name}( - ${argLabel(label)}operand, - at: _ptr, - ordering: ordering) - return original ${op} operand - } - % end - - /// Perform an atomic wrapping increment operation applying the - /// specified memory ordering. - /// - /// Note: This operation silently wraps around on overflow, like the - /// `&+=` operator does on `Int` values. - /// - /// - Parameter operand: The value to add to the current value. - /// - Parameter ordering: The memory ordering to apply on this operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func wrappingIncrement( - by operand: Value = 1, - ordering: AtomicUpdateOrdering - ) { - _ = _Storage.atomicLoadThenWrappingIncrement( - by: operand, - at: _ptr, - ordering: ordering) - } - - /// Perform an atomic wrapping decrement operation applying the - /// specified memory ordering. - /// - /// Note: This operation silently wraps around on overflow, like the - /// `&-=` operator does on `Int` values. - /// - /// - Parameter operand: The value to subtract from the current value. - /// - Parameter ordering: The memory ordering to apply on this operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func wrappingDecrement( - by operand: Value = 1, - ordering: AtomicUpdateOrdering - ) { - _ = _Storage.atomicLoadThenWrappingDecrement( - by: operand, - at: _ptr, - ordering: ordering) - } -} -%end diff --git a/Sources/Atomics/AtomicLazyReference.swift.gyb b/Sources/Atomics/Types/UnsafeAtomicLazyReference.swift similarity index 80% rename from Sources/Atomics/AtomicLazyReference.swift.gyb rename to Sources/Atomics/Types/UnsafeAtomicLazyReference.swift index 0767635..c34bd05 100644 --- a/Sources/Atomics/AtomicLazyReference.swift.gyb +++ b/Sources/Atomics/Types/UnsafeAtomicLazyReference.swift @@ -9,10 +9,6 @@ // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// -%{ - from gyb_utils import autogenerated_warning -}% -${autogenerated_warning()} /// An unsafe reference type holding a lazily initializable atomic /// strong reference, requiring manual memory management of the @@ -122,49 +118,7 @@ extension UnsafeAtomicLazyReference { } } -/// A reference type holding a lazily initializable atomic -/// strong reference, with automatic memory management. -/// -/// These values can be set (initialized) exactly once, but read many -/// times. -@_fixed_layout -public class ManagedAtomicLazyReference { - /// The value logically stored in an atomic lazy reference value. - public typealias Value = Instance? - - @usableFromInline - internal typealias _Rep = Optional>.AtomicRepresentation - - /// The atomic representation of the value stored inside. - /// - /// Warning: This ivar must only ever be accessed via `_ptr` after - /// its initialization. - @usableFromInline - internal let _storage: _Rep - - /// Initializes a new managed atomic lazy reference with a nil value. - @inlinable - public init() { - _storage = _Rep(nil) - } - - deinit { - if let unmanaged = _ptr.pointee.dispose() { - unmanaged.release() - } - } - - @_alwaysEmitIntoClient @inline(__always) - internal var _ptr: UnsafeMutablePointer<_Rep> { - _getUnsafePointerToStoredProperties(self).assumingMemoryBound(to: _Rep.self) - } -} - -extension ManagedAtomicLazyReference: @unchecked Sendable -where Instance: Sendable {} - -% for type in ["UnsafeAtomicLazyReference", "ManagedAtomicLazyReference"]: -extension ${type} { +extension UnsafeAtomicLazyReference { /// Atomically initializes this reference if its current value is nil, then /// returns the initialized value. If this reference is already initialized, /// then `storeIfNilThenLoad(_:)` discards its supplied argument and returns @@ -192,10 +146,10 @@ extension ${type} { public func storeIfNilThenLoad(_ desired: __owned Instance) -> Instance { let desiredUnmanaged = Unmanaged.passRetained(desired) let (exchanged, current) = _Rep.atomicCompareExchange( - expected: nil, - desired: desiredUnmanaged, - at: _ptr, - ordering: .acquiringAndReleasing) + expected: nil, + desired: desiredUnmanaged, + at: _ptr, + ordering: .acquiringAndReleasing) if !exchanged { // The reference has already been initialized. Balance the retain that // we performed on `desired`. diff --git a/Sources/Atomics/Types/autogenerated/IntegerOperations.swift b/Sources/Atomics/Types/autogenerated/IntegerOperations.swift new file mode 100644 index 0000000..541f2ea --- /dev/null +++ b/Sources/Atomics/Types/autogenerated/IntegerOperations.swift @@ -0,0 +1,497 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift Atomics open source project +// +// Copyright (c) 2020 - 2023 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +// ############################################################################# +// # # +// # DO NOT EDIT THIS FILE; IT IS AUTOGENERATED. # +// # # +// ############################################################################# + + +extension UnsafeAtomic where Value: AtomicInteger { + /// Perform an atomic wrapping add operation and return the original value, applying + /// the specified memory ordering. + /// + /// Note: This operation silently wraps around on overflow, like the + /// `&+` operator does on `Int` values. + /// + /// - Parameter operand: An integer value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The original value before the operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func loadThenWrappingIncrement( + by operand: Value = 1, + ordering: AtomicUpdateOrdering + ) -> Value { + _Storage.atomicLoadThenWrappingIncrement( + by: operand, + at: _ptr, + ordering: ordering) + } + + /// Perform an atomic wrapping subtract operation and return the original value, applying + /// the specified memory ordering. + /// + /// Note: This operation silently wraps around on overflow, like the + /// `&-` operator does on `Int` values. + /// + /// - Parameter operand: An integer value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The original value before the operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func loadThenWrappingDecrement( + by operand: Value = 1, + ordering: AtomicUpdateOrdering + ) -> Value { + _Storage.atomicLoadThenWrappingDecrement( + by: operand, + at: _ptr, + ordering: ordering) + } + + /// Perform an atomic bitwise AND operation and return the original value, applying + /// the specified memory ordering. + /// + /// - Parameter operand: An integer value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The original value before the operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func loadThenBitwiseAnd( + with operand: Value, + ordering: AtomicUpdateOrdering + ) -> Value { + _Storage.atomicLoadThenBitwiseAnd( + with: operand, + at: _ptr, + ordering: ordering) + } + + /// Perform an atomic bitwise OR operation and return the original value, applying + /// the specified memory ordering. + /// + /// - Parameter operand: An integer value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The original value before the operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func loadThenBitwiseOr( + with operand: Value, + ordering: AtomicUpdateOrdering + ) -> Value { + _Storage.atomicLoadThenBitwiseOr( + with: operand, + at: _ptr, + ordering: ordering) + } + + /// Perform an atomic bitwise XOR operation and return the original value, applying + /// the specified memory ordering. + /// + /// - Parameter operand: An integer value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The original value before the operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func loadThenBitwiseXor( + with operand: Value, + ordering: AtomicUpdateOrdering + ) -> Value { + _Storage.atomicLoadThenBitwiseXor( + with: operand, + at: _ptr, + ordering: ordering) + } + + /// Perform an atomic wrapping add operation and return the new value, applying + /// the specified memory ordering. + /// + /// Note: This operation silently wraps around on overflow, like the + /// `&+` operator does on `Int` values. + /// + /// - Parameter operand: An integer value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The new value after the operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func wrappingIncrementThenLoad( + by operand: Value = 1, + ordering: AtomicUpdateOrdering + ) -> Value { + let original = _Storage.atomicLoadThenWrappingIncrement( + by: operand, + at: _ptr, + ordering: ordering) + return original &+ operand + } + + /// Perform an atomic wrapping subtract operation and return the new value, applying + /// the specified memory ordering. + /// + /// Note: This operation silently wraps around on overflow, like the + /// `&-` operator does on `Int` values. + /// + /// - Parameter operand: An integer value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The new value after the operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func wrappingDecrementThenLoad( + by operand: Value = 1, + ordering: AtomicUpdateOrdering + ) -> Value { + let original = _Storage.atomicLoadThenWrappingDecrement( + by: operand, + at: _ptr, + ordering: ordering) + return original &- operand + } + + /// Perform an atomic bitwise AND operation and return the new value, applying + /// the specified memory ordering. + /// + /// - Parameter operand: An integer value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The new value after the operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func bitwiseAndThenLoad( + with operand: Value, + ordering: AtomicUpdateOrdering + ) -> Value { + let original = _Storage.atomicLoadThenBitwiseAnd( + with: operand, + at: _ptr, + ordering: ordering) + return original & operand + } + + /// Perform an atomic bitwise OR operation and return the new value, applying + /// the specified memory ordering. + /// + /// - Parameter operand: An integer value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The new value after the operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func bitwiseOrThenLoad( + with operand: Value, + ordering: AtomicUpdateOrdering + ) -> Value { + let original = _Storage.atomicLoadThenBitwiseOr( + with: operand, + at: _ptr, + ordering: ordering) + return original | operand + } + + /// Perform an atomic bitwise XOR operation and return the new value, applying + /// the specified memory ordering. + /// + /// - Parameter operand: An integer value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The new value after the operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func bitwiseXorThenLoad( + with operand: Value, + ordering: AtomicUpdateOrdering + ) -> Value { + let original = _Storage.atomicLoadThenBitwiseXor( + with: operand, + at: _ptr, + ordering: ordering) + return original ^ operand + } + + + /// Perform an atomic wrapping increment operation applying the + /// specified memory ordering. + /// + /// Note: This operation silently wraps around on overflow, like the + /// `&+=` operator does on `Int` values. + /// + /// - Parameter operand: The value to add to the current value. + /// - Parameter ordering: The memory ordering to apply on this operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func wrappingIncrement( + by operand: Value = 1, + ordering: AtomicUpdateOrdering + ) { + _ = _Storage.atomicLoadThenWrappingIncrement( + by: operand, + at: _ptr, + ordering: ordering) + } + + /// Perform an atomic wrapping decrement operation applying the + /// specified memory ordering. + /// + /// Note: This operation silently wraps around on overflow, like the + /// `&-=` operator does on `Int` values. + /// + /// - Parameter operand: The value to subtract from the current value. + /// - Parameter ordering: The memory ordering to apply on this operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func wrappingDecrement( + by operand: Value = 1, + ordering: AtomicUpdateOrdering + ) { + _ = _Storage.atomicLoadThenWrappingDecrement( + by: operand, + at: _ptr, + ordering: ordering) + } +} +extension ManagedAtomic where Value: AtomicInteger { + /// Perform an atomic wrapping add operation and return the original value, applying + /// the specified memory ordering. + /// + /// Note: This operation silently wraps around on overflow, like the + /// `&+` operator does on `Int` values. + /// + /// - Parameter operand: An integer value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The original value before the operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func loadThenWrappingIncrement( + by operand: Value = 1, + ordering: AtomicUpdateOrdering + ) -> Value { + _Storage.atomicLoadThenWrappingIncrement( + by: operand, + at: _ptr, + ordering: ordering) + } + + /// Perform an atomic wrapping subtract operation and return the original value, applying + /// the specified memory ordering. + /// + /// Note: This operation silently wraps around on overflow, like the + /// `&-` operator does on `Int` values. + /// + /// - Parameter operand: An integer value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The original value before the operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func loadThenWrappingDecrement( + by operand: Value = 1, + ordering: AtomicUpdateOrdering + ) -> Value { + _Storage.atomicLoadThenWrappingDecrement( + by: operand, + at: _ptr, + ordering: ordering) + } + + /// Perform an atomic bitwise AND operation and return the original value, applying + /// the specified memory ordering. + /// + /// - Parameter operand: An integer value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The original value before the operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func loadThenBitwiseAnd( + with operand: Value, + ordering: AtomicUpdateOrdering + ) -> Value { + _Storage.atomicLoadThenBitwiseAnd( + with: operand, + at: _ptr, + ordering: ordering) + } + + /// Perform an atomic bitwise OR operation and return the original value, applying + /// the specified memory ordering. + /// + /// - Parameter operand: An integer value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The original value before the operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func loadThenBitwiseOr( + with operand: Value, + ordering: AtomicUpdateOrdering + ) -> Value { + _Storage.atomicLoadThenBitwiseOr( + with: operand, + at: _ptr, + ordering: ordering) + } + + /// Perform an atomic bitwise XOR operation and return the original value, applying + /// the specified memory ordering. + /// + /// - Parameter operand: An integer value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The original value before the operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func loadThenBitwiseXor( + with operand: Value, + ordering: AtomicUpdateOrdering + ) -> Value { + _Storage.atomicLoadThenBitwiseXor( + with: operand, + at: _ptr, + ordering: ordering) + } + + /// Perform an atomic wrapping add operation and return the new value, applying + /// the specified memory ordering. + /// + /// Note: This operation silently wraps around on overflow, like the + /// `&+` operator does on `Int` values. + /// + /// - Parameter operand: An integer value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The new value after the operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func wrappingIncrementThenLoad( + by operand: Value = 1, + ordering: AtomicUpdateOrdering + ) -> Value { + let original = _Storage.atomicLoadThenWrappingIncrement( + by: operand, + at: _ptr, + ordering: ordering) + return original &+ operand + } + + /// Perform an atomic wrapping subtract operation and return the new value, applying + /// the specified memory ordering. + /// + /// Note: This operation silently wraps around on overflow, like the + /// `&-` operator does on `Int` values. + /// + /// - Parameter operand: An integer value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The new value after the operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func wrappingDecrementThenLoad( + by operand: Value = 1, + ordering: AtomicUpdateOrdering + ) -> Value { + let original = _Storage.atomicLoadThenWrappingDecrement( + by: operand, + at: _ptr, + ordering: ordering) + return original &- operand + } + + /// Perform an atomic bitwise AND operation and return the new value, applying + /// the specified memory ordering. + /// + /// - Parameter operand: An integer value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The new value after the operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func bitwiseAndThenLoad( + with operand: Value, + ordering: AtomicUpdateOrdering + ) -> Value { + let original = _Storage.atomicLoadThenBitwiseAnd( + with: operand, + at: _ptr, + ordering: ordering) + return original & operand + } + + /// Perform an atomic bitwise OR operation and return the new value, applying + /// the specified memory ordering. + /// + /// - Parameter operand: An integer value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The new value after the operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func bitwiseOrThenLoad( + with operand: Value, + ordering: AtomicUpdateOrdering + ) -> Value { + let original = _Storage.atomicLoadThenBitwiseOr( + with: operand, + at: _ptr, + ordering: ordering) + return original | operand + } + + /// Perform an atomic bitwise XOR operation and return the new value, applying + /// the specified memory ordering. + /// + /// - Parameter operand: An integer value. + /// - Parameter ordering: The memory ordering to apply on this operation. + /// - Returns: The new value after the operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func bitwiseXorThenLoad( + with operand: Value, + ordering: AtomicUpdateOrdering + ) -> Value { + let original = _Storage.atomicLoadThenBitwiseXor( + with: operand, + at: _ptr, + ordering: ordering) + return original ^ operand + } + + + /// Perform an atomic wrapping increment operation applying the + /// specified memory ordering. + /// + /// Note: This operation silently wraps around on overflow, like the + /// `&+=` operator does on `Int` values. + /// + /// - Parameter operand: The value to add to the current value. + /// - Parameter ordering: The memory ordering to apply on this operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func wrappingIncrement( + by operand: Value = 1, + ordering: AtomicUpdateOrdering + ) { + _ = _Storage.atomicLoadThenWrappingIncrement( + by: operand, + at: _ptr, + ordering: ordering) + } + + /// Perform an atomic wrapping decrement operation applying the + /// specified memory ordering. + /// + /// Note: This operation silently wraps around on overflow, like the + /// `&-=` operator does on `Int` values. + /// + /// - Parameter operand: The value to subtract from the current value. + /// - Parameter ordering: The memory ordering to apply on this operation. + @_semantics("atomics.requires_constant_orderings") + @_transparent @_alwaysEmitIntoClient + public func wrappingDecrement( + by operand: Value = 1, + ordering: AtomicUpdateOrdering + ) { + _ = _Storage.atomicLoadThenWrappingDecrement( + by: operand, + at: _ptr, + ordering: ordering) + } +} diff --git a/Sources/Atomics/autogenerated/AtomicLazyReference.swift b/Sources/Atomics/autogenerated/AtomicLazyReference.swift deleted file mode 100644 index 5a5e048..0000000 --- a/Sources/Atomics/autogenerated/AtomicLazyReference.swift +++ /dev/null @@ -1,268 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Atomics open source project -// -// Copyright (c) 2020 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -// ############################################################################# -// # # -// # DO NOT EDIT THIS FILE; IT IS AUTOGENERATED. # -// # # -// ############################################################################# - - -/// An unsafe reference type holding a lazily initializable atomic -/// strong reference, requiring manual memory management of the -/// underlying storage representation. -/// -/// These values can be set (initialized) exactly once, but read many -/// times. -@frozen -public struct UnsafeAtomicLazyReference { - /// The value logically stored in an atomic lazy reference value. - public typealias Value = Instance? - - @usableFromInline - internal typealias _Rep = Optional>.AtomicRepresentation - - @usableFromInline - internal let _ptr: UnsafeMutablePointer<_Rep> - - /// Initialize an unsafe atomic lazy reference that uses the supplied memory - /// location for storage. The storage location must already be initialized to - /// represent a valid atomic value. - /// - /// At the end of the lifetime of the atomic value, you must manually ensure - /// that the storage location is correctly `dispose()`d, deinitalized and - /// deallocated. - /// - /// Note: This is not an atomic operation. - @_transparent // Debug performance - public init(@_nonEphemeral at pointer: UnsafeMutablePointer) { - // `Storage` is layout-compatible with its only stored property. - _ptr = UnsafeMutableRawPointer(pointer).assumingMemoryBound(to: _Rep.self) - } -} - -extension UnsafeAtomicLazyReference: @unchecked Sendable -where Instance: Sendable {} - -extension UnsafeAtomicLazyReference { - /// The storage representation for an atomic lazy reference value. - @frozen - public struct Storage { - @usableFromInline - internal var _storage: _Rep - - /// Initialize a new atomic lazy reference storage value holding `nil`. - /// - /// Note: This is not an atomic operation. This call may have side effects - /// (such as unpaired retains of strong references) that will need to be - /// undone by calling `dispose()` before the storage value is - /// deinitialized. - @inlinable @inline(__always) - public init() { - _storage = _Rep(nil) - } - - /// Prepare this atomic storage value for deinitialization, extracting the - /// logical value it represents. This invalidates this atomic storage; you - /// must not perform any operations on it after this call (except for - /// deinitialization). - /// - /// This call prevents resource leaks when destroying the storage - /// representation of certain `AtomicValue` types. (In particular, ones - /// that model strong references.) - /// - /// Note: This is not an atomic operation. Logically, it implements a - /// custom destructor for the underlying non-copiable value. - @inlinable @inline(__always) - @discardableResult - public mutating func dispose() -> Value { - defer { _storage = _Rep(nil) } - return _storage.dispose()?.takeRetainedValue() - } - } -} - -extension UnsafeAtomicLazyReference { - /// Create a new `UnsafeAtomicLazyReference` value by dynamically allocating - /// storage for it. - /// - /// This call is usually paired with `destroy` to get rid of the allocated - /// storage at the end of its lifetime. - /// - /// Note: This is not an atomic operation. - @inlinable - public static func create() -> Self { - let ptr = UnsafeMutablePointer.allocate(capacity: 1) - ptr.initialize(to: Storage()) - return Self(at: ptr) - } - - /// Disposes of the current value of the storage location corresponding to - /// this unsafe atomic lazy reference, then deinitializes and deallocates the - /// storage. - /// - /// Note: This is not an atomic operation. - /// - /// - Returns: The last value stored in the storage representation before it - /// was destroyed. - @discardableResult - @inlinable - public func destroy() -> Value { - // `Storage` is layout-compatible with its only stored property. - let address = UnsafeMutableRawPointer(_ptr) - .assumingMemoryBound(to: Storage.self) - defer { address.deallocate() } - return address.pointee.dispose() - } -} - -/// A reference type holding a lazily initializable atomic -/// strong reference, with automatic memory management. -/// -/// These values can be set (initialized) exactly once, but read many -/// times. -@_fixed_layout -public class ManagedAtomicLazyReference { - /// The value logically stored in an atomic lazy reference value. - public typealias Value = Instance? - - @usableFromInline - internal typealias _Rep = Optional>.AtomicRepresentation - - /// The atomic representation of the value stored inside. - /// - /// Warning: This ivar must only ever be accessed via `_ptr` after - /// its initialization. - @usableFromInline - internal let _storage: _Rep - - /// Initializes a new managed atomic lazy reference with a nil value. - @inlinable - public init() { - _storage = _Rep(nil) - } - - deinit { - if let unmanaged = _ptr.pointee.dispose() { - unmanaged.release() - } - } - - @_alwaysEmitIntoClient @inline(__always) - internal var _ptr: UnsafeMutablePointer<_Rep> { - _getUnsafePointerToStoredProperties(self).assumingMemoryBound(to: _Rep.self) - } -} - -extension ManagedAtomicLazyReference: @unchecked Sendable -where Instance: Sendable {} - -extension UnsafeAtomicLazyReference { - /// Atomically initializes this reference if its current value is nil, then - /// returns the initialized value. If this reference is already initialized, - /// then `storeIfNilThenLoad(_:)` discards its supplied argument and returns - /// the current value without updating it. - /// - /// The following example demonstrates how this can be used to implement a - /// thread-safe lazily initialized reference: - /// - /// ``` - /// class Image { - /// var _histogram: UnsafeAtomicLazyReference = .init() - /// - /// // This is safe to call concurrently from multiple threads. - /// var atomicLazyHistogram: Histogram { - /// if let histogram = _histogram.load() { return histogram } - /// // Note that code here may run concurrently on - /// // multiple threads, but only one of them will get to - /// // succeed setting the reference. - /// let histogram = ... - /// return _histogram.storeIfNilThenLoad(histogram) - /// } - /// ``` - /// - /// This operation uses acquiring-and-releasing memory ordering. - public func storeIfNilThenLoad(_ desired: __owned Instance) -> Instance { - let desiredUnmanaged = Unmanaged.passRetained(desired) - let (exchanged, current) = _Rep.atomicCompareExchange( - expected: nil, - desired: desiredUnmanaged, - at: _ptr, - ordering: .acquiringAndReleasing) - if !exchanged { - // The reference has already been initialized. Balance the retain that - // we performed on `desired`. - desiredUnmanaged.release() - return current!.takeUnretainedValue() - } - return desiredUnmanaged.takeUnretainedValue() - } - - /// Atomically loads and returns the current value of this reference. - /// - /// The load operation is performed with the memory ordering - /// `AtomicLoadOrdering.acquiring`. - public func load() -> Instance? { - let value = _Rep.atomicLoad(at: _ptr, ordering: .acquiring) - return value?.takeUnretainedValue() - } -} -extension ManagedAtomicLazyReference { - /// Atomically initializes this reference if its current value is nil, then - /// returns the initialized value. If this reference is already initialized, - /// then `storeIfNilThenLoad(_:)` discards its supplied argument and returns - /// the current value without updating it. - /// - /// The following example demonstrates how this can be used to implement a - /// thread-safe lazily initialized reference: - /// - /// ``` - /// class Image { - /// var _histogram: UnsafeAtomicLazyReference = .init() - /// - /// // This is safe to call concurrently from multiple threads. - /// var atomicLazyHistogram: Histogram { - /// if let histogram = _histogram.load() { return histogram } - /// // Note that code here may run concurrently on - /// // multiple threads, but only one of them will get to - /// // succeed setting the reference. - /// let histogram = ... - /// return _histogram.storeIfNilThenLoad(histogram) - /// } - /// ``` - /// - /// This operation uses acquiring-and-releasing memory ordering. - public func storeIfNilThenLoad(_ desired: __owned Instance) -> Instance { - let desiredUnmanaged = Unmanaged.passRetained(desired) - let (exchanged, current) = _Rep.atomicCompareExchange( - expected: nil, - desired: desiredUnmanaged, - at: _ptr, - ordering: .acquiringAndReleasing) - if !exchanged { - // The reference has already been initialized. Balance the retain that - // we performed on `desired`. - desiredUnmanaged.release() - return current!.takeUnretainedValue() - } - return desiredUnmanaged.takeUnretainedValue() - } - - /// Atomically loads and returns the current value of this reference. - /// - /// The load operation is performed with the memory ordering - /// `AtomicLoadOrdering.acquiring`. - public func load() -> Instance? { - let value = _Rep.atomicLoad(at: _ptr, ordering: .acquiring) - return value?.takeUnretainedValue() - } -} diff --git a/Sources/Atomics/autogenerated/HighLevelTypes.swift b/Sources/Atomics/autogenerated/HighLevelTypes.swift deleted file mode 100644 index 873d546..0000000 --- a/Sources/Atomics/autogenerated/HighLevelTypes.swift +++ /dev/null @@ -1,1016 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Atomics open source project -// -// Copyright (c) 2020 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -// ############################################################################# -// # # -// # DO NOT EDIT THIS FILE; IT IS AUTOGENERATED. # -// # # -// ############################################################################# - - -/// An unsafe reference type holding an atomic value, requiring manual memory -/// management of the underlying storage representation. -@frozen -public struct UnsafeAtomic -where Value.AtomicRepresentation.Value == Value { - // Note: the Value.AtomicRepresentation.Value == Value requirement could be relaxed, - // at the cost of adding a bunch of potentially ambiguous overloads. - // (We'd need one set of implementations for the type equality condition, - // and another for `Value: AtomicReference`.) - - public typealias Storage = Value.AtomicRepresentation - @usableFromInline - internal typealias _Storage = Storage - - @usableFromInline - internal let _ptr: UnsafeMutablePointer - - /// Initialize an unsafe atomic value that uses the supplied memory location - /// for storage. The storage location must already be initialized to - /// represent a valid atomic value. - /// - /// At the end of the lifetime of the atomic value, you must manually ensure - /// that the storage location is correctly `dispose()`d, deinitalized and - /// deallocated. - /// - /// Note: This is not an atomic operation. - @_transparent // Debug performance - public init( - @_nonEphemeral at pointer: UnsafeMutablePointer - ) { - self._ptr = pointer - } - - /// Create a new `UnsafeAtomic` value with the supplied initial value by - /// dynamically allocating storage for it. - /// - /// This call is usually paired with `destroy` to get rid of the allocated - /// storage at the end of its lifetime. - /// - /// Note: This is not an atomic operation. - @inlinable - public static func create(_ initialValue: __owned Value) -> Self { - let ptr = UnsafeMutablePointer.allocate(capacity: 1) - ptr.initialize(to: Storage(initialValue)) - return Self(at: ptr) - } - - /// Disposes of the current value of the storage location corresponding to - /// this unsafe atomic value, then deinitializes and deallocates the storage. - /// - /// Note: This is not an atomic operation. - /// - /// - Returns: The last value stored in the storage representation before it - /// was destroyed. - @discardableResult - @inlinable - public func destroy() -> Value { - let result = _ptr.pointee.dispose() - _ptr.deinitialize(count: 1) - _ptr.deallocate() - return result - } -} - -extension UnsafeAtomic: @unchecked Sendable where Value: Sendable {} - -/// A reference type holding an atomic value, with automatic memory management. -@_fixed_layout -public class ManagedAtomic -where Value.AtomicRepresentation.Value == Value { - // Note: the Value.AtomicRepresentation.Value == Value requirement could be relaxed, - // at the cost of adding a bunch of potentially ambiguous overloads. - // (We'd need one set of implementations for the type equality condition, - // and another for `Value: AtomicReference`.) - - @usableFromInline - internal typealias _Storage = Value.AtomicRepresentation - - /// The atomic representation of the value stored inside. - /// - /// Warning: This ivar must only ever be accessed via `_ptr` after - /// its initialization. - @usableFromInline - internal var _storage: _Storage - - /// Initialize a new managed atomic instance holding the specified initial - /// value. - @inline(__always) @_alwaysEmitIntoClient - public init(_ value: Value) { - _storage = _Storage(value) - } - - deinit { - _ = _ptr.pointee.dispose() - } - - @_alwaysEmitIntoClient @inline(__always) - internal var _ptr: UnsafeMutablePointer<_Storage> { - _getUnsafePointerToStoredProperties(self) - .assumingMemoryBound(to: _Storage.self) - } -} - -extension ManagedAtomic: @unchecked Sendable where Value: Sendable {} - -extension UnsafeAtomic { - /// Atomically loads and returns the current value, applying the specified - /// memory ordering. - /// - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The current value. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func load( - ordering: AtomicLoadOrdering - ) -> Value { - _Storage.atomicLoad(at: _ptr, ordering: ordering) - } - - /// Atomically sets the current value to `desired`, applying the specified - /// memory ordering. - /// - /// - Parameter desired: The desired new value. - /// - Parameter ordering: The memory ordering to apply on this operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func store( - _ desired: __owned Value, - ordering: AtomicStoreOrdering - ) { - _Storage.atomicStore(desired, at: _ptr, ordering: ordering) - } - - /// Atomically sets the current value to `desired` and returns the original - /// value, applying the specified memory ordering. - /// - /// - Parameter desired: The desired new value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The original value. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func exchange( - _ desired: __owned Value, - ordering: AtomicUpdateOrdering - ) -> Value { - _Storage.atomicExchange(desired, at: _ptr, ordering: ordering) - } - - /// Perform an atomic compare and exchange operation on the current value, - /// applying the specified memory ordering. - /// - /// This operation performs the following algorithm as a single atomic - /// transaction: - /// - /// ``` - /// atomic(self) { currentValue in - /// let original = currentValue - /// guard original == expected else { return (false, original) } - /// currentValue = desired - /// return (true, original) - /// } - /// ``` - /// - /// This method implements a "strong" compare and exchange operation - /// that does not permit spurious failures. - /// - /// - Parameter expected: The expected current value. - /// - Parameter desired: The desired new value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: A tuple `(exchanged, original)`, where `exchanged` is true if - /// the exchange was successful, and `original` is the original value. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func compareExchange( - expected: Value, - desired: __owned Value, - ordering: AtomicUpdateOrdering - ) -> (exchanged: Bool, original: Value) { - _Storage.atomicCompareExchange( - expected: expected, - desired: desired, - at: _ptr, - ordering: ordering) - } - - /// Perform an atomic compare and exchange operation on the current value, - /// applying the specified success/failure memory orderings. - /// - /// This operation performs the following algorithm as a single atomic - /// transaction: - /// - /// ``` - /// atomic(self) { currentValue in - /// let original = currentValue - /// guard original == expected else { return (false, original) } - /// currentValue = desired - /// return (true, original) - /// } - /// ``` - /// - /// The `successOrdering` argument specifies the memory ordering to use when - /// the operation manages to update the current value, while `failureOrdering` - /// will be used when the operation leaves the value intact. - /// - /// This method implements a "strong" compare and exchange operation - /// that does not permit spurious failures. - /// - /// - Parameter expected: The expected current value. - /// - Parameter desired: The desired new value. - /// - Parameter successOrdering: The memory ordering to apply if this - /// operation performs the exchange. - /// - Parameter failureOrdering: The memory ordering to apply on this - /// operation does not perform the exchange. - /// - Returns: A tuple `(exchanged, original)`, where `exchanged` is true if - /// the exchange was successful, and `original` is the original value. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func compareExchange( - expected: Value, - desired: __owned Value, - successOrdering: AtomicUpdateOrdering, - failureOrdering: AtomicLoadOrdering - ) -> (exchanged: Bool, original: Value) { - _Storage.atomicCompareExchange( - expected: expected, - desired: desired, - at: _ptr, - successOrdering: successOrdering, - failureOrdering: failureOrdering) - } - - /// Perform an atomic weak compare and exchange operation on the current - /// value, applying the memory ordering. This compare-exchange variant is - /// allowed to spuriously fail; it is designed to be called in a loop until - /// it indicates a successful exchange has happened. - /// - /// This operation performs the following algorithm as a single atomic - /// transaction: - /// - /// ``` - /// atomic(self) { currentValue in - /// let original = currentValue - /// guard original == expected else { return (false, original) } - /// currentValue = desired - /// return (true, original) - /// } - /// ``` - /// - /// (In this weak form, transient conditions may cause the `original == - /// expected` check to sometimes return false when the two values are in fact - /// the same.) - /// - /// - Parameter expected: The expected current value. - /// - Parameter desired: The desired new value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: A tuple `(exchanged, original)`, where `exchanged` is true if - /// the exchange was successful, and `original` is the original value. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func weakCompareExchange( - expected: Value, - desired: __owned Value, - ordering: AtomicUpdateOrdering - ) -> (exchanged: Bool, original: Value) { - _Storage.atomicWeakCompareExchange( - expected: expected, - desired: desired, - at: _ptr, - ordering: ordering) - } - - /// Perform an atomic weak compare and exchange operation on the current - /// value, applying the specified success/failure memory orderings. This - /// compare-exchange variant is allowed to spuriously fail; it is designed to - /// be called in a loop until it indicates a successful exchange has happened. - /// - /// This operation performs the following algorithm as a single atomic - /// transaction: - /// - /// ``` - /// atomic(self) { currentValue in - /// let original = currentValue - /// guard original == expected else { return (false, original) } - /// currentValue = desired - /// return (true, original) - /// } - /// ``` - /// - /// (In this weak form, transient conditions may cause the `original == - /// expected` check to sometimes return false when the two values are in fact - /// the same.) - /// - /// The `ordering` argument specifies the memory ordering to use when the - /// operation manages to update the current value, while `failureOrdering` - /// will be used when the operation leaves the value intact. - /// - /// - Parameter expected: The expected current value. - /// - Parameter desired: The desired new value. - /// - Parameter successOrdering: The memory ordering to apply if this - /// operation performs the exchange. - /// - Parameter failureOrdering: The memory ordering to apply on this - /// operation does not perform the exchange. - /// - Returns: A tuple `(exchanged, original)`, where `exchanged` is true if - /// the exchange was successful, and `original` is the original value. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func weakCompareExchange( - expected: Value, - desired: __owned Value, - successOrdering: AtomicUpdateOrdering, - failureOrdering: AtomicLoadOrdering - ) -> (exchanged: Bool, original: Value) { - _Storage.atomicWeakCompareExchange( - expected: expected, - desired: desired, - at: _ptr, - successOrdering: successOrdering, - failureOrdering: failureOrdering) - } -} - -extension UnsafeAtomic where Value: AtomicInteger { - /// Perform an atomic wrapping add operation and return the original value, applying - /// the specified memory ordering. - /// - /// Note: This operation silently wraps around on overflow, like the - /// `&+` operator does on `Int` values. - /// - /// - Parameter operand: An integer value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The original value before the operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func loadThenWrappingIncrement( - by operand: Value = 1, - ordering: AtomicUpdateOrdering - ) -> Value { - _Storage.atomicLoadThenWrappingIncrement( - by: operand, - at: _ptr, - ordering: ordering) - } - /// Perform an atomic wrapping subtract operation and return the original value, applying - /// the specified memory ordering. - /// - /// Note: This operation silently wraps around on overflow, like the - /// `&-` operator does on `Int` values. - /// - /// - Parameter operand: An integer value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The original value before the operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func loadThenWrappingDecrement( - by operand: Value = 1, - ordering: AtomicUpdateOrdering - ) -> Value { - _Storage.atomicLoadThenWrappingDecrement( - by: operand, - at: _ptr, - ordering: ordering) - } - /// Perform an atomic bitwise AND operation and return the original value, applying - /// the specified memory ordering. - /// - /// - Parameter operand: An integer value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The original value before the operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func loadThenBitwiseAnd( - with operand: Value, - ordering: AtomicUpdateOrdering - ) -> Value { - _Storage.atomicLoadThenBitwiseAnd( - with: operand, - at: _ptr, - ordering: ordering) - } - /// Perform an atomic bitwise OR operation and return the original value, applying - /// the specified memory ordering. - /// - /// - Parameter operand: An integer value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The original value before the operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func loadThenBitwiseOr( - with operand: Value, - ordering: AtomicUpdateOrdering - ) -> Value { - _Storage.atomicLoadThenBitwiseOr( - with: operand, - at: _ptr, - ordering: ordering) - } - /// Perform an atomic bitwise XOR operation and return the original value, applying - /// the specified memory ordering. - /// - /// - Parameter operand: An integer value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The original value before the operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func loadThenBitwiseXor( - with operand: Value, - ordering: AtomicUpdateOrdering - ) -> Value { - _Storage.atomicLoadThenBitwiseXor( - with: operand, - at: _ptr, - ordering: ordering) - } - - /// Perform an atomic wrapping add operation and return the new value, applying - /// the specified memory ordering. - /// - /// Note: This operation silently wraps around on overflow, like the - /// `&+` operator does on `Int` values. - /// - /// - Parameter operand: An integer value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The new value after the operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func wrappingIncrementThenLoad( - by operand: Value = 1, - ordering: AtomicUpdateOrdering - ) -> Value { - let original = _Storage.atomicLoadThenWrappingIncrement( - by: operand, - at: _ptr, - ordering: ordering) - return original &+ operand - } - /// Perform an atomic wrapping subtract operation and return the new value, applying - /// the specified memory ordering. - /// - /// Note: This operation silently wraps around on overflow, like the - /// `&-` operator does on `Int` values. - /// - /// - Parameter operand: An integer value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The new value after the operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func wrappingDecrementThenLoad( - by operand: Value = 1, - ordering: AtomicUpdateOrdering - ) -> Value { - let original = _Storage.atomicLoadThenWrappingDecrement( - by: operand, - at: _ptr, - ordering: ordering) - return original &- operand - } - /// Perform an atomic bitwise AND operation and return the new value, applying - /// the specified memory ordering. - /// - /// - Parameter operand: An integer value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The new value after the operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func bitwiseAndThenLoad( - with operand: Value, - ordering: AtomicUpdateOrdering - ) -> Value { - let original = _Storage.atomicLoadThenBitwiseAnd( - with: operand, - at: _ptr, - ordering: ordering) - return original & operand - } - /// Perform an atomic bitwise OR operation and return the new value, applying - /// the specified memory ordering. - /// - /// - Parameter operand: An integer value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The new value after the operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func bitwiseOrThenLoad( - with operand: Value, - ordering: AtomicUpdateOrdering - ) -> Value { - let original = _Storage.atomicLoadThenBitwiseOr( - with: operand, - at: _ptr, - ordering: ordering) - return original | operand - } - /// Perform an atomic bitwise XOR operation and return the new value, applying - /// the specified memory ordering. - /// - /// - Parameter operand: An integer value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The new value after the operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func bitwiseXorThenLoad( - with operand: Value, - ordering: AtomicUpdateOrdering - ) -> Value { - let original = _Storage.atomicLoadThenBitwiseXor( - with: operand, - at: _ptr, - ordering: ordering) - return original ^ operand - } - - /// Perform an atomic wrapping increment operation applying the - /// specified memory ordering. - /// - /// Note: This operation silently wraps around on overflow, like the - /// `&+=` operator does on `Int` values. - /// - /// - Parameter operand: The value to add to the current value. - /// - Parameter ordering: The memory ordering to apply on this operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func wrappingIncrement( - by operand: Value = 1, - ordering: AtomicUpdateOrdering - ) { - _ = _Storage.atomicLoadThenWrappingIncrement( - by: operand, - at: _ptr, - ordering: ordering) - } - - /// Perform an atomic wrapping decrement operation applying the - /// specified memory ordering. - /// - /// Note: This operation silently wraps around on overflow, like the - /// `&-=` operator does on `Int` values. - /// - /// - Parameter operand: The value to subtract from the current value. - /// - Parameter ordering: The memory ordering to apply on this operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func wrappingDecrement( - by operand: Value = 1, - ordering: AtomicUpdateOrdering - ) { - _ = _Storage.atomicLoadThenWrappingDecrement( - by: operand, - at: _ptr, - ordering: ordering) - } -} -extension ManagedAtomic { - /// Atomically loads and returns the current value, applying the specified - /// memory ordering. - /// - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The current value. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func load( - ordering: AtomicLoadOrdering - ) -> Value { - _Storage.atomicLoad(at: _ptr, ordering: ordering) - } - - /// Atomically sets the current value to `desired`, applying the specified - /// memory ordering. - /// - /// - Parameter desired: The desired new value. - /// - Parameter ordering: The memory ordering to apply on this operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func store( - _ desired: __owned Value, - ordering: AtomicStoreOrdering - ) { - _Storage.atomicStore(desired, at: _ptr, ordering: ordering) - } - - /// Atomically sets the current value to `desired` and returns the original - /// value, applying the specified memory ordering. - /// - /// - Parameter desired: The desired new value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The original value. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func exchange( - _ desired: __owned Value, - ordering: AtomicUpdateOrdering - ) -> Value { - _Storage.atomicExchange(desired, at: _ptr, ordering: ordering) - } - - /// Perform an atomic compare and exchange operation on the current value, - /// applying the specified memory ordering. - /// - /// This operation performs the following algorithm as a single atomic - /// transaction: - /// - /// ``` - /// atomic(self) { currentValue in - /// let original = currentValue - /// guard original == expected else { return (false, original) } - /// currentValue = desired - /// return (true, original) - /// } - /// ``` - /// - /// This method implements a "strong" compare and exchange operation - /// that does not permit spurious failures. - /// - /// - Parameter expected: The expected current value. - /// - Parameter desired: The desired new value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: A tuple `(exchanged, original)`, where `exchanged` is true if - /// the exchange was successful, and `original` is the original value. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func compareExchange( - expected: Value, - desired: __owned Value, - ordering: AtomicUpdateOrdering - ) -> (exchanged: Bool, original: Value) { - _Storage.atomicCompareExchange( - expected: expected, - desired: desired, - at: _ptr, - ordering: ordering) - } - - /// Perform an atomic compare and exchange operation on the current value, - /// applying the specified success/failure memory orderings. - /// - /// This operation performs the following algorithm as a single atomic - /// transaction: - /// - /// ``` - /// atomic(self) { currentValue in - /// let original = currentValue - /// guard original == expected else { return (false, original) } - /// currentValue = desired - /// return (true, original) - /// } - /// ``` - /// - /// The `successOrdering` argument specifies the memory ordering to use when - /// the operation manages to update the current value, while `failureOrdering` - /// will be used when the operation leaves the value intact. - /// - /// This method implements a "strong" compare and exchange operation - /// that does not permit spurious failures. - /// - /// - Parameter expected: The expected current value. - /// - Parameter desired: The desired new value. - /// - Parameter successOrdering: The memory ordering to apply if this - /// operation performs the exchange. - /// - Parameter failureOrdering: The memory ordering to apply on this - /// operation does not perform the exchange. - /// - Returns: A tuple `(exchanged, original)`, where `exchanged` is true if - /// the exchange was successful, and `original` is the original value. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func compareExchange( - expected: Value, - desired: __owned Value, - successOrdering: AtomicUpdateOrdering, - failureOrdering: AtomicLoadOrdering - ) -> (exchanged: Bool, original: Value) { - _Storage.atomicCompareExchange( - expected: expected, - desired: desired, - at: _ptr, - successOrdering: successOrdering, - failureOrdering: failureOrdering) - } - - /// Perform an atomic weak compare and exchange operation on the current - /// value, applying the memory ordering. This compare-exchange variant is - /// allowed to spuriously fail; it is designed to be called in a loop until - /// it indicates a successful exchange has happened. - /// - /// This operation performs the following algorithm as a single atomic - /// transaction: - /// - /// ``` - /// atomic(self) { currentValue in - /// let original = currentValue - /// guard original == expected else { return (false, original) } - /// currentValue = desired - /// return (true, original) - /// } - /// ``` - /// - /// (In this weak form, transient conditions may cause the `original == - /// expected` check to sometimes return false when the two values are in fact - /// the same.) - /// - /// - Parameter expected: The expected current value. - /// - Parameter desired: The desired new value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: A tuple `(exchanged, original)`, where `exchanged` is true if - /// the exchange was successful, and `original` is the original value. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func weakCompareExchange( - expected: Value, - desired: __owned Value, - ordering: AtomicUpdateOrdering - ) -> (exchanged: Bool, original: Value) { - _Storage.atomicWeakCompareExchange( - expected: expected, - desired: desired, - at: _ptr, - ordering: ordering) - } - - /// Perform an atomic weak compare and exchange operation on the current - /// value, applying the specified success/failure memory orderings. This - /// compare-exchange variant is allowed to spuriously fail; it is designed to - /// be called in a loop until it indicates a successful exchange has happened. - /// - /// This operation performs the following algorithm as a single atomic - /// transaction: - /// - /// ``` - /// atomic(self) { currentValue in - /// let original = currentValue - /// guard original == expected else { return (false, original) } - /// currentValue = desired - /// return (true, original) - /// } - /// ``` - /// - /// (In this weak form, transient conditions may cause the `original == - /// expected` check to sometimes return false when the two values are in fact - /// the same.) - /// - /// The `ordering` argument specifies the memory ordering to use when the - /// operation manages to update the current value, while `failureOrdering` - /// will be used when the operation leaves the value intact. - /// - /// - Parameter expected: The expected current value. - /// - Parameter desired: The desired new value. - /// - Parameter successOrdering: The memory ordering to apply if this - /// operation performs the exchange. - /// - Parameter failureOrdering: The memory ordering to apply on this - /// operation does not perform the exchange. - /// - Returns: A tuple `(exchanged, original)`, where `exchanged` is true if - /// the exchange was successful, and `original` is the original value. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func weakCompareExchange( - expected: Value, - desired: __owned Value, - successOrdering: AtomicUpdateOrdering, - failureOrdering: AtomicLoadOrdering - ) -> (exchanged: Bool, original: Value) { - _Storage.atomicWeakCompareExchange( - expected: expected, - desired: desired, - at: _ptr, - successOrdering: successOrdering, - failureOrdering: failureOrdering) - } -} - -extension ManagedAtomic where Value: AtomicInteger { - /// Perform an atomic wrapping add operation and return the original value, applying - /// the specified memory ordering. - /// - /// Note: This operation silently wraps around on overflow, like the - /// `&+` operator does on `Int` values. - /// - /// - Parameter operand: An integer value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The original value before the operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func loadThenWrappingIncrement( - by operand: Value = 1, - ordering: AtomicUpdateOrdering - ) -> Value { - _Storage.atomicLoadThenWrappingIncrement( - by: operand, - at: _ptr, - ordering: ordering) - } - /// Perform an atomic wrapping subtract operation and return the original value, applying - /// the specified memory ordering. - /// - /// Note: This operation silently wraps around on overflow, like the - /// `&-` operator does on `Int` values. - /// - /// - Parameter operand: An integer value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The original value before the operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func loadThenWrappingDecrement( - by operand: Value = 1, - ordering: AtomicUpdateOrdering - ) -> Value { - _Storage.atomicLoadThenWrappingDecrement( - by: operand, - at: _ptr, - ordering: ordering) - } - /// Perform an atomic bitwise AND operation and return the original value, applying - /// the specified memory ordering. - /// - /// - Parameter operand: An integer value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The original value before the operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func loadThenBitwiseAnd( - with operand: Value, - ordering: AtomicUpdateOrdering - ) -> Value { - _Storage.atomicLoadThenBitwiseAnd( - with: operand, - at: _ptr, - ordering: ordering) - } - /// Perform an atomic bitwise OR operation and return the original value, applying - /// the specified memory ordering. - /// - /// - Parameter operand: An integer value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The original value before the operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func loadThenBitwiseOr( - with operand: Value, - ordering: AtomicUpdateOrdering - ) -> Value { - _Storage.atomicLoadThenBitwiseOr( - with: operand, - at: _ptr, - ordering: ordering) - } - /// Perform an atomic bitwise XOR operation and return the original value, applying - /// the specified memory ordering. - /// - /// - Parameter operand: An integer value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The original value before the operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func loadThenBitwiseXor( - with operand: Value, - ordering: AtomicUpdateOrdering - ) -> Value { - _Storage.atomicLoadThenBitwiseXor( - with: operand, - at: _ptr, - ordering: ordering) - } - - /// Perform an atomic wrapping add operation and return the new value, applying - /// the specified memory ordering. - /// - /// Note: This operation silently wraps around on overflow, like the - /// `&+` operator does on `Int` values. - /// - /// - Parameter operand: An integer value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The new value after the operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func wrappingIncrementThenLoad( - by operand: Value = 1, - ordering: AtomicUpdateOrdering - ) -> Value { - let original = _Storage.atomicLoadThenWrappingIncrement( - by: operand, - at: _ptr, - ordering: ordering) - return original &+ operand - } - /// Perform an atomic wrapping subtract operation and return the new value, applying - /// the specified memory ordering. - /// - /// Note: This operation silently wraps around on overflow, like the - /// `&-` operator does on `Int` values. - /// - /// - Parameter operand: An integer value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The new value after the operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func wrappingDecrementThenLoad( - by operand: Value = 1, - ordering: AtomicUpdateOrdering - ) -> Value { - let original = _Storage.atomicLoadThenWrappingDecrement( - by: operand, - at: _ptr, - ordering: ordering) - return original &- operand - } - /// Perform an atomic bitwise AND operation and return the new value, applying - /// the specified memory ordering. - /// - /// - Parameter operand: An integer value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The new value after the operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func bitwiseAndThenLoad( - with operand: Value, - ordering: AtomicUpdateOrdering - ) -> Value { - let original = _Storage.atomicLoadThenBitwiseAnd( - with: operand, - at: _ptr, - ordering: ordering) - return original & operand - } - /// Perform an atomic bitwise OR operation and return the new value, applying - /// the specified memory ordering. - /// - /// - Parameter operand: An integer value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The new value after the operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func bitwiseOrThenLoad( - with operand: Value, - ordering: AtomicUpdateOrdering - ) -> Value { - let original = _Storage.atomicLoadThenBitwiseOr( - with: operand, - at: _ptr, - ordering: ordering) - return original | operand - } - /// Perform an atomic bitwise XOR operation and return the new value, applying - /// the specified memory ordering. - /// - /// - Parameter operand: An integer value. - /// - Parameter ordering: The memory ordering to apply on this operation. - /// - Returns: The new value after the operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func bitwiseXorThenLoad( - with operand: Value, - ordering: AtomicUpdateOrdering - ) -> Value { - let original = _Storage.atomicLoadThenBitwiseXor( - with: operand, - at: _ptr, - ordering: ordering) - return original ^ operand - } - - /// Perform an atomic wrapping increment operation applying the - /// specified memory ordering. - /// - /// Note: This operation silently wraps around on overflow, like the - /// `&+=` operator does on `Int` values. - /// - /// - Parameter operand: The value to add to the current value. - /// - Parameter ordering: The memory ordering to apply on this operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func wrappingIncrement( - by operand: Value = 1, - ordering: AtomicUpdateOrdering - ) { - _ = _Storage.atomicLoadThenWrappingIncrement( - by: operand, - at: _ptr, - ordering: ordering) - } - - /// Perform an atomic wrapping decrement operation applying the - /// specified memory ordering. - /// - /// Note: This operation silently wraps around on overflow, like the - /// `&-=` operator does on `Int` values. - /// - /// - Parameter operand: The value to subtract from the current value. - /// - Parameter ordering: The memory ordering to apply on this operation. - @_semantics("atomics.requires_constant_orderings") - @_transparent @_alwaysEmitIntoClient - public func wrappingDecrement( - by operand: Value = 1, - ordering: AtomicUpdateOrdering - ) { - _ = _Storage.atomicLoadThenWrappingDecrement( - by: operand, - at: _ptr, - ordering: ordering) - } -} diff --git a/Utilities/gyb_utils.py b/Utilities/gyb_utils.py index 28ba843..6a09227 100644 --- a/Utilities/gyb_utils.py +++ b/Utilities/gyb_utils.py @@ -129,7 +129,7 @@ def lowerFirst(str): def argLabel(label): return label + ": " if label != "_" else "" -ptrBitWidth32 = "arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32)" +ptrBitWidth32 = "(compiler(>=5.9) && _pointerBitWidth(_32)) || (compiler(<5.9) && (arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32)))" def bitwidth_variants(value64, value32): if value64 == value32: diff --git a/Xcode/Atomics.xcodeproj/project.pbxproj b/Xcode/Atomics.xcodeproj/project.pbxproj index 88278e4..0c617e7 100644 --- a/Xcode/Atomics.xcodeproj/project.pbxproj +++ b/Xcode/Atomics.xcodeproj/project.pbxproj @@ -8,22 +8,7 @@ /* Begin PBXBuildFile section */ 7D489E4829CE969D00499B21 /* Atomics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7D489E3F29CE969D00499B21 /* Atomics.framework */; }; - 7D489EDB29CE96DA00499B21 /* AtomicStrongReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D489E5A29CE96D900499B21 /* AtomicStrongReference.swift */; }; - 7D489EDC29CE96DA00499B21 /* AtomicInteger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D489E5B29CE96D900499B21 /* AtomicInteger.swift */; }; - 7D489EDF29CE96DA00499B21 /* AtomicOptionalRawRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D489E5E29CE96D900499B21 /* AtomicOptionalRawRepresentable.swift */; }; - 7D489EE029CE96DA00499B21 /* AtomicValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D489E5F29CE96D900499B21 /* AtomicValue.swift */; }; - 7D489EE329CE96DA00499B21 /* AtomicRawRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D489E6229CE96D900499B21 /* AtomicRawRepresentable.swift */; }; - 7D489EE429CE96DA00499B21 /* DoubleWord.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D489E6329CE96D900499B21 /* DoubleWord.swift */; }; 7D489EE629CE96DA00499B21 /* Unmanaged extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D489E6529CE96D900499B21 /* Unmanaged extensions.swift */; }; - 7D489EE829CE96DA00499B21 /* AtomicOptional.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D489E6729CE96D900499B21 /* AtomicOptional.swift */; }; - 7D489EEA29CE96DA00499B21 /* AtomicMemoryOrderings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D489E6929CE96D900499B21 /* AtomicMemoryOrderings.swift */; }; - 7D489EED29CE96DA00499B21 /* AtomicLazyReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D489E6D29CE96D900499B21 /* AtomicLazyReference.swift */; }; - 7D489EEE29CE96DA00499B21 /* IntegerConformances.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D489E6E29CE96D900499B21 /* IntegerConformances.swift */; }; - 7D489EEF29CE96DA00499B21 /* PointerConformances.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D489E6F29CE96D900499B21 /* PointerConformances.swift */; }; - 7D489EF029CE96DA00499B21 /* Primitives.native.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D489E7029CE96D900499B21 /* Primitives.native.swift */; }; - 7D489EF129CE96DA00499B21 /* Primitives.shims.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D489E7129CE96D900499B21 /* Primitives.shims.swift */; }; - 7D489EF229CE96DA00499B21 /* AtomicBool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D489E7229CE96D900499B21 /* AtomicBool.swift */; }; - 7D489EF329CE96DA00499B21 /* HighLevelTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D489E7329CE96D900499B21 /* HighLevelTypes.swift */; }; 7D489EF529CE96DA00499B21 /* _AtomicsShims.h in Headers */ = {isa = PBXBuildFile; fileRef = 7D489E7729CE96D900499B21 /* _AtomicsShims.h */; }; 7D489EF629CE96DA00499B21 /* _AtomicsShims.c in Sources */ = {isa = PBXBuildFile; fileRef = 7D489E7A29CE96D900499B21 /* _AtomicsShims.c */; }; 7D489F4A29CE976800499B21 /* StrongReferenceShuffle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D489EBC29CE96DA00499B21 /* StrongReferenceShuffle.swift */; }; @@ -62,6 +47,25 @@ 7D489F6B29CE978100499B21 /* BasicAtomicOptionalReferenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D489EA629CE96DA00499B21 /* BasicAtomicOptionalReferenceTests.swift */; }; 7D489F6C29CE978100499B21 /* BasicAtomicUnmanagedTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D489EA129CE96DA00499B21 /* BasicAtomicUnmanagedTests.swift */; }; 7D489F6D29CE978100499B21 /* BasicAtomicRawRepresentableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D489EA429CE96DA00499B21 /* BasicAtomicRawRepresentableTests.swift */; }; + 7DA9B4702ABBD93D00F14CE3 /* UnsafeAtomicLazyReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DA9B4512ABBD93D00F14CE3 /* UnsafeAtomicLazyReference.swift */; }; + 7DA9B4722ABBD93D00F14CE3 /* DoubleWord.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DA9B4532ABBD93D00F14CE3 /* DoubleWord.swift */; }; + 7DA9B4732ABBD93D00F14CE3 /* ManagedAtomic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DA9B4542ABBD93D00F14CE3 /* ManagedAtomic.swift */; }; + 7DA9B4742ABBD93D00F14CE3 /* ManagedAtomicLazyReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DA9B4552ABBD93D00F14CE3 /* ManagedAtomicLazyReference.swift */; }; + 7DA9B4752ABBD93D00F14CE3 /* AtomicMemoryOrderings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DA9B4562ABBD93D00F14CE3 /* AtomicMemoryOrderings.swift */; }; + 7DA9B4762ABBD93D00F14CE3 /* UnsafeAtomic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DA9B4572ABBD93D00F14CE3 /* UnsafeAtomic.swift */; }; + 7DA9B4772ABBD93D00F14CE3 /* IntegerOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DA9B4592ABBD93D00F14CE3 /* IntegerOperations.swift */; }; + 7DA9B47A2ABBD93D00F14CE3 /* Primitives.native.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DA9B45E2ABBD93D00F14CE3 /* Primitives.native.swift */; }; + 7DA9B47B2ABBD93D00F14CE3 /* Primitives.shims.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DA9B45F2ABBD93D00F14CE3 /* Primitives.shims.swift */; }; + 7DA9B47C2ABBD93D00F14CE3 /* AtomicInteger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DA9B4612ABBD93D00F14CE3 /* AtomicInteger.swift */; }; + 7DA9B47D2ABBD93D00F14CE3 /* AtomicValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DA9B4622ABBD93D00F14CE3 /* AtomicValue.swift */; }; + 7DA9B47E2ABBD93D00F14CE3 /* AtomicReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DA9B4632ABBD93D00F14CE3 /* AtomicReference.swift */; }; + 7DA9B47F2ABBD93D00F14CE3 /* AtomicOptionalWrappable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DA9B4642ABBD93D00F14CE3 /* AtomicOptionalWrappable.swift */; }; + 7DA9B4802ABBD93D00F14CE3 /* AtomicStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DA9B4652ABBD93D00F14CE3 /* AtomicStorage.swift */; }; + 7DA9B4812ABBD93D00F14CE3 /* RawRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DA9B4672ABBD93D00F14CE3 /* RawRepresentable.swift */; }; + 7DA9B4842ABBD93D00F14CE3 /* OptionalRawRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DA9B46A2ABBD93D00F14CE3 /* OptionalRawRepresentable.swift */; }; + 7DA9B4862ABBD93D00F14CE3 /* IntegerConformances.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DA9B46D2ABBD93D00F14CE3 /* IntegerConformances.swift */; }; + 7DA9B4872ABBD93D00F14CE3 /* PointerConformances.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DA9B46E2ABBD93D00F14CE3 /* PointerConformances.swift */; }; + 7DA9B4882ABBD93D00F14CE3 /* AtomicBool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DA9B46F2ABBD93D00F14CE3 /* AtomicBool.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -78,31 +82,9 @@ 7D489E3F29CE969D00499B21 /* Atomics.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Atomics.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 7D489E4729CE969D00499B21 /* AtomicsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AtomicsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 7D489E5829CE96D900499B21 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = ""; }; - 7D489E5A29CE96D900499B21 /* AtomicStrongReference.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AtomicStrongReference.swift; sourceTree = ""; }; - 7D489E5B29CE96D900499B21 /* AtomicInteger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AtomicInteger.swift; sourceTree = ""; }; 7D489E5C29CE96D900499B21 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = ""; }; - 7D489E5D29CE96D900499B21 /* AtomicLazyReference.swift.gyb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AtomicLazyReference.swift.gyb; sourceTree = ""; }; - 7D489E5E29CE96D900499B21 /* AtomicOptionalRawRepresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AtomicOptionalRawRepresentable.swift; sourceTree = ""; }; - 7D489E5F29CE96D900499B21 /* AtomicValue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AtomicValue.swift; sourceTree = ""; }; - 7D489E6029CE96D900499B21 /* Primitives.shims.swift.gyb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Primitives.shims.swift.gyb; sourceTree = ""; }; - 7D489E6129CE96D900499B21 /* AtomicBool.swift.gyb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AtomicBool.swift.gyb; sourceTree = ""; }; - 7D489E6229CE96D900499B21 /* AtomicRawRepresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AtomicRawRepresentable.swift; sourceTree = ""; }; - 7D489E6329CE96D900499B21 /* DoubleWord.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoubleWord.swift; sourceTree = ""; }; - 7D489E6429CE96D900499B21 /* HighLevelTypes.swift.gyb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = HighLevelTypes.swift.gyb; sourceTree = ""; }; 7D489E6529CE96D900499B21 /* Unmanaged extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Unmanaged extensions.swift"; sourceTree = ""; }; - 7D489E6629CE96D900499B21 /* PointerConformances.swift.gyb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PointerConformances.swift.gyb; sourceTree = ""; }; - 7D489E6729CE96D900499B21 /* AtomicOptional.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AtomicOptional.swift; sourceTree = ""; }; - 7D489E6829CE96D900499B21 /* Primitives.native.swift.gyb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Primitives.native.swift.gyb; sourceTree = ""; }; - 7D489E6929CE96D900499B21 /* AtomicMemoryOrderings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AtomicMemoryOrderings.swift; sourceTree = ""; }; 7D489E6A29CE96D900499B21 /* Atomics.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = Atomics.docc; sourceTree = ""; }; - 7D489E6B29CE96D900499B21 /* IntegerConformances.swift.gyb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = IntegerConformances.swift.gyb; sourceTree = ""; }; - 7D489E6D29CE96D900499B21 /* AtomicLazyReference.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AtomicLazyReference.swift; sourceTree = ""; }; - 7D489E6E29CE96D900499B21 /* IntegerConformances.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntegerConformances.swift; sourceTree = ""; }; - 7D489E6F29CE96D900499B21 /* PointerConformances.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PointerConformances.swift; sourceTree = ""; }; - 7D489E7029CE96D900499B21 /* Primitives.native.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Primitives.native.swift; sourceTree = ""; }; - 7D489E7129CE96D900499B21 /* Primitives.shims.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Primitives.shims.swift; sourceTree = ""; }; - 7D489E7229CE96D900499B21 /* AtomicBool.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AtomicBool.swift; sourceTree = ""; }; - 7D489E7329CE96D900499B21 /* HighLevelTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HighLevelTypes.swift; sourceTree = ""; }; 7D489E7529CE96D900499B21 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = ""; }; 7D489E7729CE96D900499B21 /* _AtomicsShims.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _AtomicsShims.h; sourceTree = ""; }; 7D489E7829CE96D900499B21 /* module.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = ""; }; @@ -190,6 +172,31 @@ 7D489F6F29CE986A00499B21 /* Shared.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = ""; }; 7D489F7029CE986A00499B21 /* Atomics.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Atomics.xcconfig; sourceTree = ""; }; 7D489F7129CE986A00499B21 /* AtomicsTests.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AtomicsTests.xcconfig; sourceTree = ""; }; + 7DA9B4512ABBD93D00F14CE3 /* UnsafeAtomicLazyReference.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnsafeAtomicLazyReference.swift; sourceTree = ""; }; + 7DA9B4522ABBD93D00F14CE3 /* IntegerOperations.swift.gyb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = IntegerOperations.swift.gyb; sourceTree = ""; }; + 7DA9B4532ABBD93D00F14CE3 /* DoubleWord.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoubleWord.swift; sourceTree = ""; }; + 7DA9B4542ABBD93D00F14CE3 /* ManagedAtomic.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedAtomic.swift; sourceTree = ""; }; + 7DA9B4552ABBD93D00F14CE3 /* ManagedAtomicLazyReference.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedAtomicLazyReference.swift; sourceTree = ""; }; + 7DA9B4562ABBD93D00F14CE3 /* AtomicMemoryOrderings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AtomicMemoryOrderings.swift; sourceTree = ""; }; + 7DA9B4572ABBD93D00F14CE3 /* UnsafeAtomic.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnsafeAtomic.swift; sourceTree = ""; }; + 7DA9B4592ABBD93D00F14CE3 /* IntegerOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntegerOperations.swift; sourceTree = ""; }; + 7DA9B45B2ABBD93D00F14CE3 /* Primitives.shims.swift.gyb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Primitives.shims.swift.gyb; sourceTree = ""; }; + 7DA9B45C2ABBD93D00F14CE3 /* Primitives.native.swift.gyb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Primitives.native.swift.gyb; sourceTree = ""; }; + 7DA9B45E2ABBD93D00F14CE3 /* Primitives.native.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Primitives.native.swift; sourceTree = ""; }; + 7DA9B45F2ABBD93D00F14CE3 /* Primitives.shims.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Primitives.shims.swift; sourceTree = ""; }; + 7DA9B4612ABBD93D00F14CE3 /* AtomicInteger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AtomicInteger.swift; sourceTree = ""; }; + 7DA9B4622ABBD93D00F14CE3 /* AtomicValue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AtomicValue.swift; sourceTree = ""; }; + 7DA9B4632ABBD93D00F14CE3 /* AtomicReference.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AtomicReference.swift; sourceTree = ""; }; + 7DA9B4642ABBD93D00F14CE3 /* AtomicOptionalWrappable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AtomicOptionalWrappable.swift; sourceTree = ""; }; + 7DA9B4652ABBD93D00F14CE3 /* AtomicStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AtomicStorage.swift; sourceTree = ""; }; + 7DA9B4672ABBD93D00F14CE3 /* RawRepresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RawRepresentable.swift; sourceTree = ""; }; + 7DA9B4682ABBD93D00F14CE3 /* AtomicBool.swift.gyb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AtomicBool.swift.gyb; sourceTree = ""; }; + 7DA9B4692ABBD93D00F14CE3 /* PointerConformances.swift.gyb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PointerConformances.swift.gyb; sourceTree = ""; }; + 7DA9B46A2ABBD93D00F14CE3 /* OptionalRawRepresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionalRawRepresentable.swift; sourceTree = ""; }; + 7DA9B46B2ABBD93D00F14CE3 /* IntegerConformances.swift.gyb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = IntegerConformances.swift.gyb; sourceTree = ""; }; + 7DA9B46D2ABBD93D00F14CE3 /* IntegerConformances.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntegerConformances.swift; sourceTree = ""; }; + 7DA9B46E2ABBD93D00F14CE3 /* PointerConformances.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PointerConformances.swift; sourceTree = ""; }; + 7DA9B46F2ABBD93D00F14CE3 /* AtomicBool.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AtomicBool.swift; sourceTree = ""; }; BB63DC6A29D782010054E9C2 /* Atomics.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = Atomics.xctestplan; sourceTree = ""; }; /* End PBXFileReference section */ @@ -252,43 +259,17 @@ 7D489E5929CE96D900499B21 /* Atomics */ = { isa = PBXGroup; children = ( - 7D489E6C29CE96D900499B21 /* autogenerated */, - 7D489E6129CE96D900499B21 /* AtomicBool.swift.gyb */, - 7D489E5B29CE96D900499B21 /* AtomicInteger.swift */, - 7D489E5D29CE96D900499B21 /* AtomicLazyReference.swift.gyb */, - 7D489E6929CE96D900499B21 /* AtomicMemoryOrderings.swift */, - 7D489E6729CE96D900499B21 /* AtomicOptional.swift */, - 7D489E5E29CE96D900499B21 /* AtomicOptionalRawRepresentable.swift */, - 7D489E6229CE96D900499B21 /* AtomicRawRepresentable.swift */, + 7DA9B4662ABBD93D00F14CE3 /* Conformances */, + 7DA9B45A2ABBD93D00F14CE3 /* Primitives */, + 7DA9B4602ABBD93D00F14CE3 /* Protocols */, + 7DA9B4502ABBD93D00F14CE3 /* Types */, 7D489E6A29CE96D900499B21 /* Atomics.docc */, - 7D489E5A29CE96D900499B21 /* AtomicStrongReference.swift */, - 7D489E5F29CE96D900499B21 /* AtomicValue.swift */, 7D489E5C29CE96D900499B21 /* CMakeLists.txt */, - 7D489E6329CE96D900499B21 /* DoubleWord.swift */, - 7D489E6429CE96D900499B21 /* HighLevelTypes.swift.gyb */, - 7D489E6B29CE96D900499B21 /* IntegerConformances.swift.gyb */, - 7D489E6629CE96D900499B21 /* PointerConformances.swift.gyb */, - 7D489E6829CE96D900499B21 /* Primitives.native.swift.gyb */, - 7D489E6029CE96D900499B21 /* Primitives.shims.swift.gyb */, 7D489E6529CE96D900499B21 /* Unmanaged extensions.swift */, ); path = Atomics; sourceTree = ""; }; - 7D489E6C29CE96D900499B21 /* autogenerated */ = { - isa = PBXGroup; - children = ( - 7D489E7229CE96D900499B21 /* AtomicBool.swift */, - 7D489E6D29CE96D900499B21 /* AtomicLazyReference.swift */, - 7D489E7329CE96D900499B21 /* HighLevelTypes.swift */, - 7D489E6E29CE96D900499B21 /* IntegerConformances.swift */, - 7D489E6F29CE96D900499B21 /* PointerConformances.swift */, - 7D489E7029CE96D900499B21 /* Primitives.native.swift */, - 7D489E7129CE96D900499B21 /* Primitives.shims.swift */, - ); - path = autogenerated; - sourceTree = ""; - }; 7D489E7429CE96D900499B21 /* _AtomicsShims */ = { isa = PBXGroup; children = ( @@ -457,6 +438,83 @@ name = Xcode; sourceTree = ""; }; + 7DA9B4502ABBD93D00F14CE3 /* Types */ = { + isa = PBXGroup; + children = ( + 7DA9B4512ABBD93D00F14CE3 /* UnsafeAtomicLazyReference.swift */, + 7DA9B4522ABBD93D00F14CE3 /* IntegerOperations.swift.gyb */, + 7DA9B4532ABBD93D00F14CE3 /* DoubleWord.swift */, + 7DA9B4542ABBD93D00F14CE3 /* ManagedAtomic.swift */, + 7DA9B4552ABBD93D00F14CE3 /* ManagedAtomicLazyReference.swift */, + 7DA9B4562ABBD93D00F14CE3 /* AtomicMemoryOrderings.swift */, + 7DA9B4572ABBD93D00F14CE3 /* UnsafeAtomic.swift */, + 7DA9B4582ABBD93D00F14CE3 /* autogenerated */, + ); + path = Types; + sourceTree = ""; + }; + 7DA9B4582ABBD93D00F14CE3 /* autogenerated */ = { + isa = PBXGroup; + children = ( + 7DA9B4592ABBD93D00F14CE3 /* IntegerOperations.swift */, + ); + path = autogenerated; + sourceTree = ""; + }; + 7DA9B45A2ABBD93D00F14CE3 /* Primitives */ = { + isa = PBXGroup; + children = ( + 7DA9B45B2ABBD93D00F14CE3 /* Primitives.shims.swift.gyb */, + 7DA9B45C2ABBD93D00F14CE3 /* Primitives.native.swift.gyb */, + 7DA9B45D2ABBD93D00F14CE3 /* autogenerated */, + ); + path = Primitives; + sourceTree = ""; + }; + 7DA9B45D2ABBD93D00F14CE3 /* autogenerated */ = { + isa = PBXGroup; + children = ( + 7DA9B45E2ABBD93D00F14CE3 /* Primitives.native.swift */, + 7DA9B45F2ABBD93D00F14CE3 /* Primitives.shims.swift */, + ); + path = autogenerated; + sourceTree = ""; + }; + 7DA9B4602ABBD93D00F14CE3 /* Protocols */ = { + isa = PBXGroup; + children = ( + 7DA9B4612ABBD93D00F14CE3 /* AtomicInteger.swift */, + 7DA9B4622ABBD93D00F14CE3 /* AtomicValue.swift */, + 7DA9B4632ABBD93D00F14CE3 /* AtomicReference.swift */, + 7DA9B4642ABBD93D00F14CE3 /* AtomicOptionalWrappable.swift */, + 7DA9B4652ABBD93D00F14CE3 /* AtomicStorage.swift */, + ); + path = Protocols; + sourceTree = ""; + }; + 7DA9B4662ABBD93D00F14CE3 /* Conformances */ = { + isa = PBXGroup; + children = ( + 7DA9B4672ABBD93D00F14CE3 /* RawRepresentable.swift */, + 7DA9B4682ABBD93D00F14CE3 /* AtomicBool.swift.gyb */, + 7DA9B4692ABBD93D00F14CE3 /* PointerConformances.swift.gyb */, + 7DA9B46A2ABBD93D00F14CE3 /* OptionalRawRepresentable.swift */, + 7DA9B46B2ABBD93D00F14CE3 /* IntegerConformances.swift.gyb */, + 7DA9B46C2ABBD93D00F14CE3 /* autogenerated */, + ); + path = Conformances; + sourceTree = ""; + }; + 7DA9B46C2ABBD93D00F14CE3 /* autogenerated */ = { + isa = PBXGroup; + children = ( + 7DA9B46D2ABBD93D00F14CE3 /* IntegerConformances.swift */, + 7DA9B46E2ABBD93D00F14CE3 /* PointerConformances.swift */, + 7DA9B46F2ABBD93D00F14CE3 /* AtomicBool.swift */, + ); + path = autogenerated; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -515,7 +573,7 @@ attributes = { BuildIndependentTargetsInParallel = 1; LastSwiftUpdateCheck = 1420; - LastUpgradeCheck = 1420; + LastUpgradeCheck = 1500; TargetAttributes = { 7D489E3E29CE969D00499B21 = { CreatedOnToolsVersion = 14.2; @@ -567,23 +625,27 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 7D489EEE29CE96DA00499B21 /* IntegerConformances.swift in Sources */, + 7DA9B4802ABBD93D00F14CE3 /* AtomicStorage.swift in Sources */, + 7DA9B4752ABBD93D00F14CE3 /* AtomicMemoryOrderings.swift in Sources */, + 7DA9B47C2ABBD93D00F14CE3 /* AtomicInteger.swift in Sources */, + 7DA9B4882ABBD93D00F14CE3 /* AtomicBool.swift in Sources */, + 7DA9B47B2ABBD93D00F14CE3 /* Primitives.shims.swift in Sources */, + 7DA9B4862ABBD93D00F14CE3 /* IntegerConformances.swift in Sources */, + 7DA9B4742ABBD93D00F14CE3 /* ManagedAtomicLazyReference.swift in Sources */, + 7DA9B4812ABBD93D00F14CE3 /* RawRepresentable.swift in Sources */, + 7DA9B4872ABBD93D00F14CE3 /* PointerConformances.swift in Sources */, 7D489EF629CE96DA00499B21 /* _AtomicsShims.c in Sources */, - 7D489EDF29CE96DA00499B21 /* AtomicOptionalRawRepresentable.swift in Sources */, - 7D489EDB29CE96DA00499B21 /* AtomicStrongReference.swift in Sources */, - 7D489EE829CE96DA00499B21 /* AtomicOptional.swift in Sources */, - 7D489EF229CE96DA00499B21 /* AtomicBool.swift in Sources */, - 7D489EEF29CE96DA00499B21 /* PointerConformances.swift in Sources */, - 7D489EE029CE96DA00499B21 /* AtomicValue.swift in Sources */, - 7D489EDC29CE96DA00499B21 /* AtomicInteger.swift in Sources */, - 7D489EED29CE96DA00499B21 /* AtomicLazyReference.swift in Sources */, - 7D489EF329CE96DA00499B21 /* HighLevelTypes.swift in Sources */, + 7DA9B4732ABBD93D00F14CE3 /* ManagedAtomic.swift in Sources */, + 7DA9B47E2ABBD93D00F14CE3 /* AtomicReference.swift in Sources */, + 7DA9B47F2ABBD93D00F14CE3 /* AtomicOptionalWrappable.swift in Sources */, + 7DA9B47D2ABBD93D00F14CE3 /* AtomicValue.swift in Sources */, + 7DA9B4762ABBD93D00F14CE3 /* UnsafeAtomic.swift in Sources */, 7D489EE629CE96DA00499B21 /* Unmanaged extensions.swift in Sources */, - 7D489EE429CE96DA00499B21 /* DoubleWord.swift in Sources */, - 7D489EEA29CE96DA00499B21 /* AtomicMemoryOrderings.swift in Sources */, - 7D489EE329CE96DA00499B21 /* AtomicRawRepresentable.swift in Sources */, - 7D489EF029CE96DA00499B21 /* Primitives.native.swift in Sources */, - 7D489EF129CE96DA00499B21 /* Primitives.shims.swift in Sources */, + 7DA9B4722ABBD93D00F14CE3 /* DoubleWord.swift in Sources */, + 7DA9B4772ABBD93D00F14CE3 /* IntegerOperations.swift in Sources */, + 7DA9B4842ABBD93D00F14CE3 /* OptionalRawRepresentable.swift in Sources */, + 7DA9B4702ABBD93D00F14CE3 /* UnsafeAtomicLazyReference.swift in Sources */, + 7DA9B47A2ABBD93D00F14CE3 /* Primitives.native.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Xcode/Atomics.xcodeproj/xcshareddata/xcschemes/Atomics.xcscheme b/Xcode/Atomics.xcodeproj/xcshareddata/xcschemes/Atomics.xcscheme index d210ce2..837fae7 100644 --- a/Xcode/Atomics.xcodeproj/xcshareddata/xcschemes/Atomics.xcscheme +++ b/Xcode/Atomics.xcodeproj/xcshareddata/xcschemes/Atomics.xcscheme @@ -1,6 +1,6 @@