diff options
Diffstat (limited to 'src/vm/rwlock.h')
-rw-r--r-- | src/vm/rwlock.h | 287 |
1 files changed, 0 insertions, 287 deletions
diff --git a/src/vm/rwlock.h b/src/vm/rwlock.h deleted file mode 100644 index dc8e67e6fb..0000000000 --- a/src/vm/rwlock.h +++ /dev/null @@ -1,287 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. -// - -// -//+------------------------------------------------------------------- -// -// File: RWLock.h -// -// Contents: Reader writer lock implementation that supports the -// following features -// 1. Cheap enough to be used in large numbers -// such as per object synchronization. -// 2. Supports timeout. This is a valuable feature -// to detect deadlocks -// 3. Supports caching of events. The allows -// the events to be moved from least contentious -// regions to the most contentious regions. -// In other words, the number of events needed by -// Reader-Writer lockls is bounded by the number -// of threads in the process. -// 4. Supports nested locks by readers and writers -// 5. Supports spin counts for avoiding context switches -// on multi processor machines. -// 6. Supports functionality for upgrading to a writer -// lock with a return argument that indicates -// intermediate writes. Downgrading from a writer -// lock restores the state of the lock. -// 7. Supports functionality to Release Lock for calling -// app code. RestoreLock restores the lock state and -// indicates intermediate writes. -// 8. Recovers from most common failures such as creation of -// events. In other words, the lock mainitains consistent -// internal state and remains usable -// -// Classes: CRWLock, -// CStaticRWLock -// -//-------------------------------------------------------------------- - -#ifdef FEATURE_RWLOCK -#ifndef _RWLOCK_H_ -#define _RWLOCK_H_ -#include "common.h" -#include "threads.h" - -// If you do define this, make sure you define this in managed as well. -//#define RWLOCK_STATISTICS 0 - -extern DWORD gdwDefaultTimeout; -extern DWORD gdwDefaultSpinCount; - - -//+------------------------------------------------------------------- -// -// Struct: LockCookie -// -// Synopsis: Lock cookies returned to the client -// -//+------------------------------------------------------------------- -typedef struct { - DWORD dwFlags; - DWORD dwWriterSeqNum; - WORD wReaderLevel; - WORD wWriterLevel; - DWORD dwThreadID; -} LockCookie; - -//+------------------------------------------------------------------- -// -// Class: CRWLock -// -// Synopsis: Class the implements the reader writer locks. -// -//+------------------------------------------------------------------- -class CRWLock : public Object -{ - friend class MscorlibBinder; - -public: - // Constuctor - CRWLock(); - - // Cleanup - void Cleanup(); - - OBJECTHANDLE GetObjectHandle(); - HRESULT CreateOwnerIterator(SIZE_T *pIterator); - static void GetNextOwner(SIZE_T Iterator, IHostTask **ppOwnerHostTask); - static void DeleteOwnerIterator(SIZE_T Iterator); - - // Statics that do the core work - static FCDECL1 (void, StaticPrivateInitialize, CRWLock *pRWLock); - static FCDECL1 (void, StaticPrivateDestruct, CRWLock *pRWLock); - static FCDECL2 (void, StaticAcquireReaderLockPublic, CRWLock *pRWLock, DWORD dwDesiredTimeout); - static FCDECL2 (void, StaticAcquireWriterLockPublic, CRWLock *pRWLock, DWORD dwDesiredTimeout); - static FCDECL1 (void, StaticReleaseReaderLockPublic, CRWLock *pRWLock); - static FCDECL1 (void, StaticReleaseWriterLockPublic, CRWLock *pRWLock); - static FCDECL3 (void, StaticDoUpgradeToWriterLockPublic, CRWLock *pRWLock, LockCookie * pLockCookie, DWORD dwDesiredTimeout); - static FCDECL2 (void, StaticDowngradeFromWriterLock, CRWLock *pRWLock, LockCookie* pLockCookie); - static FCDECL2 (void, StaticDoReleaseLock, CRWLock *pRWLock, LockCookie * pLockCookie); - static FCDECL2 (void, StaticRestoreLockPublic, CRWLock *pRWLock, LockCookie* pLockCookie); - static FCDECL1 (FC_BOOL_RET, StaticIsReaderLockHeld, CRWLock *pRWLock); - static FCDECL1 (FC_BOOL_RET, StaticIsWriterLockHeld, CRWLock *pRWLock); - static FCDECL1 (INT32, StaticGetWriterSeqNum, CRWLock *pRWLock); - static FCDECL2 (FC_BOOL_RET, StaticAnyWritersSince, CRWLock *pRWLock, DWORD dwSeqNum); -private: - static void StaticAcquireReaderLock(CRWLock **ppRWLock, DWORD dwDesiredTimeout); - static void StaticAcquireWriterLock(CRWLock **ppRWLock, DWORD dwDesiredTimeout); - static void StaticReleaseReaderLock(CRWLock **ppRWLock); - static void StaticReleaseWriterLock(CRWLock **ppRWLock); - static void StaticRecoverLock(CRWLock **ppRWLock, LockCookie *pLockCookie, DWORD dwFlags); - static void StaticRestoreLock(CRWLock **ppRWLock, LockCookie *pLockCookie); - static void StaticUpgradeToWriterLock(CRWLock **ppRWLock, LockCookie *pLockCookie, DWORD dwDesiredTimeout); -public: - // Assert functions -#ifdef _DEBUG - BOOL AssertWriterLockHeld(); - BOOL AssertWriterLockNotHeld(); - BOOL AssertReaderLockHeld(); - BOOL AssertReaderLockNotHeld(); - BOOL AssertReaderOrWriterLockHeld(); - void AssertHeld() - { - WRAPPER_NO_CONTRACT; - AssertWriterLockHeld(); - } - void AssertNotHeld() - { - WRAPPER_NO_CONTRACT; - AssertWriterLockNotHeld(); - AssertReaderLockNotHeld(); - } -#else - void AssertWriterLockHeld() { LIMITED_METHOD_CONTRACT; } - void AssertWriterLockNotHeld() { LIMITED_METHOD_CONTRACT; } - void AssertReaderLockHeld() { LIMITED_METHOD_CONTRACT; } - void AssertReaderLockNotHeld() { LIMITED_METHOD_CONTRACT; } - void AssertReaderOrWriterLockHeld() { LIMITED_METHOD_CONTRACT; } - void AssertHeld() { LIMITED_METHOD_CONTRACT; } - void AssertNotHeld() { LIMITED_METHOD_CONTRACT; } -#endif - - // Helper functions -#ifdef RWLOCK_STATISTICS - DWORD GetReaderEntryCount() - { - LIMITED_METHOD_CONTRACT; - return(_dwReaderEntryCount); - } - DWORD GetReaderContentionCount() { LIMITED_METHOD_CONTRACT; return(_dwReaderContentionCount); } - DWORD GetWriterEntryCount() { LIMITED_METHOD_CONTRACT; return(_dwWriterEntryCount); } - DWORD GetWriterContentionCount() { LIMITED_METHOD_CONTRACT; return(_dwWriterContentionCount); } -#endif - // Static functions - static void *operator new(size_t size) - { - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - } - CONTRACTL_END; - - return ::operator new(size); - } - static void ProcessInit(); - - static void SetTimeout(DWORD dwTimeout) - { - LIMITED_METHOD_CONTRACT; - - gdwDefaultTimeout = dwTimeout; - } - static DWORD GetTimeout() - { - LIMITED_METHOD_CONTRACT; - return(gdwDefaultTimeout); - } - static void SetSpinCount(DWORD dwSpinCount) - { - LIMITED_METHOD_CONTRACT; - - gdwDefaultSpinCount = g_SystemInfo.dwNumberOfProcessors > 1 - ? dwSpinCount - : 0; - } - static DWORD GetSpinCount() { LIMITED_METHOD_CONTRACT; return(gdwDefaultSpinCount); } - -private: - // Private helpers - static void ChainEntry(Thread *pThread, LockEntry *pLockEntry); - LockEntry *GetLockEntry(Thread *pThread = NULL); - LockEntry *FastGetOrCreateLockEntry(); - LockEntry *SlowGetOrCreateLockEntry(Thread *pThread); - void FastRecycleLockEntry(LockEntry *pLockEntry); - static void RecycleLockEntry(LockEntry *pLockEntry); - - CLREvent* GetReaderEvent(HRESULT *pHR); - CLREvent* GetWriterEvent(HRESULT *pHR); - void ReleaseEvents(); - - static LONG RWInterlockedCompareExchange(LONG RAW_KEYWORD(volatile) *pvDestination, - LONG dwExchange, - LONG dwComperand); - static LONGLONG RWInterlockedCompareExchange64(LONGLONG RAW_KEYWORD(volatile) *pvDestination, - LONGLONG qwExchange, - LONGLONG qwComparand); - static void* RWInterlockedCompareExchangePointer(PVOID RAW_KEYWORD(volatile) *pvDestination, - PVOID pExchange, - PVOID pComparand); - static LONG RWInterlockedExchangeAdd(LONG RAW_KEYWORD(volatile) *pvDestination, LONG dwAddState); - static LONG RWInterlockedIncrement(LONG RAW_KEYWORD(volatile) *pdwState); - - static DWORD RWWaitForSingleObject(CLREvent* event, DWORD dwTimeout); - static void RWSetEvent(CLREvent* event); - static void RWResetEvent(CLREvent* event); - static void RWSleep(DWORD dwTime); - -#if defined(ENABLE_CONTRACTS_IMPL) - // The LOCK_TAKEN/RELEASED macros need a "pointer" to the lock object to do - // comparisons between takes & releases (and to provide debugging info to the - // developer). We can't use "this" (*ppRWLock), because CRWLock is an Object and thus - // can move. So we use _dwLLockID instead. It's not exactly unique, but it's - // good enough--worst that can happen is if a thread takes RWLock A and erroneously - // releases RWLock B (instead of A), we'll fail to catch that if their _dwLLockID's - // are the same. On 64 bits, we can use both _dwULockID & _dwLLockID and be unique - static void * GetPtrForLockContract(CRWLock ** ppRWLock) - { -#if defined(_WIN64) - return (void *) - ( - ( - ((__int64) ((*ppRWLock)->_dwULockID)) << 32 - ) - | - ( - (__int64) ((*ppRWLock)->_dwLLockID) - ) - ); -#else //defined(_WIN64) - return LongToPtr((*ppRWLock)->_dwLLockID); -#endif //defined(_WIN64) - } -#endif //defined(ENABLE_CONTRACTS_IMPL) - - // private new - static void *operator new(size_t size, void *pv) { LIMITED_METHOD_CONTRACT; return(pv); } - - // Private data - CLREvent *_hWriterEvent; - CLREvent *_hReaderEvent; - OBJECTHANDLE _hObjectHandle; - Volatile<LONG> _dwState; - LONG _dwULockID; - LONG _dwLLockID; - DWORD _dwWriterID; - DWORD _dwWriterSeqNum; - WORD _wWriterLevel; -#ifdef RWLOCK_STATISTICS - // WARNING: You must explicitly #define RWLOCK_STATISTICS when you build - // in both the VM and BCL directories, as the managed class must also - // contain these fields! - Volatile<LONG> _dwReaderEntryCount; - Volatile<LONG> _dwReaderContentionCount; - Volatile<LONG> _dwWriterEntryCount; - Volatile<LONG> _dwWriterContentionCount; - Volatile<LONG> _dwEventsReleasedCount; -#endif - - // Static data - static Volatile<LONGLONG> s_mostRecentLockID; - static CrstStatic s_RWLockCrst; -}; - -#ifdef USE_CHECKED_OBJECTREFS -typedef REF<CRWLock> RWLOCKREF; - -#else -typedef CRWLock* RWLOCKREF; -#endif - -#endif // _RWLOCK_H_ - -#endif // FEATURE_RWLOCK - |