This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Resolved status.
Section: 33.5.5 [atomics.lockfree] Status: Resolved Submitter: Jeffrey Yasskin Opened: 2009-06-16 Last modified: 2016-02-25
Priority: Not Prioritized
View all other issues in [atomics.lockfree].
View all issues with Resolved status.
Discussion:
Addresses US 88
The "lockfree" facilities do not tell the programmer enough.
There are 2 problems here.
First, at least on x86,
it's less important to me whether some integral types are lock free
than what is the largest type I can pass to atomic and have it be lock-free.
For example, if long longs are not lock-free,
ATOMIC_INTEGRAL_LOCK_FREE is probably 1,
but I'd still be interested in knowing whether longs are always lock-free.
Or if long longs at any address are lock-free,
I'd expect ATOMIC_INTEGRAL_LOCK_FREE to be 2,
but I may actually care whether I have access to
the cmpxchg16b
instruction.
None of the support here helps with that question.
(There are really 2 related questions here:
what alignment requirements are there for lock-free access;
and what processor is the program actually running on,
as opposed to what it was compiled for?)
Second, having atomic_is_lock_free only apply to individual objects is pretty useless (except, as Lawrence Crowl points out, for throwing an exception when an object is unexpectedly not lock-free). I'm likely to want to use its result to decide what algorithm to use, and that algorithm is probably going to allocate new memory containing atomic objects and then try to act on them. If I can't predict the lock-freedom of the new object by checking the lock-freedom of an existing object, I may discover after starting the algorithm that I can't continue.
[ 2009-06-16 Jeffrey Yasskin adds: ]
To solve the first problem, I think 2 macros would help: MAX_POSSIBLE_LOCK_FREE_SIZE and MAX_GUARANTEED_LOCK_FREE_SIZE, which expand to the maximum value of sizeof(T) for which atomic may (or will, respectively) use lock-free operations. Lawrence points out that this "relies heavily on implementations using word-size compare-swap on sub-word-size types, which in turn requires address modulation." He expects that to be the end state anyway, so it doesn't bother him much.
To solve the second, I think one could specify that equally aligned objects of the same type will return the same value from atomic_is_lock_free(). I don't know how to specify "equal alignment". Lawrence suggests an additional function, atomic_is_always_lock_free().
[ 2009-10-22 Benjamin Kosnik: ]
In the evolution discussion of N2925, "More Collected Issues with Atomics," there is an action item with respect to LWG 1146, US 88
This is stated in the paper as:
Relatedly, Mike Sperts will create an issue to propose adding a traits mechanism to check the compile-time properties through a template mechanism rather than macros
Here is my attempt to do this. I don't believe that a separate trait is necessary for this, and that instead atomic_integral::is_lock_free can be re-purposed with minimal work as follows.
[ Howard: Put Benjamin's wording in the proposed wording section. ]
[ 2009-10-22 Alberto Ganesh Barbati: ]
Just a thought... wouldn't it be better to use a scoped enum instead of plain integers? For example:
enum class is_lock_free { never = 0, sometimes = 1, always = 2; };if compatibility with C is deemed important, we could use an unscoped enum with suitably chosen names. It would still be more descriptive than 0, 1 and 2.
Previous resolution [SUPERSEDED]:
Header <cstdatomic> synopsis [atomics.synopsis]
Edit as follows:
namespace std { ... // 29.4, lock-free property#define ATOMIC_INTEGRAL_LOCK_FREE unspecified#define ATOMIC_CHAR_LOCK_FREE unspecified #define ATOMIC_CHAR16_T_LOCK_FREE unspecified #define ATOMIC_CHAR32_T_LOCK_FREE unspecified #define ATOMIC_WCHAR_T_LOCK_FREE unspecified #define ATOMIC_SHORT_LOCK_FREE unspecified #define ATOMIC_INT_LOCK_FREE unspecified #define ATOMIC_LONG_LOCK_FREE unspecified #define ATOMIC_LLONG_LOCK_FREE unspecified #define ATOMIC_ADDRESS_LOCK_FREE unspecifiedLock-free Property 33.5.5 [atomics.lockfree]
Edit the synopsis as follows.
namespace std {#define ATOMIC_INTEGRAL_LOCK_FREE unspecified#define ATOMIC_CHAR_LOCK_FREE unspecified #define ATOMIC_CHAR16_T_LOCK_FREE unspecified #define ATOMIC_CHAR32_T_LOCK_FREE unspecified #define ATOMIC_WCHAR_T_LOCK_FREE unspecified #define ATOMIC_SHORT_LOCK_FREE unspecified #define ATOMIC_INT_LOCK_FREE unspecified #define ATOMIC_LONG_LOCK_FREE unspecified #define ATOMIC_LLONG_LOCK_FREE unspecified #define ATOMIC_ADDRESS_LOCK_FREE unspecified }Edit paragraph 1 as follows.
The ATOMIC_...._LOCK_FREE macros
ATOMIC_INTEGRAL_LOCK_FREE and ATOMIC_ADDRESS_LOCK_FREEindicate the general lock-free property ofintegral and address atomicthe corresponding atomic integral types, with the signed and unsigned variants grouped together.The properties also apply to the corresponding specializations of the atomic template.A value of 0 indicates that the types are never lock-free. A value of 1 indicates that the types are sometimes lock-free. A value of 2 indicates that the types are always lock-free.Operations on Atomic Types 33.5.8.2 [atomics.types.operations]
Edit as follows.
voidstatic constexpr bool A::is_lock_free() const volatile;Returns: True if the
object'stypes's operations are lock-free, false otherwise. [Note: In the same way that <limits> std::numeric_limits<short>::max() is related to <limits.h> __LONG_LONG_MAX__, <atomic> std::atomic_short::is_lock_free is related to <stdatomic.h> and ATOMIC_SHORT_LOCK_FREE — end note]
[ 2009-10 Santa Cruz: ]
NAD EditorialResolved. Solved by N2992.
Proposed resolution:
Resolved by N2992.