*/ } 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-07-28
integration into IS ISO/IEC 9899:202y
document number | date | comment |
---|---|---|
n3672 | 202507 | Original proposal |
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 could either replace the solutions proposed there or be constructed on top of it. When discussing that paper 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.
For example, the “General” section unspecifically indicate that lock and unlock “behave as atomic operation” and “in some particular order” without properly relating to the terminology that is developed for atomic objects. In particular a simple mapping of a lock operation as one single atomic operation is not sensible: because a thread that enters a lock operation can be blocked for an indeterminate amount of time, the entry into a call and the return from the call have to represent two separate events in the modification order of the mutex:
The only sensible way to provide this integration is to add mutexes
to the set of atomic types, but much as atomic_flag
that
this type then has only atomic operations and an internal state that is
not observable directly.
So, here we distinguish the following atomic modifications in the modification order of a mutex:
memory_order_relaxed
),memory_order_acquire
),memory_order_relaxed
),memory_order_release
).Additions by this paper here are:
Replace the whole clause 7.30.4.1, General,
1
For purposes of determining the existence of a data race, lock and unlock operations behave as atomic operations. All lock and unlock operations on a particular mutex occur in some particular total order.
2 NOTE This total order can be viewed as the modification order of the mutex.
by
1 A mutex is an atomic object that implements specific operations as described in this clause. It has two states, locked and unlocked,FTN0) that are only observable by the behavior of the function calls associated to the type. The atomic operations are described as lock and unlock operations that operate on this state. The entry to a call to a lock operation and the return from such a call are two distinct modifications in the modification order of the mutex. The return from a successful call to a lock operation is an acquire operation (it acquires the mutex), an unlock operation on a is a release operation (it releases the mutex).
FTN0) If the mutex is recursive, a given mutex may be be locked several times by the same thread.
2 The entry to the call and the return from an unsuccessful call to a lock operation have a memory order that is at least as strong asmemory_order_relaxed
. In addition to the atomic operations, there are themtx_init
andmtx_destroy
function calls as well as modifications of the object representationFTN1) that also are modifications in the modification order of a mutex.
FTN1) These include for example a copy operation of a
structure type that has a mtx_t
member.
3 A mutex that is not initialized by a call tomtx_init
, or whose last operation has been a call tomtx_destroy
, or such that its object representation has been modified, has an indeterminate representation; performing any operation other than a call tomtx_init
on such a mutex has undefined behavior.
4 After a call to mtx_init
the state
of the mutex is unlocked, and, for any thread, the first subsequent
atomic operation performed in the modification order shall be the entry
to a call to a lock operation.
5 Before a call to mtx_destroy
the
state of the mutex shall be unlocked, and, for any thread, the last
preceding atomic operation performed in the modification order shall not
be the entry to a call to a lock operation; similar requirements hold
for a mutex that is not in an indeterminate state and to which a
modification of the object representation is applied.
6 NOTE That means that if a thread is blocked on a
mutex or holds a lock on it and the same or another thread concurrently
calls mtx_destroy
on that same mutex,
the behavior is undefined.
…
7.30.4.2 The mtx_destroy function
…
Transform the second sentence into a note.
2 The
mtx_destroy
function releases any resources used by the mutex pointed to bymtx
.
3 NOTE In an execution that respects the requirements (7.30.4.1) for the modification order, the mutex is initialized prior to a call tomtx_destroy
and no threadscan beare blocked waiting for the mutex pointed to bymtx
.
Annex J .2 Undefined behavior
(181c) An operation other than a call to mtx_init
is performed on a mutex that has an
indeterminate representation (7.30.4.1).
(181d) For any thread the last operation on a mutex M has been the entry to a lock
operation when another thread issues a call to mtx_destroy
with M, or modifies the object
representation of M directly
(7.30.4.1).
(181e) For any thread the last operation on a mutex M has been the return from a
successful lock operation when the same or any other thread issues a
call to mtx_destroy
with M, or modifies the object
representation of M directly
(7.30.4.1).
(181f) For any thread the first atomic operation after a call to mtx_init
is not the entry to a call to a
lock operation (7.30.4.1).
Thanks to Dave Banham and Hans Boehm for discussions and suggestions for improvements.