To enqueue and dequeue tasks is simple: The task is placed or respectively removed from the appropriate
list selected by array->queue + p->prio, and the corresponding bit in the bitmap is set if at least one task
is present, or removed if no tasks are left on the queue. Notice that new tasks are always queued at the
end of each list.
The two interesting operations are how the next task is selected and how preemption is handled. Consider
pick_next_task_rt, which handles selection of the next task first.
sched_find_first_bit is a standard function that finds the first set bit in active.bitmap— this means
that higher real-time priorities (which result in lower in-kernel priorities) are handled before lower realtime
priorities. The first task on the selected list is taken out, and se.exec_start is set to the current
real-time clock value of the run queue — that’s all that is required.
The implementation of the periodic tick is likewise simple. SCHED_FIFO tasks are easiest to handle: They
can run as long as they like and must pass control to another task explicitly by using the yield system
call:
If the current process is a round robin process, its time slice is decremented. When the time quantum
is not yet exceeded, nothing more needs to be done — the process can keep running. Once the counter
reverts to 0, its value is renewed to DEF_TIMESLICE, which is set to 100 * HZ / 1000, that is, 100 ms. If the
task is not the only task in its list, it is requeued to the end. Rescheduling is requested as usual by setting
the TIF_NEED_RESCHED flag with set_tsk_need_resched:
The sched_setscheduler system call must be used to convert a process into a real-time process. This call
is not discussed at length because it performs only the following simple tasks:
❑ It removes the process from its current queue using deactivate_task.
❑ It sets the real-time priority and the scheduling class in the task data structure.
❑ It reactivates the task.
If the process was not previously on any run queue, only the scheduling class and the new priority value
need be set; deactivation and reactivation are unnecessary.
Note that changing the scheduler class or priority is only possible without constraints if the
sched_setscheduler system call is performed by a process with root rights (or, equivalently, the
capability CAP_SYS_NICE). Otherwise, the following conditions apply:
❑ The scheduling class can only be changed from SCHED_NORMAL to SCHED_BATCH or vice versa. A
change to SCHED_FIFO is impossible.
❑ Only the priority of processes with the same UID or EUID as the EUID of the caller can be
changed. Additionally, the priority may only be decreased, but not increased.