Skip to content

Commit 8b703fe

Browse files
committed
[native atomics] Fix alignment issues by reintroducing custom storage types
The SysV ABI defined uint64_t with 4 byte alignment on i386 — so we can’t just assume that the integer types will have the right alignment by default for atomics. Emulate the original `_Atomic<Width>Storage` types in the C shims even in native atomics configuration, so that they can carry a custom `@_alignment` attribute.
1 parent 9351ce0 commit 8b703fe

File tree

13 files changed

+1702
-3016
lines changed

13 files changed

+1702
-3016
lines changed

Sources/Atomics/Conformances/AtomicBool.swift.gyb

Lines changed: 47 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,17 @@
1616
}%
1717
${autogenerated_warning()}
1818

19-
#if !ATOMICS_NATIVE_BUILTINS
19+
#if ATOMICS_NATIVE_BUILTINS
20+
import Builtin
21+
22+
extension Bool {
23+
@_alwaysEmitIntoClient
24+
@_transparent
25+
internal init(_ builtin: Builtin.Int1) {
26+
self = unsafeBitCast(builtin, to: Bool.self)
27+
}
28+
}
29+
#else
2030
import _AtomicsShims
2131
#endif
2232

@@ -25,46 +35,42 @@ extension Bool: AtomicValue {
2535
public struct AtomicRepresentation {
2636
public typealias Value = Bool
2737

28-
#if ATOMICS_NATIVE_BUILTINS
29-
@usableFromInline
30-
internal typealias _Storage = Int8
31-
#else
3238
@usableFromInline
3339
internal typealias _Storage = _AtomicInt8Storage
34-
#endif
3540

3641
@usableFromInline
3742
internal var _storage: _Storage
3843

39-
@inline(__always) @_alwaysEmitIntoClient
44+
@_transparent @_alwaysEmitIntoClient
4045
public init(_ value: Bool) {
41-
#if ATOMICS_NATIVE_BUILTINS
42-
_storage = value._atomicValue
43-
#else
44-
_storage = _sa_prepare_Int8(value._atomicValue)
45-
#endif
46+
_storage = value._atomicRepresentation
4647
}
4748

48-
@inline(__always) @_alwaysEmitIntoClient
49+
@_transparent @_alwaysEmitIntoClient
4950
public func dispose() -> Value {
50-
#if ATOMICS_NATIVE_BUILTINS
51-
return _storage._atomicBoolValue
52-
#else
53-
return _sa_dispose_Int8(_storage)._atomicBoolValue
54-
#endif
51+
return _storage._decodeBool
5552
}
5653
}
5754

58-
@_alwaysEmitIntoClient @inline(__always)
59-
internal var _atomicValue: Int8 {
60-
self ? 1 : 0
55+
@_transparent @_alwaysEmitIntoClient
56+
internal var _atomicRepresentation: _AtomicInt8Storage {
57+
let v: Int8 = (self ? 1 : 0)
58+
#if ATOMICS_NATIVE_BUILTINS
59+
return .init(v._value)
60+
#else
61+
return _sa_prepare_Int8(v)
62+
#endif
6163
}
6264
}
6365

64-
extension Int8 {
65-
@_alwaysEmitIntoClient @inline(__always)
66-
internal var _atomicBoolValue: Bool {
67-
(self & 1) != 0
66+
extension _AtomicInt8Storage {
67+
@_transparent @_alwaysEmitIntoClient
68+
internal var _decodeBool: Bool {
69+
#if ATOMICS_NATIVE_BUILTINS
70+
return (Int8(self._value) & 1) != 0
71+
#else
72+
return (_sa_dispose_Int8(self) & 1) != 0
73+
#endif
6874
}
6975
}
7076

@@ -86,7 +92,7 @@ extension Bool.AtomicRepresentation: AtomicStorage {
8692
at pointer: UnsafeMutablePointer<Bool.AtomicRepresentation>,
8793
ordering: AtomicLoadOrdering
8894
) -> Bool {
89-
pointer._extract._atomicLoad(ordering: ordering)._atomicBoolValue
95+
pointer._extract._atomicLoad(ordering: ordering)._decodeBool
9096
}
9197

9298
@_semantics("atomics.requires_constant_orderings")
@@ -96,7 +102,8 @@ extension Bool.AtomicRepresentation: AtomicStorage {
96102
at pointer: UnsafeMutablePointer<Bool.AtomicRepresentation>,
97103
ordering: AtomicStoreOrdering
98104
) {
99-
pointer._extract._atomicStore(desired._atomicValue, ordering: ordering)
105+
pointer._extract._atomicStore(
106+
desired._atomicRepresentation, ordering: ordering)
100107
}
101108

102109
@_semantics("atomics.requires_constant_orderings")
@@ -107,8 +114,8 @@ extension Bool.AtomicRepresentation: AtomicStorage {
107114
ordering: AtomicUpdateOrdering
108115
) -> Bool {
109116
pointer._extract._atomicExchange(
110-
desired._atomicValue, ordering: ordering
111-
)._atomicBoolValue
117+
desired._atomicRepresentation, ordering: ordering
118+
)._decodeBool
112119
}
113120

114121
@_semantics("atomics.requires_constant_orderings")
@@ -120,10 +127,10 @@ extension Bool.AtomicRepresentation: AtomicStorage {
120127
ordering: AtomicUpdateOrdering
121128
) -> (exchanged: Bool, original: Bool) {
122129
let r = pointer._extract._atomicCompareExchange(
123-
expected: expected._atomicValue,
124-
desired: desired._atomicValue,
130+
expected: expected._atomicRepresentation,
131+
desired: desired._atomicRepresentation,
125132
ordering: ordering)
126-
return (r.exchanged, r.original._atomicBoolValue)
133+
return (r.exchanged, r.original._decodeBool)
127134
}
128135

129136
@_semantics("atomics.requires_constant_orderings")
@@ -136,11 +143,11 @@ extension Bool.AtomicRepresentation: AtomicStorage {
136143
failureOrdering: AtomicLoadOrdering
137144
) -> (exchanged: Bool, original: Bool) {
138145
let r = pointer._extract._atomicCompareExchange(
139-
expected: expected._atomicValue,
140-
desired: desired._atomicValue,
146+
expected: expected._atomicRepresentation,
147+
desired: desired._atomicRepresentation,
141148
successOrdering: successOrdering,
142149
failureOrdering: failureOrdering)
143-
return (r.exchanged, r.original._atomicBoolValue)
150+
return (r.exchanged, r.original._decodeBool)
144151
}
145152

146153
@_semantics("atomics.requires_constant_orderings")
@@ -153,11 +160,11 @@ extension Bool.AtomicRepresentation: AtomicStorage {
153160
failureOrdering: AtomicLoadOrdering
154161
) -> (exchanged: Bool, original: Bool) {
155162
let r = pointer._extract._atomicWeakCompareExchange(
156-
expected: expected._atomicValue,
157-
desired: desired._atomicValue,
163+
expected: expected._atomicRepresentation,
164+
desired: desired._atomicRepresentation,
158165
successOrdering: successOrdering,
159166
failureOrdering: failureOrdering)
160-
return (r.exchanged, r.original._atomicBoolValue)
167+
return (r.exchanged, r.original._decodeBool)
161168
}
162169
}
163170

@@ -183,8 +190,8 @@ extension Bool.AtomicRepresentation {
183190
ordering: AtomicUpdateOrdering
184191
) -> Value {
185192
pointer._extract._atomicLoadThen${iname}(
186-
${argLabel(label)}operand._atomicValue, ordering: ordering
187-
)._atomicBoolValue
193+
${argLabel(label)}operand._atomicRepresentation, ordering: ordering
194+
)._decodeBool
188195
}
189196
% end
190197
}

0 commit comments

Comments
 (0)