/* * kernel/fifo_common.c * * Fifo helper functions. Could one day be a FIFO plugin if someone * is interested. * * The current FIFO implementaion automatically chops Linux tasks into * smaller jobs by assigning a fixed time slice. Once that time slice expires, * it is treated as a new job release (that is queued in the back). * * The result is that it provides FIFO properties on a job level and round-robin * on a task level if the tasks execute continuously. */ #include #include #include #include #include #include #include #include /* This function is defined in sched.c. We need access it for * indirect switching. */ void __activate_task(struct task_struct *p, runqueue_t *rq); /* fifo_higher_prio - returns true if first has a higher FIFO priority * than second. Release time ties are broken by PID. * * first first must not be NULL and a real-time task. * second may be NULL or a non-rt task. */ int fifo_higher_prio(struct task_struct* first, struct task_struct* second) { struct task_struct *first_task = first; struct task_struct *second_task = second; /* Check for inherited priorities. Change task * used for comparison in such a case. */ if (first && first->rt_param.inh_task) first_task = first->rt_param.inh_task; if (second && second->rt_param.inh_task) second_task = second->rt_param.inh_task; return /* does the second task exist and is it a real-time task? If * not, the first task (which is a RT task) has higher * priority. */ !second_task || !is_realtime(second_task) || /* is the release of the first task earlier? * Then it has higher priority. */ earlier_last_release(first_task, second_task) || /* Do we have a release time tie? * Then break by PID. */ (get_last_release(first_task) == get_last_release(second_task) && (first_task->pid < second_task->pid || /* If the PIDs are the same then the task with the inherited * priority wins. */ (first_task->pid == second_task->pid && !second->rt_param.inh_task))); } int fifo_ready_order(struct list_head* a, struct list_head* b) { return fifo_higher_prio( list_entry(a, struct task_struct, rt_list), list_entry(b, struct task_struct, rt_list)); } void fifo_domain_init(rt_domain_t* rt, check_resched_needed_t resched) { rt_domain_init(rt, resched, fifo_ready_order); }