LLVM API Documentation

Windows/RWMutex.inc
Go to the documentation of this file.
00001 //= llvm/Support/Win32/Mutex.inc - Win32 Reader/Writer Mutual Exclusion Lock  =//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the Win32 specific (non-pthread) RWMutex class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 //===----------------------------------------------------------------------===//
00015 //=== WARNING: Implementation here must contain only generic Win32 code that
00016 //===          is guaranteed to work on *all* Win32 variants.
00017 //===----------------------------------------------------------------------===//
00018 
00019 #include "WindowsSupport.h"
00020 
00021 namespace llvm {
00022 using namespace sys;
00023 
00024 // Windows has slim read-writer lock support on Vista and higher, so we
00025 // will attempt to load the APIs.  If they exist, we will use them, and
00026 // if not, we will fall back on critical sections.  When we drop support
00027 // for XP, we can stop lazy-loading these APIs and just use them directly.
00028 #if defined(__MINGW32__)
00029   // Taken from WinNT.h
00030   typedef struct _RTL_SRWLOCK {
00031     PVOID Ptr;
00032   } RTL_SRWLOCK, *PRTL_SRWLOCK;
00033 
00034   // Taken from WinBase.h
00035   typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK;
00036 #endif
00037 
00038 static VOID (WINAPI *fpInitializeSRWLock)(PSRWLOCK lock) = NULL;
00039 static VOID (WINAPI *fpAcquireSRWLockExclusive)(PSRWLOCK lock) = NULL;
00040 static VOID (WINAPI *fpAcquireSRWLockShared)(PSRWLOCK lock) = NULL;
00041 static VOID (WINAPI *fpReleaseSRWLockExclusive)(PSRWLOCK lock) = NULL;
00042 static VOID (WINAPI *fpReleaseSRWLockShared)(PSRWLOCK lock) = NULL;
00043 
00044 static bool sHasSRW = false;
00045 
00046 static bool loadSRW() {
00047   static bool sChecked = false;
00048   if (!sChecked) {
00049     sChecked = true;
00050 
00051     if (HMODULE hLib = ::GetModuleHandleW(L"Kernel32.dll")) {
00052       fpInitializeSRWLock =
00053         (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
00054                                                "InitializeSRWLock");
00055       fpAcquireSRWLockExclusive =
00056         (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
00057                                                "AcquireSRWLockExclusive");
00058       fpAcquireSRWLockShared =
00059         (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
00060                                                "AcquireSRWLockShared");
00061       fpReleaseSRWLockExclusive =
00062         (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
00063                                                "ReleaseSRWLockExclusive");
00064       fpReleaseSRWLockShared =
00065         (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
00066                                                "ReleaseSRWLockShared");
00067 
00068       if (fpInitializeSRWLock != NULL) {
00069         sHasSRW = true;
00070       }
00071     }
00072   }
00073   return sHasSRW;
00074 }
00075 
00076 RWMutexImpl::RWMutexImpl() {
00077   if (loadSRW()) {
00078     data_ = calloc(1, sizeof(SRWLOCK));
00079     fpInitializeSRWLock(static_cast<PSRWLOCK>(data_));
00080   } else {
00081     data_ = calloc(1, sizeof(CRITICAL_SECTION));
00082     InitializeCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
00083   }
00084 }
00085 
00086 RWMutexImpl::~RWMutexImpl() {
00087   if (sHasSRW) {
00088     // Nothing to do in the case of slim reader/writers
00089   } else {
00090     DeleteCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
00091     free(data_);
00092   }
00093 }
00094 
00095 bool RWMutexImpl::reader_acquire() {
00096   if (sHasSRW) {
00097     fpAcquireSRWLockShared(static_cast<PSRWLOCK>(data_));
00098   } else {
00099     EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
00100   }
00101   return true;
00102 }
00103 
00104 bool RWMutexImpl::reader_release() {
00105   if (sHasSRW) {
00106     fpReleaseSRWLockShared(static_cast<PSRWLOCK>(data_));
00107   } else {
00108     LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
00109   }
00110   return true;
00111 }
00112 
00113 bool RWMutexImpl::writer_acquire() {
00114   if (sHasSRW) {
00115     fpAcquireSRWLockExclusive(static_cast<PSRWLOCK>(data_));
00116   } else {
00117     EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
00118   }
00119   return true;
00120 }
00121 
00122 bool RWMutexImpl::writer_release() {
00123   if (sHasSRW) {
00124     fpReleaseSRWLockExclusive(static_cast<PSRWLOCK>(data_));
00125   } else {
00126     LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
00127   }
00128   return true;
00129 }
00130 
00131 
00132 }