4.1 Multi-tasking
Multi-tasking operating system: concurrently interactively executing multiple processes
Multitasking operating systems can cause multiple processes to clog or sleep. These tasks, although they are in memory, are not in a functioning state. These processes use the kernel to block themselves until an event occurs.
Multi-tasking systems can be divided into two categories: non-preemptive and preemptive.
Preemption: Forced suspend.
Time slices: The processor time period that is assigned to each running process.
process scheduling for 4.2 Linux
4.3 strategy
The policy determines when the scheduler will let the program run.
4.3.1I/O consumption-and processor-consumable processes
I/O consumption: Most of the time the process is used to submit I/O Request or wait I/O request. Such a process is often operational, but usually runs for just a few moments because it is always blocked while waiting for more I/O requests.
Processor consumption type: Most of the time is spent on executing code. Unless they are preempted, they are generally kept running. Their scheduling strategy is usually to minimize their dispatch frequency and prolong their uptime.
Scheduling policy requirements:1, short response time 2, high throughput
4.3.2 Process Priority
Thought: Grading processes based on the value of the process and its need for processor time
The scheduler always chooses the process in which the time slice is not exhausted and the highest priority is run.
Linux two different priority ranges are used:
1 , Nice Value: Range -20~+19 , the default value is 0 ; the bigger the Nice value means a lower priority. High-priority processes can get more processor time.
2 , real-time priority: Value configurable, by default the range is 0~99. the higher the real-time priority value means the higher the process priority. Any real-time process has a higher priority than a normal process. Refer to the UNIX - related
Standard:posix.1b.
Real-time priorities and nice priorities are in the two areas of disjoint.
4.3.3 Time Slice
Too long a time slice can cause the system to respond poorly to interactions, and too short can significantly increase the processor time that is brought by process switching.
The processor time obtained by the process is related to the system load nice value.
4.4linux Scheduling Algorithm
4.4.1 Scheduler Class
Linux schedulers are provided in a modular manner, allowing different types of processes to selectively select scheduling algorithms. This modular structure is called the Scheduler class.
Each scheduler has a priority, the underlying scheduler code is defined in the kernel/sched.c file, it traverses the scheduler in order of precedence, and the Scheduler class with the highest priority of an executable process wins, choosing a program to execute below.
Fully Fair dispatch (CFS): Scheduling classes for normal processes, called sched_normalin Linux,CFS the algorithm is defined in the file kernel/sched_fair.c .
4.4.2 process scheduling in UNIX processes
The following issues exist:
1 , to add Nice values are mapped to time slices, it is necessary to Nice The unit value corresponds to the absolute time of the processor, but doing so will result in process switching not being optimized.
2 , the process of Nice value decreased 1 The effect is greatly dependent on its Nice 's initial value.
3 , if you perform Nice to the time slice mapping, the time slice must be an integer multiple of the timer beat, and the system timer limits the difference of two time slices.
4 , priority-based scheduler wakes up the process in order to optimize the interaction, in order for the process to run as quickly as possible, and to prioritize new processes to wake up, even if their time slices are exhausted, allowing a given process to break the principle of fairness, gain more processor time, and compromise the benefits of other processes in the system.
CFS Improvement: Completely discard the time slices instead of assigning to the process a processor to use the weighting.
4.4.3 Fair Dispatch
We want the process to run only a very short period, and theCFS Implementation first ensures that the system performance is not lost.
CFS Practice: Allow each process to run for a period of time, cycle round, select the least-run process as the next running process, and no longer take the practice of allocating time slices to each process. The nice value is the weight of the processor running in CFS as the process gets: The higher the Nice value process gets the lower the processor usage weight.
How to calculate the accurate time slice?
CFS The "target delay" is established for the approximate value of the infinitely small scheduling period in the perfect multitasking, and the smaller the scheduling cycle will bring better interactivity and closer to the perfect multi-tasking. CFS introduces the time slice bottom line that each process obtains-the minimum granularity. By default, this value is 1ms. Even if the number of running processes tends to be infinite, at least 1ms uptime can be achieved , ensuring that switching consumption is limited to a certain range.
Summary: The processor time obtained by any process is determined by the relative difference of the nice value of its own and all other operational processes . Nice values are geometrically weighted against time slices, and the absolute time corresponding to any nice value is no longer an absolute value, but rather a processor's use ratio.
implementation of 4.5 Linux scheduling
4.5.1 Time Accounting
The time slice is reduced by one tick cycle each time the system clock beats occur. When the time slice of a process is reduced to 0 , it will be preempted by another time slice that has not yet been reduced to 0 .
1. Scheduler Entity structure: Used to track process running bookkeeping
The scheduler entity structure, as a member variable named se , is embedded within the process descriptor struct task_struct .
2. Virtual real-time
Vruntime The virtual run time of the variable holding process, which is calculated by standardizing the total number of running processes. The virtual time is in ns , so it is no longer relevant to the timer Street beat. CFS uses the vruntime variable to record how long a program is running and how long it should run.
Update_curr () calculates the execution time of the current process and stores it in a variable delta_exec the. Then he passes the run time to __update_curr (), which then weights the run time based on the total number of currently running processes, and ultimately the value of the above with the current running process Vruntime added.
Update_curr () called periodically by the system counter.
4.5.2 Process Selection
CFS the core of the scheduling algorithm: Select a minimum Vruntime worthwhile process.
CFS use a red-black tree to organize a running process queue and use it to quickly find the smallest Vruntime worthwhile process.
1. pick the next task
CFS The process selection algorithm can be summed up as "running Rbtree The process represented by the leftmost leaf node in the tree. The function to implement this procedure is __pick_next_entity ().
2. Join the process to the tree
Occurs when the process becomes operational (wake-up) or the first time the process is created through a fork () call. the enqueue_entity () function achieves this purpose.
The function updates the run time and some other statistics, and then calls __enqueue_entity () for a heavy insert operation that actually inserts the data item into the red-black tree.
3. Remove a process from the tree
Delete actions occur when a process is blocked or terminated.
4.5.3 Scheduler Entry
The main entry point for process scheduling is the function schedule (), which is the portal that other parts of the kernel use to invoke the process Scheduler: Select which process can run and when it will be put into operation. The only important thing in this function is to call pick_next_task (), which takes precedence, from high to low, checks each schedule class at a time, and selects the highest-priority process from the highest-priority scheduling class. The core of the function is the For() loop, which implements the traversal.
4.5.4 sleep and wake up
Hibernate: The process marks itself as dormant, moves out of the executable red-black tree, puts in the wait queue, and then calls schedule() to select and execute a different process.
Wake up: The process is placed in an executable state and then moved from the wait queue to the executable red-black tree.
There are two related process states for hibernation:task_interruptible and task_uninterruptible. Their only difference is that the task_uninterruptible process ignores the signal, while the process of task_interruptible state receives a signal, will be awakened in advance and the signal should be ringing. The signals in both states are on the same waiting queue, waiting for certain events to run.
1. Waiting Queue
The process adds itself to a wait queue by following several steps:
2. Wake up
Through the function wake_up () , it wakes up all the processes on the specified wait queue. It calls the function try_to_wake_up (), which is responsible for setting the process to the task_running State, calling Enqueue_task () put this process into a red-black tree, and set the need_resched flag if the awakened process has a higher priority than the process that is currently executing .
4.6 preemption and context switching
This is handled by the context_switch () function defined in kernel/sched.c . The function is called by schedule () when a new process is selected to be ready to run. It completed the following two basic tasks:
Invoke switch_mm ()declared in <asm/mmu_contesxt.h> , which is responsible for switching virtual memory from the previous process map to the new process.
Invoke switch_to ()declared in <asm/system.h> , which is responsible for switching from the processor state of the previous process to the processor state of the new process.
4.6.1 user preemption
Occurs in:
When the user space is returned from the system call.
When the user space is returned from the interrupt handler.
4.6.2 kernel preemption
As long as the lock is not held, the kernel can take a preemption.
Occurs in:
The interrupt handler is executing and before the kernel space is returned.
The kernel code once again has the time to be preemptive.
If the task in kernel space explicitly calls schedule().
If the task in the kernel is blocked. ( Schedule() is also called).
4.7 Real-time scheduling strategy
Linux two real-time scheduling strategies are available: Sched_fifo and the SCHED_RR .
Sched_fifo : First-in, first-out algorithms.
SCHED_RR : First-in, first-out algorithm with time slices.
4.8 scheduling-related system calls
"Linux Kernel Analysis" chapter fourth reading notes