[ros-diffs] [ion] 23214: - Implement Kernel, Memory Manager and Process Manager APIs for the following concepts (not yet used): - Process Quantum. - Fixed and Variable Quantum Tables. - Long and Short Quantum Variability. - Priority Separation and Separation Masks. - Foreground Quantum Table. - Process Priority, Priority Modes and Priority Classes. - Virtual Memory Priority - Job Scheduling Classes - Implement PsSetProcessPriorityByClass.

ion at svn.reactos.org ion at svn.reactos.org
Fri Jul 21 21:28:39 CEST 2006


Author: ion
Date: Fri Jul 21 23:28:38 2006
New Revision: 23214

URL: http://svn.reactos.org/svn/reactos?rev=23214&view=rev
Log:
- Implement Kernel, Memory Manager and Process Manager APIs for the following concepts (not yet used):
  - Process Quantum.
  - Fixed and Variable Quantum Tables.
  - Long and Short Quantum Variability.
  - Priority Separation and Separation Masks.
  - Foreground Quantum Table.
  - Process Priority, Priority Modes and Priority Classes.
  - Virtual Memory Priority
  - Job Scheduling Classes
- Implement PsSetProcessPriorityByClass.

Modified:
    trunk/reactos/include/ndk/ketypes.h
    trunk/reactos/include/ndk/pstypes.h
    trunk/reactos/ntoskrnl/KrnlFun.c
    trunk/reactos/ntoskrnl/include/internal/ke.h
    trunk/reactos/ntoskrnl/include/internal/mm.h
    trunk/reactos/ntoskrnl/include/internal/ps.h
    trunk/reactos/ntoskrnl/include/internal/ps_x.h
    trunk/reactos/ntoskrnl/ke/process.c
    trunk/reactos/ntoskrnl/mm/mminit.c
    trunk/reactos/ntoskrnl/mm/process.c
    trunk/reactos/ntoskrnl/ps/job.c
    trunk/reactos/ntoskrnl/ps/process.c

Modified: trunk/reactos/include/ndk/ketypes.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/ketypes.h?rev=23214&r1=23213&r2=23214&view=diff
==============================================================================
--- trunk/reactos/include/ndk/ketypes.h (original)
+++ trunk/reactos/include/ndk/ketypes.h Fri Jul 21 23:28:38 2006
@@ -929,6 +929,9 @@
 #endif
 } KPROCESS, *PKPROCESS;
 
+#define ASSERT_PROCESS(object) \
+    ASSERT((((object)->Header.Type & KOBJECT_TYPE_MASK) == ProcessObject))
+
 //
 // System Service Table Descriptor
 //

Modified: trunk/reactos/include/ndk/pstypes.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/pstypes.h?rev=23214&r1=23213&r2=23214&view=diff
==============================================================================
--- trunk/reactos/include/ndk/pstypes.h (original)
+++ trunk/reactos/include/ndk/pstypes.h Fri Jul 21 23:28:38 2006
@@ -107,6 +107,12 @@
 #define PROCESS_PRIORITY_IDLE                   3
 #define PROCESS_PRIORITY_NORMAL                 8
 #define PROCESS_PRIORITY_NORMAL_FOREGROUND      9
+
+//
+// Process Priority Separation Values (OR)
+//
+#define PSP_VARIABLE_QUANTUMS                   4
+#define PSP_LONG_QUANTUMS                       16
 
 //
 // Number of TLS expansion slots
@@ -303,6 +309,13 @@
 } THREADINFOCLASS;
 
 #else
+
+typedef enum _PSPROCESSPRIORITYMODE
+{
+    PsProcessPriorityForeground,
+    PsProcessPriorityBackground,
+    PsProcessPrioritySpinning
+} PSPROCESSPRIORITYMODE;
 
 typedef enum _JOBOBJECTINFOCLASS
 {

Modified: trunk/reactos/ntoskrnl/KrnlFun.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/KrnlFun.c?rev=23214&r1=23213&r2=23214&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/KrnlFun.c (original)
+++ trunk/reactos/ntoskrnl/KrnlFun.c Fri Jul 21 23:28:38 2006
@@ -48,4 +48,5 @@
 // Ke:
 //  - Add code for interval recalulation when wait interrupted by an APC
 //
-///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+

Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/ke.h?rev=23214&r1=23213&r2=23214&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ke.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ke.h Fri Jul 21 23:28:38 2006
@@ -397,6 +397,21 @@
     LARGE_INTEGER DirectoryTableBase
 );
 
+VOID
+NTAPI
+KeSetQuantumProcess(
+    IN PKPROCESS Process,
+    IN UCHAR Quantum
+);
+
+KPRIORITY
+NTAPI
+KeSetPriorityAndQuantumProcess(
+    IN PKPROCESS Process,
+    IN KPRIORITY Priority,
+    IN UCHAR Quantum OPTIONAL
+);
+
 ULONG
 STDCALL
 KeForceResumeThread(IN PKTHREAD Thread);

Modified: trunk/reactos/ntoskrnl/include/internal/mm.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/mm.h?rev=23214&r1=23213&r2=23214&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/mm.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/mm.h Fri Jul 21 23:28:38 2006
@@ -654,6 +654,13 @@
 NTAPI
 MmGetSessionLocaleId(VOID);
 
+NTSTATUS
+NTAPI
+MmSetMemoryPriorityProcess(
+    IN PEPROCESS Process,
+    IN UCHAR MemoryPriority
+);
+
 /* i386/pfault.c *************************************************************/
 
 NTSTATUS

Modified: trunk/reactos/ntoskrnl/include/internal/ps.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/ps.h?rev=23214&r1=23213&r2=23214&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ps.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ps.h Fri Jul 21 23:28:38 2006
@@ -18,6 +18,8 @@
 #define PSP_MAX_CREATE_THREAD_NOTIFY            8
 #define PSP_MAX_LOAD_IMAGE_NOTIFY               8
 #define PSP_MAX_CREATE_PROCESS_NOTIFY           8
+
+#define PSP_JOB_SCHEDULING_CLASSES              10
 
 VOID
 NTAPI
@@ -226,7 +228,8 @@
 extern PKWIN32_THREAD_CALLOUT PspW32ThreadCallout;
 extern PVOID PspSystemDllEntryPoint;
 extern PVOID PspSystemDllBase;
-
+extern BOOLEAN PspUseJobSchedulingClasses;
+extern CHAR PspJobSchedulingClasses[PSP_JOB_SCHEDULING_CLASSES];
 #include "ps_x.h"
 
 #endif /* __INCLUDE_INTERNAL_PS_H */

Modified: trunk/reactos/ntoskrnl/include/internal/ps_x.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/ps_x.h?rev=23214&r1=23213&r2=23214&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ps_x.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ps_x.h Fri Jul 21 23:28:38 2006
@@ -6,6 +6,18 @@
 * PROGRAMMERS:     Alex Ionescu (alex.ionescu at reactos.org)
 *                  Thomas Weidenmueller (w3seek at reactos.org)
 */
+
+//
+// Extract Quantum Settings from the Priority Separation Mask
+//
+#define PspPrioritySeparationFromMask(Mask)                 \
+    ((Mask) & 3)
+
+#define PspQuantumTypeFromMask(Mask)                        \
+    ((Mask) & 12)
+
+#define PspQuantumLengthFromMask(Mask)                      \
+    ((Mask) & 48)
 
 VOID
 FORCEINLINE

Modified: trunk/reactos/ntoskrnl/ke/process.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/process.c?rev=23214&r1=23213&r2=23214&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/process.c (original)
+++ trunk/reactos/ntoskrnl/ke/process.c Fri Jul 21 23:28:38 2006
@@ -221,6 +221,204 @@
     Ke386SetPageTableDirectory(NewProcess->DirectoryTableBase.u.LowPart);
 }
 
+VOID
+NTAPI
+KeSetQuantumProcess(IN PKPROCESS Process,
+                    IN UCHAR Quantum)
+{
+    KIRQL OldIrql;
+    PLIST_ENTRY NextEntry, ListHead;
+    PKTHREAD Thread;
+    ASSERT_PROCESS(Process);
+    ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
+
+    /* Lock Dispatcher */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+
+    /* Set new quantum */
+    Process->QuantumReset = Quantum;
+
+    /* Loop all child threads */
+    ListHead = &Process->ThreadListHead;
+    NextEntry = ListHead->Flink;
+    while (ListHead != NextEntry)
+    {
+        /* Get the thread */
+        Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
+
+        /* Set quantum */
+        Thread->QuantumReset = Quantum;
+
+        /* Go to the next one */
+        NextEntry = NextEntry->Flink;
+    }
+
+    /* Release Dispatcher Database */
+    KeReleaseDispatcherDatabaseLock(OldIrql);
+}
+
+KPRIORITY
+NTAPI
+KeSetPriorityAndQuantumProcess(IN PKPROCESS Process,
+                               IN KPRIORITY Priority,
+                               IN UCHAR Quantum OPTIONAL)
+{
+    KPRIORITY Delta;
+    PLIST_ENTRY NextEntry, ListHead;
+    KPRIORITY NewPriority, OldPriority;
+    KIRQL OldIrql;
+    PKTHREAD Thread;
+    BOOLEAN Released;
+    ASSERT_PROCESS(Process);
+    ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
+
+    /* Check if the process already has this priority */
+    if (Process->BasePriority == Priority)
+    {
+        /* Don't change anything */
+        return Process->BasePriority;
+    }
+
+    /* If the caller gave priority 0, normalize to 1 */
+    if (!Priority) Priority = 1;
+
+    /* Lock Dispatcher */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+
+    /* Check if we are modifying the quantum too */
+    if (Quantum) Process->QuantumReset = Quantum;
+
+    /* Save the current base priority and update it */
+    OldPriority = Process->BasePriority;
+    Process->BasePriority = Priority;
+
+    /* Calculate the priority delta */
+    Delta = Priority - OldPriority;
+
+    /* Set the list head and list entry */
+    ListHead = &Process->ThreadListHead;
+    NextEntry = ListHead->Flink;
+
+    /* Check if this is a real-time priority */
+    if (Priority >= LOW_REALTIME_PRIORITY)
+    {
+        /* Loop the thread list */
+        while (NextEntry != ListHead)
+        {
+            /* Get the thread */
+            Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
+
+            /* Update the quantum if we had one */
+            if (Quantum) Thread->QuantumReset = Quantum;
+
+            /* Calculate the new priority */
+            NewPriority = Thread->BasePriority + Delta;
+            if (NewPriority < LOW_REALTIME_PRIORITY)
+            {
+                /* We're in real-time range, don't let it go below */
+                NewPriority = LOW_REALTIME_PRIORITY;
+            }
+            else if (NewPriority > HIGH_PRIORITY)
+            {
+                /* We're going beyond the maximum priority, normalize */
+                NewPriority = HIGH_PRIORITY;
+            }
+
+            /*
+             * If priority saturation occured or the old priority was still in
+             * the real-time range, don't do anything.
+             */
+            if (!(Thread->Saturation) || (OldPriority < LOW_REALTIME_PRIORITY))
+            {
+                /* Check if we had priority saturation */
+                if (Thread->Saturation > 0)
+                {
+                    /* Boost priority to maximum */
+                    NewPriority = HIGH_PRIORITY;
+                }
+                else if (Thread->Saturation < 0)
+                {
+                    /* If we had negative saturation, set minimum priority */
+                    NewPriority = LOW_REALTIME_PRIORITY;
+                }
+
+                /* Update priority and quantum */
+                Thread->BasePriority = NewPriority;
+                Thread->Quantum = Thread->QuantumReset;
+
+                /* Disable decrements and update priority */
+                Thread->PriorityDecrement = 0;
+                KiSetPriorityThread(Thread, NewPriority, &Released);
+            }
+
+            /* Go to the next thread */
+            NextEntry = NextEntry->Flink;
+        }
+    }
+    else
+    {
+        /* Loop the thread list */
+        while (NextEntry != ListHead)
+        {
+            /* Get the thread */
+            Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
+
+            /* Update the quantum if we had one */
+            if (Quantum) Thread->QuantumReset = Quantum;
+
+            /* Calculate the new priority */
+            NewPriority = Thread->BasePriority + Delta;
+            if (NewPriority >= LOW_REALTIME_PRIORITY)
+            {
+                /* We're not real-time range, don't let it enter RT range */
+                NewPriority = LOW_REALTIME_PRIORITY - 1;
+            }
+            else if (NewPriority <= LOW_PRIORITY)
+            {
+                /* We're going below the minimum priority, normalize */
+                NewPriority = 1;
+            }
+
+            /*
+             * If priority saturation occured or the old priority was still in
+             * the real-time range, don't do anything.
+             */
+            if (!(Thread->Saturation) ||
+                (OldPriority >= LOW_REALTIME_PRIORITY))
+            {
+                /* Check if we had priority saturation */
+                if (Thread->Saturation > 0)
+                {
+                    /* Boost priority to maximum */
+                    NewPriority = LOW_REALTIME_PRIORITY - 1;
+                }
+                else if (Thread->Saturation < 0)
+                {
+                    /* If we had negative saturation, set minimum priority */
+                    NewPriority = 1;
+                }
+
+                /* Update priority and quantum */
+                Thread->BasePriority = NewPriority;
+                Thread->Quantum = Thread->QuantumReset;
+
+                /* Disable decrements and update priority */
+                Thread->PriorityDecrement = 0;
+                KiSetPriorityThread(Thread, NewPriority, &Released);
+            }
+
+            /* Go to the next thread */
+            NextEntry = NextEntry->Flink;
+        }
+    }
+
+    /* Release Dispatcher Database */
+    if (!Released) KeReleaseDispatcherDatabaseLock(OldIrql);
+
+    /* Return previous priority */
+    return OldPriority;
+}
+
 /*
  * @implemented
  */

Modified: trunk/reactos/ntoskrnl/mm/mminit.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/mminit.c?rev=23214&r1=23213&r2=23214&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/mm/mminit.c (original)
+++ trunk/reactos/ntoskrnl/mm/mminit.c Fri Jul 21 23:28:38 2006
@@ -29,7 +29,7 @@
 
 
 static BOOLEAN IsThisAnNtAsSystem = FALSE;
-static MM_SYSTEM_SIZE MmSystemSize = MmSmallSystem;
+MM_SYSTEM_SIZE MmSystemSize = MmSmallSystem;
 
 PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress;
 

Modified: trunk/reactos/ntoskrnl/mm/process.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/process.c?rev=23214&r1=23213&r2=23214&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/mm/process.c (original)
+++ trunk/reactos/ntoskrnl/mm/process.c Fri Jul 21 23:28:38 2006
@@ -17,11 +17,35 @@
 extern ULONG NtMinorVersion;
 extern ULONG NtOSCSDVersion;
 extern ULONG NtGlobalFlag;
+extern MM_SYSTEM_SIZE MmSystemSize;
 
 #define MM_HIGHEST_VAD_ADDRESS \
     (PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE))
 
 /* FUNCTIONS *****************************************************************/
+
+NTSTATUS
+NTAPI
+MmSetMemoryPriorityProcess(IN PEPROCESS Process,
+                           IN UCHAR MemoryPriority)
+{
+    UCHAR OldPriority;
+
+    /* Check if we have less then 16MB of Physical Memory */
+    if ((MmSystemSize == MmSmallSystem) &&
+        (MmStats.NrTotalPages < ((15 * 1024 * 1024) / PAGE_SIZE)))
+    {
+        /* Always use background priority */
+        MemoryPriority = 0;
+    }
+
+    /* Save the old priority and update it */
+    OldPriority = Process->Vm.Flags.MemoryPriority;
+    Process->Vm.Flags.MemoryPriority = MemoryPriority;
+
+    /* Return the old priority */
+    return OldPriority;
+}
 
 LCID
 NTAPI

Modified: trunk/reactos/ntoskrnl/ps/job.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/job.c?rev=23214&r1=23213&r2=23214&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ps/job.c (original)
+++ trunk/reactos/ntoskrnl/ps/job.c Fri Jul 21 23:28:38 2006
@@ -18,14 +18,28 @@
 #pragma alloc_text(INIT, PsInitJobManagment)
 #endif
 
-
-
 /* GLOBALS *******************************************************************/
 
 POBJECT_TYPE PsJobType = NULL;
 
 LIST_ENTRY PsJobListHead;
 static FAST_MUTEX PsJobListLock;
+
+BOOLEAN PspUseJobSchedulingClasses;
+
+CHAR PspJobSchedulingClasses[PSP_JOB_SCHEDULING_CLASSES] =
+{
+    1 * 6,
+    2 * 6,
+    3 * 6,
+    4 * 6,
+    5 * 6,
+    6 * 6,
+    7 * 6,
+    8 * 6,
+    9 * 6,
+    10 * 6
+};
 
 static GENERIC_MAPPING PiJobMapping =
 {

Modified: trunk/reactos/ntoskrnl/ps/process.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/process.c?rev=23214&r1=23213&r2=23214&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ps/process.c (original)
+++ trunk/reactos/ntoskrnl/ps/process.c Fri Jul 21 23:28:38 2006
@@ -27,6 +27,49 @@
 
 LARGE_INTEGER ShortPsLockDelay;
 
+ULONG PsPrioritySeparation;
+CHAR PspForegroundQuantum[3];
+
+/* Fixed quantum table */
+CHAR PspFixedQuantums[6] =
+{
+    /* Short quantums */
+    3 * 6, /* Level 1 */
+    3 * 6, /* Level 2 */
+    3 * 6, /* Level 3 */
+
+    /* Long quantums */
+    6 * 6, /* Level 1 */
+    6 * 6, /* Level 2 */
+    6 * 6  /* Level 3 */
+};
+
+/* Variable quantum table */
+CHAR PspVariableQuantums[6] =
+{
+    /* Short quantums */
+    1 * 6, /* Level 1 */
+    2 * 6, /* Level 2 */
+    3 * 6, /* Level 3 */
+
+    /* Long quantums */
+    2 * 6, /* Level 1 */
+    4 * 6, /* Level 2 */
+    6 * 6  /* Level 3 */
+};
+
+/* Priority table */
+KPRIORITY PspPriorityTable[PROCESS_PRIORITY_CLASS_ABOVE_NORMAL + 1] =
+{
+    8,
+    4,
+    8,
+    13,
+    24,
+    6,
+    10
+};
+
 /* PRIVATE FUNCTIONS *********************************************************/
 
 NTSTATUS
@@ -140,6 +183,164 @@
     /* Reference the Process we had referenced earlier */
     if (OldProcess) ObDereferenceObject(OldProcess);
     return FoundProcess;
+}
+
+KPRIORITY
+NTAPI
+PspComputeQuantumAndPriority(IN PEPROCESS Process,
+                             IN PSPROCESSPRIORITYMODE Mode,
+                             OUT PCHAR Quantum)
+{
+    ULONG i;
+    UCHAR LocalQuantum, MemoryPriority;
+    PAGED_CODE();
+
+    /* Check if this is a foreground process */
+    if (Mode == PsProcessPriorityForeground)
+    {
+        /* Set the memory priority and use priority separation */
+        MemoryPriority = 2;
+        i = PsPrioritySeparation;
+    }
+    else
+    {
+        /* Set the background memory priority and no separation */
+        MemoryPriority = 0;
+        i = 0;
+    }
+
+    /* Make sure that the process mode isn't spinning */
+    if (Mode != PsProcessPrioritySpinning)
+    {
+        /* Set the priority */
+        MmSetMemoryPriorityProcess(Process, MemoryPriority);
+    }
+
+    /* Make sure that the process isn't idle */
+    if (Process->PriorityClass != PROCESS_PRIORITY_CLASS_IDLE)
+    {
+        /* Does the process have a job? */
+        if ((Process->Job) && (PspUseJobSchedulingClasses))
+        {
+            /* Use job quantum */
+            LocalQuantum = PspJobSchedulingClasses[Process->Job->
+                                                   SchedulingClass];
+        }
+        else
+        {
+            /* Use calculated quantum */
+            LocalQuantum = PspForegroundQuantum[i];
+        }
+    }
+    else
+    {
+        /* Process is idle, use default quantum */
+        LocalQuantum = 6;
+    }
+
+    /* Return quantum to caller */
+    *Quantum = LocalQuantum;
+
+    /* Return priority */
+    return PspPriorityTable[Process->PriorityClass];
+}
+
+VOID
+NTAPI
+PsChangeQuantumTable(IN BOOLEAN Immediate,
+                     IN ULONG PrioritySeparation)
+{
+    PEPROCESS Process = NULL;
+    ULONG i;
+    UCHAR Quantum;
+    PCHAR QuantumTable;
+    PAGED_CODE();
+
+    /* Write the current priority separation */
+    PsPrioritySeparation = PspPrioritySeparationFromMask(PrioritySeparation);
+
+    /* Normalize it if it was too high */
+    if (PsPrioritySeparation == 3) PsPrioritySeparation = 2;
+
+    /* Get the quantum table to use */
+    if (PspQuantumTypeFromMask(PrioritySeparation) == PSP_VARIABLE_QUANTUMS)
+    {
+        /* Use a variable table */
+        QuantumTable = PspVariableQuantums;
+    }
+    else
+    {
+        /* Use fixed table */
+        QuantumTable = PspFixedQuantums;
+    }
+
+    /* Now check if we should use long or short */
+    if (PspQuantumLengthFromMask(PrioritySeparation) == PSP_LONG_QUANTUMS)
+    {
+        /* Use long quantums */
+        QuantumTable += 3;
+    }
+
+    /* Check if we're using long fixed quantums */
+    if (QuantumTable == &PspFixedQuantums[3])
+    {
+        /* Use Job scheduling classes */
+         PspUseJobSchedulingClasses = TRUE;
+    }
+    else
+    {
+        /* Otherwise, we don't */
+        PspUseJobSchedulingClasses = FALSE;
+    }
+
+    /* Copy the selected table into the Foreground Quantum table */
+    RtlCopyMemory(PspForegroundQuantum,
+                  QuantumTable,
+                  sizeof(PspForegroundQuantum));
+
+    /* Check if we should apply these changes real-time */
+    if (Immediate)
+    {
+        /* We are...loop every process */
+        Process == PsGetNextProcess(Process);
+        while (Process)
+        {
+            /*
+             * Use the priority separation, unless the process has
+             * low memory priority
+             */
+            i = (Process->Vm.Flags.MemoryPriority == 1) ?
+                0: PsPrioritySeparation;
+
+            /* Make sure that the process isn't idle */
+            if (Process->PriorityClass != PROCESS_PRIORITY_CLASS_IDLE)
+            {
+                /* Does the process have a job? */
+                if ((Process->Job) && (PspUseJobSchedulingClasses))
+                {
+                    /* Use job quantum */
+                    Quantum = PspJobSchedulingClasses[Process->Job->
+                                                      SchedulingClass];
+                }
+                else
+                {
+                    /* Use calculated quantum */
+                    Quantum = PspForegroundQuantum[i];
+                }
+            }
+            else
+            {
+                /* Process is idle, use default quantum */
+                Quantum = 6;
+            }
+
+            /* Now set the quantum */
+            KeSetQuantumProcess(&Process->Pcb, Quantum);
+
+            /* Get the next process */
+            Process == PsGetNextProcess(Process);
+        }
+    }
 }
 
 NTSTATUS
@@ -861,15 +1062,21 @@
 }
 
 /*
- * @unimplemented
- */
-NTSTATUS
+ * @implemented
+ */
+VOID
 NTAPI
 PsSetProcessPriorityByClass(IN PEPROCESS Process,
-                            IN ULONG Type)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+                            IN PSPROCESSPRIORITYMODE Type)
+{
+    UCHAR Quantum;
+    ULONG Priority;
+
+    /* Compute quantum and priority */
+    Priority = PspComputeQuantumAndPriority(Process, Type, &Quantum);
+
+    /* Set them */
+    KeSetPriorityAndQuantumProcess(&Process->Pcb, Priority, Quantum);
 }
 
 /*




More information about the Ros-diffs mailing list