Fundamentals 57 min read

Low‑Level Atomic Operations (SE‑0282) – Swift Atomics Overview

This article presents a comprehensive translation of the Swift Evolution proposal SE‑0282, detailing the design and implementation of low‑level atomic operations, memory orderings, and related types such as UnsafeAtomic and UnsafeAtomicLazyReference, providing examples and discussing integration with Swift’s concurrency model.

Sohu Tech Products
Sohu Tech Products
Sohu Tech Products
Low‑Level Atomic Operations (SE‑0282) – Swift Atomics Overview
Translator: Si Niang, iOS developer, member of the "老司机技术周报". Currently works at Gelonghui, interested in Swift and compiler‑related topics.

Introduction

Apple recently released swift‑atomics , allowing high‑performance lock‑free concurrent data structures to be written in pure Swift. This document translates the original proposal SE‑0282 "Low‑Level Atomic Operations" to help readers understand the design and usage of swift‑atomics .

The proposal was split into three parts: compiler changes, a private Swift‑only implementation, and the public Atomics package. The public package is independent of Swift’s ABI stability concerns.

Background

In Swift, synchronising shared mutable state across threads currently relies on DispatchQueue or NSLocking . To become a systems programming language, Swift needs low‑level atomic primitives that can be used directly in lock‑free data structures.

Atomic values provide two essential capabilities:

Introduce a set of new types that give explicit semantics for concurrent accesses, a concept previously missing in Swift.

Require an explicit memory ordering parameter for each atomic operation, allowing developers to reason about the ordering of memory effects across threads.

Solution Overview

The proposal adopts a C++‑style memory model with five ordering levels (relaxed, acquire, release, acquire‑release, sequentially‑consistent). All atomic operations require an ordering argument, encouraging developers to think carefully about the required guarantees.

Atomic Module

The core type is UnsafeAtomic<Value> , where Value conforms to the internal AtomicProtocol . The type provides six basic atomic operations (load, store, exchange, compareExchange, compareExchange with separate success/failure orderings, and weakCompareExchange) and a set of convenience integer operations for types that also conform to AtomicInteger .

import
Atomics
import
Dispatch
let
counter =
UnsafeAtomic
<
Int
>.create(initialValue:
0
)
DispatchQueue
.concurrentPerform(iterations:
10
) { _ in
for
_ in
0
..
1_000_000
{
    counter.wrappingIncrement(ordering: .relaxed)
  }
}
print
(counter.load(ordering: .relaxed))
counter
.destroy()

For integer types, additional methods such as loadThenWrappingIncrement , wrappingIncrementThenLoad , and bitwise variants are provided, mirroring the semantics of C++ atomic fetch‑add, fetch‑and, etc.

Atomic Memory Orderings

The ordering structs are modelled as frozen types with static properties:

@frozen public struct AtomicLoadOrdering: Equatable, Hashable, CustomStringConvertible {
  public static var relaxed: Self { get }
  public static var acquiring: Self { get }
  public static var sequentiallyConsistent: Self { get }
}

@frozen public struct AtomicStoreOrdering: Equatable, Hashable, CustomStringConvertible {
  public static var relaxed: Self { get }
  public static var releasing: Self { get }
  public static var sequentiallyConsistent: Self { get }
}

@frozen public struct AtomicUpdateOrdering: Equatable, Hashable, CustomStringConvertible {
  public static var relaxed: Self { get }
  public static var acquiring: Self { get }
  public static var releasing: Self { get }
  public static var acquiringAndReleasing: Self { get }
  public static var sequentiallyConsistent: Self { get }
}

A global function atomicMemoryFence(ordering:) provides a fence that is not tied to a specific atomic operation.

Atomic Protocols

The internal AtomicProtocol defines the mapping between a value type and its storage representation. Standard library types such as all fixed‑width integers, pointers, unmanaged references, and optional‑wrapped variants conform to this protocol. Users can obtain atomic support for custom RawRepresentable enums by relying on a default implementation that forwards to the raw value’s atomic storage.

UnsafeAtomicLazyReference

For cases where a lazily‑initialised optional reference is needed, UnsafeAtomicLazyReference<Instance> provides storeIfNilThenLoad and load operations. The type is used internally by the standard library for the lazy bridge of Array , Dictionary , and Set .

public struct UnsafeAtomicLazyReference<Instance: AnyObject> {
  public typealias Value = Instance?
  @frozen public struct Storage {
    public init()
    @discardableResult public mutating func dispose() -> Value
  }
  public init(at address: UnsafeMutablePointer
)
  public static func create() -> Self
  @discardableResult public func destroy() -> Value
  public func storeIfNil(_ desired: __owned Instance) -> Instance
  public func load() -> Instance?
}

Interaction with Existing Language Features

Exclusivity rule amendment : The proposal clarifies that two overlapping accesses to the same variable are allowed if both are atomic accesses, otherwise they remain a violation of Swift’s exclusivity model.

Non‑instantaneous accesses : Mutating methods such as sort() are still considered a single long write access, and atomic operations cannot be mixed with non‑atomic accesses to the same memory location without undefined behaviour.

Design Details

All atomic functions are marked @inlinable so that the compiler can emit the appropriate hardware instruction directly. The proposal does not affect ABI stability because the new types live in a separate Atomics module and are not part of the stable Swift standard library ABI.

Future Directions

Introduce memory‑safe, non‑copiable atomic types once the Ownership Manifesto is implemented.

Add double‑word atomics to solve the ABA problem and enable lock‑free pointer algorithms.

Provide atomic strong references with proper memory‑reclamation strategies.

Explore additional ordering variants (e.g., consume, volatile) and platform‑specific atomic extensions.

concurrencySwiftLow-level programmingatomic operationsmemory-ordering
Sohu Tech Products
Written by

Sohu Tech Products

A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.