# \[Accepted with modifications\] SE-0410: Atomics

**URL:** <https://forums.swift.org/t/accepted-with-modifications-se-0410-atomics/69244>\
**Category:** Announcements\
**Created:** [January 3, 2024, 1:50am UTC](https://forums.swift.org/t/accepted-with-modifications-se-0410-atomics/69244 "2024-01-03T01:50:33Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [January 3, 2024, 1:50am UTC](https://forums.swift.org/t/accepted-with-modifications-se-0410-atomics/69244/1 "2024-01-03T01:50:33Z")

</div>

The [second review of SE-0410: Atomics](https://forums.swift.org/t/second-review-se-0410-atomics/68810/132) ended on January 2, 2024, and the Language Steering Group has decided to **accept the proposal with modifications** to the protocol names, but otherwise accepting as proposed.

## Naming changes

The proposal reuses names from the `swift-atomics` package where possible to minimize migration cost for existing developers. The Language Steering Group does not foresee name changes to protocols, types, and methods as being an insurmountable issue for developers, so although the ease of that migration is a valid concern, we would like to prioritize establishing the best name possible for these new APIs. We accept the proposal with the **following name changes** :

- The `AtomicValue` protocol shall be named `AtomicRepresentable`.
- The `AtomicOptionalWrappable` protocol shall be named `AtomicOptionalRepresentable`.

Review discussion raised a number of alternatives, but the Language Steering Group noted that `AtomicValue`’s requirements all contain the string `AtomicRepresentation` in their names, and likewise `AtomicOptionalWrappable`’s requirement names all contain `AtomicOptionalRepresentation`, so adopting the `-able` variant of those suffixes keeps these protocol names related both to each other and to their requirement names.

Reviewers also explored the naming of the following APIs, which we **accept as is** from the proposal, as well as any other names not specifically mentioned:

- The `Atomic<T>` type should be named `Atomic` with no additional qualifiers, such as `ManagedAtomic`, `UnsafeAtomic`, `InlineAtomic` or anything like that.
- The module in which `Atomic` and its related API will be placed will be called `Synchronization`. Module name collisions are something that Swift does not provide good tools for mitigating, and naming the standard module `Atomics` would create such a collision with existing `swift-atomics` code that is important to avoid. The name `Synchronization` also allows the module to be a natural place to put other low-level synchronization primitives that we might not want to be generally available in the default-imported `Swift` module, such as raw locks, semaphores, condition variables, and the like.
- `WordPair` belongs in the `Synchronization` module alongside the atomic APIs. The Steering Group believes its use should be tied to supporting double-wide atomics. Being in an explicitly-imported module somewhat mitigates concerns about code completion pollution when developers reach for `Double`, which was an argument for changing the name from `DoubleWord` as used by the `swift-atomics` module. However, the Language Steering Group believes that `WordPair` is a better name than `DoubleWord` on its own merits. WordPair emphasizes that the value is a pair of not-necessarily-related values, and the phrase "double word" has other common meanings, particularly its use on Windows to specifically mean a 32-bit value due to the platform's history.

## Interactions with the ownership and exclusivity model

A lot of the discussion centered on the way atomics fit into the ownership model. Almost all of the `Atomic` type’s API is `borrowing`, because atomic operations are meant to be safe even when multiple operations happen simultaneously so exclusive access isn’t necessary. This has the surprising implication that an atomic’s contained value can be updated even when it appears in a `let` property or as part of an otherwise-immutable aggregate. For most types, the borrow model and the law of exclusivity govern whether a value is immutable or mutable, but atomics and other concurrency primitives reveal that the more fundamental property being governed is shared vs. exclusive access. Atomics don’t require exclusive access in order to be updated, and enforcing exclusivity by our usual non-thread-safe mechanism would be counterproductive and introduce unsafety, so in the vast majority of cases atomic properties ought to be declared as `let` properties.

Since there’ll be a natural inclination to think of atomics as being mutable and incorrectly declare them as `var`, the proposal includes a provision to raise a diagnostic preventing `var` declarations of `Atomic` type. There was vigorous debate over how much this expansion compromises the core promises of the language, how APIs can separate mutating and nonmutating access to their atomic state, and whether we should consider an alternative model. We could for instance say that `var x: Atomic` is treated as a shared-borrows-only declaration despite the `var`, and only allow atomic update operations on atomic fields visible as `var`. These alternative schemes break down in the face of abstraction and composition, though, since the special behavior of `Atomic` under ownership is still present when `Atomic` is used as a generic parameter or appears as a component of a noncopyable struct or enum. We would have to introduce new generic constraints and/or transitive type properties to mark these “atomically updatable” types separately in order to keep atomics and similar concurrent types fully separated from “normal” types. On the other hand, the “immutable vs. mutable really means shared vs. exclusive”model as proposed works within the framework we already have without surfacing a new end-user-level language concept. It also follows the footsteps of Rust, where atomics have behaved like this from before Rust 1.0, and Rust’s atomics don’t seem to have caused any catastrophic effects or lasting confusion in that community. The Language Steering Group believes that this is the right model for Swift as well, and **accepts this aspect of the proposal as is**.

## Should `Atomic` never, sometimes, or always be `Sendable`?

The proposal states that `Atomic` conditionally conforms to `Sendable` when its element type does. Review discussion argued against this in both directions: some folks argued that atomics in any circumstance are a “you know what you’re doing” feature, and raw exposure to atomics would never meet the safety bar for fearless concurrency we’re trying to reach with Sendable checking and isolation control, therefore `Atomic` should never be `Sendable` and should always have to be marked, either inside of a containing type that declares itself as `@unchecked Sendable` or as a `nonisolated(unsafe)` field, an “I think I know what I’m doing, AUDITORS LOOK HERE” trail in the code. On the other hand, `Atomic`’s very purpose is to be shared across threads, and the programmer already has to take intentional steps importing the `Synchronization` module and writing `Atomic` into their code to use atomics. Having `Atomic` ever not be `Sendable` in that view arguably imposes additional busywork on nearly every use of the type for little practical safety gain. Rust in particular takes this permissive approach, where even though their unsafe pointer types `*T` and `*mut T` do not have the `Send` trait, their `AtomicPtr` type does unconditionally have the `Send` trait, based on the notion that you’re already in `unsafe` land and outside of the language’s protection.

Based on community feedback, the Language Steering Group has decided to **accept the proposal as is** , leaving the `Atomic` type as `Sendable` only when the contained type is. The authors of the proposal as well as existing users of the `swift-atomics` package had noted that their use of the package’s atomic types generally coincides with the need for `@unchecked Sendable` for reasons outside of the use of atomics, and that the sendability or lack thereof of `Atomic` itself has not been a major issue in their development. There was also strong concern that making `Atomic` always `Sendable` would make it too large of a hole in the concurrency model, allowing arbitrary values to be improperly shared across threads through an `Atomic<UnsafePointer<T>>` even when `T` itself isn’t `Sendable`. If `Atomic` is `Sendable`, then it’s also readily usable with Swift’s higher-level concurrency language features, such as being able to appear as a `nonisolated let` field of an `actor`. Having this “just work” for pointers or other non-sendable types without any warning is likely too big a hole. On the other hand, a field of `Atomic<Int>` or other sendable type could be useful as a way of storing counters or other atomic-update-sized values in an actor that can be accessed independently without acquiring the actor’s execution context. Although even these simple-seeming uses of atomics require manual care to get right, such as ensuring matching ordering between readers and writers, an ABA problem with a numeric value is not a direct memory safety error like it would be with a pointer (unless it is used with unsafe operations, such as converting an integer to and from a pointer), and as such isn’t “unsafe” as the standard library generally uses the term. As such, we believe the proposal as written strikes the correct balance, leaving `Atomic` as `Sendable` only when the contained type is.

Thanks to everybody for participating in both rounds of review!

---

<div class="post-metadata">

**Author:** ![wadetregaskis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/wadetregaskis/32/8494_2.png) [@wadetregaskis](https://forums.swift.org/u/wadetregaskis)\
**Post date:** [January 3, 2024, 6:11am UTC](https://forums.swift.org/t/accepted-with-modifications-se-0410-atomics/69244/2 "2024-01-03T06:11:12Z")

</div>

It's good to see this conclude. As the length of the acceptance post suggests, this was a pretty tricky proposal; atomics are not a trivial addition to Swift and not nearly so simple as in lower-level languages like C. The conversation in the review thread was thought-provoking and (I think) very helpful. I appreciate the contributions of the reviewers, and of course the hard work of the proposal's authors. Thank you all!

---

<div class="post-metadata">

**Author:** ![scanon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/scanon/32/2445_2.png) [@scanon](https://forums.swift.org/u/scanon)\
**Post date:** [January 3, 2024, 12:15pm UTC](https://forums.swift.org/t/accepted-with-modifications-se-0410-atomics/69244/3 "2024-01-03T12:15:43Z")

</div>

> not nearly so simple as in lower-level languages like C

Not nearly so simple in C either if we’re honest … 😂

More seriously, yes, big thanks to @Alejandro and @Karoy_Lorentey for seeing this through.

---

<div class="post-metadata">

**Author:** ![benrimmington](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/benrimmington/32/695_2.png) [@benrimmington](https://forums.swift.org/u/benrimmington)\
**Post date:** [January 23, 2025, 4:04am UTC](https://forums.swift.org/t/accepted-with-modifications-se-0410-atomics/69244/4 "2025-01-23T04:04:33Z")

</div>

The following conformance wasn't implemented in Swift 6.0:

```swift
// NOTE: WordPair is semantically a (UInt, UInt). Tuple comparability
// works based of lexicographical ordering, so WordPair will do
// the same. It will compare 'first' first, and 'second' second.
extension WordPair: Comparable {...}

```

Should the [proposal](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0410-atomics.md) or [implementation](https://github.com/swiftlang/swift/blob/main/stdlib/public/Synchronization/Atomics/WordPair.swift) be amended?

---

<div class="post-metadata">

**Author:** ![Alejandro](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/alejandro/32/46197_2.png) [@Alejandro](https://forums.swift.org/u/Alejandro)\
**Post date:** [January 23, 2025, 6:51pm UTC](https://forums.swift.org/t/accepted-with-modifications-se-0410-atomics/69244/5 "2025-01-23T18:51:08Z")

</div>

This was an unfortunate overlook on my part. I've amended the implementation here: [[stdlib] Add Comparable conformance to WordPair by Azoy · Pull Request #78857 · swiftlang/swift · GitHub](https://github.com/swiftlang/swift/pull/78857). The conformance itself will have to have a higher availability than the type, but the `<` function can share the same availability as the one the type has.

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [February 3, 2025, 9:25pm UTC](https://forums.swift.org/t/accepted-with-modifications-se-0410-atomics/69244/6 "2025-02-03T21:25:44Z")

</div>

The LSG discussed this and agreed that this should just be added without any re-review, as we're still within a reasonable period for the "initial" implementation. The conformance needing a tighter deployment limitation than the type is unfortunate but ultimately something we have to live with.

This should get a release note, if we haven't added one yet.
