In §7.26.1 Introduction the C11 threads library defines the mtx_recursive enumerator...
which is passed to mtx_init to create a mutex object that supports recursive locking;
In §18.104.22.168 The mtx_init function the standard then specifies that the function creates four kinds of mutex objects:
However, the semantics of neither recursive locking nor recursive mutex objects are specified. In particular, the only other normative reference to a recursive mutex is in §22.214.171.124 The mtx_lock function when describing its effects on non-recursive mutexes:
The mtx_lock function blocks until it locks the mutex pointed to by mtx. If the mutex is non-recursive, it shall not be locked by the calling thread. Prior calls to mtx_unlock on the same mutex shall synchronize with this operation.
Thus, the effects of calling mtx_lock() on mutex objects of the three recursive kinds are unspecified and the only kinds of mutexes whose semantics are specified are mtx_plain and mtx_timed.
The underspecification of recursive mutexes has come up before, for example during the committee's discussion of DR 469 but the authors feel the issue is important enough to warrant its own defect report.
The authors see two options for handling this defect: Either define the semantics of the C11 threads library functions for recursive mutex objects or remove recursive mutexes from the specification.
This suggested technical corrigendum outlines the first option.
Add a new subsection to §7.26.1 Introduction titled (for example) §126.96.36.199 Recursive Mutex, with the following text (adopted from the POSIX specification):
Modify §188.8.131.52 The mtx_lock function, paragraph 2 as follows:
The mtx_lock function
blocks until it locksthe mutex pointed to by mtx. If the mutex is non-recursive, it shall not be lockedby the calling thread. Prior calls to mtx_unlock on the same mutex shall synchronize with this operation.
Modify §184.108.40.206 The mtx_timedlock function, paragraph 2 as follows:
The mtx_timedlock function
endeavors to block until it locksthe mutex pointed to by mtx or until after the TIME_UTC-based calendar time pointed to by ts. The specified mutex shall support timeout. If the operation succeeds, prior calls to mtx_unlock on the same mutex shall synchronize with this operation.
Modify §220.127.116.11 The mtx_trylock function, paragraph 2 as follows:
The mtx_trylock function
endeavors to lockthe mutex pointed to by mtx. If the mutex is already locked, the function return s
Note that in addition to clarifying the effects on recursive mutexes the change above also relaxes the requirement on implementations to accept calls to the mtx_trylock function made by a thread that already owns the mutex. This change is proposed in order to allow more efficient implementations that rely on hardware support for locking and lock elision in hardware implementations that don't have the ability to track this case (an example is Hardware Lock Elision (HLE) support in Intel Transactional Sychnronization Extensions (TSX)). Although the existing guarantee is also provided by POSIX, a precedent for the relaxed requirement is the C++ threads specification.
Modify §18.104.22.168 The mtx_unlock function, paragraph 2 as follows:
The mtx_unlock function unlocks the mutex pointed to by mtx.The mutex pointed to by mtx shall be lockedby the calling thread. .