From 9caacb13297747118cf178870345cdfcb597aa44 Mon Sep 17 00:00:00 2001 From: Glenn Elliott Date: Sat, 9 Apr 2011 09:58:34 -0400 Subject: CONFIG_DONT_PREEMPT_ON_TIE: Don't preeempt a scheduled task on priority tie. Added the compilation option CONFIG_DONT_PREEMPT_ON_TIE. In the event of a priority tie, a task that is currently scheduled is favored over one that is not. If both tasks are scheduled (or both are not), then tie breaks on PID and inheritance still hold. Configuration option includes a warning that schedulability analysis that depends upon task-id/PID tie-breaks breaks when CONFIG_DONT_PREEMPT_ON_TIE is enabled. Pfair/PD^2 not supported. --- litmus/Kconfig | 13 +++++++++++++ litmus/edf_common.c | 32 +++++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/litmus/Kconfig b/litmus/Kconfig index 651b66a77c65..e7376a165be3 100644 --- a/litmus/Kconfig +++ b/litmus/Kconfig @@ -52,6 +52,19 @@ config CPU_SCHED_BIAS Only bias towards previously used CPU is currently implemented. In the future: bias on CPU topology. +config DONT_PREEMPT_ON_TIE + bool "Don't preempt a task on priority tie." + default n + help + Don't preempt a scheduled task to schedule another if the two tasks + have equal priority. Preformance is improved through the reduction + of preemptions. Only tasks with periods that share a common factor + will likely see any gains. + + WARNING: Schedulability analysis that depends upon specific + tie-breaking rules, such as tie-break on task-id/PID (the default + LITMUS behavior), may break. + endmenu menu "Real-Time Synchronization" diff --git a/litmus/edf_common.c b/litmus/edf_common.c index 9b44dc2d8d1e..6ed927fcce6d 100644 --- a/litmus/edf_common.c +++ b/litmus/edf_common.c @@ -14,6 +14,17 @@ #include +#ifdef DONT_PREEMPT_ON_TIE +static inline cur_sched_higher_prio( + struct task_struct* first, + struct task_struct* second) +{ + int first_is_sched = (tsk_rt(first)->scheduled_on != NO_CPU); + int second_is_sched = (tsk_rt(second)->scheduled_on != NO_CPU); + return(first_is_sched > second_is_sched); +} +#endif + /* edf_higher_prio - returns true if first has a higher EDF priority * than second. Deadline ties are broken by PID. * @@ -71,17 +82,20 @@ int edf_higher_prio(struct task_struct* first, */ earlier_deadline(first_task, second_task) || - /* Do we have a deadline tie? - * Then break by PID. - */ + /* tie-break order: cur scheduled, pid, inheritance */ (get_deadline(first_task) == get_deadline(second_task) && +#ifdef DONT_PREEMPT_ON_TIE + (cur_sched_higher_prio(first, second) || +#endif (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))); + (first_task->pid == second_task->pid && + !second->rt_param.inh_task + ) + ) +#ifdef DONT_PREEMPT_ON_TIE + ) +#endif + ); } int edf_ready_order(struct bheap_node* a, struct bheap_node* b) -- cgit v1.2.2