From 35eb408157e9b287ac193970c8985c4b1b95267e Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sat, 1 Oct 2005 08:58:49 +0000 Subject: [PATCH] - 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 svn path=/trunk/; revision=18185 --- reactos/ntoskrnl/ke/mutex.c | 119 +++++++++++++--------------------- reactos/ntoskrnl/ntoskrnl.def | 4 +- 2 files changed, 46 insertions(+), 77 deletions(-) diff --git a/reactos/ntoskrnl/ke/mutex.c b/reactos/ntoskrnl/ke/mutex.c index 06f81c9665b..e45cf486d5b 100644 --- a/reactos/ntoskrnl/ke/mutex.c +++ b/reactos/ntoskrnl/ke/mutex.c @@ -27,33 +27,30 @@ STDCALL 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 @@ KeInitializeMutant(IN PKMUTANT Mutant, 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 @@ KeInitializeMutex(IN PKMUTEX Mutex, { 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); } /* @@ -105,17 +99,6 @@ KeReadStateMutant(IN PKMUTANT Mutant) return(Mutant->Header.SignalState); } -/* - * @implemented - */ -LONG -STDCALL -KeReadStateMutex(IN PKMUTEX Mutex) -{ - /* Return the Signal State */ - return(Mutex->Header.SignalState); -} - /* * @implemented */ @@ -129,7 +112,6 @@ KeReleaseMutant(IN PKMUTANT Mutant, KIRQL OldIrql; LONG PreviousState; PKTHREAD CurrentThread = KeGetCurrentThread(); - DPRINT("KeReleaseMutant: %x\n", Mutant); /* Lock the Dispatcher Database */ @@ -139,22 +121,26 @@ KeReleaseMutant(IN PKMUTANT Mutant, 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,24 +148,27 @@ KeReleaseMutant(IN PKMUTANT Mutant, } /* 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])) { - - /* Make sure they aren't disabled though */ - if (!CurrentThread->KernelApcDisable) { + /* 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; /* Request the Interrupt */ DPRINT("Requesting APC Interupt\n"); @@ -193,8 +182,8 @@ KeReleaseMutant(IN PKMUTANT Mutant, /* 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 @@ KeReleaseMutant(IN PKMUTANT Mutant, } /* 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 @@ STDCALL 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); -} - -/* - * @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); + return KeReleaseMutant(Mutex, 1, FALSE, Wait); } /* EOF */ diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index 17ee641ce2b..cb2d3315f0c 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -588,7 +588,7 @@ KeQueryTimeIncrement@0 KeRaiseUserException@4 KeReadStateEvent@4 KeReadStateMutant@4 -KeReadStateMutex@4 +KeReadStateMutex@4=KeReadStateMutant@4 KeReadStateQueue@4 KeReadStateSemaphore@4 KeReadStateTimer@4 @@ -645,7 +645,7 @@ KeUpdateSystemTime@8 KeUnstackDetachProcess@4 KeUserModeCallback@20 KeWaitForMultipleObjects@32 -KeWaitForMutexObject@20 +KeWaitForMutexObject@20=KeWaitForSingleObject@20 KeWaitForSingleObject@20 @KefAcquireSpinLockAtDpcLevel@4 @KefReleaseSpinLockFromDpcLevel@4