LLVM  8.0.1
RWMutex.inc
Go to the documentation of this file.
1 //= llvm/Support/Win32/Mutex.inc - Win32 Reader/Writer Mutual Exclusion Lock =//
2 //
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.
7 //
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 
19 #include "WindowsSupport.h"
20 
21 namespace llvm {
22 
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 
50  if (HMODULE hLib = ::GetModuleHandleW(L"Kernel32.dll")) {
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");
66 
67  if (fpInitializeSRWLock != NULL) {
68  sHasSRW = true;
69  }
70  }
71  }
72  return sHasSRW;
73 }
74 
76  if (loadSRW()) {
77  data_ = safe_calloc(1, sizeof(SRWLOCK));
78  fpInitializeSRWLock(static_cast<PSRWLOCK>(data_));
79  } else {
80  data_ = safe_calloc(1, sizeof(CRITICAL_SECTION));
81  InitializeCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
82  }
83 }
84 
86  if (!sHasSRW)
87  DeleteCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
88  // Nothing to do in the case of slim reader/writers except free the memory.
89  free(data_);
90 }
91 
93  if (sHasSRW) {
94  fpAcquireSRWLockShared(static_cast<PSRWLOCK>(data_));
95  } else {
96  EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
97  }
98  return true;
99 }
100 
102  if (sHasSRW) {
103  fpReleaseSRWLockShared(static_cast<PSRWLOCK>(data_));
104  } else {
105  LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
106  }
107  return true;
108 }
109 
111  if (sHasSRW) {
112  fpAcquireSRWLockExclusive(static_cast<PSRWLOCK>(data_));
113  } else {
114  EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
115  }
116  return true;
117 }
118 
120  if (sHasSRW) {
121  fpReleaseSRWLockExclusive(static_cast<PSRWLOCK>(data_));
122  } else {
123  LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
124  }
125  return true;
126 }
127 
128 
129 }
This class represents lattice values for constants.
Definition: AllocatorList.h:24
bool reader_release()
Attempts to release the lock in reader mode.
Definition: RWMutex.cpp:89
bool writer_acquire()
Attempts to unconditionally acquire the lock in reader mode.
Definition: RWMutex.cpp:99
bool reader_acquire()
Attempts to unconditionally acquire the lock in reader mode.
Definition: RWMutex.cpp:79
RWMutexImpl()
Initializes the lock but doesn&#39;t acquire it.
Definition: RWMutex.cpp:49
LLVM_ATTRIBUTE_RETURNS_NONNULL void * safe_calloc(size_t Count, size_t Sz)
Definition: MemAlloc.h:33
bool writer_release()
Attempts to release the lock in writer mode.
Definition: RWMutex.cpp:109
~RWMutexImpl()
Releases and removes the lock Destructor.
Definition: RWMutex.cpp:70