mirror of
https://github.com/reactos/reactos.git
synced 2024-08-29 22:58:34 +00:00
Fixed up Critical Section code
svn path=/trunk/; revision=1124
This commit is contained in:
parent
b01b3e0e97
commit
ee3307e21d
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue