Scheduling Unit
Process description, located at the bottom of the running stack, which can be located through offsetThread_info {task_struct * task; // basic scheduling unit (expanded below) flags // tif_need_resched indicates that the CPU/CPU number needs to be scheduled... }
Basic Unit of Task SchedulingTask_struct {state // status, task_running, zombie, or other * thread_info PRIO Dynamic Priority static_prio static priority sleep_avg average sleep time policy scheduling algorithm, normal, RR, real-time priority of the time slice remaining in the FIFO time_slice rt_priority ......}
Running Queue (
Scheduling control structure)Runqueue {task_struct * curr is running the task prio_array * active priority queue prio_array * expired priority queue prio_array arrays [2] actual priority queue ...} priority queue (O (1) scheduling algorithm structure) prio_array {number of tasks in the nr_active queue bitmap [bitmap_size] // priority bitmap, 1 indicates that the corresponding priority has a process to schedule, 0 indicates no. You can quickly find the task with the highest priority through bit search. List_head queue [max_prio] priority queue}
PriorityLinux divides processes into real-time scheduling and general scheduling. The real-time scheduling priority is 0 ~ 99. Only FCFS or RR is used for scheduling. Non-real-time general process priority is 100 ~ 139, that is, the formula is 100 (the highest real-time priority) + 20 + nice. Nice value:-20 ~ 19. It is specified when the process is created. The dynamic priority is calculated dynamically based on the interaction of processes. Generally, the priority is calculated based on nice ~ + 5 interactive rewards and punishments. Evaluate the interaction of a process by calculating sleep_avg. If sleep_avg is large, that is, the process is Io-consuming, and its priority can be reduced (not occupying too much CPU), and vice versa.
Time sliceThe available time slice of a process is allocated proportionally according to the calculated priority. The value ranges from 5 ~ 800 ms; default value: 100 ms.
Schedulable flagThe kernel provides a need_resched flag to indicate whether a new scheduling is required. When a process consumes its time slice, scheduler_tick () sets this flag. When a high-priority process enters the executable state, try_to_wake_up () also sets this flag. The kernel also checks the need_resched flag when returning the user space and the returned from the interrupt. If it has been set, the kernel will call
Scheduler
Scheduling AlgorithmThe core function is implemented by the schedule () function and scheduler_tick () function. The schedule function selects the process with the highest priority from the priority array prio_array --> gets the thread_info of the process --> implements context switch to a new process to run. Scheduler_tick () is mainly used to update the time slice. The clock interrupt program automatically calls scheduler_tick. Scheduler_tick determines that if the current process is a real-time process, and the time slice is exhausted, re-calculate the time slice, and re-insert the tail of the active queue. If it is a common process and the time slice is exhausted, re-calculate the time slice and move it into the expired queue. When there are no other scheduling processes in the active priority queue, the active priority queue switches with the pointer of the expired priority queue to enter a new round of scheduling. In version 2.6, the kernel recalculates the time slice every time slice is used up, greatly improving the scheduling efficiency.
When to schedule? (When is called?
Schedule ()
)1. direct active call 2. active processes enter sleep 3. set need_resched. this bit is detected when the user State is returned from the kernel state. If it is 1, Schedule () is scheduled (). need_schedulea. in the clock interruption service program, use your own time slice B. when a sleep process is awakened, the process has a higher priority C. A process changes the scheduling policy and priority.
When to seize?User preemption 1. When the system call is returned to the user State 2. When the program is interrupted, the user State is returned. The kernel can be preemptible to the kernel of version 2.6. 1. If the kernel does not have a lock when it is returned from the interrupt, it can be preemptible. If a lock exists, it cannot be preemptible. This is determined by the kernel through the preempt_count variable. 2. kernel blocking, resulting in calling schedule () refer to Linux kernel 2.6 process scheduling analysis http://blog.163.com/steven_zyz/blog/static/1178243820071144412485/ <Linux kernel development 2nd> Robert love
V