CMPXCHG16B is not always available on 64-bit x86 platforms, so 16-byte
naturally aligned atomics are not inlineable. The support functions for
such atomics are free to use lock-free implementation if the instruction
is available on specific platforms.
Except that it is available on almost all 64-bit x86 platforms. As far as I
know, only 2004 era AMD processors didn't have it; all Intel 64-bit cpus have
supported it.
Further, gcc will most certainly make use of it when one specifies any
command-line option that enables it, such as -march=native.
Therefore we must specify that for x86_64, 16-byte objects are non-locking on
cpus that support cmpxchg16b.
However, if a compiler inlines an atomic operation on an _Atomic long
double object and uses the new lock-free instructions, it could break
the compatibility if the library implementation is still non-lock-free.
So such compiler change must be accompanied by a library change, and
the ABI must be updated as well.
The tie between gcc version and libgcc.so version is tight; I see no reason
that the libatomic.so version should not also be tight with the compiler version.
It is sufficient that libatomic use atomic instructions when they are
available. If a new processor comes out with new capabilities, the compiler
and runtime are upgraded in lock-step.
How that is selected is beyond the ABI but possible solutions are
(1) ld.so search path, based on processor capabilities,
(2) ifunc (or workalike) where the function is selected at startup,
(3) explicit runtime test within the relevant functions.
All solutions expose the same function interface so the function call ABI is
not affected.
_Bool __atomic_is_lock_free (size_t size, void *object);
Returns whether the object pointed to by object is lock-free.
The function assumes that the size of the object is size. If object
is NULL then the function assumes that object is aligned on an
size-byte address.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65033
The actual code change is completely within libstdc++, but it affects the
description of the libatomic function.
C++ requires that is_lock_free return the same result for all objects of a
given type. Whereas __atomic_is_lock_free, with a non-null object, determines
if we will implement lock free for a *specific* object, using the specific
object's alignment.
Rather than break the ABI and add a different function that passes the type
alignment, the solution we hit upon was to pass a "fake", minimally aligned
pointer as the object parameter: (void *)(uintptr_t)-__alignof(type).
The final component of the ABI that you've forgotten to specify, if you want
full compatibility of linked binaries, is symbol versioning.
We have had two ABI additions since the original release. See
https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libatomic/libatomic.map;h=39e7c2c6b9a70121b5f4031da346a27ae6c1be98;hb=HEAD
r~