http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54005

--- Comment #7 from Andrew Macleod <amacleod at redhat dot com> 2012-08-14 
13:45:50 UTC ---
If NULL is passed as the second parameter, *both* functions are per type.  They
only become per-object based when an object is actually passed as the second
parameter.   libstdc++ could simply pass NULL as the second parameter rather
than the object, but it shouldn't matter since the C11/C++11 types will have
the atomic attribute set and thus will always be either lock free or not
anyway.  We don't even look at the object pointer in this case. 

Type and size are combined by the first parameter, so the meaning is now
changed to whether something {is|always} lock free for a type of SIZE with the
new atomic attribute (which is to be added soonish).  Since both C++11 and C11
will have the atomic attribute set on memory for their atomic types, this will
work fine.  

If the memory does not have the atomic attribute, then the answer can only be
resolved by using the (second parameter) pointer to the actual object. We'll
look at the type at compile time to see if the size/alignment of that type is
always good, and proceed from there to either generate instructions or call
into libatomic.

__atomic_is_lock_free() is the compiler implementation of the standard method.
This is the one which *must* be used since then answer cannot always be
provided at compile time.  The library MAY provide a lock free implementation
for a type which the compiler cannot, and thus a type may be always lock free
at runtime even if it isn't at compile time.  Thats why the query exists. 
Think of an old binary running on new hardware that provides new lock free
instructions which are utilized in a new library.  __atomic_always_lock_free()
would return the incorrect result and lock free algorithms wouldn't be able to
utilize the new instructions.

__atomic_always_lock_free() is a compiler creation to answer the question of
whether we know at compile time if a type/object is always lock free or not.
This is then resolved early in compilation so the preprocessor can resolve the
set of predefined ATOMIC_*_LOCK_FREE macros.  It is *identical* to
__atomic_is_lock_free except resolves to a FALSE at compile time rather than
turning into a call into libatomic.  

In fact, the compiler implements __atomic_is_lock_free() by (paraphrased):

  if (__atomic_always_lock_free (size, ptr))
    return TRUE;
  else
    emit_call_to_atomic_is_lock_free(size, ptr)



So if a code change is desired (but it isn't required), the 2nd parameter could
be passed as NULL to __atomic_is_lock_free().

Reply via email to