Fwd: Re: GCC libatomic questions

Richard Henderson rth@redhat.com
Wed Jul 6 19:41:00 GMT 2016


> 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~



More information about the Gcc mailing list