mirror of
https://github.com/reactos/reactos.git
synced 2024-07-30 08:08:56 +00:00
Basic support for priority boosting.
svn path=/trunk/; revision=12965
This commit is contained in:
parent
e0adece65b
commit
e6464bc179
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue