Basic support for priority boosting.

svn path=/trunk/; revision=12965
This commit is contained in:
Filip Navara 2005-01-12 13:43:05 +00:00
parent e0adece65b
commit e6464bc179
11 changed files with 79 additions and 34 deletions

View file

@ -147,7 +147,7 @@ VOID KeAcquireDispatcherDatabaseLockAtDpcLevel(VOID);
VOID KeReleaseDispatcherDatabaseLock(KIRQL Irql); VOID KeReleaseDispatcherDatabaseLock(KIRQL Irql);
VOID KeReleaseDispatcherDatabaseLockFromDpcLevel(VOID); VOID KeReleaseDispatcherDatabaseLockFromDpcLevel(VOID);
BOOLEAN KiDispatcherObjectWake(DISPATCHER_HEADER* hdr); BOOLEAN KiDispatcherObjectWake(DISPATCHER_HEADER* hdr, KPRIORITY increment);
VOID STDCALL KeExpireTimers(PKDPC Apc, VOID STDCALL KeExpireTimers(PKDPC Apc,
PVOID Arg1, PVOID Arg1,
PVOID Arg2, PVOID Arg2,

View file

@ -528,7 +528,7 @@ VOID
PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode, PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode,
BOOLEAN DispatcherLock, KIRQL WaitIrql, UCHAR WaitReason); BOOLEAN DispatcherLock, KIRQL WaitIrql, UCHAR WaitReason);
VOID VOID
PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus); PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus, KPRIORITY Increment);
VOID VOID
PsApplicationProcessorInit(VOID); PsApplicationProcessorInit(VOID);
VOID VOID

View file

@ -87,9 +87,9 @@ LONG STDCALL KeSetEvent (PKEVENT Event,
OldIrql = KeAcquireDispatcherDatabaseLock(); OldIrql = KeAcquireDispatcherDatabaseLock();
ret = InterlockedExchange(&(Event->Header.SignalState),1); ret = InterlockedExchange(&Event->Header.SignalState,1);
KiDispatcherObjectWake((DISPATCHER_HEADER *)Event); KiDispatcherObjectWake(&Event->Header, Increment);
if (Wait == FALSE) if (Wait == FALSE)
{ {
@ -117,8 +117,8 @@ NTSTATUS STDCALL KePulseEvent (PKEVENT Event,
DPRINT("KePulseEvent(Event %x, Wait %x)\n",Event,Wait); DPRINT("KePulseEvent(Event %x, Wait %x)\n",Event,Wait);
OldIrql = KeAcquireDispatcherDatabaseLock(); OldIrql = KeAcquireDispatcherDatabaseLock();
ret = InterlockedExchange(&(Event->Header.SignalState),1); ret = InterlockedExchange(&Event->Header.SignalState,1);
KiDispatcherObjectWake((DISPATCHER_HEADER *)Event); KiDispatcherObjectWake(&Event->Header, Increment);
InterlockedExchange(&(Event->Header.SignalState),0); InterlockedExchange(&(Event->Header.SignalState),0);
if (Wait == FALSE) if (Wait == FALSE)

View file

@ -82,7 +82,7 @@ KeReleaseMutex(IN PKMUTEX Mutex,
Mutex->OwnerThread = NULL; Mutex->OwnerThread = NULL;
if (Mutex->MutantListEntry.Flink && Mutex->MutantListEntry.Blink) if (Mutex->MutantListEntry.Flink && Mutex->MutantListEntry.Blink)
RemoveEntryList(&Mutex->MutantListEntry); RemoveEntryList(&Mutex->MutantListEntry);
KiDispatcherObjectWake(&Mutex->Header); KiDispatcherObjectWake(&Mutex->Header, IO_NO_INCREMENT);
} }
if (Wait == FALSE) if (Wait == FALSE)
@ -191,7 +191,7 @@ KeReleaseMutant(IN PKMUTANT Mutant,
Mutant->OwnerThread = NULL; Mutant->OwnerThread = NULL;
if (Mutant->MutantListEntry.Flink && Mutant->MutantListEntry.Blink) if (Mutant->MutantListEntry.Flink && Mutant->MutantListEntry.Blink)
RemoveEntryList(&Mutant->MutantListEntry); RemoveEntryList(&Mutant->MutantListEntry);
KiDispatcherObjectWake(&Mutant->Header); KiDispatcherObjectWake(&Mutant->Header, Increment);
} }
if (Wait == FALSE) if (Wait == FALSE)

View file

@ -100,7 +100,7 @@ KiInsertQueue(
!IsListEmpty(&Queue->Header.WaitListHead) && !IsListEmpty(&Queue->Header.WaitListHead) &&
KeGetCurrentThread()->Queue != Queue) KeGetCurrentThread()->Queue != Queue)
{ {
KiDispatcherObjectWake(&Queue->Header); KiDispatcherObjectWake(&Queue->Header, IO_NO_INCREMENT);
} }
return InitialState; return InitialState;
@ -179,7 +179,7 @@ KeRemoveQueue(IN PKQUEUE Queue,
if (Thread->Queue->CurrentCount < Thread->Queue->MaximumCount && if (Thread->Queue->CurrentCount < Thread->Queue->MaximumCount &&
!IsListEmpty(&Thread->Queue->EntryListHead)) !IsListEmpty(&Thread->Queue->EntryListHead))
{ {
KiDispatcherObjectWake(&Thread->Queue->Header); KiDispatcherObjectWake(&Thread->Queue->Header, 0);
} }
} }

View file

@ -105,7 +105,7 @@ KeReleaseSemaphore (PKSEMAPHORE Semaphore,
Semaphore->Header.SignalState += Adjustment; Semaphore->Header.SignalState += Adjustment;
if (InitialState == 0) if (InitialState == 0)
{ {
KiDispatcherObjectWake(&Semaphore->Header); KiDispatcherObjectWake(&Semaphore->Header, SEMAPHORE_INCREMENT);
} }
if (Wait == FALSE) if (Wait == FALSE)

View file

@ -529,7 +529,7 @@ HandleExpiredTimer(PKTIMER Timer)
KeAcquireDispatcherDatabaseLockAtDpcLevel(); KeAcquireDispatcherDatabaseLockAtDpcLevel();
Timer->Header.SignalState = TRUE; Timer->Header.SignalState = TRUE;
KiDispatcherObjectWake(&Timer->Header); KiDispatcherObjectWake(&Timer->Header, 0);
KeReleaseDispatcherDatabaseLockFromDpcLevel(); KeReleaseDispatcherDatabaseLockFromDpcLevel();
if (Timer->Period != 0) if (Timer->Period != 0)

View file

@ -25,8 +25,8 @@
static KSPIN_LOCK DispatcherDatabaseLock; static KSPIN_LOCK DispatcherDatabaseLock;
#define KeDispatcherObjectWakeOne(hdr) KeDispatcherObjectWakeOneOrAll(hdr, FALSE) #define KeDispatcherObjectWakeOne(hdr, increment) KeDispatcherObjectWakeOneOrAll(hdr, increment, FALSE)
#define KeDispatcherObjectWakeAll(hdr) KeDispatcherObjectWakeOneOrAll(hdr, TRUE) #define KeDispatcherObjectWakeAll(hdr, increment) KeDispatcherObjectWakeOneOrAll(hdr, increment, TRUE)
extern POBJECT_TYPE EXPORTED ExMutantObjectType; extern POBJECT_TYPE EXPORTED ExMutantObjectType;
extern POBJECT_TYPE EXPORTED ExSemaphoreObjectType; extern POBJECT_TYPE EXPORTED ExSemaphoreObjectType;
@ -227,13 +227,14 @@ BOOLEAN KiAbortWaitThread(PKTHREAD Thread, NTSTATUS WaitStatus)
if (WasWaiting) if (WasWaiting)
{ {
PsUnblockThread((PETHREAD)Thread, &WaitStatus); PsUnblockThread((PETHREAD)Thread, &WaitStatus, 0);
} }
return WasWaiting; return WasWaiting;
} }
static BOOLEAN static BOOLEAN
KeDispatcherObjectWakeOneOrAll(DISPATCHER_HEADER * hdr, KeDispatcherObjectWakeOneOrAll(DISPATCHER_HEADER * hdr,
KPRIORITY increment,
BOOLEAN WakeAll) BOOLEAN WakeAll)
{ {
PKWAIT_BLOCK Waiter; PKWAIT_BLOCK Waiter;
@ -332,7 +333,8 @@ KeDispatcherObjectWakeOneOrAll(DISPATCHER_HEADER * hdr,
WakedAny = TRUE; WakedAny = TRUE;
DPRINT("Waking %x status = %x\n", WaiterHead->Thread, Status); DPRINT("Waking %x status = %x\n", WaiterHead->Thread, Status);
PsUnblockThread(CONTAINING_RECORD(WaiterHead->Thread, ETHREAD, Tcb), &Status); PsUnblockThread(CONTAINING_RECORD(WaiterHead->Thread, ETHREAD, Tcb),
&Status, increment);
} }
} }
@ -340,7 +342,7 @@ KeDispatcherObjectWakeOneOrAll(DISPATCHER_HEADER * hdr,
} }
BOOLEAN KiDispatcherObjectWake(DISPATCHER_HEADER* hdr) BOOLEAN KiDispatcherObjectWake(DISPATCHER_HEADER* hdr, KPRIORITY increment)
/* /*
* FUNCTION: Wake threads waiting on a dispatcher object * FUNCTION: Wake threads waiting on a dispatcher object
* NOTE: The exact semantics of waking are dependant on the type of object * NOTE: The exact semantics of waking are dependant on the type of object
@ -355,19 +357,19 @@ BOOLEAN KiDispatcherObjectWake(DISPATCHER_HEADER* hdr)
switch (hdr->Type) switch (hdr->Type)
{ {
case InternalNotificationEvent: case InternalNotificationEvent:
return(KeDispatcherObjectWakeAll(hdr)); return(KeDispatcherObjectWakeAll(hdr, increment));
case InternalNotificationTimer: case InternalNotificationTimer:
return(KeDispatcherObjectWakeAll(hdr)); return(KeDispatcherObjectWakeAll(hdr, increment));
case InternalSynchronizationEvent: case InternalSynchronizationEvent:
return(KeDispatcherObjectWakeOne(hdr)); return(KeDispatcherObjectWakeOne(hdr, increment));
case InternalSynchronizationTimer: case InternalSynchronizationTimer:
return(KeDispatcherObjectWakeOne(hdr)); return(KeDispatcherObjectWakeOne(hdr, increment));
case InternalQueueType: case InternalQueueType:
return(KeDispatcherObjectWakeOne(hdr)); return(KeDispatcherObjectWakeOne(hdr, increment));
case InternalSemaphoreType: case InternalSemaphoreType:
DPRINT("hdr->SignalState %d\n", hdr->SignalState); DPRINT("hdr->SignalState %d\n", hdr->SignalState);
@ -376,20 +378,20 @@ BOOLEAN KiDispatcherObjectWake(DISPATCHER_HEADER* hdr)
do do
{ {
DPRINT("Waking one semaphore waiter\n"); DPRINT("Waking one semaphore waiter\n");
Ret = KeDispatcherObjectWakeOne(hdr); Ret = KeDispatcherObjectWakeOne(hdr, increment);
} while(hdr->SignalState > 0 && Ret) ; } while(hdr->SignalState > 0 && Ret) ;
return(Ret); return(Ret);
} }
else return FALSE; else return FALSE;
case InternalProcessType: case InternalProcessType:
return(KeDispatcherObjectWakeAll(hdr)); return(KeDispatcherObjectWakeAll(hdr, increment));
case InternalThreadType: case InternalThreadType:
return(KeDispatcherObjectWakeAll(hdr)); return(KeDispatcherObjectWakeAll(hdr, increment));
case InternalMutexType: case InternalMutexType:
return(KeDispatcherObjectWakeOne(hdr)); return(KeDispatcherObjectWakeOne(hdr, increment));
} }
DbgPrint("Dispatcher object %x has unknown type %d\n", hdr, hdr->Type); DbgPrint("Dispatcher object %x has unknown type %d\n", hdr, hdr->Type);
KEBUGCHECK(0); KEBUGCHECK(0);
@ -723,7 +725,7 @@ KeWaitForMultipleObjects(ULONG Count,
if (CurrentThread->Queue->CurrentCount < CurrentThread->Queue->MaximumCount && if (CurrentThread->Queue->CurrentCount < CurrentThread->Queue->MaximumCount &&
!IsListEmpty(&CurrentThread->Queue->EntryListHead)) !IsListEmpty(&CurrentThread->Queue->EntryListHead))
{ {
KiDispatcherObjectWake(&CurrentThread->Queue->Header); KiDispatcherObjectWake(&CurrentThread->Queue->Header, IO_NO_INCREMENT);
} }
} }

View file

@ -748,7 +748,7 @@ NtCreateThread(OUT PHANDLE ThreadHandle,
Thread->Tcb.Alerted[KernelMode] = TRUE; Thread->Tcb.Alerted[KernelMode] = TRUE;
oldIrql = KeAcquireDispatcherDatabaseLock (); oldIrql = KeAcquireDispatcherDatabaseLock ();
PsUnblockThread(Thread, NULL); PsUnblockThread(Thread, NULL, 0);
KeReleaseDispatcherDatabaseLock(oldIrql); KeReleaseDispatcherDatabaseLock(oldIrql);
@ -814,9 +814,9 @@ PsCreateSystemThread(PHANDLE ThreadHandle,
*ClientId=Thread->Cid; *ClientId=Thread->Cid;
} }
oldIrql = KeAcquireDispatcherDatabaseLock (); oldIrql = KeAcquireDispatcherDatabaseLock ();
PsUnblockThread(Thread, NULL); PsUnblockThread(Thread, NULL, 0);
KeReleaseDispatcherDatabaseLock(oldIrql); KeReleaseDispatcherDatabaseLock(oldIrql);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }

View file

@ -191,7 +191,7 @@ PsTerminateCurrentThread(NTSTATUS ExitStatus)
oldIrql = KeAcquireDispatcherDatabaseLock(); oldIrql = KeAcquireDispatcherDatabaseLock();
CurrentThread->Tcb.DispatcherHeader.SignalState = TRUE; CurrentThread->Tcb.DispatcherHeader.SignalState = TRUE;
KiDispatcherObjectWake(&CurrentThread->Tcb.DispatcherHeader); KiDispatcherObjectWake(&CurrentThread->Tcb.DispatcherHeader, IO_NO_INCREMENT);
KeReleaseDispatcherDatabaseLock (oldIrql); KeReleaseDispatcherDatabaseLock (oldIrql);
/* The last thread shall close the door on exit */ /* The last thread shall close the door on exit */
@ -325,7 +325,7 @@ PiTerminateProcess(PEPROCESS Process,
} }
OldIrql = KeAcquireDispatcherDatabaseLock (); OldIrql = KeAcquireDispatcherDatabaseLock ();
Process->Pcb.DispatcherHeader.SignalState = TRUE; Process->Pcb.DispatcherHeader.SignalState = TRUE;
KiDispatcherObjectWake(&Process->Pcb.DispatcherHeader); KiDispatcherObjectWake(&Process->Pcb.DispatcherHeader, IO_NO_INCREMENT);
KeReleaseDispatcherDatabaseLock (OldIrql); KeReleaseDispatcherDatabaseLock (OldIrql);
ObDereferenceObject(Process); ObDereferenceObject(Process);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);

View file

@ -475,7 +475,7 @@ PsDispatchThread(ULONG NewThreadStatus)
} }
VOID VOID
PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus) PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus, KPRIORITY Increment)
{ {
if (THREAD_STATE_TERMINATED_1 == Thread->Tcb.State || if (THREAD_STATE_TERMINATED_1 == Thread->Tcb.State ||
THREAD_STATE_TERMINATED_2 == Thread->Tcb.State) THREAD_STATE_TERMINATED_2 == Thread->Tcb.State)
@ -493,6 +493,22 @@ PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus)
{ {
ULONG Processor; ULONG Processor;
KAFFINITY Affinity; KAFFINITY Affinity;
/* FIXME: This propably isn't the right way to do it... */
if (Thread->Tcb.Priority < LOW_REALTIME_PRIORITY &&
Thread->Tcb.BasePriority < LOW_REALTIME_PRIORITY - 2)
{
if (!Thread->Tcb.PriorityDecrement && !Thread->Tcb.DisableBoost)
{
Thread->Tcb.Priority = Thread->Tcb.BasePriority + Increment;
Thread->Tcb.PriorityDecrement = Increment;
}
}
else
{
Thread->Tcb.Quantum = Thread->Tcb.ApcState.Process->ThreadQuantum;
}
if (WaitStatus != NULL) if (WaitStatus != NULL)
{ {
Thread->Tcb.WaitStatus = *WaitStatus; Thread->Tcb.WaitStatus = *WaitStatus;
@ -965,6 +981,33 @@ KeSetAffinityThread(PKTHREAD Thread,
} }
NTSTATUS STDCALL
NtAlertThread (IN HANDLE ThreadHandle)
{
PETHREAD Thread;
NTSTATUS Status;
NTSTATUS ThreadStatus;
KIRQL oldIrql;
Status = ObReferenceObjectByHandle(ThreadHandle,
THREAD_SUSPEND_RESUME,
PsThreadType,
UserMode,
(PVOID*)&Thread,
NULL);
if (Status != STATUS_SUCCESS)
{
return(Status);
}
ThreadStatus = STATUS_ALERTED;
oldIrql = KeAcquireDispatcherDatabaseLock();
(VOID)PsUnblockThread(Thread, &ThreadStatus, 0);
KeReleaseDispatcherDatabaseLock(oldIrql);
ObDereferenceObject(Thread);
return(STATUS_SUCCESS);
}
/********************************************************************** /**********************************************************************
* NtOpenThread/4 * NtOpenThread/4