mirror of
https://github.com/reactos/reactos.git
synced 2025-06-06 01:40:36 +00:00
- 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. svn path=/trunk/; revision=23214
This commit is contained in:
parent
3ea8db48b1
commit
2f2139d851
12 changed files with 507 additions and 10 deletions
|
@ -929,6 +929,9 @@ typedef struct _KPROCESS
|
||||||
#endif
|
#endif
|
||||||
} KPROCESS, *PKPROCESS;
|
} KPROCESS, *PKPROCESS;
|
||||||
|
|
||||||
|
#define ASSERT_PROCESS(object) \
|
||||||
|
ASSERT((((object)->Header.Type & KOBJECT_TYPE_MASK) == ProcessObject))
|
||||||
|
|
||||||
//
|
//
|
||||||
// System Service Table Descriptor
|
// System Service Table Descriptor
|
||||||
//
|
//
|
||||||
|
|
|
@ -108,6 +108,12 @@ extern NTSYSAPI POBJECT_TYPE PsProcessType;
|
||||||
#define PROCESS_PRIORITY_NORMAL 8
|
#define PROCESS_PRIORITY_NORMAL 8
|
||||||
#define PROCESS_PRIORITY_NORMAL_FOREGROUND 9
|
#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
|
// Number of TLS expansion slots
|
||||||
//
|
//
|
||||||
|
@ -304,6 +310,13 @@ typedef enum _THREADINFOCLASS
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
typedef enum _PSPROCESSPRIORITYMODE
|
||||||
|
{
|
||||||
|
PsProcessPriorityForeground,
|
||||||
|
PsProcessPriorityBackground,
|
||||||
|
PsProcessPrioritySpinning
|
||||||
|
} PSPROCESSPRIORITYMODE;
|
||||||
|
|
||||||
typedef enum _JOBOBJECTINFOCLASS
|
typedef enum _JOBOBJECTINFOCLASS
|
||||||
{
|
{
|
||||||
JobObjectBasicAccountingInformation = 1,
|
JobObjectBasicAccountingInformation = 1,
|
||||||
|
|
|
@ -48,4 +48,5 @@
|
||||||
// Ke:
|
// Ke:
|
||||||
// - Add code for interval recalulation when wait interrupted by an APC
|
// - Add code for interval recalulation when wait interrupted by an APC
|
||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
|
@ -397,6 +397,21 @@ KeInitializeProcess(
|
||||||
LARGE_INTEGER DirectoryTableBase
|
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
|
ULONG
|
||||||
STDCALL
|
STDCALL
|
||||||
KeForceResumeThread(IN PKTHREAD Thread);
|
KeForceResumeThread(IN PKTHREAD Thread);
|
||||||
|
|
|
@ -654,6 +654,13 @@ ULONG
|
||||||
NTAPI
|
NTAPI
|
||||||
MmGetSessionLocaleId(VOID);
|
MmGetSessionLocaleId(VOID);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
MmSetMemoryPriorityProcess(
|
||||||
|
IN PEPROCESS Process,
|
||||||
|
IN UCHAR MemoryPriority
|
||||||
|
);
|
||||||
|
|
||||||
/* i386/pfault.c *************************************************************/
|
/* i386/pfault.c *************************************************************/
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -19,6 +19,8 @@ struct _EJOB;
|
||||||
#define PSP_MAX_LOAD_IMAGE_NOTIFY 8
|
#define PSP_MAX_LOAD_IMAGE_NOTIFY 8
|
||||||
#define PSP_MAX_CREATE_PROCESS_NOTIFY 8
|
#define PSP_MAX_CREATE_PROCESS_NOTIFY 8
|
||||||
|
|
||||||
|
#define PSP_JOB_SCHEDULING_CLASSES 10
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
PspShutdownProcessManager(VOID);
|
PspShutdownProcessManager(VOID);
|
||||||
|
@ -226,7 +228,8 @@ extern PKWIN32_PROCESS_CALLOUT PspW32ProcessCallout;
|
||||||
extern PKWIN32_THREAD_CALLOUT PspW32ThreadCallout;
|
extern PKWIN32_THREAD_CALLOUT PspW32ThreadCallout;
|
||||||
extern PVOID PspSystemDllEntryPoint;
|
extern PVOID PspSystemDllEntryPoint;
|
||||||
extern PVOID PspSystemDllBase;
|
extern PVOID PspSystemDllBase;
|
||||||
|
extern BOOLEAN PspUseJobSchedulingClasses;
|
||||||
|
extern CHAR PspJobSchedulingClasses[PSP_JOB_SCHEDULING_CLASSES];
|
||||||
#include "ps_x.h"
|
#include "ps_x.h"
|
||||||
|
|
||||||
#endif /* __INCLUDE_INTERNAL_PS_H */
|
#endif /* __INCLUDE_INTERNAL_PS_H */
|
||||||
|
|
|
@ -7,6 +7,18 @@
|
||||||
* Thomas Weidenmueller (w3seek@reactos.org)
|
* Thomas Weidenmueller (w3seek@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
|
VOID
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
PspRunCreateThreadNotifyRoutines(IN PETHREAD CurrentThread,
|
PspRunCreateThreadNotifyRoutines(IN PETHREAD CurrentThread,
|
||||||
|
|
|
@ -221,6 +221,204 @@ KiSwapProcess(PKPROCESS NewProcess,
|
||||||
Ke386SetPageTableDirectory(NewProcess->DirectoryTableBase.u.LowPart);
|
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
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -29,7 +29,7 @@ extern unsigned int _bss_end__;
|
||||||
|
|
||||||
|
|
||||||
static BOOLEAN IsThisAnNtAsSystem = FALSE;
|
static BOOLEAN IsThisAnNtAsSystem = FALSE;
|
||||||
static MM_SYSTEM_SIZE MmSystemSize = MmSmallSystem;
|
MM_SYSTEM_SIZE MmSystemSize = MmSmallSystem;
|
||||||
|
|
||||||
PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress;
|
PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress;
|
||||||
|
|
||||||
|
|
|
@ -17,12 +17,36 @@ extern ULONG NtMajorVersion;
|
||||||
extern ULONG NtMinorVersion;
|
extern ULONG NtMinorVersion;
|
||||||
extern ULONG NtOSCSDVersion;
|
extern ULONG NtOSCSDVersion;
|
||||||
extern ULONG NtGlobalFlag;
|
extern ULONG NtGlobalFlag;
|
||||||
|
extern MM_SYSTEM_SIZE MmSystemSize;
|
||||||
|
|
||||||
#define MM_HIGHEST_VAD_ADDRESS \
|
#define MM_HIGHEST_VAD_ADDRESS \
|
||||||
(PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE))
|
(PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE))
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* 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
|
LCID
|
||||||
NTAPI
|
NTAPI
|
||||||
MmGetSessionLocaleId(VOID)
|
MmGetSessionLocaleId(VOID)
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
#pragma alloc_text(INIT, PsInitJobManagment)
|
#pragma alloc_text(INIT, PsInitJobManagment)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
POBJECT_TYPE PsJobType = NULL;
|
POBJECT_TYPE PsJobType = NULL;
|
||||||
|
@ -27,6 +25,22 @@ POBJECT_TYPE PsJobType = NULL;
|
||||||
LIST_ENTRY PsJobListHead;
|
LIST_ENTRY PsJobListHead;
|
||||||
static FAST_MUTEX PsJobListLock;
|
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 =
|
static GENERIC_MAPPING PiJobMapping =
|
||||||
{
|
{
|
||||||
STANDARD_RIGHTS_READ | JOB_OBJECT_QUERY,
|
STANDARD_RIGHTS_READ | JOB_OBJECT_QUERY,
|
||||||
|
|
|
@ -27,6 +27,49 @@ KGUARDED_MUTEX PspActiveProcessMutex;
|
||||||
|
|
||||||
LARGE_INTEGER ShortPsLockDelay;
|
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 *********************************************************/
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -142,6 +185,164 @@ PsGetNextProcess(IN PEPROCESS OldProcess)
|
||||||
return FoundProcess;
|
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
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
PspCreateProcess(OUT PHANDLE ProcessHandle,
|
PspCreateProcess(OUT PHANDLE ProcessHandle,
|
||||||
|
@ -861,15 +1062,21 @@ PsSetProcessWindowStation(PEPROCESS Process,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
PsSetProcessPriorityByClass(IN PEPROCESS Process,
|
PsSetProcessPriorityByClass(IN PEPROCESS Process,
|
||||||
IN ULONG Type)
|
IN PSPROCESSPRIORITYMODE Type)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UCHAR Quantum;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
ULONG Priority;
|
||||||
|
|
||||||
|
/* Compute quantum and priority */
|
||||||
|
Priority = PspComputeQuantumAndPriority(Process, Type, &Quantum);
|
||||||
|
|
||||||
|
/* Set them */
|
||||||
|
KeSetPriorityAndQuantumProcess(&Process->Pcb, Priority, Quantum);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue