Files
swift-mirror/stdlib/public/Synchronization/Atomics/AtomicBool.swift
Alejandro Alonso 66ec7abd54 Underscore some things, add explicit internal
Fix some compile issues
2024-06-04 09:06:37 -07:00

249 lines
7.4 KiB
Swift

//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2023 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
//
//===----------------------------------------------------------------------===//
import Builtin
//===----------------------------------------------------------------------===//
// Bool AtomicRepresentable conformance
//===----------------------------------------------------------------------===//
@available(SwiftStdlib 6.0, *)
extension Bool: AtomicRepresentable {
/// The storage representation type that `Self` encodes to and decodes from
/// which is a suitable type when used in atomic operations.
@available(SwiftStdlib 6.0, *)
public typealias AtomicRepresentation = UInt8.AtomicRepresentation
/// Destroys a value of `Self` and prepares an `AtomicRepresentation` storage
/// type to be used for atomic operations.
///
/// - Note: This is not an atomic operation. This simply encodes the logical
/// type `Self` into its storage representation suitable for atomic
/// operations, `AtomicRepresentation`.
///
/// - Parameter value: A valid instance of `Self` that's about to be destroyed
/// to encode an instance of its `AtomicRepresentation`.
/// - Returns: The newly encoded `AtomicRepresentation` storage.
@available(SwiftStdlib 6.0, *)
@_alwaysEmitIntoClient
@_transparent
public static func encodeAtomicRepresentation(
_ value: borrowing Bool
) -> AtomicRepresentation {
UInt8.encodeAtomicRepresentation(
UInt8(Builtin.zext_Int1_Int8(value._value))
)
}
/// Recovers the logical atomic type `Self` by destroying some
/// `AtomicRepresentation` storage instance returned from an atomic operation.
///
/// - Note: This is not an atomic operation. This simply decodes the storage
/// representation used in atomic operations back into the logical type for
/// normal use, `Self`.
///
/// - Parameter storage: The storage representation for `Self` that's used
/// within atomic operations.
/// - Returns: The newly decoded logical type `Self`.
@available(SwiftStdlib 6.0, *)
@_alwaysEmitIntoClient
@_transparent
public static func decodeAtomicRepresentation(
_ representation: consuming AtomicRepresentation
) -> Bool {
Bool(Builtin.trunc_Int8_Int1(
UInt8.decodeAtomicRepresentation(representation)._value)
)
}
}
//===----------------------------------------------------------------------===//
// Bool atomic operations
//===----------------------------------------------------------------------===//
@available(SwiftStdlib 6.0, *)
extension Atomic where Value == Bool {
/// Perform an atomic logical AND operation and return the old and new value,
/// applying the specified memory ordering.
///
/// - Parameter operand: A boolean value.
/// - Parameter ordering: The memory ordering to apply on this operation.
/// - Returns: A tuple with the old value before the operation a the new value
/// after the operation.
@available(SwiftStdlib 6.0, *)
@discardableResult
@_semantics("atomics.requires_constant_orderings")
@_alwaysEmitIntoClient
@_transparent
public func logicalAnd(
_ operand: Bool,
ordering: AtomicUpdateOrdering
) -> (oldValue: Bool, newValue: Bool) {
let builtinOperand = Bool.encodeAtomicRepresentation(operand)._storage
let original = switch ordering {
case .relaxed:
Builtin.atomicrmw_and_monotonic_Int8(
_rawAddress,
builtinOperand
)
case .acquiring:
Builtin.atomicrmw_and_acquire_Int8(
_rawAddress,
builtinOperand
)
case .releasing:
Builtin.atomicrmw_and_release_Int8(
_rawAddress,
builtinOperand
)
case .acquiringAndReleasing:
Builtin.atomicrmw_and_acqrel_Int8(
_rawAddress,
builtinOperand
)
case .sequentiallyConsistent:
Builtin.atomicrmw_and_seqcst_Int8(
_rawAddress,
builtinOperand
)
default:
Builtin.unreachable()
}
let old = Bool.decodeAtomicRepresentation(UInt8.AtomicRepresentation(original))
return (oldValue: old, newValue: old && operand)
}
/// Perform an atomic logical OR operation and return the old and new value,
/// applying the specified memory ordering.
///
/// - Parameter operand: A boolean value.
/// - Parameter ordering: The memory ordering to apply on this operation.
/// - Returns: A tuple with the old value before the operation a the new value
/// after the operation.
@available(SwiftStdlib 6.0, *)
@discardableResult
@_semantics("atomics.requires_constant_orderings")
@_alwaysEmitIntoClient
@_transparent
public func logicalOr(
_ operand: Bool,
ordering: AtomicUpdateOrdering
) -> (oldValue: Bool, newValue: Bool) {
let builtinOperand = Bool.encodeAtomicRepresentation(operand)._storage
let original = switch ordering {
case .relaxed:
Builtin.atomicrmw_or_monotonic_Int8(
_rawAddress,
builtinOperand
)
case .acquiring:
Builtin.atomicrmw_or_acquire_Int8(
_rawAddress,
builtinOperand
)
case .releasing:
Builtin.atomicrmw_or_release_Int8(
_rawAddress,
builtinOperand
)
case .acquiringAndReleasing:
Builtin.atomicrmw_or_acqrel_Int8(
_rawAddress,
builtinOperand
)
case .sequentiallyConsistent:
Builtin.atomicrmw_or_seqcst_Int8(
_rawAddress,
builtinOperand
)
default:
Builtin.unreachable()
}
let old = Bool.decodeAtomicRepresentation(UInt8.AtomicRepresentation(original))
return (oldValue: old, newValue: old || operand)
}
/// Perform an atomic logical XOR operation and return the old and new value,
/// applying the specified memory ordering.
///
/// - Parameter operand: A boolean value.
/// - Parameter ordering: The memory ordering to apply on this operation.
/// - Returns: A tuple with the old value before the operation a the new value
/// after the operation.
@available(SwiftStdlib 6.0, *)
@discardableResult
@_semantics("atomics.requires_constant_orderings")
@_alwaysEmitIntoClient
@_transparent
public func logicalXor(
_ operand: Bool,
ordering: AtomicUpdateOrdering
) -> (oldValue: Bool, newValue: Bool) {
let builtinOperand = Bool.encodeAtomicRepresentation(operand)._storage
let original = switch ordering {
case .relaxed:
Builtin.atomicrmw_xor_monotonic_Int8(
_rawAddress,
builtinOperand
)
case .acquiring:
Builtin.atomicrmw_xor_acquire_Int8(
_rawAddress,
builtinOperand
)
case .releasing:
Builtin.atomicrmw_xor_release_Int8(
_rawAddress,
builtinOperand
)
case .acquiringAndReleasing:
Builtin.atomicrmw_xor_acqrel_Int8(
_rawAddress,
builtinOperand
)
case .sequentiallyConsistent:
Builtin.atomicrmw_xor_seqcst_Int8(
_rawAddress,
builtinOperand
)
default:
Builtin.unreachable()
}
let old = Bool.decodeAtomicRepresentation(UInt8.AtomicRepresentation(original))
return (oldValue: old, newValue: old != operand)
}
}