]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Support/Windows/RWMutex.inc
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Support / Windows / RWMutex.inc
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
75 sys::RWMutexImpl::RWMutexImpl() {
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
85 sys::RWMutexImpl::~RWMutexImpl() {
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
92 bool sys::RWMutexImpl::reader_acquire() {
93   if (sHasSRW) {
94     fpAcquireSRWLockShared(static_cast<PSRWLOCK>(data_));
95   } else {
96     EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
97   }
98   return true;
99 }
100
101 bool sys::RWMutexImpl::reader_release() {
102   if (sHasSRW) {
103     fpReleaseSRWLockShared(static_cast<PSRWLOCK>(data_));
104   } else {
105     LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
106   }
107   return true;
108 }
109
110 bool sys::RWMutexImpl::writer_acquire() {
111   if (sHasSRW) {
112     fpAcquireSRWLockExclusive(static_cast<PSRWLOCK>(data_));
113   } else {
114     EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
115   }
116   return true;
117 }
118
119 bool sys::RWMutexImpl::writer_release() {
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 }