It began so innocently. My object needed to track the number of calls to begin and end methods for observing another object. It would only stop observing when those calls were balanced. To do this I had to implement a thread-safe counter. In the past you might use OSAtomicIncrement32Barrier and OSAtomicDecrement32Barrier which safely increments and decrements a 32 bit value.

Int32 counter = 0; OSAtomicIncrement32Barrier(&counter); OSAtomicDecrement32Barrier(&counter);

In C and Objective-C that is still usable, but deprecated. In Swift 4 it has been removed entirely. C11 introduced atomics as a language feature, which is what should be used moving forward.

_Atomic(int) counter = 0; atomic_fetch_add_explicit(&i, 1, memory_order_seq_cst); atomic_fetch_sub_explicit(&i, 1, memory_order_seq_cst);

…Which is not available to Swift 4, and there is no Swift equivalent. Now, normally this would be no big loss and would just be another thing that Swift is missing.

Most modern processors enforce strict ordering of access to memory. The order of things in your code is exactly the order things will be happening on the processor. For our counter and almost any other operation that requires thread-safe access to shared data that is pretty important. The order of memory access is not usually a source of problems until your code is running on a processor that has “weak” memory ordering.

ARM has weak memory ordering. The processor is free to re-order accesses to memory as it sees fit. That is a problem. For in-depth explanation of why, see here and here.

The (obvious?) solution is to bridge from Swift 4 to the missing C11 atomic functions. Lucky for us there is a library that can do this for us that was written pretty much how I would have written it myself.

But… that does not solve our problem. As it turns out even this is not safe (see developer forums thread 1 and thread 2). Swift still does not have a memory consistency model defined. Swift cannot guarantee memory ordering, even when calling C or Objective-C code from Swift.

So Swift 4 cannot guarantee memory ordering, has no memory barriers available, and even calling into C for these things is not guaranteed to work.

The core issue here is that without a well defined memory consistency model there may be no safe way to share data or communicate between threads in a Swift application.