- Get completely rid of old Dispatcher Lock macros and use new ones.

- apc.c -> Also multiple optimizations to use the APC lock instead of the full-fledged dispatcher lock.
- gate.c -> Use APC lock as well, the full dispatcher lock isn't required because a thread can only wait on one and only one gate.
- process.c -> Optimize the code to use the Process and/or APC lock instead of the dispatcher lock. Also delay acquiring the locks after some checks, to make the exit paths simpler.
- More fixes are teh needed.

svn path=/trunk/; revision=24038
This commit is contained in:
Alex Ionescu 2006-09-10 18:26:50 +00:00
parent 63346a8dda
commit da15ddafc8
16 changed files with 254 additions and 266 deletions

View file

@ -307,7 +307,7 @@ ExpExpandResourceOwnerTable(IN PERESOURCE_XP Resource,
OldSize * sizeof(OWNER_ENTRY));
/* Acquire dispatcher lock to prevent thread boosting */
KeAcquireDispatcherDatabaseLockAtDpcLevel();
KiAcquireDispatcherLockAtDpcLevel();
/* Set the new table data */
Table->TableSize = NewSize;
@ -317,7 +317,7 @@ ExpExpandResourceOwnerTable(IN PERESOURCE_XP Resource,
ExpVerifyResource(Resource);
/* Release locks */
KeReleaseDispatcherDatabaseLockFromDpcLevel();
KiReleaseDispatcherLockFromDpcLevel();
ExReleaseResourceLock(&Resource->SpinLock, *OldIrql);
/* Free the old table */
@ -571,7 +571,7 @@ ExpBoostOwnerThread(IN PKTHREAD Thread,
KiSetPriorityThread(OwnerThread, 14, &Released);
/* Reacquire lock if it got releases */
if (Released) KeAcquireDispatcherDatabaseLockFromDpcLevel();
if (Released) KiAcquireDispatcherLockFromDpcLevel();
/* Make sure we're still at dispatch */
ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
@ -691,7 +691,7 @@ ExpWaitForResource(IN PERESOURCE_XP Resource,
/* Get the current kernel thread and lock the dispatcher */
Thread = KeGetCurrentThread();
Thread->WaitIrql = KeAcquireDispatcherDatabaseLock();
Thread->WaitIrql = KiAcquireDispatcherLock();
Thread->WaitNext = TRUE;
/* Get the owner thread and boost it */

View file

@ -187,12 +187,6 @@ extern VOID KiTrap2(VOID);
/* INTERNAL KERNEL FUNCTIONS ************************************************/
#define KeInitializeDispatcher()
#define KeAcquireDispatcherDatabaseLock() KeRaiseIrqlToDpcLevel();
#define KeReleaseDispatcherDatabaseLock(OldIrql) KiExitDispatcher(OldIrql);
#define KeAcquireDispatcherDatabaseLockAtDpcLevel()
#define KeReleaseDispatcherDatabaseLockFromDpcLevel()
/* Readies a Thread for Execution. */
BOOLEAN
NTAPI
@ -620,7 +614,7 @@ NTAPI
KiAttachProcess(
struct _KTHREAD *Thread,
struct _KPROCESS *Process,
KIRQL ApcLock,
PKLOCK_QUEUE_HANDLE ApcLock,
struct _KAPC_STATE *SavedApcState
);

View file

@ -482,39 +482,34 @@ KeInsertQueueApc(PKAPC Apc,
PVOID SystemArgument2,
KPRIORITY PriorityBoost)
{
KIRQL OldIrql;
PKTHREAD Thread;
PKTHREAD Thread = Apc->Thread;
KLOCK_QUEUE_HANDLE ApcLock;
BOOLEAN State = TRUE;
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
DPRINT("KeInsertQueueApc(Apc %x, SystemArgument1 %x, "
"SystemArgument2 %x)\n",Apc,SystemArgument1,
SystemArgument2);
/* Lock the Dispatcher Database */
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Get the Thread specified in the APC */
Thread = Apc->Thread;
/* Get the APC lock */
KiAcquireApcLock(Thread, &ApcLock);
/* Make sure we can Queue APCs and that this one isn't already inserted */
if ((Thread->ApcQueueable == FALSE) && (Apc->Inserted == TRUE))
{
DPRINT("Can't queue the APC\n");
KeReleaseDispatcherDatabaseLock(OldIrql);
return FALSE;
/* Fail */
State = FALSE;
}
else
{
/* Set the System Arguments and set it as inserted */
Apc->SystemArgument1 = SystemArgument1;
Apc->SystemArgument2 = SystemArgument2;
Apc->Inserted = TRUE;
/* Call the Internal Function */
KiInsertQueueApc(Apc, PriorityBoost);
}
/* Set the System Arguments and set it as inserted */
Apc->SystemArgument1 = SystemArgument1;
Apc->SystemArgument2 = SystemArgument2;
Apc->Inserted = TRUE;
/* Call the Internal Function */
KiInsertQueueApc(Apc, PriorityBoost);
/* Return Sucess if we are here */
KeReleaseDispatcherDatabaseLock(OldIrql);
return TRUE;
/* Release the APC lock and return success */
KiReleaseApcLock(&ApcLock);
KiExitDispatcher(ApcLock.OldIrql);
return State;
}
/*++
@ -542,13 +537,12 @@ STDCALL
KeFlushQueueApc(IN PKTHREAD Thread,
IN KPROCESSOR_MODE PreviousMode)
{
KIRQL OldIrql;
PKAPC Apc;
PLIST_ENTRY FirstEntry, CurrentEntry;
KLOCK_QUEUE_HANDLE ApcLock;
/* Lock the Dispatcher Database and APC Queue */
OldIrql = KeAcquireDispatcherDatabaseLock();
KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
/* Get the APC lock */
KiAcquireApcLock(Thread, &ApcLock);
if (IsListEmpty(&Thread->ApcState.ApcListHead[PreviousMode])) {
FirstEntry = NULL;
@ -563,9 +557,8 @@ KeFlushQueueApc(IN PKTHREAD Thread,
} while (CurrentEntry != FirstEntry);
}
/* Release the locks */
KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
KeReleaseDispatcherDatabaseLock(OldIrql);
/* Release the lock */
KiReleaseApcLock(&ApcLock);
/* Return the first entry */
return FirstEntry;
@ -596,16 +589,13 @@ BOOLEAN
STDCALL
KeRemoveQueueApc(PKAPC Apc)
{
KIRQL OldIrql;
PKTHREAD Thread = Apc->Thread;
PKAPC_STATE ApcState;
BOOLEAN Inserted;
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
DPRINT("KeRemoveQueueApc called for APC: %x \n", Apc);
KLOCK_QUEUE_HANDLE ApcLock;
/* Acquire locks */
OldIrql = KeAcquireDispatcherDatabaseLock();
KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
/* Get the APC lock */
KiAcquireApcLock(Thread, &ApcLock);
/* Check if it's inserted */
if ((Inserted = Apc->Inserted))
@ -630,9 +620,8 @@ KeRemoveQueueApc(PKAPC Apc)
}
}
/* Restore IRQL and Return */
KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
KeReleaseDispatcherDatabaseLock(OldIrql);
/* Release the lock and return */
KiReleaseApcLock(&ApcLock);
return Inserted;
}

View file

@ -99,7 +99,7 @@ KiSetSystemTime(PLARGE_INTEGER NewSystemTime)
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
OldIrql = KeAcquireDispatcherDatabaseLock();
OldIrql = KiAcquireDispatcherLock();
do
{
@ -122,7 +122,7 @@ KiSetSystemTime(PLARGE_INTEGER NewSystemTime)
/* Update absolute timers */
DPRINT1("FIXME: TIMER UPDATE NOT DONE!!!\n");
KeReleaseDispatcherDatabaseLock(OldIrql);
KiReleaseDispatcherLock(OldIrql);
/*
* NOTE: Expired timers will be processed at the next clock tick!

View file

@ -80,7 +80,7 @@ KePulseEvent(IN PKEVENT Event,
DPRINT("KePulseEvent(Event %x, Wait %x)\n",Event,Wait);
/* Lock the Dispatcher Database */
OldIrql = KeAcquireDispatcherDatabaseLock();
OldIrql = KiAcquireDispatcherLock();
/* Save the Old State */
PreviousState = Event->Header.SignalState;
@ -102,7 +102,7 @@ KePulseEvent(IN PKEVENT Event,
if (Wait == FALSE) {
/* Wait not requested, release Dispatcher Database and return */
KeReleaseDispatcherDatabaseLock(OldIrql);
KiReleaseDispatcherLock(OldIrql);
} else {
@ -140,7 +140,7 @@ KeResetEvent(PKEVENT Event)
DPRINT("KeResetEvent(Event %x)\n",Event);
/* Lock the Dispatcher Database */
OldIrql = KeAcquireDispatcherDatabaseLock();
OldIrql = KiAcquireDispatcherLock();
/* Save the Previous State */
PreviousState = Event->Header.SignalState;
@ -149,7 +149,7 @@ KeResetEvent(PKEVENT Event)
Event->Header.SignalState = 0;
/* Release Dispatcher Database and return previous state */
KeReleaseDispatcherDatabaseLock(OldIrql);
KiReleaseDispatcherLock(OldIrql);
return PreviousState;
}
@ -169,7 +169,7 @@ KeSetEvent(PKEVENT Event,
DPRINT("KeSetEvent(Event %x, Wait %x)\n",Event,Wait);
/* Lock the Dispathcer Database */
OldIrql = KeAcquireDispatcherDatabaseLock();
OldIrql = KiAcquireDispatcherLock();
/* Save the Previous State */
PreviousState = Event->Header.SignalState;
@ -212,7 +212,7 @@ KeSetEvent(PKEVENT Event,
if (Wait == FALSE) {
/* Wait not requested, release Dispatcher Database and return */
KeReleaseDispatcherDatabaseLock(OldIrql);
KiReleaseDispatcherLock(OldIrql);
} else {
@ -241,7 +241,7 @@ KeSetEventBoostPriority(IN PKEVENT Event,
DPRINT("KeSetEventBoostPriority(Event %x, Thread %x)\n",Event,Thread);
/* Acquire Dispatcher Database Lock */
OldIrql = KeAcquireDispatcherDatabaseLock();
OldIrql = KiAcquireDispatcherLock();
/* If our wait list is empty, then signal the event and return */
if (IsListEmpty(&Event->Header.WaitListHead)) {
@ -264,7 +264,7 @@ KeSetEventBoostPriority(IN PKEVENT Event,
}
/* Release the Dispatcher Database Lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
KiReleaseDispatcherLock(OldIrql);
}
/* EOF */

View file

@ -32,7 +32,7 @@ KeWaitForGate(IN PKGATE Gate,
IN KWAIT_REASON WaitReason,
IN KPROCESSOR_MODE WaitMode)
{
KIRQL OldIrql;
KLOCK_QUEUE_HANDLE ApcLock;
PKTHREAD CurrentThread = KeGetCurrentThread();
PKWAIT_BLOCK GateWaitBlock;
NTSTATUS Status;
@ -42,15 +42,16 @@ KeWaitForGate(IN PKGATE Gate,
/* Start wait loop */
do
{
/* Lock the dispatcher */
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Acquire the APC lock */
KiAcquireApcLock(CurrentThread, &ApcLock);
/* Check if a kernel APC is pending and we're below APC_LEVEL */
if ((CurrentThread->ApcState.KernelApcPending) &&
!(CurrentThread->SpecialApcDisable) && (OldIrql < APC_LEVEL))
!(CurrentThread->SpecialApcDisable) &&
(ApcLock.OldIrql < APC_LEVEL))
{
/* Unlock the dispatcher, this will fire the APC */
KeReleaseDispatcherDatabaseLock(OldIrql);
/* Release the lock, this will fire the APC */
KiReleaseApcLock(&ApcLock);
}
else
{
@ -60,8 +61,8 @@ KeWaitForGate(IN PKGATE Gate,
/* Unsignal it */
Gate->Header.SignalState = 0;
/* Unlock the Queue and return */
KeReleaseDispatcherDatabaseLock(OldIrql);
/* Release the APC lock and return */
KiReleaseApcLock(&ApcLock);
return;
}
@ -73,7 +74,7 @@ KeWaitForGate(IN PKGATE Gate,
/* Set the Thread Wait Data */
CurrentThread->WaitMode = WaitMode;
CurrentThread->WaitReason = WaitReason;
CurrentThread->WaitIrql = OldIrql;
CurrentThread->WaitIrql = ApcLock.OldIrql;
CurrentThread->State = GateWait;
CurrentThread->GateObject = Gate;
@ -84,6 +85,9 @@ KeWaitForGate(IN PKGATE Gate,
/* Handle Kernel Queues */
if (CurrentThread->Queue) KiWakeQueue(CurrentThread->Queue);
/* Release the APC lock but stay at DPC level */
KiReleaseApcLockFromDpcLevel(&ApcLock);
/* Find a new thread to run */
Status = KiSwapThread(CurrentThread, KeGetCurrentPrcb());
@ -104,11 +108,16 @@ KeSignalGateBoostPriority(IN PKGATE Gate)
ASSERT_GATE(Gate);
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
/* Acquire Dispatcher Database Lock */
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Raise to synch level */
OldIrql = KeRaiseIrqlToSynchLevel();
/* Make sure we're not already signaled or that the list is empty */
if (Gate->Header.SignalState) goto quit;
if (Gate->Header.SignalState)
{
/* Lower IRQL and quit */
KeLowerIrql(OldIrql);
return;
}
/* Check if our wait list is empty */
if (IsListEmpty(&Gate->Header.WaitListHead))
@ -136,9 +145,8 @@ KeSignalGateBoostPriority(IN PKGATE Gate)
KiAbortWaitThread(WaitThread, WaitStatus, EVENT_INCREMENT);
}
quit:
/* Release the Dispatcher Database Lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
/* Exit the dispatcher */
KiExitDispatcher(OldIrql);
}
/* EOF */

View file

@ -264,7 +264,6 @@ KiInitSpinLocks(IN PKPRCB Prcb,
KeInitializeSpinLock(&MmNonPagedPoolLock);
KeInitializeSpinLock(&NtfsStructLock);
KeInitializeSpinLock(&AfdWorkQueueSpinLock);
KeInitializeDispatcher(); // ROS OLD DISPATCHER
}
}

View file

@ -39,14 +39,14 @@ KeInitializeMutant(IN PKMUTANT Mutant,
Mutant->OwnerThread = CurrentThread;
/* We're about to touch the Thread, so lock the Dispatcher */
OldIrql = KeAcquireDispatcherDatabaseLock();
OldIrql = KiAcquireDispatcherLock();
/* And insert it into its list */
InsertTailList(&CurrentThread->MutantListHead,
&Mutant->MutantListEntry);
/* Release Dispatcher Lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
KiReleaseDispatcherLock(OldIrql);
DPRINT("Mutant with Initial Owner\n");
}
else
@ -115,7 +115,7 @@ KeReleaseMutant(IN PKMUTANT Mutant,
DPRINT("KeReleaseMutant: %x\n", Mutant);
/* Lock the Dispatcher Database */
OldIrql = KeAcquireDispatcherDatabaseLock();
OldIrql = KiAcquireDispatcherLock();
/* Save the Previous State */
PreviousState = Mutant->Header.SignalState;
@ -129,7 +129,7 @@ KeReleaseMutant(IN PKMUTANT Mutant,
DPRINT1("Trying to touch a Mutant that the caller doesn't own!\n");
/* Release the lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
KiReleaseDispatcherLock(OldIrql);
/* Raise an exception */
ExRaiseStatus(Mutant->Abandoned ? STATUS_ABANDONED :
@ -194,7 +194,7 @@ KeReleaseMutant(IN PKMUTANT Mutant,
if (Wait == FALSE)
{
/* Release the Lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
KiReleaseDispatcherLock(OldIrql);
}
else
{

View file

@ -61,7 +61,7 @@ VOID
NTAPI
KiAttachProcess(PKTHREAD Thread,
PKPROCESS Process,
KIRQL OldIrql,
PKLOCK_QUEUE_HANDLE ApcLock,
PRKAPC_STATE SavedApcState)
{
ASSERT(Process != Thread->ApcState.Process);
@ -95,11 +95,14 @@ KiAttachProcess(PKTHREAD Thread,
{
/* FIXME: Scan the Ready Thread List once new scheduler is in */
/* Swap the Processes */
/* Release lock */
KiReleaseApcLockFromDpcLevel(ApcLock);
/* Swap Processes */
KiSwapProcess(Process, SavedApcState->Process);
/* Return to old IRQL*/
KeReleaseDispatcherDatabaseLock(OldIrql);
/* Exit the dispatcher */
KiExitDispatcher(ApcLock->OldIrql);
}
else
{
@ -189,7 +192,7 @@ KeSetProcess(PKPROCESS Process,
ULONG OldState;
/* Lock Dispatcher */
OldIrql = KeAcquireDispatcherDatabaseLock();
OldIrql = KiAcquireDispatcherLock();
/* Get Old State */
OldState = Process->Header.SignalState;
@ -203,7 +206,7 @@ KeSetProcess(PKPROCESS Process,
}
/* Release Dispatcher Database */
KeReleaseDispatcherDatabaseLock(OldIrql);
KiReleaseDispatcherLock(OldIrql);
/* Return the previous State */
return OldState;
@ -223,14 +226,14 @@ NTAPI
KeSetQuantumProcess(IN PKPROCESS Process,
IN UCHAR Quantum)
{
KIRQL OldIrql;
KLOCK_QUEUE_HANDLE ProcessLock;
PLIST_ENTRY NextEntry, ListHead;
PKTHREAD Thread;
ASSERT_PROCESS(Process);
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
/* Lock Dispatcher */
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Lock the process */
KiAcquireProcessLock(Process, &ProcessLock);
/* Set new quantum */
Process->QuantumReset = Quantum;
@ -250,8 +253,8 @@ KeSetQuantumProcess(IN PKPROCESS Process,
NextEntry = NextEntry->Flink;
}
/* Release Dispatcher Database */
KeReleaseDispatcherDatabaseLock(OldIrql);
/* Release lock */
KiReleaseProcessLock(&ProcessLock);
}
KPRIORITY
@ -280,7 +283,7 @@ KeSetPriorityAndQuantumProcess(IN PKPROCESS Process,
if (!Priority) Priority = 1;
/* Lock Dispatcher */
OldIrql = KeAcquireDispatcherDatabaseLock();
OldIrql = KiAcquireDispatcherLock();
/* Check if we are modifying the quantum too */
if (Quantum) Process->QuantumReset = Quantum;
@ -410,7 +413,7 @@ KeSetPriorityAndQuantumProcess(IN PKPROCESS Process,
}
/* Release Dispatcher Database */
if (!Released) KeReleaseDispatcherDatabaseLock(OldIrql);
if (!Released) KiReleaseDispatcherLock(OldIrql);
/* Return previous priority */
return OldPriority;
@ -423,7 +426,7 @@ VOID
NTAPI
KeAttachProcess(PKPROCESS Process)
{
KIRQL OldIrql;
KLOCK_QUEUE_HANDLE ApcLock;
PKTHREAD Thread;
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
DPRINT("KeAttachProcess: %x\n", Process);
@ -432,19 +435,17 @@ KeAttachProcess(PKPROCESS Process)
Thread = KeGetCurrentThread();
UpdatePageDirs(Thread, Process);
/* Lock Dispatcher */
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Check if we're already in that process */
if (Thread->ApcState.Process == Process)
if (Thread->ApcState.Process == Process) return;
/* Acquire APC Lock */
KiAcquireApcLock(Thread, &ApcLock);
/* Check if a DPC is executing or if we're already attached */
if ((Thread->ApcStateIndex != OriginalApcEnvironment) ||
(KeIsExecutingDpc()))
{
/* Unlock the dispatcher, nothing to do */
KeReleaseDispatcherDatabaseLock(OldIrql);
}
else if ((Thread->ApcStateIndex != OriginalApcEnvironment) ||
(KeIsExecutingDpc()))
{
/* Executing a DPC or already attached, crash! */
/* Invalid attempt */
KEBUGCHECKEX(INVALID_PROCESS_ATTACH_ATTEMPT,
(ULONG_PTR)Process,
(ULONG_PTR)Thread->ApcState.Process,
@ -454,7 +455,7 @@ KeAttachProcess(PKPROCESS Process)
else
{
/* Legit attach attempt: do it! */
KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
KiAttachProcess(Thread, Process, &ApcLock, &Thread->SavedApcState);
}
}
@ -465,45 +466,46 @@ VOID
NTAPI
KeDetachProcess (VOID)
{
PKTHREAD Thread;
KIRQL OldIrql;
PKTHREAD Thread = KeGetCurrentThread();
KLOCK_QUEUE_HANDLE ApcLock;
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
DPRINT("KeDetachProcess()\n");
/* Get Current Thread and lock the dispatcher */
Thread = KeGetCurrentThread();
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Check if it's attached */
if (Thread->ApcStateIndex != OriginalApcEnvironment)
if (Thread->ApcStateIndex == OriginalApcEnvironment) return;
/* Acquire APC Lock */
KiAcquireApcLock(Thread, &ApcLock);
/* It is, decrease Stack Count */
if(!(--Thread->ApcState.Process->StackCount))
{
/* It is, decrease Stack Count */
if(!(--Thread->ApcState.Process->StackCount))
{
/* FIXME: Swap the process out */
}
/* Restore the APC State */
KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
Thread->SavedApcState.Process = NULL;
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
Thread->ApcStateIndex = OriginalApcEnvironment;
/* Check if we have pending APCs */
if (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]))
{
/* What do you know, we do! Request them to be delivered */
Thread->ApcState.KernelApcPending = TRUE;
HalRequestSoftwareInterrupt(APC_LEVEL);
}
/* Swap Processes */
KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
/* FIXME: Swap the process out */
}
/* Unlock Dispatcher */
KeReleaseDispatcherDatabaseLock(OldIrql);
/* Restore the APC State */
KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
Thread->SavedApcState.Process = NULL;
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
Thread->ApcStateIndex = OriginalApcEnvironment;
/* Release lock */
KiReleaseApcLockFromDpcLevel(&ApcLock);
/* Swap Processes */
KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
/* Exit the dispatcher */
KiExitDispatcher(ApcLock.OldIrql);
/* Check if we have pending APCs */
if (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]))
{
/* What do you know, we do! Request them to be delivered */
Thread->ApcState.KernelApcPending = TRUE;
HalRequestSoftwareInterrupt(APC_LEVEL);
}
}
/*
@ -525,17 +527,13 @@ NTAPI
KeStackAttachProcess(IN PKPROCESS Process,
OUT PRKAPC_STATE ApcState)
{
KIRQL OldIrql;
PKTHREAD Thread;
KLOCK_QUEUE_HANDLE ApcLock;
PKTHREAD Thread = KeGetCurrentThread();
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
/* Make sure that we are in the right page directory */
Thread = KeGetCurrentThread();
UpdatePageDirs(Thread, Process);
/* Acquire the dispatcher lock */
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Crash system if DPC is being executed! */
if (KeIsExecutingDpc())
{
@ -550,26 +548,25 @@ KeStackAttachProcess(IN PKPROCESS Process,
/* Check if we are already in the target process */
if (Thread->ApcState.Process == Process)
{
/* Unlock the dispatcher database */
KeReleaseDispatcherDatabaseLock(OldIrql);
/* Set magic value so we don't crash later when detaching */
ApcState->Process = (PKPROCESS)1;
return;
}
/* Acquire APC Lock */
KiAcquireApcLock(Thread, &ApcLock);
/* Check if the Current Thread is already attached */
if (Thread->ApcStateIndex != OriginalApcEnvironment)
{
/* We're already attached, so save the APC State into what we got */
KiAttachProcess(Thread, Process, &ApcLock, ApcState);
}
else
{
/* Check if the Current Thread is already attached */
if (Thread->ApcStateIndex != OriginalApcEnvironment)
{
/* We're already attached, so save the APC State into what we got */
KiAttachProcess(Thread, Process, OldIrql, ApcState);
}
else
{
/* We're not attached, so save the APC State into SavedApcState */
KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
ApcState->Process = NULL;
}
/* We're not attached, so save the APC State into SavedApcState */
KiAttachProcess(Thread, Process, &ApcLock, &Thread->SavedApcState);
ApcState->Process = NULL;
}
}
@ -580,64 +577,65 @@ VOID
NTAPI
KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
{
KIRQL OldIrql;
PKTHREAD Thread;
KLOCK_QUEUE_HANDLE ApcLock;
PKTHREAD Thread = KeGetCurrentThread();
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
/* Get the current thread and acquire the dispatcher lock */
Thread = KeGetCurrentThread();
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Check for magic value meaning we were already in the same process */
if (ApcState->Process != (PKPROCESS)1)
if (ApcState->Process == (PKPROCESS)1) return;
/* Acquire APC Lock */
KiAcquireApcLock(Thread, &ApcLock);
/*
* Check if the process isn't attacked, or has a Kernel APC in progress
* or has pending APC of any kind.
*/
if ((Thread->ApcStateIndex == OriginalApcEnvironment) ||
(Thread->ApcState.KernelApcInProgress) ||
(!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) ||
(!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])))
{
/*
* Check if the process isn't attacked, or has a Kernel APC in progress
* or has pending APC of any kind.
*/
if ((Thread->ApcStateIndex == OriginalApcEnvironment) ||
(Thread->ApcState.KernelApcInProgress) ||
(!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) ||
(!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])))
{
KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
}
/* Decrease Stack Count */
if(!(--Thread->ApcState.Process->StackCount))
{
/* FIXME: Swap the process out */
}
if (ApcState->Process != NULL)
{
/* Restore the APC State */
KiMoveApcState(ApcState, &Thread->ApcState);
}
else
{
/* The ApcState parameter is useless, so use the saved data and reset it */
KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
Thread->SavedApcState.Process = NULL;
Thread->ApcStateIndex = OriginalApcEnvironment;
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
}
/* Check if we have pending APCs */
if (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]))
{
/* What do you know, we do! Request them to be delivered */
Thread->ApcState.KernelApcPending = TRUE;
HalRequestSoftwareInterrupt(APC_LEVEL);
}
/* Swap Processes */
KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
}
/* Return to old IRQL*/
KeReleaseDispatcherDatabaseLock(OldIrql);
/* Decrease Stack Count */
if(!(--Thread->ApcState.Process->StackCount))
{
/* FIXME: Swap the process out */
}
if (ApcState->Process != NULL)
{
/* Restore the APC State */
KiMoveApcState(ApcState, &Thread->ApcState);
}
else
{
/* The ApcState parameter is useless, so use the saved data and reset it */
KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
Thread->SavedApcState.Process = NULL;
Thread->ApcStateIndex = OriginalApcEnvironment;
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
}
/* Release lock */
KiReleaseApcLockFromDpcLevel(&ApcLock);
/* Swap Processes */
KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
/* Exit the dispatcher */
KiExitDispatcher(ApcLock.OldIrql);
/* Check if we have pending APCs */
if (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]))
{
/* What do you know, we do! Request them to be delivered */
Thread->ApcState.KernelApcPending = TRUE;
HalRequestSoftwareInterrupt(APC_LEVEL);
}
}
/*

View file

@ -180,13 +180,13 @@ KeInsertHeadQueue(IN PKQUEUE Queue,
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
/* Lock the Dispatcher Database */
OldIrql = KeAcquireDispatcherDatabaseLock();
OldIrql = KiAcquireDispatcherLock();
/* Insert the Queue */
PreviousState = KiInsertQueue(Queue, Entry, TRUE);
/* Release the Dispatcher Lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
KiReleaseDispatcherLock(OldIrql);
/* Return previous State */
return PreviousState;
@ -206,13 +206,13 @@ KeInsertQueue(IN PKQUEUE Queue,
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
/* Lock the Dispatcher Database */
OldIrql = KeAcquireDispatcherDatabaseLock();
OldIrql = KiAcquireDispatcherLock();
/* Insert the Queue */
PreviousState = KiInsertQueue(Queue, Entry, FALSE);
/* Release the Dispatcher Lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
KiReleaseDispatcherLock(OldIrql);
/* Return previous State */
return PreviousState;
@ -263,7 +263,7 @@ KeRemoveQueue(IN PKQUEUE Queue,
else
{
/* Lock the Dispatcher Database */
OldIrql = KeAcquireDispatcherDatabaseLock();
OldIrql = KiAcquireDispatcherLock();
Thread->WaitIrql = OldIrql;
}
@ -335,7 +335,7 @@ KeRemoveQueue(IN PKQUEUE Queue,
{
/* Increment the count and unlock the dispatcher */
Queue->CurrentCount++;
KeReleaseDispatcherDatabaseLock(Thread->WaitIrql);
KiReleaseDispatcherLock(Thread->WaitIrql);
}
else
{
@ -449,7 +449,7 @@ KeRemoveQueue(IN PKQUEUE Queue,
}
/* Reacquire the lock */
OldIrql = KeAcquireDispatcherDatabaseLock();
OldIrql = KiAcquireDispatcherLock();
/* Save the new IRQL and decrease number of waiting threads */
Thread->WaitIrql = OldIrql;
@ -458,7 +458,7 @@ KeRemoveQueue(IN PKQUEUE Queue,
}
/* Unlock Database and return */
KeReleaseDispatcherDatabaseLock(Thread->WaitIrql);
KiReleaseDispatcherLock(Thread->WaitIrql);
return QueueEntry;
}
@ -478,7 +478,7 @@ KeRundownQueue(IN PKQUEUE Queue)
ASSERT(IsListEmpty(&Queue->Header.WaitListHead));
/* Get the Dispatcher Lock */
OldIrql = KeAcquireDispatcherDatabaseLock();
OldIrql = KiAcquireDispatcherLock();
/* Make sure the list is not empty */
if (!IsListEmpty(&Queue->EntryListHead))
@ -501,7 +501,7 @@ KeRundownQueue(IN PKQUEUE Queue)
}
/* Release the lock and return */
KeReleaseDispatcherDatabaseLock(OldIrql);
KiReleaseDispatcherLock(OldIrql);
return FirstEntry;
}

View file

@ -87,7 +87,7 @@ KeReleaseSemaphore(PKSEMAPHORE Semaphore,
Wait);
/* Lock the Dispatcher Database */
OldIrql = KeAcquireDispatcherDatabaseLock();
OldIrql = KiAcquireDispatcherLock();
/* Save the Old State and get new one */
InitialState = Semaphore->Header.SignalState;
@ -97,7 +97,7 @@ KeReleaseSemaphore(PKSEMAPHORE Semaphore,
if ((Semaphore->Limit < State) || (InitialState > State))
{
/* Raise an error if it was exceeded */
KeReleaseDispatcherDatabaseLock(OldIrql);
KiReleaseDispatcherLock(OldIrql);
ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED);
}
@ -115,7 +115,7 @@ KeReleaseSemaphore(PKSEMAPHORE Semaphore,
if (Wait == FALSE)
{
/* Release the Lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
KiReleaseDispatcherLock(OldIrql);
}
else
{

View file

@ -124,7 +124,7 @@ KiDispatchThreadNoLock(ULONG NewThreadStatus)
if (Candidate == CurrentThread) {
Candidate->State = Running;
KeReleaseDispatcherDatabaseLockFromDpcLevel();
KiReleaseDispatcherLockFromDpcLevel();
return FALSE;
}
@ -204,7 +204,7 @@ KiDispatchThread(ULONG NewThreadStatus)
return;
}
OldIrql = KeAcquireDispatcherDatabaseLock();
OldIrql = KiAcquireDispatcherLock();
KiDispatchThreadNoLock(NewThreadStatus);
KeLowerIrql(OldIrql);
}
@ -328,7 +328,7 @@ KiSetPriorityThread(PKTHREAD Thread,
/* Reschedule if the new one is already on a CPU */
if (Pcr->Prcb->CurrentThread == Thread)
{
KeReleaseDispatcherDatabaseLockFromDpcLevel();
KiReleaseDispatcherLockFromDpcLevel();
KiRequestReschedule(i);
*Released = TRUE;
return;
@ -393,7 +393,7 @@ KiSetAffinityThread(IN PKTHREAD Thread,
if (!(Affinity & ProcessorMask)) {
KeReleaseDispatcherDatabaseLockFromDpcLevel();
KiReleaseDispatcherLockFromDpcLevel();
KiRequestReschedule(i);
*Released = TRUE;
return OldAffinity;

View file

@ -142,7 +142,7 @@ KiExpireTimers(IN PKDPC Dpc,
InitializeListHead(&ExpiredTimerList);
/* Lock the Database and Raise IRQL */
OldIrql = KeAcquireDispatcherDatabaseLock();
OldIrql = KiAcquireDispatcherLock();
/* Query Interrupt Times */
InterruptTime = KeQueryInterruptTime();
@ -185,7 +185,7 @@ KiExpireTimers(IN PKDPC Dpc,
}
/* Release Dispatcher Lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
KiReleaseDispatcherLock(OldIrql);
}
/* PUBLIC FUNCTIONS **********************************************************/
@ -203,7 +203,7 @@ KeCancelTimer(IN OUT PKTIMER Timer)
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
/* Lock the Database and Raise IRQL */
OldIrql = KeAcquireDispatcherDatabaseLock();
OldIrql = KiAcquireDispatcherLock();
/* Check if it's inserted, and remove it if it is */
Inserted = Timer->Header.Inserted;
@ -218,7 +218,7 @@ KeCancelTimer(IN OUT PKTIMER Timer)
}
/* Release Dispatcher Lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
KiReleaseDispatcherLock(OldIrql);
return Inserted;
}
@ -293,7 +293,7 @@ KeSetTimerEx(IN OUT PKTIMER Timer,
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
/* Lock the Database and Raise IRQL */
OldIrql = KeAcquireDispatcherDatabaseLock();
OldIrql = KiAcquireDispatcherLock();
/* Check if it's inserted, and remove it if it is */
Inserted = Timer->Header.Inserted;
@ -341,7 +341,7 @@ KeSetTimerEx(IN OUT PKTIMER Timer,
}
/* Release Dispatcher Lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
KiReleaseDispatcherLock(OldIrql);
/* Return old state */
return Inserted;

View file

@ -252,7 +252,7 @@ KiExitDispatcher(IN KIRQL OldIrql)
else
{
/* Otherwise just release the lock */
KeReleaseDispatcherDatabaseLockFromDpcLevel();
KiReleaseDispatcherLockFromDpcLevel();
}
/* Lower irql back */
@ -287,7 +287,7 @@ KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode,
else
{
/* Lock not held, acquire it */
CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock();
CurrentThread->WaitIrql = KiAcquireDispatcherLock();
}
/* Use built-in Wait block */
@ -302,7 +302,7 @@ KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode,
(CurrentThread->WaitIrql < APC_LEVEL))
{
/* Unlock the dispatcher */
KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
KiReleaseDispatcherLock(CurrentThread->WaitIrql);
}
else
{
@ -372,11 +372,11 @@ KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode,
}
/* Acquire again the lock */
CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock();
CurrentThread->WaitIrql = KiAcquireDispatcherLock();
} while (TRUE);
/* Release the Lock, we are done */
KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
KiReleaseDispatcherLock(CurrentThread->WaitIrql);
return WaitStatus;
}
@ -410,7 +410,7 @@ KeWaitForSingleObject(IN PVOID Object,
else
{
/* Lock not held, acquire it */
CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock();
CurrentThread->WaitIrql = KiAcquireDispatcherLock();
}
/* Start the actual Loop */
@ -423,7 +423,7 @@ KeWaitForSingleObject(IN PVOID Object,
(CurrentThread->WaitIrql < APC_LEVEL))
{
/* Unlock the dispatcher */
KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
KiReleaseDispatcherLock(CurrentThread->WaitIrql);
}
else
{
@ -451,7 +451,7 @@ KeWaitForSingleObject(IN PVOID Object,
else
{
/* Raise an exception (see wasm.ru) */
KeReleaseDispatcherDatabaseLock(CurrentThread->
KiReleaseDispatcherLock(CurrentThread->
WaitIrql);
ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED);
}
@ -557,11 +557,11 @@ KeWaitForSingleObject(IN PVOID Object,
}
/* Acquire again the lock */
CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock();
CurrentThread->WaitIrql = KiAcquireDispatcherLock();
} while (TRUE);
/* Release the Lock, we are done */
KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
KiReleaseDispatcherLock(CurrentThread->WaitIrql);
return WaitStatus;
DontWait:
@ -569,7 +569,7 @@ DontWait:
KiAdjustQuantumThread(CurrentThread);
/* Release & Return */
KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
KiReleaseDispatcherLock(CurrentThread->WaitIrql);
return WaitStatus;
}
@ -611,7 +611,7 @@ KeWaitForMultipleObjects(IN ULONG Count,
else
{
/* Lock not held, acquire it */
CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock();
CurrentThread->WaitIrql = KiAcquireDispatcherLock();
}
/* Make sure the Wait Count is valid */
@ -646,7 +646,7 @@ KeWaitForMultipleObjects(IN ULONG Count,
(CurrentThread->WaitIrql < APC_LEVEL))
{
/* Unlock the dispatcher */
KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
KiReleaseDispatcherLock(CurrentThread->WaitIrql);
}
else
{
@ -689,7 +689,7 @@ KeWaitForMultipleObjects(IN ULONG Count,
else
{
/* Raise an exception (see wasm.ru) */
KeReleaseDispatcherDatabaseLock(CurrentThread->
KiReleaseDispatcherLock(CurrentThread->
WaitIrql);
ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED);
}
@ -713,7 +713,7 @@ KeWaitForMultipleObjects(IN ULONG Count,
(CurrentObject->Header.SignalState == MINLONG))
{
/* Raise an exception */
KeReleaseDispatcherDatabaseLock(CurrentThread->
KiReleaseDispatcherLock(CurrentThread->
WaitIrql);
ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED);
}
@ -844,12 +844,12 @@ KeWaitForMultipleObjects(IN ULONG Count,
}
/* Acquire again the lock */
CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock();
CurrentThread->WaitIrql = KiAcquireDispatcherLock();
}
} while (TRUE);
/* Release the Lock, we are done */
KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
KiReleaseDispatcherLock(CurrentThread->WaitIrql);
return WaitStatus;
DontWait:
@ -857,7 +857,7 @@ DontWait:
KiAdjustQuantumThread(CurrentThread);
/* Release & Return */
KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
KiReleaseDispatcherLock(CurrentThread->WaitIrql);
return WaitStatus;
}

View file

@ -105,9 +105,9 @@ PsInitIdleThread(VOID)
KernelMode,
FALSE);
oldIrql = KeAcquireDispatcherDatabaseLock ();
oldIrql = KiAcquireDispatcherLock ();
KiReadyThread(&IdleThread->Tcb);
KeReleaseDispatcherDatabaseLock(oldIrql);
KiReleaseDispatcherLock(oldIrql);
KeGetCurrentPrcb()->IdleThread = &IdleThread->Tcb;
KeSetPriorityThread(&IdleThread->Tcb, LOW_PRIORITY);

View file

@ -397,9 +397,9 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
if (CreateSuspended) KeResumeThread(&Thread->Tcb);
/* Dispatch thread */
OldIrql = KeAcquireDispatcherDatabaseLock ();
OldIrql = KiAcquireDispatcherLock ();
KiReadyThread(&Thread->Tcb);
KeReleaseDispatcherDatabaseLock(OldIrql);
KiReleaseDispatcherLock(OldIrql);
/* Dereference completely to kill it */
ObDereferenceObjectEx(Thread, 2);
@ -439,9 +439,9 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
if (CreateSuspended) KeResumeThread(&Thread->Tcb);
/* Dispatch thread */
OldIrql = KeAcquireDispatcherDatabaseLock ();
OldIrql = KiAcquireDispatcherLock ();
KiReadyThread(&Thread->Tcb);
KeReleaseDispatcherDatabaseLock(OldIrql);
KiReleaseDispatcherLock(OldIrql);
/* Dereference it, leaving only the keep-alive */
ObDereferenceObject(Thread);
@ -482,9 +482,9 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
if (CreateSuspended) KeResumeThread(&Thread->Tcb);
/* Dispatch thread */
OldIrql = KeAcquireDispatcherDatabaseLock ();
OldIrql = KiAcquireDispatcherLock ();
KiReadyThread(&Thread->Tcb);
KeReleaseDispatcherDatabaseLock(OldIrql);
KiReleaseDispatcherLock(OldIrql);
/* Dereference it, leaving only the keep-alive */
ObDereferenceObject(Thread);
@ -533,9 +533,9 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
/* Dispatch thread */
PSREFTRACE(Thread);
OldIrql = KeAcquireDispatcherDatabaseLock ();
OldIrql = KiAcquireDispatcherLock ();
KiReadyThread(&Thread->Tcb);
KeReleaseDispatcherDatabaseLock(OldIrql);
KiReleaseDispatcherLock(OldIrql);
/* Dereference it, leaving only the keep-alive */
ObDereferenceObject(Thread);