--- linux-2.6.0-test1-mm2/kernel/sched.c 2003-07-24 10:31:41.000000000 +1000 +++ linux-2.6.0-test1ck2/kernel/sched.c 2003-07-27 12:17:23.000000000 +1000 @@ -68,7 +68,8 @@ */ #define MIN_TIMESLICE ( 10 * HZ / 1000) #define MAX_TIMESLICE (200 * HZ / 1000) -#define CHILD_PENALTY 60 +#define TIMESLICE_GRANULARITY (HZ / 20 ?: 1) +#define CHILD_PENALTY 90 #define PARENT_PENALTY 100 #define EXIT_WEIGHT 3 #define PRIO_BONUS_RATIO 25 @@ -348,28 +349,37 @@ static inline void __activate_task(task_ */ static inline void activate_task(task_t *p, runqueue_t *rq) { - long sleep_time = jiffies - p->last_run - 1; - - if (sleep_time > 0) { - /* - * User tasks that sleep a long time are categorised as idle and - * will get just under interactive status to prevent them suddenly - * becoming cpu hogs and starving other processes. - */ - if (p->mm && sleep_time > HZ) - p->sleep_avg = MAX_SLEEP_AVG * (MAX_BONUS - INTERACTIVE_DELTA - 2) / MAX_BONUS; - else { + if (likely(p->last_run)){ + long sleep_time = jiffies - p->last_run - 1; + if (sleep_time > 0) { /* - * Processes that sleep get pushed to one higher priority - * each time they sleep greater than one tick. -ck + * User tasks that sleep a long time are categorised as + * idle and will get just under interactive status to + * prevent them suddenly becoming cpu hogs and starving + * other processes. */ - p->sleep_avg = (p->sleep_avg * MAX_BONUS / MAX_SLEEP_AVG + 1) * MAX_SLEEP_AVG / MAX_BONUS; + if (p->mm && sleep_time > HZ) + p->sleep_avg = MAX_SLEEP_AVG * + (MAX_BONUS - 1) / MAX_BONUS - 1; + else { + + /* + * Processes that sleep get pushed to one higher + * priority each time they sleep greater than + * one tick. -ck + */ + p->sleep_avg = (p->sleep_avg * MAX_BONUS / + MAX_SLEEP_AVG + 1) * + MAX_SLEEP_AVG / MAX_BONUS; - if (p->sleep_avg > MAX_SLEEP_AVG) - p->sleep_avg = MAX_SLEEP_AVG; + if (p->sleep_avg > MAX_SLEEP_AVG) + p->sleep_avg = MAX_SLEEP_AVG; + } } - } + } else + p->last_run = jiffies; + p->prio = effective_prio(p); __activate_task(p, rq); } @@ -549,6 +559,7 @@ void wake_up_forked_process(task_t * p) current->sleep_avg = current->sleep_avg * PARENT_PENALTY / 100; p->sleep_avg = p->sleep_avg * CHILD_PENALTY / 100; p->prio = effective_prio(p); + p->last_run = 0; set_task_cpu(p, smp_processor_id()); if (unlikely(!current->array)) @@ -1242,16 +1253,15 @@ void scheduler_tick(int user_ticks, int enqueue_task(p, rq->expired); } else enqueue_task(p, rq->active); - } else if (p->mm && !((task_timeslice(p) - p->time_slice) % - (MIN_TIMESLICE * (MAX_BONUS + 1 - p->sleep_avg * MAX_BONUS / MAX_SLEEP_AVG)))){ + } else if (!((task_timeslice(p) - p->time_slice) % + TIMESLICE_GRANULARITY) && (p->time_slice > MIN_TIMESLICE)) { /* - * Running user tasks get requeued with their remaining timeslice - * after a period proportional to how cpu intensive they are to - * minimise the duration one interactive task can starve another + * Running user tasks get requeued with their remaining + * timeslice after TIMESLICE_GRANULARITY provided they have at + * least MIN_TIMESLICE to go. */ dequeue_task(p, rq->active); set_tsk_need_resched(p); - p->prio = effective_prio(p); enqueue_task(p, rq->active); } out_unlock: