ARTICLE AD BOX
[thread.mutex.requirements.mutex.general] p4 says
For purposes of determining the existence of a data race, these behave as atomic operations ([intro.multithread]). The lock and unlock operations on a single mutex appears to occur in a single total order.
[Note 2: This can be viewed as the modification order of the mutex. — end note]
The modification order only describes modifications to the object according to [intro.races] p4
All modifications to a particular atomic object M occur in some particular total order, called the modification order of M.
Assuming the lock in thread B owns the ownership after the unlock in thread A released the ownership, and there is a lock and unlock operation on thread C.
[thread.mutex.requirements.mutex.general] p8 says
Synchronization: Prior unlock() operations on the same object synchronize with ([intro.multithread]) this operation.
This means unlock in thread A happens before the lock in thread B. However, [thread.mutex.requirements.mutex.general] don't specify whether lock and unlock are considered as modifications or not. So, how to infer that the following modification is invalid?
unlock_in_A < unlock_in_C < lock_in_BIf [thread.mutex.requirements.mutex.general] don't specify that unlock and lock operations are modifications, how can [intro.races] p11 ~ p14 apply here to determine the position of the corresponding operations in the modification order of the mutex to conclude that unlock_in_A < unlock_in_C < lock_in_B is an invalid total order?
Update
To make the intent of the issue clear, consider this example
#include <mutex> std::mutex m; int main(){ m.lock(); // #1 m.unlock(); // #2 }Where is the wording in the current standard that defines the single total order of m is #1 < #2 rather than #2 < #1? As pointed by @ PeterCordes, an object of mutex type is not even defined as "an atomic object", so [intro.race] p11-p14 cannot even apply here to specify the order in the total order. Let alone, it is also unclear whether lock and unlock are modifications.
