<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 1146: "lockfree" does not say enough</title>
<meta property="og:title" content="Issue 1146: &quot;lockfree&quot; does not say enough">
<meta property="og:description" content="C++ library issue. Status: Resolved">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue1146.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#Resolved">Resolved</a> status.</em></p>
<h3 id="1146"><a href="lwg-defects.html#1146">1146</a>. "lockfree" does not say enough</h3>
<p><b>Section:</b> 32.5.5 <a href="https://wg21.link/atomics.lockfree">[atomics.lockfree]</a> <b>Status:</b> <a href="lwg-active.html#Resolved">Resolved</a>
 <b>Submitter:</b> Jeffrey Yasskin <b>Opened:</b> 2009-06-16 <b>Last modified:</b> 2016-02-25</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#atomics.lockfree">issues</a> in [atomics.lockfree].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Resolved">Resolved</a> status.</p>
<p><b>Discussion:</b></p>

<p><b>Addresses US 88</b></p>

<p>
The "lockfree" facilities do not tell the programmer enough.
</p>

<p>
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 <code>long long</code>s are not lock-free,
<code>ATOMIC_INTEGRAL_LOCK_FREE</code> 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 <code>ATOMIC_INTEGRAL_LOCK_FREE</code> to be 2,
but I may actually care whether I have access to
the <code>cmpxchg16b</code> 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?)
</p>

<p>
Second, having <code>atomic_is_lock_free</code> 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.
</p>

<p><i>[
2009-06-16 Jeffrey Yasskin adds:
]</i></p>


<blockquote>
<p>
To solve the first problem, I think 2 macros would help:
<code>MAX_POSSIBLE_LOCK_FREE_SIZE</code> and <code>MAX_GUARANTEED_LOCK_FREE_SIZE</code>,
which expand to the maximum value of <code>sizeof(T)</code> 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.
</p>

<p>
To solve the second,
I think one could specify that equally aligned objects of the same type
will return the same value from <code>atomic_is_lock_free()</code>.
I don't know how to specify "equal alignment".
Lawrence suggests an additional function, <code>atomic_is_always_lock_free()</code>.
</p>
</blockquote>

<p><i>[
2009-10-22 Benjamin Kosnik:
]</i></p>


<blockquote>
<p>
In the evolution discussion of N2925, "More Collected Issues with
Atomics," there is an action item with respect to
LWG <a href="lwg-defects.html#1146" title="&quot;lockfree&quot; does not say enough (Status: Resolved)">1146</a><sup><a href="https://cplusplus.github.io/LWG/issue1146" title="Latest snapshot">(i)</a></sup>, US 88
</p>

<p>
This is stated in the paper as:
</p>
<p>
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
</p>

<p>
Here is my attempt to do this. I don't believe that a separate trait is
necessary for this, and that instead <code>atomic_integral::is_lock_free</code> can
be re-purposed with minimal work as follows.
</p>

<p><i>[
Howard: Put Benjamin's wording in the proposed wording section.
]</i></p>


</blockquote>

<p><i>[
2009-10-22 Alberto Ganesh Barbati:
]</i></p>


<blockquote>
<p>
Just a thought... wouldn't it be better to use a scoped enum instead of
plain integers? For example:
</p>

<blockquote><pre>
enum class is_lock_free
{
    never = 0, sometimes = 1, always = 2;
};
</pre></blockquote>

<p>
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.
</p>

</blockquote>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p>
Header <code>&lt;cstdatomic&gt;</code> synopsis  [atomics.synopsis]
</p>

<p>
Edit  as follows:
</p>

<blockquote><pre>
namespace std {
...
// 29.4, lock-free property
<del>#define ATOMIC_INTEGRAL_LOCK_FREE unspecified</del>
<ins>#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</ins>
#define ATOMIC_ADDRESS_LOCK_FREE unspecified
</pre></blockquote>

<p>
Lock-free Property 32.5.5 <a href="https://wg21.link/atomics.lockfree">[atomics.lockfree]</a>
</p>

<p>
Edit the synopsis as follows.
</p>

<blockquote><pre>
namespace std {
   <del>#define ATOMIC_INTEGRAL_LOCK_FREE unspecified</del>
   <ins>#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</ins>
   #define ATOMIC_ADDRESS_LOCK_FREE unspecified
}
</pre></blockquote>

<p>
Edit paragraph 1 as follows.
</p>

<blockquote><p>
The <ins>ATOMIC_...._LOCK_FREE</ins> macros <del>ATOMIC_INTEGRAL_LOCK_FREE and ATOMIC_ADDRESS_LOCK_FREE</del> indicate the general lock-free
property of <del>integral and address atomic</del> <ins>the corresponding atomic integral</ins> types<ins>, with the
signed and unsigned variants grouped together</ins>.
<del>The properties also apply to the corresponding specializations of the atomic template.</del>
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.
</p></blockquote>

<p>
Operations on Atomic Types 32.5.8.2 <a href="https://wg21.link/atomics.types.operations">[atomics.types.operations]</a>
</p>

<p>
Edit as follows.
</p>

<blockquote><pre>
<del>void</del> <ins>static constexpr bool</ins> A::is_lock_free() const volatile;
</pre>
<blockquote><p>
<i>Returns:</i> True if the <del>object's</del> <ins>types's</ins> operations are lock-free, false
otherwise.
<ins>
[<i>Note:</i> In the same way that <code>&lt;limits&gt;</code>
<code>std::numeric_limits&lt;short&gt;::max()</code> is related to <code>&lt;limits.h&gt;</code> 
<code>__LONG_LONG_MAX__</code>, <code>&lt;atomic&gt; std::atomic_short::is_lock_free</code> is related to
<code>&lt;stdatomic.h&gt;</code> and <code>ATOMIC_SHORT_LOCK_FREE</code> &mdash; <i>end note</i>]
</ins>
</p></blockquote>
</blockquote>
</blockquote>

<p><i>[
2009-10 Santa Cruz:
]</i></p>


<blockquote><p>
<del>NAD Editorial</del><ins>Resolved</ins>.  Solved by
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2992.htm">N2992</a>.
</p></blockquote>



<p id="res-1146"><b>Proposed resolution:</b></p>
Resolved by <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2992.htm">N2992</a>.





</body>
</html>
