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.
 
 
 
 
 
 

115 lines
3.0 KiB

/*++
Copyright (c) Microsoft Corporation. All rights reserved.
Module Name:
win32simplelock.c
Abstract:
works downlevel to Win95/NT3.
The only dependencies are InterlocedIncrement, IncrementDecrement, Sleep.
The old Interlocked semantics are good enough.
can be statically initialized, but not with all zeros.
never runs out of memory
does not wait or boost-upon-exit efficiently.
must be held for only short periods of time.
should perhaps be called spinlock
can be taken recursively.
can only be taken exclusively, NOT reader/writer.
acquire has a "SleepCount" parameter:
0 is like TryEnterCriticalSection
INFINITE is like EnterCriticalSection
SHOULD have a spincount to scale hot locks on multiprocs
Author:
Jay Krell (JayKrell) August 2001
Revision History:
--*/
#include "windows.h"
#include "win32simplelock.h"
DWORD
Win32AcquireSimpleLock(PWIN32_SIMPLE_LOCK Lock, DWORD SleepCount)
{
DWORD Result = 0;
BOOL IncrementedWaiters = FALSE;
// ASSERT(Lock->Size != 0);
Retry:
if (InterlockedIncrement(&Lock->Lock) == 0)
{
//
// I got it.
//
Lock->OwnerThreadId = GetCurrentThreadId();
if (Lock->EntryCount == 0)
{
Result |= WIN32_ACQUIRE_SIMPLE_LOCK_WAS_FIRST_ACQUIRE;
}
if (Lock->EntryCount+1 != 0) /* avoid rollover */
Lock->EntryCount += 1;
if (IncrementedWaiters)
InterlockedDecrement(&Lock->Waiters);
Result |= WIN32_ACQUIRE_SIMPLE_LOCK_WAS_NOT_RECURSIVE_ACQUIRE;
return Result;
}
else if (Lock->OwnerThreadId == GetCurrentThreadId())
{
//
// I got it recursively.
//
Result |= WIN32_ACQUIRE_SIMPLE_LOCK_WAS_RECURSIVE_ACQUIRE;
return Result;
}
InterlockedDecrement(&Lock->Lock);
if (SleepCount == 0)
return 0;
//
// Someone else has it, wait for them to finish.
//
if (!IncrementedWaiters)
{
InterlockedIncrement(&Lock->Waiters);
IncrementedWaiters = TRUE;
}
if (SleepCount == INFINITE)
{
while (Lock->OwnerThreadId != 0)
Sleep(0);
}
else
{
while (Lock->OwnerThreadId != 0 && SleepCount--)
Sleep(0);
}
goto Retry;
}
DWORD
Win32ReleaseSimpleLock(PWIN32_SIMPLE_LOCK Lock)
{
// ASSERT(Lock->Size != 0);
DWORD Result = 0;
if (InterlockedDecrement(&Lock->Lock) < 0)
{
// I'm done with it (recursively).
Lock->OwnerThreadId = 0;
// Give any waiters a slightly better chance than me.
// This is "racy", but that's ok.
if (Lock->Waiters != 0)
Sleep(0);
Result |= WIN32_RELEASE_SIMPLE_LOCK_WAS_NOT_RECURSIVE_RELEASE;
}
else
{
Result |= WIN32_RELEASE_SIMPLE_LOCK_WAS_RECURSIVE_RELEASE;
}
return Result;
}