This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

4519. No formal rule associates the total order of a mutex object with the rule for modification order

Section: 32.6.4.2.1 [thread.mutex.requirements.mutex.general] Status: New Submitter: jim x Opened: 2026-02-05 Last modified: 2026-02-11

Priority: Not Prioritized

View other active issues in [thread.mutex.requirements.mutex.general].

View all other issues in [thread.mutex.requirements.mutex.general].

View all issues with New status.

Discussion:

32.6.4.2.1 [thread.mutex.requirements.mutex.general] p4 says (emphasis mine):

For purposes of determining the existence of a data race, these behave as atomic operations (6.10.2 [intro.multithread]). The lock and unlock operations on a single mutex appears to occur in a single total order.

The second note in 32.6.4.2.1 [thread.mutex.requirements.mutex.general] p4

[Note 2: This can be viewed as the modification order of the mutex. — end note]

wants to inform the reader to interpret the single total order as a modification order. The review in LWG 4475(i) says:

For atomic objects, the modification order is already a single total order, seq_cst or not. This isn't a useful change.

This implies that we want the single total order of a mutex object to be considered as the modification order of an atomic object for defining the order of the single total order by existing rules (especially, 6.10.2.2 [intro.races] p11-p14).

However, the wording in 32.6.4.2.1 [thread.mutex.requirements.mutex.general] p1 (emphasis mine)

In this description, m denotes an object of a mutex type.

strongly implies that there is a difference between atomic objects and mutex objects. Except for the note, there is no formal wording to state that lock() and unlock() operations are modifications to the mutex object as if they were modifications to an atomic object for the purpose of determining the total order, that is, the rules defined in 6.10.2.2 [intro.races] that applies to an atomic object can also apply to an mutex object.

For example:

#include <mutex>

std::mutex m;

int main(){
  m.lock(); // #1
  m.unlock(); // #2
}

The current formal wording only says m has a single total order. There is no formal wording that would associate the order of these operations in the total order of m with happens-before. We do want write-write coherence to apply to the total order of a mutex object. However, 6.10.2.2 [intro.races] p11 (emphasis mine),

If an operation A that modifies an atomic object M happens before an operation B that modifies M, then A is earlier than B in the modification order of M.

only applies to an atomic object, as shown in the emphasized text. The definition of total order only says the order can be either #1 < #2 or #2 < #1, either one of which is valid. Presumably, the intended meaning should be that the total order of the mutex object m in this program is #1 < #2 according to happens-before and 6.10.2.2 [intro.races] p11.

Proposed resolution:

This wording is relative to N5032.

  1. Modify 32.6.4.2.1 [thread.mutex.requirements.mutex.general] as indicated:

    -4- The implementation provides lock and unlock operations, as described below. For purposes of determining the existence of a data race, these behave as atomic operations (6.10.2 [intro.multithread]). Therefore, the lock and unlock operations on a single mutex appears to occur in a single total order as if they were modifications to a hypothetical atomic object corresponding to the mutex object.

    [Note 2: This can be viewed as the modification order (6.10.2 [intro.multithread]) of the mutex. Specifically, the requirements in 6.10.2.2 [intro.races] that are imposed on the modification order of an atomic object are also imposed on the total order of the mutex.end note]