summaryrefslogtreecommitdiff
path: root/src/vm/rwlock.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/rwlock.h')
-rw-r--r--src/vm/rwlock.h287
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
-