Another daemon: waiting for condition variables

Jens Gustedt, INRIA and ICube, France

2025-05-28

target

integration into IS ISO/IEC 9899:202y

document history

document number date comment
n3559 202505 this document

1 Introduction

The two wait funtions for conditional variables use non-binding terminology to describe a requirement. For example they claim that these functions would “require” the passed-in mutex to be locked. The use of such wording is not binding normatively.

Additionally, the text claims that the mutex is unlocked when such a function is entered and re-locked when the call finishes. It is not specified, how this “locking” behaves with respect to the other functions on mtx_t and with respect to the “synchronized by” relation.

There is no indication that this even has caused confusion in implementations. Nevertheless, we think that some housekeeping is in order.

This paper is not intended to make a normative change.

Note that the defects that are treated in this paper here seem not have been discussed before by WG14. Therefore they are not included in n3542 but are proposed in a separate paper.

2 Approach

In general, there is no way that a compiler can know if a specific mutex is already locked when entering into a wait for a conditional variable. Therefore we suggest that the only reasonable specification here is to have UB if the mutex is not locked. The simplest way is to use “shall” to make this normative.

Also it is currently claimed that when it is destroyed, it “requires” that no thread be blocked. We think that what is meant here is that no other thread should be using the same condition variable while it is destroyed. This is best state that such uses lead to a data race.

These UBs seems to have been below the radar for now, so we suggest that corresponding items are added to J .2.

The simplest way to ensure that these wait calls are suitably integrated into the mechanisms described for mtx_t is to claim that the unlocking and then re-locking behaves as if by calls to mtx_unlock and mtx_lock. Claiming so is consistent with POSIX pthread_cond_t and pthread_mutex_t, which had been the model for this feature when introduced in C11. We also then add explicit text that specifies the synchronization properties.

3 Suggested wording changes

New text is underlined green, removed text is stroke-out red.

3.1 In 7.30

7.30.3.2 The cnd_destroy function

2 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. Concurrent access to the condition variable being destroyed constitutes a data race.

7.30.3.5 The cnd_timedwait function

2 The cnd_timedwait function atomically unlocks the mutex pointed to by mtx (as if by mtx_unlock) and blocks until the condition variable pointed to by cond is signaled by a call to cnd_signal or to cnd_broadcast, or until after the TIME_UTC-based calendar time pointed to by ts, or until it is unblocked due to an unspecified reason. When the calling thread becomes unblocked it locks (as if by mtx_lock) the object pointed to by mtx before it returns. The cnd_timedwait function requires that Prior to the call, the mutex pointed to by mtx shall be locked by the calling thread. Entry and completion of calls with the same mutex pointed to by mtx synchronize as if by calls to mtx_unlock and mtx_lock, respectively.

7.30.3.6 The cnd_wait function

The cnd_wait function atomically unlocks the mutex pointed to by mtx (as if by mtx_unlock) and blocks until the condition variable pointed to by cond is signaled by a call to cnd_signal or to cnd_broadcast, or until it is unblocked due to an unspecified reason. When the calling thread becomes unblocked it locks the mutex pointed to by mtx (as if by mtx_lock) before it returns. The cnd_wait function requires that Prior to the call, the mutex pointed to by mtx shall be locked by the calling thread. Entry and completion of calls with the same mutex pointed to by mtx synchronize as if by calls to mtx_unlock and mtx_lock, respectively.

3.2 In J .2

Add at an appropriate point in the list

3.3 Note to the editors

The wording changes have been integrated into the standard source in the following branch:

https://gitlab.gwdg.de/iso-c/draft/-/tree/cnd_t