Chapter 2: Process Management and Scheduling
void (*set_curr_task) (struct rq *rq);
void (*task_tick) (struct rq *rq, struct task_struct *p);
void (*task_new) (struct rq *rq, struct task_struct *p);
};
An instance ofstruct sched_classmust be provided for each scheduling class. Scheduling classes are
related in a flat hierarchy: Real-time processes are most important, so they are handled before completely
fair processes, which are, in turn, given preference to the idle tasks that are active on a CPU when there
is nothing better to do. Thenextelement connects thesched_classinstances of the different scheduling
classes in the described order. Note that this hierarchy is already set up at compile time: There is no
mechanism to add new scheduler classes dynamically at run time.
The operations that can be provided by each scheduling class are as follows:
❑ enqueue_taskadds a new process to the run queue. This happens when a process changes from
a sleeping into a runnable state.
❑ dequeue_taskprovides the inverse operation: It takes a process off a run queue. Naturally, this
happens when a process switches from a runnable into an un-runnable state, or when the kernel
decides to take it off the run queue for other reasons — for instance, because its priority needs to
be changed.
Although the termrun queueis used, the individual scheduling classes need not represent their
processes on a simple queue. In fact, recall from above that the completely fair scheduler uses a
red-black tree for this purpose.
❑ When a process wants to relinquish control of the processor voluntarily, it can use the
sched_yieldsystem call. This triggersyield_taskto be called in the kernel.
❑ check_preempt_curris used to preempt the current task with a newly woken task if this is
necessary. The function is called, for instance, when a new task is woken up with
wake_up_new_task.
❑ pick_next_taskselects the next task that is supposed to run, whileput_prev_taskis called
before the currently executing task is replaced with another one. Note that these operations are
notequivalent to putting tasks on and off the run queue likeenqueue_taskanddequeue_task.
Instead, they are responsible to give the CPU to a task, respectively, take it away. Switching
between different tasks, however, still requires performing a low-level context switch.
❑ set_curr_taskis called when the scheduling policy of a task is changed. There are also some
other places that call the function, butthey are not relevant for our purposes.
❑ task_tickis called by the periodic scheduler each time it is activated.
❑ new_taskallows for setting up a connection between theforksystem call and the scheduler.
Each time a new task is created, the scheduler is notified about this withnew_task.
The standard functionsactivate_taskanddeactivate_taskare provided to enqueue and dequeue a
task by calling the aforementioned functions. Additionally, they keep the kernel statistics up to date.
kernel/sched.c
static void enqueue_task(struct rq *rq, struct task_struct *p, int wakeup)
static void dequeue_task(struct rq *rq, struct task_struct *p, int sleep)
When a process is registered on a run queue, theon_rqelement of the embeddedsched_entityinstance
is set to 1, otherwise to 0.