Skip to content

Commit d5e6386

Browse files
committed
Subset out the used portions of swift-atomics
1 parent 3ff4620 commit d5e6386

File tree

9 files changed

+492
-3
lines changed

9 files changed

+492
-3
lines changed

Package.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ let package = Package(
4444
],
4545
dependencies: [
4646
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.0.0"),
47-
.package(url: "https://github.com/apple/swift-atomics", from: "1.0.0"),
4847
],
4948
targets: [
5049
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
@@ -61,12 +60,18 @@ let package = Package(
6160
.target(
6261
name: "_CUnicode",
6362
dependencies: []),
63+
.target(
64+
name: "_LazyAtomicShims",
65+
dependencies: []),
66+
.target(
67+
name: "_LazyAtomic",
68+
dependencies: ["_LazyAtomicShims"]),
6469
.target(
6570
name: "_StringProcessing",
6671
dependencies: [
67-
.product(name: "Atomics", package: "swift-atomics"),
6872
"_RegexParser",
6973
"_CUnicode",
74+
"_LazyAtomic",
7075
],
7176
swiftSettings: publicStdlibSettings),
7277
.target(

Sources/_LazyAtomic/AtomicValue.swift

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
//
10+
//===----------------------------------------------------------------------===//
11+
12+
// THIS FILE IS PART OF A SUBSET OF https://github.com/apple/swift-atomics/
13+
14+
public protocol AtomicValue {
15+
associatedtype AtomicRepresentation: AtomicStorage
16+
where AtomicRepresentation.Value == Self
17+
}
18+
19+
public protocol AtomicStorage {
20+
associatedtype Value
21+
22+
init(_ value: __owned Value)
23+
24+
__consuming func dispose() -> Value
25+
26+
@_semantics("atomics.requires_constant_orderings")
27+
static func atomicLoad(
28+
at pointer: UnsafeMutablePointer<Self>
29+
) -> Value
30+
31+
@_semantics("atomics.requires_constant_orderings")
32+
static func atomicCompareExchange(
33+
expected: Value,
34+
desired: __owned Value,
35+
at pointer: UnsafeMutablePointer<Self>
36+
) -> (exchanged: Bool, original: Value)
37+
}

Sources/_LazyAtomic/Int.swift

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
//
10+
//===----------------------------------------------------------------------===//
11+
12+
// THIS FILE IS PART OF A SUBSET OF https://github.com/apple/swift-atomics/
13+
14+
import _LazyAtomicShims
15+
16+
extension Int: AtomicValue {
17+
@frozen
18+
public struct AtomicRepresentation {
19+
public typealias Value = Int
20+
21+
@usableFromInline
22+
var _storage: _AtomicIntStorage
23+
24+
@inline(__always) @_alwaysEmitIntoClient
25+
public init(_ value: Value) {
26+
self._storage = _sa_prepare_Int(value)
27+
}
28+
29+
@inline(__always) @_alwaysEmitIntoClient
30+
public func dispose() -> Value {
31+
return _sa_dispose_Int(_storage)
32+
}
33+
}
34+
}
35+
36+
extension UnsafeMutablePointer
37+
where Pointee == Int.AtomicRepresentation {
38+
@inlinable @inline(__always)
39+
internal var _extract: UnsafeMutablePointer<_AtomicIntStorage> {
40+
// `Int` is layout-compatible with its only stored property.
41+
return UnsafeMutableRawPointer(self)
42+
.assumingMemoryBound(to: _AtomicIntStorage.self)
43+
}
44+
}
45+
46+
extension Int.AtomicRepresentation: AtomicStorage {
47+
@_semantics("atomics.requires_constant_orderings")
48+
@_transparent @_alwaysEmitIntoClient
49+
public static func atomicLoad(
50+
at pointer: UnsafeMutablePointer<Self>
51+
) -> Value {
52+
_sa_load_acquire_Int(pointer._extract)
53+
}
54+
55+
@_semantics("atomics.requires_constant_orderings")
56+
@_transparent @_alwaysEmitIntoClient
57+
public static func atomicCompareExchange(
58+
expected: Value,
59+
desired: Value,
60+
at pointer: UnsafeMutablePointer<Self>
61+
) -> (exchanged: Bool, original: Value) {
62+
var expected = expected
63+
let exchanged: Bool
64+
exchanged = _sa_cmpxchg_strong_acq_rel_acquire_Int(
65+
pointer._extract,
66+
&expected, desired)
67+
return (exchanged, expected)
68+
}
69+
}

Sources/_LazyAtomic/Optional.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
//
10+
//===----------------------------------------------------------------------===//
11+
12+
// THIS FILE IS PART OF A SUBSET OF https://github.com/apple/swift-atomics/
13+
14+
public protocol AtomicOptionalWrappable: AtomicValue {
15+
associatedtype AtomicOptionalRepresentation: AtomicStorage
16+
where AtomicOptionalRepresentation.Value == Self?
17+
}
18+
19+
extension Optional: AtomicValue where Wrapped: AtomicOptionalWrappable {
20+
public typealias AtomicRepresentation = Wrapped.AtomicOptionalRepresentation
21+
}

Sources/_LazyAtomic/Unmanaged.swift

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
//
10+
//===----------------------------------------------------------------------===//
11+
12+
// THIS FILE IS PART OF A SUBSET OF https://github.com/apple/swift-atomics/
13+
14+
extension Unmanaged: AtomicValue {
15+
@frozen
16+
public struct AtomicRepresentation {
17+
public typealias Value = Unmanaged
18+
@usableFromInline internal typealias Storage = Int.AtomicRepresentation
19+
20+
@usableFromInline
21+
internal let _storage: Storage
22+
23+
@inline(__always) @_alwaysEmitIntoClient
24+
public init(_ value: Value) {
25+
self._storage = .init(Self._encode(value))
26+
}
27+
28+
@inline(__always) @_alwaysEmitIntoClient
29+
public func dispose() -> Value {
30+
Self._decode(_storage.dispose())
31+
}
32+
}
33+
}
34+
35+
extension Unmanaged.AtomicRepresentation {
36+
@_transparent @_alwaysEmitIntoClient
37+
@usableFromInline
38+
internal static func _extract(
39+
_ ptr: UnsafeMutablePointer<Self>
40+
) -> UnsafeMutablePointer<Storage> {
41+
// `Self` is layout-compatible with its only stored property.
42+
return UnsafeMutableRawPointer(ptr)
43+
.assumingMemoryBound(to: Storage.self)
44+
}
45+
46+
@_transparent @_alwaysEmitIntoClient
47+
internal static func _decode(_ bitPattern: Int) -> Value {
48+
return Unmanaged.fromOpaque(UnsafeRawPointer(bitPattern: bitPattern)!)
49+
}
50+
51+
@_transparent @_alwaysEmitIntoClient
52+
internal static func _encode(_ value: Value) -> Int {
53+
return Int(bitPattern: value.toOpaque())
54+
}
55+
}
56+
57+
extension Unmanaged.AtomicRepresentation: AtomicStorage {
58+
@_semantics("atomics.requires_constant_orderings")
59+
@_transparent @_alwaysEmitIntoClient
60+
public static func atomicLoad(
61+
at pointer: UnsafeMutablePointer<Self>
62+
) -> Value {
63+
let encoded = Storage.atomicLoad(at: _extract(pointer))
64+
return _decode(encoded)
65+
}
66+
67+
@_semantics("atomics.requires_constant_orderings")
68+
@_transparent @_alwaysEmitIntoClient
69+
public static func atomicCompareExchange(
70+
expected: Value,
71+
desired: Value,
72+
at pointer: UnsafeMutablePointer<Self>
73+
) -> (exchanged: Bool, original: Value) {
74+
let (exchanged, original) = Storage.atomicCompareExchange(
75+
expected: _encode(expected),
76+
desired: _encode(desired),
77+
at: _extract(pointer))
78+
return (exchanged, _decode(original))
79+
}
80+
}
81+
82+
extension Unmanaged: AtomicOptionalWrappable {
83+
@frozen
84+
public struct AtomicOptionalRepresentation {
85+
public typealias Value = Unmanaged?
86+
@usableFromInline internal typealias Storage = Int.AtomicRepresentation
87+
88+
@usableFromInline
89+
internal let _storage: Storage
90+
91+
@inline(__always) @_alwaysEmitIntoClient
92+
public init(_ value: Value) {
93+
self._storage = .init(Self._encode(value))
94+
}
95+
96+
@inline(__always) @_alwaysEmitIntoClient
97+
public func dispose() -> Value {
98+
Self._decode(_storage.dispose())
99+
}
100+
}
101+
}
102+
103+
extension Unmanaged.AtomicOptionalRepresentation {
104+
@_transparent @_alwaysEmitIntoClient
105+
@usableFromInline
106+
internal static func _extract(
107+
_ ptr: UnsafeMutablePointer<Self>
108+
) -> UnsafeMutablePointer<Storage> {
109+
// `Self` is layout-compatible with its only stored property.
110+
return UnsafeMutableRawPointer(ptr)
111+
.assumingMemoryBound(to: Storage.self)
112+
}
113+
114+
@_transparent @_alwaysEmitIntoClient
115+
internal static func _decode(_ bitPattern: Int) -> Value {
116+
guard let opaque = UnsafeRawPointer(bitPattern: bitPattern) else {
117+
return nil
118+
}
119+
return Unmanaged.fromOpaque(opaque)
120+
}
121+
122+
@_transparent @_alwaysEmitIntoClient
123+
internal static func _encode(_ value: Value) -> Int {
124+
guard let value = value else { return 0 }
125+
return Int(bitPattern: value.toOpaque())
126+
}
127+
}
128+
129+
extension Unmanaged.AtomicOptionalRepresentation: AtomicStorage {
130+
@_semantics("atomics.requires_constant_orderings")
131+
@_transparent @_alwaysEmitIntoClient
132+
public static func atomicLoad(
133+
at pointer: UnsafeMutablePointer<Self>
134+
) -> Value {
135+
let encoded = Storage.atomicLoad(at: _extract(pointer))
136+
return _decode(encoded)
137+
}
138+
139+
@_semantics("atomics.requires_constant_orderings")
140+
@_transparent @_alwaysEmitIntoClient
141+
public static func atomicCompareExchange(
142+
expected: Value,
143+
desired: Value,
144+
at pointer: UnsafeMutablePointer<Self>
145+
) -> (exchanged: Bool, original: Value) {
146+
let (exchanged, original) = Storage.atomicCompareExchange(
147+
expected: _encode(expected),
148+
desired: _encode(desired),
149+
at: _extract(pointer))
150+
return (exchanged, _decode(original))
151+
}
152+
}

0 commit comments

Comments
 (0)