VOID KeReleaseDispatcherDatabaseLock(KIRQL Irql);
VOID KeReleaseDispatcherDatabaseLockFromDpcLevel(VOID);
-BOOLEAN KiDispatcherObjectWake(DISPATCHER_HEADER* hdr);
+BOOLEAN KiDispatcherObjectWake(DISPATCHER_HEADER* hdr, KPRIORITY increment);
VOID STDCALL KeExpireTimers(PKDPC Apc,
PVOID Arg1,
PVOID Arg2,
PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode,
BOOLEAN DispatcherLock, KIRQL WaitIrql, UCHAR WaitReason);
VOID
-PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus);
+PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus, KPRIORITY Increment);
VOID
PsApplicationProcessorInit(VOID);
VOID
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)
{
DPRINT("KePulseEvent(Event %x, Wait %x)\n",Event,Wait);
OldIrql = KeAcquireDispatcherDatabaseLock();
- ret = InterlockedExchange(&(Event->Header.SignalState),1);
- KiDispatcherObjectWake((DISPATCHER_HEADER *)Event);
+ ret = InterlockedExchange(&Event->Header.SignalState,1);
+ KiDispatcherObjectWake(&Event->Header, Increment);
InterlockedExchange(&(Event->Header.SignalState),0);
if (Wait == FALSE)
Mutex->OwnerThread = NULL;
if (Mutex->MutantListEntry.Flink && Mutex->MutantListEntry.Blink)
RemoveEntryList(&Mutex->MutantListEntry);
- KiDispatcherObjectWake(&Mutex->Header);
+ KiDispatcherObjectWake(&Mutex->Header, IO_NO_INCREMENT);
}
if (Wait == FALSE)
Mutant->OwnerThread = NULL;
if (Mutant->MutantListEntry.Flink && Mutant->MutantListEntry.Blink)
RemoveEntryList(&Mutant->MutantListEntry);
- KiDispatcherObjectWake(&Mutant->Header);
+ KiDispatcherObjectWake(&Mutant->Header, Increment);
}
if (Wait == FALSE)
!IsListEmpty(&Queue->Header.WaitListHead) &&
KeGetCurrentThread()->Queue != Queue)
{
- KiDispatcherObjectWake(&Queue->Header);
+ KiDispatcherObjectWake(&Queue->Header, IO_NO_INCREMENT);
}
return InitialState;
if (Thread->Queue->CurrentCount < Thread->Queue->MaximumCount &&
!IsListEmpty(&Thread->Queue->EntryListHead))
{
- KiDispatcherObjectWake(&Thread->Queue->Header);
+ KiDispatcherObjectWake(&Thread->Queue->Header, 0);
}
}
Semaphore->Header.SignalState += Adjustment;
if (InitialState == 0)
{
- KiDispatcherObjectWake(&Semaphore->Header);
+ KiDispatcherObjectWake(&Semaphore->Header, SEMAPHORE_INCREMENT);
}
if (Wait == FALSE)
KeAcquireDispatcherDatabaseLockAtDpcLevel();
Timer->Header.SignalState = TRUE;
- KiDispatcherObjectWake(&Timer->Header);
+ KiDispatcherObjectWake(&Timer->Header, 0);
KeReleaseDispatcherDatabaseLockFromDpcLevel();
if (Timer->Period != 0)
static KSPIN_LOCK DispatcherDatabaseLock;
-#define KeDispatcherObjectWakeOne(hdr) KeDispatcherObjectWakeOneOrAll(hdr, FALSE)
-#define KeDispatcherObjectWakeAll(hdr) KeDispatcherObjectWakeOneOrAll(hdr, TRUE)
+#define KeDispatcherObjectWakeOne(hdr, increment) KeDispatcherObjectWakeOneOrAll(hdr, increment, FALSE)
+#define KeDispatcherObjectWakeAll(hdr, increment) KeDispatcherObjectWakeOneOrAll(hdr, increment, TRUE)
extern POBJECT_TYPE EXPORTED ExMutantObjectType;
extern POBJECT_TYPE EXPORTED ExSemaphoreObjectType;
if (WasWaiting)
{
- PsUnblockThread((PETHREAD)Thread, &WaitStatus);
+ PsUnblockThread((PETHREAD)Thread, &WaitStatus, 0);
}
return WasWaiting;
}
static BOOLEAN
KeDispatcherObjectWakeOneOrAll(DISPATCHER_HEADER * hdr,
+ KPRIORITY increment,
BOOLEAN WakeAll)
{
PKWAIT_BLOCK Waiter;
WakedAny = TRUE;
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);
}
}
}
-BOOLEAN KiDispatcherObjectWake(DISPATCHER_HEADER* hdr)
+BOOLEAN KiDispatcherObjectWake(DISPATCHER_HEADER* hdr, KPRIORITY increment)
/*
* FUNCTION: Wake threads waiting on a dispatcher object
* NOTE: The exact semantics of waking are dependant on the type of object
switch (hdr->Type)
{
case InternalNotificationEvent:
- return(KeDispatcherObjectWakeAll(hdr));
+ return(KeDispatcherObjectWakeAll(hdr, increment));
case InternalNotificationTimer:
- return(KeDispatcherObjectWakeAll(hdr));
+ return(KeDispatcherObjectWakeAll(hdr, increment));
case InternalSynchronizationEvent:
- return(KeDispatcherObjectWakeOne(hdr));
+ return(KeDispatcherObjectWakeOne(hdr, increment));
case InternalSynchronizationTimer:
- return(KeDispatcherObjectWakeOne(hdr));
+ return(KeDispatcherObjectWakeOne(hdr, increment));
case InternalQueueType:
- return(KeDispatcherObjectWakeOne(hdr));
+ return(KeDispatcherObjectWakeOne(hdr, increment));
case InternalSemaphoreType:
DPRINT("hdr->SignalState %d\n", hdr->SignalState);
do
{
DPRINT("Waking one semaphore waiter\n");
- Ret = KeDispatcherObjectWakeOne(hdr);
+ Ret = KeDispatcherObjectWakeOne(hdr, increment);
} while(hdr->SignalState > 0 && Ret) ;
return(Ret);
}
else return FALSE;
case InternalProcessType:
- return(KeDispatcherObjectWakeAll(hdr));
+ return(KeDispatcherObjectWakeAll(hdr, increment));
case InternalThreadType:
- return(KeDispatcherObjectWakeAll(hdr));
+ return(KeDispatcherObjectWakeAll(hdr, increment));
case InternalMutexType:
- return(KeDispatcherObjectWakeOne(hdr));
+ return(KeDispatcherObjectWakeOne(hdr, increment));
}
DbgPrint("Dispatcher object %x has unknown type %d\n", hdr, hdr->Type);
KEBUGCHECK(0);
if (CurrentThread->Queue->CurrentCount < CurrentThread->Queue->MaximumCount &&
!IsListEmpty(&CurrentThread->Queue->EntryListHead))
{
- KiDispatcherObjectWake(&CurrentThread->Queue->Header);
+ KiDispatcherObjectWake(&CurrentThread->Queue->Header, IO_NO_INCREMENT);
}
}
Thread->Tcb.Alerted[KernelMode] = TRUE;
oldIrql = KeAcquireDispatcherDatabaseLock ();
- PsUnblockThread(Thread, NULL);
+ PsUnblockThread(Thread, NULL, 0);
KeReleaseDispatcherDatabaseLock(oldIrql);
*ClientId=Thread->Cid;
}
- oldIrql = KeAcquireDispatcherDatabaseLock ();
- PsUnblockThread(Thread, NULL);
- KeReleaseDispatcherDatabaseLock(oldIrql);
+ oldIrql = KeAcquireDispatcherDatabaseLock ();
+ PsUnblockThread(Thread, NULL, 0);
+ KeReleaseDispatcherDatabaseLock(oldIrql);
return(STATUS_SUCCESS);
}
oldIrql = KeAcquireDispatcherDatabaseLock();
CurrentThread->Tcb.DispatcherHeader.SignalState = TRUE;
- KiDispatcherObjectWake(&CurrentThread->Tcb.DispatcherHeader);
+ KiDispatcherObjectWake(&CurrentThread->Tcb.DispatcherHeader, IO_NO_INCREMENT);
KeReleaseDispatcherDatabaseLock (oldIrql);
/* The last thread shall close the door on exit */
}
OldIrql = KeAcquireDispatcherDatabaseLock ();
Process->Pcb.DispatcherHeader.SignalState = TRUE;
- KiDispatcherObjectWake(&Process->Pcb.DispatcherHeader);
+ KiDispatcherObjectWake(&Process->Pcb.DispatcherHeader, IO_NO_INCREMENT);
KeReleaseDispatcherDatabaseLock (OldIrql);
ObDereferenceObject(Process);
return(STATUS_SUCCESS);
}
VOID
-PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus)
+PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus, KPRIORITY Increment)
{
if (THREAD_STATE_TERMINATED_1 == Thread->Tcb.State ||
THREAD_STATE_TERMINATED_2 == Thread->Tcb.State)
{
ULONG Processor;
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)
{
Thread->Tcb.WaitStatus = *WaitStatus;
}
+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