[cfe-dev] atomic intrinsics

John McCall rjmccall at apple.com
Fri Oct 15 18:05:07 PDT 2010


On Oct 15, 2010, at 5:03 PM, Howard Hinnant wrote:
> Thanks for looking at this John.
> 
> On Oct 15, 2010, at 7:21 PM, John McCall wrote:
> 
>> On Oct 7, 2010, at 5:30 PM, Howard Hinnant wrote:
>>> I see what you mean.  I'll mention this in the design doc.  I believe it will be an issue for any design we choose (A, B, or C).
>> 
>> 
>> After some thought, I think I personally prefer proposal A, slightly modified such that __atomic_is_lock_free is a pseudofunction like __is_pod().
> 
> I see, like:
> 
>   bool __atomic_is_lock_free(type);
> 
> ?

That's what I was thinking.

>> The builtins have exactly those names and are "overloaded";  memory ordering parameters are required to be constant expressions but not necessarily literals.
> 
> If the memory orderings are required to be constant expressions, this is really Design B, just with some renaming.

I see what you mean.  I hadn't actually realized that the library actually takes these as runtime parameters;  that seems very un-C++-ish to me.  Certainly it's not very "pay for what you use", although I guess the presumption is that it will quickly optimize to the right thing.

> This is not a problem for libc++.  However I've heard rumblings that this won't be ok for the C library.  Want to comment Blaine?

Are the committees actually going to agree enough here to permit re-use?  The main advantage of requiring the parameters to be constant expressions is that the builtins don't become intimately tied to a specific library.  I'm very concerned about building compiler APIs on top of competing and incomplete standards.

If we accept this as a runtime argument, we will invoke undefined behavior on out-of-range enumerators.  Is that acceptable to C and C++?

>> Arguments not of fundamental type, or not exactly matching a permitted type for the intrinsic, are not required to be supported by the implementation (so calling swap with a long* and an int, or a Base** and a Derived*, or a ConvertibleToIntPtr and a ConvertibleToInt, may or may not have sensible results).
> 
> I'm afraid my spec is ambiguous, sorry.  In:
> 
> bool __atomic_compare_exchange_strong(type* atomic_obj,
>                                      type* expected, type desired,
>                                      int mem_success, int mem_failure);
> 
> It was my intention that in each argument that specifies "type", the types are all required to be the same.

Right, I just clarifying that.

>  In C++ templates, this would be:
> 
> template <class type>
> bool __atomic_compare_exchange_strong(type* atomic_obj,
>                                      type* expected, type desired,
>                                      int mem_success, int mem_failure);
> 
> Concerning arguments "type" that are not scalars: I believe I can handle this in libc++ with some fancy template meta programming, and pass them through to the front end type-punned as scalars if there is a scalar of the appropriate size, and otherwise route them to a library-lock function.  I can do this because "type" is a-priori known to be trivially copyable.

Okay.  If the libraries need to work with arbitrary trivially-copyable types, we should definitely do that in the builtins instead of in the library.  I'm willing to have the builtins take trivially-copyable types.

>> This doesn't strictly matter for you, but we would implement this in Clang by having the frontend do the ABI-compliant lowerings for the locking implementations and then emitting everything that can be done lock-free as an LLVM intrinsic call.
> 
> Does this translate to a call to compiler-rt for the locking implementations?  I ask because I'm probably going to be the one to implement these in compiler-rt if they are needed.

Multiple calls, I think;  an explicit acquire and release call.  Unless you think there's some benefit in having your compiler-rt function implement memcpy?

Note that these functions become platform ABI requirements.

John.



More information about the cfe-dev mailing list