1460. Missing lock-free property for type bool should be added

Section: 32.5 [atomics.lockfree] Status: Resolved Submitter: INCITS Opened: 2010-08-25 Last modified: 2016-02-10

Priority: Not Prioritized

View all other issues in [atomics.lockfree].

View all issues with Resolved status.

Discussion:

Addresses US-154

There is no ATOMIC_BOOL_LOCK_FREE macro.

Proposed resolution suggested by the NB comment:

Add ATOMIC_BOOL_LOCK_FREE to 32.5 [atomics.lockfree] and to 32.2 [atomics.syn]:

[..]
#define ATOMIC_BOOL_LOCK_FREE unspecified
#define ATOMIC_CHAR_LOCK_FREE unspecified
#define ATOMIC_CHAR16_T_LOCK_FREE unspecified
#define ATOMIC_CHAR32_T_LOCK_FREE unspecified
[..]

[2011-03-12: Lawrence comments and drafts wording]

Point: We were missing a macro test for bool.

Comment: The atomic<bool> type is the easiest to make lock-free. There is no harm in providing a macro.

Action: Add an ATOMIC_BOOL_LOCK_FREE.

Point: We were missing a macro test for pointers.

Comment: The national body comment noting the missing macro for bool did not note the lack of a macro for pointers because ATOMIC_ADDRESS_LOCK_FREE was present at the time of the comment. Its removal appears to be an overzealous consequence of removing atomic_address.

Action: Add an ATOMIC_POINTER_LOCK_FREE.

Point: Presumably atomic_is_lock_free() will be an inline function producing a constant in those cases in which the macros are useful.

Comment: The point is technically correct, but could use some exposition. Systems providing forward binary compatibility, e.g. mainstream desktop and server systems, would likely have these functions as inline constants only when the answer is true. Otherwise, the function should defer to a platform-specific dynamic library to take advantage of future systems that do provide lock-free support.

Comment: Such functions are not useful in the preprocessor, and not portably useful in static_assert.

Action: Preserve the macros.

Point: The required explicit instantiations are atomic<X> for each of the types X in Table 145. Table 145 does not list bool, so atomic<bool> is not a required instantiation.

Comment: I think specialization was intended in the point instead of instantiation. In any event, 32.6 [atomics.types.generic] paragraph 5 does indirectly require a specialization for atomic<bool>. Confusion arises because the specialization for other integral types have a wider interface than the generic atomic<T>, but atomic<bool> does not.

Action: Add clarifying text.

Point: The name of Table 145, "atomic integral typedefs", is perhaps misleading, since the types listed do not contain all of the "integral" types.

Comment: Granted, though the table describe those with extra operations.

Action: Leave the text as is.

Point: The macros correspond to the types in Table 145, "with the signed and unsigned variants grouped together". That's a rather inartful way of saying that ATOMIC_SHORT_LOCK_FREE applies to signed short and unsigned short. Presumably this also means that ATOMIC_CHAR_LOCK_FREE applies to all three char types.

Comment: Yes, it is inartful.

Comment: Adding additional macros to distinguish signed and unsigned would provide no real additional information given the other constraints in the language.

Comment: Yes, it applies to all three char types.

Action: Leave the text as is.

Point: The standard says that "There are full specializations over the integral types (char, signed char, ...)" bool is not in the list. But this text is not normative. It simply tells you that "there are" specializations, not "there shall be" specializations, which would impose a requirement. The requirement, to the extent that there is one, is in the header synopsis, which, in N3242, sort of pulls in the list of types in Table 145.

Comment: The intent was for the specializations to be normative. Otherwise the extra member functions could not be present.

Action: Clarify the text.

[Proposed Resolution]

  1. Edit header <atomic> synopsis 32.2 [atomics.syn]:

    namespace std {
      // 29.3, order and consistency
      enum memory_order;
      template <class T>
      T kill_dependency(T y);
    
      // 29.4, lock-free property
      #define ATOMIC_BOOL_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_POINTER_LOCK_FREE unspecified
      
      // 29.5, generic types
      template<class T> struct atomic;
      template<> struct atomic<integral>;
      template<class T> struct atomic<T*>;
    
      // 29.6.1, general operations on atomic types
      // In the following declarations, atomic_type is either
      // atomic<T> or a named base class for T from
      // Table 145 or inferred from
      // Table 146 or from bool. 
    
      […]
    }
    
  2. Edit the synopsis of 32.5 [atomics.lockfree] and paragraph 1 as follows:

    #define ATOMIC_BOOL_LOCK_FREE unspecified
    #define ATOMIC_CHAR_LOCK_FREE implementation-definedunspecified
    #define ATOMIC_CHAR16_T_LOCK_FREE implementation-definedunspecified
    #define ATOMIC_CHAR32_T_LOCK_FREE implementation-definedunspecified
    #define ATOMIC_WCHAR_T_LOCK_FREE implementation-definedunspecified
    #define ATOMIC_SHORT_LOCK_FREE implementation-definedunspecified
    #define ATOMIC_INT_LOCK_FREE implementation-definedunspecified
    #define ATOMIC_LONG_LOCK_FREE implementation-definedunspecified
    #define ATOMIC_LLONG_LOCK_FREE implementation-definedunspecified
    #define ATOMIC_POINTER_LOCK_FREE unspecified
    

    1 The ATOMIC_…_LOCK_FREE macros indicate the lock-free property of the corresponding atomic types, with the signed and unsigned variants grouped together. The properties also apply to the corresponding (partial) 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.

  3. Edit 32.6 [atomics.types.generic] paragraph 3, 4, and 6-8 as follows:

    2 The semantics of the operations on specializations of atomic are defined in 32.6.1 [atomics.types.operations].

    3 Specializations and instantiations of the atomic template shall have a deleted copy constructor, a deleted copy assignment operator, and a constexpr value constructor.

    4 There areshall be full specializations overfor the integral types ( char, signed char, unsigned char, short, unsigned short, int, unsigned int, long, unsigned long, long long, unsigned long long, char16_t, char32_t, and wchar_t, and any other types needed by the typedefs in the header <cstdint>) on the atomic class template. For each integral type integral, the specialization atomic<integral> provides additional atomic operations appropriate to integral types. [Editor's note: I'm guessing that this is the correct rendering of the text in the paper; if this sentence was intended to impose a requirement, rather than a description, it will have to be changed.] There shall be a specialization atomic<bool> which provides the general atomic operations as specified in [atomics.types.operations.general].

    5 The atomic integral specializations and the specialization atomic<bool> shall have standard layout. They shall each have a trivial default constructor and a trivial destructor. They shall each support aggregate initialization syntax.

    6 There areshall be pointer partial specializations onof the atomic class template. These specializations shall have trivial default constructors and trivial destructors.

    7 There areshall be named types corresponding to the integral specializations of atomic, as specified in Table 145. In addition, there shall be named type atomic_bool corresponding to the specialization atomic<bool>. Each named type is either a typedef to the corresponding specialization or a base class of the corresponding specialization. If it is a base class, it shall support the same member functions as the corresponding specialization.

    8 There areshall be atomic typedefs corresponding to the typedefs in the header <inttypes.h> as specified in Table 146.

Proposed resolution:

Resolved 2011-03 Madrid meeting by paper N3278