-
Notifications
You must be signed in to change notification settings - Fork 10.4k
/
Copy pathAtomicInt.swift.gyb
143 lines (123 loc) · 4.96 KB
/
AtomicInt.swift.gyb
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
// NOTE: older runtimes had Swift._stdlib_AtomicInt as the ObjC name.
// The two must coexist, so it was renamed. The old name must not be
// used in the new runtime. _TtCs18__stdlib_AtomicInt is the mangled
// name for Swift.__stdlib_AtomicInt
@available(swift, deprecated: 4.2, obsoleted: 5.0)
@_objcRuntimeName(_TtCs18__stdlib_AtomicInt)
public final class _stdlib_AtomicInt {
internal var _value: Int
internal var _valuePtr: UnsafeMutablePointer<Int> {
return _getUnsafePointerToStoredProperties(self).assumingMemoryBound(
to: Int.self)
}
public init(_ value: Int = 0) {
_value = value
}
public func store(_ desired: Int) {
return _swift_stdlib_atomicStoreInt(object: _valuePtr, desired: desired)
}
public func load() -> Int {
return _swift_stdlib_atomicLoadInt(object: _valuePtr)
}
% for operation_name, operation in [ ('Add', '+'), ('And', '&'), ('Or', '|'), ('Xor', '^') ]:
@discardableResult
public func fetchAnd${operation_name}(_ operand: Int) -> Int {
return _swift_stdlib_atomicFetch${operation_name}Int(
object: _valuePtr,
operand: operand)
}
public func ${operation_name.lower()}AndFetch(_ operand: Int) -> Int {
return fetchAnd${operation_name}(operand) ${operation} operand
}
% end
public func compareExchange(expected: inout Int, desired: Int) -> Bool {
var expectedVar = expected
let result = _swift_stdlib_atomicCompareExchangeStrongInt(
object: _valuePtr,
expected: &expectedVar,
desired: desired)
expected = expectedVar
return result
}
}
@usableFromInline // used by SwiftPrivate._stdlib_AtomicInt
internal func _swift_stdlib_atomicCompareExchangeStrongInt(
object target: UnsafeMutablePointer<Int>,
expected: UnsafeMutablePointer<Int>,
desired: Int) -> Bool {
#if arch(i386) || arch(arm)
let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int32(
target._rawValue, expected.pointee._value, desired._value)
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int64(
target._rawValue, expected.pointee._value, desired._value)
#endif
expected.pointee._value = oldValue
return Bool(won)
}
// FIXME: ideally it should not be here, at the very least not public, but
// @usableFromInline internal to be used by SwiftPrivate._stdlib_AtomicInt
public // Existing uses outside stdlib
func _swift_stdlib_atomicLoadInt(
object target: UnsafeMutablePointer<Int>) -> Int {
#if arch(i386) || arch(arm)
let value = Builtin.atomicload_seqcst_Int32(target._rawValue)
return Int(value)
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
let value = Builtin.atomicload_seqcst_Int64(target._rawValue)
return Int(value)
#endif
}
@usableFromInline // used by SwiftPrivate._stdlib_AtomicInt
internal func _swift_stdlib_atomicStoreInt(
object target: UnsafeMutablePointer<Int>,
desired: Int) {
#if arch(i386) || arch(arm)
Builtin.atomicstore_seqcst_Int32(target._rawValue, desired._value)
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
Builtin.atomicstore_seqcst_Int64(target._rawValue, desired._value)
#endif
}
% for operation in ['Add', 'And', 'Or', 'Xor']:
// Warning: no overflow checking.
// FIXME: ideally it should not be here, at the very least not public, but
// @usableFromInline internal to be used by SwiftPrivate._stdlib_AtomicInt
public // Existing uses outside stdlib
func _swift_stdlib_atomicFetch${operation}Int(
object target: UnsafeMutablePointer<Int>,
operand: Int) -> Int {
let rawTarget = UnsafeMutableRawPointer(target)
#if arch(i386) || arch(arm)
let value = _swift_stdlib_atomicFetch${operation}Int32(
object: rawTarget.assumingMemoryBound(to: Int32.self),
operand: Int32(operand))
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
let value = _swift_stdlib_atomicFetch${operation}Int64(
object: rawTarget.assumingMemoryBound(to: Int64.self),
operand: Int64(operand))
#endif
return Int(value)
}
% for bits in [ 32, 64 ]:
// Warning: no overflow checking.
@usableFromInline // used by SwiftPrivate._stdlib_AtomicInt
internal func _swift_stdlib_atomicFetch${operation}Int${bits}(
object target: UnsafeMutablePointer<Int${bits}>,
operand: Int${bits}) -> Int${bits} {
let value = Builtin.atomicrmw_${operation.lower()}_seqcst_Int${bits}(
target._rawValue, operand._value)
return Int${bits}(value)
}
% end
% end