From ee3307e21d34ef113c4a68efdcd3f3e0318fbad9 Mon Sep 17 00:00:00 2001 From: Phillip Susi Date: Thu, 20 Apr 2000 05:29:27 +0000 Subject: [PATCH] Fixed up Critical Section code svn path=/trunk/; revision=1124 --- reactos/lib/kernel32/synch/critical.c | 68 +++++++-------- reactos/lib/ntdll/rtl/critical.c | 115 ++++++++++++++++++++++++-- 2 files changed, 143 insertions(+), 40 deletions(-) diff --git a/reactos/lib/kernel32/synch/critical.c b/reactos/lib/kernel32/synch/critical.c index c6e2de225cc..ecdd659c9cd 100644 --- a/reactos/lib/kernel32/synch/critical.c +++ b/reactos/lib/kernel32/synch/critical.c @@ -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; } diff --git a/reactos/lib/ntdll/rtl/critical.c b/reactos/lib/ntdll/rtl/critical.c index aefe5b06f9d..befbc7af17a 100644 --- a/reactos/lib/ntdll/rtl/critical.c +++ b/reactos/lib/ntdll/rtl/critical.c @@ -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 */ + + + + +