/* * kernel/edzl_common.c * * Common functions for EDZL based scheduler. */ #include #include #include #include #include #include #include #include int edzl_higher_prio(struct task_struct* first, struct task_struct* second) { struct task_struct *first_task = first; struct task_struct *second_task = second; /* There is no point in comparing a task to itself. */ if (first && first == second) { TRACE_TASK(first, "WARNING: pointless edf priority comparison.\n"); return 0; } /* 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; /* null checks & rt checks */ if(!first_task) return 0; else if(!second_task || !is_realtime(second_task)) return 1; if(likely(get_zerolaxity(first_task) == get_zerolaxity(second_task))) { /* edf order if both tasks have the same laxity state */ return(edf_higher_prio(first_task, second_task)); } else { return(get_zerolaxity(first_task)); } } int edzl_ready_order(struct bheap_node* a, struct bheap_node* b) { return edzl_higher_prio(bheap2task(a), bheap2task(b)); } void edzl_domain_init(rt_domain_t* rt, check_resched_needed_t resched, release_jobs_t release) { rt_domain_init(rt, edzl_ready_order, resched, release); } /* need_to_preempt - check whether the task t needs to be preempted * call only with irqs disabled and with ready_lock acquired * THIS DOES NOT TAKE NON-PREEMPTIVE SECTIONS INTO ACCOUNT! */ int edzl_preemption_needed(rt_domain_t* rt, struct task_struct *t) { /* we need the read lock for edzl_ready_queue */ /* no need to preempt if there is nothing pending */ if (!__jobs_pending(rt)) return 0; /* we need to reschedule if t doesn't exist */ if (!t) return 1; /* make sure to get non-rt stuff out of the way */ if (!is_realtime(t)) return 1; /* NOTE: We cannot check for non-preemptibility since we * don't know what address space we're currently in. */ /* Detect zero-laxity as needed. Easier to do it here than in tick. (No timer is used to detect zero-laxity while a job is running.) */ if(unlikely(!get_zerolaxity(t) && laxity_remaining(t) == 0)) { set_zerolaxity(t, 1); } return edzl_higher_prio(__next_ready(rt), t); } #ifdef CONFIG_PLUGIN_AEDZL int aedzl_preemption_needed(rt_domain_t* rt, struct task_struct *t) { /* we need the read lock for edzl_ready_queue */ /* no need to preempt if there is nothing pending */ if (!__jobs_pending(rt)) return 0; /* we need to reschedule if t doesn't exist */ if (!t) return 1; /* make sure to get non-rt stuff out of the way */ if (!is_realtime(t)) return 1; /* Detect zero-laxity as needed. Easier to do it here than in tick. (No timer is used to detect zero-laxity while a job is running.) */ if(unlikely(!get_zerolaxity(t) && laxity_remaining_est(t) == 0)) { set_zerolaxity(t, 1); } return edzl_higher_prio(__next_ready(rt), t); } #endif