...
Our implementation doesn't use Win32 CRITICAL_SECTIONs; primarily because this would involve exposing <windows.h> to all people who include <threads.h>, or duplicating the definition of CRITICAL_SECTION (messy). Instead, we implement a locking primitive loosely inspired by Linux' futexes. Ignoring support for recursive mutexes, our mutex implementation works as follows:on top of Windows' event handles
- Every mutex has two members, _WaitEvHandle, which is a automatic reset Win32 event handle used for blocking, and _State, which is a 32-bit integerThreadId, the ID of the current thread
- _State is initialized to -10
- To lock,
mtx_lock
calls InterlockedIncrement on _State. If the return value is 0, we successfully locked the mutex. If it is not 0, then we must block, so go ahead and block on the event handle - To unlock,
mtx_unlock
calls InterlockedDecrement on _State. If the return value is -1, nobody was waiting and we can return without touching the kernel; otherwise, we mustSetEvent
the event handle in order to unblock a thread - Note that at no point once someone has blocked on the mutex will the _State member return to -1 until all threads blocked on the mutex
...