Fixed up Critical Section code

svn path=/trunk/; revision=1124
This commit is contained in:
Phillip Susi 2000-04-20 05:29:27 +00:00
parent b01b3e0e97
commit ee3307e21d
2 changed files with 143 additions and 40 deletions

View file

@ -1,4 +1,4 @@
/* $Id: critical.c,v 1.7 2000/04/17 03:09:04 phreak Exp $
/* $Id: critical.c,v 1.8 2000/04/20 05:28:31 phreak Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@ -30,17 +30,17 @@ VOID
STDCALL
EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
{
if( InterlockedIncrement(&(lpCriticalSection->LockCount) ) != 0) {
if (lpCriticalSection->OwningThread != (HANDLE)GetCurrentThreadId() ) {
WaitForSingleObject(lpCriticalSection->LockSemaphore,100000);
// WAIT_TIMEOUT should give message if DEBUG
lpCriticalSection->OwningThread = (HANDLE)GetCurrentThreadId();
}
}
else
lpCriticalSection->OwningThread = (HANDLE)GetCurrentThreadId();
lpCriticalSection->RecursionCount++;
if( InterlockedIncrement(&(lpCriticalSection->LockCount) ) != 1 ) {
if (lpCriticalSection->OwningThread != (HANDLE)GetCurrentThreadId() ) {
WaitForSingleObject(lpCriticalSection->LockSemaphore,100000);
// WAIT_TIMEOUT should give message if DEBUG
lpCriticalSection->OwningThread = (HANDLE)GetCurrentThreadId();
}
}
else
lpCriticalSection->OwningThread = (HANDLE)GetCurrentThreadId();
lpCriticalSection->RecursionCount++;
}
@ -60,19 +60,16 @@ VOID
STDCALL
LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
{
lpCriticalSection->RecursionCount--;
if ( lpCriticalSection->RecursionCount == 0 ) {
lpCriticalSection->OwningThread = (HANDLE)-1;
// if LockCount > 0 and RecursionCount == 0 there
// is a waiting thread
// ReleaseSemaphore will fire up a waiting thread
if (lpCriticalSection->LockCount > 0 )
ReleaseSemaphore( lpCriticalSection->LockSemaphore,1,NULL);
}
InterlockedDecrement( &lpCriticalSection->LockCount );
lpCriticalSection->RecursionCount--;
if ( lpCriticalSection->RecursionCount == 0 ) {
lpCriticalSection->OwningThread = (HANDLE)-1;
// if LockCount > 0 and RecursionCount == 0 there
// is a waiting thread
// ReleaseSemaphore will fire up a waiting thread
if ( InterlockedDecrement( &lpCriticalSection->LockCount ) > 0 )
ReleaseSemaphore( lpCriticalSection->LockSemaphore,1,NULL);
}
else InterlockedDecrement( &lpCriticalSection->LockCount );
}
@ -80,15 +77,18 @@ WINBOOL
STDCALL
TryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
{
if( InterlockedIncrement(&(lpCriticalSection->LockCount) ) != 0) {
if (lpCriticalSection->OwningThread != (HANDLE)GetCurrentThreadId() )
return FALSE;
}
else
lpCriticalSection->OwningThread = (HANDLE)GetCurrentThreadId();
lpCriticalSection->RecursionCount++;
return TRUE;
if( InterlockedCompareExchange( (PVOID *)&lpCriticalSection->LockCount, (PVOID)1, (PVOID)0 ) == 0 )
{
lpCriticalSection->OwningThread = (HANDLE)GetCurrentThreadId();
lpCriticalSection->RecursionCount++;
return TRUE;
}
if( lpCriticalSection->OwningThread == (HANDLE)GetCurrentThreadId() )
{
lpCriticalSection->RecursionCount++;
return TRUE;
}
return FALSE;
}

View file

@ -1,4 +1,4 @@
/* $Id: critical.c,v 1.5 2000/03/09 00:14:10 ekohl Exp $
/* $Id: critical.c,v 1.6 2000/04/20 05:29:27 phreak Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@ -17,10 +17,73 @@
/* FUNCTIONS *****************************************************************/
/* shouldn't these have correct Rtl equivalents? I just copied from kernel32 */
PVOID
STDCALL
InterlockedCompareExchange(
PVOID *Destination,
PVOID Exchange,
PVOID Comperand )
{
PVOID ret;
__asm__ ( /* lock for SMP systems */
"lock\n\t"
"cmpxchgl %2,(%1)"
:"=r" (ret)
:"r" (Destination),"r" (Exchange), "0" (Comperand)
:"memory" );
return ret;
}
LONG
STDCALL
InterlockedIncrement(PLONG Addend)
{
long ret = 0;
__asm__
(
"\tlock\n" /* for SMP systems */
"\tincl (%1)\n"
"\tje 2f\n"
"\tjl 1f\n"
"\tincl %0\n"
"\tjmp 2f\n"
"1:\tdec %0\n"
"2:\n"
:"=r" (ret):"r" (Addend), "0" (0): "memory"
);
return ret;
}
LONG
STDCALL
InterlockedDecrement(LPLONG lpAddend)
{
long ret;
__asm__
(
"\tlock\n" /* for SMP systems */
"\tdecl (%1)\n"
"\tje 2f\n"
"\tjl 1f\n"
"\tincl %0\n"
"\tjmp 2f\n"
"1:\tdec %0\n"
"2:\n"
:"=r" (ret):"r" (lpAddend), "0" (0): "memory"
);
return ret;
}
VOID
STDCALL
RtlDeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
{
NtClose(lpCriticalSection->LockSemaphore);
lpCriticalSection->Reserved = -1;
}
@ -28,16 +91,28 @@ VOID
STDCALL
RtlEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
{
HANDLE Thread = (HANDLE)NtCurrentTeb()->Cid.UniqueThread;
ULONG ret;
if( (ret = InterlockedIncrement(&(lpCriticalSection->LockCount) )) != 1 ) {
if (lpCriticalSection->OwningThread != Thread ) {
NtWaitForSingleObject( lpCriticalSection->LockSemaphore, 0, FALSE );
lpCriticalSection->OwningThread = Thread;
}
}
else
lpCriticalSection->OwningThread = Thread;
lpCriticalSection->RecursionCount++;
}
VOID
STDCALL
RtlInitializeCriticalSection(LPCRITICAL_SECTION pcritical)
{
pcritical->LockCount = -1;
pcritical->LockCount = 0;
pcritical->RecursionCount = 0;
pcritical->LockSemaphore = NULL;
pcritical->OwningThread = (HANDLE)-1;
NtCreateSemaphore( &pcritical->LockSemaphore, STANDARD_RIGHTS_ALL, NULL, 0, 1 );
pcritical->OwningThread = (HANDLE)-1; // critical section has no owner yet
pcritical->Reserved = 0;
}
@ -45,14 +120,42 @@ VOID
STDCALL
RtlLeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
{
lpCriticalSection->RecursionCount--;
if ( lpCriticalSection->RecursionCount == 0 ) {
lpCriticalSection->OwningThread = (HANDLE)-1;
// if LockCount > 0 and RecursionCount == 0 there
// is a waiting thread
// ReleaseSemaphore will fire up a waiting thread
if ( InterlockedDecrement( &lpCriticalSection->LockCount ) > 0 )
{
NtReleaseSemaphore( lpCriticalSection->LockSemaphore,1,NULL);
}
}
else InterlockedDecrement( &lpCriticalSection->LockCount );
}
BOOLEAN
STDCALL
RtlTryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
{
UNIMPLEMENTED;
for(;;);
if( InterlockedCompareExchange( (PVOID *)&lpCriticalSection->LockCount, (PVOID)1, (PVOID)0 ) == 0 )
{
lpCriticalSection->OwningThread = (HANDLE) NtCurrentTeb()->Cid.UniqueThread;
lpCriticalSection->RecursionCount++;
return TRUE;
}
if( lpCriticalSection->OwningThread == (HANDLE)NtCurrentTeb()->Cid.UniqueThread )
{
lpCriticalSection->RecursionCount++;
return TRUE;
}
return FALSE;
}
/* EOF */