1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
\documentclass{article}
\usepackage{graphicx}
\usepackage{hyperref}
\title{CoreProcessScheduler: Technical Documentation}
\author{Amlal El Mahrouss}
\date{\today}
\begin{document}
\maketitle
\section{Abstract}
{The CoreProcessScheduler governs how the scheduling backend and policy of the kernel works, It is the common gateway for schedulers inside NeKernel based systems.}
\section{Overview}
{The CoreProcessScheduler (now referred as CPS) serves as the intermediate foundal between the scheduler backend and kernel.} {It takes care of process life-cycle management, team-based process grouping, and affinity-based CPU based allocation to mention the least.}
\section{The Affinity System}
{Processes are given CPU time affinity hints using an affinity kind type, these hints help the scheduler run or adjust the current process.}
\subsection{Sample Code \#1}
{The following sample is C++ code.} {The smaller the value, the more critical the process.}
\begin{verbatim}
enum struct AffinityKind : Int32 {
kRealTime = 100,
kVeryHigh = 150,
kHigh = 200,
kStandard = 1000,
kLowUsage = 1500,
kVeryLowUsage = 2000,
};
\end{verbatim}
\section{The Team System}
{The team system holds process metadata for the backend scheduler to run on. It holds methods and fields for backend specific operations.} {One implementation of such team is the UserProcessTeam object inside NeKernel.}
\subsection{Sample Code \#2}
{The following sample is used to hold team metadata.} {This is part of the NeKernel source tree.}
\begin{verbatim}
class UserProcessTeam final {
public:
explicit UserProcessTeam();
~UserProcessTeam() = default;
NE_COPY_DEFAULT(UserProcessTeam)
Array<USER_PROCESS, kSchedProcessLimitPerTeam>& AsArray();
Ref<USER_PROCESS>& AsRef();
ProcessID& Id() noexcept;
public:
USER_PROCESS_ARRAY mProcessList;
USER_PROCESS_REF mCurrentProcess;
ProcessID mTeamId{0};
ProcessID mProcessCur{0};
};
\end{verbatim}
\section{The Process Image System}
{The process image container is a design pattern made to contain process data and metadata, its purpose comes from the lack of mainstream operating systems of such ability to hold metadata.}
{This approach helps separate concerns and give modularity to the system, as the image and process structure are not mixed together.}
\subsection{Sample Code \#3}
{The following sample is a C++ container used to hold process data and metadata.} {This is part of the NeKernel source tree.}
\begin{verbatim}
struct PROCESS_IMAGE final {
explicit PROCESS_IMAGE() = default;
private:
friend USER_PROCESS;
friend KERNEL_TASK;
friend class UserProcessScheduler;
ImagePtr fCode;
ImagePtr fBlob;
public:
Bool HasCode() const { return this->fCode != nullptr; }
Bool HasImage() const { return this->fBlob != nullptr; }
ErrorOr<ImagePtr> LeakImage() {
if (this->fCode) {
return ErrorOr<ImagePtr>{this->fCode};
}
return ErrorOr<ImagePtr>{kErrorInvalidData};
}
ErrorOr<ImagePtr> LeakBlob() {
if (this->fBlob) {
return ErrorOr<ImagePtr>{this->fBlob};
}
return ErrorOr<ImagePtr>{kErrorInvalidData};
}
};
\end{verbatim}
\section{Conclusion}
{The CoreProcessScheduler is a piece of systems design with robust design and useful cases, although useful in desktop/server cases, It may not be suited for every other tasks.}
{And while one scheduler backend (such as the UserProcessScheduler) takes care of user process scheduling and fairness, the CoreProcessScheduler takes care of the foundation for those systems.}
\section{References}
{NeKernel}: \href{https://github.com/nekernel-org/nekernel}{NeKernel}
{CoreProcessScheduler}: \href{https://github.com/nekernel-org/nekernel/blob/dev/src/kernel/KernelKit/CoreProcessScheduler.h}{CoreProcessScheduler}
\end{document}
|