Properly specify the interaction of library calls for condition variables

Jens Gustedt, INRIA and ICube, France

2025-07-28

target

integration into IS ISO/IEC 9899:202y

document history

document number date comment
n3673 202507 Original proposal

license

CC BY, see https://creativecommons.org/licenses/by/4.0

1 Motivation

This paper draws part of its motivation from n3655

‘’Make implicit undefined behaviour in mtx_destroy() explicit’’,

and n3672

‘’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:

2 Wording

Add a new clause

7.30.3.1 General
1 A condition variable is an atomic object that implements specific operations as described in this clause but has no observable value. The entry to a call to a wait function and the return from such a call are two distinct atomic operations. These and the cnd_broadcast and cnd_signal operations are atomic read-modify-write operations with a memory order that is at least as strong as memory_order_relaxed. No other operation is an atomic operation but each operation described and any modification of the object representation contributes to the modification order of the condition variable.
2 A condition variable that is not initialized by a call to cnd_init, or whose last operation has been a call to cnd_destroy, or such that its object representation has been modified, has an indeterminate representation; performing any operation other than a call to cnd_init on such a condition variable has undefined behavior.
3 Before a call to cnd_destroy or before a modification of the object representation of a condition variable, all wait operations on that same condition variable shall have returned to their calling thread.
4 NOTE 1 That means that if a thread is blocked on a condition variable and another thread concurrently calls cnd_destroy on that same condition variable, the behavior is undefined.
5 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 to a wait operation.

7.30.4.2 The cnd_destroy function

Remove the second sentence.

The cnd_destroy function releases all resources used by the condition variable pointed to by cond. The cnd_destroy function requires that no threads be blocked waiting for the condition variable pointed to by cond.

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 returned to its calling thread when a call to cnd_destroy with C is performed or when the object representation of C is modified directly (7.30.3.1).

Acknowledgment

Thanks to Dave Banham and Hans Boehm for discussions and suggestions for improvements.