Atomics

So we actually experimented with a different approach where the orderings are overloads and have static properties that return values of the thing:

public enum AtomicMemoryOrdering {
  public struct Relaxed {
    public static var relaxed: Relaxed {
      Relaxed()
    }
  }

  ...
}

extension Atomic where Value.AtomicRepresentation == AtomicIntNNStorage {
  public borrowing func load(
    ordering: AtomicMemoryOrdering.Relaxed
  ) -> Value {
    // No switch statement, there's only a single kind of atomic op
    // that this overload could be.
  }
}

In fact this is what the initial implementation does.

I think this approach has several benefits. Each overload has a single canonical atomic operation because of both the combination of the specific atomic storage extension (which gives us the size of the atomic op) and the ordering overload. We preserve the nice "enum-like" API when using these operations and we'd only have overloads to each ordering that is supported (this was already the case with AtomicLoadOrdering and such, but atomicMemoryFence wouldn't have a relaxed overload resolving the no op case you mentioned @wadetregaskis ). Additionally, we can remove any special handling done by the compiler for applications of these functions to make sure the orderings are constant expressions (which is not itself a bad thing, but it does feel a little better to be less magical).The big reason why this approach is desirable in my mind is that in debug builds there's no question about whether the optimizer will eliminate the ordering switch statement. The switch statement doesn't exist. Of course this does put more pressure on the type checker to resolve the overload, but we always get either a right or wrong answer from the type checker vs. the optimizer giving us right, wrong, and technically right but not what we wanted. (In fact in debug clang doesn't eliminate the memory ordering switch for std::atomic in -O0 Compiler Explorer)

Considering this, I'm going to update the proposal to support this design to align with what's currently implemented.

4 Likes