Rt
/** * Decrements the current process's time slice counter and checks if the time slice has been exhausted. * Because of the different scheduling types of the process, the operations performed by the functions vary greatly. */* If it is a real-time process, it further depends on the real-time process */if (Rt_task (p)) {/** * for the SCHED_RR type (time slice rotation) of the FIFO or RR type, which needs to decrement its temporal slice. * For Sched_fifo type (FIFO) real-time process, do nothing, * exit. In this case, the * current process cannot be preempted by a process that has a lower priority or equal priority, so it makes no sense to maintain the latest time slice counter for this process. */if ((P->policy = = sched_rr) &&!--p->time_slice) {/** * real-time process for SCHED_RR type, if its time slice is exhausted, * perform this action, To achieve the goal of seizing the current process. * If necessary, seize as soon as possible. */* Recalculates its time slice, which calculates its time slice based on the static priority of the process. */p->time_slice = Task_timeslice (p);/** * This flag is set by the copy_process in the fork routines, * until here, it is not the first time that the process has run, * it has used one of its times slices, The _time_slice is set to 0. * This way, it does not return the remaining time slices to the parent process even if it exits. */p->first_time_slice = 0;/** * Set the dispatch flag to achieve the purpose of preemption as soon as possible. * This flag forces the call to the schedule function so that the process that current points to can be replaced by another real-time process, if any, that has the same priority (or higher priority). */set_tsk_need_resched (P);/* put it at the end of the queue: *//** * Put the real-time process at the end of the queue. This way, there are other RR processes in the list that have the same priority *, and other processes can be run. */requeue_task (P, rq->active);} Goto Out_unlock;}
1. Here are some of the main sub-functions, first of all task_timeslice, to recalculate the time slices. First introduce the concept of basic time slice.
The static priority essentially determines the basic time slice of the process, which is the time slice length that the system allocates to the process before the process has run out of time. The relationship between the static priority and the base time slice is determined by the following formula:
As you can see, the higher the static priority (the smaller the value), the longer the base time slice. As a result, higher-priority processes typically get longer CPU time slices than low-priority processes.
#define Nice_to_prio (Nice) (Max_rt_prio + (Nice) +) #define Scale_prio (x, PRIO) MAX (x * (Max_prio-prio)/(Max_user_pri O/2), min_timeslice) static unsigned int task_timeslice (task_t *p) {if (P->static_prio < Nice_to_prio (0)) return Scale_prio (def_timeslice*4, P->static_prio); Elsereturn Scale_prio (Def_timeslice, P->static_prio);}
The 2.requeue_task function moves the process descriptor to the end of the Run Queue activity list corresponding to the current process priority. Placing the current-pointing process at the end of the list guarantees that it will not be selected again for execution until the CPU time slice is obtained for each of the running real-time processes with the same priority as it does.
This is a scheduling strategy based on time-slice rotation. The move of the process descriptor is done in two steps: Call List_del to remove the process from the active list of the running queue, and then call List_add_tail to reinsert the process into the tail of the same active list.
Linux2.6 Kernel process scheduling series--scheduler_tick () function 2. Update the time slice of the real-time process