Skip to content

Commit 87974a8

Browse files
committed
Some documentation work, some work from review, add tests
1 parent 6d6e55a commit 87974a8

40 files changed

+2526
-440
lines changed

stdlib/public/core/Atomics/Atomic.swift

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,18 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
/// An atomic value.
14-
@available(SwiftStdlib 5.10, *)
14+
@available(SwiftStdlib 5.11, *)
1515
@_rawLayout(like: Value.AtomicRepresentation)
1616
@frozen
1717
public struct Atomic<Value: AtomicValue>: ~Copyable {
18-
@available(SwiftStdlib 5.10, *)
18+
@available(SwiftStdlib 5.11, *)
1919
@_alwaysEmitIntoClient
2020
@_transparent
2121
var address: UnsafeMutablePointer<Value.AtomicRepresentation> {
2222
UnsafeMutablePointer<Value.AtomicRepresentation>(rawAddress)
2323
}
2424

25-
@available(SwiftStdlib 5.10, *)
25+
@available(SwiftStdlib 5.11, *)
2626
@_alwaysEmitIntoClient
2727
@_transparent
2828
var rawAddress: Builtin.RawPointer {
@@ -32,17 +32,25 @@ public struct Atomic<Value: AtomicValue>: ~Copyable {
3232
/// Initializes a value of this atomic with the given initial value.
3333
///
3434
/// - Parameter initialValue: The initial value to set this atomic.
35-
@available(SwiftStdlib 5.10, *)
36-
@inlinable
35+
@available(SwiftStdlib 5.11, *)
36+
@_alwaysEmitIntoClient
37+
@_transparent
3738
public init(_ initialValue: consuming Value) {
3839
address.initialize(to: Value.encodeAtomicRepresentation(initialValue))
3940
}
4041

42+
// Deinit's can't be marked @_transparent. Do these things need all of these
43+
// attributes..?
44+
@available(SwiftStdlib 5.11, *)
45+
@_alwaysEmitIntoClient
4146
@inlinable
4247
deinit {
48+
let oldValue = Value.decodeAtomicRepresentation(address.pointee)
49+
_ = consume oldValue
50+
4351
address.deinitialize(count: 1)
4452
}
4553
}
4654

47-
@available(SwiftStdlib 5.10, *)
55+
@available(SwiftStdlib 5.11, *)
4856
extension Atomic: @unchecked Sendable where Value: Sendable {}

stdlib/public/core/Atomics/AtomicBool.swift

Lines changed: 57 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,24 @@
1414
// Bool AtomicValue conformance
1515
//===----------------------------------------------------------------------===//
1616

17-
@available(SwiftStdlib 5.10, *)
17+
@available(SwiftStdlib 5.11, *)
1818
extension Bool: AtomicValue {
19-
@available(SwiftStdlib 5.10, *)
19+
/// The storage representation type that `Self` encodes to and decodes from
20+
/// which is a suitable type when used in atomic operations.
21+
@available(SwiftStdlib 5.11, *)
2022
public typealias AtomicRepresentation = UInt8.AtomicRepresentation
2123

22-
@available(SwiftStdlib 5.10, *)
24+
/// Destroys a value of `Self` and prepares an `AtomicRepresentation` storage
25+
/// type to be used for atomic operations.
26+
///
27+
/// - Note: This is not an atomic operation. This simply encodes the logical
28+
/// type `Self` into its storage representation suitable for atomic
29+
/// operations, `AtomicRepresentation`.
30+
///
31+
/// - Parameter value: A valid instance of `Self` that's about to be destroyed
32+
/// to encode an instance of its `AtomicRepresentation`.
33+
/// - Returns: The newly encoded `AtomicRepresentation` storage.
34+
@available(SwiftStdlib 5.11, *)
2335
@_alwaysEmitIntoClient
2436
@_transparent
2537
public static func encodeAtomicRepresentation(
@@ -30,7 +42,17 @@ extension Bool: AtomicValue {
3042
)
3143
}
3244

33-
@available(SwiftStdlib 5.10, *)
45+
/// Recovers the logical atomic type `Self` by destroying some
46+
/// `AtomicRepresentation` storage instance returned from an atomic operation.
47+
///
48+
/// - Note: This is not an atomic operation. This simply decodes the storage
49+
/// representation used in atomic operations back into the logical type for
50+
/// normal use, `Self`.
51+
///
52+
/// - Parameter storage: The storage representation for `Self` that's used
53+
/// within atomic operations.
54+
/// - Returns: The newly decoded logical type `Self`.
55+
@available(SwiftStdlib 5.11, *)
3456
@_alwaysEmitIntoClient
3557
@_transparent
3658
public static func decodeAtomicRepresentation(
@@ -43,10 +65,10 @@ extension Bool: AtomicValue {
4365
}
4466

4567
//===----------------------------------------------------------------------===//
46-
// Bool load then atomic operations
68+
// Bool atomic operations
4769
//===----------------------------------------------------------------------===//
4870

49-
@available(SwiftStdlib 5.10, *)
71+
@available(SwiftStdlib 5.11, *)
5072
extension Atomic where Value == Bool {
5173
/// Perform an atomic logical AND operation and return the old and new value,
5274
/// applying the specified memory ordering.
@@ -55,54 +77,53 @@ extension Atomic where Value == Bool {
5577
/// - Parameter ordering: The memory ordering to apply on this operation.
5678
/// - Returns: A tuple with the old value before the operation a the new value
5779
/// after the operation.
58-
@available(SwiftStdlib 5.10, *)
80+
@available(SwiftStdlib 5.11, *)
5981
@discardableResult
6082
@_semantics("atomics.requires_constant_orderings")
6183
@_alwaysEmitIntoClient
6284
@_transparent
6385
public func logicalAnd(
64-
with operand: Bool,
86+
_ operand: Bool,
6587
ordering: AtomicUpdateOrdering
6688
) -> (oldValue: Bool, newValue: Bool) {
67-
// If we could reinterpret self as `Atomic<UInt8>` then we could just call
68-
// bitwiseAnd...
89+
let builtinOperand = Bool.encodeAtomicRepresentation(operand)._storage
6990

7091
let original = switch ordering {
7192
case .relaxed:
7293
Builtin.atomicrmw_and_monotonic_Int8(
7394
rawAddress,
74-
Bool.encodeAtomicRepresentation(operand).storage
95+
builtinOperand
7596
)
7697

7798
case .acquiring:
7899
Builtin.atomicrmw_and_acquire_Int8(
79100
rawAddress,
80-
Bool.encodeAtomicRepresentation(operand).storage
101+
builtinOperand
81102
)
82103

83104
case .releasing:
84105
Builtin.atomicrmw_and_release_Int8(
85106
rawAddress,
86-
Bool.encodeAtomicRepresentation(operand).storage
107+
builtinOperand
87108
)
88109

89110
case .acquiringAndReleasing:
90111
Builtin.atomicrmw_and_acqrel_Int8(
91112
rawAddress,
92-
Bool.encodeAtomicRepresentation(operand).storage
113+
builtinOperand
93114
)
94115

95116
case .sequentiallyConsistent:
96117
Builtin.atomicrmw_and_seqcst_Int8(
97118
rawAddress,
98-
Bool.encodeAtomicRepresentation(operand).storage
119+
builtinOperand
99120
)
100121

101122
default:
102123
Builtin.unreachable()
103124
}
104125

105-
let old = Bool.decodeAtomicRepresentation(_AtomicStorage8(original))
126+
let old = Bool.decodeAtomicRepresentation(UInt8.AtomicRepresentation(original))
106127

107128
return (oldValue: old, newValue: old && operand)
108129
}
@@ -114,51 +135,53 @@ extension Atomic where Value == Bool {
114135
/// - Parameter ordering: The memory ordering to apply on this operation.
115136
/// - Returns: A tuple with the old value before the operation a the new value
116137
/// after the operation.
117-
@available(SwiftStdlib 5.10, *)
138+
@available(SwiftStdlib 5.11, *)
118139
@discardableResult
119140
@_semantics("atomics.requires_constant_orderings")
120141
@_alwaysEmitIntoClient
121142
@_transparent
122143
public func logicalOr(
123-
with operand: Bool,
144+
_ operand: Bool,
124145
ordering: AtomicUpdateOrdering
125146
) -> (oldValue: Bool, newValue: Bool) {
147+
let builtinOperand = Bool.encodeAtomicRepresentation(operand)._storage
148+
126149
let original = switch ordering {
127150
case .relaxed:
128151
Builtin.atomicrmw_or_monotonic_Int8(
129152
rawAddress,
130-
Bool.encodeAtomicRepresentation(operand).storage
153+
builtinOperand
131154
)
132155

133156
case .acquiring:
134157
Builtin.atomicrmw_or_acquire_Int8(
135158
rawAddress,
136-
Bool.encodeAtomicRepresentation(operand).storage
159+
builtinOperand
137160
)
138161

139162
case .releasing:
140163
Builtin.atomicrmw_or_release_Int8(
141164
rawAddress,
142-
Bool.encodeAtomicRepresentation(operand).storage
165+
builtinOperand
143166
)
144167

145168
case .acquiringAndReleasing:
146169
Builtin.atomicrmw_or_acqrel_Int8(
147170
rawAddress,
148-
Bool.encodeAtomicRepresentation(operand).storage
171+
builtinOperand
149172
)
150173

151174
case .sequentiallyConsistent:
152175
Builtin.atomicrmw_or_seqcst_Int8(
153176
rawAddress,
154-
Bool.encodeAtomicRepresentation(operand).storage
177+
builtinOperand
155178
)
156179

157180
default:
158181
Builtin.unreachable()
159182
}
160183

161-
let old = Bool.decodeAtomicRepresentation(_AtomicStorage8(original))
184+
let old = Bool.decodeAtomicRepresentation(UInt8.AtomicRepresentation(original))
162185

163186
return (oldValue: old, newValue: old || operand)
164187
}
@@ -170,51 +193,53 @@ extension Atomic where Value == Bool {
170193
/// - Parameter ordering: The memory ordering to apply on this operation.
171194
/// - Returns: A tuple with the old value before the operation a the new value
172195
/// after the operation.
173-
@available(SwiftStdlib 5.10, *)
196+
@available(SwiftStdlib 5.11, *)
174197
@discardableResult
175198
@_semantics("atomics.requires_constant_orderings")
176199
@_alwaysEmitIntoClient
177200
@_transparent
178201
public func logicalXor(
179-
with operand: Bool,
202+
_ operand: Bool,
180203
ordering: AtomicUpdateOrdering
181204
) -> (oldValue: Bool, newValue: Bool) {
205+
let builtinOperand = Bool.encodeAtomicRepresentation(operand)._storage
206+
182207
let original = switch ordering {
183208
case .relaxed:
184209
Builtin.atomicrmw_xor_monotonic_Int8(
185210
rawAddress,
186-
Bool.encodeAtomicRepresentation(operand).storage
211+
builtinOperand
187212
)
188213

189214
case .acquiring:
190215
Builtin.atomicrmw_xor_acquire_Int8(
191216
rawAddress,
192-
Bool.encodeAtomicRepresentation(operand).storage
217+
builtinOperand
193218
)
194219

195220
case .releasing:
196221
Builtin.atomicrmw_xor_release_Int8(
197222
rawAddress,
198-
Bool.encodeAtomicRepresentation(operand).storage
223+
builtinOperand
199224
)
200225

201226
case .acquiringAndReleasing:
202227
Builtin.atomicrmw_xor_acqrel_Int8(
203228
rawAddress,
204-
Bool.encodeAtomicRepresentation(operand).storage
229+
builtinOperand
205230
)
206231

207232
case .sequentiallyConsistent:
208233
Builtin.atomicrmw_xor_seqcst_Int8(
209234
rawAddress,
210-
Bool.encodeAtomicRepresentation(operand).storage
235+
builtinOperand
211236
)
212237

213238
default:
214239
Builtin.unreachable()
215240
}
216241

217-
let old = Bool.decodeAtomicRepresentation(_AtomicStorage8(original))
242+
let old = Bool.decodeAtomicRepresentation(UInt8.AtomicRepresentation(original))
218243

219244
return (oldValue: old, newValue: old != operand)
220245
}

0 commit comments

Comments
 (0)