--- linux-2.6.0-test7-base/include/linux/sched.h 2003-10-12 22:34:09.000000000 +1000 +++ linux-2.6.0-test7/include/linux/sched.h 2003-10-12 20:46:55.000000000 +1000 @@ -126,6 +126,7 @@ extern unsigned long nr_iowait(void); #define SCHED_NORMAL 0 #define SCHED_FIFO 1 #define SCHED_RR 2 +#define SCHED_BATCH 3 struct sched_param { int sched_priority; @@ -294,6 +295,7 @@ struct signal_struct { #define MAX_PRIO (MAX_RT_PRIO + 40) #define rt_task(p) ((p)->prio < MAX_RT_PRIO) +#define batch_task(p) ((p)->policy == SCHED_BATCH) /* * Some day this will be a full-fledged user tracking system.. --- linux-2.6.0-test7-base/kernel/sched.c 2003-10-12 22:34:09.000000000 +1000 +++ linux-2.6.0-test7/kernel/sched.c 2003-10-12 23:07:45.000000000 +1000 @@ -153,8 +153,13 @@ #define LOW_CREDIT(p) \ ((p)->interactive_credit < -CREDIT_LIMIT) +/* + * Batch tasks are preempted by any priority normal tasks. + */ #define TASK_PREEMPTS_CURR(p, rq) \ - ((p)->prio < (rq)->curr->prio) + ((((p)->prio < (rq)->curr->prio) && (!batch_task(p) || \ + (batch_task(p) && batch_task((rq)->curr)))) || \ + (!batch_task(p) && batch_task((rq)->curr))) /* * BASE_TIMESLICE scales user-nice values [ -20 ... 19 ] @@ -172,6 +177,12 @@ static inline unsigned int task_timeslice(task_t *p) { + /* + * Batch tasks get much longer timeslices + */ + if (unlikely(batch_task(p))) + return BASE_TIMESLICE(p) * 10; + return BASE_TIMESLICE(p); } @@ -359,7 +370,10 @@ static int effective_prio(task_t *p) if (rt_task(p)) return p->prio; - bonus = CURRENT_BONUS(p) - MAX_BONUS / 2; + if (unlikely(batch_task(p))) + bonus = 0; + else + bonus = CURRENT_BONUS(p) - MAX_BONUS / 2; prio = p->static_prio - bonus; if (prio < MAX_RT_PRIO) @@ -374,7 +388,14 @@ static int effective_prio(task_t *p) */ static inline void __activate_task(task_t *p, runqueue_t *rq) { - enqueue_task(p, rq->active); + /* + * Batch tasks get activated onto the expired array. + */ + if (unlikely(batch_task(p))) + enqueue_task(p, rq->expired); + else + enqueue_task(p, rq->active); + nr_running_inc(rq); } @@ -1408,10 +1429,14 @@ void scheduler_tick(int user_ticks, int p->time_slice = task_timeslice(p); p->first_time_slice = 0; - if (!rq->expired_timestamp) + if (!rq->expired_timestamp && !batch_task(p)) rq->expired_timestamp = jiffies; - if (!TASK_INTERACTIVE(p) || EXPIRED_STARVING(rq)) { - enqueue_task(p, rq->expired); + /* + * Batch tasks are always expired. + */ + if (batch_task(p) || !TASK_INTERACTIVE(p) || + EXPIRED_STARVING(rq)) { + enqueue_task(p, rq->expired); } else enqueue_task(p, rq->active); } else { @@ -2015,8 +2040,8 @@ static int setscheduler(pid_t pid, int p else { retval = -EINVAL; if (policy != SCHED_FIFO && policy != SCHED_RR && - policy != SCHED_NORMAL) - goto out_unlock; + policy != SCHED_NORMAL && policy !=SCHED_BATCH) + goto out_unlock; } /* @@ -2026,8 +2051,9 @@ static int setscheduler(pid_t pid, int p retval = -EINVAL; if (lp.sched_priority < 0 || lp.sched_priority > MAX_USER_RT_PRIO-1) goto out_unlock; - if ((policy == SCHED_NORMAL) != (lp.sched_priority == 0)) - goto out_unlock; + if ((policy == SCHED_NORMAL || policy == SCHED_BATCH) != + (lp.sched_priority == 0)) + goto out_unlock; retval = -EPERM; if ((policy == SCHED_FIFO || policy == SCHED_RR) && @@ -2048,7 +2074,7 @@ static int setscheduler(pid_t pid, int p p->policy = policy; p->rt_priority = lp.sched_priority; oldprio = p->prio; - if (policy != SCHED_NORMAL) + if (policy != SCHED_NORMAL && policy != SCHED_BATCH) p->prio = MAX_USER_RT_PRIO-1 - p->rt_priority; else p->prio = p->static_prio; @@ -2353,6 +2379,7 @@ asmlinkage long sys_sched_get_priority_m ret = MAX_USER_RT_PRIO-1; break; case SCHED_NORMAL: + case SCHED_BATCH: ret = 0; break; } @@ -2376,6 +2403,7 @@ asmlinkage long sys_sched_get_priority_m ret = 1; break; case SCHED_NORMAL: + case SCHED_BATCH: ret = 0; } return ret;