RWMutex.inc revision 263508
194541Sru//= llvm/Support/Win32/Mutex.inc - Win32 Reader/Writer Mutual Exclusion Lock =// 294541Sru// 394541Sru// The LLVM Compiler Infrastructure 494541Sru// 594541Sru// This file is distributed under the University of Illinois Open Source 694541Sru// License. See LICENSE.TXT for details. 794541Sru// 894541Sru//===----------------------------------------------------------------------===// 994541Sru// 1094541Sru// This file implements the Win32 specific (non-pthread) RWMutex class. 1194541Sru// 1294541Sru//===----------------------------------------------------------------------===// 1394541Sru 1494541Sru//===----------------------------------------------------------------------===// 1594541Sru//=== WARNING: Implementation here must contain only generic Win32 code that 1694541Sru//=== is guaranteed to work on *all* Win32 variants. 1794541Sru//===----------------------------------------------------------------------===// 1894541Sru 1994541Sru#include "Windows.h" 2094541Sru 2194541Srunamespace llvm { 2294541Sruusing namespace sys; 2394541Sru 2494541Sru// Windows has slim read-writer lock support on Vista and higher, so we 2594541Sru// will attempt to load the APIs. If they exist, we will use them, and 2694541Sru// if not, we will fall back on critical sections. When we drop support 2794541Sru// for XP, we can stop lazy-loading these APIs and just use them directly. 2894541Sru#if defined(__MINGW32__) 2994541Sru // Taken from WinNT.h 3094541Sru typedef struct _RTL_SRWLOCK { 3194541Sru PVOID Ptr; 3294541Sru } RTL_SRWLOCK, *PRTL_SRWLOCK; 3394541Sru 3494541Sru // Taken from WinBase.h 3594541Sru typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK; 3694541Sru#endif 3794541Sru 3894541Srustatic VOID (WINAPI *fpInitializeSRWLock)(PSRWLOCK lock) = NULL; 3994541Srustatic VOID (WINAPI *fpAcquireSRWLockExclusive)(PSRWLOCK lock) = NULL; 4094541Srustatic VOID (WINAPI *fpAcquireSRWLockShared)(PSRWLOCK lock) = NULL; 4194541Srustatic VOID (WINAPI *fpReleaseSRWLockExclusive)(PSRWLOCK lock) = NULL; 4294541Srustatic VOID (WINAPI *fpReleaseSRWLockShared)(PSRWLOCK lock) = NULL; 4394541Sru 4494541Srustatic bool sHasSRW = false; 4594541Sru 4694541Srustatic bool loadSRW() { 4794541Sru static bool sChecked = false; 4894541Sru if (!sChecked) { 4994541Sru sChecked = true; 5094541Sru 5194541Sru if (HMODULE hLib = ::GetModuleHandleW(L"Kernel32.dll")) { 5294541Sru fpInitializeSRWLock = 5394541Sru (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib, 5494541Sru "InitializeSRWLock"); 5594541Sru fpAcquireSRWLockExclusive = 5694541Sru (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib, 5794541Sru "AcquireSRWLockExclusive"); 5894541Sru fpAcquireSRWLockShared = 5994541Sru (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib, 6094541Sru "AcquireSRWLockShared"); 6194541Sru fpReleaseSRWLockExclusive = 6294541Sru (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib, 6394541Sru "ReleaseSRWLockExclusive"); 6494541Sru fpReleaseSRWLockShared = 6594541Sru (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib, 6694541Sru "ReleaseSRWLockShared"); 6794541Sru 6894541Sru if (fpInitializeSRWLock != NULL) { 6994541Sru sHasSRW = true; 7094541Sru } 7194541Sru } 7294541Sru } 7394541Sru return sHasSRW; 7494541Sru} 7594541Sru 7694541SruRWMutexImpl::RWMutexImpl() { 7794541Sru if (loadSRW()) { 7894541Sru data_ = calloc(1, sizeof(SRWLOCK)); 7994541Sru fpInitializeSRWLock(static_cast<PSRWLOCK>(data_)); 8094541Sru } else { 8194541Sru data_ = calloc(1, sizeof(CRITICAL_SECTION)); 8294541Sru InitializeCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); 8394541Sru } 8494541Sru} 8594541Sru 8694541SruRWMutexImpl::~RWMutexImpl() { 8794541Sru if (sHasSRW) { 8894541Sru // Nothing to do in the case of slim reader/writers 8994541Sru } else { 9094541Sru DeleteCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); 9194541Sru free(data_); 9294541Sru } 9394541Sru} 9494541Sru 9594541Srubool RWMutexImpl::reader_acquire() { 9694541Sru if (sHasSRW) { 9794541Sru fpAcquireSRWLockShared(static_cast<PSRWLOCK>(data_)); 9894541Sru } else { 9994541Sru EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); 10094541Sru } 10194541Sru return true; 10294541Sru} 10394541Sru 10494541Srubool RWMutexImpl::reader_release() { 10594541Sru if (sHasSRW) { 10694541Sru fpReleaseSRWLockShared(static_cast<PSRWLOCK>(data_)); 10794541Sru } else { 10894541Sru LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); 10994541Sru } 11094541Sru return true; 11194541Sru} 11294541Sru 11394541Srubool RWMutexImpl::writer_acquire() { 11494541Sru if (sHasSRW) { 11594541Sru fpAcquireSRWLockExclusive(static_cast<PSRWLOCK>(data_)); 11694541Sru } else { 11794541Sru EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); 118 } 119 return true; 120} 121 122bool RWMutexImpl::writer_release() { 123 if (sHasSRW) { 124 fpReleaseSRWLockExclusive(static_cast<PSRWLOCK>(data_)); 125 } else { 126 LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); 127 } 128 return true; 129} 130 131 132} 133