- Remove some duplicated/useless code and use internal forward exports instead. - Set kernel apc pending flag when needed in KeReleaseMutant - Optimize check for kernel apc delivery in KeReleaseMutant - Raise right exception in KeReleaseMutant - Simplify KeInitializeMutant and remove some duplicated operations. - Remove duplicated listhead initialization in KeInitiializeMutex - Use correct increment in KeReleaseMutex Modified: trunk/reactos/ntoskrnl/ke/mutex.c Modified: trunk/reactos/ntoskrnl/ntoskrnl.def _____
Modified: trunk/reactos/ntoskrnl/ke/mutex.c --- trunk/reactos/ntoskrnl/ke/mutex.c 2005-10-01 08:20:12 UTC (rev 18184) +++ trunk/reactos/ntoskrnl/ke/mutex.c 2005-10-01 08:58:49 UTC (rev 18185) @@ -27,33 +27,30 @@
KeInitializeMutant(IN PKMUTANT Mutant, IN BOOLEAN InitialOwner) { - ULONG Signaled = TRUE; - PKTHREAD CurrentThread = NULL; + PKTHREAD CurrentThread; KIRQL OldIrql; - DPRINT("KeInitializeMutant: %x\n", Mutant);
/* Check if we have an initial owner */ - if (InitialOwner == TRUE) { - - /* In this case, the object is not signaled */ - Signaled = FALSE; - + if (InitialOwner == TRUE) + { /* We also need to associate a thread */ CurrentThread = KeGetCurrentThread(); + Mutant->OwnerThread = CurrentThread;
/* We're about to touch the Thread, so lock the Dispatcher */ OldIrql = KeAcquireDispatcherDatabaseLock();
/* And insert it into its list */ - InsertTailList(&CurrentThread->MutantListHead, &Mutant->MutantListEntry); + InsertTailList(&CurrentThread->MutantListHead, + &Mutant->MutantListEntry);
/* Release Dispatcher Lock */ KeReleaseDispatcherDatabaseLock(OldIrql); DPRINT("Mutant with Initial Owner\n"); - - } else { - + } + else + { /* In this case, we don't have an owner yet */ Mutant->OwnerThread = NULL; } @@ -62,10 +59,9 @@ KeInitializeDispatcherHeader(&Mutant->Header, MutantObject, sizeof(KMUTANT) / sizeof(ULONG), - Signaled); + InitialOwner ? FALSE : TRUE);
/* Initialize the default data */ - Mutant->OwnerThread = CurrentThread; Mutant->Abandoned = FALSE; Mutant->ApcDisable = 0; } @@ -80,18 +76,16 @@ { DPRINT("KeInitializeMutex: %x\n", Mutex);
- /* Set up the Dispatcher Header */ KeInitializeDispatcherHeader(&Mutex->Header, MutantObject, sizeof(KMUTEX) / sizeof(ULONG), - 1); + TRUE);
/* Initialize the default data */ Mutex->OwnerThread = NULL; Mutex->Abandoned = FALSE; Mutex->ApcDisable = 1; - InitializeListHead(&Mutex->Header.WaitListHead); }
/* @@ -110,17 +104,6 @@ */ LONG STDCALL -KeReadStateMutex(IN PKMUTEX Mutex) -{ - /* Return the Signal State */ - return(Mutex->Header.SignalState); -} - -/* - * @implemented - */ -LONG -STDCALL KeReleaseMutant(IN PKMUTANT Mutant, IN KPRIORITY Increment, IN BOOLEAN Abandon, @@ -129,7 +112,6 @@ KIRQL OldIrql; LONG PreviousState; PKTHREAD CurrentThread = KeGetCurrentThread(); - DPRINT("KeReleaseMutant: %x\n", Mutant);
/* Lock the Dispatcher Database */ @@ -139,22 +121,26 @@ PreviousState = Mutant->Header.SignalState;
/* Check if it is to be abandonned */ - if (Abandon == FALSE) { - + if (Abandon == FALSE) + { /* Make sure that the Owner Thread is the current Thread */ - if (Mutant->OwnerThread != CurrentThread) { + if (Mutant->OwnerThread != CurrentThread) + { + DPRINT1("Trying to touch a Mutant that the caller doesn't own!\n");
+ /* Release the lock */ KeReleaseDispatcherDatabaseLock(OldIrql);
- DPRINT1("Trying to touch a Mutant that the caller doesn't own!\n"); - ExRaiseStatus(STATUS_MUTANT_NOT_OWNED); + /* Raise an exception */ + ExRaiseStatus(Mutant->Abandoned ? STATUS_ABANDONED : + STATUS_MUTANT_NOT_OWNED); }
/* If the thread owns it, then increase the signal state */ Mutant->Header.SignalState++; - - } else { - + } + else + { /* It's going to be abandonned */ DPRINT("Abandonning the Mutant\n"); Mutant->Header.SignalState = 1; @@ -162,25 +148,28 @@ }
/* Check if the signal state is only single */ - if (Mutant->Header.SignalState == 1) { - + if (Mutant->Header.SignalState == 1) + { /* Check if it's below 0 now */ - if (PreviousState <= 0) { - + if (PreviousState <= 0) + { /* Remove the mutant from the list */ - DPRINT("Removing Mutant\n"); + DPRINT("Removing Mutant %p\n", Mutant); RemoveEntryList(&Mutant->MutantListEntry);
/* Reenable APCs */ DPRINT("Re-enabling APCs\n"); CurrentThread->KernelApcDisable += Mutant->ApcDisable;
- /* Force an Interrupt if Apcs are pending */ - if (!IsListEmpty(&CurrentThread->ApcState.ApcListHead[KernelMode])) { + /* Check if the thread has APCs enabled */ + if (!CurrentThread->KernelApcDisable) + { + /* Check if any are pending */ + if (!IsListEmpty(&CurrentThread->ApcState.ApcListHead[KernelMode])) + { + /* Set Kernel APC Pending */ + CurrentThread->ApcState.KernelApcPending = TRUE;
- /* Make sure they aren't disabled though */ - if (!CurrentThread->KernelApcDisable) { - /* Request the Interrupt */ DPRINT("Requesting APC Interupt\n"); HalRequestSoftwareInterrupt(APC_LEVEL); @@ -193,8 +182,8 @@
/* Check if the Wait List isn't empty */ DPRINT("Checking whether to wake the Mutant\n"); - if (!IsListEmpty(&Mutant->Header.WaitListHead)) { - + if (!IsListEmpty(&Mutant->Header.WaitListHead)) + { /* Wake the Mutant */ DPRINT("Waking the Mutant\n"); KiWaitTest(&Mutant->Header, Increment); @@ -202,13 +191,13 @@ }
/* If the Wait is true, then return with a Wait and don't unlock the Dispatcher Database */ - if (Wait == FALSE) { - + if (Wait == FALSE) + { /* Release the Lock */ KeReleaseDispatcherDatabaseLock(OldIrql); - - } else { - + } + else + { /* Set a wait */ CurrentThread->WaitNext = TRUE; CurrentThread->WaitIrql = OldIrql; @@ -226,28 +215,8 @@ KeReleaseMutex(IN PKMUTEX Mutex, IN BOOLEAN Wait) { - /* There's no difference at this level between the two */ - return KeReleaseMutant(Mutex, IO_NO_INCREMENT, FALSE, Wait); + return KeReleaseMutant(Mutex, 1, FALSE, Wait); }
-/* - * @implemented - */ -NTSTATUS -STDCALL -KeWaitForMutexObject(IN PKMUTEX Mutex, - IN KWAIT_REASON WaitReason, - IN KPROCESSOR_MODE WaitMode, - IN BOOLEAN Alertable, - IN PLARGE_INTEGER Timeout) -{ - /* This is a simple macro. Export the function here though */ - return KeWaitForSingleObject(Mutex, - WaitReason, - WaitMode, - Alertable, - Timeout); -} - /* EOF */ _____
Modified: trunk/reactos/ntoskrnl/ntoskrnl.def --- trunk/reactos/ntoskrnl/ntoskrnl.def 2005-10-01 08:20:12 UTC (rev 18184) +++ trunk/reactos/ntoskrnl/ntoskrnl.def 2005-10-01 08:58:49 UTC (rev 18185) @@ -588,7 +588,7 @@
KeRaiseUserException@4 KeReadStateEvent@4 KeReadStateMutant@4 -KeReadStateMutex@4 +KeReadStateMutex@4=KeReadStateMutant@4 KeReadStateQueue@4 KeReadStateSemaphore@4 KeReadStateTimer@4 @@ -645,7 +645,7 @@ KeUnstackDetachProcess@4 KeUserModeCallback@20 KeWaitForMultipleObjects@32 -KeWaitForMutexObject@20 +KeWaitForMutexObject@20=KeWaitForSingleObject@20 KeWaitForSingleObject@20 @KefAcquireSpinLockAtDpcLevel@4 @KefReleaseSpinLockFromDpcLevel@4