[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