[llvm-objdump] - Import the test/Object/X86/no-start-symbol.test test case and rewrit...
[llvm-complete.git] / lib / Support / Windows / RWMutex.inc
blob8df9bc394160338ee3d4a76c0fe4ad48f3a27379
1 //= llvm/Support/Win32/Mutex.inc - Win32 Reader/Writer Mutual Exclusion Lock  =//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the Win32 specific (non-pthread) RWMutex class.
11 //===----------------------------------------------------------------------===//
13 //===----------------------------------------------------------------------===//
14 //=== WARNING: Implementation here must contain only generic Win32 code that
15 //===          is guaranteed to work on *all* Win32 variants.
16 //===----------------------------------------------------------------------===//
18 #include "WindowsSupport.h"
20 namespace llvm {
22 // Windows has slim read-writer lock support on Vista and higher, so we
23 // will attempt to load the APIs.  If they exist, we will use them, and
24 // if not, we will fall back on critical sections.  When we drop support
25 // for XP, we can stop lazy-loading these APIs and just use them directly.
26 #if defined(__MINGW32__)
27   // Taken from WinNT.h
28   typedef struct _RTL_SRWLOCK {
29     PVOID Ptr;
30   } RTL_SRWLOCK, *PRTL_SRWLOCK;
32   // Taken from WinBase.h
33   typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK;
34 #endif
36 static VOID (WINAPI *fpInitializeSRWLock)(PSRWLOCK lock) = NULL;
37 static VOID (WINAPI *fpAcquireSRWLockExclusive)(PSRWLOCK lock) = NULL;
38 static VOID (WINAPI *fpAcquireSRWLockShared)(PSRWLOCK lock) = NULL;
39 static VOID (WINAPI *fpReleaseSRWLockExclusive)(PSRWLOCK lock) = NULL;
40 static VOID (WINAPI *fpReleaseSRWLockShared)(PSRWLOCK lock) = NULL;
42 static bool sHasSRW = false;
44 static bool loadSRW() {
45   static bool sChecked = false;
46   if (!sChecked) {
47     sChecked = true;
49     if (HMODULE hLib = ::GetModuleHandleW(L"Kernel32.dll")) {
50       fpInitializeSRWLock =
51         (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
52                                                "InitializeSRWLock");
53       fpAcquireSRWLockExclusive =
54         (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
55                                                "AcquireSRWLockExclusive");
56       fpAcquireSRWLockShared =
57         (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
58                                                "AcquireSRWLockShared");
59       fpReleaseSRWLockExclusive =
60         (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
61                                                "ReleaseSRWLockExclusive");
62       fpReleaseSRWLockShared =
63         (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
64                                                "ReleaseSRWLockShared");
66       if (fpInitializeSRWLock != NULL) {
67         sHasSRW = true;
68       }
69     }
70   }
71   return sHasSRW;
74 sys::RWMutexImpl::RWMutexImpl() {
75   if (loadSRW()) {
76     data_ = safe_calloc(1, sizeof(SRWLOCK));
77     fpInitializeSRWLock(static_cast<PSRWLOCK>(data_));
78   } else {
79     data_ = safe_calloc(1, sizeof(CRITICAL_SECTION));
80     InitializeCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
81   }
84 sys::RWMutexImpl::~RWMutexImpl() {
85   if (!sHasSRW)
86     DeleteCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
87   // Nothing to do in the case of slim reader/writers except free the memory.
88   free(data_);
91 bool sys::RWMutexImpl::reader_acquire() {
92   if (sHasSRW) {
93     fpAcquireSRWLockShared(static_cast<PSRWLOCK>(data_));
94   } else {
95     EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
96   }
97   return true;
100 bool sys::RWMutexImpl::reader_release() {
101   if (sHasSRW) {
102     fpReleaseSRWLockShared(static_cast<PSRWLOCK>(data_));
103   } else {
104     LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
105   }
106   return true;
109 bool sys::RWMutexImpl::writer_acquire() {
110   if (sHasSRW) {
111     fpAcquireSRWLockExclusive(static_cast<PSRWLOCK>(data_));
112   } else {
113     EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
114   }
115   return true;
118 bool sys::RWMutexImpl::writer_release() {
119   if (sHasSRW) {
120     fpReleaseSRWLockExclusive(static_cast<PSRWLOCK>(data_));
121   } else {
122     LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
123   }
124   return true;