diff -urN linux-2.4.19-pre9-O1/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S --- linux-2.4.19-pre9-O1/arch/i386/kernel/entry.S Mon Jun 3 17:28:52 2002 +++ linux/arch/i386/kernel/entry.S Mon Jun 3 17:21:12 2002 @@ -641,6 +641,7 @@ .long SYMBOL_NAME(sys_ni_syscall) /* 240 reserved for futex */ .long SYMBOL_NAME(sys_ni_syscall) /* reserved for sched_setaffinity */ .long SYMBOL_NAME(sys_ni_syscall) /* reserved for sched_getaffinity */ + .long SYMBOL_NAME(sys_sched_hint) .rept NR_syscalls-(.-sys_call_table)/4 .long SYMBOL_NAME(sys_ni_syscall) diff -urN linux-2.4.19-pre9-O1/include/asm-i386/unistd.h linux/include/asm-i386/unistd.h --- linux-2.4.19-pre9-O1/include/asm-i386/unistd.h Mon Jun 3 17:27:16 2002 +++ linux/include/asm-i386/unistd.h Mon Jun 3 17:19:31 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.4.19-pre9-O1/include/linux/sched.h linux/include/linux/sched.h --- linux-2.4.19-pre9-O1/include/linux/sched.h Mon Jun 3 17:28:53 2002 +++ linux/include/linux/sched.h Mon Jun 3 17:19:31 2002 @@ -115,6 +115,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.4.19-pre9-O1/kernel/sched.c linux/kernel/sched.c --- linux-2.4.19-pre9-O1/kernel/sched.c Mon Jun 3 17:28:53 2002 +++ linux/kernel/sched.c Mon Jun 3 17:19:38 2002 @@ -1179,6 +1179,64 @@ return retval; } +/* + * 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;