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=…
==============================================================================
--- 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=…
==============================================================================
--- 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=232…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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(a)reactos.org)
* Thomas Weidenmueller (w3seek(a)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=…
==============================================================================
--- 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=2…
==============================================================================
--- 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=…
==============================================================================
--- 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=2321…
==============================================================================
--- 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=…
==============================================================================
--- 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);
}
/*