| Charles Davis | 54c9eb6 | 2010-11-29 19:44:50 +0000 | [diff] [blame] | 1 | //= llvm/Support/Win32/Mutex.inc - Win32 Reader/Writer Mutual Exclusion Lock  =// | 
| Michael J. Spencer | 447762d | 2010-11-29 18:16:10 +0000 | [diff] [blame] | 2 | // | 
| Owen Anderson | 324f94c | 2009-06-16 20:19:28 +0000 | [diff] [blame] | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
|  | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
| Michael J. Spencer | 447762d | 2010-11-29 18:16:10 +0000 | [diff] [blame] | 7 | // | 
| Owen Anderson | 324f94c | 2009-06-16 20:19:28 +0000 | [diff] [blame] | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 | // | 
|  | 10 | // This file implements the Win32 specific (non-pthread) RWMutex class. | 
|  | 11 | // | 
|  | 12 | //===----------------------------------------------------------------------===// | 
|  | 13 |  | 
|  | 14 | //===----------------------------------------------------------------------===// | 
|  | 15 | //=== WARNING: Implementation here must contain only generic Win32 code that | 
|  | 16 | //===          is guaranteed to work on *all* Win32 variants. | 
|  | 17 | //===----------------------------------------------------------------------===// | 
|  | 18 |  | 
| Reid Kleckner | d59e2fa | 2014-02-12 21:26:20 +0000 | [diff] [blame] | 19 | #include "WindowsSupport.h" | 
| Owen Anderson | 324f94c | 2009-06-16 20:19:28 +0000 | [diff] [blame] | 20 |  | 
|  | 21 | namespace llvm { | 
| Owen Anderson | 324f94c | 2009-06-16 20:19:28 +0000 | [diff] [blame] | 22 |  | 
| Michael J. Spencer | 0084615 | 2011-10-13 23:10:56 +0000 | [diff] [blame] | 23 | // Windows has slim read-writer lock support on Vista and higher, so we | 
|  | 24 | // will attempt to load the APIs.  If they exist, we will use them, and | 
|  | 25 | // if not, we will fall back on critical sections.  When we drop support | 
|  | 26 | // for XP, we can stop lazy-loading these APIs and just use them directly. | 
|  | 27 | #if defined(__MINGW32__) | 
|  | 28 | // Taken from WinNT.h | 
|  | 29 | typedef struct _RTL_SRWLOCK { | 
|  | 30 | PVOID Ptr; | 
|  | 31 | } RTL_SRWLOCK, *PRTL_SRWLOCK; | 
|  | 32 |  | 
|  | 33 | // Taken from WinBase.h | 
|  | 34 | typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK; | 
|  | 35 | #endif | 
|  | 36 |  | 
|  | 37 | static VOID (WINAPI *fpInitializeSRWLock)(PSRWLOCK lock) = NULL; | 
|  | 38 | static VOID (WINAPI *fpAcquireSRWLockExclusive)(PSRWLOCK lock) = NULL; | 
|  | 39 | static VOID (WINAPI *fpAcquireSRWLockShared)(PSRWLOCK lock) = NULL; | 
|  | 40 | static VOID (WINAPI *fpReleaseSRWLockExclusive)(PSRWLOCK lock) = NULL; | 
|  | 41 | static VOID (WINAPI *fpReleaseSRWLockShared)(PSRWLOCK lock) = NULL; | 
|  | 42 |  | 
|  | 43 | static bool sHasSRW = false; | 
|  | 44 |  | 
|  | 45 | static bool loadSRW() { | 
|  | 46 | static bool sChecked = false; | 
|  | 47 | if (!sChecked) { | 
|  | 48 | sChecked = true; | 
|  | 49 |  | 
| David Majnemer | 7af1857 | 2013-10-14 00:06:58 +0000 | [diff] [blame] | 50 | if (HMODULE hLib = ::GetModuleHandleW(L"Kernel32.dll")) { | 
| Michael J. Spencer | 0084615 | 2011-10-13 23:10:56 +0000 | [diff] [blame] | 51 | fpInitializeSRWLock = | 
|  | 52 | (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib, | 
|  | 53 | "InitializeSRWLock"); | 
|  | 54 | fpAcquireSRWLockExclusive = | 
|  | 55 | (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib, | 
|  | 56 | "AcquireSRWLockExclusive"); | 
|  | 57 | fpAcquireSRWLockShared = | 
|  | 58 | (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib, | 
|  | 59 | "AcquireSRWLockShared"); | 
|  | 60 | fpReleaseSRWLockExclusive = | 
|  | 61 | (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib, | 
|  | 62 | "ReleaseSRWLockExclusive"); | 
|  | 63 | fpReleaseSRWLockShared = | 
|  | 64 | (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib, | 
|  | 65 | "ReleaseSRWLockShared"); | 
| Michael J. Spencer | 0084615 | 2011-10-13 23:10:56 +0000 | [diff] [blame] | 66 |  | 
| Bill Wendling | 2b07965 | 2012-07-19 00:06:06 +0000 | [diff] [blame] | 67 | if (fpInitializeSRWLock != NULL) { | 
|  | 68 | sHasSRW = true; | 
|  | 69 | } | 
| Michael J. Spencer | 0084615 | 2011-10-13 23:10:56 +0000 | [diff] [blame] | 70 | } | 
|  | 71 | } | 
|  | 72 | return sHasSRW; | 
|  | 73 | } | 
|  | 74 |  | 
| Kristof Beyls | a11dbf2 | 2017-03-31 14:26:44 +0000 | [diff] [blame] | 75 | sys::RWMutexImpl::RWMutexImpl() { | 
| Michael J. Spencer | 0084615 | 2011-10-13 23:10:56 +0000 | [diff] [blame] | 76 | if (loadSRW()) { | 
|  | 77 | data_ = calloc(1, sizeof(SRWLOCK)); | 
|  | 78 | fpInitializeSRWLock(static_cast<PSRWLOCK>(data_)); | 
|  | 79 | } else { | 
|  | 80 | data_ = calloc(1, sizeof(CRITICAL_SECTION)); | 
|  | 81 | InitializeCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); | 
|  | 82 | } | 
| Owen Anderson | 74af4ee | 2009-06-17 09:10:42 +0000 | [diff] [blame] | 83 | } | 
| Owen Anderson | 324f94c | 2009-06-16 20:19:28 +0000 | [diff] [blame] | 84 |  | 
| Kristof Beyls | a11dbf2 | 2017-03-31 14:26:44 +0000 | [diff] [blame] | 85 | sys::RWMutexImpl::~RWMutexImpl() { | 
| David Blaikie | df95153 | 2014-10-21 00:34:39 +0000 | [diff] [blame] | 86 | if (!sHasSRW) | 
| Michael J. Spencer | 0084615 | 2011-10-13 23:10:56 +0000 | [diff] [blame] | 87 | DeleteCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); | 
| David Blaikie | df95153 | 2014-10-21 00:34:39 +0000 | [diff] [blame] | 88 | // Nothing to do in the case of slim reader/writers except free the memory. | 
|  | 89 | free(data_); | 
| Owen Anderson | 74af4ee | 2009-06-17 09:10:42 +0000 | [diff] [blame] | 90 | } | 
| Owen Anderson | 324f94c | 2009-06-16 20:19:28 +0000 | [diff] [blame] | 91 |  | 
| Kristof Beyls | a11dbf2 | 2017-03-31 14:26:44 +0000 | [diff] [blame] | 92 | bool sys::RWMutexImpl::reader_acquire() { | 
| Michael J. Spencer | 0084615 | 2011-10-13 23:10:56 +0000 | [diff] [blame] | 93 | if (sHasSRW) { | 
|  | 94 | fpAcquireSRWLockShared(static_cast<PSRWLOCK>(data_)); | 
|  | 95 | } else { | 
|  | 96 | EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); | 
|  | 97 | } | 
| Owen Anderson | 324f94c | 2009-06-16 20:19:28 +0000 | [diff] [blame] | 98 | return true; | 
|  | 99 | } | 
|  | 100 |  | 
| Kristof Beyls | a11dbf2 | 2017-03-31 14:26:44 +0000 | [diff] [blame] | 101 | bool sys::RWMutexImpl::reader_release() { | 
| Michael J. Spencer | 0084615 | 2011-10-13 23:10:56 +0000 | [diff] [blame] | 102 | if (sHasSRW) { | 
|  | 103 | fpReleaseSRWLockShared(static_cast<PSRWLOCK>(data_)); | 
|  | 104 | } else { | 
|  | 105 | LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); | 
|  | 106 | } | 
| Owen Anderson | 324f94c | 2009-06-16 20:19:28 +0000 | [diff] [blame] | 107 | return true; | 
|  | 108 | } | 
|  | 109 |  | 
| Kristof Beyls | a11dbf2 | 2017-03-31 14:26:44 +0000 | [diff] [blame] | 110 | bool sys::RWMutexImpl::writer_acquire() { | 
| Michael J. Spencer | 0084615 | 2011-10-13 23:10:56 +0000 | [diff] [blame] | 111 | if (sHasSRW) { | 
|  | 112 | fpAcquireSRWLockExclusive(static_cast<PSRWLOCK>(data_)); | 
|  | 113 | } else { | 
|  | 114 | EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); | 
|  | 115 | } | 
| Owen Anderson | 324f94c | 2009-06-16 20:19:28 +0000 | [diff] [blame] | 116 | return true; | 
|  | 117 | } | 
|  | 118 |  | 
| Kristof Beyls | a11dbf2 | 2017-03-31 14:26:44 +0000 | [diff] [blame] | 119 | bool sys::RWMutexImpl::writer_release() { | 
| Michael J. Spencer | 0084615 | 2011-10-13 23:10:56 +0000 | [diff] [blame] | 120 | if (sHasSRW) { | 
|  | 121 | fpReleaseSRWLockExclusive(static_cast<PSRWLOCK>(data_)); | 
|  | 122 | } else { | 
|  | 123 | LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); | 
|  | 124 | } | 
| Owen Anderson | 324f94c | 2009-06-16 20:19:28 +0000 | [diff] [blame] | 125 | return true; | 
|  | 126 | } | 
|  | 127 |  | 
|  | 128 |  | 
|  | 129 | } |