├── .gitignore ├── .travis.yml ├── LICENSE ├── Package.swift ├── Package@swift-4.swift ├── README.md ├── Sources └── SwiftAtomics │ ├── atomics-fence.swift │ ├── atomics-integer.swift │ ├── atomics-integer.swift.gyb │ ├── atomics-orderings.swift │ ├── atomics-pointer.swift │ ├── atomics-pointer.swift.gyb │ └── atomics-reference.swift ├── Tests-on-Device ├── Atomics Test.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── Atomics.xcscheme ├── AtomicsApp │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Default-568h@2x.png │ ├── Info.plist │ └── ViewController.swift └── AtomicsTests │ └── Info.plist ├── Tests ├── LinuxMain.swift ├── SwiftAtomicsTests │ ├── AtomicsRaceTests.swift │ ├── AtomicsTests.swift │ ├── AtomicsTests.swift.gyb │ ├── RandomPositive.swift │ ├── ReferenceTests.swift │ └── XCTestManifests.swift └── test-script.sh ├── Utilities ├── generate-linuxmain.sh ├── generate-swift.sh ├── git-pre-commit.sh ├── install-swift.sh ├── test-compatibility.diff └── validate-gybbed-files.sh └── Xcode-Old ├── Atomics.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ ├── AtomicsTestApp.xcscheme │ ├── CAtomics.xcscheme │ └── SwiftAtomics.xcscheme ├── AtomicsTestApp ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist └── ViewController.swift ├── AtomicsTestAppTests └── Info.plist ├── CAtomics └── Info.plist ├── CAtomicsTests └── Info.plist ├── SwiftAtomics └── Info.plist └── SwiftAtomicsTests ├── AtomicsPerformanceTests.swift └── Info.plist /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .build 3 | .swiftpm 4 | xcuserdatad 5 | xcuserdata 6 | gyb.py 7 | IDEWorkspaceChecks.plist 8 | .swift-version 9 | Package.resolved 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | os: linux 2 | dist: bionic 3 | language: generic 4 | 5 | jobs: 6 | include: 7 | - os: osx 8 | osx_image: xcode9.2 9 | env: SWIFT=4.0.3 10 | 11 | - os: osx 12 | osx_image: xcode9.4 13 | env: SWIFT=4.1.2 14 | 15 | - os: osx 16 | osx_image: xcode10.1 17 | env: SWIFT=4.2.1 18 | 19 | - os: osx 20 | osx_image: xcode10.3 21 | env: SWIFT=5.0.3 22 | 23 | - os: osx 24 | osx_image: xcode11.3 25 | env: SWIFT=5.1.3 26 | 27 | - os: osx 28 | osx_image: xcode11.5 29 | env: SWIFT=5.2.4 30 | 31 | - os: osx 32 | osx_image: xcode12.2 33 | env: SWIFT=5.3.1 34 | 35 | - dist: xenial 36 | env: SWIFT=4.0.3 37 | 38 | - dist: xenial 39 | env: SWIFT=4.1.3 40 | 41 | - env: SWIFT=4.2.4 42 | 43 | - env: SWIFT=5.0.3 44 | 45 | - env: SWIFT=5.1.5 46 | 47 | - env: SWIFT=5.2.4 48 | 49 | - env: SWIFT=5.3.1 50 | 51 | before_install: 52 | - . Utilities/install-swift.sh 53 | 54 | script: 55 | - /bin/bash Utilities/validate-gybbed-files.sh 56 | - /bin/bash Tests/test-script.sh 57 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2017, Guillaume Lessard 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:4.2 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "SwiftAtomics", 7 | products: [ 8 | .library(name: "SwiftAtomics", targets: ["SwiftAtomics"]), 9 | ], 10 | dependencies: [ 11 | .package(url: "https://github.com/glessard/CAtomics", from: "6.5.1"), 12 | ], 13 | targets: [ 14 | .target(name: "SwiftAtomics", dependencies: ["CAtomics"]), 15 | .testTarget(name: "SwiftAtomicsTests", dependencies: ["SwiftAtomics"]), 16 | ], 17 | swiftLanguageVersions: [.v3, .v4, .v4_2, .version("5")] 18 | ) 19 | -------------------------------------------------------------------------------- /Package@swift-4.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:4.0 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "SwiftAtomics", 7 | products: [ 8 | .library(name: "SwiftAtomics", targets: ["SwiftAtomics"]), 9 | ], 10 | dependencies: [ 11 | .package(url: "https://github.com/glessard/CAtomics", from: "6.5.1"), 12 | ], 13 | targets: [ 14 | .target(name: "SwiftAtomics", dependencies: ["CAtomics"]), 15 | .testTarget(name: "SwiftAtomicsTests", dependencies: ["SwiftAtomics"]), 16 | ], 17 | swiftLanguageVersions: [3, 4, 5] 18 | ) 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # swift-atomics [![Build Status](https://travis-ci.org/glessard/swift-atomics.svg?branch=main)](https://travis-ci.org/glessard/swift-atomics) 2 | Some atomic functions made available to Swift, thanks to Clang. 3 | 4 | NOTE: This package is deprecated in favor of the official atomics preview package, [Swift Atomics](https://github.com/apple/swift-atomics). 5 | 6 | The atomic functions available in `/usr/include/libkern/OSAtomic.h` are quite limiting in Swift, due to impedance mismatches between the type systems of Swift and C. Furthermore, some simple things such as a synchronized load or a synchronized store are not immediately available. On top of that, they have now been deprecated. 7 | 8 | Clang, of course, implements the C11 atomic functions — and they're available on Linux. 9 | 10 | This project bridges a subset of Clang's C11 atomics support to Swift, as two modules. 11 | 12 | The latest version (6.5.0) supports Swift 4.0 and up. 13 | 14 | Version 6.2.3 of this package supports versions of Swift as far back as 3.1.1 15 | 16 | ### Module SwiftAtomics 17 | 18 | `SwiftAtomics` has a swift-style interface to provide access to atomic operations. 19 | `SwiftAtomics` implements the following types: 20 | - `AtomicPointer`, `AtomicMutablePointer`, `AtomicRawPointer`, `AtomicMutableRawPointer` and `AtomicOpaquePointer`; 21 | - `AtomicInt` and `AtomicUInt`, as well as signed and unsigned versions of the 8-bit, 16-bit, 32-bit and 64-bit integer types; 22 | - `AtomicBool` 23 | 24 | The pointer types have the following methods: 25 | - `load`, `store`, `swap`, and `CAS` 26 | 27 | The integer types have the following methods: 28 | - `load`, `store`, `swap`, `CAS`, `add`, `subtract`, `increment`, `decrement`, `bitwiseAnd`, `bitwiseOr`, and `bitwiseXor` 29 | 30 | `AtomicBool` has the following methods: 31 | - `load`, `store`, `swap`, `CAS`, `and`, `or`, and `xor`. 32 | 33 | The memory ordering (from ``) can be set by using the `order` parameter on each method; the defaults are `.acquire` for loading operations, `.release` for storing operations, and `.acqrel` for read-modify-write operations. Note that `memory_order_consume` has no equivalent in this module, as (as far as I can tell) clang silently upgrades that ordering to `memory_order_acquire`, making it impossible (at the moment) to test whether an algorithm can properly use `memory_order_consume`. This also means nothing is lost by its absence. 34 | 35 | The integer types have a `value` property, as a convenient way to perform a `.relaxed` load. 36 | The pointer types have a `pointer` property, which performs an `.acquire` load. 37 | 38 | #### Notes on atomics and the law-of-exclusivity: 39 | 40 | Atomic types are useful as synchronization points between threads, and therefore have an interesting relationship with Swift's exclusivity checking. They should be used as members of reference types, or directly captured by closures. They are `struct` types, so as to be not incur additional memory allocation, but that feature means that if you use the thread sanitizer, it will warn about them. 41 | 42 | The types defined in `SwiftAtomics` work as expected with Swift 5's run-time exclusivity checking when used as members of class instances, but present difficulties when the thread sanitizer is enabled. 43 | 44 | In order to use atomics in a way that is acceptable to the thread sanitizer, one must have allocated memory for atomic variables on the heap using `UnsafeMutablePointer`. If you require compatibility with the thread sanitizer, it is best to use the underlying dependency [`CAtomics`](https://github.com/glessard/CAtomics) directly or, even better, the official [Swift Atomics](https://github.com/apple/swift-atomics) atomics preview package. 45 | 46 | #### Requirements 47 | 48 | This version of `SwiftAtomics` requires Swift 4.0 or later. On Linux, it also requires Clang 3.6 or later. 49 | -------------------------------------------------------------------------------- /Sources/SwiftAtomics/atomics-fence.swift: -------------------------------------------------------------------------------- 1 | // 2 | // atomics-fence.swift 3 | // Atomics 4 | // 5 | // Created by Guillaume Lessard on 09/02/2017. 6 | // Copyright © 2017 Guillaume Lessard. All rights reserved. 7 | // This file is distributed under the BSD 3-clause license. See LICENSE for details. 8 | // 9 | 10 | import func CAtomics.CAtomicsThreadFence 11 | @_exported import enum CAtomics.MemoryOrder 12 | 13 | public func threadFence(order: MemoryOrder = .acqrel) 14 | { 15 | CAtomicsThreadFence(order) 16 | } 17 | -------------------------------------------------------------------------------- /Sources/SwiftAtomics/atomics-integer.swift.gyb: -------------------------------------------------------------------------------- 1 | // 2 | // atomics-integer.swift 3 | // Atomics 4 | // 5 | // Created by Guillaume Lessard on 31/05/2016. 6 | // Copyright © 2016-2017 Guillaume Lessard. All rights reserved. 7 | // This file is distributed under the BSD 3-clause license. See LICENSE for details. 8 | // 9 | 10 | @_exported import enum CAtomics.MemoryOrder 11 | @_exported import enum CAtomics.LoadMemoryOrder 12 | @_exported import enum CAtomics.StoreMemoryOrder 13 | @_exported import enum CAtomics.CASType 14 | import CAtomics 15 | % for IntType in ['Int', 'UInt', 'Int8', 'UInt8', 'Int16', 'UInt16', 'Int32', 'UInt32', 'Int64', 'UInt64', 'Bool']: 16 | % AtomicType = 'Atomic' + IntType 17 | 18 | @_exported import struct CAtomics.${AtomicType} 19 | 20 | extension ${AtomicType} 21 | { 22 | #if swift(>=4.2) 23 | % for inlinable in ['@inlinable', '@inline(__always)']: 24 | % usableFromInline = '@usableFromInline' if inlinable == '@inlinable' else '@_versioned' 25 | % end = '#else' if inlinable == '@inlinable' else '#endif' 26 | public var value: ${IntType} { 27 | ${inlinable} 28 | mutating get { return CAtomicsLoad(&self, .relaxed) } 29 | } 30 | 31 | ${inlinable} 32 | public mutating func initialize(_ value: ${IntType}) 33 | { 34 | CAtomicsInitialize(&self, value) 35 | } 36 | 37 | 38 | ${inlinable} 39 | public mutating func load(order: LoadMemoryOrder = .acquire) -> ${IntType} 40 | { 41 | return CAtomicsLoad(&self, order) 42 | } 43 | 44 | ${inlinable} 45 | public mutating func store(_ value: ${IntType}, order: StoreMemoryOrder = .release) 46 | { 47 | CAtomicsStore(&self, value, order) 48 | } 49 | 50 | 51 | ${inlinable} 52 | public mutating func swap(_ value: ${IntType}, order: MemoryOrder = .acqrel) -> ${IntType} 53 | { 54 | return CAtomicsExchange(&self, value, order) 55 | } 56 | 57 | % if IntType == 'Bool': 58 | % for (rmwMethod, rmwFunc, rmwParam) in [('or', 'Or', 'value'), ('xor', 'Xor', 'value'), ('and', 'And', 'value')]: 59 | 60 | ${inlinable} @discardableResult 61 | public mutating func ${rmwMethod}(_ ${rmwParam}: ${IntType}, order: MemoryOrder = .acqrel) -> ${IntType} 62 | { 63 | return CAtomics${rmwFunc}(&self, ${rmwParam}, order) 64 | } 65 | 66 | % end # for 67 | % else: 68 | % for (rmwMethod, rmwFunc, rmwParam) in [('add', 'Add', 'delta'), ('subtract', 'Subtract', 'delta'), ('bitwiseOr', 'BitwiseOr', 'bits'), ('bitwiseXor', 'BitwiseXor', 'bits'), ('bitwiseAnd', 'BitwiseAnd', 'bits')]: 69 | ${inlinable} @discardableResult 70 | public mutating func ${rmwMethod}(_ ${rmwParam}: ${IntType}, order: MemoryOrder = .acqrel) -> ${IntType} 71 | { 72 | return CAtomics${rmwFunc}(&self, ${rmwParam}, order) 73 | } 74 | 75 | % end # for 76 | % for (inc, op) in [('increment', 'Add'), ('decrement', 'Subtract')]: 77 | ${inlinable} @discardableResult 78 | public mutating func ${inc}(order: MemoryOrder = .acqrel) -> ${IntType} 79 | { 80 | return CAtomics${op}(&self, 1, order) 81 | } 82 | 83 | % end # for 84 | % end # if IntType == 'Bool' 85 | ${inlinable} @discardableResult 86 | public mutating func loadCAS(current: inout ${IntType}, future: ${IntType}, 87 | type: CASType = .strong, 88 | orderSwap: MemoryOrder = .acqrel, 89 | orderLoad: LoadMemoryOrder = .acquire) -> Bool 90 | { 91 | return type == .weak 92 | ? CAtomicsCompareAndExchangeWeak(&self, ¤t, future, orderSwap, orderLoad) 93 | : CAtomicsCompareAndExchangeStrong(&self, ¤t, future, orderSwap, orderLoad) 94 | } 95 | 96 | ${inlinable} @discardableResult 97 | public mutating func CAS(current: ${IntType}, future: ${IntType}, 98 | type: CASType = .strong, 99 | order: MemoryOrder = .acqrel) -> Bool 100 | { 101 | var current = current 102 | return loadCAS(current: ¤t, future: future, type: type, 103 | orderSwap: order, orderLoad: order.asLoadOrdering()) 104 | } 105 | ${end} 106 | % end # inlinable 107 | } 108 | % end # for AtomicType 109 | -------------------------------------------------------------------------------- /Sources/SwiftAtomics/atomics-orderings.swift: -------------------------------------------------------------------------------- 1 | // 2 | // atomics-orderings.swift 3 | // 4 | // 5 | // Created by Guillaume Lessard on 4/4/20. 6 | // 7 | 8 | import CAtomics 9 | 10 | extension MemoryOrder 11 | { 12 | #if swift(>=4.2) 13 | @usableFromInline 14 | internal func asLoadOrdering() -> LoadMemoryOrder 15 | { 16 | switch self { 17 | case .relaxed: return .relaxed 18 | case .acquire: return .acquire 19 | case .release: return .relaxed 20 | case .acqrel : return .acquire 21 | case .sequential: return .sequential 22 | default: return LoadMemoryOrder(rawValue: rawValue)! 23 | } 24 | } 25 | #else 26 | @_versioned 27 | internal func asLoadOrdering() -> LoadMemoryOrder 28 | { 29 | switch self { 30 | case .relaxed: return .relaxed 31 | case .acquire: return .acquire 32 | case .release: return .relaxed 33 | case .acqrel : return .acquire 34 | case .sequential: return .sequential 35 | default: return LoadMemoryOrder(rawValue: rawValue)! 36 | } 37 | } 38 | #endif 39 | } 40 | -------------------------------------------------------------------------------- /Sources/SwiftAtomics/atomics-pointer.swift.gyb: -------------------------------------------------------------------------------- 1 | // 2 | // atomics-pointer.swift 3 | // Atomics 4 | // 5 | // Created by Guillaume Lessard on 2015-05-21. 6 | // Copyright © 2015-2017 Guillaume Lessard. All rights reserved. 7 | // This file is distributed under the BSD 3-clause license. See LICENSE for details. 8 | // 9 | 10 | @_exported import enum CAtomics.MemoryOrder 11 | @_exported import enum CAtomics.LoadMemoryOrder 12 | @_exported import enum CAtomics.StoreMemoryOrder 13 | @_exported import enum CAtomics.CASType 14 | import CAtomics 15 | % for Nullable in ['', 'Optional']: 16 | % for Mutable in ['', 'Mutable']: 17 | % Pointer = 'Pointer?' if (Nullable == 'Optional') else 'Pointer' 18 | % optional = '?' if (Nullable == 'Optional') else '' 19 | 20 | public struct Atomic${Nullable}${Mutable}Pointer 21 | { 22 | #if swift(>=4.2) 23 | % for inlinable in ['@inlinable', '@inline(__always)']: 24 | % usableFromInline = '@usableFromInline' if inlinable == '@inlinable' else '@_versioned' 25 | % end = '#else' if inlinable == '@inlinable' else '#endif' 26 | ${usableFromInline} var ptr = Atomic${Nullable}${Mutable}RawPointer() 27 | ${end} 28 | % end # inlinable 29 | 30 | % if Nullable == 'Optional': 31 | public init() 32 | { 33 | CAtomicsInitialize(&ptr, nil) 34 | } 35 | 36 | % end 37 | public init(_ pointer: Unsafe${Mutable}${Pointer}) 38 | { 39 | CAtomicsInitialize(&ptr, pointer) 40 | } 41 | 42 | public mutating func initialize(_ pointer: Unsafe${Mutable}${Pointer}) 43 | { 44 | CAtomicsInitialize(&ptr, pointer) 45 | } 46 | 47 | #if swift(>=4.2) 48 | % for inlinable in ['@inlinable', '@inline(__always)']: 49 | % usableFromInline = '@usableFromInline' if inlinable == '@inlinable' else '@_versioned' 50 | % end = '#else' if inlinable == '@inlinable' else '#endif' 51 | public var pointer: Unsafe${Mutable}${Pointer} { 52 | ${inlinable} 53 | mutating get { 54 | return CAtomicsLoad(&ptr, .acquire)${optional}.assumingMemoryBound(to: Pointee.self) 55 | } 56 | } 57 | 58 | ${inlinable} 59 | public mutating func load(order: LoadMemoryOrder = .acquire) -> Unsafe${Mutable}${Pointer} 60 | { 61 | return CAtomicsLoad(&ptr, order)${optional}.assumingMemoryBound(to: Pointee.self) 62 | } 63 | 64 | ${inlinable} 65 | public mutating func store(_ pointer: Unsafe${Mutable}${Pointer}, order: StoreMemoryOrder = .release) 66 | { 67 | CAtomicsStore(&ptr, pointer, order) 68 | } 69 | 70 | ${inlinable} 71 | public mutating func swap(_ pointer: Unsafe${Mutable}${Pointer}, order: MemoryOrder = .acqrel) -> Unsafe${Mutable}${Pointer} 72 | { 73 | return CAtomicsExchange(&ptr, pointer, order)${optional}.assumingMemoryBound(to: Pointee.self) 74 | } 75 | 76 | ${inlinable} @discardableResult 77 | public mutating func loadCAS(current: inout Unsafe${Mutable}${Pointer}, 78 | future: Unsafe${Mutable}${Pointer}, 79 | type: CASType = .strong, 80 | orderSwap: MemoryOrder = .acqrel, 81 | orderLoad: LoadMemoryOrder = .acquire) -> Bool 82 | { 83 | var c = Unsafe${Mutable}RawPointer(current) 84 | let s = (type == .weak) 85 | ? CAtomicsCompareAndExchangeWeak(&ptr, &c, future, orderSwap, orderLoad) 86 | : CAtomicsCompareAndExchangeStrong(&ptr, &c, future, orderSwap, orderLoad) 87 | current = c${optional}.assumingMemoryBound(to: Pointee.self) 88 | return s 89 | } 90 | 91 | ${inlinable} @discardableResult 92 | public mutating func CAS(current: Unsafe${Mutable}${Pointer}, future: Unsafe${Mutable}${Pointer}, 93 | type: CASType = .strong, 94 | order: MemoryOrder = .acqrel) -> Bool 95 | { 96 | var current = current 97 | return loadCAS(current: ¤t, future: future, type: type, 98 | orderSwap: order, orderLoad: order.asLoadOrdering()) 99 | } 100 | ${end} 101 | % end # inlinable 102 | } 103 | % end 104 | % end 105 | % for type in ['Raw', 'MutableRaw', 'Opaque']: 106 | % for optional in ['', 'Optional']: 107 | 108 | @_exported import struct CAtomics.Atomic${optional}${type}Pointer 109 | 110 | % opt = '?' if optional else '' 111 | % prefix = '' if type == 'Opaque' else 'Unsafe' 112 | extension Atomic${optional}${type}Pointer 113 | { 114 | #if swift(>=4.2) 115 | % for inlinable in ['@inlinable', '@inline(__always)']: 116 | % usableFromInline = '@usableFromInline' if inlinable == '@inlinable' else '@_versioned' 117 | % end = '#else' if inlinable == '@inlinable' else '#endif' 118 | public var pointer: ${prefix}${type}Pointer${opt} { 119 | ${inlinable} 120 | mutating get { 121 | return CAtomicsLoad(&self, .acquire) 122 | } 123 | } 124 | 125 | ${inlinable} 126 | public mutating func initialize(_ pointer: ${prefix}${type}Pointer${opt}) 127 | { 128 | CAtomicsInitialize(&self, pointer) 129 | } 130 | 131 | ${inlinable} 132 | public mutating func load(order: LoadMemoryOrder = .acquire) -> ${prefix}${type}Pointer${opt} 133 | { 134 | return CAtomicsLoad(&self, order) 135 | } 136 | 137 | ${inlinable} 138 | public mutating func store(_ pointer: ${prefix}${type}Pointer${opt}, order: StoreMemoryOrder = .release) 139 | { 140 | CAtomicsStore(&self, pointer, order) 141 | } 142 | 143 | ${inlinable} 144 | public mutating func swap(_ pointer: ${prefix}${type}Pointer${opt}, order: MemoryOrder = .acqrel) -> ${prefix}${type}Pointer${opt} 145 | { 146 | return CAtomicsExchange(&self, pointer, order) 147 | } 148 | 149 | ${inlinable} @discardableResult 150 | public mutating func loadCAS(current: inout ${prefix}${type}Pointer${opt}, 151 | future: ${prefix}${type}Pointer${opt}, 152 | type: CASType = .strong, 153 | orderSwap: MemoryOrder = .acqrel, 154 | orderLoad: LoadMemoryOrder = .acquire) -> Bool 155 | { 156 | return type == .weak 157 | ? CAtomicsCompareAndExchangeWeak(&self, ¤t, future, orderSwap, orderLoad) 158 | : CAtomicsCompareAndExchangeStrong(&self, ¤t, future, orderSwap, orderLoad) 159 | } 160 | 161 | ${inlinable} @discardableResult 162 | public mutating func CAS(current: ${prefix}${type}Pointer${opt}, future: ${prefix}${type}Pointer${opt}, 163 | type: CASType = .strong, 164 | order: MemoryOrder = .acqrel) -> Bool 165 | { 166 | var current = current 167 | return loadCAS(current: ¤t, future: future, type: type, 168 | orderSwap: order, orderLoad: order.asLoadOrdering()) 169 | } 170 | ${end} 171 | % end # inlinable 172 | } 173 | % end 174 | % end 175 | 176 | % for type in ['Raw', 'MutableRaw']: 177 | % for optional in ['', 'Optional']: 178 | @_exported import struct CAtomics.AtomicTagged${optional}${type}Pointer 179 | 180 | % opt = '?' if optional else '' 181 | extension AtomicTagged${optional}${type}Pointer 182 | { 183 | public init(_ p: (pointer: Unsafe${type}Pointer${opt}, tag: Int)) 184 | { 185 | self.init(Tagged${optional}${type}Pointer(p.pointer, tag: p.tag)) 186 | } 187 | 188 | #if swift(>=4.2) 189 | % for inlinable in ['@inlinable', '@inline(__always)']: 190 | % usableFromInline = '@usableFromInline' if inlinable == '@inlinable' else '@_versioned' 191 | % end = '#else' if inlinable == '@inlinable' else '#endif' 192 | public var value: (pointer: Unsafe${type}Pointer${opt}, tag: Int) { 193 | ${inlinable} 194 | mutating get { 195 | let t = CAtomicsLoad(&self, .acquire) 196 | return (t.ptr, t.tag) 197 | } 198 | } 199 | 200 | ${inlinable} 201 | public mutating func initialize(_ p: (pointer: Unsafe${type}Pointer${opt}, tag: Int)) 202 | { 203 | CAtomicsInitialize(&self, Tagged${optional}${type}Pointer(p.pointer, tag: p.tag)) 204 | } 205 | 206 | ${inlinable} 207 | public mutating func load(order: LoadMemoryOrder = .acquire) -> (pointer: Unsafe${type}Pointer${opt}, tag: Int) 208 | { 209 | let t = CAtomicsLoad(&self, order) 210 | return (t.ptr, t.tag) 211 | } 212 | 213 | ${inlinable} 214 | public mutating func store(_ p: (pointer: Unsafe${type}Pointer${opt}, tag: Int), order: StoreMemoryOrder = .release) 215 | { 216 | CAtomicsStore(&self, Tagged${optional}${type}Pointer(p.pointer, tag: p.tag), order) 217 | } 218 | 219 | ${inlinable} 220 | public mutating func swap(_ p: (pointer: Unsafe${type}Pointer${opt}, tag: Int), order: MemoryOrder = .acqrel) -> (pointer: Unsafe${type}Pointer${opt}, tag: Int) 221 | { 222 | let t = CAtomicsExchange(&self, Tagged${optional}${type}Pointer(p.pointer, tag: p.tag), order) 223 | return (t.ptr, t.tag) 224 | } 225 | 226 | ${inlinable} @discardableResult 227 | public mutating func loadCAS(current: inout (pointer: Unsafe${type}Pointer${opt}, tag: Int), 228 | future: (pointer: Unsafe${type}Pointer${opt}, tag: Int), 229 | type: CASType = .strong, 230 | orderSwap: MemoryOrder = .acqrel, 231 | orderLoad: LoadMemoryOrder = .acquire) -> Bool 232 | { 233 | var c = Tagged${optional}${type}Pointer(current.0, tag: current.1) 234 | let f = Tagged${optional}${type}Pointer(future.0, tag: future.1) 235 | let s = (type == .weak) 236 | ? CAtomicsCompareAndExchangeWeak(&self, &c, f, orderSwap, orderLoad) 237 | : CAtomicsCompareAndExchangeStrong(&self, &c, f, orderSwap, orderLoad) 238 | current = (c.ptr, c.tag) 239 | return s 240 | } 241 | 242 | ${inlinable} @discardableResult 243 | public mutating func CAS(current: (pointer: Unsafe${type}Pointer${opt}, tag: Int), 244 | future: (pointer: Unsafe${type}Pointer${opt}, tag: Int), 245 | type: CASType = .strong, 246 | order: MemoryOrder = .acqrel) -> Bool 247 | { 248 | var current = current 249 | return loadCAS(current: ¤t, future: future, type: type, 250 | orderSwap: order, orderLoad: order.asLoadOrdering()) 251 | } 252 | ${end} 253 | % end # inlinable 254 | } 255 | 256 | % end 257 | % end 258 | @available(*, unavailable, renamed: "AtomicPointer") 259 | public typealias AtomicNonNullPointer = AtomicPointer 260 | 261 | @available(*, unavailable, renamed: "AtomicMutablePointer") 262 | public typealias AtomicNonNullMutablePointer = AtomicMutablePointer 263 | 264 | @available(*, unavailable, renamed: "AtomicRawPointer") 265 | public typealias AtomicNonNullRawPointer = AtomicRawPointer 266 | 267 | @available(*, unavailable, renamed: "AtomicMutableRawPointer") 268 | public typealias AtomicNonNullMutableRawPointer = AtomicMutableRawPointer 269 | 270 | @available(*, unavailable, renamed: "AtomicOpaquePointer") 271 | public typealias AtomicNonNullOpaquePointer = AtomicOpaquePointer 272 | -------------------------------------------------------------------------------- /Sources/SwiftAtomics/atomics-reference.swift: -------------------------------------------------------------------------------- 1 | // 2 | // atomics-reference.swift 3 | // Atomics 4 | // 5 | // Created by Guillaume Lessard on 1/16/17. 6 | // Copyright © 2017 Guillaume Lessard. All rights reserved. 7 | // This file is distributed under the BSD 3-clause license. See LICENSE for details. 8 | // 9 | 10 | @_exported import enum CAtomics.MemoryOrder 11 | @_exported import enum CAtomics.LoadMemoryOrder 12 | @_exported import enum CAtomics.StoreMemoryOrder 13 | import CAtomics 14 | 15 | import struct CAtomics.OpaqueUnmanagedHelper 16 | 17 | #if !swift(>=3.2) 18 | extension MemoryOrder 19 | { 20 | @_versioned init(order: LoadMemoryOrder) 21 | { 22 | self = MemoryOrder.init(rawValue: order.rawValue) ?? .sequential 23 | } 24 | 25 | @_versioned init(order: StoreMemoryOrder) 26 | { 27 | self = MemoryOrder.init(rawValue: order.rawValue) ?? .sequential 28 | } 29 | } 30 | #endif 31 | 32 | public struct AtomicReference 33 | { 34 | #if swift(>=4.2) 35 | @usableFromInline internal var ptr = OpaqueUnmanagedHelper() 36 | #else 37 | @_versioned internal var ptr = OpaqueUnmanagedHelper() 38 | #endif 39 | 40 | public init(_ reference: T? = nil) 41 | { 42 | self.initialize(reference) 43 | } 44 | 45 | mutating public func initialize(_ reference: T?) 46 | { 47 | let u = reference.map { Unmanaged.passRetained($0).toOpaque() } 48 | CAtomicsInitialize(&ptr, u) 49 | } 50 | } 51 | 52 | extension AtomicReference 53 | { 54 | #if swift(>=4.2) 55 | @inlinable 56 | public mutating func swap(_ reference: T?, order: MemoryOrder = .acqrel) -> T? 57 | { 58 | let u = reference.map { Unmanaged.passRetained($0).toOpaque() } 59 | 60 | let pointer = CAtomicsExchange(&ptr, u, order) 61 | return pointer.map { Unmanaged.fromOpaque($0).takeRetainedValue() } 62 | } 63 | #else 64 | @inline(__always) 65 | public mutating func swap(_ reference: T?, order: MemoryOrder = .acqrel) -> T? 66 | { 67 | let u = reference.map { Unmanaged.passRetained($0).toOpaque() } 68 | 69 | let pointer = CAtomicsExchange(&ptr, u, order) 70 | return pointer.map { Unmanaged.fromOpaque($0).takeRetainedValue() } 71 | } 72 | #endif 73 | 74 | #if swift(>=5.0) 75 | @available(swift, obsoleted: 5.0, renamed: "storeIfNil(_:order:)") 76 | public mutating func swapIfNil(_ ref: T, order: MemoryOrder = .sequential) -> Bool { fatalError() } 77 | #else 78 | @available(*, deprecated, renamed: "storeIfNil(_:order:)") 79 | public mutating func swapIfNil(_ ref: T, order: StoreMemoryOrder = .sequential) -> Bool 80 | { 81 | return self.storeIfNil(ref, order: order) 82 | } 83 | #endif 84 | 85 | #if swift(>=4.2) 86 | @inlinable 87 | public mutating func storeIfNil(_ reference: T, order: StoreMemoryOrder = .release) -> Bool 88 | { 89 | let u = Unmanaged.passRetained(reference) 90 | if CAtomicsCompareAndExchange(&ptr, nil, u.toOpaque(), .strong, MemoryOrder(rawValue: order.rawValue)!) 91 | { return true } 92 | 93 | u.release() 94 | return false 95 | } 96 | #elseif swift(>=3.2) 97 | @inline(__always) 98 | public mutating func storeIfNil(_ reference: T, order: StoreMemoryOrder = .release) -> Bool 99 | { 100 | let u = Unmanaged.passRetained(reference) 101 | if CAtomicsCompareAndExchange(&ptr, nil, u.toOpaque(), .strong, MemoryOrder(rawValue: order.rawValue)!) 102 | { return true } 103 | 104 | u.release() 105 | return false 106 | } 107 | #else 108 | @inline(__always) 109 | public mutating func storeIfNil(_ reference: T, order: StoreMemoryOrder = .sequential) -> Bool 110 | { 111 | let u = Unmanaged.passRetained(reference) 112 | if CAtomicsCompareAndExchange(&ptr, nil, u.toOpaque(), .strong, MemoryOrder(order: order)) 113 | { return true } 114 | 115 | u.release() 116 | return false 117 | } 118 | #endif 119 | 120 | #if swift(>=4.2) 121 | @inlinable 122 | public mutating func take(order: LoadMemoryOrder = .acquire) -> T? 123 | { 124 | let pointer = CAtomicsExchange(&ptr, nil, MemoryOrder(rawValue: order.rawValue)!) 125 | return pointer.map { Unmanaged.fromOpaque($0).takeRetainedValue() } 126 | } 127 | #elseif swift(>=3.2) 128 | @inline(__always) 129 | public mutating func take(order: LoadMemoryOrder = .acquire) -> T? 130 | { 131 | let pointer = CAtomicsExchange(&ptr, nil, MemoryOrder(rawValue: order.rawValue)!) 132 | return pointer.map { Unmanaged.fromOpaque($0).takeRetainedValue() } 133 | } 134 | #else // swift 3.1 135 | @inline(__always) 136 | public mutating func take(order: LoadMemoryOrder = .sequential) -> T? 137 | { 138 | let pointer = CAtomicsExchange(&ptr, nil, MemoryOrder(order: order)) 139 | return pointer.map { Unmanaged.fromOpaque($0).takeRetainedValue() } 140 | } 141 | #endif 142 | 143 | #if swift(>=4.2) 144 | @inlinable @discardableResult 145 | public mutating func CAS(current: T?, future: T?, 146 | order: MemoryOrder = .acqrel) -> Bool 147 | { 148 | let c = current.map(Unmanaged.passUnretained) 149 | let f = future.map(Unmanaged.passRetained) 150 | 151 | if CAtomicsCompareAndExchangeStrong(&ptr, c?.toOpaque(), f?.toOpaque(), order) 152 | { 153 | c?.release() 154 | return true 155 | } 156 | 157 | f?.release() 158 | return false 159 | } 160 | #else 161 | @inline(__always) @discardableResult 162 | public mutating func CAS(current: T?, future: T?, 163 | order: MemoryOrder = .acqrel) -> Bool 164 | { 165 | let c = current.map(Unmanaged.passUnretained) 166 | let f = future.map(Unmanaged.passRetained) 167 | 168 | if CAtomicsCompareAndExchangeStrong(&ptr, c?.toOpaque(), f?.toOpaque(), order) 169 | { 170 | c?.release() 171 | return true 172 | } 173 | 174 | f?.release() 175 | return false 176 | } 177 | #endif 178 | 179 | @available(*, deprecated, renamed: "CAS(current:future:order:)") 180 | public mutating func CAS(current: T?, future: T?, type: CASType, order: MemoryOrder = .acqrel) -> Bool 181 | { 182 | return CAS(current: current, future: future, order: order) 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /Tests-on-Device/Atomics Test.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 52; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 031F70642374A8DA0086343E /* AtomicsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031F705A2374A8B10086343E /* AtomicsTests.swift */; }; 11 | 031F70652374A8DA0086343E /* AtomicsRaceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031F70582374A8B10086343E /* AtomicsRaceTests.swift */; }; 12 | 031F70662374A8DA0086343E /* ReferenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031F70572374A8B10086343E /* ReferenceTests.swift */; }; 13 | 031F70672374A8DA0086343E /* CAtomicsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031F70562374A8B10086343E /* CAtomicsTests.swift */; }; 14 | 031F70682374A8DA0086343E /* CAtomicsRaceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031F70542374A8B00086343E /* CAtomicsRaceTests.swift */; }; 15 | 031F70692374A8DA0086343E /* CAtomicsReferenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031F705B2374A8B10086343E /* CAtomicsReferenceTests.swift */; }; 16 | 031F706A2374A8DA0086343E /* MemoryOrderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031F70592374A8B10086343E /* MemoryOrderTests.swift */; }; 17 | 031F706B2374A8DA0086343E /* RandomPositive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031F70552374A8B10086343E /* RandomPositive.swift */; }; 18 | 031F706D2374A93A0086343E /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 031F706C2374A93A0086343E /* Default-568h@2x.png */; }; 19 | 0382B62920DC4A2B00F4B44B /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0382B62820DC4A2B00F4B44B /* AppDelegate.swift */; }; 20 | 0382B62B20DC4A2B00F4B44B /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0382B62A20DC4A2B00F4B44B /* ViewController.swift */; }; 21 | 0382B62E20DC4A2B00F4B44B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0382B62C20DC4A2B00F4B44B /* Main.storyboard */; }; 22 | 0382B63020DC4A2D00F4B44B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0382B62F20DC4A2D00F4B44B /* Assets.xcassets */; }; 23 | 0382B63320DC4A2D00F4B44B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0382B63120DC4A2D00F4B44B /* LaunchScreen.storyboard */; }; 24 | 0388884F2384546F0086343E /* CAtomics in Frameworks */ = {isa = PBXBuildFile; productRef = 0388884E2384546F0086343E /* CAtomics */; }; 25 | 038888512384546F0086343E /* SwiftAtomics in Frameworks */ = {isa = PBXBuildFile; productRef = 038888502384546F0086343E /* SwiftAtomics */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXContainerItemProxy section */ 29 | 0382B63A20DC4A2D00F4B44B /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = 031CA33520DBDC0400F4B44B /* Project object */; 32 | proxyType = 1; 33 | remoteGlobalIDString = 0382B62520DC4A2B00F4B44B; 34 | remoteInfo = AtomicsTestApp; 35 | }; 36 | /* End PBXContainerItemProxy section */ 37 | 38 | /* Begin PBXCopyFilesBuildPhase section */ 39 | 0382B65A20DC52CF00F4B44B /* Embed Frameworks */ = { 40 | isa = PBXCopyFilesBuildPhase; 41 | buildActionMask = 2147483647; 42 | dstPath = ""; 43 | dstSubfolderSpec = 10; 44 | files = ( 45 | ); 46 | name = "Embed Frameworks"; 47 | runOnlyForDeploymentPostprocessing = 0; 48 | }; 49 | /* End PBXCopyFilesBuildPhase section */ 50 | 51 | /* Begin PBXFileReference section */ 52 | 031F70542374A8B00086343E /* CAtomicsRaceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CAtomicsRaceTests.swift; path = ../../Tests/CAtomicsTests/CAtomicsRaceTests.swift; sourceTree = ""; }; 53 | 031F70552374A8B10086343E /* RandomPositive.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RandomPositive.swift; path = ../../Tests/CAtomicsTests/RandomPositive.swift; sourceTree = ""; }; 54 | 031F70562374A8B10086343E /* CAtomicsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CAtomicsTests.swift; path = ../../Tests/CAtomicsTests/CAtomicsTests.swift; sourceTree = ""; }; 55 | 031F70572374A8B10086343E /* ReferenceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ReferenceTests.swift; path = ../../Tests/SwiftAtomicsTests/ReferenceTests.swift; sourceTree = ""; }; 56 | 031F70582374A8B10086343E /* AtomicsRaceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AtomicsRaceTests.swift; path = ../../Tests/SwiftAtomicsTests/AtomicsRaceTests.swift; sourceTree = ""; }; 57 | 031F70592374A8B10086343E /* MemoryOrderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MemoryOrderTests.swift; path = ../../Tests/CAtomicsTests/MemoryOrderTests.swift; sourceTree = ""; }; 58 | 031F705A2374A8B10086343E /* AtomicsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AtomicsTests.swift; path = ../../Tests/SwiftAtomicsTests/AtomicsTests.swift; sourceTree = ""; }; 59 | 031F705B2374A8B10086343E /* CAtomicsReferenceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CAtomicsReferenceTests.swift; path = ../../Tests/CAtomicsTests/CAtomicsReferenceTests.swift; sourceTree = ""; }; 60 | 031F706C2374A93A0086343E /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 61 | 0382B62620DC4A2B00F4B44B /* Atomics.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Atomics.app; sourceTree = BUILT_PRODUCTS_DIR; }; 62 | 0382B62820DC4A2B00F4B44B /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 63 | 0382B62A20DC4A2B00F4B44B /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 64 | 0382B62D20DC4A2B00F4B44B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 65 | 0382B62F20DC4A2D00F4B44B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 66 | 0382B63220DC4A2D00F4B44B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 67 | 0382B63420DC4A2D00F4B44B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 68 | 0382B63920DC4A2D00F4B44B /* AtomicsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AtomicsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 69 | 0382B63F20DC4A2D00F4B44B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 70 | 0388884D2384541D0086343E /* swift-atomics */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "swift-atomics"; path = ..; sourceTree = ""; }; 71 | /* End PBXFileReference section */ 72 | 73 | /* Begin PBXFrameworksBuildPhase section */ 74 | 0382B62320DC4A2B00F4B44B /* Frameworks */ = { 75 | isa = PBXFrameworksBuildPhase; 76 | buildActionMask = 2147483647; 77 | files = ( 78 | 0388884F2384546F0086343E /* CAtomics in Frameworks */, 79 | 038888512384546F0086343E /* SwiftAtomics in Frameworks */, 80 | ); 81 | runOnlyForDeploymentPostprocessing = 0; 82 | }; 83 | 0382B63620DC4A2D00F4B44B /* Frameworks */ = { 84 | isa = PBXFrameworksBuildPhase; 85 | buildActionMask = 2147483647; 86 | files = ( 87 | ); 88 | runOnlyForDeploymentPostprocessing = 0; 89 | }; 90 | /* End PBXFrameworksBuildPhase section */ 91 | 92 | /* Begin PBXGroup section */ 93 | 031CA33420DBDC0400F4B44B = { 94 | isa = PBXGroup; 95 | children = ( 96 | 0388884D2384541D0086343E /* swift-atomics */, 97 | 0382B62720DC4A2B00F4B44B /* AtomicsApp */, 98 | 0382B63C20DC4A2D00F4B44B /* AtomicsTests */, 99 | 031CA33F20DBDC0400F4B44B /* Products */, 100 | 031CA3AB20DC401400F4B44B /* Frameworks */, 101 | ); 102 | sourceTree = ""; 103 | }; 104 | 031CA33F20DBDC0400F4B44B /* Products */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 0382B62620DC4A2B00F4B44B /* Atomics.app */, 108 | 0382B63920DC4A2D00F4B44B /* AtomicsTests.xctest */, 109 | ); 110 | name = Products; 111 | sourceTree = ""; 112 | }; 113 | 031CA3AB20DC401400F4B44B /* Frameworks */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | ); 117 | name = Frameworks; 118 | sourceTree = ""; 119 | }; 120 | 0382B62720DC4A2B00F4B44B /* AtomicsApp */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | 0382B62820DC4A2B00F4B44B /* AppDelegate.swift */, 124 | 0382B62A20DC4A2B00F4B44B /* ViewController.swift */, 125 | 0382B62C20DC4A2B00F4B44B /* Main.storyboard */, 126 | 0382B62F20DC4A2D00F4B44B /* Assets.xcassets */, 127 | 0382B63120DC4A2D00F4B44B /* LaunchScreen.storyboard */, 128 | 031F706C2374A93A0086343E /* Default-568h@2x.png */, 129 | 0382B63420DC4A2D00F4B44B /* Info.plist */, 130 | ); 131 | path = AtomicsApp; 132 | sourceTree = ""; 133 | }; 134 | 0382B63C20DC4A2D00F4B44B /* AtomicsTests */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | 031F705A2374A8B10086343E /* AtomicsTests.swift */, 138 | 031F70582374A8B10086343E /* AtomicsRaceTests.swift */, 139 | 031F70572374A8B10086343E /* ReferenceTests.swift */, 140 | 031F70562374A8B10086343E /* CAtomicsTests.swift */, 141 | 031F70542374A8B00086343E /* CAtomicsRaceTests.swift */, 142 | 031F705B2374A8B10086343E /* CAtomicsReferenceTests.swift */, 143 | 031F70592374A8B10086343E /* MemoryOrderTests.swift */, 144 | 031F70552374A8B10086343E /* RandomPositive.swift */, 145 | 0382B63F20DC4A2D00F4B44B /* Info.plist */, 146 | ); 147 | path = AtomicsTests; 148 | sourceTree = ""; 149 | }; 150 | /* End PBXGroup section */ 151 | 152 | /* Begin PBXNativeTarget section */ 153 | 0382B62520DC4A2B00F4B44B /* Atomics */ = { 154 | isa = PBXNativeTarget; 155 | buildConfigurationList = 0382B64420DC4A2D00F4B44B /* Build configuration list for PBXNativeTarget "Atomics" */; 156 | buildPhases = ( 157 | 0382B62220DC4A2B00F4B44B /* Sources */, 158 | 0382B62320DC4A2B00F4B44B /* Frameworks */, 159 | 0382B62420DC4A2B00F4B44B /* Resources */, 160 | 0382B65A20DC52CF00F4B44B /* Embed Frameworks */, 161 | ); 162 | buildRules = ( 163 | ); 164 | dependencies = ( 165 | ); 166 | name = Atomics; 167 | packageProductDependencies = ( 168 | 0388884E2384546F0086343E /* CAtomics */, 169 | 038888502384546F0086343E /* SwiftAtomics */, 170 | ); 171 | productName = AtomicsTestApp; 172 | productReference = 0382B62620DC4A2B00F4B44B /* Atomics.app */; 173 | productType = "com.apple.product-type.application"; 174 | }; 175 | 0382B63820DC4A2D00F4B44B /* AtomicsTests */ = { 176 | isa = PBXNativeTarget; 177 | buildConfigurationList = 0382B64520DC4A2D00F4B44B /* Build configuration list for PBXNativeTarget "AtomicsTests" */; 178 | buildPhases = ( 179 | 0382B63520DC4A2D00F4B44B /* Sources */, 180 | 0382B63620DC4A2D00F4B44B /* Frameworks */, 181 | 0382B63720DC4A2D00F4B44B /* Resources */, 182 | ); 183 | buildRules = ( 184 | ); 185 | dependencies = ( 186 | 0382B63B20DC4A2D00F4B44B /* PBXTargetDependency */, 187 | ); 188 | name = AtomicsTests; 189 | productName = AtomicsTests; 190 | productReference = 0382B63920DC4A2D00F4B44B /* AtomicsTests.xctest */; 191 | productType = "com.apple.product-type.bundle.unit-test"; 192 | }; 193 | /* End PBXNativeTarget section */ 194 | 195 | /* Begin PBXProject section */ 196 | 031CA33520DBDC0400F4B44B /* Project object */ = { 197 | isa = PBXProject; 198 | attributes = { 199 | LastSwiftUpdateCheck = 1000; 200 | LastUpgradeCheck = 1000; 201 | ORGANIZATIONNAME = "Guillaume Lessard"; 202 | TargetAttributes = { 203 | 0382B62520DC4A2B00F4B44B = { 204 | CreatedOnToolsVersion = 10.0; 205 | }; 206 | 0382B63820DC4A2D00F4B44B = { 207 | CreatedOnToolsVersion = 10.0; 208 | TestTargetID = 0382B62520DC4A2B00F4B44B; 209 | }; 210 | }; 211 | }; 212 | buildConfigurationList = 031CA33820DBDC0400F4B44B /* Build configuration list for PBXProject "Atomics Test" */; 213 | compatibilityVersion = "Xcode 9.3"; 214 | developmentRegion = en; 215 | hasScannedForEncodings = 0; 216 | knownRegions = ( 217 | en, 218 | Base, 219 | ); 220 | mainGroup = 031CA33420DBDC0400F4B44B; 221 | packageReferences = ( 222 | ); 223 | productRefGroup = 031CA33F20DBDC0400F4B44B /* Products */; 224 | projectDirPath = ""; 225 | projectRoot = ""; 226 | targets = ( 227 | 0382B62520DC4A2B00F4B44B /* Atomics */, 228 | 0382B63820DC4A2D00F4B44B /* AtomicsTests */, 229 | ); 230 | }; 231 | /* End PBXProject section */ 232 | 233 | /* Begin PBXResourcesBuildPhase section */ 234 | 0382B62420DC4A2B00F4B44B /* Resources */ = { 235 | isa = PBXResourcesBuildPhase; 236 | buildActionMask = 2147483647; 237 | files = ( 238 | 0382B63320DC4A2D00F4B44B /* LaunchScreen.storyboard in Resources */, 239 | 031F706D2374A93A0086343E /* Default-568h@2x.png in Resources */, 240 | 0382B63020DC4A2D00F4B44B /* Assets.xcassets in Resources */, 241 | 0382B62E20DC4A2B00F4B44B /* Main.storyboard in Resources */, 242 | ); 243 | runOnlyForDeploymentPostprocessing = 0; 244 | }; 245 | 0382B63720DC4A2D00F4B44B /* Resources */ = { 246 | isa = PBXResourcesBuildPhase; 247 | buildActionMask = 2147483647; 248 | files = ( 249 | ); 250 | runOnlyForDeploymentPostprocessing = 0; 251 | }; 252 | /* End PBXResourcesBuildPhase section */ 253 | 254 | /* Begin PBXSourcesBuildPhase section */ 255 | 0382B62220DC4A2B00F4B44B /* Sources */ = { 256 | isa = PBXSourcesBuildPhase; 257 | buildActionMask = 2147483647; 258 | files = ( 259 | 0382B62B20DC4A2B00F4B44B /* ViewController.swift in Sources */, 260 | 0382B62920DC4A2B00F4B44B /* AppDelegate.swift in Sources */, 261 | ); 262 | runOnlyForDeploymentPostprocessing = 0; 263 | }; 264 | 0382B63520DC4A2D00F4B44B /* Sources */ = { 265 | isa = PBXSourcesBuildPhase; 266 | buildActionMask = 2147483647; 267 | files = ( 268 | 031F70672374A8DA0086343E /* CAtomicsTests.swift in Sources */, 269 | 031F70642374A8DA0086343E /* AtomicsTests.swift in Sources */, 270 | 031F70692374A8DA0086343E /* CAtomicsReferenceTests.swift in Sources */, 271 | 031F706B2374A8DA0086343E /* RandomPositive.swift in Sources */, 272 | 031F706A2374A8DA0086343E /* MemoryOrderTests.swift in Sources */, 273 | 031F70682374A8DA0086343E /* CAtomicsRaceTests.swift in Sources */, 274 | 031F70662374A8DA0086343E /* ReferenceTests.swift in Sources */, 275 | 031F70652374A8DA0086343E /* AtomicsRaceTests.swift in Sources */, 276 | ); 277 | runOnlyForDeploymentPostprocessing = 0; 278 | }; 279 | /* End PBXSourcesBuildPhase section */ 280 | 281 | /* Begin PBXTargetDependency section */ 282 | 0382B63B20DC4A2D00F4B44B /* PBXTargetDependency */ = { 283 | isa = PBXTargetDependency; 284 | target = 0382B62520DC4A2B00F4B44B /* Atomics */; 285 | targetProxy = 0382B63A20DC4A2D00F4B44B /* PBXContainerItemProxy */; 286 | }; 287 | /* End PBXTargetDependency section */ 288 | 289 | /* Begin PBXVariantGroup section */ 290 | 0382B62C20DC4A2B00F4B44B /* Main.storyboard */ = { 291 | isa = PBXVariantGroup; 292 | children = ( 293 | 0382B62D20DC4A2B00F4B44B /* Base */, 294 | ); 295 | name = Main.storyboard; 296 | sourceTree = ""; 297 | }; 298 | 0382B63120DC4A2D00F4B44B /* LaunchScreen.storyboard */ = { 299 | isa = PBXVariantGroup; 300 | children = ( 301 | 0382B63220DC4A2D00F4B44B /* Base */, 302 | ); 303 | name = LaunchScreen.storyboard; 304 | sourceTree = ""; 305 | }; 306 | /* End PBXVariantGroup section */ 307 | 308 | /* Begin XCBuildConfiguration section */ 309 | 031CA35020DBDC0400F4B44B /* Debug */ = { 310 | isa = XCBuildConfiguration; 311 | buildSettings = { 312 | ALWAYS_SEARCH_USER_PATHS = NO; 313 | CLANG_ANALYZER_NONNULL = YES; 314 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 315 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 316 | CLANG_CXX_LIBRARY = "libc++"; 317 | CLANG_ENABLE_MODULES = YES; 318 | CLANG_ENABLE_OBJC_ARC = YES; 319 | CLANG_ENABLE_OBJC_WEAK = YES; 320 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 321 | CLANG_WARN_BOOL_CONVERSION = YES; 322 | CLANG_WARN_COMMA = YES; 323 | CLANG_WARN_CONSTANT_CONVERSION = YES; 324 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 325 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 326 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 327 | CLANG_WARN_EMPTY_BODY = YES; 328 | CLANG_WARN_ENUM_CONVERSION = YES; 329 | CLANG_WARN_INFINITE_RECURSION = YES; 330 | CLANG_WARN_INT_CONVERSION = YES; 331 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 332 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 333 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 334 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 335 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 336 | CLANG_WARN_STRICT_PROTOTYPES = YES; 337 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 338 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 339 | CLANG_WARN_UNREACHABLE_CODE = YES; 340 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 341 | COPY_PHASE_STRIP = NO; 342 | CURRENT_PROJECT_VERSION = 1; 343 | DEBUG_INFORMATION_FORMAT = dwarf; 344 | ENABLE_STRICT_OBJC_MSGSEND = YES; 345 | ENABLE_TESTABILITY = YES; 346 | GCC_C_LANGUAGE_STANDARD = gnu11; 347 | GCC_DYNAMIC_NO_PIC = NO; 348 | GCC_NO_COMMON_BLOCKS = YES; 349 | GCC_OPTIMIZATION_LEVEL = 0; 350 | GCC_PREPROCESSOR_DEFINITIONS = ( 351 | "DEBUG=1", 352 | "$(inherited)", 353 | ); 354 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 355 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 356 | GCC_WARN_UNDECLARED_SELECTOR = YES; 357 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 358 | GCC_WARN_UNUSED_FUNCTION = YES; 359 | GCC_WARN_UNUSED_VARIABLE = YES; 360 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 361 | MACOSX_DEPLOYMENT_TARGET = 10.10; 362 | ONLY_ACTIVE_ARCH = YES; 363 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 364 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 365 | SWIFT_SWIFT3_OBJC_INFERENCE = Off; 366 | SWIFT_VERSION = 5.0; 367 | TVOS_DEPLOYMENT_TARGET = 9.0; 368 | VERSIONING_SYSTEM = "apple-generic"; 369 | VERSION_INFO_PREFIX = ""; 370 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 371 | }; 372 | name = Debug; 373 | }; 374 | 031CA35120DBDC0400F4B44B /* Release */ = { 375 | isa = XCBuildConfiguration; 376 | buildSettings = { 377 | ALWAYS_SEARCH_USER_PATHS = NO; 378 | CLANG_ANALYZER_NONNULL = YES; 379 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 380 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 381 | CLANG_CXX_LIBRARY = "libc++"; 382 | CLANG_ENABLE_MODULES = YES; 383 | CLANG_ENABLE_OBJC_ARC = YES; 384 | CLANG_ENABLE_OBJC_WEAK = YES; 385 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 386 | CLANG_WARN_BOOL_CONVERSION = YES; 387 | CLANG_WARN_COMMA = YES; 388 | CLANG_WARN_CONSTANT_CONVERSION = YES; 389 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 390 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 391 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 392 | CLANG_WARN_EMPTY_BODY = YES; 393 | CLANG_WARN_ENUM_CONVERSION = YES; 394 | CLANG_WARN_INFINITE_RECURSION = YES; 395 | CLANG_WARN_INT_CONVERSION = YES; 396 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 397 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 398 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 399 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 400 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 401 | CLANG_WARN_STRICT_PROTOTYPES = YES; 402 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 403 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 404 | CLANG_WARN_UNREACHABLE_CODE = YES; 405 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 406 | COPY_PHASE_STRIP = NO; 407 | CURRENT_PROJECT_VERSION = 1; 408 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 409 | ENABLE_NS_ASSERTIONS = NO; 410 | ENABLE_STRICT_OBJC_MSGSEND = YES; 411 | ENABLE_TESTABILITY = YES; 412 | GCC_C_LANGUAGE_STANDARD = gnu11; 413 | GCC_NO_COMMON_BLOCKS = YES; 414 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 415 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 416 | GCC_WARN_UNDECLARED_SELECTOR = YES; 417 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 418 | GCC_WARN_UNUSED_FUNCTION = YES; 419 | GCC_WARN_UNUSED_VARIABLE = YES; 420 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 421 | MACOSX_DEPLOYMENT_TARGET = 10.10; 422 | SWIFT_COMPILATION_MODE = wholemodule; 423 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 424 | SWIFT_SWIFT3_OBJC_INFERENCE = Off; 425 | SWIFT_VERSION = 5.0; 426 | TVOS_DEPLOYMENT_TARGET = 9.0; 427 | VERSIONING_SYSTEM = "apple-generic"; 428 | VERSION_INFO_PREFIX = ""; 429 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 430 | }; 431 | name = Release; 432 | }; 433 | 0382B64020DC4A2D00F4B44B /* Debug */ = { 434 | isa = XCBuildConfiguration; 435 | buildSettings = { 436 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 437 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 438 | CODE_SIGN_IDENTITY = "iPhone Developer"; 439 | CODE_SIGN_STYLE = Automatic; 440 | DEVELOPMENT_TEAM = 96558JVW34; 441 | INFOPLIST_FILE = "$(SRCROOT)/AtomicsApp/Info.plist"; 442 | LD_RUNPATH_SEARCH_PATHS = ( 443 | "$(inherited)", 444 | "@executable_path/Frameworks", 445 | ); 446 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 447 | PRODUCT_BUNDLE_IDENTIFIER = com.tffenterprises.AtomicsTestApp.0x3a2; 448 | PRODUCT_NAME = "$(TARGET_NAME)"; 449 | SDKROOT = iphoneos; 450 | TARGETED_DEVICE_FAMILY = "1,2"; 451 | }; 452 | name = Debug; 453 | }; 454 | 0382B64120DC4A2D00F4B44B /* Release */ = { 455 | isa = XCBuildConfiguration; 456 | buildSettings = { 457 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 458 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 459 | CODE_SIGN_IDENTITY = "iPhone Developer"; 460 | CODE_SIGN_STYLE = Automatic; 461 | DEVELOPMENT_TEAM = 96558JVW34; 462 | INFOPLIST_FILE = "$(SRCROOT)/AtomicsApp/Info.plist"; 463 | LD_RUNPATH_SEARCH_PATHS = ( 464 | "$(inherited)", 465 | "@executable_path/Frameworks", 466 | ); 467 | MTL_ENABLE_DEBUG_INFO = NO; 468 | PRODUCT_BUNDLE_IDENTIFIER = com.tffenterprises.AtomicsTestApp.0x3a2; 469 | PRODUCT_NAME = "$(TARGET_NAME)"; 470 | SDKROOT = iphoneos; 471 | TARGETED_DEVICE_FAMILY = "1,2"; 472 | VALIDATE_PRODUCT = YES; 473 | }; 474 | name = Release; 475 | }; 476 | 0382B64220DC4A2D00F4B44B /* Debug */ = { 477 | isa = XCBuildConfiguration; 478 | buildSettings = { 479 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 480 | BUNDLE_LOADER = "$(TEST_HOST)"; 481 | CODE_SIGN_IDENTITY = "iPhone Developer"; 482 | CODE_SIGN_STYLE = Automatic; 483 | DEVELOPMENT_TEAM = 96558JVW34; 484 | INFOPLIST_FILE = AtomicsTests/Info.plist; 485 | LD_RUNPATH_SEARCH_PATHS = ( 486 | "$(inherited)", 487 | "@executable_path/Frameworks", 488 | "@loader_path/Frameworks", 489 | ); 490 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 491 | PRODUCT_BUNDLE_IDENTIFIER = com.tffenterprises.AtomicsTests; 492 | PRODUCT_NAME = "$(TARGET_NAME)"; 493 | SDKROOT = iphoneos; 494 | TARGETED_DEVICE_FAMILY = "1,2"; 495 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Atomics.app/Atomics"; 496 | }; 497 | name = Debug; 498 | }; 499 | 0382B64320DC4A2D00F4B44B /* Release */ = { 500 | isa = XCBuildConfiguration; 501 | buildSettings = { 502 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 503 | BUNDLE_LOADER = "$(TEST_HOST)"; 504 | CODE_SIGN_IDENTITY = "iPhone Developer"; 505 | CODE_SIGN_STYLE = Automatic; 506 | DEVELOPMENT_TEAM = 96558JVW34; 507 | INFOPLIST_FILE = AtomicsTests/Info.plist; 508 | LD_RUNPATH_SEARCH_PATHS = ( 509 | "$(inherited)", 510 | "@executable_path/Frameworks", 511 | "@loader_path/Frameworks", 512 | ); 513 | MTL_ENABLE_DEBUG_INFO = NO; 514 | PRODUCT_BUNDLE_IDENTIFIER = com.tffenterprises.AtomicsTests; 515 | PRODUCT_NAME = "$(TARGET_NAME)"; 516 | SDKROOT = iphoneos; 517 | TARGETED_DEVICE_FAMILY = "1,2"; 518 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Atomics.app/Atomics"; 519 | VALIDATE_PRODUCT = YES; 520 | }; 521 | name = Release; 522 | }; 523 | /* End XCBuildConfiguration section */ 524 | 525 | /* Begin XCConfigurationList section */ 526 | 031CA33820DBDC0400F4B44B /* Build configuration list for PBXProject "Atomics Test" */ = { 527 | isa = XCConfigurationList; 528 | buildConfigurations = ( 529 | 031CA35020DBDC0400F4B44B /* Debug */, 530 | 031CA35120DBDC0400F4B44B /* Release */, 531 | ); 532 | defaultConfigurationIsVisible = 0; 533 | defaultConfigurationName = Release; 534 | }; 535 | 0382B64420DC4A2D00F4B44B /* Build configuration list for PBXNativeTarget "Atomics" */ = { 536 | isa = XCConfigurationList; 537 | buildConfigurations = ( 538 | 0382B64020DC4A2D00F4B44B /* Debug */, 539 | 0382B64120DC4A2D00F4B44B /* Release */, 540 | ); 541 | defaultConfigurationIsVisible = 0; 542 | defaultConfigurationName = Release; 543 | }; 544 | 0382B64520DC4A2D00F4B44B /* Build configuration list for PBXNativeTarget "AtomicsTests" */ = { 545 | isa = XCConfigurationList; 546 | buildConfigurations = ( 547 | 0382B64220DC4A2D00F4B44B /* Debug */, 548 | 0382B64320DC4A2D00F4B44B /* Release */, 549 | ); 550 | defaultConfigurationIsVisible = 0; 551 | defaultConfigurationName = Release; 552 | }; 553 | /* End XCConfigurationList section */ 554 | 555 | /* Begin XCSwiftPackageProductDependency section */ 556 | 0388884E2384546F0086343E /* CAtomics */ = { 557 | isa = XCSwiftPackageProductDependency; 558 | productName = CAtomics; 559 | }; 560 | 038888502384546F0086343E /* SwiftAtomics */ = { 561 | isa = XCSwiftPackageProductDependency; 562 | productName = SwiftAtomics; 563 | }; 564 | /* End XCSwiftPackageProductDependency section */ 565 | }; 566 | rootObject = 031CA33520DBDC0400F4B44B /* Project object */; 567 | } 568 | -------------------------------------------------------------------------------- /Tests-on-Device/Atomics Test.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Tests-on-Device/Atomics Test.xcodeproj/xcshareddata/xcschemes/Atomics.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 71 | 73 | 79 | 80 | 81 | 82 | 84 | 85 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /Tests-on-Device/AtomicsApp/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Atomics_TestApp 4 | // 5 | 6 | import UIKit 7 | 8 | import SwiftAtomics 9 | import CAtomics 10 | 11 | #if !swift(>=4.2) 12 | extension UIApplication { typealias LaunchOptionsKey = UIApplicationLaunchOptionsKey } 13 | #endif 14 | 15 | @UIApplicationMain 16 | class AppDelegate: UIResponder, UIApplicationDelegate { 17 | 18 | var window: UIWindow? 19 | 20 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool 21 | { 22 | var o = AtomicOptionalRawPointer() 23 | let p = UnsafeRawPointer(bitPattern: 0x1013)! 24 | CAtomicsInitialize(&o, p) 25 | assert(CAtomicsLoad(&o, .relaxed) != nil) 26 | let q = CAtomicsExchange(&o, nil, .sequential) 27 | assert(q == p) 28 | assert(CAtomicsLoad(&o, .relaxed) == nil) 29 | 30 | var tagged = AtomicTaggedRawPointer() 31 | assert(MemoryLayout.size == 2*MemoryLayout.size) 32 | tagged.initialize((UnsafeRawPointer(bitPattern: 0x0731)!, 1755)) 33 | var t = tagged.load(order: .relaxed) 34 | let u = (UnsafeRawPointer(bitPattern: 0x1013)!, 1837) 35 | let success = tagged.loadCAS(current: &t, future: u, type: .strong, orderSwap: .relaxed, orderLoad: .relaxed) 36 | assert(tagged.value.pointer == u.0) 37 | assert(success) 38 | 39 | var bool = AtomicBool() 40 | bool.store(false) 41 | let f = bool.swap(true, order: .sequential) 42 | assert(f == false) 43 | assert(bool.load(order: .acquire)) 44 | return bool.value 45 | } 46 | 47 | func applicationWillResignActive(_ application: UIApplication) { 48 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 49 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 50 | } 51 | 52 | func applicationDidEnterBackground(_ application: UIApplication) { 53 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 54 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 55 | } 56 | 57 | func applicationWillEnterForeground(_ application: UIApplication) { 58 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 59 | } 60 | 61 | func applicationDidBecomeActive(_ application: UIApplication) { 62 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 63 | } 64 | 65 | func applicationWillTerminate(_ application: UIApplication) { 66 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 67 | } 68 | 69 | 70 | } 71 | 72 | -------------------------------------------------------------------------------- /Tests-on-Device/AtomicsApp/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /Tests-on-Device/AtomicsApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Tests-on-Device/AtomicsApp/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Tests-on-Device/AtomicsApp/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Tests-on-Device/AtomicsApp/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glessard/swift-atomics/39c855f5fbbf30de8dcd517672f9d53499b6c03b/Tests-on-Device/AtomicsApp/Default-568h@2x.png -------------------------------------------------------------------------------- /Tests-on-Device/AtomicsApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | UIInterfaceOrientationPortraitUpsideDown 37 | 38 | UISupportedInterfaceOrientations~ipad 39 | 40 | UIInterfaceOrientationPortrait 41 | UIInterfaceOrientationPortraitUpsideDown 42 | UIInterfaceOrientationLandscapeLeft 43 | UIInterfaceOrientationLandscapeRight 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Tests-on-Device/AtomicsApp/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Atomics_TestApp 4 | // 5 | 6 | import UIKit 7 | 8 | class ViewController: UIViewController { 9 | 10 | override func viewDidLoad() { 11 | super.viewDidLoad() 12 | // Do any additional setup after loading the view, typically from a nib. 13 | } 14 | 15 | override func didReceiveMemoryWarning() { 16 | super.didReceiveMemoryWarning() 17 | // Dispose of any resources that can be recreated. 18 | } 19 | 20 | 21 | } 22 | 23 | -------------------------------------------------------------------------------- /Tests-on-Device/AtomicsTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import SwiftAtomicsTests 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += SwiftAtomicsTests.__allTests() 7 | 8 | XCTMain(tests) 9 | -------------------------------------------------------------------------------- /Tests/SwiftAtomicsTests/AtomicsRaceTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AtomicsRaceTests.swift 3 | // AtomicsTests 4 | // 5 | // Copyright © 2015-2018 Guillaume Lessard. All rights reserved. 6 | // This file is distributed under the BSD 3-clause license. See LICENSE for details. 7 | // 8 | 9 | import XCTest 10 | import Dispatch 11 | 12 | import SwiftAtomics 13 | 14 | private let iterations = 200_000//_000 15 | 16 | private struct Point { var x = 0.0, y = 0.0, z = 0.0 } 17 | 18 | public class AtomicsRaceTests: XCTestCase 19 | { 20 | public func testRaceCrash() 21 | { // this version is guaranteed to crash with a double-free 22 | let q = DispatchQueue(label: "", attributes: .concurrent) 23 | 24 | #if false 25 | for _ in 1...iterations 26 | { 27 | var p: Optional = UnsafeMutablePointer.allocate(capacity: 1) 28 | let closure = { 29 | while true 30 | { 31 | if let c = p 32 | { 33 | p = nil 34 | #if swift(>=4.1) 35 | c.deallocate() 36 | #else 37 | c.deallocate(capacity: 1) 38 | #endif 39 | } 40 | else // pointer is deallocated 41 | { 42 | break 43 | } 44 | } 45 | } 46 | 47 | q.async(execute: closure) 48 | q.async(execute: closure) 49 | } 50 | #else 51 | print("double-free crash disabled") 52 | #endif 53 | 54 | q.sync(flags: .barrier) {} 55 | } 56 | 57 | public func testRaceSpinLock() 58 | { 59 | let q = DispatchQueue(label: "", attributes: .concurrent) 60 | 61 | for _ in 1...iterations 62 | { 63 | var p: Optional = UnsafeMutablePointer.allocate(capacity: 1) 64 | var lock = AtomicInt() 65 | let closure = { 66 | while true 67 | { 68 | if lock.CAS(current: 0, future: 1, type: .weak, order: .acquire) 69 | { 70 | defer { lock.store(0, order: .release) } 71 | if let c = p 72 | { 73 | p = nil 74 | #if swift(>=4.1) 75 | c.deallocate() 76 | #else 77 | c.deallocate(capacity: 1) 78 | #endif 79 | } 80 | else // pointer is deallocated 81 | { 82 | break 83 | } 84 | } 85 | } 86 | } 87 | 88 | q.async(execute: closure) 89 | q.async(execute: closure) 90 | } 91 | 92 | q.sync(flags: .barrier) {} 93 | } 94 | 95 | public func testRacePointerCAS() 96 | { 97 | let q = DispatchQueue(label: "", attributes: .concurrent) 98 | 99 | for _ in 1...iterations 100 | { 101 | var p = AtomicOptionalMutablePointer(UnsafeMutablePointer.allocate(capacity: 1)) 102 | let closure = { 103 | while true 104 | { 105 | if let c = p.load(order: .acquire) 106 | { 107 | if p.CAS(current: c, future: nil, type: .weak, order: .release) 108 | { 109 | #if swift(>=4.1) 110 | c.deallocate() 111 | #else 112 | c.deallocate(capacity: 1) 113 | #endif 114 | } 115 | } 116 | else // pointer is deallocated 117 | { 118 | break 119 | } 120 | } 121 | } 122 | 123 | q.async(execute: closure) 124 | q.async(execute: closure) 125 | } 126 | 127 | q.sync(flags: .barrier) {} 128 | } 129 | 130 | public func testRacePointerLoadCAS() 131 | { 132 | let q = DispatchQueue(label: "", attributes: .concurrent) 133 | 134 | for _ in 1...iterations 135 | { 136 | var p = AtomicOptionalMutablePointer(UnsafeMutablePointer.allocate(capacity: 1)) 137 | let closure = { 138 | var c = p.pointer 139 | while true 140 | { 141 | if p.loadCAS(current: &c, future: nil, type: .weak, orderSwap: .release, orderLoad: .relaxed), 142 | let c = c 143 | { 144 | #if swift(>=4.1) 145 | c.deallocate() 146 | #else 147 | c.deallocate(capacity: 1) 148 | #endif 149 | } 150 | else // pointer is deallocated 151 | { 152 | break 153 | } 154 | } 155 | } 156 | 157 | q.async(execute: closure) 158 | q.async(execute: closure) 159 | } 160 | 161 | q.sync(flags: .barrier) {} 162 | } 163 | 164 | public func testRacePointerSwap() 165 | { 166 | let q = DispatchQueue(label: "", attributes: .concurrent) 167 | 168 | for _ in 1...iterations 169 | { 170 | var p = AtomicOptionalMutablePointer(UnsafeMutablePointer.allocate(capacity: 1)) 171 | let closure = { 172 | while true 173 | { 174 | if let c = p.swap(nil, order: .acquire) 175 | { 176 | #if swift(>=4.1) 177 | c.deallocate() 178 | #else 179 | c.deallocate(capacity: 1) 180 | #endif 181 | } 182 | else // pointer is deallocated 183 | { 184 | break 185 | } 186 | } 187 | } 188 | 189 | q.async(execute: closure) 190 | q.async(execute: closure) 191 | } 192 | 193 | q.sync(flags: .barrier) {} 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /Tests/SwiftAtomicsTests/AtomicsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AtomicsTests.swift 3 | // AtomicsTests 4 | // 5 | // Copyright © 2015-2018 Guillaume Lessard. All rights reserved. 6 | // This file is distributed under the BSD 3-clause license. See LICENSE for details. 7 | // 8 | 9 | import XCTest 10 | 11 | import SwiftAtomics 12 | 13 | public class AtomicsBasicTests: XCTestCase 14 | { 15 | public func testInt() 16 | { 17 | var i = AtomicInt(0) 18 | XCTAssertEqual(i.value, 0) 19 | i.initialize(1) 20 | XCTAssertEqual(i.value, 1) 21 | 22 | #if swift(>=4.0) 23 | let r1 = Int.randomPositive() 24 | let r2 = Int.randomPositive() 25 | let r3 = Int.randomPositive() 26 | #else 27 | let r1 = Int(UInt.randomPositive()) 28 | let r2 = Int(UInt.randomPositive()) 29 | let r3 = Int(UInt.randomPositive()) 30 | #endif 31 | 32 | i.store(r1) 33 | XCTAssertEqual(r1, i.load()) 34 | 35 | var j = i.swap(r2) 36 | XCTAssertEqual(r1, j) 37 | XCTAssertEqual(r2, i.load()) 38 | 39 | j = i.add(r1) 40 | XCTAssertEqual(r2, j) 41 | XCTAssertEqual(r1 &+ r2, i.load()) 42 | 43 | j = i.subtract(r2) 44 | XCTAssertEqual(r1 &+ r2, j) 45 | XCTAssertEqual(r1, i.load()) 46 | 47 | j = i.increment() 48 | XCTAssertEqual(r1, j) 49 | XCTAssertEqual(r1 &+ 1, i.load()) 50 | 51 | i.store(r3) 52 | j = i.decrement() 53 | XCTAssertEqual(r3, j) 54 | XCTAssertEqual(r3 &- 1, i.load()) 55 | 56 | i.store(r1) 57 | j = i.bitwiseOr(r2) 58 | XCTAssertEqual(r1, j) 59 | XCTAssertEqual(r1 | r2, i.load()) 60 | 61 | i.store(r2) 62 | j = i.bitwiseXor(r1) 63 | XCTAssertEqual(r2, j) 64 | XCTAssertEqual(r1 ^ r2, i.load()) 65 | 66 | i.store(r1) 67 | j = i.bitwiseAnd(r2) 68 | XCTAssertEqual(r1, j) 69 | XCTAssertEqual(r1 & r2, i.load()) 70 | 71 | i.store(r1) 72 | XCTAssertTrue(i.CAS(current: r1, future: r2, type: .strong)) 73 | XCTAssertEqual(r2, i.load()) 74 | 75 | j = r2 76 | i.store(r1) 77 | while(!i.loadCAS(current: &j, future: r3)) {} 78 | XCTAssertEqual(r1, j) 79 | XCTAssertEqual(r3, i.load()) 80 | } 81 | 82 | public func testUInt() 83 | { 84 | var i = AtomicUInt(0) 85 | XCTAssertEqual(i.value, 0) 86 | i.initialize(1) 87 | XCTAssertEqual(i.value, 1) 88 | 89 | #if swift(>=4.0) 90 | let r1 = UInt.randomPositive() 91 | let r2 = UInt.randomPositive() 92 | let r3 = UInt.randomPositive() 93 | #else 94 | let r1 = UInt(UInt.randomPositive()) 95 | let r2 = UInt(UInt.randomPositive()) 96 | let r3 = UInt(UInt.randomPositive()) 97 | #endif 98 | 99 | i.store(r1) 100 | XCTAssertEqual(r1, i.load()) 101 | 102 | var j = i.swap(r2) 103 | XCTAssertEqual(r1, j) 104 | XCTAssertEqual(r2, i.load()) 105 | 106 | j = i.add(r1) 107 | XCTAssertEqual(r2, j) 108 | XCTAssertEqual(r1 &+ r2, i.load()) 109 | 110 | j = i.subtract(r2) 111 | XCTAssertEqual(r1 &+ r2, j) 112 | XCTAssertEqual(r1, i.load()) 113 | 114 | j = i.increment() 115 | XCTAssertEqual(r1, j) 116 | XCTAssertEqual(r1 &+ 1, i.load()) 117 | 118 | i.store(r3) 119 | j = i.decrement() 120 | XCTAssertEqual(r3, j) 121 | XCTAssertEqual(r3 &- 1, i.load()) 122 | 123 | i.store(r1) 124 | j = i.bitwiseOr(r2) 125 | XCTAssertEqual(r1, j) 126 | XCTAssertEqual(r1 | r2, i.load()) 127 | 128 | i.store(r2) 129 | j = i.bitwiseXor(r1) 130 | XCTAssertEqual(r2, j) 131 | XCTAssertEqual(r1 ^ r2, i.load()) 132 | 133 | i.store(r1) 134 | j = i.bitwiseAnd(r2) 135 | XCTAssertEqual(r1, j) 136 | XCTAssertEqual(r1 & r2, i.load()) 137 | 138 | i.store(r1) 139 | XCTAssertTrue(i.CAS(current: r1, future: r2, type: .strong)) 140 | XCTAssertEqual(r2, i.load()) 141 | 142 | j = r2 143 | i.store(r1) 144 | while(!i.loadCAS(current: &j, future: r3)) {} 145 | XCTAssertEqual(r1, j) 146 | XCTAssertEqual(r3, i.load()) 147 | } 148 | 149 | public func testInt8() 150 | { 151 | var i = AtomicInt8(0) 152 | XCTAssertEqual(i.value, 0) 153 | i.initialize(1) 154 | XCTAssertEqual(i.value, 1) 155 | 156 | #if swift(>=4.0) 157 | let r1 = Int8.randomPositive() 158 | let r2 = Int8.randomPositive() 159 | let r3 = Int8.randomPositive() 160 | #else 161 | let r1 = Int8(truncatingBitPattern: UInt.randomPositive()) 162 | let r2 = Int8(truncatingBitPattern: UInt.randomPositive()) 163 | let r3 = Int8(truncatingBitPattern: UInt.randomPositive()) 164 | #endif 165 | 166 | i.store(r1) 167 | XCTAssertEqual(r1, i.load()) 168 | 169 | var j = i.swap(r2) 170 | XCTAssertEqual(r1, j) 171 | XCTAssertEqual(r2, i.load()) 172 | 173 | j = i.add(r1) 174 | XCTAssertEqual(r2, j) 175 | XCTAssertEqual(r1 &+ r2, i.load()) 176 | 177 | j = i.subtract(r2) 178 | XCTAssertEqual(r1 &+ r2, j) 179 | XCTAssertEqual(r1, i.load()) 180 | 181 | j = i.increment() 182 | XCTAssertEqual(r1, j) 183 | XCTAssertEqual(r1 &+ 1, i.load()) 184 | 185 | i.store(r3) 186 | j = i.decrement() 187 | XCTAssertEqual(r3, j) 188 | XCTAssertEqual(r3 &- 1, i.load()) 189 | 190 | i.store(r1) 191 | j = i.bitwiseOr(r2) 192 | XCTAssertEqual(r1, j) 193 | XCTAssertEqual(r1 | r2, i.load()) 194 | 195 | i.store(r2) 196 | j = i.bitwiseXor(r1) 197 | XCTAssertEqual(r2, j) 198 | XCTAssertEqual(r1 ^ r2, i.load()) 199 | 200 | i.store(r1) 201 | j = i.bitwiseAnd(r2) 202 | XCTAssertEqual(r1, j) 203 | XCTAssertEqual(r1 & r2, i.load()) 204 | 205 | i.store(r1) 206 | XCTAssertTrue(i.CAS(current: r1, future: r2, type: .strong)) 207 | XCTAssertEqual(r2, i.load()) 208 | 209 | j = r2 210 | i.store(r1) 211 | while(!i.loadCAS(current: &j, future: r3)) {} 212 | XCTAssertEqual(r1, j) 213 | XCTAssertEqual(r3, i.load()) 214 | } 215 | 216 | public func testUInt8() 217 | { 218 | var i = AtomicUInt8(0) 219 | XCTAssertEqual(i.value, 0) 220 | i.initialize(1) 221 | XCTAssertEqual(i.value, 1) 222 | 223 | #if swift(>=4.0) 224 | let r1 = UInt8.randomPositive() 225 | let r2 = UInt8.randomPositive() 226 | let r3 = UInt8.randomPositive() 227 | #else 228 | let r1 = UInt8(truncatingBitPattern: UInt.randomPositive()) 229 | let r2 = UInt8(truncatingBitPattern: UInt.randomPositive()) 230 | let r3 = UInt8(truncatingBitPattern: UInt.randomPositive()) 231 | #endif 232 | 233 | i.store(r1) 234 | XCTAssertEqual(r1, i.load()) 235 | 236 | var j = i.swap(r2) 237 | XCTAssertEqual(r1, j) 238 | XCTAssertEqual(r2, i.load()) 239 | 240 | j = i.add(r1) 241 | XCTAssertEqual(r2, j) 242 | XCTAssertEqual(r1 &+ r2, i.load()) 243 | 244 | j = i.subtract(r2) 245 | XCTAssertEqual(r1 &+ r2, j) 246 | XCTAssertEqual(r1, i.load()) 247 | 248 | j = i.increment() 249 | XCTAssertEqual(r1, j) 250 | XCTAssertEqual(r1 &+ 1, i.load()) 251 | 252 | i.store(r3) 253 | j = i.decrement() 254 | XCTAssertEqual(r3, j) 255 | XCTAssertEqual(r3 &- 1, i.load()) 256 | 257 | i.store(r1) 258 | j = i.bitwiseOr(r2) 259 | XCTAssertEqual(r1, j) 260 | XCTAssertEqual(r1 | r2, i.load()) 261 | 262 | i.store(r2) 263 | j = i.bitwiseXor(r1) 264 | XCTAssertEqual(r2, j) 265 | XCTAssertEqual(r1 ^ r2, i.load()) 266 | 267 | i.store(r1) 268 | j = i.bitwiseAnd(r2) 269 | XCTAssertEqual(r1, j) 270 | XCTAssertEqual(r1 & r2, i.load()) 271 | 272 | i.store(r1) 273 | XCTAssertTrue(i.CAS(current: r1, future: r2, type: .strong)) 274 | XCTAssertEqual(r2, i.load()) 275 | 276 | j = r2 277 | i.store(r1) 278 | while(!i.loadCAS(current: &j, future: r3)) {} 279 | XCTAssertEqual(r1, j) 280 | XCTAssertEqual(r3, i.load()) 281 | } 282 | 283 | public func testInt16() 284 | { 285 | var i = AtomicInt16(0) 286 | XCTAssertEqual(i.value, 0) 287 | i.initialize(1) 288 | XCTAssertEqual(i.value, 1) 289 | 290 | #if swift(>=4.0) 291 | let r1 = Int16.randomPositive() 292 | let r2 = Int16.randomPositive() 293 | let r3 = Int16.randomPositive() 294 | #else 295 | let r1 = Int16(truncatingBitPattern: UInt.randomPositive()) 296 | let r2 = Int16(truncatingBitPattern: UInt.randomPositive()) 297 | let r3 = Int16(truncatingBitPattern: UInt.randomPositive()) 298 | #endif 299 | 300 | i.store(r1) 301 | XCTAssertEqual(r1, i.load()) 302 | 303 | var j = i.swap(r2) 304 | XCTAssertEqual(r1, j) 305 | XCTAssertEqual(r2, i.load()) 306 | 307 | j = i.add(r1) 308 | XCTAssertEqual(r2, j) 309 | XCTAssertEqual(r1 &+ r2, i.load()) 310 | 311 | j = i.subtract(r2) 312 | XCTAssertEqual(r1 &+ r2, j) 313 | XCTAssertEqual(r1, i.load()) 314 | 315 | j = i.increment() 316 | XCTAssertEqual(r1, j) 317 | XCTAssertEqual(r1 &+ 1, i.load()) 318 | 319 | i.store(r3) 320 | j = i.decrement() 321 | XCTAssertEqual(r3, j) 322 | XCTAssertEqual(r3 &- 1, i.load()) 323 | 324 | i.store(r1) 325 | j = i.bitwiseOr(r2) 326 | XCTAssertEqual(r1, j) 327 | XCTAssertEqual(r1 | r2, i.load()) 328 | 329 | i.store(r2) 330 | j = i.bitwiseXor(r1) 331 | XCTAssertEqual(r2, j) 332 | XCTAssertEqual(r1 ^ r2, i.load()) 333 | 334 | i.store(r1) 335 | j = i.bitwiseAnd(r2) 336 | XCTAssertEqual(r1, j) 337 | XCTAssertEqual(r1 & r2, i.load()) 338 | 339 | i.store(r1) 340 | XCTAssertTrue(i.CAS(current: r1, future: r2, type: .strong)) 341 | XCTAssertEqual(r2, i.load()) 342 | 343 | j = r2 344 | i.store(r1) 345 | while(!i.loadCAS(current: &j, future: r3)) {} 346 | XCTAssertEqual(r1, j) 347 | XCTAssertEqual(r3, i.load()) 348 | } 349 | 350 | public func testUInt16() 351 | { 352 | var i = AtomicUInt16(0) 353 | XCTAssertEqual(i.value, 0) 354 | i.initialize(1) 355 | XCTAssertEqual(i.value, 1) 356 | 357 | #if swift(>=4.0) 358 | let r1 = UInt16.randomPositive() 359 | let r2 = UInt16.randomPositive() 360 | let r3 = UInt16.randomPositive() 361 | #else 362 | let r1 = UInt16(truncatingBitPattern: UInt.randomPositive()) 363 | let r2 = UInt16(truncatingBitPattern: UInt.randomPositive()) 364 | let r3 = UInt16(truncatingBitPattern: UInt.randomPositive()) 365 | #endif 366 | 367 | i.store(r1) 368 | XCTAssertEqual(r1, i.load()) 369 | 370 | var j = i.swap(r2) 371 | XCTAssertEqual(r1, j) 372 | XCTAssertEqual(r2, i.load()) 373 | 374 | j = i.add(r1) 375 | XCTAssertEqual(r2, j) 376 | XCTAssertEqual(r1 &+ r2, i.load()) 377 | 378 | j = i.subtract(r2) 379 | XCTAssertEqual(r1 &+ r2, j) 380 | XCTAssertEqual(r1, i.load()) 381 | 382 | j = i.increment() 383 | XCTAssertEqual(r1, j) 384 | XCTAssertEqual(r1 &+ 1, i.load()) 385 | 386 | i.store(r3) 387 | j = i.decrement() 388 | XCTAssertEqual(r3, j) 389 | XCTAssertEqual(r3 &- 1, i.load()) 390 | 391 | i.store(r1) 392 | j = i.bitwiseOr(r2) 393 | XCTAssertEqual(r1, j) 394 | XCTAssertEqual(r1 | r2, i.load()) 395 | 396 | i.store(r2) 397 | j = i.bitwiseXor(r1) 398 | XCTAssertEqual(r2, j) 399 | XCTAssertEqual(r1 ^ r2, i.load()) 400 | 401 | i.store(r1) 402 | j = i.bitwiseAnd(r2) 403 | XCTAssertEqual(r1, j) 404 | XCTAssertEqual(r1 & r2, i.load()) 405 | 406 | i.store(r1) 407 | XCTAssertTrue(i.CAS(current: r1, future: r2, type: .strong)) 408 | XCTAssertEqual(r2, i.load()) 409 | 410 | j = r2 411 | i.store(r1) 412 | while(!i.loadCAS(current: &j, future: r3)) {} 413 | XCTAssertEqual(r1, j) 414 | XCTAssertEqual(r3, i.load()) 415 | } 416 | 417 | public func testInt32() 418 | { 419 | var i = AtomicInt32(0) 420 | XCTAssertEqual(i.value, 0) 421 | i.initialize(1) 422 | XCTAssertEqual(i.value, 1) 423 | 424 | #if swift(>=4.0) 425 | let r1 = Int32.randomPositive() 426 | let r2 = Int32.randomPositive() 427 | let r3 = Int32.randomPositive() 428 | #else 429 | let r1 = Int32(truncatingBitPattern: UInt.randomPositive()) 430 | let r2 = Int32(truncatingBitPattern: UInt.randomPositive()) 431 | let r3 = Int32(truncatingBitPattern: UInt.randomPositive()) 432 | #endif 433 | 434 | i.store(r1) 435 | XCTAssertEqual(r1, i.load()) 436 | 437 | var j = i.swap(r2) 438 | XCTAssertEqual(r1, j) 439 | XCTAssertEqual(r2, i.load()) 440 | 441 | j = i.add(r1) 442 | XCTAssertEqual(r2, j) 443 | XCTAssertEqual(r1 &+ r2, i.load()) 444 | 445 | j = i.subtract(r2) 446 | XCTAssertEqual(r1 &+ r2, j) 447 | XCTAssertEqual(r1, i.load()) 448 | 449 | j = i.increment() 450 | XCTAssertEqual(r1, j) 451 | XCTAssertEqual(r1 &+ 1, i.load()) 452 | 453 | i.store(r3) 454 | j = i.decrement() 455 | XCTAssertEqual(r3, j) 456 | XCTAssertEqual(r3 &- 1, i.load()) 457 | 458 | i.store(r1) 459 | j = i.bitwiseOr(r2) 460 | XCTAssertEqual(r1, j) 461 | XCTAssertEqual(r1 | r2, i.load()) 462 | 463 | i.store(r2) 464 | j = i.bitwiseXor(r1) 465 | XCTAssertEqual(r2, j) 466 | XCTAssertEqual(r1 ^ r2, i.load()) 467 | 468 | i.store(r1) 469 | j = i.bitwiseAnd(r2) 470 | XCTAssertEqual(r1, j) 471 | XCTAssertEqual(r1 & r2, i.load()) 472 | 473 | i.store(r1) 474 | XCTAssertTrue(i.CAS(current: r1, future: r2, type: .strong)) 475 | XCTAssertEqual(r2, i.load()) 476 | 477 | j = r2 478 | i.store(r1) 479 | while(!i.loadCAS(current: &j, future: r3)) {} 480 | XCTAssertEqual(r1, j) 481 | XCTAssertEqual(r3, i.load()) 482 | } 483 | 484 | public func testUInt32() 485 | { 486 | var i = AtomicUInt32(0) 487 | XCTAssertEqual(i.value, 0) 488 | i.initialize(1) 489 | XCTAssertEqual(i.value, 1) 490 | 491 | #if swift(>=4.0) 492 | let r1 = UInt32.randomPositive() 493 | let r2 = UInt32.randomPositive() 494 | let r3 = UInt32.randomPositive() 495 | #else 496 | let r1 = UInt32(truncatingBitPattern: UInt.randomPositive()) 497 | let r2 = UInt32(truncatingBitPattern: UInt.randomPositive()) 498 | let r3 = UInt32(truncatingBitPattern: UInt.randomPositive()) 499 | #endif 500 | 501 | i.store(r1) 502 | XCTAssertEqual(r1, i.load()) 503 | 504 | var j = i.swap(r2) 505 | XCTAssertEqual(r1, j) 506 | XCTAssertEqual(r2, i.load()) 507 | 508 | j = i.add(r1) 509 | XCTAssertEqual(r2, j) 510 | XCTAssertEqual(r1 &+ r2, i.load()) 511 | 512 | j = i.subtract(r2) 513 | XCTAssertEqual(r1 &+ r2, j) 514 | XCTAssertEqual(r1, i.load()) 515 | 516 | j = i.increment() 517 | XCTAssertEqual(r1, j) 518 | XCTAssertEqual(r1 &+ 1, i.load()) 519 | 520 | i.store(r3) 521 | j = i.decrement() 522 | XCTAssertEqual(r3, j) 523 | XCTAssertEqual(r3 &- 1, i.load()) 524 | 525 | i.store(r1) 526 | j = i.bitwiseOr(r2) 527 | XCTAssertEqual(r1, j) 528 | XCTAssertEqual(r1 | r2, i.load()) 529 | 530 | i.store(r2) 531 | j = i.bitwiseXor(r1) 532 | XCTAssertEqual(r2, j) 533 | XCTAssertEqual(r1 ^ r2, i.load()) 534 | 535 | i.store(r1) 536 | j = i.bitwiseAnd(r2) 537 | XCTAssertEqual(r1, j) 538 | XCTAssertEqual(r1 & r2, i.load()) 539 | 540 | i.store(r1) 541 | XCTAssertTrue(i.CAS(current: r1, future: r2, type: .strong)) 542 | XCTAssertEqual(r2, i.load()) 543 | 544 | j = r2 545 | i.store(r1) 546 | while(!i.loadCAS(current: &j, future: r3)) {} 547 | XCTAssertEqual(r1, j) 548 | XCTAssertEqual(r3, i.load()) 549 | } 550 | 551 | public func testInt64() 552 | { 553 | var i = AtomicInt64(0) 554 | XCTAssertEqual(i.value, 0) 555 | i.initialize(1) 556 | XCTAssertEqual(i.value, 1) 557 | 558 | #if swift(>=4.0) 559 | let r1 = Int64.randomPositive() 560 | let r2 = Int64.randomPositive() 561 | let r3 = Int64.randomPositive() 562 | #else 563 | let r1 = Int64(UInt.randomPositive()) 564 | let r2 = Int64(UInt.randomPositive()) 565 | let r3 = Int64(UInt.randomPositive()) 566 | #endif 567 | 568 | i.store(r1) 569 | XCTAssertEqual(r1, i.load()) 570 | 571 | var j = i.swap(r2) 572 | XCTAssertEqual(r1, j) 573 | XCTAssertEqual(r2, i.load()) 574 | 575 | j = i.add(r1) 576 | XCTAssertEqual(r2, j) 577 | XCTAssertEqual(r1 &+ r2, i.load()) 578 | 579 | j = i.subtract(r2) 580 | XCTAssertEqual(r1 &+ r2, j) 581 | XCTAssertEqual(r1, i.load()) 582 | 583 | j = i.increment() 584 | XCTAssertEqual(r1, j) 585 | XCTAssertEqual(r1 &+ 1, i.load()) 586 | 587 | i.store(r3) 588 | j = i.decrement() 589 | XCTAssertEqual(r3, j) 590 | XCTAssertEqual(r3 &- 1, i.load()) 591 | 592 | i.store(r1) 593 | j = i.bitwiseOr(r2) 594 | XCTAssertEqual(r1, j) 595 | XCTAssertEqual(r1 | r2, i.load()) 596 | 597 | i.store(r2) 598 | j = i.bitwiseXor(r1) 599 | XCTAssertEqual(r2, j) 600 | XCTAssertEqual(r1 ^ r2, i.load()) 601 | 602 | i.store(r1) 603 | j = i.bitwiseAnd(r2) 604 | XCTAssertEqual(r1, j) 605 | XCTAssertEqual(r1 & r2, i.load()) 606 | 607 | i.store(r1) 608 | XCTAssertTrue(i.CAS(current: r1, future: r2, type: .strong)) 609 | XCTAssertEqual(r2, i.load()) 610 | 611 | j = r2 612 | i.store(r1) 613 | while(!i.loadCAS(current: &j, future: r3)) {} 614 | XCTAssertEqual(r1, j) 615 | XCTAssertEqual(r3, i.load()) 616 | } 617 | 618 | public func testUInt64() 619 | { 620 | var i = AtomicUInt64(0) 621 | XCTAssertEqual(i.value, 0) 622 | i.initialize(1) 623 | XCTAssertEqual(i.value, 1) 624 | 625 | #if swift(>=4.0) 626 | let r1 = UInt64.randomPositive() 627 | let r2 = UInt64.randomPositive() 628 | let r3 = UInt64.randomPositive() 629 | #else 630 | let r1 = UInt64(UInt.randomPositive()) 631 | let r2 = UInt64(UInt.randomPositive()) 632 | let r3 = UInt64(UInt.randomPositive()) 633 | #endif 634 | 635 | i.store(r1) 636 | XCTAssertEqual(r1, i.load()) 637 | 638 | var j = i.swap(r2) 639 | XCTAssertEqual(r1, j) 640 | XCTAssertEqual(r2, i.load()) 641 | 642 | j = i.add(r1) 643 | XCTAssertEqual(r2, j) 644 | XCTAssertEqual(r1 &+ r2, i.load()) 645 | 646 | j = i.subtract(r2) 647 | XCTAssertEqual(r1 &+ r2, j) 648 | XCTAssertEqual(r1, i.load()) 649 | 650 | j = i.increment() 651 | XCTAssertEqual(r1, j) 652 | XCTAssertEqual(r1 &+ 1, i.load()) 653 | 654 | i.store(r3) 655 | j = i.decrement() 656 | XCTAssertEqual(r3, j) 657 | XCTAssertEqual(r3 &- 1, i.load()) 658 | 659 | i.store(r1) 660 | j = i.bitwiseOr(r2) 661 | XCTAssertEqual(r1, j) 662 | XCTAssertEqual(r1 | r2, i.load()) 663 | 664 | i.store(r2) 665 | j = i.bitwiseXor(r1) 666 | XCTAssertEqual(r2, j) 667 | XCTAssertEqual(r1 ^ r2, i.load()) 668 | 669 | i.store(r1) 670 | j = i.bitwiseAnd(r2) 671 | XCTAssertEqual(r1, j) 672 | XCTAssertEqual(r1 & r2, i.load()) 673 | 674 | i.store(r1) 675 | XCTAssertTrue(i.CAS(current: r1, future: r2, type: .strong)) 676 | XCTAssertEqual(r2, i.load()) 677 | 678 | j = r2 679 | i.store(r1) 680 | while(!i.loadCAS(current: &j, future: r3)) {} 681 | XCTAssertEqual(r1, j) 682 | XCTAssertEqual(r3, i.load()) 683 | } 684 | 685 | public func testUnsafeRawPointer() 686 | { 687 | let r0 = UnsafeRawPointer(bitPattern: UInt.randomPositive())! 688 | let r1 = UnsafeRawPointer(bitPattern: UInt.randomPositive())! 689 | let r2 = UnsafeRawPointer(bitPattern: UInt.randomPositive())! 690 | let r3 = UnsafeRawPointer(bitPattern: UInt.randomPositive())! 691 | 692 | var i = AtomicRawPointer(r0) 693 | XCTAssertEqual(i.pointer, r0) 694 | 695 | i.initialize(r1) 696 | XCTAssertEqual(i.pointer, r1) 697 | 698 | i.store(r0) 699 | XCTAssertEqual(r0, i.load()) 700 | 701 | var j = i.swap(r2) 702 | XCTAssertEqual(r0, j) 703 | XCTAssertEqual(r2, i.load()) 704 | 705 | i.store(r1) 706 | XCTAssertTrue(i.CAS(current: r1, future: r2, type: .strong)) 707 | XCTAssertEqual(r2, i.load()) 708 | 709 | j = r2 710 | i.store(r1) 711 | while(!i.loadCAS(current: &j, future: r3)) {} 712 | XCTAssertEqual(r1, j) 713 | XCTAssertEqual(r3, i.load()) 714 | } 715 | 716 | public func testUnsafeRawPointerOptional() 717 | { 718 | var n = AtomicOptionalRawPointer() 719 | XCTAssertEqual(n.pointer, nil) 720 | 721 | let r0 = UnsafeRawPointer(bitPattern: UInt.randomPositive()) 722 | let r1 = UnsafeRawPointer(bitPattern: UInt.randomPositive()) 723 | let r2 = UnsafeRawPointer(bitPattern: UInt.randomPositive()) 724 | let r3 = UnsafeRawPointer(bitPattern: UInt.randomPositive()) 725 | 726 | var i = AtomicOptionalRawPointer(r0) 727 | XCTAssertEqual(i.pointer, r0) 728 | 729 | i.initialize(r1) 730 | XCTAssertEqual(i.pointer, r1) 731 | 732 | i.store(r0) 733 | XCTAssertEqual(r0, i.load()) 734 | 735 | var j = i.swap(r2) 736 | XCTAssertEqual(r0, j) 737 | XCTAssertEqual(r2, i.load()) 738 | 739 | i.store(r1) 740 | XCTAssertTrue(i.CAS(current: r1, future: r2, type: .strong)) 741 | XCTAssertEqual(r2, i.load()) 742 | 743 | j = r2 744 | i.store(r1) 745 | while(!i.loadCAS(current: &j, future: r3)) {} 746 | XCTAssertEqual(r1, j) 747 | XCTAssertEqual(r3, i.load()) 748 | } 749 | 750 | public func testUnsafeMutableRawPointer() 751 | { 752 | let r0 = UnsafeMutableRawPointer(bitPattern: UInt.randomPositive())! 753 | let r1 = UnsafeMutableRawPointer(bitPattern: UInt.randomPositive())! 754 | let r2 = UnsafeMutableRawPointer(bitPattern: UInt.randomPositive())! 755 | let r3 = UnsafeMutableRawPointer(bitPattern: UInt.randomPositive())! 756 | 757 | var i = AtomicMutableRawPointer(r0) 758 | XCTAssertEqual(i.pointer, r0) 759 | 760 | i.initialize(r1) 761 | XCTAssertEqual(i.pointer, r1) 762 | 763 | i.store(r0) 764 | XCTAssertEqual(r0, i.load()) 765 | 766 | var j = i.swap(r2) 767 | XCTAssertEqual(r0, j) 768 | XCTAssertEqual(r2, i.load()) 769 | 770 | i.store(r1) 771 | XCTAssertTrue(i.CAS(current: r1, future: r2, type: .strong)) 772 | XCTAssertEqual(r2, i.load()) 773 | 774 | j = r2 775 | i.store(r1) 776 | while(!i.loadCAS(current: &j, future: r3)) {} 777 | XCTAssertEqual(r1, j) 778 | XCTAssertEqual(r3, i.load()) 779 | } 780 | 781 | public func testUnsafeMutableRawPointerOptional() 782 | { 783 | var n = AtomicOptionalMutableRawPointer() 784 | XCTAssertEqual(n.pointer, nil) 785 | 786 | let r0 = UnsafeMutableRawPointer(bitPattern: UInt.randomPositive()) 787 | let r1 = UnsafeMutableRawPointer(bitPattern: UInt.randomPositive()) 788 | let r2 = UnsafeMutableRawPointer(bitPattern: UInt.randomPositive()) 789 | let r3 = UnsafeMutableRawPointer(bitPattern: UInt.randomPositive()) 790 | 791 | var i = AtomicOptionalMutableRawPointer(r0) 792 | XCTAssertEqual(i.pointer, r0) 793 | 794 | i.initialize(r1) 795 | XCTAssertEqual(i.pointer, r1) 796 | 797 | i.store(r0) 798 | XCTAssertEqual(r0, i.load()) 799 | 800 | var j = i.swap(r2) 801 | XCTAssertEqual(r0, j) 802 | XCTAssertEqual(r2, i.load()) 803 | 804 | i.store(r1) 805 | XCTAssertTrue(i.CAS(current: r1, future: r2, type: .strong)) 806 | XCTAssertEqual(r2, i.load()) 807 | 808 | j = r2 809 | i.store(r1) 810 | while(!i.loadCAS(current: &j, future: r3)) {} 811 | XCTAssertEqual(r1, j) 812 | XCTAssertEqual(r3, i.load()) 813 | } 814 | 815 | public func testUnsafePointer() 816 | { 817 | let r0 = UnsafePointer(bitPattern: UInt.randomPositive())! 818 | let r1 = UnsafePointer(bitPattern: UInt.randomPositive())! 819 | let r2 = UnsafePointer(bitPattern: UInt.randomPositive())! 820 | let r3 = UnsafePointer(bitPattern: UInt.randomPositive())! 821 | 822 | var i = AtomicPointer(r0) 823 | XCTAssertEqual(i.pointer, r0) 824 | 825 | i.initialize(r1) 826 | XCTAssertEqual(i.pointer, r1) 827 | 828 | i.store(r0) 829 | XCTAssertEqual(r0, i.load()) 830 | 831 | var j = i.swap(r2) 832 | XCTAssertEqual(r0, j) 833 | XCTAssertEqual(r2, i.load()) 834 | 835 | i.store(r1) 836 | XCTAssertTrue(i.CAS(current: r1, future: r2, type: .strong)) 837 | XCTAssertEqual(r2, i.load()) 838 | 839 | j = r2 840 | i.store(r1) 841 | while(!i.loadCAS(current: &j, future: r3)) {} 842 | XCTAssertEqual(r1, j) 843 | XCTAssertEqual(r3, i.load()) 844 | } 845 | 846 | public func testUnsafePointerOptional() 847 | { 848 | var n = AtomicOptionalPointer() 849 | XCTAssertEqual(n.pointer, nil) 850 | 851 | let r0 = UnsafePointer(bitPattern: UInt.randomPositive()) 852 | let r1 = UnsafePointer(bitPattern: UInt.randomPositive()) 853 | let r2 = UnsafePointer(bitPattern: UInt.randomPositive()) 854 | let r3 = UnsafePointer(bitPattern: UInt.randomPositive()) 855 | 856 | var i = AtomicOptionalPointer(r0) 857 | XCTAssertEqual(i.pointer, r0) 858 | 859 | i.initialize(r1) 860 | XCTAssertEqual(i.pointer, r1) 861 | 862 | i.store(r0) 863 | XCTAssertEqual(r0, i.load()) 864 | 865 | var j = i.swap(r2) 866 | XCTAssertEqual(r0, j) 867 | XCTAssertEqual(r2, i.load()) 868 | 869 | i.store(r1) 870 | XCTAssertTrue(i.CAS(current: r1, future: r2, type: .strong)) 871 | XCTAssertEqual(r2, i.load()) 872 | 873 | j = r2 874 | i.store(r1) 875 | while(!i.loadCAS(current: &j, future: r3)) {} 876 | XCTAssertEqual(r1, j) 877 | XCTAssertEqual(r3, i.load()) 878 | } 879 | 880 | public func testUnsafeMutablePointer() 881 | { 882 | let r0 = UnsafeMutablePointer(bitPattern: UInt.randomPositive())! 883 | let r1 = UnsafeMutablePointer(bitPattern: UInt.randomPositive())! 884 | let r2 = UnsafeMutablePointer(bitPattern: UInt.randomPositive())! 885 | let r3 = UnsafeMutablePointer(bitPattern: UInt.randomPositive())! 886 | 887 | var i = AtomicMutablePointer(r0) 888 | XCTAssertEqual(i.pointer, r0) 889 | 890 | i.initialize(r1) 891 | XCTAssertEqual(i.pointer, r1) 892 | 893 | i.store(r0) 894 | XCTAssertEqual(r0, i.load()) 895 | 896 | var j = i.swap(r2) 897 | XCTAssertEqual(r0, j) 898 | XCTAssertEqual(r2, i.load()) 899 | 900 | i.store(r1) 901 | XCTAssertTrue(i.CAS(current: r1, future: r2, type: .strong)) 902 | XCTAssertEqual(r2, i.load()) 903 | 904 | j = r2 905 | i.store(r1) 906 | while(!i.loadCAS(current: &j, future: r3)) {} 907 | XCTAssertEqual(r1, j) 908 | XCTAssertEqual(r3, i.load()) 909 | } 910 | 911 | public func testUnsafeMutablePointerOptional() 912 | { 913 | var n = AtomicOptionalMutablePointer() 914 | XCTAssertEqual(n.pointer, nil) 915 | 916 | let r0 = UnsafeMutablePointer(bitPattern: UInt.randomPositive()) 917 | let r1 = UnsafeMutablePointer(bitPattern: UInt.randomPositive()) 918 | let r2 = UnsafeMutablePointer(bitPattern: UInt.randomPositive()) 919 | let r3 = UnsafeMutablePointer(bitPattern: UInt.randomPositive()) 920 | 921 | var i = AtomicOptionalMutablePointer(r0) 922 | XCTAssertEqual(i.pointer, r0) 923 | 924 | i.initialize(r1) 925 | XCTAssertEqual(i.pointer, r1) 926 | 927 | i.store(r0) 928 | XCTAssertEqual(r0, i.load()) 929 | 930 | var j = i.swap(r2) 931 | XCTAssertEqual(r0, j) 932 | XCTAssertEqual(r2, i.load()) 933 | 934 | i.store(r1) 935 | XCTAssertTrue(i.CAS(current: r1, future: r2, type: .strong)) 936 | XCTAssertEqual(r2, i.load()) 937 | 938 | j = r2 939 | i.store(r1) 940 | while(!i.loadCAS(current: &j, future: r3)) {} 941 | XCTAssertEqual(r1, j) 942 | XCTAssertEqual(r3, i.load()) 943 | } 944 | 945 | public func testOpaquePointer() 946 | { 947 | let r0 = OpaquePointer(bitPattern: UInt.randomPositive())! 948 | let r1 = OpaquePointer(bitPattern: UInt.randomPositive())! 949 | let r2 = OpaquePointer(bitPattern: UInt.randomPositive())! 950 | let r3 = OpaquePointer(bitPattern: UInt.randomPositive())! 951 | 952 | var i = AtomicOpaquePointer(r0) 953 | XCTAssertEqual(i.pointer, r0) 954 | 955 | i.initialize(r1) 956 | XCTAssertEqual(i.pointer, r1) 957 | 958 | i.store(r0) 959 | XCTAssertEqual(r0, i.load()) 960 | 961 | var j = i.swap(r2) 962 | XCTAssertEqual(r0, j) 963 | XCTAssertEqual(r2, i.load()) 964 | 965 | i.store(r1) 966 | XCTAssertTrue(i.CAS(current: r1, future: r2, type: .strong)) 967 | XCTAssertEqual(r2, i.load()) 968 | 969 | j = r2 970 | i.store(r1) 971 | while(!i.loadCAS(current: &j, future: r3)) {} 972 | XCTAssertEqual(r1, j) 973 | XCTAssertEqual(r3, i.load()) 974 | } 975 | 976 | public func testOpaquePointerOptional() 977 | { 978 | var n = AtomicOptionalOpaquePointer() 979 | XCTAssertEqual(n.pointer, nil) 980 | 981 | let r0 = OpaquePointer(bitPattern: UInt.randomPositive()) 982 | let r1 = OpaquePointer(bitPattern: UInt.randomPositive()) 983 | let r2 = OpaquePointer(bitPattern: UInt.randomPositive()) 984 | let r3 = OpaquePointer(bitPattern: UInt.randomPositive()) 985 | 986 | var i = AtomicOptionalOpaquePointer(r0) 987 | XCTAssertEqual(i.pointer, r0) 988 | 989 | i.initialize(r1) 990 | XCTAssertEqual(i.pointer, r1) 991 | 992 | i.store(r0) 993 | XCTAssertEqual(r0, i.load()) 994 | 995 | var j = i.swap(r2) 996 | XCTAssertEqual(r0, j) 997 | XCTAssertEqual(r2, i.load()) 998 | 999 | i.store(r1) 1000 | XCTAssertTrue(i.CAS(current: r1, future: r2, type: .strong)) 1001 | XCTAssertEqual(r2, i.load()) 1002 | 1003 | j = r2 1004 | i.store(r1) 1005 | while(!i.loadCAS(current: &j, future: r3)) {} 1006 | XCTAssertEqual(r1, j) 1007 | XCTAssertEqual(r3, i.load()) 1008 | } 1009 | 1010 | public func testTaggedRawPointer() 1011 | { 1012 | let r0 = (UnsafeRawPointer(bitPattern: UInt.randomPositive())!, 0) 1013 | let r1 = (UnsafeRawPointer(bitPattern: UInt.randomPositive())!, 1) 1014 | let r2 = (UnsafeRawPointer(bitPattern: UInt.randomPositive())!, 2) 1015 | let r3 = (r2.0, r2.1+1) 1016 | 1017 | var p = AtomicTaggedRawPointer(r3) 1018 | XCTAssertEqual(r3.0, p.value.pointer) 1019 | XCTAssertEqual(r3.1, p.value.tag) 1020 | 1021 | p.initialize((r3.0, r0.1)) 1022 | XCTAssertEqual(r3.0, p.value.pointer) 1023 | XCTAssertEqual(r0.1, p.value.tag) 1024 | 1025 | p.store(r1, order: .release) 1026 | XCTAssertEqual(r1.0, p.value.pointer) 1027 | XCTAssertEqual(r1.1, p.value.tag) 1028 | 1029 | var j = p.swap(r2, order: .acqrel) 1030 | XCTAssertEqual(r1.0, j.0) 1031 | XCTAssertEqual(r1.1, j.1) 1032 | j = p.load(order: .acquire) 1033 | XCTAssertEqual(r2.0, j.0) 1034 | XCTAssertEqual(r2.1, j.1) 1035 | 1036 | XCTAssertTrue(p.CAS(current: r2, future: r3)) 1037 | XCTAssertEqual(r3.0, p.value.pointer) 1038 | XCTAssertEqual(r3.1, p.value.tag) 1039 | 1040 | XCTAssertFalse(p.CAS(current: j, future: r2, type: .weak)) 1041 | XCTAssertTrue(p.CAS(current: r3, future: r2)) 1042 | j = p.load(order: .relaxed) 1043 | XCTAssertTrue(p.CAS(current: r2, future: r1)) 1044 | while !p.loadCAS(current: &j, future: r3) {} 1045 | XCTAssertEqual(r1.0, j.0) 1046 | XCTAssertEqual(r1.1, j.1) 1047 | XCTAssertEqual(r3.0, p.value.pointer) 1048 | XCTAssertEqual(r3.1, p.value.tag) 1049 | } 1050 | 1051 | public func testTaggedOptionalRawPointer() 1052 | { 1053 | let r0 = (UnsafeRawPointer(bitPattern: UInt.randomPositive()), 0) 1054 | let r1 = (UnsafeRawPointer(bitPattern: UInt.randomPositive()), 1) 1055 | let r2 = (UnsafeRawPointer(bitPattern: UInt.randomPositive()), 2) 1056 | let r3 = (r2.0, r2.1+1) 1057 | 1058 | var p = AtomicTaggedOptionalRawPointer(r3) 1059 | XCTAssertEqual(r3.0, p.value.pointer) 1060 | XCTAssertEqual(r3.1, p.value.tag) 1061 | 1062 | p.initialize((r3.0, r0.1)) 1063 | XCTAssertEqual(r3.0, p.value.pointer) 1064 | XCTAssertEqual(r0.1, p.value.tag) 1065 | 1066 | p.store(r1, order: .release) 1067 | XCTAssertEqual(r1.0, p.value.pointer) 1068 | XCTAssertEqual(r1.1, p.value.tag) 1069 | 1070 | var j = p.swap(r2, order: .acqrel) 1071 | XCTAssertEqual(r1.0, j.0) 1072 | XCTAssertEqual(r1.1, j.1) 1073 | j = p.load(order: .acquire) 1074 | XCTAssertEqual(r2.0, j.0) 1075 | XCTAssertEqual(r2.1, j.1) 1076 | 1077 | XCTAssertTrue(p.CAS(current: r2, future: r3)) 1078 | XCTAssertEqual(r3.0, p.value.pointer) 1079 | XCTAssertEqual(r3.1, p.value.tag) 1080 | 1081 | XCTAssertFalse(p.CAS(current: j, future: r2, type: .weak)) 1082 | XCTAssertTrue(p.CAS(current: r3, future: r2)) 1083 | j = p.load(order: .relaxed) 1084 | XCTAssertTrue(p.CAS(current: r2, future: r1)) 1085 | while !p.loadCAS(current: &j, future: r3) {} 1086 | XCTAssertEqual(r1.0, j.0) 1087 | XCTAssertEqual(r1.1, j.1) 1088 | XCTAssertEqual(r3.0, p.value.pointer) 1089 | XCTAssertEqual(r3.1, p.value.tag) 1090 | } 1091 | 1092 | public func testTaggedMutableRawPointer() 1093 | { 1094 | let r0 = (UnsafeMutableRawPointer(bitPattern: UInt.randomPositive())!, 0) 1095 | let r1 = (UnsafeMutableRawPointer(bitPattern: UInt.randomPositive())!, 1) 1096 | let r2 = (UnsafeMutableRawPointer(bitPattern: UInt.randomPositive())!, 2) 1097 | let r3 = (r2.0, r2.1+1) 1098 | 1099 | var p = AtomicTaggedMutableRawPointer(r3) 1100 | XCTAssertEqual(r3.0, p.value.pointer) 1101 | XCTAssertEqual(r3.1, p.value.tag) 1102 | 1103 | p.initialize((r3.0, r0.1)) 1104 | XCTAssertEqual(r3.0, p.value.pointer) 1105 | XCTAssertEqual(r0.1, p.value.tag) 1106 | 1107 | p.store(r1, order: .release) 1108 | XCTAssertEqual(r1.0, p.value.pointer) 1109 | XCTAssertEqual(r1.1, p.value.tag) 1110 | 1111 | var j = p.swap(r2, order: .acqrel) 1112 | XCTAssertEqual(r1.0, j.0) 1113 | XCTAssertEqual(r1.1, j.1) 1114 | j = p.load(order: .acquire) 1115 | XCTAssertEqual(r2.0, j.0) 1116 | XCTAssertEqual(r2.1, j.1) 1117 | 1118 | XCTAssertTrue(p.CAS(current: r2, future: r3)) 1119 | XCTAssertEqual(r3.0, p.value.pointer) 1120 | XCTAssertEqual(r3.1, p.value.tag) 1121 | 1122 | XCTAssertFalse(p.CAS(current: j, future: r2, type: .weak)) 1123 | XCTAssertTrue(p.CAS(current: r3, future: r2)) 1124 | j = p.load(order: .relaxed) 1125 | XCTAssertTrue(p.CAS(current: r2, future: r1)) 1126 | while !p.loadCAS(current: &j, future: r3) {} 1127 | XCTAssertEqual(r1.0, j.0) 1128 | XCTAssertEqual(r1.1, j.1) 1129 | XCTAssertEqual(r3.0, p.value.pointer) 1130 | XCTAssertEqual(r3.1, p.value.tag) 1131 | } 1132 | 1133 | public func testTaggedOptionalMutableRawPointer() 1134 | { 1135 | let r0 = (UnsafeMutableRawPointer(bitPattern: UInt.randomPositive()), 0) 1136 | let r1 = (UnsafeMutableRawPointer(bitPattern: UInt.randomPositive()), 1) 1137 | let r2 = (UnsafeMutableRawPointer(bitPattern: UInt.randomPositive()), 2) 1138 | let r3 = (r2.0, r2.1+1) 1139 | 1140 | var p = AtomicTaggedOptionalMutableRawPointer(r3) 1141 | XCTAssertEqual(r3.0, p.value.pointer) 1142 | XCTAssertEqual(r3.1, p.value.tag) 1143 | 1144 | p.initialize((r3.0, r0.1)) 1145 | XCTAssertEqual(r3.0, p.value.pointer) 1146 | XCTAssertEqual(r0.1, p.value.tag) 1147 | 1148 | p.store(r1, order: .release) 1149 | XCTAssertEqual(r1.0, p.value.pointer) 1150 | XCTAssertEqual(r1.1, p.value.tag) 1151 | 1152 | var j = p.swap(r2, order: .acqrel) 1153 | XCTAssertEqual(r1.0, j.0) 1154 | XCTAssertEqual(r1.1, j.1) 1155 | j = p.load(order: .acquire) 1156 | XCTAssertEqual(r2.0, j.0) 1157 | XCTAssertEqual(r2.1, j.1) 1158 | 1159 | XCTAssertTrue(p.CAS(current: r2, future: r3)) 1160 | XCTAssertEqual(r3.0, p.value.pointer) 1161 | XCTAssertEqual(r3.1, p.value.tag) 1162 | 1163 | XCTAssertFalse(p.CAS(current: j, future: r2, type: .weak)) 1164 | XCTAssertTrue(p.CAS(current: r3, future: r2)) 1165 | j = p.load(order: .relaxed) 1166 | XCTAssertTrue(p.CAS(current: r2, future: r1)) 1167 | while !p.loadCAS(current: &j, future: r3) {} 1168 | XCTAssertEqual(r1.0, j.0) 1169 | XCTAssertEqual(r1.1, j.1) 1170 | XCTAssertEqual(r3.0, p.value.pointer) 1171 | XCTAssertEqual(r3.1, p.value.tag) 1172 | } 1173 | 1174 | public func testBool() 1175 | { 1176 | var boolean = AtomicBool() 1177 | boolean.initialize(false) 1178 | XCTAssertEqual(boolean.value, false) 1179 | 1180 | boolean.store(false) 1181 | XCTAssertEqual(boolean.value, false) 1182 | 1183 | boolean.store(true) 1184 | XCTAssertEqual(boolean.value, true) 1185 | XCTAssertEqual(boolean.value, boolean.load()) 1186 | 1187 | boolean.store(true) 1188 | boolean.or(true) 1189 | XCTAssertEqual(boolean.value, true) 1190 | boolean.or(false) 1191 | XCTAssertEqual(boolean.value, true) 1192 | boolean.store(false) 1193 | boolean.or(false) 1194 | XCTAssertEqual(boolean.value, false) 1195 | boolean.or(true) 1196 | XCTAssertEqual(boolean.value, true) 1197 | 1198 | boolean.and(false) 1199 | XCTAssertEqual(boolean.value, false) 1200 | boolean.and(true) 1201 | XCTAssertEqual(boolean.value, false) 1202 | 1203 | boolean.xor(false) 1204 | XCTAssertEqual(boolean.value, false) 1205 | boolean.xor(true) 1206 | XCTAssertEqual(boolean.value, true) 1207 | 1208 | var old = boolean.swap(false) 1209 | XCTAssertEqual(old, true) 1210 | XCTAssertEqual(boolean.swap(true), false) 1211 | 1212 | boolean.CAS(current: true, future: false) 1213 | XCTAssertEqual(boolean.value, false) 1214 | 1215 | XCTAssertEqual(boolean.CAS(current: false, future: true, type: .strong), true) 1216 | XCTAssertEqual(boolean.value, old) 1217 | XCTAssertEqual(boolean.loadCAS(current: &old, future: false, type: .strong), true) 1218 | 1219 | while !boolean.loadCAS(current: &old, future: true, type: .weak) {} 1220 | while !boolean.CAS(current: !old, future: false, type: .weak) {} 1221 | } 1222 | 1223 | public func testFence() 1224 | { 1225 | threadFence() 1226 | threadFence(order: .sequential) 1227 | } 1228 | } 1229 | -------------------------------------------------------------------------------- /Tests/SwiftAtomicsTests/AtomicsTests.swift.gyb: -------------------------------------------------------------------------------- 1 | // 2 | // AtomicsTests.swift 3 | // AtomicsTests 4 | // 5 | // Copyright © 2015-2018 Guillaume Lessard. All rights reserved. 6 | // This file is distributed under the BSD 3-clause license. See LICENSE for details. 7 | // 8 | 9 | import XCTest 10 | 11 | import SwiftAtomics 12 | 13 | public class AtomicsBasicTests: XCTestCase 14 | { 15 | % for i in ['Int', 'UInt', 'Int8', 'UInt8', 'Int16', 'UInt16', 'Int32', 'UInt32', 'Int64', 'UInt64']: 16 | public func test${i}() 17 | { 18 | var i = Atomic${i}(0) 19 | XCTAssertEqual(i.value, 0) 20 | i.initialize(1) 21 | XCTAssertEqual(i.value, 1) 22 | 23 | #if swift(>=4.0) 24 | let r1 = ${i}.randomPositive() 25 | let r2 = ${i}.randomPositive() 26 | let r3 = ${i}.randomPositive() 27 | #else 28 | % truncating = '' if (i == 'Int' or i == 'UInt' or i == 'Int64' or i == 'UInt64') else 'truncatingBitPattern: ' 29 | let r1 = ${i}(${truncating}UInt.randomPositive()) 30 | let r2 = ${i}(${truncating}UInt.randomPositive()) 31 | let r3 = ${i}(${truncating}UInt.randomPositive()) 32 | #endif 33 | 34 | i.store(r1) 35 | XCTAssertEqual(r1, i.load()) 36 | 37 | var j = i.swap(r2) 38 | XCTAssertEqual(r1, j) 39 | XCTAssertEqual(r2, i.load()) 40 | 41 | j = i.add(r1) 42 | XCTAssertEqual(r2, j) 43 | XCTAssertEqual(r1 &+ r2, i.load()) 44 | 45 | j = i.subtract(r2) 46 | XCTAssertEqual(r1 &+ r2, j) 47 | XCTAssertEqual(r1, i.load()) 48 | 49 | j = i.increment() 50 | XCTAssertEqual(r1, j) 51 | XCTAssertEqual(r1 &+ 1, i.load()) 52 | 53 | i.store(r3) 54 | j = i.decrement() 55 | XCTAssertEqual(r3, j) 56 | XCTAssertEqual(r3 &- 1, i.load()) 57 | 58 | i.store(r1) 59 | j = i.bitwiseOr(r2) 60 | XCTAssertEqual(r1, j) 61 | XCTAssertEqual(r1 | r2, i.load()) 62 | 63 | i.store(r2) 64 | j = i.bitwiseXor(r1) 65 | XCTAssertEqual(r2, j) 66 | XCTAssertEqual(r1 ^ r2, i.load()) 67 | 68 | i.store(r1) 69 | j = i.bitwiseAnd(r2) 70 | XCTAssertEqual(r1, j) 71 | XCTAssertEqual(r1 & r2, i.load()) 72 | 73 | i.store(r1) 74 | XCTAssertTrue(i.CAS(current: r1, future: r2, type: .strong)) 75 | XCTAssertEqual(r2, i.load()) 76 | 77 | j = r2 78 | i.store(r1) 79 | while(!i.loadCAS(current: &j, future: r3)) {} 80 | XCTAssertEqual(r1, j) 81 | XCTAssertEqual(r3, i.load()) 82 | } 83 | 84 | % end 85 | % for type in ['Raw', 'MutableRaw', '', 'Mutable', 'Opaque']: 86 | % for optional in ['', 'Optional']: 87 | % unsafe = 'Unsafe' if type != 'Opaque' else '' 88 | % pointee = '' if (type == '' or type == 'Mutable') else '' 89 | public func test${unsafe}${type}Pointer${optional}() 90 | { 91 | % if optional == 'Optional': 92 | var n = Atomic${optional}${type}Pointer${pointee}() 93 | XCTAssertEqual(n.pointer, nil) 94 | 95 | % end 96 | % bang = '' if optional else '!' 97 | let r0 = ${unsafe}${type}Pointer${pointee}(bitPattern: UInt.randomPositive())${bang} 98 | let r1 = ${unsafe}${type}Pointer${pointee}(bitPattern: UInt.randomPositive())${bang} 99 | let r2 = ${unsafe}${type}Pointer${pointee}(bitPattern: UInt.randomPositive())${bang} 100 | let r3 = ${unsafe}${type}Pointer${pointee}(bitPattern: UInt.randomPositive())${bang} 101 | 102 | var i = Atomic${optional}${type}Pointer${pointee}(r0) 103 | XCTAssertEqual(i.pointer, r0) 104 | 105 | i.initialize(r1) 106 | XCTAssertEqual(i.pointer, r1) 107 | 108 | i.store(r0) 109 | XCTAssertEqual(r0, i.load()) 110 | 111 | var j = i.swap(r2) 112 | XCTAssertEqual(r0, j) 113 | XCTAssertEqual(r2, i.load()) 114 | 115 | i.store(r1) 116 | XCTAssertTrue(i.CAS(current: r1, future: r2, type: .strong)) 117 | XCTAssertEqual(r2, i.load()) 118 | 119 | j = r2 120 | i.store(r1) 121 | while(!i.loadCAS(current: &j, future: r3)) {} 122 | XCTAssertEqual(r1, j) 123 | XCTAssertEqual(r3, i.load()) 124 | } 125 | 126 | % end 127 | % end 128 | % for type in ['Raw', 'MutableRaw']: 129 | % for optional in ['', 'Optional']: 130 | public func testTagged${optional}${type}Pointer() 131 | { 132 | % bang = '' if optional else '!' 133 | let r0 = (Unsafe${type}Pointer(bitPattern: UInt.randomPositive())${bang}, 0) 134 | let r1 = (Unsafe${type}Pointer(bitPattern: UInt.randomPositive())${bang}, 1) 135 | let r2 = (Unsafe${type}Pointer(bitPattern: UInt.randomPositive())${bang}, 2) 136 | let r3 = (r2.0, r2.1+1) 137 | 138 | var p = AtomicTagged${optional}${type}Pointer(r3) 139 | XCTAssertEqual(r3.0, p.value.pointer) 140 | XCTAssertEqual(r3.1, p.value.tag) 141 | 142 | p.initialize((r3.0, r0.1)) 143 | XCTAssertEqual(r3.0, p.value.pointer) 144 | XCTAssertEqual(r0.1, p.value.tag) 145 | 146 | p.store(r1, order: .release) 147 | XCTAssertEqual(r1.0, p.value.pointer) 148 | XCTAssertEqual(r1.1, p.value.tag) 149 | 150 | var j = p.swap(r2, order: .acqrel) 151 | XCTAssertEqual(r1.0, j.0) 152 | XCTAssertEqual(r1.1, j.1) 153 | j = p.load(order: .acquire) 154 | XCTAssertEqual(r2.0, j.0) 155 | XCTAssertEqual(r2.1, j.1) 156 | 157 | XCTAssertTrue(p.CAS(current: r2, future: r3)) 158 | XCTAssertEqual(r3.0, p.value.pointer) 159 | XCTAssertEqual(r3.1, p.value.tag) 160 | 161 | XCTAssertFalse(p.CAS(current: j, future: r2, type: .weak)) 162 | XCTAssertTrue(p.CAS(current: r3, future: r2)) 163 | j = p.load(order: .relaxed) 164 | XCTAssertTrue(p.CAS(current: r2, future: r1)) 165 | while !p.loadCAS(current: &j, future: r3) {} 166 | XCTAssertEqual(r1.0, j.0) 167 | XCTAssertEqual(r1.1, j.1) 168 | XCTAssertEqual(r3.0, p.value.pointer) 169 | XCTAssertEqual(r3.1, p.value.tag) 170 | } 171 | 172 | % end 173 | % end 174 | public func testBool() 175 | { 176 | var boolean = AtomicBool() 177 | boolean.initialize(false) 178 | XCTAssertEqual(boolean.value, false) 179 | 180 | boolean.store(false) 181 | XCTAssertEqual(boolean.value, false) 182 | 183 | boolean.store(true) 184 | XCTAssertEqual(boolean.value, true) 185 | XCTAssertEqual(boolean.value, boolean.load()) 186 | 187 | boolean.store(true) 188 | boolean.or(true) 189 | XCTAssertEqual(boolean.value, true) 190 | boolean.or(false) 191 | XCTAssertEqual(boolean.value, true) 192 | boolean.store(false) 193 | boolean.or(false) 194 | XCTAssertEqual(boolean.value, false) 195 | boolean.or(true) 196 | XCTAssertEqual(boolean.value, true) 197 | 198 | boolean.and(false) 199 | XCTAssertEqual(boolean.value, false) 200 | boolean.and(true) 201 | XCTAssertEqual(boolean.value, false) 202 | 203 | boolean.xor(false) 204 | XCTAssertEqual(boolean.value, false) 205 | boolean.xor(true) 206 | XCTAssertEqual(boolean.value, true) 207 | 208 | var old = boolean.swap(false) 209 | XCTAssertEqual(old, true) 210 | XCTAssertEqual(boolean.swap(true), false) 211 | 212 | boolean.CAS(current: true, future: false) 213 | XCTAssertEqual(boolean.value, false) 214 | 215 | XCTAssertEqual(boolean.CAS(current: false, future: true, type: .strong), true) 216 | XCTAssertEqual(boolean.value, old) 217 | XCTAssertEqual(boolean.loadCAS(current: &old, future: false, type: .strong), true) 218 | 219 | while !boolean.loadCAS(current: &old, future: true, type: .weak) {} 220 | while !boolean.CAS(current: !old, future: false, type: .weak) {} 221 | } 222 | 223 | public func testFence() 224 | { 225 | threadFence() 226 | threadFence(order: .sequential) 227 | } 228 | } 229 | -------------------------------------------------------------------------------- /Tests/SwiftAtomicsTests/RandomPositive.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RandomPositive.swift 3 | // 4 | 5 | #if swift(>=4.1.50) 6 | extension FixedWidthInteger where Self.Magnitude: UnsignedInteger, Self.Stride: SignedInteger 7 | { 8 | // returns a positive random integer greater than 0 and less-than-or-equal to Self.max/2 9 | static func randomPositive() -> Self 10 | { 11 | return Self.random(in: 1...(Self.max>>1)) 12 | } 13 | } 14 | #else 15 | 16 | #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) 17 | import func Darwin.C.stdlib.arc4random 18 | #else // assuming os(Linux) 19 | import func Glibc.random 20 | #endif 21 | 22 | #if swift(>=4.0) 23 | extension FixedWidthInteger where Self.Magnitude: UnsignedInteger, Self.Stride: SignedInteger 24 | { 25 | // returns a positive random integer greater than 0 and less-than-or-equal to Self.max/2 26 | static func randomPositive() -> Self 27 | { 28 | var t: Self = 0 29 | repeat { 30 | for _ in 0...((t.bitWidth-1)/32) 31 | { 32 | #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) 33 | t = t<<32 &+ Self(truncatingIfNeeded: arc4random()) 34 | #else // probably Linux 35 | t = t<<32 &+ Self(truncatingIfNeeded: Glibc.random()) 36 | #endif 37 | } 38 | } while t == 0 39 | 40 | return t & (Self.max>>1) 41 | } 42 | } 43 | #else 44 | extension UInt 45 | { 46 | // returns a positive random integer greater than 0 and less-than-or-equal to UInt32.max/2 47 | static func randomPositive() -> UInt 48 | { 49 | var t: UInt 50 | repeat { 51 | #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) 52 | t = UInt(arc4random()) 53 | #else // probably Linux 54 | t = UInt(Glibc.random()) 55 | #endif 56 | } while t == 0 57 | 58 | return t & (UInt.max>>1) 59 | } 60 | } 61 | #endif // swift(>=4.0) 62 | 63 | #endif // swift(>=4.1.50) 64 | -------------------------------------------------------------------------------- /Tests/SwiftAtomicsTests/ReferenceTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ReferenceTests.swift 3 | // AtomicsTests 4 | // 5 | // Created by Guillaume Lessard on 10/9/18. 6 | // Copyright © 2018 Guillaume Lessard. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import Dispatch 11 | 12 | import SwiftAtomics 13 | 14 | private struct Point { var x = 0.0, y = 0.0, z = 0.0 } 15 | 16 | private class Thing 17 | { 18 | let id: UInt 19 | init(_ x: UInt = UInt.randomPositive()) { id = x } 20 | } 21 | 22 | private class Witness: Thing 23 | { 24 | override init(_ x: UInt) { super.init(x) } 25 | deinit { print("Released \(id)") } 26 | } 27 | 28 | public class ReferenceTests: XCTestCase 29 | { 30 | public func testUnmanaged() 31 | { 32 | var i = UInt.randomPositive() 33 | var a = AtomicReference(Witness(i)) 34 | do { 35 | let r1 = a.swap(.none) 36 | print("Will release \(i)") 37 | XCTAssertNotNil(r1) 38 | XCTAssertNil(a.swap(nil)) 39 | } 40 | 41 | i = UInt.randomPositive() 42 | XCTAssertNil(a.swap(Witness(i))) 43 | print("Releasing \(i)") 44 | XCTAssertNotNil(a.swap(nil)) 45 | 46 | i = UInt.randomPositive() 47 | XCTAssertEqual(a.storeIfNil(Witness(i)), true) 48 | var j = UInt.randomPositive() 49 | print("Will drop \(j)") 50 | // a compiler warning is expected for the next line 51 | #if swift(>=5.0) 52 | XCTAssertEqual(a.storeIfNil(Witness(j)), false) 53 | #else 54 | XCTAssertEqual(a.swapIfNil(Witness(j), order: .release), false) 55 | #endif 56 | 57 | weak var witnessi: Witness? = { 58 | let w = a.swap(nil) 59 | XCTAssertNotNil(w) 60 | XCTAssertTrue(a.storeIfNil(w!)) 61 | return w 62 | }() 63 | XCTAssertNotNil(witnessi) 64 | XCTAssertEqual(witnessi?.id, i) 65 | 66 | j = UInt.randomPositive() 67 | var witnessj = Optional(Witness(j)) 68 | XCTAssertFalse(a.CAS(current: nil, future: witnessi)) 69 | XCTAssertFalse(a.CAS(current: witnessj, future: witnessi)) 70 | 71 | print("Will release \(i)") 72 | XCTAssertTrue(a.CAS(current: witnessi, future: witnessj)) 73 | witnessj = nil 74 | 75 | print("Will release \(j)") 76 | XCTAssertNotNil(a.take()) 77 | XCTAssertNil(a.take()) 78 | } 79 | } 80 | 81 | private let iterations = 200_000//_000 82 | 83 | public class ReferenceRaceTests: XCTestCase 84 | { 85 | #if false 86 | public func testRaceCrash() 87 | { 88 | let q = DispatchQueue(label: "", attributes: .concurrent) 89 | 90 | for _ in 1...iterations 91 | { 92 | var r: Optional = ManagedBuffer.create(minimumCapacity: 1, makingHeaderWith: { _ in 1 }) 93 | let closure = { 94 | while true 95 | { 96 | if r != nil 97 | { 98 | r = nil 99 | } 100 | else 101 | { 102 | break 103 | } 104 | } 105 | } 106 | 107 | q.async(execute: closure) 108 | q.async(execute: closure) 109 | } 110 | 111 | q.sync(flags: .barrier) {} 112 | } 113 | #endif 114 | 115 | public func testRaceAtomicReference() 116 | { 117 | let q = DispatchQueue(label: "", attributes: .concurrent) 118 | 119 | for _ in 1...iterations 120 | { 121 | var r = AtomicReference(ManagedBuffer.create(minimumCapacity: 1, makingHeaderWith: { _ in 1 })) 122 | 123 | let closure = { 124 | while true 125 | { 126 | if let buffer = r.take() 127 | { 128 | XCTAssertEqual(buffer.header, 1) 129 | } 130 | else 131 | { 132 | break 133 | } 134 | } 135 | } 136 | 137 | q.async(execute: closure) 138 | q.async(execute: closure) 139 | } 140 | 141 | q.sync(flags: .barrier) {} 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /Tests/SwiftAtomicsTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | #if !(os(macOS) || os(iOS) || os(tvOS) || os(watchOS)) 2 | import XCTest 3 | 4 | extension AtomicsBasicTests { 5 | // DO NOT MODIFY: This is autogenerated, use: 6 | // `swift test --generate-linuxmain` 7 | // to regenerate. 8 | static let __allTests__AtomicsBasicTests = [ 9 | ("testBool", testBool), 10 | ("testFence", testFence), 11 | ("testInt", testInt), 12 | ("testInt16", testInt16), 13 | ("testInt32", testInt32), 14 | ("testInt64", testInt64), 15 | ("testInt8", testInt8), 16 | ("testOpaquePointer", testOpaquePointer), 17 | ("testOpaquePointerOptional", testOpaquePointerOptional), 18 | ("testTaggedMutableRawPointer", testTaggedMutableRawPointer), 19 | ("testTaggedOptionalMutableRawPointer", testTaggedOptionalMutableRawPointer), 20 | ("testTaggedOptionalRawPointer", testTaggedOptionalRawPointer), 21 | ("testTaggedRawPointer", testTaggedRawPointer), 22 | ("testUInt", testUInt), 23 | ("testUInt16", testUInt16), 24 | ("testUInt32", testUInt32), 25 | ("testUInt64", testUInt64), 26 | ("testUInt8", testUInt8), 27 | ("testUnsafeMutablePointer", testUnsafeMutablePointer), 28 | ("testUnsafeMutablePointerOptional", testUnsafeMutablePointerOptional), 29 | ("testUnsafeMutableRawPointer", testUnsafeMutableRawPointer), 30 | ("testUnsafeMutableRawPointerOptional", testUnsafeMutableRawPointerOptional), 31 | ("testUnsafePointer", testUnsafePointer), 32 | ("testUnsafePointerOptional", testUnsafePointerOptional), 33 | ("testUnsafeRawPointer", testUnsafeRawPointer), 34 | ("testUnsafeRawPointerOptional", testUnsafeRawPointerOptional), 35 | ] 36 | } 37 | 38 | extension AtomicsRaceTests { 39 | // DO NOT MODIFY: This is autogenerated, use: 40 | // `swift test --generate-linuxmain` 41 | // to regenerate. 42 | static let __allTests__AtomicsRaceTests = [ 43 | ("testRaceCrash", testRaceCrash), 44 | ("testRacePointerCAS", testRacePointerCAS), 45 | ("testRacePointerLoadCAS", testRacePointerLoadCAS), 46 | ("testRacePointerSwap", testRacePointerSwap), 47 | ("testRaceSpinLock", testRaceSpinLock), 48 | ] 49 | } 50 | 51 | extension ReferenceRaceTests { 52 | // DO NOT MODIFY: This is autogenerated, use: 53 | // `swift test --generate-linuxmain` 54 | // to regenerate. 55 | static let __allTests__ReferenceRaceTests = [ 56 | ("testRaceAtomicReference", testRaceAtomicReference), 57 | ] 58 | } 59 | 60 | extension ReferenceTests { 61 | // DO NOT MODIFY: This is autogenerated, use: 62 | // `swift test --generate-linuxmain` 63 | // to regenerate. 64 | static let __allTests__ReferenceTests = [ 65 | ("testUnmanaged", testUnmanaged), 66 | ] 67 | } 68 | 69 | public func __allTests() -> [XCTestCaseEntry] { 70 | return [ 71 | testCase(AtomicsBasicTests.__allTests__AtomicsBasicTests), 72 | testCase(AtomicsRaceTests.__allTests__AtomicsRaceTests), 73 | testCase(ReferenceRaceTests.__allTests__ReferenceRaceTests), 74 | testCase(ReferenceTests.__allTests__ReferenceTests), 75 | ] 76 | } 77 | #endif 78 | -------------------------------------------------------------------------------- /Tests/test-script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | COMPILER_MAJOR_VERSION=`echo ${COMPILER_VERSION} | awk -F . '{print $1}'` 5 | TEST_OPTIONS="-c release -Xcc -mcx16" 6 | 7 | swift --version 8 | swift test ${TEST_OPTIONS} 9 | 10 | if [[ "${COMPILER_MAJOR_VERSION}" = "4" ]] 11 | then 12 | MINOR_VERSION=`echo ${COMPILER_VERSION} | awk -F . '{print $2}'` 13 | if [[ "${MINOR_VERSION}" = "2" ]] 14 | then 15 | VERSIONS="4 3" 16 | else 17 | VERSIONS="3" 18 | fi 19 | elif [[ "${COMPILER_MAJOR_VERSION}" = "5" ]] 20 | then 21 | VERSIONS="4.2 4" 22 | fi 23 | 24 | for LANGUAGE_VERSION in $VERSIONS 25 | do 26 | echo "" # add a small visual separation 27 | echo "Testing in compatibility mode for Swift ${LANGUAGE_VERSION}" 28 | if [[ "${LANGUAGE_VERSION}" = "3" ]] 29 | then 30 | TEST_OPTIONS="-Xcc -mcx16" 31 | fi 32 | swift package reset 33 | rm -f Package.resolved 34 | swift test ${TEST_OPTIONS} -Xswiftc -swift-version -Xswiftc ${LANGUAGE_VERSION} 35 | done 36 | -------------------------------------------------------------------------------- /Utilities/generate-linuxmain.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | manifest="XCTestManifests.swift" 4 | 5 | if [[ -z ${PROJECT_DIR} ]] 6 | then 7 | testspath="${PWD}/Tests" 8 | else 9 | testspath="${PROJECT_DIR}/../Tests" 10 | fi 11 | 12 | testdirs="SwiftAtomicsTests" 13 | 14 | for testdir in ${testdirs} 15 | do 16 | manifestpath="${testspath}/${testdir}/${manifest}" 17 | if /bin/test ! -s "${manifestpath}" 18 | then 19 | # echo "$manifestpath does not exist" 20 | generate="yes" 21 | else 22 | newer=`/usr/bin/find "${testspath}/${testdir}" -newer "${manifestpath}"` 23 | if /bin/test "${newer}" 24 | then 25 | # echo "newer files than $manifestpath" 26 | generate="yes" 27 | fi 28 | fi 29 | done 30 | 31 | if /bin/test "${generate}" 32 | then 33 | /usr/bin/find "${testspath}" -name "${manifest}" -exec rm -f {} \; 34 | echo "Regenerating test manifests" 35 | /usr/bin/swift test --generate-linuxmain 36 | prev="${PWD}" 37 | cd "${testspath}/../" 38 | /usr/bin/git apply "Utilities/test-compatibility.diff" 39 | cd "${prev}" 40 | else 41 | echo "No need to regenerate test manifests" 42 | fi 43 | -------------------------------------------------------------------------------- /Utilities/generate-swift.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [[ -z ${PROJECT_DIR} ]] 6 | then 7 | SOURCES="${PWD}/Sources" 8 | TESTS="${PWD}/Tests" 9 | UTILITIES="${PWD}/Utilities" 10 | else 11 | SOURCES="${PROJECT_DIR}/../Sources" 12 | TESTS="${PROJECT_DIR}/../Tests" 13 | UTILITIES="${PROJECT_DIR}/../Utilities" 14 | fi 15 | 16 | if [[ ! -d ${SOURCES} || ! -d ${TESTS} || ! -d ${UTILITIES} ]] 17 | then 18 | echo "Missing some directories, assuming the worst and exiting" 19 | exit 1 20 | fi 21 | 22 | GYB="${UTILITIES}/gyb.py" 23 | if [[ ! -x ${GYB} ]] 24 | then 25 | GITHUB=https://raw.githubusercontent.com/apple/swift/master/utils/gyb.py 26 | echo "Retrieving gyb.py from ${GITHUB}" 27 | /usr/bin/curl ${GITHUB} -o ${GYB} 28 | chmod u+x ${GYB} 29 | fi 30 | 31 | if [[ ${1} == "-f" ]] 32 | then 33 | FORCE="-f" 34 | fi 35 | 36 | INPUT_FILE_LIST=`find ${SOURCES} ${TESTS} -name "*.gyb"` 37 | 38 | echo "Starting generation of boilerplate:" 39 | for INPUT_FILE in $INPUT_FILE_LIST 40 | do 41 | OUTPUT_FILE=${INPUT_FILE%.*} 42 | 43 | if [[ -n $FORCE || $OUTPUT_FILE -ot $INPUT_FILE ]] 44 | then # output file is either older or doesn't exist yet 45 | echo "Generating ${OUTPUT_FILE}" 46 | ${GYB} --line-directive="" "${INPUT_FILE}" -o "${OUTPUT_FILE}" 47 | fi 48 | done 49 | echo "Boilerplate successfully generated." 50 | -------------------------------------------------------------------------------- /Utilities/git-pre-commit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Called by "git commit" with no arguments. The hook should 4 | # exit with non-zero status after issuing an appropriate message if 5 | # it wants to stop the commit. 6 | 7 | if git rev-parse --verify HEAD >/dev/null 2>&1 8 | then 9 | against=HEAD 10 | else 11 | # Initial commit: diff against an empty tree object 12 | against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 13 | fi 14 | 15 | # Redirect output to stderr. 16 | exec 1>&2 17 | 18 | sh ./Utilities/validate-gybbed-files.sh 19 | if [ $? -ne 0 ] 20 | then 21 | exit 1 22 | fi 23 | -------------------------------------------------------------------------------- /Utilities/install-swift.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | if [[ -n "$SWIFT" ]] 5 | then 6 | export COMPILER_VERSION=$SWIFT 7 | 8 | COMPILER="swift-${COMPILER_VERSION}-RELEASE" 9 | BRANCH="swift-${COMPILER_VERSION}-release" 10 | URLBASE="https://swift.org/builds/${BRANCH}" 11 | 12 | if [[ "$TRAVIS_OS_NAME" == "linux" ]] 13 | then 14 | if [[ "$TRAVIS_DIST" == "bionic" ]] 15 | then 16 | PLATFORM="ubuntu1804" 17 | BASENAME="${COMPILER}-ubuntu18.04" 18 | elif [[ "$TRAVIS_DIST" == "xenial" ]] 19 | then 20 | PLATFORM="ubuntu1604" 21 | BASENAME="${COMPILER}-ubuntu16.04" 22 | else 23 | echo "Unknown linux distribution in use" 24 | exit 1 25 | fi 26 | 27 | # install swift 28 | cd .. 29 | echo "Getting ${URLBASE}/${PLATFORM}/${COMPILER}/${BASENAME}.tar.gz" 30 | curl -s -O ${URLBASE}/${PLATFORM}/${COMPILER}/${BASENAME}.tar.gz 31 | tar xzf ${BASENAME}.tar.gz 32 | export PATH="${PWD}/${BASENAME}/usr/bin:${PATH}" 33 | cd "${TRAVIS_BUILD_DIR}" 34 | fi 35 | elif [[ -z $(which swift) ]] 36 | then 37 | echo "Set SWIFT to define which compiler version to install" 38 | exit 1 39 | fi 40 | 41 | swift --version 42 | -------------------------------------------------------------------------------- /Utilities/test-compatibility.diff: -------------------------------------------------------------------------------- 1 | diff --git a/Tests/SwiftAtomicsTests/XCTestManifests.swift b/Tests/SwiftAtomicsTests/XCTestManifests.swift 2 | index b2cd3de..c870da3 100644 3 | --- a/Tests/SwiftAtomicsTests/XCTestManifests.swift 4 | +++ b/Tests/SwiftAtomicsTests/XCTestManifests.swift 5 | @@ -1,4 +1,4 @@ 6 | -#if !canImport(ObjectiveC) 7 | +#if !(os(macOS) || os(iOS) || os(tvOS) || os(watchOS)) 8 | import XCTest 9 | 10 | extension AtomicsBasicTests { 11 | -------------------------------------------------------------------------------- /Utilities/validate-gybbed-files.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script will fail if a `gyb` file and the file it generates are out of sync. 4 | 5 | INPUT_LIST=`find Sources Tests -name "*.gyb"` 6 | [[ -z $INPUT_LIST ]] && exit 0 7 | 8 | GYB="Utilities/gyb.py" 9 | if [ -n "${TRAVIS_BUILD_DIR}" ]; 10 | then 11 | GYB="${TRAVIS_BUILD_DIR}/${GYB}" 12 | fi 13 | 14 | if [[ ! -x ${GYB} ]] 15 | then 16 | GITHUB=https://raw.githubusercontent.com/apple/swift/main/utils/gyb.py 17 | echo "Retrieving gyb.py from ${GITHUB}" 18 | /usr/bin/curl ${GITHUB} -o ${GYB} 19 | chmod u+x ${GYB} 20 | fi 21 | 22 | for INPUT_FILE in $INPUT_LIST 23 | do 24 | INPUT_FILE_PATH=${INPUT_FILE%/*} 25 | INPUT_FILE_NAME=${INPUT_FILE##*/} 26 | INPUT_FILE_BASE=${INPUT_FILE_NAME%.*} 27 | 28 | OUTPUT_TMP="/tmp/${INPUT_FILE_BASE}" 29 | OUT_TARGET="${INPUT_FILE_PATH}/${INPUT_FILE_BASE}" 30 | 31 | # echo "Generating ${OUTPUT_TMP}" 32 | ${GYB} --line-directive="" "${INPUT_FILE}" -o "${OUTPUT_TMP}" 33 | # echo "Comparing ${OUT_TARGET} with ${OUTPUT_TMP}" 34 | DIFF=`/usr/bin/diff -q "${OUTPUT_TMP}" "${OUT_TARGET}"` 35 | if [ $? -ne 0 ] 36 | then 37 | echo "${INPUT_FILE_BASE} differs from generated output of ${INPUT_FILE_NAME} in ${INPUT_FILE_PATH}" 38 | exit 1 39 | fi 40 | /bin/rm -f "${OUTPUT_TMP}" 41 | done 42 | -------------------------------------------------------------------------------- /Xcode-Old/Atomics.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Xcode-Old/Atomics.xcodeproj/xcshareddata/xcschemes/AtomicsTestApp.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 65 | 67 | 73 | 74 | 75 | 76 | 77 | 78 | 84 | 86 | 92 | 93 | 94 | 95 | 97 | 98 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /Xcode-Old/Atomics.xcodeproj/xcshareddata/xcschemes/CAtomics.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 65 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 84 | 90 | 91 | 92 | 93 | 95 | 96 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /Xcode-Old/Atomics.xcodeproj/xcshareddata/xcschemes/SwiftAtomics.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 44 | 50 | 51 | 52 | 53 | 54 | 60 | 61 | 62 | 63 | 64 | 65 | 75 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 94 | 100 | 101 | 102 | 103 | 105 | 106 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /Xcode-Old/AtomicsTestApp/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Atomics_TestApp 4 | // 5 | 6 | import UIKit 7 | 8 | import SwiftAtomics 9 | import CAtomics 10 | 11 | #if !swift(>=4.2) 12 | extension UIApplication { typealias LaunchOptionsKey = UIApplicationLaunchOptionsKey } 13 | #endif 14 | 15 | @UIApplicationMain 16 | class AppDelegate: UIResponder, UIApplicationDelegate { 17 | 18 | var window: UIWindow? 19 | 20 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool 21 | { 22 | var o = AtomicOptionalRawPointer() 23 | let p = UnsafeRawPointer(bitPattern: 0x1013)! 24 | CAtomicsInitialize(&o, p) 25 | assert(CAtomicsLoad(&o, .relaxed) != nil) 26 | let q = CAtomicsExchange(&o, nil, .sequential) 27 | assert(q == p) 28 | assert(CAtomicsLoad(&o, .relaxed) == nil) 29 | 30 | var tagged = AtomicTaggedRawPointer() 31 | assert(MemoryLayout.size == 2*MemoryLayout.size) 32 | tagged.initialize((UnsafeRawPointer(bitPattern: 0x0731)!, 1755)) 33 | var t = tagged.load(order: .relaxed) 34 | let u = (UnsafeRawPointer(bitPattern: 0x1013)!, 1837) 35 | let success = tagged.loadCAS(current: &t, future: u, type: .strong, orderSwap: .relaxed, orderLoad: .relaxed) 36 | assert(tagged.value.pointer == u.0) 37 | assert(success) 38 | 39 | var bool = AtomicBool() 40 | bool.store(false) 41 | let f = bool.swap(true, order: .sequential) 42 | assert(f == false) 43 | assert(bool.load(order: .acquire)) 44 | return bool.value 45 | } 46 | 47 | func applicationWillResignActive(_ application: UIApplication) { 48 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 49 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 50 | } 51 | 52 | func applicationDidEnterBackground(_ application: UIApplication) { 53 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 54 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 55 | } 56 | 57 | func applicationWillEnterForeground(_ application: UIApplication) { 58 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 59 | } 60 | 61 | func applicationDidBecomeActive(_ application: UIApplication) { 62 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 63 | } 64 | 65 | func applicationWillTerminate(_ application: UIApplication) { 66 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 67 | } 68 | 69 | 70 | } 71 | 72 | -------------------------------------------------------------------------------- /Xcode-Old/AtomicsTestApp/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /Xcode-Old/AtomicsTestApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Xcode-Old/AtomicsTestApp/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Xcode-Old/AtomicsTestApp/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Xcode-Old/AtomicsTestApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | UIInterfaceOrientationPortraitUpsideDown 37 | 38 | UISupportedInterfaceOrientations~ipad 39 | 40 | UIInterfaceOrientationPortrait 41 | UIInterfaceOrientationPortraitUpsideDown 42 | UIInterfaceOrientationLandscapeLeft 43 | UIInterfaceOrientationLandscapeRight 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Xcode-Old/AtomicsTestApp/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Atomics_TestApp 4 | // 5 | 6 | import UIKit 7 | 8 | class ViewController: UIViewController { 9 | 10 | override func viewDidLoad() { 11 | super.viewDidLoad() 12 | // Do any additional setup after loading the view, typically from a nib. 13 | } 14 | 15 | override func didReceiveMemoryWarning() { 16 | super.didReceiveMemoryWarning() 17 | // Dispose of any resources that can be recreated. 18 | } 19 | 20 | 21 | } 22 | 23 | -------------------------------------------------------------------------------- /Xcode-Old/AtomicsTestAppTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Xcode-Old/CAtomics/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSHumanReadableCopyright 22 | Copyright © 2018 Guillaume Lessard. All rights reserved. 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Xcode-Old/CAtomicsTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Xcode-Old/SwiftAtomics/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSHumanReadableCopyright 22 | Copyright © 2018 Guillaume Lessard. All rights reserved. 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Xcode-Old/SwiftAtomicsTests/AtomicsPerformanceTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AtomicsPerformanceTests.swift 3 | // AtomicsTests 4 | // 5 | // Copyright © 2015-2017 Guillaume Lessard. All rights reserved. 6 | // This file is distributed under the BSD 3-clause license. See LICENSE for details. 7 | // 8 | 9 | import XCTest 10 | import Atomics 11 | 12 | public class AtomicsPerformanceTests: XCTestCase 13 | { 14 | let testLoopCount = 1_000_000 15 | 16 | public func testPerformanceStore() 17 | { 18 | let c = testLoopCount 19 | var m = AtomicInt() 20 | measure { 21 | m.store(0) 22 | for i in 0.. 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | --------------------------------------------------------------------------------