Created
February 23, 2026 01:59
-
-
Save timboudreau/fc407172405299cc4a5c160d64567bf4 to your computer and use it in GitHub Desktop.
An atomic object reference in Swift (using Rust for the actual atomic operations)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /// An atomic reference to an object. | |
| public final class SwiftAtomicReference<T : AnyObject> : @unchecked Sendable where T: Sendable { | |
| private let pointer: UnsafeMutablePointer<size_t> | |
| public var value : T { | |
| get { | |
| load() | |
| } set(val) { | |
| store(val) | |
| } | |
| } | |
| public init(_ initialValue: T) { | |
| pointer = UnsafeMutablePointer<Int>.allocate(capacity: 1) | |
| let raw = Unmanaged.passRetained(initialValue).toOpaque() | |
| pointer.initialize(to: size_t(bitPattern: raw)) | |
| } | |
| // Load the stored value, with sequentially consistent semantics. | |
| public func load() -> T { | |
| let raw = UnsafeRawPointer(bitPattern: load_usize_atomic_strong(pointer))! | |
| return Unmanaged<T>.fromOpaque(raw).takeUnretainedValue() | |
| } | |
| // Replace the stored value with the passed one atomically, with sequentially consistent semantics. | |
| public func store(_ newValue: T) { | |
| let newRaw = Unmanaged.passRetained(newValue).toOpaque() | |
| let oldRaw = exchange_usize_atomic_strong(size_t(bitPattern: newRaw), pointer) | |
| Unmanaged<T>.fromOpaque(UnsafeRawPointer(bitPattern: oldRaw)!).release() | |
| } | |
| // Exchanged the stored value and the passed one atomically, with sequentially consistent semantics. | |
| public func exchange(with newValue: T) -> T { | |
| let newRaw = Unmanaged.passRetained(newValue).toOpaque() | |
| let oldRaw = exchange_usize_atomic_strong(size_t(bitPattern: newRaw), pointer) | |
| return Unmanaged<T>.fromOpaque(UnsafeRawPointer(bitPattern: oldRaw)!).takeRetainedValue() | |
| } | |
| deinit { | |
| let raw = UnsafeRawPointer(bitPattern: load_usize_atomic_strong(pointer))! | |
| Unmanaged<T>.fromOpaque(raw).release() | |
| pointer.deallocate() | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment