Leaked source code of windows server 2003
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/*==========================================================================*\
Module: spinlock.h
Copyright Microsoft Corporation 1996, All Rights Reserved.
Author: mikepurt
Descriptions: Implements a spin lock that can be used on Shared Memory
\*==========================================================================*/
#ifndef __SPINLOCK_H__
#define __SPINLOCK_H__
//
// This correct value of the spin count will depend heavily on how much time
// is spent holding the lock.
//
const DWORD DEFAULT_SPIN_COUNT = 500; // ??
const DWORD SPIN_UNLOCKED = 0;
/*$--CSpinLock==============================================================*\
\*==========================================================================*/
class CSpinLock { public: void Initialize(IN DWORD cMaxSpin = DEFAULT_SPIN_COUNT); void Acquire(); void Relinquish(); void ResetIfOwnedByOtherProcess(); private: BOOL m_fMultiProc; DWORD m_cMaxSpin; volatile DWORD m_dwLock; };
/*$--CSpinLock::Initialize==================================================*\
\*==========================================================================*/
inline void CSpinLock::Initialize(IN DWORD cMaxSpin) { SYSTEM_INFO si; GetSystemInfo(&si); m_fMultiProc = (si.dwNumberOfProcessors > 1); m_dwLock = SPIN_UNLOCKED; m_cMaxSpin = cMaxSpin; }
/*$--CSpinLock::Acquire=====================================================*\
\*==========================================================================*/
inline void CSpinLock::Acquire() { DWORD cSpin = m_cMaxSpin; DWORD dwLockId = GetCurrentProcessId();
while(InterlockedCompareExchange((LONG *)&m_dwLock, dwLockId, SPIN_UNLOCKED)) { // We should only spin if we're running on a multiprocessor
if (m_fMultiProc) { if (cSpin--) continue; cSpin = m_cMaxSpin; } Sleep(0); // Deschedule ourselves and let whomever has the lock get out
} }
/*$--CSpinLock::Relinquish==================================================*\
\*==========================================================================*/
inline void CSpinLock::Relinquish() { Assert(m_dwLock); m_dwLock = SPIN_UNLOCKED; }
/*$--CSpinLock::ResetIfOwnedByOtherProcess==================================*\
This method is needed to reset the spin lock in the case where it was being held by a process that died and didn't have a chance to relinquish it.
\*==========================================================================*/
inline void CSpinLock::ResetIfOwnedByOtherProcess() { // If it's not locked by us, then reset it.
if ((DWORD)m_dwLock != GetCurrentProcessId()) m_dwLock = SPIN_UNLOCKED; }
#endif // __SPINLOCK_H__
|