Basic support for priority boosting.
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
Modified: trunk/reactos/ntoskrnl/include/internal/ps.h
Modified: trunk/reactos/ntoskrnl/ke/event.c
Modified: trunk/reactos/ntoskrnl/ke/mutex.c
Modified: trunk/reactos/ntoskrnl/ke/queue.c
Modified: trunk/reactos/ntoskrnl/ke/sem.c
Modified: trunk/reactos/ntoskrnl/ke/timer.c
Modified: trunk/reactos/ntoskrnl/ke/wait.c
Modified: trunk/reactos/ntoskrnl/ps/create.c
Modified: trunk/reactos/ntoskrnl/ps/kill.c
Modified: trunk/reactos/ntoskrnl/ps/thread.c

Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
--- trunk/reactos/ntoskrnl/include/internal/ke.h	2005-01-12 13:35:43 UTC (rev 12964)
+++ trunk/reactos/ntoskrnl/include/internal/ke.h	2005-01-12 13:43:05 UTC (rev 12965)
@@ -147,7 +147,7 @@
 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,

Modified: trunk/reactos/ntoskrnl/include/internal/ps.h
--- trunk/reactos/ntoskrnl/include/internal/ps.h	2005-01-12 13:35:43 UTC (rev 12964)
+++ trunk/reactos/ntoskrnl/include/internal/ps.h	2005-01-12 13:43:05 UTC (rev 12965)
@@ -528,7 +528,7 @@
 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

Modified: trunk/reactos/ntoskrnl/ke/event.c
--- trunk/reactos/ntoskrnl/ke/event.c	2005-01-12 13:35:43 UTC (rev 12964)
+++ trunk/reactos/ntoskrnl/ke/event.c	2005-01-12 13:43:05 UTC (rev 12965)
@@ -87,9 +87,9 @@
 
   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)
     {
@@ -117,8 +117,8 @@
 
    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)

Modified: trunk/reactos/ntoskrnl/ke/mutex.c
--- trunk/reactos/ntoskrnl/ke/mutex.c	2005-01-12 13:35:43 UTC (rev 12964)
+++ trunk/reactos/ntoskrnl/ke/mutex.c	2005-01-12 13:43:05 UTC (rev 12965)
@@ -82,7 +82,7 @@
       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)
@@ -191,7 +191,7 @@
       Mutant->OwnerThread = NULL;
       if (Mutant->MutantListEntry.Flink && Mutant->MutantListEntry.Blink)
 	RemoveEntryList(&Mutant->MutantListEntry);
-      KiDispatcherObjectWake(&Mutant->Header);
+      KiDispatcherObjectWake(&Mutant->Header, Increment);
     }
 
   if (Wait == FALSE)

Modified: trunk/reactos/ntoskrnl/ke/queue.c
--- trunk/reactos/ntoskrnl/ke/queue.c	2005-01-12 13:35:43 UTC (rev 12964)
+++ trunk/reactos/ntoskrnl/ke/queue.c	2005-01-12 13:43:05 UTC (rev 12965)
@@ -100,7 +100,7 @@
        !IsListEmpty(&Queue->Header.WaitListHead) &&
        KeGetCurrentThread()->Queue != Queue)
    {
-      KiDispatcherObjectWake(&Queue->Header);
+      KiDispatcherObjectWake(&Queue->Header, IO_NO_INCREMENT);
    }
 
    return InitialState;
@@ -179,7 +179,7 @@
          if (Thread->Queue->CurrentCount < Thread->Queue->MaximumCount && 
              !IsListEmpty(&Thread->Queue->EntryListHead))
          {
-            KiDispatcherObjectWake(&Thread->Queue->Header);
+            KiDispatcherObjectWake(&Thread->Queue->Header, 0);
          }
       }
 

Modified: trunk/reactos/ntoskrnl/ke/sem.c
--- trunk/reactos/ntoskrnl/ke/sem.c	2005-01-12 13:35:43 UTC (rev 12964)
+++ trunk/reactos/ntoskrnl/ke/sem.c	2005-01-12 13:43:05 UTC (rev 12965)
@@ -105,7 +105,7 @@
   Semaphore->Header.SignalState += Adjustment;
   if (InitialState == 0)
     {
-      KiDispatcherObjectWake(&Semaphore->Header);
+      KiDispatcherObjectWake(&Semaphore->Header, SEMAPHORE_INCREMENT);
     }
 
   if (Wait == FALSE)

Modified: trunk/reactos/ntoskrnl/ke/timer.c
--- trunk/reactos/ntoskrnl/ke/timer.c	2005-01-12 13:35:43 UTC (rev 12964)
+++ trunk/reactos/ntoskrnl/ke/timer.c	2005-01-12 13:43:05 UTC (rev 12965)
@@ -529,7 +529,7 @@
 
    KeAcquireDispatcherDatabaseLockAtDpcLevel();
    Timer->Header.SignalState = TRUE;
-   KiDispatcherObjectWake(&Timer->Header);
+   KiDispatcherObjectWake(&Timer->Header, 0);
    KeReleaseDispatcherDatabaseLockFromDpcLevel();
 
    if (Timer->Period != 0)

Modified: trunk/reactos/ntoskrnl/ke/wait.c
--- trunk/reactos/ntoskrnl/ke/wait.c	2005-01-12 13:35:43 UTC (rev 12964)
+++ trunk/reactos/ntoskrnl/ke/wait.c	2005-01-12 13:43:05 UTC (rev 12965)
@@ -25,8 +25,8 @@
 
 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;
@@ -227,13 +227,14 @@
 
    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;
@@ -332,7 +333,8 @@
 
          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);
       }
    }
 
@@ -340,7 +342,7 @@
 }
 
 
-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
@@ -355,19 +357,19 @@
    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);
@@ -376,20 +378,20 @@
 	    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);
@@ -723,7 +725,7 @@
          if (CurrentThread->Queue->CurrentCount < CurrentThread->Queue->MaximumCount &&
              !IsListEmpty(&CurrentThread->Queue->EntryListHead))
          {
-            KiDispatcherObjectWake(&CurrentThread->Queue->Header);
+            KiDispatcherObjectWake(&CurrentThread->Queue->Header, IO_NO_INCREMENT);
          }
       }
 

Modified: trunk/reactos/ntoskrnl/ps/create.c
--- trunk/reactos/ntoskrnl/ps/create.c	2005-01-12 13:35:43 UTC (rev 12964)
+++ trunk/reactos/ntoskrnl/ps/create.c	2005-01-12 13:43:05 UTC (rev 12965)
@@ -748,7 +748,7 @@
   Thread->Tcb.Alerted[KernelMode] = TRUE;
 
   oldIrql = KeAcquireDispatcherDatabaseLock ();
-  PsUnblockThread(Thread, NULL);
+  PsUnblockThread(Thread, NULL, 0);
   KeReleaseDispatcherDatabaseLock(oldIrql);
 
 
@@ -814,9 +814,9 @@
 	*ClientId=Thread->Cid;
      }
 
-  oldIrql = KeAcquireDispatcherDatabaseLock ();
-  PsUnblockThread(Thread, NULL);
-  KeReleaseDispatcherDatabaseLock(oldIrql);
+   oldIrql = KeAcquireDispatcherDatabaseLock ();
+   PsUnblockThread(Thread, NULL, 0);
+   KeReleaseDispatcherDatabaseLock(oldIrql);
    
    return(STATUS_SUCCESS);
 }

Modified: trunk/reactos/ntoskrnl/ps/kill.c
--- trunk/reactos/ntoskrnl/ps/kill.c	2005-01-12 13:35:43 UTC (rev 12964)
+++ trunk/reactos/ntoskrnl/ps/kill.c	2005-01-12 13:43:05 UTC (rev 12965)
@@ -191,7 +191,7 @@
 
    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 */
@@ -325,7 +325,7 @@
    }
    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);

Modified: trunk/reactos/ntoskrnl/ps/thread.c
--- trunk/reactos/ntoskrnl/ps/thread.c	2005-01-12 13:35:43 UTC (rev 12964)
+++ trunk/reactos/ntoskrnl/ps/thread.c	2005-01-12 13:43:05 UTC (rev 12965)
@@ -475,7 +475,7 @@
 }
 
 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)
@@ -493,6 +493,22 @@
     {
       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;
@@ -965,7 +981,34 @@
 }
 
 
+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
  *