Decrease quantum during wait and during no-wait... mentionned by Shmuel Baron
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
Modified: trunk/reactos/ntoskrnl/ke/kthread.c
Modified: trunk/reactos/ntoskrnl/ke/wait.c

Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
--- trunk/reactos/ntoskrnl/include/internal/ke.h	2005-07-30 23:16:03 UTC (rev 16906)
+++ trunk/reactos/ntoskrnl/include/internal/ke.h	2005-07-30 23:43:45 UTC (rev 16907)
@@ -81,6 +81,10 @@
 FASTCALL
 KiSwapContext(PKTHREAD NewThread);
 
+VOID
+STDCALL
+KiAdjustQuantumThread(IN PKTHREAD Thread);
+
 /* gmutex.c ********************************************************************/
 
 VOID

Modified: trunk/reactos/ntoskrnl/ke/kthread.c
--- trunk/reactos/ntoskrnl/ke/kthread.c	2005-07-30 23:16:03 UTC (rev 16906)
+++ trunk/reactos/ntoskrnl/ke/kthread.c	2005-07-30 23:43:45 UTC (rev 16907)
@@ -274,6 +274,9 @@
                 Thread->PriorityDecrement = Increment;
             }
 
+            /* Also decrease quantum */
+            Thread->Quantum--;
+
         } else {
 
             Thread->Quantum = Thread->QuantumReset;
@@ -321,6 +324,53 @@
 
 VOID
 STDCALL
+KiAdjustQuantumThread(IN PKTHREAD Thread)
+{
+    KPRIORITY Priority;
+
+    /* Don't adjust for RT threads */
+    if ((Thread->Priority < LOW_REALTIME_PRIORITY) &&
+        Thread->BasePriority < LOW_REALTIME_PRIORITY - 2)
+    {
+        /* Decrease Quantum by one and see if we've ran out */
+        if (--Thread->Quantum <= 0)
+        {
+            /* Return quantum */
+            Thread->Quantum = Thread->QuantumReset;
+
+            /* Calculate new Priority */
+            Priority = Thread->Priority - (Thread->PriorityDecrement + 1);
+
+            /* Normalize it if we've gone too low */
+            if (Priority < Thread->BasePriority)
+            {
+                /* Normalize it if we've gone too low */
+                Priority = Thread->BasePriority;
+            }
+
+            /* Reset the priority decrement, we've done it */
+            Thread->PriorityDecrement = 0;
+
+            /* Set the new priority, if needed */
+            if (Priority != Thread->Priority)
+            {
+                /* HACK HACK This isn't nice, but it's the only way with our current codebase */
+                Thread->Priority = Priority;
+            }
+            else
+            {
+                /* Priority hasn't changed, find a new thread */
+            }
+        }
+    }
+
+    /* Nothing to do... */
+    return;
+}
+
+
+VOID
+STDCALL
 KiSuspendThreadKernelRoutine(PKAPC Apc,
                              PKNORMAL_ROUTINE* NormalRoutine,
                              PVOID* NormalContext,

Modified: trunk/reactos/ntoskrnl/ke/wait.c
--- trunk/reactos/ntoskrnl/ke/wait.c	2005-07-30 23:16:03 UTC (rev 16906)
+++ trunk/reactos/ntoskrnl/ke/wait.c	2005-07-30 23:43:45 UTC (rev 16907)
@@ -250,7 +250,7 @@
                 /* It has a normal signal state, so unwait it and return */
                 KiSatisfyObjectWait(CurrentObject, CurrentThread);
                 Status = STATUS_WAIT_0;
-                goto WaitDone;
+                goto DontWait;
 
             } else {
 
@@ -285,7 +285,7 @@
 
                 /* Return a timeout */
                 Status = STATUS_TIMEOUT;
-                goto WaitDone;
+                goto DontWait;
             }
 
             /* Point to Timer Wait Block and Thread Timer */
@@ -311,7 +311,7 @@
 
                 /* Return a timeout if we couldn't insert the timer for some reason */
                 Status = STATUS_TIMEOUT;
-                goto WaitDone;
+                goto DontWait;
             }
         }
 
@@ -344,11 +344,19 @@
 
     } while (TRUE);
 
-WaitDone:
     /* Release the Lock, we are done */
     DPRINT("Returning from KeWaitForMultipleObjects(), %x. Status: %d\n", KeGetCurrentThread(), Status);
     KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
     return Status;
+
+DontWait:
+    /* Adjust the Quantum */
+    KiAdjustQuantumThread(CurrentThread);
+
+    /* Release & Return */
+    DPRINT("Returning from KeWaitForMultipleObjects(), %x. Status: %d\n. We did not wait.", KeGetCurrentThread(), Status);
+    KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
+    return Status;
 }
 
 /*
@@ -460,7 +468,7 @@
                         /* It has a normal signal state, so unwait it and return */
                         KiSatisfyObjectWait(CurrentObject, CurrentThread);
                         Status = STATUS_WAIT_0 | WaitIndex;
-                        goto WaitDone;
+                        goto DontWait;
 
                     } else {
 
@@ -504,7 +512,7 @@
             /* Satisfy their Waits and return to the caller */
             KiSatisifyMultipleObjectWaits(WaitBlock);
             Status = STATUS_WAIT_0;
-            goto WaitDone;
+            goto DontWait;
         }
 
         /* Make sure we can satisfy the Alertable request */
@@ -521,7 +529,7 @@
 
                 /* Return a timeout */
                 Status = STATUS_TIMEOUT;
-                goto WaitDone;
+                goto DontWait;
             }
 
             /* Point to Timer Wait Block and Thread Timer */
@@ -546,7 +554,7 @@
 
                 /* Return a timeout if we couldn't insert the timer for some reason */
                 Status = STATUS_TIMEOUT;
-                goto WaitDone;
+                goto DontWait;
             }
         }
 
@@ -590,11 +598,19 @@
 
     } while (TRUE);
 
-WaitDone:
     /* Release the Lock, we are done */
     DPRINT("Returning from KeWaitForMultipleObjects(), %x. Status: %d\n", KeGetCurrentThread(), Status);
     KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
     return Status;
+
+DontWait:
+    /* Adjust the Quantum */
+    KiAdjustQuantumThread(CurrentThread);
+
+    /* Release & Return */
+    DPRINT("Returning from KeWaitForMultipleObjects(), %x. Status: %d\n. We did not wait.", KeGetCurrentThread(), Status);
+    KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
+    return Status;
 }
 
 VOID