blob: 5eb9351eee5268435ed702e60049ccd78a04bd4a [file] [log] [blame]
Charles Davis54c9eb62010-11-29 19:44:50 +00001//= llvm/Support/Win32/Mutex.inc - Win32 Reader/Writer Mutual Exclusion Lock =//
Michael J. Spencer447762d2010-11-29 18:16:10 +00002//
Owen Anderson324f94c2009-06-16 20:19:28 +00003// 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. Spencer447762d2010-11-29 18:16:10 +00007//
Owen Anderson324f94c2009-06-16 20:19:28 +00008//===----------------------------------------------------------------------===//
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 Klecknerd59e2fa2014-02-12 21:26:20 +000019#include "WindowsSupport.h"
Owen Anderson324f94c2009-06-16 20:19:28 +000020
21namespace llvm {
Owen Anderson324f94c2009-06-16 20:19:28 +000022
Michael J. Spencer00846152011-10-13 23:10:56 +000023// 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
37static VOID (WINAPI *fpInitializeSRWLock)(PSRWLOCK lock) = NULL;
38static VOID (WINAPI *fpAcquireSRWLockExclusive)(PSRWLOCK lock) = NULL;
39static VOID (WINAPI *fpAcquireSRWLockShared)(PSRWLOCK lock) = NULL;
40static VOID (WINAPI *fpReleaseSRWLockExclusive)(PSRWLOCK lock) = NULL;
41static VOID (WINAPI *fpReleaseSRWLockShared)(PSRWLOCK lock) = NULL;
42
43static bool sHasSRW = false;
44
45static bool loadSRW() {
46 static bool sChecked = false;
47 if (!sChecked) {
48 sChecked = true;
49
David Majnemer7af18572013-10-14 00:06:58 +000050 if (HMODULE hLib = ::GetModuleHandleW(L"Kernel32.dll")) {
Michael J. Spencer00846152011-10-13 23:10:56 +000051 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. Spencer00846152011-10-13 23:10:56 +000066
Bill Wendling2b079652012-07-19 00:06:06 +000067 if (fpInitializeSRWLock != NULL) {
68 sHasSRW = true;
69 }
Michael J. Spencer00846152011-10-13 23:10:56 +000070 }
71 }
72 return sHasSRW;
73}
74
Kristof Beylsa11dbf22017-03-31 14:26:44 +000075sys::RWMutexImpl::RWMutexImpl() {
Michael J. Spencer00846152011-10-13 23:10:56 +000076 if (loadSRW()) {
Serge Pavlov76d8cce2018-02-20 05:41:26 +000077 data_ = safe_calloc(1, sizeof(SRWLOCK));
Michael J. Spencer00846152011-10-13 23:10:56 +000078 fpInitializeSRWLock(static_cast<PSRWLOCK>(data_));
79 } else {
Serge Pavlov76d8cce2018-02-20 05:41:26 +000080 data_ = safe_calloc(1, sizeof(CRITICAL_SECTION));
Michael J. Spencer00846152011-10-13 23:10:56 +000081 InitializeCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
82 }
Owen Anderson74af4ee2009-06-17 09:10:42 +000083}
Owen Anderson324f94c2009-06-16 20:19:28 +000084
Kristof Beylsa11dbf22017-03-31 14:26:44 +000085sys::RWMutexImpl::~RWMutexImpl() {
David Blaikiedf951532014-10-21 00:34:39 +000086 if (!sHasSRW)
Michael J. Spencer00846152011-10-13 23:10:56 +000087 DeleteCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
David Blaikiedf951532014-10-21 00:34:39 +000088 // Nothing to do in the case of slim reader/writers except free the memory.
89 free(data_);
Owen Anderson74af4ee2009-06-17 09:10:42 +000090}
Owen Anderson324f94c2009-06-16 20:19:28 +000091
Kristof Beylsa11dbf22017-03-31 14:26:44 +000092bool sys::RWMutexImpl::reader_acquire() {
Michael J. Spencer00846152011-10-13 23:10:56 +000093 if (sHasSRW) {
94 fpAcquireSRWLockShared(static_cast<PSRWLOCK>(data_));
95 } else {
96 EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
97 }
Owen Anderson324f94c2009-06-16 20:19:28 +000098 return true;
99}
100
Kristof Beylsa11dbf22017-03-31 14:26:44 +0000101bool sys::RWMutexImpl::reader_release() {
Michael J. Spencer00846152011-10-13 23:10:56 +0000102 if (sHasSRW) {
103 fpReleaseSRWLockShared(static_cast<PSRWLOCK>(data_));
104 } else {
105 LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
106 }
Owen Anderson324f94c2009-06-16 20:19:28 +0000107 return true;
108}
109
Kristof Beylsa11dbf22017-03-31 14:26:44 +0000110bool sys::RWMutexImpl::writer_acquire() {
Michael J. Spencer00846152011-10-13 23:10:56 +0000111 if (sHasSRW) {
112 fpAcquireSRWLockExclusive(static_cast<PSRWLOCK>(data_));
113 } else {
114 EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
115 }
Owen Anderson324f94c2009-06-16 20:19:28 +0000116 return true;
117}
118
Kristof Beylsa11dbf22017-03-31 14:26:44 +0000119bool sys::RWMutexImpl::writer_release() {
Michael J. Spencer00846152011-10-13 23:10:56 +0000120 if (sHasSRW) {
121 fpReleaseSRWLockExclusive(static_cast<PSRWLOCK>(data_));
122 } else {
123 LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
124 }
Owen Anderson324f94c2009-06-16 20:19:28 +0000125 return true;
126}
127
128
129}