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 143 144 145 146 147 148 149 150 151 152 153 154
|
//===----------------------------------------------------------------------===//
//
// 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
}
}
@available(*, unavailable)
extension _stdlib_AtomicInt: Sendable {}
@usableFromInline // used by SwiftPrivate._stdlib_AtomicInt
internal func _swift_stdlib_atomicCompareExchangeStrongInt(
object target: UnsafeMutablePointer<Int>,
expected: UnsafeMutablePointer<Int>,
desired: Int) -> Bool {
#if _pointerBitWidth(_64)
let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int64(
target._rawValue, expected.pointee._value, desired._value)
#elseif _pointerBitWidth(_32)
let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int32(
target._rawValue, expected.pointee._value, desired._value)
#else
#error("Unknown platform")
#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 _pointerBitWidth(_64)
let value = Builtin.atomicload_seqcst_Int64(target._rawValue)
return Int(value)
#elseif _pointerBitWidth(_32)
let value = Builtin.atomicload_seqcst_Int32(target._rawValue)
return Int(value)
#else
#error("Unknown platform")
#endif
}
@usableFromInline // used by SwiftPrivate._stdlib_AtomicInt
internal func _swift_stdlib_atomicStoreInt(
object target: UnsafeMutablePointer<Int>,
desired: Int) {
#if _pointerBitWidth(_64)
Builtin.atomicstore_seqcst_Int64(target._rawValue, desired._value)
#elseif _pointerBitWidth(_32)
Builtin.atomicstore_seqcst_Int32(target._rawValue, desired._value)
#else
#error("Unknown platform")
#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 _pointerBitWidth(_64)
let value = _swift_stdlib_atomicFetch${operation}Int64(
object: rawTarget.assumingMemoryBound(to: Int64.self),
operand: Int64(operand))
#elseif _pointerBitWidth(_32)
let value = _swift_stdlib_atomicFetch${operation}Int32(
object: rawTarget.assumingMemoryBound(to: Int32.self),
operand: Int32(operand))
#else
#error("Unknown platform")
#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
|