#define RWLOCK_MAX_ACQUIRE_COUNT 0xFFFF
// globals
-Volatile<LONG> CRWLock::s_mostRecentLLockID = 0;
-Volatile<LONG> CRWLock::s_mostRecentULockID = -1;
+Volatile<LONGLONG> CRWLock::s_mostRecentLockID = 0;
CrstStatic CRWLock::s_RWLockCrst;
// Default values
}
CONTRACT_END;
- LONG dwKnownLLockID;
- LONG dwULockID = s_mostRecentULockID;
- LONG dwLLockID = s_mostRecentLLockID;
- do
+ LONGLONG qwLockID = s_mostRecentLockID;
+ while (true)
{
- dwKnownLLockID = dwLLockID;
- if(dwKnownLLockID != 0)
+ LONGLONG qwNextLockID = qwLockID + 1;
+ if (static_cast<LONG>(qwNextLockID) == 0)
{
- dwLLockID = RWInterlockedCompareExchange(&s_mostRecentLLockID, dwKnownLLockID+1, dwKnownLLockID);
+ // A value of zero for the lower half of the ID is reserved to identify that a thread does not own any RW locks,
+ // regardless of the upper half of the ID
+ ++qwNextLockID;
}
- else
+
+ LONGLONG qwLockIDBeforeExchange = RWInterlockedCompareExchange64(&s_mostRecentLockID, qwNextLockID, qwLockID);
+ if (qwLockIDBeforeExchange == qwLockID)
{
- CrstHolder ch(&s_RWLockCrst);
-
- if(s_mostRecentLLockID == 0)
- {
- dwULockID = ++s_mostRecentULockID;
- dwLLockID = s_mostRecentLLockID++;
- dwKnownLLockID = dwLLockID;
- }
- else
- {
- dwULockID = s_mostRecentULockID;
- dwLLockID = s_mostRecentLLockID;
- }
+ qwLockID = qwNextLockID;
+ break;
}
- } while(dwKnownLLockID != dwLLockID);
- _dwLLockID = ++dwLLockID;
- _dwULockID = dwULockID;
+ qwLockID = qwLockIDBeforeExchange;
+ }
+
+ _dwLLockID = static_cast<LONG>(qwLockID);
+ _dwULockID = static_cast<LONG>(qwLockID >> 32);
RETURN;
}
dwComparand);
}
+inline LONGLONG CRWLock::RWInterlockedCompareExchange64(LONGLONG volatile *pvDestination,
+ LONGLONG qwExchange,
+ LONGLONG qwComparand)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ return FastInterlockCompareExchangeLong(pvDestination, qwExchange, qwComparand);
+}
+
inline void* CRWLock::RWInterlockedCompareExchangePointer(PVOID volatile *pvDestination,
void* pExchange,
void* pComparand)
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);
#endif
// Static data
- static Volatile<LONG> s_mostRecentULockID;
- static Volatile<LONG> s_mostRecentLLockID;
+ static Volatile<LONGLONG> s_mostRecentLockID;
static CrstStatic s_RWLockCrst;
};