<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang>
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="mpark/wg21" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <meta name="dcterms.date" content="2024-07-16" />
  <title>Expose whether atomic notifying operations are lock
free</title>
  <style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.csl-block{margin-left: 1.5em;}
ul.task-list{list-style: none;}
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
{ counter-reset: source-line 0; }
pre.numberSource code > span
{ position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
{ content: counter(source-line);
position: relative; left: -1em; text-align: right; vertical-align: baseline;
border: none; display: inline-block;
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em;
color: #aaaaaa;
}
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
div.sourceCode
{ background-color: #f6f8fa; }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span { } 
code span.al { color: #ff0000; } 
code span.an { } 
code span.at { } 
code span.bn { color: #9f6807; } 
code span.bu { color: #9f6807; } 
code span.cf { color: #00607c; } 
code span.ch { color: #9f6807; } 
code span.cn { } 
code span.co { color: #008000; font-style: italic; } 
code span.cv { color: #008000; font-style: italic; } 
code span.do { color: #008000; } 
code span.dt { color: #00607c; } 
code span.dv { color: #9f6807; } 
code span.er { color: #ff0000; font-weight: bold; } 
code span.ex { } 
code span.fl { color: #9f6807; } 
code span.fu { } 
code span.im { } 
code span.in { color: #008000; } 
code span.kw { color: #00607c; } 
code span.op { color: #af1915; } 
code span.ot { } 
code span.pp { color: #6f4e37; } 
code span.re { } 
code span.sc { color: #9f6807; } 
code span.ss { color: #9f6807; } 
code span.st { color: #9f6807; } 
code span.va { } 
code span.vs { color: #9f6807; } 
code span.wa { color: #008000; font-weight: bold; } 
code.diff {color: #898887}
code.diff span.va {color: #006e28}
code.diff span.st {color: #bf0303}
</style>
  <style type="text/css">
body {
margin: 5em;
font-family: serif;

hyphens: auto;
line-height: 1.35;
text-align: justify;
}
@media screen and (max-width: 30em) {
body {
margin: 1.5em;
}
}
div.wrapper {
max-width: 60em;
margin: auto;
}

ul {
list-style-type: none;
padding-left: 2.5em;
margin-top: -0.2em;
margin-bottom: -0.2em;
}
ol {
padding-left: 2.5em;
}
a {
text-decoration: none;
color: #4183C4;
}
a.hidden_link {
text-decoration: none;
color: inherit;
}
li {
margin-top: 0.6em;
margin-bottom: 0.6em;
}
h1, h2, h3, h4 {
position: relative;
line-height: 1;
}
a.self-link {
position: absolute;
top: 0;
left: calc(-1 * (3.5rem - 26px));
width: calc(3.5rem - 26px);
height: 2em;
text-align: center;
border: none;
transition: opacity .2s;
opacity: .5;
font-family: sans-serif;
font-weight: normal;
font-size: 83%;
}
a.self-link:hover { opacity: 1; }
a.self-link::before { content: "§"; }
ul > li:before {
content: "\2014";
position: absolute;
margin-left: -1.5em;
}

#TOC ul > li:before {
content: none;
}
#TOC > ul {
padding-left: 0;
}

.toc-section-number {
margin-right: 0.5em;
}
:target { background-color: #C9FBC9; }
:target .codeblock { background-color: #C9FBC9; }
:target ul { background-color: #C9FBC9; }
.abbr_ref { float: right; }
.folded_abbr_ref { float: right; }
:target .folded_abbr_ref { display: none; }
:target .unfolded_abbr_ref { float: right; display: inherit; }
.unfolded_abbr_ref { display: none; }
.secnum { display: inline-block; min-width: 35pt; }
.header-section-number { display: inline-block; min-width: 35pt; }
.annexnum { display: block; }
div.sourceLinkParent {
float: right;
}
a.sourceLink {
position: absolute;
opacity: 0;
margin-left: 10pt;
}
a.sourceLink:hover {
opacity: 1;
}
a.itemDeclLink {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
opacity: 0;
}
a.itemDeclLink:hover { opacity: 1; }
span.marginalizedparent {
position: relative;
left: -5em;
}
li span.marginalizedparent { left: -7em; }
li ul > li span.marginalizedparent { left: -9em; }
li ul > li ul > li span.marginalizedparent { left: -11em; }
li ul > li ul > li ul > li span.marginalizedparent { left: -13em; }
div.footnoteNumberParent {
position: relative;
left: -4.7em;
}
a.marginalized {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
}
a.enumerated_item_num {
position: relative;
left: -3.5em;
display: inline-block;
margin-right: -3em;
text-align: right;
width: 3em;
}
div.para { margin-bottom: 0.6em; margin-top: 0.6em; text-align: justify; }
div.section { text-align: justify; }
div.sentence { display: inline; }
span.indexparent {
display: inline;
position: relative;
float: right;
right: -1em;
}
a.index {
position: absolute;
display: none;
}
a.index:before { content: "⟵"; }

a.index:target {
display: inline;
}
.indexitems {
margin-left: 2em;
text-indent: -2em;
}
div.itemdescr {
margin-left: 3em;
}
.bnf {
font-family: serif;
margin-left: 40pt;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
.ncbnf {
font-family: serif;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
}
.ncsimplebnf {
font-family: serif;
font-style: italic;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
background: inherit; 
}
span.textnormal {
font-style: normal;
font-family: serif;
white-space: normal;
display: inline-block;
}
span.rlap {
display: inline-block;
width: 0px;
}
span.descr { font-style: normal; font-family: serif; }
span.grammarterm { font-style: italic; }
span.term { font-style: italic; }
span.terminal { font-family: monospace; font-style: normal; }
span.nonterminal { font-style: italic; }
span.tcode { font-family: monospace; font-style: normal; }
span.textbf { font-weight: bold; }
span.textsc { font-variant: small-caps; }
a.nontermdef { font-style: italic; font-family: serif; }
span.emph { font-style: italic; }
span.techterm { font-style: italic; }
span.mathit { font-style: italic; }
span.mathsf { font-family: sans-serif; }
span.mathrm { font-family: serif; font-style: normal; }
span.textrm { font-family: serif; }
span.textsl { font-style: italic; }
span.mathtt { font-family: monospace; font-style: normal; }
span.mbox { font-family: serif; font-style: normal; }
span.ungap { display: inline-block; width: 2pt; }
span.textit { font-style: italic; }
span.texttt { font-family: monospace; }
span.tcode_in_codeblock { font-family: monospace; font-style: normal; }
span.phantom { color: white; }

span.math { font-style: normal; }
span.mathblock {
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 1.2em;
margin-bottom: 1.2em;
text-align: center;
}
span.mathalpha {
font-style: italic;
}
span.synopsis {
font-weight: bold;
margin-top: 0.5em;
display: block;
}
span.definition {
font-weight: bold;
display: block;
}
.codeblock {
margin-left: 1.2em;
line-height: 127%;
}
.outputblock {
margin-left: 1.2em;
line-height: 127%;
}
div.itemdecl {
margin-top: 2ex;
}
code.itemdeclcode {
white-space: pre;
display: block;
}
span.textsuperscript {
vertical-align: super;
font-size: smaller;
line-height: 0;
}
.footnotenum { vertical-align: super; font-size: smaller; line-height: 0; }
.footnote {
font-size: small;
margin-left: 2em;
margin-right: 2em;
margin-top: 0.6em;
margin-bottom: 0.6em;
}
div.minipage {
display: inline-block;
margin-right: 3em;
}
div.numberedTable {
text-align: center;
margin: 2em;
}
div.figure {
text-align: center;
margin: 2em;
}
table {
border: 1px solid black;
border-collapse: collapse;
margin-left: auto;
margin-right: auto;
margin-top: 0.8em;
text-align: left;
hyphens: none; 
}
td, th {
padding-left: 1em;
padding-right: 1em;
vertical-align: top;
}
td.empty {
padding: 0px;
padding-left: 1px;
}
td.left {
text-align: left;
}
td.right {
text-align: right;
}
td.center {
text-align: center;
}
td.justify {
text-align: justify;
}
td.border {
border-left: 1px solid black;
}
tr.rowsep, td.cline {
border-top: 1px solid black;
}
tr.even, tr.odd {
border-bottom: 1px solid black;
}
tr.capsep {
border-top: 3px solid black;
border-top-style: double;
}
tr.header {
border-bottom: 3px solid black;
border-bottom-style: double;
}
th {
border-bottom: 1px solid black;
}
span.centry {
font-weight: bold;
}
div.table {
display: block;
margin-left: auto;
margin-right: auto;
text-align: center;
width: 90%;
}
span.indented {
display: block;
margin-left: 2em;
margin-bottom: 1em;
margin-top: 1em;
}
ol.enumeratea { list-style-type: none; background: inherit; }
ol.enumerate { list-style-type: none; background: inherit; }

code.sourceCode > span { display: inline; }
</style>
  <link href="data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAVoJEAN6CRADegkQAWIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wCCRAAAgkQAAIJEAACCRAAsgkQAvoJEAP+CRAD/gkQA/4JEAP+CRADAgkQALoJEAACCRAAAgkQAAP///wD///8AgkQAAIJEABSCRACSgkQA/IJEAP99PQD/dzMA/3czAP99PQD/gkQA/4JEAPyCRACUgkQAFIJEAAD///8A////AHw+AFiBQwDqgkQA/4BBAP9/PxP/uZd6/9rJtf/bybX/upd7/39AFP+AQQD/gkQA/4FDAOqAQgBc////AP///wDKklv4jlEa/3o7AP+PWC//8+3o///////////////////////z7un/kFox/35AAP+GRwD/mVYA+v///wD///8A0Zpk+NmibP+0d0T/8evj///////+/fv/1sKz/9bCs//9/fr//////+/m2/+NRwL/nloA/5xYAPj///8A////ANKaZPjRmGH/5cKh////////////k149/3UwAP91MQD/lmQ//86rhv+USg3/m1YA/5hSAP+bVgD4////AP///wDSmmT4zpJY/+/bx///////8+TV/8mLT/+TVx//gkIA/5lVAP+VTAD/x6B//7aEVv/JpH7/s39J+P///wD///8A0ppk+M6SWP/u2sf///////Pj1f/Nj1T/2KFs/8mOUv+eWhD/lEsA/8aee/+0glT/x6F7/7J8Rvj///8A////ANKaZPjRmGH/48Cf///////+/v7/2qt//82PVP/OkFX/37KJ/86siv+USg7/mVQA/5hRAP+bVgD4////AP///wDSmmT40ppk/9CVXP/69O////////7+/v/x4M//8d/P//7+/f//////9u7n/6tnJf+XUgD/nFgA+P///wD///8A0ppk+NKaZP/RmWL/1qNy//r07///////////////////////+vXw/9akdP/Wnmn/y5FY/6JfFvj///8A////ANKaZFTSmmTo0ppk/9GYYv/Ql1//5cWm//Hg0P/x4ND/5cWm/9GXYP/RmGH/0ppk/9KaZOjVnmpY////AP///wDSmmQA0ppkEtKaZI7SmmT60ppk/9CWX//OkVb/zpFW/9CWX//SmmT/0ppk/NKaZJDSmmQS0ppkAP///wD///8A0ppkANKaZADSmmQA0ppkKtKaZLrSmmT/0ppk/9KaZP/SmmT/0ppkvNKaZCrSmmQA0ppkANKaZAD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkUtKaZNzSmmTc0ppkVNKaZADSmmQA0ppkANKaZADSmmQA////AP5/AAD4HwAA4AcAAMADAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMADAADgBwAA+B8AAP5/AAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAyCRACMgkQA6oJEAOqCRACQgkQAEIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRABigkQA5oJEAP+CRAD/gkQA/4JEAP+CRADqgkQAZoJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAA4gkQAwoJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQAxIJEADyCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAP///wD///8A////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAWgkQAmIJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAJyCRAAYgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAdIJEAPCCRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAPSCRAB4gkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQASoJEANKCRAD/gkQA/4JEAP+CRAD/g0YA/39AAP9zLgD/bSQA/2shAP9rIQD/bSQA/3MuAP9/PwD/g0YA/4JEAP+CRAD/gkQA/4JEAP+CRADUgkQAToJEAACCRAAAgkQAAP///wD///8A////AP///wB+PwAAgkUAIoJEAKiCRAD/gkQA/4JEAP+CRAD/hEcA/4BBAP9sIwD/dTAA/5RfKv+viF7/vp56/76ee/+wiF7/lWAr/3YxAP9sIwD/f0AA/4RHAP+CRAD/gkQA/4JEAP+CRAD/gkQArIJEACaBQwAA////AP///wD///8A////AIBCAEBzNAD6f0EA/4NFAP+CRAD/gkQA/4VIAP92MwD/bSUA/6N1Tv/ezsL/////////////////////////////////38/D/6V3Uv9uJgD/dTEA/4VJAP+CRAD/gkQA/4JEAP+BQwD/fUAA/4FDAEj///8A////AP///wD///8AzJRd5qBlKf91NgD/dDUA/4JEAP+FSQD/cy4A/3YyAP/PuKP//////////////////////////////////////////////////////9K7qP94NQD/ciwA/4VJAP+CRAD/fkEA/35BAP+LSwD/mlYA6v///wD///8A////AP///wDdpnL/4qx3/8KJUv+PUhf/cTMA/3AsAP90LgD/4dK+/////////////////////////////////////////////////////////////////+TYxf91MAD/dTIA/31CAP+GRwD/llQA/6FcAP+gWwD8////AP///wD///8A////ANGZY/LSm2X/4ap3/92mcP+wdT3/byQA/8mwj////////////////////////////////////////////////////////////////////////////+LYxv9zLgP/jUoA/59bAP+hXAD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/RmWL/1p9q/9ubXv/XqXj////////////////////////////7+fD/vZyG/6BxS/+gcUr/vJuE//r37f//////////////////////3MOr/5dQBf+dVQD/nVkA/5xYAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmWP/yohJ//jo2P//////////////////////4NTG/4JDFf9lGAD/bSQA/20kAP9kGAD/fz8S/+Xb0f//////5NG9/6txN/+LOgD/m1QA/51aAP+cWAD/m1cA/5xYAP+cWADy////AP///wD///8A////ANKaZPLSmmT/0ppk/8+TWf/Unmv//v37//////////////////////+TWRr/VwsA/35AAP+ERgD/g0UA/4JGAP9lHgD/kFga/8KXX/+TRwD/jT4A/49CAP+VTQD/n10A/5xYAP+OQQD/lk4A/55cAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/y4tO/92yiP//////////////////////8NnE/8eCQP+rcTT/ez0A/3IyAP98PgD/gEMA/5FSAP+USwD/jj8A/5lUAP+JNwD/yqV2/694Mf+HNQD/jkAA/82rf/+laBj/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/LiUr/4byY///////////////////////gupX/0I5P/+Wuev/Lklz/l1sj/308AP+QSwD/ol0A/59aAP+aVQD/k0oA/8yoh///////+fXv/6pwO//Lp3v///////Pr4f+oay7y////AP///wD///8A////ANKaZPLSmmT/0ppk/8uJSv/hvJj//////////////////////+G7l//Jhkb/0ppk/96nc//fqXX/x4xO/6dkFP+QSQD/llEA/5xXAP+USgD/yaOA///////38uv/qG05/8ijdv//////8efb/6ZpLPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/zIxO/9yxh///////////////////////7dbA/8iEQf/Sm2X/0Zlj/9ScZv/eqHf/2KJv/7yAQf+XTgD/iToA/5lSAP+JNgD/yKFv/611LP+HNQD/jT8A/8qmeP+kZRT/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/Pk1n/1J5q//78+//////////////////+/fv/1aFv/8iEQv/Tm2b/0ppl/9GZY//Wn2z/1pZc/9eldf/Bl2b/kUcA/4w9AP+OQAD/lUwA/59eAP+cWQD/jT8A/5ZOAP+eXADy////AP///wD///8A////ANKaZPLSmmT/0ppk/9KZY//KiEn/8d/P///////////////////////47+f/05tm/8iCP//KiEj/yohJ/8eCP//RmGH//vfy///////n1sP/rXQ7/4k4AP+TTAD/nVoA/5xYAP+cVwD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/0ptl/8uLTf/aq37////////////////////////////+/fz/6c2y/961jv/etY7/6Myx//78+v//////////////////////3MWv/5xXD/+ORAD/mFQA/51ZAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmmT/0ppk/8mFRP/s1b//////////////////////////////////////////////////////////////////////////////+PD/0JFU/7NzMv+WUQD/kUsA/5tXAP+dWQDy////AP///wD///8A////ANKaZP/SmmT/0ppk/9KaZP/Sm2X/z5NZ/8yMT//z5NX/////////////////////////////////////////////////////////////////9Ofa/8yNUP/UmGH/36p5/8yTWv+qaSD/kksA/5ROAPz///8A////AP///wD///8A0ppk5NKaZP/SmmT/0ppk/9KaZP/TnGf/zY9T/82OUv/t1sD//////////////////////////////////////////////////////+7Yw//OkFX/zI5R/9OcZ//SmmP/26V0/9ymdf/BhUf/ol8R6P///wD///8A////AP///wDSmmQ80ppk9tKaZP/SmmT/0ppk/9KaZP/TnGj/zpFW/8qJSv/dson/8uHS//////////////////////////////////Lj0//etIv/y4lL/86QVf/TnGj/0ppk/9KaZP/RmWP/05xn/9ymdfjUnWdC////AP///wD///8A////ANKaZADSmmQc0ppkotKaZP/SmmT/0ppk/9KaZP/Tm2b/0Zli/8qJSf/NjlH/16Z3/+G8mP/myKr/5siq/+G8mP/Xp3f/zY5S/8qISf/RmGH/05tm/9KaZP/SmmT/0ppk/9KaZP/SmmSm0pljINWdaQD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkQtKaZMrSmmT/0ppk/9KaZP/SmmT/0ptl/9GYYf/Nj1P/y4lL/8qISP/KiEj/y4lK/82PU//RmGH/0ptl/9KaZP/SmmT/0ppk/9KaZP/SmmTO0ppkRtKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZGzSmmTu0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmTw0ppkcNKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZBLSmmSQ0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppklNKaZBTSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQy0ppkutKaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppkvtKaZDbSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkXNKaZODSmmT/0ppk/9KaZP/SmmT/0ppk5NKaZGDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkBtKaZIbSmmTo0ppk6tKaZIrSmmQK0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP/8P///+B///+AH//+AAf//AAD//AAAP/AAAA/gAAAHwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA+AAAAfwAAAP/AAAP/8AAP//gAH//+AH///4H////D//" rel="icon" />
  
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
</head>
<body>
<div class="wrapper">
<header id="title-block-header">
<h1 class="title" style="text-align:center">Expose whether atomic
notifying operations are lock free</h1>
<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P3255R1</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2024-07-16</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project:</td>
    <td>Programming Language C++</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Audience:</td>
    <td>
      LEWG<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Brian Bi<br>&lt;<a href="mailto:bbi10@bloomberg.net" class="email">bbi10@bloomberg.net</a>&gt;<br>
    </td>
  </tr>
</table>
</header>
<div style="clear:both">
<div id="TOC" role="doc-toc">
<h1 id="toctitle">Contents</h1>
<ul>
<li><a href="#revision-history" id="toc-revision-history"><span class="toc-section-number">1</span> Revision history</a>
<ul>
<li><a href="#r1" id="toc-r1"><span class="toc-section-number">1.1</span> R1</a></li>
</ul></li>
<li><a href="#abstract" id="toc-abstract"><span class="toc-section-number">2</span> Abstract</a></li>
<li><a href="#the-problem" id="toc-the-problem"><span class="toc-section-number">3</span> The problem</a></li>
<li><a href="#importance-of-lock-free-notifying-operations" id="toc-importance-of-lock-free-notifying-operations"><span class="toc-section-number">4</span> Importance of lock-free notifying
operations</a></li>
<li><a href="#notify_is_always_lock_free-versus-notify_is_lock_free" id="toc-notify_is_always_lock_free-versus-notify_is_lock_free"><span class="toc-section-number">5</span>
<code class="sourceCode cpp">notify_is_always_lock_free</code> versus
<code class="sourceCode cpp">notify_is_lock_free</code></a></li>
<li><a href="#using-waiting-operations-in-signal-handlers" id="toc-using-waiting-operations-in-signal-handlers"><span class="toc-section-number">6</span> Using waiting operations in signal
handlers</a></li>
<li><a href="#proposal" id="toc-proposal"><span class="toc-section-number">7</span> Proposal</a></li>
<li><a href="#wording" id="toc-wording"><span class="toc-section-number">8</span> Wording</a></li>
<li><a href="#bibliography" id="toc-bibliography"><span class="toc-section-number">9</span> References</a></li>
</ul>
</div>
<h1 data-number="1" id="revision-history"><span class="header-section-number">1</span> Revision history<a href="#revision-history" class="self-link"></a></h1>
<h2 data-number="1.1" id="r1"><span class="header-section-number">1.1</span> R1<a href="#r1" class="self-link"></a></h2>
<ul>
<li>Added <code class="sourceCode cpp">wait_is_signal_safe</code>,
<code class="sourceCode cpp">wait_is_always_signal_safe</code>, and
<code class="sourceCode cpp">std<span class="op">::</span>atomic_is_signal_safe</code>.</li>
<li>Miscellaneous wording fixes.</li>
<li>Now ready for LEWG review after being forwarded from SG1.</li>
</ul>
<h1 data-number="2" id="abstract"><span class="header-section-number">2</span> Abstract<a href="#abstract" class="self-link"></a></h1>
<p>The atomic notifying functions for <code class="sourceCode cpp">std<span class="op">::</span>atomic_flag</code>
are not always lock-free even though <code class="sourceCode cpp">std<span class="op">::</span>atomic_flag</code>
is specified to always be lock-free. Therefore, use of <code class="sourceCode cpp">std<span class="op">::</span>atomic_flag<span class="op">::</span>notify_one</code>
or <code class="sourceCode cpp">std<span class="op">::</span>atomic_flag<span class="op">::</span>notify_all</code>
may cause unpredictable behavior when called in a signal handler, even
though the Standard currently claims that these functions are
signal-safe. It would be useful for signal handlers to know for sure
whether they can safely notify a <code class="sourceCode cpp">std<span class="op">::</span>atomic_flag</code>.
Therefore, I propose the introduction of member constant
<code class="sourceCode cpp">notify_is_always_lock_free</code>, member
function <code class="sourceCode cpp">notify_is_lock_free</code>, and
free function <code class="sourceCode cpp">std<span class="op">::</span>atomic_notify_is_lock_free</code>
for <code class="sourceCode cpp">std<span class="op">::</span>atomic_flag</code>.
I also propose the same for
<code class="sourceCode cpp">std<span class="op">::</span>atomic</code>
and <code class="sourceCode cpp">std<span class="op">::</span>atomic_ref</code>
specializations in case the lock-free property of their notifying
functions differ from those of their other functions such as loads and
stores. Similarly, in the case of the atomic waiting operations, it
would be useful to know whether they are safe to call in signal handlers
(despite not being lock-free).</p>
<h1 data-number="3" id="the-problem"><span class="header-section-number">3</span> The problem<a href="#the-problem" class="self-link"></a></h1>
<p>Atomic notifying operations for <code class="sourceCode cpp">std<span class="op">::</span>atomic_flag</code>
were originally proposed by <span class="citation" data-cites="P0514R0">[<a href="https://wg21.link/p0514r0" role="doc-biblioref">P0514R0</a>]</span>. In that paper, the authors
provided a reference implementation and wrote that their current
implementation was not lock-free. In the following revision, <span class="citation" data-cites="P0514R1">[<a href="https://wg21.link/p0514r1" role="doc-biblioref">P0514R1</a>]</span>, the authors revised their
proposal to no longer propose the addition of the waiting/notifying
interface to <code class="sourceCode cpp">std<span class="op">::</span>atomic_flag</code>,
writing that “lock-freedom is guaranteed to
<code class="sourceCode cpp">atomic_flag</code> and could not be
preserved with the extension”. That version of the paper instead
proposed a waiting/notifying interface only for semaphore types.
However, the atomic waiting/notifying interface was eventually added to
<code class="sourceCode cpp">std<span class="op">::</span>atomic_flag</code>
and
<code class="sourceCode cpp">std<span class="op">::</span>atomic</code>
by <span class="citation" data-cites="P1135R6">[<a href="https://wg21.link/p1135r6" role="doc-biblioref">P1135R6</a>]</span>, and to <code class="sourceCode cpp">std<span class="op">::</span>atomic_ref</code> by
<span class="citation" data-cites="P1643R1">[<a href="https://wg21.link/p1643r1" role="doc-biblioref">P1643R1</a>]</span>.</p>
<p>It was pointed out to me that the waiting functions are clearly not
lock-free because they may block the calling thread. Whether or not the
notifying functions are lock-free is a much more interesting question.
The notifying functions can always be made lock-free by implementing
them as no-ops while the waiting threads spin, waiting for the value to
change<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a>, which is one of the approaches used
by the reference implemention provided with P0514R0 <span class="citation" data-cites="refimpl">[<a href="https://github.com/ogiroux/atomic_flag/blob/master/atomic_flag/atomic_flag.hpp" role="doc-biblioref">refimpl</a>]</span>. On Linux and Windows, which
provide operating system support for notifying and waiting on objects up
to a certain size, the reference implementations of the notifying
functions consist of a single system call for each function, which makes
them lock-free.</p>
<p>In practice, however, implementations of the Standard Library fall
back to the “array of condvars” strategy at least some of the time,
rather than spinning:</p>
<ul>
<li>libstdc++ uses an array of condvars on platforms other than Linux,
as well as on Linux for atomic objects that are too large for the futex
API.</li>
<li>libc++ currently always uses an array of condvars; the use of
futexes or other operating system specific APIs does not appear to have
been implemented yet.</li>
<li>Although the Microsoft STL supports only Windows, it supports
versions of Windows that do not provide system calls for waiting and
notifying, so must fall back to an array of condvars on such platforms,
even for <code class="sourceCode cpp">std<span class="op">::</span>atomic_flag</code>.</li>
</ul>
<p>Therefore, in practice, the
<code class="sourceCode cpp">notify_one</code> and
<code class="sourceCode cpp">notify_all</code> functions for <code class="sourceCode cpp">std<span class="op">::</span>atomic_flag</code>
are not always lock-free even though the Standard specifies that all
operations on <code class="sourceCode cpp">std<span class="op">::</span>atomic_flag</code>
shall be lock-free (§<span>33.5.10
<a href="https://wg21.link/N4981#atomics.flag">[atomics.flag]</a><a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a></span>p2). I think that the
implementations correctly implement the intent of the Standard, but the
wording of the Standard erroneously requires implementations lacking
operating system support for waiting and notifying to spin rather than
using an array of condvars, considering that notifying a condvar is not,
in general, a lock-free operation.</p>
<p>Similarly, for
<code class="sourceCode cpp">std<span class="op">::</span>atomic</code>
and <code class="sourceCode cpp">std<span class="op">::</span>atomic_ref</code>, I
believe that the intent of the Standard is that
<code class="sourceCode cpp">is_lock_free</code>,
<code class="sourceCode cpp">is_always_lock_free</code>, and
<code class="sourceCode cpp">atomic_is_lock_free</code> should report
whether all operations <em>except</em> the waiting and notifying
operations are lock-free.</p>
<h1 data-number="4" id="importance-of-lock-free-notifying-operations"><span class="header-section-number">4</span> Importance of lock-free notifying
operations<a href="#importance-of-lock-free-notifying-operations" class="self-link"></a></h1>
<p>Fixing the wording to match the intent could be accomplished through
an LWG issue: we would simply say that all operations on <code class="sourceCode cpp">std<span class="op">::</span>atomic_flag</code>
other than the waiting and notifying operations are lock-free, and that
<code class="sourceCode cpp">is_lock_free</code>,
<code class="sourceCode cpp">is_always_lock_free</code>, and
<code class="sourceCode cpp">atomic_is_lock_free</code> for <code class="sourceCode cpp">std<span class="op">::</span>atomic<span class="op">&lt;</span>T<span class="op">&gt;</span></code>
and <code class="sourceCode cpp">std<span class="op">::</span>atomic_ref<span class="op">&lt;</span>T<span class="op">&gt;</span></code>
report whether all operations other than the waiting and notifying
operations are lock-free.</p>
<p>This paper proposes something else in addition to the above. I
believe that being able to tell whether the notifying operations are
lock-free, at the very least for <code class="sourceCode cpp">std<span class="op">::</span>atomic_flag</code>,
would be extremely useful because no equivalent functionality is
currently available for use in signal handlers. Because the set of
functions specified by the Standard and by POSIX as signal-safe is so
limited—for example, even <code class="sourceCode cpp">printf</code> is
not signal-safe—a programmer who wishes to perform any but the simplest
operations in a signal handler for an inherently fatal signal such as
SIGSEGV or SIGFPE must generally use the signal handler only to store
data to a global variable that some other thread reads and acts on.
While it would be acceptable for the signal handler itself to spin
(considering that the program cannot continue to function normally
anyway), there should not be a thread that spends its entire lifetime
spinning while waiting for a global variable to change (indicating that
a signal handler has asked it to do something), since in most
executions, the signal handler will hopefully not be invoked at all. It
is desirable for the thread that performs the actual work to be blocked
while waiting to be woken up by the signal handler. Unfortunately,
<code class="sourceCode cpp">pthread_cond_signal</code> is not
signal-safe so it cannot be used by the signal handler to wake up
another thread, and workarounds must be used such as communicating
through the filesystem (<em>i.e.</em>, using a pipe or socket). Such
workarounds are not only obscure but also cumbersome: they are difficult
to implement correctly, resulting in a source of bugs.</p>
<p>§<span>17.13.5
<a href="https://wg21.link/N4981#support.signal">[support.signal]</a></span>
currently implies that the notifying operation of <code class="sourceCode cpp">std<span class="op">::</span>atomic_flag</code>
is safe to call within a signal handler; however, since this safety is
considered to be a result of such operations being “plain lock-free
atomic operations”, and such operations are not always lock-free in
practice, unpredictable behavior may occur when such operations are
called within a signal handler, despite what the Standard says. Instead
of merely amending the Standard to exclude the notifying operations of
<code class="sourceCode cpp">std<span class="op">::</span>atomic_flag</code>
from being signal-safe, we should give users a way to determine when
those operations <em>are</em> signal-safe so that they can rely on
defined behavior when performing those operations in signal handlers. On
implementations that provide the guarantee that atomic notifying
operations are lock-free (and therefore signal safe), those operations
can become the preferred means for a signal handler to wake up another
thread.</p>
<h1 data-number="5" id="notify_is_always_lock_free-versus-notify_is_lock_free"><span class="header-section-number">5</span>
<code class="sourceCode cpp">notify_is_always_lock_free</code> versus
<code class="sourceCode cpp">notify_is_lock_free</code><a href="#notify_is_always_lock_free-versus-notify_is_lock_free" class="self-link"></a></h1>
<p><span class="citation" data-cites="P0152R1">[<a href="https://wg21.link/p0152r1" role="doc-biblioref">P0152R1</a>]</span> discusses the rationale for
both the older runtime functions
<code class="sourceCode cpp">is_lock_free</code> and <code class="sourceCode cpp">std<span class="op">::</span>atomic_is_lock_free</code>
and the newer constant
<code class="sourceCode cpp">is_always_lock_free</code>. For the
notifying operations, similar considerations apply. If a program is
compiled for both old and new versions of an operating system, but only
new versions have the necessary support for lock-free notifying
operations, then
<code class="sourceCode cpp">notify_is_always_lock_free</code> will not
be true during the compilation, and the program will have to perform a
runtime check. On the other hand, if the programmer simply doesn’t want
to support any platforms that don’t provide a lock-free atomic notifying
operation, they might wish to <code class="sourceCode cpp"><span class="kw">static_assert</span><span class="op">(</span>std<span class="op">::</span>atomic_flag<span class="op">::</span>notify_is_always_lock_free<span class="op">)</span></code>;
this assertion might pass if the user has configured their toolchain to
target only newer versions of the target operating system. For this
reason, this paper proposes both the member constant and the runtime
functions.</p>
<h1 data-number="6" id="using-waiting-operations-in-signal-handlers"><span class="header-section-number">6</span> Using waiting operations in
signal handlers<a href="#using-waiting-operations-in-signal-handlers" class="self-link"></a></h1>
<p>SG1 reviewed P3255R0 and pointed out that, although waiting
operations are not lock-free, there exist implementations in which they
can be signal-safe because they use a timed backoff approach. David
Goldblatt provided an application for calling atomic waiting operations
in a signal handler (lightly edited):</p>
<blockquote>
<p>This can be handy with userspace profiling—<em>e.g.</em> some “main”
thread gets a SIGALRM, and when it gets it, it sends a SIGUSR to
whatever set of threads it’s interested in, then that SIGUSR handler
gathers profiling data and lets the main thread know it’s done. You want
the main thread to wait until all the signal handlers it triggered have
executed.</p>
</blockquote>
<p>To support signal handlers that may wish to use atomic waiting
operations, this paper also proposes functions and traits to query
whether atomic waiting operations are signal-safe, analogous to the
queries of whether atomic notifying operations are lock-free.</p>
<h1 data-number="7" id="proposal"><span class="header-section-number">7</span> Proposal<a href="#proposal" class="self-link"></a></h1>
<p>For the foregoing reasons, I propose that:</p>
<ul>
<li>the Standard be amended to clarify that the waiting and notifying
operations of <code class="sourceCode cpp">std<span class="op">::</span>atomic_flag</code>
are not required to be lock-free, consistent with existing
practice;</li>
<li>the Standard be amended to clarify that
<code class="sourceCode cpp">is_lock_free</code>,
<code class="sourceCode cpp">is_always_lock_free</code>, and <code class="sourceCode cpp">std<span class="op">::</span>atomic_is_lock_free</code>
do not pertain to the atomic waiting and notifying operations,
consistent with existing practice; and</li>
<li>the member function
<code class="sourceCode cpp">notify_is_lock_free</code>, the free
function <code class="sourceCode cpp">std<span class="op">::</span>atomic_notify_is_lock_free</code>,
and the member constant
<code class="sourceCode cpp">notify_is_always_lock_free</code> be added
for <code class="sourceCode cpp">std<span class="op">::</span>atomic_flag</code>,
<code class="sourceCode cpp">std<span class="op">::</span>atomic</code>,
and <code class="sourceCode cpp">std<span class="op">::</span>atomic_ref</code>,
and that their values indicate whether atomic notifying operations for
the corresponding atomic type are lock-free; and</li>
<li>the member function
<code class="sourceCode cpp">wait_is_signal_safe</code>, the free
function <code class="sourceCode cpp">std<span class="op">::</span>atomic_notify_is_signal_safe</code>,
and the member constant
<code class="sourceCode cpp">notify_is_always_signal_safe</code> be
added for <code class="sourceCode cpp">std<span class="op">::</span>atomic_flag</code>,
<code class="sourceCode cpp">std<span class="op">::</span>atomic</code>,
and <code class="sourceCode cpp">std<span class="op">::</span>atomic_ref</code>,
and that their values indicate whether atomic waiting operations for the
corresponding atomic type may be used in signal handlers without
undefined behavior.</li>
</ul>
<p>I do not propose the addition of macros
<code class="sourceCode cpp">ATOMIC_BOOL_NOTIFY_LOCK_FREE</code> and so
on at this time (§<span>33.5.5
<a href="https://wg21.link/N4981#atomics.lockfree">[atomics.lockfree]</a></span>)
because the spelling of any such macros would need to be decided by WG14
before they are added to C++ and, in fact, C doesn’t even have atomic
waiting and notifying operations yet.</p>
<h1 data-number="8" id="wording"><span class="header-section-number">8</span> Wording<a href="#wording" class="self-link"></a></h1>
<p>In §<span>17.3.2
<a href="https://wg21.link/N4981#version.syn">[version.syn]</a></span>,
add a feature test macro named
<code class="sourceCode cpp">__cpp_lib_atomic_notify_is_lock_free</code>
with the comment <code class="sourceCode cpp"><span class="co">// freestanding, also in &lt;atomic&gt;</span></code>.</p>
<p>Edit §<span>17.13.5
<a href="https://wg21.link/N4981#support.signal">[support.signal]</a></span>p2:</p>
<blockquote>
<p>A <em>plain lock-free atomic operation</em> is an invocation of a
function <code class="sourceCode cpp">f</code> from [atomics] <span class="add" style="color: #006e28"><ins>, other than an atomic waiting
or notifying operation ([atomics.wait])</ins></span>, such that:</p>
<ul>
<li><code class="sourceCode cpp">f</code> is the function <code class="sourceCode cpp">atomic_is_lock_free<span class="op">()</span></code>
<span class="add" style="color: #006e28"><ins>,
<span><code class="sourceCode default">atomic_notify_is_lock_free()</code></span>,
or
<span><code class="sourceCode default">atomic_wait_is_signal_safe()</code></span></ins></span>,
or</li>
<li><code class="sourceCode cpp">f</code> is the member function <code class="sourceCode cpp">is_lock_free<span class="op">()</span></code>
<span class="add" style="color: #006e28"><ins>,
<span><code class="sourceCode default">notify_is_lock_free()</code></span>,
or
<span><code class="sourceCode default">wait_is_signal_safe()</code></span></ins></span>,
or</li>
<li><code class="sourceCode cpp">f</code> is a non-static member
function of class <code class="sourceCode cpp">atomic_flag</code>,
or</li>
<li><code class="sourceCode cpp">f</code> is a non-member function, and
the first parameter of <code class="sourceCode cpp">f</code> has type
<em>cv</em>
<code class="sourceCode cpp">atomic_flag<span class="op">*</span></code>,
or</li>
<li><code class="sourceCode cpp">f</code> is a non-static member
function invoked on an object <code class="sourceCode cpp">A</code>,
such that <code class="sourceCode cpp">A<span class="op">.</span>is_lock_free<span class="op">()</span></code>
yields <code class="sourceCode cpp"><span class="kw">true</span></code>,
or</li>
<li><code class="sourceCode cpp">f</code> is a non-member function, and
for every pointer-to-atomic argument
<code class="sourceCode cpp">A</code> passed to
<code class="sourceCode cpp">f</code>, <code class="sourceCode cpp">atomic_is_lock_free<span class="op">(</span>A<span class="op">)</span></code>
yields
<code class="sourceCode cpp"><span class="kw">true</span></code>.</li>
</ul>
</blockquote>
<p>Insert a new paragraph after §<span>17.13.5
<a href="https://wg21.link/N4981#support.signal">[support.signal]</a></span>p2:</p>
<div class="add" style="color: #006e28">

<blockquote>
<p>A <em>lock-free atomic notifying operation</em> is an invocation of
an atomic notifying function ([atomics.wait])
<code class="sourceCode default">f</code> such that</p>
<ul>
<li><code class="sourceCode default">f</code> is a non-static member
function of a class <code class="sourceCode default">A</code> such that
<code class="sourceCode default">A.notify_is_lock_free()</code> yields
<code class="sourceCode default">true</code>, or</li>
<li><code class="sourceCode default">f</code> is a non-member function
whose parameter has type pointer to <em>cv</em>
<code class="sourceCode default">A</code>, where
<code class="sourceCode default">A.notify_is_lock_free()</code> yields
<code class="sourceCode default">true</code>.</li>
</ul>
</blockquote>

</div>
<p>Edit §<span>17.13.5
<a href="https://wg21.link/N4981#support.signal">[support.signal]</a></span>p3:</p>
<blockquote>
<p>An evaluation is <em>signal-safe</em> unless it includes one of the
following:</p>
<ul>
<li>a call to any standard library function, except for plain lock-free
atomic operations<span class="add" style="color: #006e28"><ins>,
lock-free atomic notifying operations,</ins></span> and functions
explicitly identified as signal-safe;<br />
[<em>Note 1</em>: […] — <em>end note</em>]</li>
<li>[…]</li>
</ul>
</blockquote>
<p>Edit §<span>33.5.2
<a href="https://wg21.link/N4981#atomics.syn">[atomics.syn]</a></span>:</p>
<blockquote>
<div>
<div class="sourceCode" id="cb1"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>// ...</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>template&lt;class T&gt;</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  bool atomic_is_lock_free(const volatile atomic&lt;T&gt;*) noexcept;  // freestanding</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>template&lt;class T&gt;</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>  bool atomic_is_lock_free(const atomic&lt;T&gt;*) noexcept;  // freestanding</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="va">+ template&lt;class T&gt;</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="va">+   bool atomic_notify_is_lock_free(const volatile atomic&lt;T&gt;*) noexcept;  // freestanding</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="va">+ template&lt;class T&gt;</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="va">+   bool atomic_notify_is_lock_free(const atomic&lt;T&gt;*) noexcept;  // freestanding</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="va">+ template&lt;class T&gt;</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a><span class="va">+   bool atomic_wait_is_signal_safe(const volatile atomic&lt;T&gt;*) noexcept;  // freestanding</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a><span class="va">+ template&lt;class T&gt;</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a><span class="va">+   bool atomic_wait_is_signal_safe(const atomic&lt;T&gt;*) noexcept;  // freestanding</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>// ...</span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>// [atomics.flag], flag type and operations</span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>// struct atomic_flag;  // freestanding</span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool atomic_flag_notify_is_lock_free(const volatile atomic_flag*) noexcept;  // freestanding</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool atomic_flag_notify_is_lock_free(const atomic_flag*) noexcept;  // freestanding</span></span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool atomic_flag_wait_is_signal_safe(const volatile atomic_flag*) noexcept;  // freestanding</span></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool atomic_flag_wait_is_signal_safe(const atomic_flag*) noexcept;  // freestanding</span></span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>// ...</span></code></pre></div>
</div>
</blockquote>
<p>Insert a paragraph before §<span>33.5.5
<a href="https://wg21.link/N4981#atomics.lockfree">[atomics.lockfree]</a></span>p1:</p>
<blockquote>
<p><span class="add" style="color: #006e28"><ins>A <em>lock-free atomic
type</em> is one for which operations other than atomic waiting and
notifying operations ([atomics.wait]) are lock-free.</ins></span></p>
</blockquote>
<p>Edit the synopsis in §<span>33.5.7.1
<a href="https://wg21.link/N4981#atomics.ref.generic.general">[atomics.ref.generic.general]</a></span>:</p>
<blockquote>
<div>
<div class="sourceCode" id="cb2"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>// ...</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>static constexpr bool is_always_lock_free = <em>implementation-defined</em>;</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>bool is_lock_free() const noexcept;</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="va">+ static constexpr bool notify_is_always_lock_free = <em>implementation-defined</em>;</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool notify_is_lock_free() const noexcept;</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a><span class="va">+ static constexpr bool wait_is_always_signal_safe = <em>implementation-defined</em>;</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool wait_is_signal_safe() const noexcept;</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>// ...</span></code></pre></div>
</div>
</blockquote>
<p>Edit §<span>33.5.7.2
<a href="https://wg21.link/N4981#atomics.ref.ops">[atomics.ref.ops]</a></span>p3:</p>
<blockquote>
<p>The static data member
<code class="sourceCode cpp">is_always_lock_free</code> is
<code class="sourceCode cpp"><span class="kw">true</span></code> if
<span class="rm" style="color: #bf0303"><del>the
<span><code class="sourceCode default">atomic_ref</code></span> type’s
operations are always</del></span><span class="add" style="color: #006e28"><ins><span><code class="sourceCode default">atomic_ref&lt;T&gt;</code></span>
is</ins></span> lock-free <span class="add" style="color: #006e28"><ins>([atomics.lockfree])</ins></span>, and
<code class="sourceCode cpp"><span class="kw">false</span></code>
otherwise.</p>
</blockquote>
<p>Edit §<span>33.5.7.2
<a href="https://wg21.link/N4981#atomics.ref.ops">[atomics.ref.ops]</a></span>p4:</p>
<blockquote>
<p><em>Returns</em>:
<code class="sourceCode cpp"><span class="kw">true</span></code> if
<span class="rm" style="color: #bf0303"><del>operations on all objects
of the type
<span><code class="sourceCode default">atomic_ref&lt;T&gt;</code></span>
are</del></span><span class="add" style="color: #006e28"><ins><span><code class="sourceCode default">atomic_ref&lt;T&gt;</code></span>
is</ins></span> lock-free <span class="add" style="color: #006e28"><ins>([atomics.lockfree])</ins></span>,
<code class="sourceCode cpp"><span class="kw">false</span></code>
otherwise.</p>
</blockquote>
<p>Insert four paragraphs after §<span>33.5.7.2
<a href="https://wg21.link/N4981#atomics.ref.ops">[atomics.ref.ops]</a></span>p4:</p>
<div class="add" style="color: #006e28">

<blockquote>
<p><code class="sourceCode default">static constexpr bool notify_is_always_lock_free;</code><br />
The static data member
<code class="sourceCode default">notify_is_always_lock_free</code> is
<code class="sourceCode default">true</code> if atomic notifying
operations for type
<code class="sourceCode default">atomic_ref&lt;T&gt;</code> are
lock-free, and <code class="sourceCode default">false</code>
otherwise.</p>
<p><code class="sourceCode default">bool notify_is_lock_free() const noexcept;</code><br />
<em>Returns</em>: <code class="sourceCode default">true</code> if atomic
notifying operations for type
<code class="sourceCode default">atomic_ref&lt;T&gt;</code> are
lock-free, <code class="sourceCode default">false</code> otherwise.</p>
<p><code class="sourceCode default">static constexpr bool wait_is_always_signal_safe;</code><br />
The static data member
<code class="sourceCode default">wait_is_always_signal_safe</code> is
<code class="sourceCode default">true</code> if atomic waiting
operations for type
<code class="sourceCode default">atomic_ref&lt;T&gt;</code> are
signal-safe ([support.signal]), and
<code class="sourceCode default">false</code> otherwise.</p>
<p><code class="sourceCode default">bool wait_is_signal_safe() const noexcept;</code><br />
<em>Returns</em>: <code class="sourceCode default">true</code> if atomic
waiting operations for type
<code class="sourceCode default">atomic_ref&lt;T&gt;</code> are
signal-safe, <code class="sourceCode default">false</code>
otherwise.</p>
</blockquote>

</div>
<p>Edit §<span>33.5.7.3
<a href="https://wg21.link/N4981#atomics.ref.int">[atomics.ref.int]</a></span>p1:</p>
<blockquote>
<div>
<div class="sourceCode" id="cb3"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>// ...</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>static constexpr bool is_always_lock_free = <em>implementation-defined</em>;</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>bool is_lock_free() const noexcept;</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="va">+ static constexpr bool notify_is_always_lock_free = <em>implementation-defined</em>;</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool notify_is_lock_free() const noexcept;</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a><span class="va">+ static constexpr bool wait_is_always_signal_safe = <em>implementation-defined</em>;</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool wait_is_signal_safe() const noexcept;</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>// ...</span></code></pre></div>
</div>
</blockquote>
<p>Edit §<span>33.5.7.4
<a href="https://wg21.link/N4981#atomics.ref.float">[atomics.ref.float]</a></span>p1:</p>
<blockquote>
<div>
<div class="sourceCode" id="cb4"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>// ...</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>static constexpr bool is_always_lock_free = <em>implementation-defined</em>;</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>bool is_lock_free() const noexcept;</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="va">+ static constexpr bool notify_is_always_lock_free = <em>implementation-defined</em>;</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool notify_is_lock_free() const noexcept;</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a><span class="va">+ static constexpr bool wait_is_always_signal_safe = <em>implementation-defined</em>;</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool wait_is_signal_safe() const noexcept;</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>// ...</span></code></pre></div>
</div>
</blockquote>
<p>Edit the synopsis in §<span>33.5.7.5
<a href="https://wg21.link/N4981#atomics.ref.pointer">[atomics.ref.pointer]</a></span>:</p>
<blockquote>
<div>
<div class="sourceCode" id="cb5"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>// ...</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>static constexpr bool is_always_lock_free = <em>implementation-defined</em>;</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>bool is_lock_free() const noexcept;</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a><span class="va">+ static constexpr bool notify_is_always_lock_free = <em>implementation-defined</em>;</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool notify_is_lock_free() const noexcept;</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a><span class="va">+ static constexpr bool wait_is_always_signal_safe = <em>implementation-defined</em>;</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool wait_is_signal_safe() const noexcept;</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>// ...</span></code></pre></div>
</div>
</blockquote>
<p>Edit the synopsis in §<span>33.5.8.1
<a href="https://wg21.link/N4981#atomics.types.generic.general">[atomics.types.generic.general]</a></span>:</p>
<blockquote>
<div>
<div class="sourceCode" id="cb6"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>// ...</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>static constexpr bool is_always_lock_free = <em>implementation-defined</em>;</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>bool is_lock_free() const volatile noexcept;</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>bool is_lock_free() const noexcept;</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a><span class="va">+ static constexpr bool notify_is_always_lock_free = <em>implementation-defined</em>;</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool notify_is_lock_free() const volatile noexcept;</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool notify_is_lock_free() const noexcept;</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a><span class="va">+ static constexpr bool wait_is_always_signal_safe = <em>implementation-defined</em>;</span></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool wait_is_signal_safe() const volatile noexcept;</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool wait_is_signal_safe() const noexcept;</span></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a>// ...</span></code></pre></div>
</div>
</blockquote>
<p>Edit §<span>33.5.8.2
<a href="https://wg21.link/N4981#atomics.types.operations">[atomics.types.operations]</a></span>p4:</p>
<blockquote>
<p>The static data member
<code class="sourceCode cpp">is_always_lock_free</code> is
<code class="sourceCode cpp"><span class="kw">true</span></code> if
<span class="rm" style="color: #bf0303"><del>the
<span><code class="sourceCode default">atomic_ref</code></span> type’s
operations are always</del></span><span class="add" style="color: #006e28"><ins><span><code class="sourceCode default">atomic&lt;T&gt;</code></span>
is</ins></span> lock-free <span class="add" style="color: #006e28"><ins>([atomics.lockfree])</ins></span>, and
<code class="sourceCode cpp"><span class="kw">false</span></code>
otherwise.<br />
[<em>Note 2</em>: […] —<em>end note</em>]</p>
</blockquote>
<p>Edit §<span>33.5.8.2
<a href="https://wg21.link/N4981#atomics.types.operations">[atomics.types.operations]</a></span>p5:</p>
<blockquote>
<p><em>Returns</em>:
<code class="sourceCode cpp"><span class="kw">true</span></code> if
<span class="rm" style="color: #bf0303"><del>the object’s operations
are</del></span><span class="add" style="color: #006e28"><ins><span><code class="sourceCode default">atomic&lt;T&gt;</code></span>
is</ins></span> lock-free <span class="add" style="color: #006e28"><ins>([atomics.lockfree])</ins></span>,
<code class="sourceCode cpp"><span class="kw">false</span></code>
otherwise.<br />
[<em>Note 3</em>: […] —<em>end note</em>]</p>
</blockquote>
<p>Insert four paragraphs after §<span>33.5.8.2
<a href="https://wg21.link/N4981#atomics.types.operations">[atomics.types.operations]</a></span>p5:</p>
<div class="add" style="color: #006e28">

<blockquote>
<p><code class="sourceCode default">static constexpr bool notify_is_always_lock_free = <em>implementation-defined</em>;</code><br />
The static data member
<code class="sourceCode default">notify_is_always_lock_free</code> is
<code class="sourceCode default">true</code> if atomic notifying
operations for type
<code class="sourceCode default">atomic&lt;T&gt;</code> are lock-free,
and <code class="sourceCode default">false</code> otherwise.</p>
<p><code class="sourceCode default">bool notify_is_lock_free() const volatile noexcept;</code><br />
<code class="sourceCode default">bool notify_is_lock_free() const noexcept;</code><br />
<em>Returns</em>: <code class="sourceCode default">true</code> if atomic
notifying operations for type
<code class="sourceCode default">atomic&lt;T&gt;</code> are lock-free,
<code class="sourceCode default">false</code> otherwise.</p>
<p><code class="sourceCode default">static constexpr bool wait_is_always_signal_safe = <em>implementation-defined</em>;</code><br />
The static data member
<code class="sourceCode default">wait_is_always_signal_safe</code> is
<code class="sourceCode default">true</code> if atomic waiting
operations for type
<code class="sourceCode default">atomic&lt;T&gt;</code> are signal-safe
([support.syn]), and <code class="sourceCode default">false</code>
otherwise.</p>
<p><code class="sourceCode default">bool wait_is_signal_safe() const volatile noexcept;</code><br />
<code class="sourceCode default">bool wait_is_signal_safe() const noexcept;</code><br />
<em>Returns</em>: <code class="sourceCode default">true</code> if atomic
waiting operations for type
<code class="sourceCode default">atomic&lt;T&gt;</code> are signal-safe,
<code class="sourceCode default">false</code> otherwise.</p>
</blockquote>

</div>
<p>Edit §<span>33.5.8.3
<a href="https://wg21.link/N4981#atomics.types.int">[atomics.types.int]</a></span>p1:</p>
<blockquote>
<div>
<div class="sourceCode" id="cb7"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>// ...</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>static constexpr bool is_always_lock_free = <em>implementation-defined</em>;</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>bool is_lock_free() const volatile noexcept;</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>bool is_lock_free() const noexcept;</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a><span class="va">+ static constexpr bool notify_is_always_lock_free = <em>implementation-defined</em>;</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool notify_is_lock_free() const volatile noexcept;</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool notify_is_lock_free() const noexcept;</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a><span class="va">+ static constexpr bool wait_is_always_signal_safe = <em>implementation-defined</em>;</span></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool wait_is_signal_safe() const volatile noexcept;</span></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool wait_is_signal_safe() const noexcept;</span></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a>// ...</span></code></pre></div>
</div>
</blockquote>
<p>Edit §<span>33.5.8.4
<a href="https://wg21.link/N4981#atomics.types.float">[atomics.types.float]</a></span>p1:</p>
<blockquote>
<div>
<div class="sourceCode" id="cb8"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>// ...</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>static constexpr bool is_always_lock_free = <em>implementation-defined</em>;</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>bool is_lock_free() const volatile noexcept;</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>bool is_lock_free() const noexcept;</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a><span class="va">+ static constexpr bool notify_is_always_lock_free = <em>implementation-defined</em>;</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool notify_is_lock_free() const volatile noexcept;</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool notify_is_lock_free() const noexcept;</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a><span class="va">+ static constexpr bool wait_is_always_signal_safe = <em>implementation-defined</em>;</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool wait_is_signal_safe() const volatile noexcept;</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool wait_is_signal_safe() const noexcept;</span></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>// ...</span></code></pre></div>
</div>
</blockquote>
<p>Edit the synopsis in §<span>33.5.8.5
<a href="https://wg21.link/N4981#atomics.types.pointer">[atomics.types.pointer]</a></span>:</p>
<blockquote>
<div>
<div class="sourceCode" id="cb9"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>// ...</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>static constexpr bool is_always_lock_free = <em>implementation-defined</em>;</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>bool is_lock_free() const volatile noexcept;</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>bool is_lock_free() const noexcept;</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a><span class="va">+ static constexpr bool notify_is_always_lock_free = <em>implementation-defined</em>;</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool notify_is_lock_free() const volatile noexcept;</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool notify_is_lock_free() const noexcept;</span></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a><span class="va">+ static constexpr bool wait_is_always_signal_safe = <em>implementation-defined</em>;</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool wait_is_signal_safe() const volatile noexcept;</span></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool wait_is_signal_safe() const noexcept;</span></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a>// ...</span></code></pre></div>
</div>
</blockquote>
<p>Edit the synopsis in §<span>33.5.8.7.2
<a href="https://wg21.link/N4981#util.smartptr.atomic.shared">[util.smartptr.atomic.shared]</a></span>:</p>
<blockquote>
<div>
<div class="sourceCode" id="cb10"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>// ...</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>static constexpr bool is_always_lock_free = <em>implementation-defined</em>;</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>bool is_lock_free() const noexcept;</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a><span class="va">+ static constexpr bool notify_is_always_lock_free = <em>implementation-defined</em>;</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool notify_is_lock_free() const noexcept;</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a><span class="va">+ static constexpr bool wait_is_always_signal_safe = <em>implementation-defined</em>;</span></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool wait_is_signal_safe() const noexcept;</span></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>// ...</span></code></pre></div>
</div>
</blockquote>
<p>Edit the synopsis in §<span>33.5.8.7.3
<a href="https://wg21.link/N4981#util.smartptr.atomic.weak">[util.smartptr.atomic.weak]</a></span>:</p>
<blockquote>
<div>
<div class="sourceCode" id="cb11"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>// ...</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>static constexpr bool is_always_lock_free = <em>implementation-defined</em>;</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>bool is_lock_free() const noexcept;</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a><span class="va">+ static constexpr bool notify_is_always_lock_free = <em>implementation-defined</em>;</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool notify_is_lock_free() const noexcept;</span></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a><span class="va">+ static constexpr bool wait_is_always_signal_safe = <em>implementation-defined</em>;</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a><span class="va">+ bool wait_is_signal_safe() const noexcept;</span></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a>// ...</span></code></pre></div>
</div>
</blockquote>
<p>Edit the synopsis in §<span>33.5.10
<a href="https://wg21.link/N4981#atomics.flag">[atomics.flag]</a></span>:</p>
<blockquote>
<div>
<div class="sourceCode" id="cb12"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>namespace std {</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>struct atomic_flag {</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a><span class="va">+     static constexpr bool notify_is_always_lock_free = <em>implementation-defined</em>;</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a><span class="va">+     bool notify_is_lock_free() const volatile noexcept;</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a><span class="va">+     bool notify_is_lock_free() const noexcept;</span></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a><span class="va">+     static constexpr bool wait_is_always_signal_safe = <em>implementation-defined</em>;</span></span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a><span class="va">+     bool wait_is_signal_safe() const volatile noexcept;</span></span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a><span class="va">+     bool wait_is_signal_safe() const noexcept;</span></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>// ...</span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>};</span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
</div>
</blockquote>
<p>Edit §<span>33.5.10
<a href="https://wg21.link/N4981#atomics.flag">[atomics.flag]</a></span>p2:</p>
<blockquote>
<p><span class="rm" style="color: #bf0303"><del>Operations on an object
of type <span><code class="sourceCode default">atomic_flag</code></span>
shall be lock-free. The operations should also be
address-free.</del></span><span class="add" style="color: #006e28"><ins><span><code class="sourceCode default">atomic_flag</code></span>
is a lock-free type ([atomics.lockfree]).</ins></span></p>
</blockquote>
<p><em>Drafting note:</em> We shouldn’t need to repeat the “should be
address-free” recommendation from §<span>33.5.5
<a href="https://wg21.link/N4981#atomics.lockfree">[atomics.lockfree]</a></span>p5.</p>
<p>Insert four paragraphs after §<span>33.5.10
<a href="https://wg21.link/N4981#atomics.flag">[atomics.flag]</a></span>p3:</p>
<div class="add" style="color: #006e28">

<blockquote>
<p><code class="sourceCode default">static constexpr bool atomic_flag::notify_is_always_lock_free = <em>implementation-defined</em>;</code><br />
The static data member
<code class="sourceCode default">notify_is_always_lock_free</code> is
<code class="sourceCode default">true</code> if atomic notifying
operations for type <code class="sourceCode default">atomic_flag</code>
are lock-free, and <code class="sourceCode default">false</code>
otherwise.</p>
<p><code class="sourceCode default">bool atomic_flag_notify_is_lock_free(const volatile atomic_flag* object) noexcept;</code><br />
<code class="sourceCode default">bool atomic_flag_notify_is_lock_free(const atomic_flag* object) noexcept;</code><br />
<code class="sourceCode default">bool atomic_flag::notify_is_lock_free() const volatile noexcept;</code><br />
<code class="sourceCode default">bool atomic_flag::notify_is_lock_free() const noexcept;</code><br />
<em>Returns</em>: <code class="sourceCode default">true</code> if atomic
notifying operations for type
<code class="sourceCode default">atomic_flag</code> are lock-free,
<code class="sourceCode default">false</code> otherwise.</p>
<p><code class="sourceCode default">static constexpr bool atomic_flag::wait_is_always_signal_safe = <em>implementation-defined</em>;</code><br />
The static data member
<code class="sourceCode default">wait_is_always_signal_safe</code> is
<code class="sourceCode default">true</code> if atomic waiting
operations for type <code class="sourceCode default">atomic_flag</code>
are signal-safe ([support.syn]), and
<code class="sourceCode default">false</code> otherwise.</p>
<p><code class="sourceCode default">bool atomic_flag_wait_is_signal_safe(const volatile atomic_flag* object) noexcept;</code><br />
<code class="sourceCode default">bool atomic_flag_wait_is_signal_safe(const atomic_flag* object) noexcept;</code><br />
<code class="sourceCode default">bool atomic_flag::wait_is_signal_safe() const volatile noexcept;</code><br />
<code class="sourceCode default">bool atomic_flag::wait_is_signal_safe() const noexcept;</code><br />
<em>Returns</em>: <code class="sourceCode default">true</code> if atomic
waiting operations for type
<code class="sourceCode default">atomic_flag</code> are signal-safe,
<code class="sourceCode default">false</code> otherwise.</p>
</blockquote>

</div>
<h1 data-number="9" id="bibliography"><span class="header-section-number">9</span> References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="1" role="doc-bibliography">
<div id="ref-P0152R1" class="csl-entry" role="doc-biblioentry">
[P0152R1] Olivier Giroux, JF Bastien, Jeff Snyder. 2016-03-02. constexpr
atomic&lt;T&gt;::is_always_lock_free. <a href="https://wg21.link/p0152r1"><div class="csl-block">https://wg21.link/p0152r1</div></a>
</div>
<div id="ref-P0514R0" class="csl-entry" role="doc-biblioentry">
[P0514R0] Olivier Giroux. 2016-11-15. Enhancing std::atomic_flag for
waiting. <a href="https://wg21.link/p0514r0"><div class="csl-block">https://wg21.link/p0514r0</div></a>
</div>
<div id="ref-P0514R1" class="csl-entry" role="doc-biblioentry">
[P0514R1] Olivier Giroux. 2017-06-14. Enhancing std::atomic_flag for
waiting. <a href="https://wg21.link/p0514r1"><div class="csl-block">https://wg21.link/p0514r1</div></a>
</div>
<div id="ref-P1135R6" class="csl-entry" role="doc-biblioentry">
[P1135R6] David Olsen, Olivier Giroux, JF Bastien, Detlef Vollmann,
Bryce Lelbach. 2019-07-20. The C++20 Synchronization Library. <a href="https://wg21.link/p1135r6"><div class="csl-block">https://wg21.link/p1135r6</div></a>
</div>
<div id="ref-P1643R1" class="csl-entry" role="doc-biblioentry">
[P1643R1] David Olsen. 2019-07-20. Add wait/notify to atomic_ref. <a href="https://wg21.link/p1643r1"><div class="csl-block">https://wg21.link/p1643r1</div></a>
</div>
<div id="ref-refimpl" class="csl-entry" role="doc-biblioentry">
[refimpl] NVIDIA Corporation. 2016-11-11. ogiroux/atomic_flag. <a href="https://github.com/ogiroux/atomic_flag/blob/master/atomic_flag/atomic_flag.hpp"><div class="csl-block">https://github.com/ogiroux/atomic_flag/blob/master/atomic_flag/atomic_flag.hpp</div></a>
</div>
</div>
<section id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>Although <code class="sourceCode cpp">notify_one</code>
is supposed to wake up only one waiting thread, the specification of
<code class="sourceCode cpp">wait</code> allows for spurious wakeups.
Therefore, an implementation of <code class="sourceCode cpp">wait</code>
that spins and returns whenever it sees that the value has changed is
conforming: if <code class="sourceCode cpp">notify_one</code> was
called, then one of the threads that wakes up can be arbitrarily
considered to have been notified, while all other such threads can be
considered to have been unblocked spuriously.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2"><p>All citations to the Standard are to working draft N4981
unless otherwise specified.<a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
</div>
</div>
</body>
</html>
