LLVM  3.7.0
Windows/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 using namespace sys;
23 
24 // Windows has slim read-writer lock support on Vista and higher, so we
25 // will attempt to load the APIs. If they exist, we will use them, and
26 // if not, we will fall back on critical sections. When we drop support
27 // for XP, we can stop lazy-loading these APIs and just use them directly.
28 #if defined(__MINGW32__)
29  // Taken from WinNT.h
30  typedef struct _RTL_SRWLOCK {
31  PVOID Ptr;
32  } RTL_SRWLOCK, *PRTL_SRWLOCK;
33 
34  // Taken from WinBase.h
35  typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK;
36 #endif
37 
38 static VOID (WINAPI *fpInitializeSRWLock)(PSRWLOCK lock) = NULL;
39 static VOID (WINAPI *fpAcquireSRWLockExclusive)(PSRWLOCK lock) = NULL;
40 static VOID (WINAPI *fpAcquireSRWLockShared)(PSRWLOCK lock) = NULL;
41 static VOID (WINAPI *fpReleaseSRWLockExclusive)(PSRWLOCK lock) = NULL;
42 static VOID (WINAPI *fpReleaseSRWLockShared)(PSRWLOCK lock) = NULL;
43 
44 static bool sHasSRW = false;
45 
46 static bool loadSRW() {
47  static bool sChecked = false;
48  if (!sChecked) {
49  sChecked = true;
50 
51  if (HMODULE hLib = ::GetModuleHandleW(L"Kernel32.dll")) {
52  fpInitializeSRWLock =
53  (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
54  "InitializeSRWLock");
55  fpAcquireSRWLockExclusive =
56  (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
57  "AcquireSRWLockExclusive");
58  fpAcquireSRWLockShared =
59  (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
60  "AcquireSRWLockShared");
61  fpReleaseSRWLockExclusive =
62  (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
63  "ReleaseSRWLockExclusive");
64  fpReleaseSRWLockShared =
65  (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
66  "ReleaseSRWLockShared");
67 
68  if (fpInitializeSRWLock != NULL) {
69  sHasSRW = true;
70  }
71  }
72  }
73  return sHasSRW;
74 }
75 
77  if (loadSRW()) {
78  data_ = calloc(1, sizeof(SRWLOCK));
79  fpInitializeSRWLock(static_cast<PSRWLOCK>(data_));
80  } else {
81  data_ = calloc(1, sizeof(CRITICAL_SECTION));
82  InitializeCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
83  }
84 }
85 
87  if (!sHasSRW)
88  DeleteCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
89  // Nothing to do in the case of slim reader/writers except free the memory.
90  free(data_);
91 }
92 
94  if (sHasSRW) {
95  fpAcquireSRWLockShared(static_cast<PSRWLOCK>(data_));
96  } else {
97  EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
98  }
99  return true;
100 }
101 
103  if (sHasSRW) {
104  fpReleaseSRWLockShared(static_cast<PSRWLOCK>(data_));
105  } else {
106  LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
107  }
108  return true;
109 }
110 
112  if (sHasSRW) {
113  fpAcquireSRWLockExclusive(static_cast<PSRWLOCK>(data_));
114  } else {
115  EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
116  }
117  return true;
118 }
119 
121  if (sHasSRW) {
122  fpReleaseSRWLockExclusive(static_cast<PSRWLOCK>(data_));
123  } else {
124  LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
125  }
126  return true;
127 }
128 
129 
130 }
~RWMutexImpl()
Releases and removes the lock.
Definition: RWMutex.cpp:68
bool writer_release()
Attempts to release the lock in writer mode.
Definition: RWMutex.cpp:107
bool writer_acquire()
Attempts to unconditionally acquire the lock in reader mode.
Definition: RWMutex.cpp:97
bool reader_acquire()
Attempts to unconditionally acquire the lock in reader mode.
Definition: RWMutex.cpp:77
RWMutexImpl()
Initializes the lock but doesn't acquire it.
Definition: RWMutex.cpp:46
bool reader_release()
Attempts to release the lock in reader mode.
Definition: RWMutex.cpp:87