Reputation: 5676
While looking at the C++ Reference for std::mutex
, I noticed that the constructor for std::mutex
is marked constexpr
.
This is surprising at first, since we usually have to make a system call (either pthread_mutex_init()
(POSIX) or CreateMutex()
(Windows)) to initialize a mutex. However, on closer inspection, for POSIX, one can use the constant PTHREAD_MUTEX_INITIALIZER
to statically initialize the mutex (perhaps as a global variable), though I can find no equivalent for Windows.
However, even if this static initialization for POSIX was the reason behind the constexpr
constructor, there're still various unsolved issues for an implementation:
std::is_constant_evaluated()
was added, so we don't have a way to determine if PTHREAD_MUTEX_INITIALIZER
or pthread_mutex_init()
should be used.So, how does one implement the constexpr
constructor for std::mutex
?
Upvotes: 6
Views: 1203
Reputation: 13689
On Windows, it is possible to implement std::mutex
as constexpr
using SRWLOCK
.
Unfortunately full SRWLOCK
is available starting in Windows 7. It was introduced in Windows Vista, but without the ability to implement try_lock
using it.
Visual Studio 2022 has dropped Windows Vista support, so it could have switched to SRWLOCK
, but for ABI compatibility reasons, to be compatible down to VS 2015, it still uses the implementation that allowed runtime selection of sync primitive, to avoid SRWLOCK
on pre-Win7.
Technically it is possible to implement std::mutex
based on CreateEvent
and lazy initialization, in Windows 95 and later, but this implementation would be complex and suboptimal, as it will not use the OS primitives directly and will not allow the OS to be aware of the mutex.
On POSIX, you can use PTHREAD_MUTEX_INITIALIZER
unconditionally, even in runtime.
Upvotes: 2