The case for atomic types in programming languages

February 12, 2023

In My review of the C standard library in practice Chris Wellons says, as part of the overall discussion:

I’ve used the _Atomic qualifier in examples since it helps with conciseness, but I hardly use it in practice. In part because it has the inconvenient effect of bleeding into APIs and ABIs. As with volatile, C is using the type system to indirectly achieve a goal. Types are not atomic, loads and stores are atomic. [..]

Wellons is entirely correct here; at the CPU level (on current general purpose CPUs), specific operations are atomic, not specific storage locations. An atomic type is essentially a lie by the language. One language that originally embraced this reality is Go, which originally had no atomic types, only atomic access. On the other side is Rust; Rust has atomic types and a general discussion of atomic operation.

(In Go 1.19, Go added a number of atomic types, so now Go can be used with either approach.)

However, I feel that that the lie of atomic types is a genuine improvement in almost all cases, because of the increase in usability and safety. The problem with only having atomic operations is the same as with optional error checking; you have to remember to always use them, even if the types you're operating on can be used with ordinary operations. As we all know, people can forget this, or they can think that they're clever enough to use non-atomic operations in this one special circumstance that is surely harmless.

Like forced error handling (whether through exceptions or option/result types), having atomic types means that you don't have a choice. The language makes sure that they're always used safely, and you as the programmer are relieved of one more thing to worry about and try to keep track of. Atomic types may be a bit of a lie, but they're an ergonomic lie that improves safety.

The question of whether atomic types should be separate things (as in Rust) or be a qualifier on regular types (as in C) is something that you can argue over. It's clear that atomic types need extra operations because there are important atomic operations (like compare and swap) that have no non-atomic equivalent. I tend to think that atomic types should be there own thing because there are many standard operations that they can't properly support, at least not without potentially transforming simple code that you wrote into something much more complex. It's better to be honest about what atomic types can and can't do.

Sidebar: Why an atomic type qualifier has to bleed into APIs and ABIs

A type qualifier like C's _Atomic is a promise from the compiler to you that all (supported) operations on the object will be performed atomically. If you remove this qualifier as part of passing a variable around, you're removing this promise and now your atomic qualified thing might be accessed non-atomically. In other words, the atomic access is part of the API. It's not even necessarily safe to automatically promote a non-atomic object into being an atomic object as part of, say, a function call, because the code being called may reasonably assume that all access to the object is atomic.

Comments on this page:

By Andrew at 2023-02-13 21:21:29:

You could also say "integers aren't signed or unsigned inside the computer; multiplies and divides (and some loads and stores) are." But C has signed and unsigned integral types anyway.

By jonys at 2023-03-15 08:00:07:

The other major issue with the "atomic operation, not atomic type" view is portability – CPU and system architectures differ wrt. which types support which atomic operations, and when a particular type isn't supported (e.g. 64b atomic data access on 32b archs), the "atomic type" approach allows emulation of atomicity using attached locks. If you use an atomic op on a non-atomic type, there is no space to put the lock into.

Written on 12 February 2023.
« Learning about Linux fwmark masks
Our current plague of revolving .top and .click spam email domains »

Page tools: View Source, View Normal, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sun Feb 12 23:05:49 2023
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.