*/ } ul /* Whole unordered list */ { } ul li /* Unordered list item */ { } ol /* Whole ordered list */ { } ol li /* Ordered list item */ { } hr {} /* ---- Some span elements --- */ sub /* Subscripts. Pandoc: H~2~O */ { } sup /* Superscripts. Pandoc: The 2^nd^ try. */ { } em /* Emphasis. Markdown: *emphasis* or _emphasis_ */ { } em > em /* Emphasis within emphasis: *This is all *emphasized* except that* */ { font-style: normal; } blockquote > p > em /* Emphasis within emphasis: *This is all *emphasized* except that* */ { font-style: normal; } blockquote > * > p > em /* Emphasis within emphasis: *This is all *emphasized* except that* */ { font-style: normal; } blockquote > p > ins > em /* Emphasis within emphasis: *This is all *emphasized* except that* */ { font-style: normal; } blockquote > * > p > ins > em /* Emphasis within emphasis: *This is all *emphasized* except that* */ { font-style: normal; } /* ---- Links (anchors) ---- */ a /* All links */ { /* Keep links clean. On screen, they are colored; in print, they do nothing anyway. */ text-decoration: none; } @media screen { a:hover { /* On hover, we indicate a bit more that it is a link. */ text-decoration: underline; } } @media print { a { /* In print, a colored link is useless, so un-style it. */ color: black; background: transparent; } a[href^="http://"]:after, a[href^="https://"]:after { /* However, links that go somewhere else, might be useful to the reader, so for http and https links, print the URL after what was the link text in parens */ content: " (" attr(href) ") "; font-size: 90%; } } /* ---- Images ---- */ img { /* Let it be inline left/right where it wants to be, but verticality make it in the middle to look nicer, but opinions differ, and if in a multi-line paragraph, it might not be so great. */ vertical-align: middle; } div.figure /* Pandoc figure-style image */ { /* Center the image and caption */ margin-left: auto; margin-right: auto; text-align: center; font-style: italic; } p.caption /* Pandoc figure-style caption within div.figure */ { /* Inherits div.figure props by default */ } /* ---- Code blocks and spans ---- */ pre, code { background-color: #fdf7ee; /* BEGIN word wrap */ /* Need all the following to word wrap instead of scroll box */ /* This will override the overflow:auto if present */ white-space: pre-wrap; /* css-3 */ white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */ white-space: -pre-wrap; /* Opera 4-6 */ white-space: -o-pre-wrap; /* Opera 7 */ word-wrap: break-word; /* Internet Explorer 5.5+ */ /* END word wrap */ } pre /* Code blocks */ { /* Distinguish pre blocks from other text by more than the font with a background tint. */ padding: 0.5em; /* Since we have a background color */ border-radius: 5px; /* Softens it */ /* Give it a some definition */ border: 1px solid #aaa; /* Set it off left and right, seems to look a bit nicer when we have a background */ margin-left: 0.5em; margin-right: 0.5em; } pre.yacc, code.yacc { background-color: #f0f0f0; } pre.yacc /* Code blocks */ { /* Distinguish pre blocks from other text by more than the font with a background tint. */ padding: 0.0em; /* Since we have a background color */ border-radius: 5px; /* Softens it */ /* Give it a some definition */ border: 0px solid #aaa; /* Set it off left and right, seems to look a bit nicer when we have a background */ margin-left: 0.0em; margin-right: 0.0em; } @media screen { pre { white-space: pre; /* Dotted looks better on screen and solid seems to print better. */ border: 1px dotted #777; } } code /* All inline code spans */ { } p > code, li > code /* Code spans in paragraphs and tight lists */ { /* Pad a little from adjacent text */ padding-left: 2px; padding-right: 2px; } li > p code /* Code span in a loose list */ { /* We have room for some more background color above and below */ padding: 2px; } span.option { color: blue; text-decoration: underline; } /* ---- Math ---- */ span.math /* Pandoc inline math default and --jsmath inline math */ { /* Tried font-style:italic here, and it messed up MathJax rendering in some browsers. Maybe don't mess with at all. */ } div.math /* Pandoc --jsmath display math */ { } span.LaTeX /* Pandoc --latexmathml math */ { } eq /* Pandoc --gladtex math */ { } /* ---- Tables ---- */ /* A clean textbook-like style with horizontal lines above and below and under the header. Rows highlight on hover to help scanning the table on screen. */ table { border-collapse: collapse; border-spacing: 0; /* IE 6 */ border-bottom: 2pt solid #000; border-top: 2pt solid #000; /* The caption on top will not have a bottom-border */ /* Center */ margin-left: auto; margin-right: auto; } thead /* Entire table header */ { border-bottom: 1pt solid #000; background-color: #eee; /* Does this BG print well? */ } tr.header /* Each header row */ { } tbody /* Entire table body */ { } /* Table body rows */ tr { } tr.odd:hover, tr.even:hover /* Use .odd and .even classes to avoid styling rows in other tables */ { background-color: #eee; } /* Odd and even rows */ tr.odd {} tr.even {} td, th /* Table cells and table header cells */ { vertical-align: top; /* Word */ vertical-align: baseline; /* Others */ padding-left: 0.5em; padding-right: 0.5em; padding-top: 0.2em; padding-bottom: 0.2em; } /* Removes padding on left and right of table for a tight look. Good if thead has no background color*/ /* tr td:last-child, tr th:last-child { padding-right: 0; } tr td:first-child, tr th:first-child { padding-left: 0; } */ th /* Table header cells */ { font-weight: bold; } tfoot /* Table footer (what appears here if caption is on top?) */ { } caption /* This is for a table caption tag, not the p.caption Pandoc uses in a div.figure */ { caption-side: top; border: none; font-size: 0.9em; font-style: italic; text-align: center; margin-bottom: 0.3em; /* Good for when on top */ padding-bottom: 0.2em; } /* ---- Definition lists ---- */ dl /* The whole list */ { border-top: 2pt solid black; padding-top: 0.5em; border-bottom: 2pt solid black; } dt /* Definition term */ { font-weight: bold; } dd+dt /* 2nd or greater term in the list */ { border-top: 1pt solid black; padding-top: 0.5em; } dd /* A definition */ { margin-bottom: 0.5em; } dd+dd /* 2nd or greater definition of a term */ { border-top: 1px solid black; /* To separate multiple definitions */ } /* ---- Footnotes ---- */ a.footnote, a.footnoteRef { /* Pandoc, MultiMarkdown footnote links */ font-size: small; vertical-align: text-top; } a[href^="#fnref"], a.reversefootnote /* Pandoc, MultiMarkdown, ?? footnote back links */ { } @media print { a[href^="#fnref"], a.reversefootnote /* Pandoc, MultiMarkdown */ { /* Don't display these at all in print since the arrow is only something to click on */ display: none; } } div.footnotes /* Pandoc footnotes div at end of the document */ { } div.footnotes li[id^="fn"] /* A footnote item within that div */ { } table tr td,th { border-right: 1px solid; border-left: 1px solid; } /* You can class stuff as "noprint" to not print. Useful since you can't set this media conditional inside an HTML element's style attribute (I think), and you don't want to make another stylesheet that imports this one and adds a class just to do this. */ @media print { .noprint { display:none; } }
2025-10-07
integration into IS ISO/IEC 9899:202y
C document ID: C4243
document number | date | comment |
---|---|---|
n3673 | 202507 | Original proposal |
n3709 | 202510 | Be careful when waiting for the mutex |
Describe the atomicity of the wait operations | ||
Factorize the description of the waits |
CC BY, see https://creativecommons.org/licenses/by/4.0
This paper draws part of its motivation from n3655
‘’Make implicit undefined behaviour in
mtx_destroy()
explicit’’,
and n3708
‘’Properly specify the interaction of library calls for mutexes’’.
When discussing the former on the reflector it became quickly
apparent, that not only the undefined behavior is currently poorly
described, but that the description also lacks a proper integration into
C11’s model of inter-thread time. The same observations hold for the
type cnd_t
and
clause 7.3, condition variable functions.
The only sensible way to provide this integration is to add condition
variables to the set of atomic types, but much as atomic_flag
this
type then has only atomic operations and an internal state that is not
observable directly.
Additions by this paper here are:
cnd_timedwait
and cnd_wait
.This proposal is not supposed to change the behavior of any implementation (even for related specifications such as C++ or POSIX), but formulates semantics that are conforming with the terminology of the C standard and that is consistent with the existing practice.
Modifications are against n3550
with the accepted modifcations in n3559
applied. New text is underlined green, removed text is
stroke-out red.
Add a new clause
7.30.3.1 General
1 The type cnd_t
of condition
variables is a complete atomic object type that implements specific
operations as described in this subclause but has no observable value.
2 Prior to a wait operation, that is a call tocnd_timedwait
orcnd_wait
, the mutex pointed to by themtx_t*
argument shall be locked by the calling thread. A wait operation performs
- a call to
mtx_unlock
with the mutex argument,- following that, two distinct atomic modifications to the condition variable object, the wait-entry followed by the wait-completion, and
- following that a call to the
mtx_lock
function with the mutex argument.
A thread that performs a wait operation on a condition variable is said to be blocked after writing the wait-entry and unblocked when the wait-completion is written. Wait operations with the same mutex synchronize by the call tomtx_unlock
(a release operation) and the call tomtx_lock
(an acquire operation). A wait operation as a whole, including the calls tomtx_unlock
andmtx_lock
, is perceived as one indivisible operation by the calling thread.FNT)
FTN) In contrast to that, in general, synchronizing operations on lock-free atomic objects in signal handlers for signals that are raised during a wait operation will not synchronize via the mutex.
3 Wait-entry, wait-completion, andcnd_broadcast
andcnd_signal
operations are atomic read-modify-write operations on the condition variable with a memory order that is at least as strong asmemory_order_relaxed
. Thecnd_t
type is not necessarily lock-free. In addition to the atomic operations, there are thecnd_init
andcnd_destroy
operations as well as modifications of the object representationFTN1) that also are modifications in the modification order of a condition variable.
FTN1) These include for example a copy operation of a
structure type that has a cnd_t
member.
4 A condition variable that is not initialized by acnd_init
operation, or whose last modification has been by acnd_destroy
operation, or such that its object representation has been modified directly, has an indeterminate representation; performing any of the described operations other thancnd_init
on such a condition variable has undefined behavior.
5 Before a cnd_destroy
operation or
before a direct modification of the object representation of a condition
variable, for all preceding wait operations in the modification order,
the wait-entry and wait-completion modifications shall have been
performed.
6 NOTE 1 That means that if a thread has entered a wait
operation but the wait-completion modification has not been performed
and another thread concurrently calls cnd_destroy
on that same condition variable,
the behavior is undefined. On the other hand, if after the
wait-completion the calling thread is yet suspended waiting for the lock
on the associated mutex the execution remains in a defined state.
7 NOTE 2 There is no synchronization operation for the
type cnd_t
itself. Synchronization is only implied by the described lock and unlock
operations on the mutex that is associated with a wait operation.
…
7.30.3.5 The cnd_timedwait function
…
2 The
cnd_timedwait function
atomicallyunlocks the mutex pointed to bymtx
(as if bymtx_unlock
)andblockssuspends the execution of the calling thread until the condition variable pointed to bycond
is unblocked,
is signaledby a call tocnd_signal
or tocnd_broadcast
, oruntil afterbecause theTIME_UTC
-based calendar time pointed to byts
has passed, oruntil it is unblockeddue to an unspecified reason.
WhenThereafter the calling threadbecomes unblocked itlocks(as if bymtx_lock
)the object pointed to bymtx
before it returns.Prior to the call, the mutex pointed to bymtx
shall be locked by the calling thread. Wait-entry and wait-completion of calls with the same mutex pointed to bymtx
synchronize as if by calls tomtx_unlock
andmtx_lock
, respectively.
Returns
3 The
cnd_timedwait
function returnsthrd_success
upon successif the calling thread is unblocked by a call tocnd_signal
orcnd_broadcast
, or otherwisethrd_timedout
if the time specified in the call was reachedwithout acquiring the requested resource, orthrd_error
if the request could not be honoredotherwise.
7.30.3.6 The cnd_wait function
…
2 The
cnd_wait function
atomicallyunlocks the mutex pointed to bymtx
(as if bymtx_unlock
)andblockssuspends the execution of the calling thread until the condition variable pointed to bycond
is unblocked,
is signaledby a call tocnd_signal
or tocnd_broadcast
, oruntil it is unblockeddue to an unspecified reason.
WhenThereafter the calling threadbecomes unblocked itlocks(as if bymtx_lock
)the object pointed to bymtx
before it returns.Prior to the call, the mutex pointed to bymtx
shall be locked by the calling thread. Entry and completion of calls with the same mutex pointed to bymtx
synchronize as if by calls tomtx_unlock
andmtx_lock
, respectively.
Returns
3 The
cnd_wait
function returnsthrd_success
upon successif the calling thread is unblocked by a call tocnd_signal
orcnd_broadcast
orthrd_error
if the request could not be honoredotherwise.
Annex J .2 Undefined behavior
(181a) An operation other than a call to cnd_init
is performed on a condition
variable that has an indeterminate representation (7.30.3.1).
(181b) A wait operation on a condition variable C has not resulted in the
wait-completion modification when a call to cnd_destroy
with C is performed or when the object
representation of C is
modified directly (7.30.3.1).
The changes here add cnd_t
to the notion
of atomic types. If n3706
is accepted into C2Y (there should be an online vote for inclusion
before the end of 2025) the list of atomic types that are exempted from
the generic atomic operations (7.17.7.2) should be amended with cnd_t
.
… that operate on all atomic types other than
atomic_flag
andcnd_t
Thanks to Dave Banham, Hans Boehm and Joseph Myers for discussions and suggestions for improvements.