This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Fwd: Re: GCC libatomic questions


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~


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]