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.
 
 
 
 
 
 

129 lines
3.0 KiB

/*==========================================================================*\
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__