diff -urN linux-2.5.20/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S --- linux-2.5.20/arch/i386/kernel/entry.S Sun Jun 2 18:44:44 2002 +++ linux/arch/i386/kernel/entry.S Mon Jun 3 13:48:43 2002 @@ -785,6 +785,7 @@ .long sys_futex /* 240 */ .long sys_sched_setaffinity .long sys_sched_getaffinity + .long sys_sched_hint .rept NR_syscalls-(.-sys_call_table)/4 .long sys_ni_syscall diff -urN linux-2.5.20/include/asm-i386/unistd.h linux/include/asm-i386/unistd.h --- linux-2.5.20/include/asm-i386/unistd.h Sun Jun 2 18:44:51 2002 +++ linux/include/asm-i386/unistd.h Mon Jun 3 13:48:59 2002 @@ -247,6 +247,7 @@ #define __NR_futex 240 #define __NR_sched_setaffinity 241 #define __NR_sched_getaffinity 242 +#define __NR_sched_hint 243 /* user-visible error numbers are in the range -1 - -124: see */ diff -urN linux-2.5.20/include/linux/sched.h linux/include/linux/sched.h --- linux-2.5.20/include/linux/sched.h Sun Jun 2 18:44:41 2002 +++ linux/include/linux/sched.h Mon Jun 3 17:10:10 2002 @@ -116,6 +116,13 @@ #endif /* + * Scheduling Hints + */ +#define HINT_TIME 1 /* increase remaining timeslice */ +#define HINT_INTERACTIVE 2 /* interactive task: prio bonus */ +#define HINT_BATCH 4 /* batch task: prio penalty */ + +/* * Scheduling policies */ #define SCHED_OTHER 0 diff -urN linux-2.5.20/kernel/sched.c linux/kernel/sched.c --- linux-2.5.20/kernel/sched.c Sun Jun 2 18:44:44 2002 +++ linux/kernel/sched.c Mon Jun 3 17:09:09 2002 @@ -1143,7 +1143,7 @@ policy != SCHED_OTHER) goto out_unlock; } - + /* * Valid priorities for SCHED_FIFO and SCHED_RR are * 1..MAX_USER_RT_PRIO, valid priority for SCHED_OTHER is 0. @@ -1336,6 +1336,64 @@ return real_len; } +/* + * sys_sched_hint - give the scheduler a hint to (hopefully) provide + * better scheduling behavior. For example, if a task is about + * to acquire a highly contended resource, it would be wise to + * increase its remaining timeslice to ensure it could drop the + * resource before being preempted. + * + * `hint' is the hint to the scheduler, defined in include/linux/sched.h + */ +asmlinkage int sys_sched_hint(unsigned long hint) +{ + int ret = -EINVAL; + unsigned long flags; + runqueue_t *rq; + + /* + * Requiring CAP_SYS_NICE is an issue: we really want any task + * to be able to give the scheduler a `hint' but we have no + * way of ensuring fairness. The compromise is to require + * some sort of permission... you may want to get rid of this. + */ + if (!capable(CAP_SYS_NICE)) + return -EPERM; + + rq = task_rq_lock(current, &flags); + + if (hint & HINT_TIME) { + current->time_slice = MAX_TIMESLICE; + /* + * we may have run out of timeslice and have been + * put on the expired runqueue: if so, fix that. + */ + if (unlikely(current->array != rq->active)) { + dequeue_task(current, current->array); + enqueue_task(current, rq->active); + } + ret = 0; + } + + if (hint & HINT_INTERACTIVE) { + dequeue_task(current, current->array); + current->sleep_avg = MAX_SLEEP_AVG; + current->prio = effective_prio(current); + enqueue_task(current, rq->active); + ret = 0; + } else if (hint & HINT_BATCH) { + dequeue_task(current, current->array); + current->sleep_avg = 0; + current->prio = effective_prio(current); + enqueue_task(current, rq->active); + ret = 0; + } + + task_rq_unlock(rq, &flags); + + return ret; +} + asmlinkage long sys_sched_yield(void) { runqueue_t *rq; @@ -1376,6 +1434,7 @@ return 0; } + asmlinkage long sys_sched_get_priority_max(int policy) { int ret = -EINVAL;