[llvm-commits] [llvm] r141907 - /llvm/trunk/lib/Support/Windows/RWMutex.inc
NAKAMURA Takumi
geek4civic at gmail.com
Tue Nov 15 23:05:58 PST 2011
Bill please revert it on release_30, if we should resolve compile
error on Visual Studio 2005.
It is not needed to revert on ToT. IMO, we have to introduce NT6
header checking in future.
...Takumi
2011/10/14 Michael J. Spencer <bigcheesegs at gmail.com>:
> Author: mspencer
> Date: Thu Oct 13 18:10:56 2011
> New Revision: 141907
>
> URL: http://llvm.org/viewvc/llvm-project?rev=141907&view=rev
> Log:
> Support/Windows: Add efficent RW mutex on Windows. Patch by Aaron Ballman!
>
> Modified:
> llvm/trunk/lib/Support/Windows/RWMutex.inc
>
> Modified: llvm/trunk/lib/Support/Windows/RWMutex.inc
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/RWMutex.inc?rev=141907&r1=141906&r2=141907&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Support/Windows/RWMutex.inc (original)
> +++ llvm/trunk/lib/Support/Windows/RWMutex.inc Thu Oct 13 18:10:56 2011
> @@ -18,39 +18,115 @@
>
> #include "Windows.h"
>
> -// FIXME: Windows does not have reader-writer locks pre-Vista. If you want
> -// real reader-writer locks, you a threads implementation for Windows.
> -
> namespace llvm {
> using namespace sys;
>
> +// Windows has slim read-writer lock support on Vista and higher, so we
> +// will attempt to load the APIs. If they exist, we will use them, and
> +// if not, we will fall back on critical sections. When we drop support
> +// for XP, we can stop lazy-loading these APIs and just use them directly.
> +#if defined(__MINGW32__)
> + // Taken from WinNT.h
> + typedef struct _RTL_SRWLOCK {
> + PVOID Ptr;
> + } RTL_SRWLOCK, *PRTL_SRWLOCK;
> +
> + // Taken from WinBase.h
> + typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK;
> +#endif
> +
> +static VOID (WINAPI *fpInitializeSRWLock)(PSRWLOCK lock) = NULL;
> +static VOID (WINAPI *fpAcquireSRWLockExclusive)(PSRWLOCK lock) = NULL;
> +static VOID (WINAPI *fpAcquireSRWLockShared)(PSRWLOCK lock) = NULL;
> +static VOID (WINAPI *fpReleaseSRWLockExclusive)(PSRWLOCK lock) = NULL;
> +static VOID (WINAPI *fpReleaseSRWLockShared)(PSRWLOCK lock) = NULL;
> +
> +static bool sHasSRW = false;
> +
> +static bool loadSRW() {
> + static bool sChecked = false;
> + if (!sChecked) {
> + sChecked = true;
> +
> + HMODULE hLib = ::LoadLibrary(TEXT("Kernel32"));
> + if (hLib) {
> + fpInitializeSRWLock =
> + (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
> + "InitializeSRWLock");
> + fpAcquireSRWLockExclusive =
> + (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
> + "AcquireSRWLockExclusive");
> + fpAcquireSRWLockShared =
> + (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
> + "AcquireSRWLockShared");
> + fpReleaseSRWLockExclusive =
> + (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
> + "ReleaseSRWLockExclusive");
> + fpReleaseSRWLockShared =
> + (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
> + "ReleaseSRWLockShared");
> + ::FreeLibrary(hLib);
> +
> + if (fpInitializeSRWLock != NULL) {
> + sHasSRW = true;
> + }
> + }
> + }
> + return sHasSRW;
> +}
> +
> RWMutexImpl::RWMutexImpl() {
> - data_ = calloc(1, sizeof(CRITICAL_SECTION));
> - InitializeCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
> + if (loadSRW()) {
> + data_ = calloc(1, sizeof(SRWLOCK));
> + fpInitializeSRWLock(static_cast<PSRWLOCK>(data_));
> + } else {
> + data_ = calloc(1, sizeof(CRITICAL_SECTION));
> + InitializeCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
> + }
> }
>
> RWMutexImpl::~RWMutexImpl() {
> - DeleteCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
> - free(data_);
> + if (sHasSRW) {
> + // Nothing to do in the case of slim reader/writers
> + } else {
> + DeleteCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
> + free(data_);
> + }
> }
>
> bool RWMutexImpl::reader_acquire() {
> - EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
> + if (sHasSRW) {
> + fpAcquireSRWLockShared(static_cast<PSRWLOCK>(data_));
> + } else {
> + EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
> + }
> return true;
> }
>
> bool RWMutexImpl::reader_release() {
> - LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
> + if (sHasSRW) {
> + fpReleaseSRWLockShared(static_cast<PSRWLOCK>(data_));
> + } else {
> + LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
> + }
> return true;
> }
>
> bool RWMutexImpl::writer_acquire() {
> - EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
> + if (sHasSRW) {
> + fpAcquireSRWLockExclusive(static_cast<PSRWLOCK>(data_));
> + } else {
> + EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
> + }
> return true;
> }
>
> bool RWMutexImpl::writer_release() {
> - LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
> + if (sHasSRW) {
> + fpReleaseSRWLockExclusive(static_cast<PSRWLOCK>(data_));
> + } else {
> + LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
> + }
> return true;
> }
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
More information about the llvm-commits
mailing list