--- linux-2.5.74/kernel/sched.c 2003-07-04 14:30:11.000000000 +1000 +++ linux-2.5.74-test/kernel/sched.c 2003-07-04 14:41:22.000000000 +1000 @@ -68,7 +68,7 @@ */ #define MIN_TIMESLICE ( 10 * HZ / 1000) #define MAX_TIMESLICE (200 * HZ / 1000) -#define CHILD_PENALTY 50 +#define CHILD_PENALTY 80 #define PARENT_PENALTY 100 #define EXIT_WEIGHT 3 #define PRIO_BONUS_RATIO 25 @@ -405,30 +405,30 @@ static inline void activate_task(task_t * from continually getting larger. */ if (runtime < MAX_SLEEP_AVG) - p->sleep_avg += (runtime - p->sleep_avg) * (MAX_SLEEP_AVG - runtime) / MAX_SLEEP_AVG; + p->sleep_avg += (runtime - p->sleep_avg) * (MAX_SLEEP_AVG - runtime) * + (10 - INTERACTIVE_DELTA) / 10 / MAX_SLEEP_AVG; /* - * Keep a buffer of 10-20% bonus sleep_avg with hysteresis + * Keep a buffer of 10% sleep_avg * to prevent short bursts of cpu activity from making * interactive tasks lose their bonus */ - if (p->sleep_avg > MAX_SLEEP_AVG * 12/10) + if (p->sleep_avg > MAX_SLEEP_AVG * 11/10) p->sleep_avg = MAX_SLEEP_AVG * 11/10; /* * Tasks that sleep a long time are categorised as idle and * get their static priority only */ - if (sleep_time > MIN_SLEEP_AVG){ - p->avg_start = jiffies - MIN_SLEEP_AVG; - p->sleep_avg = MIN_SLEEP_AVG / 2; - } + if (sleep_time > MIN_SLEEP_AVG) + p->sleep_avg = runtime / 2; + if (unlikely(p->avg_start > jiffies)){ p->avg_start = jiffies; p->sleep_avg = 0; } - p->prio = effective_prio(p); } + p->prio = effective_prio(p); __activate_task(p, rq); } @@ -605,7 +605,6 @@ void wake_up_forked_process(task_t * p) * from forking tasks that are max-interactive. */ current->sleep_avg = current->sleep_avg * PARENT_PENALTY / 100; - p->avg_start = current->avg_start; normalise_sleep(p); p->sleep_avg = p->sleep_avg * CHILD_PENALTY / 100; p->prio = effective_prio(p); @@ -647,6 +646,8 @@ void sched_exit(task_t * p) * If the child was a (relative-) CPU hog then decrease * the sleep_avg of the parent as well. */ + normalise_sleep(p); + normalise_sleep(p->parent); if (p->sleep_avg < p->parent->sleep_avg) p->parent->sleep_avg = (p->parent->sleep_avg * EXIT_WEIGHT + p->sleep_avg) / (EXIT_WEIGHT + 1);