├── Tests-on-Device
├── AtomicsApp
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Default-568h@2x.png
│ ├── ViewController.swift
│ ├── Info.plist
│ ├── Base.lproj
│ │ ├── Main.storyboard
│ │ └── LaunchScreen.storyboard
│ └── AppDelegate.swift
├── Atomics Test.xcodeproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── xcschemes
│ │ │ └── Atomics.xcscheme
│ └── project.pbxproj
└── AtomicsTests
│ └── Info.plist
├── Xcode-Old
├── AtomicsTestApp
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── ViewController.swift
│ ├── Info.plist
│ ├── Base.lproj
│ │ ├── Main.storyboard
│ │ └── LaunchScreen.storyboard
│ └── AppDelegate.swift
├── Atomics.xcodeproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── xcschemes
│ │ ├── CAtomics.xcscheme
│ │ ├── AtomicsTestApp.xcscheme
│ │ └── SwiftAtomics.xcscheme
├── CAtomicsTests
│ └── Info.plist
├── AtomicsTestAppTests
│ └── Info.plist
├── SwiftAtomicsTests
│ ├── Info.plist
│ └── AtomicsPerformanceTests.swift
├── CAtomics
│ └── Info.plist
└── SwiftAtomics
│ └── Info.plist
├── .gitignore
├── Tests
├── LinuxMain.swift
├── test-script.sh
└── SwiftAtomicsTests
│ ├── RandomPositive.swift
│ ├── XCTestManifests.swift
│ ├── ReferenceTests.swift
│ ├── AtomicsRaceTests.swift
│ ├── AtomicsTests.swift.gyb
│ └── AtomicsTests.swift
├── Utilities
├── test-compatibility.diff
├── git-pre-commit.sh
├── generate-linuxmain.sh
├── install-swift.sh
├── validate-gybbed-files.sh
└── generate-swift.sh
├── Sources
└── SwiftAtomics
│ ├── atomics-fence.swift
│ ├── atomics-orderings.swift
│ ├── atomics-integer.swift.gyb
│ ├── atomics-reference.swift
│ └── atomics-pointer.swift.gyb
├── Package@swift-4.swift
├── Package.swift
├── .travis.yml
├── LICENSE
└── README.md
/Tests-on-Device/AtomicsApp/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Xcode-Old/AtomicsTestApp/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Tests-on-Device/AtomicsApp/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/glessard/swift-atomics/HEAD/Tests-on-Device/AtomicsApp/Default-568h@2x.png
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/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-on-Device/Atomics Test.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Xcode-Old/Atomics.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/SwiftAtomicsTests/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/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 |
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/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/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/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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-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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 | }
--------------------------------------------------------------------------------
/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/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.. [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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # swift-atomics [](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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/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/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------