Skip to content

Commit d3e7d59

Browse files
authored
Merge pull request swiftlang#20290 from moiseev/atomic-int
[stdlib] Move _stdlib_AtomicInt and friends out of the stdlib
2 parents d8f06e5 + ca51626 commit d3e7d59

16 files changed

+225
-120
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2018 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+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import Swift
14+
15+
public final class _stdlib_AtomicInt {
16+
internal var _value: Int
17+
18+
internal var _valuePtr: UnsafeMutablePointer<Int> {
19+
return _getUnsafePointerToStoredProperties(self).assumingMemoryBound(
20+
to: Int.self)
21+
}
22+
23+
public init(_ value: Int = 0) {
24+
_value = value
25+
}
26+
27+
public func store(_ desired: Int) {
28+
return _swift_stdlib_atomicStoreInt(object: _valuePtr, desired: desired)
29+
}
30+
31+
public func load() -> Int {
32+
return _swift_stdlib_atomicLoadInt(object: _valuePtr)
33+
}
34+
35+
% for operation_name, operation in [ ('Add', '+'), ('And', '&'), ('Or', '|'), ('Xor', '^') ]:
36+
@discardableResult
37+
public func fetchAnd${operation_name}(_ operand: Int) -> Int {
38+
return _swift_stdlib_atomicFetch${operation_name}Int(
39+
object: _valuePtr,
40+
operand: operand)
41+
}
42+
43+
public func ${operation_name.lower()}AndFetch(_ operand: Int) -> Int {
44+
return fetchAnd${operation_name}(operand) ${operation} operand
45+
}
46+
% end
47+
48+
public func compareExchange(expected: inout Int, desired: Int) -> Bool {
49+
var expectedVar = expected
50+
let result = _stdlib_atomicCompareExchangeStrongInt(
51+
object: _valuePtr,
52+
expected: &expectedVar,
53+
desired: desired)
54+
expected = expectedVar
55+
return result
56+
}
57+
}
58+
59+
public func _swift_stdlib_atomicLoadInt(
60+
object target: UnsafeMutablePointer<Int>) -> Int {
61+
#if arch(i386) || arch(arm)
62+
let value = Builtin.atomicload_seqcst_Int32(target._rawValue)
63+
return Int(value)
64+
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
65+
let value = Builtin.atomicload_seqcst_Int64(target._rawValue)
66+
return Int(value)
67+
#endif
68+
}
69+
70+
public func _swift_stdlib_atomicStoreInt(
71+
object target: UnsafeMutablePointer<Int>,
72+
desired: Int) {
73+
#if arch(i386) || arch(arm)
74+
Builtin.atomicstore_seqcst_Int32(target._rawValue, desired._value)
75+
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
76+
Builtin.atomicstore_seqcst_Int64(target._rawValue, desired._value)
77+
#endif
78+
}
79+
80+
public func _stdlib_atomicCompareExchangeStrongInt(
81+
object target: UnsafeMutablePointer<Int>,
82+
expected: UnsafeMutablePointer<Int>,
83+
desired: Int) -> Bool {
84+
#if arch(i386) || arch(arm)
85+
let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int32(
86+
target._rawValue, expected.pointee._value, desired._value)
87+
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
88+
let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int64(
89+
target._rawValue, expected.pointee._value, desired._value)
90+
#endif
91+
expected.pointee._value = oldValue
92+
return Bool(won)
93+
}
94+
95+
% for operation in ['Add', 'And', 'Or', 'Xor']:
96+
// Warning: no overflow checking.
97+
public func _swift_stdlib_atomicFetch${operation}Int(
98+
object target: UnsafeMutablePointer<Int>,
99+
operand: Int) -> Int {
100+
let rawTarget = UnsafeMutableRawPointer(target)
101+
#if arch(i386) || arch(arm)
102+
let value = _swift_stdlib_atomicFetch${operation}Int32(
103+
object: rawTarget.assumingMemoryBound(to: Int32.self),
104+
operand: Int32(operand))
105+
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
106+
let value = _swift_stdlib_atomicFetch${operation}Int64(
107+
object: rawTarget.assumingMemoryBound(to: Int64.self),
108+
operand: Int64(operand))
109+
#endif
110+
return Int(value)
111+
}
112+
113+
% for bits in [ 32, 64 ]:
114+
115+
// Warning: no overflow checking.
116+
public func _swift_stdlib_atomicFetch${operation}Int${bits}(
117+
object target: UnsafeMutablePointer<Int${bits}>,
118+
operand: Int${bits}) -> Int${bits} {
119+
120+
let value = Builtin.atomicrmw_${operation.lower()}_seqcst_Int${bits}(
121+
target._rawValue, operand._value)
122+
123+
return Int${bits}(value)
124+
}
125+
126+
% end
127+
128+
% end
129+

stdlib/private/SwiftPrivate/CMakeLists.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1+
set(swift_swiftprivate_compile_flags
2+
"-parse-stdlib"
3+
"-Xfrontend" "-disable-access-control")
4+
15
add_swift_target_library(swiftSwiftPrivate ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_STDLIB
26
# This file should be listed the first. Module name is inferred from the
37
# filename.
48
SwiftPrivate.swift
9+
10+
AtomicInt.swift.gyb
511
IO.swift
612
ShardedAtomicCounter.swift
713

@@ -13,6 +19,6 @@ add_swift_target_library(swiftSwiftPrivate ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} I
1319
SWIFT_MODULE_DEPENDS_FREEBSD Glibc
1420
SWIFT_MODULE_DEPENDS_CYGWIN Glibc
1521
SWIFT_MODULE_DEPENDS_HAIKU Glibc
16-
SWIFT_COMPILE_FLAGS
22+
SWIFT_COMPILE_FLAGS ${swift_swiftprivate_compile_flags}
1723
INSTALL_IN_COMPONENT stdlib-experimental)
1824

stdlib/private/SwiftPrivate/IO.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
import Swift
1314
import SwiftShims
1415
import SwiftOverlayShims
1516

stdlib/private/SwiftPrivate/ShardedAtomicCounter.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
import Swift
1314
import SwiftShims
1415

1516
public func _stdlib_getHardwareConcurrency() -> Int {

stdlib/private/SwiftPrivate/SwiftPrivate.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
import Swift
1314
import SwiftShims
1415

1516
/// Convert the given numeric value to a hexadecimal string.

stdlib/public/core/Runtime.swift.gyb

Lines changed: 35 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -102,53 +102,24 @@ func _stdlib_atomicInitializeARCRef(
102102
return wonRace
103103
}
104104

105-
% for bits in [ 32, 64 ]:
106-
% for operation in ['Add', 'And', 'Or', 'Xor']:
107-
108-
// Warning: no overflow checking.
109-
@inlinable // FIXME(sil-serialize-all)
110-
internal func _swift_stdlib_atomicFetch${operation}Int${bits}(
111-
object target: UnsafeMutablePointer<Int${bits}>,
112-
operand: Int${bits}) -> Int${bits} {
113-
114-
let value = Builtin.atomicrmw_${operation.lower()}_seqcst_Int${bits}(
115-
target._rawValue, operand._value)
116-
117-
return Int${bits}(value)
118-
}
119-
120-
% end
121-
% end
122-
123-
@inlinable // FIXME(sil-serialize-all)
124-
internal func _stdlib_atomicCompareExchangeStrongInt(
125-
object target: UnsafeMutablePointer<Int>,
126-
expected: UnsafeMutablePointer<Int>,
127-
desired: Int) -> Bool {
128-
#if arch(i386) || arch(arm)
129-
let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int32(
130-
target._rawValue, expected.pointee._value, desired._value)
131-
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
132-
let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int64(
133-
target._rawValue, expected.pointee._value, desired._value)
134-
#endif
135-
expected.pointee._value = oldValue
136-
return Bool(won)
137-
}
138-
139-
@inlinable // FIXME(sil-serialize-all)
140-
internal func _swift_stdlib_atomicStoreInt(
141-
object target: UnsafeMutablePointer<Int>,
142-
desired: Int) {
143-
#if arch(i386) || arch(arm)
144-
Builtin.atomicstore_seqcst_Int32(target._rawValue, desired._value)
145-
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
146-
Builtin.atomicstore_seqcst_Int64(target._rawValue, desired._value)
147-
#endif
105+
@_transparent
106+
public // @testable
107+
func _stdlib_atomicLoadARCRef(
108+
object target: UnsafeMutablePointer<AnyObject?>
109+
) -> AnyObject? {
110+
let value = Builtin.atomicload_seqcst_Word(target._rawValue)
111+
if let unwrapped = UnsafeRawPointer(bitPattern: Int(value)) {
112+
return Unmanaged<AnyObject>.fromOpaque(unwrapped).takeUnretainedValue()
113+
}
114+
return nil
148115
}
149116

150-
@_transparent
151-
public func _swift_stdlib_atomicLoadInt(
117+
//===----------------------------------------------------------------------===//
118+
// These pieces are used in ThreadLocalStorage.swift in debug builds.
119+
// For tests, see similar functions from SwiftPrivate/AtomicInt.swift.gyb
120+
//===----------------------------------------------------------------------===//
121+
#if INTERNAL_CHECKS_ENABLED
122+
internal func _swift_stdlib_atomicLoadInt(
152123
object target: UnsafeMutablePointer<Int>) -> Int {
153124
#if arch(i386) || arch(arm)
154125
let value = Builtin.atomicload_seqcst_Int32(target._rawValue)
@@ -159,93 +130,40 @@ public func _swift_stdlib_atomicLoadInt(
159130
#endif
160131
}
161132

162-
@_transparent
163-
public // @testable
164-
func _stdlib_atomicLoadARCRef(
165-
object target: UnsafeMutablePointer<AnyObject?>
166-
) -> AnyObject? {
167-
let value = Builtin.atomicload_seqcst_Word(target._rawValue)
168-
if let unwrapped = UnsafeRawPointer(bitPattern: Int(value)) {
169-
return Unmanaged<AnyObject>.fromOpaque(unwrapped).takeUnretainedValue()
170-
}
171-
return nil
172-
}
133+
% for bits in [ 32, 64 ]:
173134

174-
% for operation in ['Add', 'And', 'Or', 'Xor']:
175135
// Warning: no overflow checking.
176136
@inlinable // FIXME(sil-serialize-all)
177-
public func _swift_stdlib_atomicFetch${operation}Int(
137+
internal func _swift_stdlib_atomicFetchAddInt${bits}(
138+
object target: UnsafeMutablePointer<Int${bits}>,
139+
operand: Int${bits}) -> Int${bits} {
140+
141+
let value = Builtin.atomicrmw_add_seqcst_Int${bits}(
142+
target._rawValue, operand._value)
143+
144+
return Int${bits}(value)
145+
}
146+
147+
% end
148+
149+
// Warning: no overflow checking.
150+
internal func _swift_stdlib_atomicFetchAddInt(
178151
object target: UnsafeMutablePointer<Int>,
179152
operand: Int) -> Int {
180153
let rawTarget = UnsafeMutableRawPointer(target)
181154
#if arch(i386) || arch(arm)
182-
let value = _swift_stdlib_atomicFetch${operation}Int32(
155+
let value = _swift_stdlib_atomicFetchAddInt32(
183156
object: rawTarget.assumingMemoryBound(to: Int32.self),
184157
operand: Int32(operand))
185158
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
186-
let value = _swift_stdlib_atomicFetch${operation}Int64(
159+
let value = _swift_stdlib_atomicFetchAddInt64(
187160
object: rawTarget.assumingMemoryBound(to: Int64.self),
188161
operand: Int64(operand))
189162
#endif
190163
return Int(value)
191164
}
192-
% end
193-
194-
@_fixed_layout // FIXME(sil-serialize-all)
195-
public final class _stdlib_AtomicInt {
196-
@usableFromInline // FIXME(sil-serialize-all)
197-
internal var _value: Int
198-
199-
@inlinable // FIXME(sil-serialize-all)
200-
internal var _valuePtr: UnsafeMutablePointer<Int> {
201-
return _getUnsafePointerToStoredProperties(self).assumingMemoryBound(
202-
to: Int.self)
203-
}
204-
205-
@inlinable // FIXME(sil-serialize-all)
206-
public init(_ value: Int = 0) {
207-
_value = value
208-
}
209-
210-
@inlinable // FIXME(sil-serialize-all)
211-
deinit {}
212-
213-
@inlinable // FIXME(sil-serialize-all)
214-
public func store(_ desired: Int) {
215-
return _swift_stdlib_atomicStoreInt(object: _valuePtr, desired: desired)
216-
}
217-
218-
@inlinable // FIXME(sil-serialize-all)
219-
public func load() -> Int {
220-
return _swift_stdlib_atomicLoadInt(object: _valuePtr)
221-
}
222-
223-
% for operation_name, operation in [ ('Add', '+'), ('And', '&'), ('Or', '|'), ('Xor', '^') ]:
224-
@inlinable // FIXME(sil-serialize-all)
225-
@discardableResult
226-
public func fetchAnd${operation_name}(_ operand: Int) -> Int {
227-
return _swift_stdlib_atomicFetch${operation_name}Int(
228-
object: _valuePtr,
229-
operand: operand)
230-
}
231-
232-
@inlinable // FIXME(sil-serialize-all)
233-
public func ${operation_name.lower()}AndFetch(_ operand: Int) -> Int {
234-
return fetchAnd${operation_name}(operand) ${operation} operand
235-
}
236-
% end
237-
238-
@inlinable // FIXME(sil-serialize-all)
239-
public func compareExchange(expected: inout Int, desired: Int) -> Bool {
240-
var expectedVar = expected
241-
let result = _stdlib_atomicCompareExchangeStrongInt(
242-
object: _valuePtr,
243-
expected: &expectedVar,
244-
desired: desired)
245-
expected = expectedVar
246-
return result
247-
}
248-
}
165+
#endif // INTERNAL_CHECKS_ENABLED
166+
//===----------------------------------------------------------------------===//
249167

250168
//===----------------------------------------------------------------------===//
251169
// Conversion of primitive types to `String`

0 commit comments

Comments
 (0)