This documents some of the design decisions made when implementing the C11 threading primitives on Windows
Note: see C11 defect report: tss_t destruction unspecified for issues with the standard specification of tss_t. The PDCLib implementation at present follows that report.
Windows provides a thread local storage implementation which mostly implements the requirements of the standard. However, it doesn't implement destructors. To solve that, PDCLib uses two approaches
There are three cases to consider:
Our implementation strategy:
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 on top of Windows' event handles
_WaitEvHandle
, which is a automatic reset Win32 event handle used for blocking, and _ThreadId
, the ID of the current thread_ThreadId
is initialized to 0mtx_lock
calls InterlockedCompareExchange
on _ThreadId
. 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 handlemtx_unlock
sets _ThreadId
to 0 and invokes SetEvent
to unblock a thread