diff -urNbBd linux-2.2.16.orig/drivers/sched/rnd_sched.c linux-2.2.16.new/drivers/sched/rnd_sched.c --- linux-2.2.16.orig/drivers/sched/rnd_sched.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.16.new/drivers/sched/rnd_sched.c Mon Nov 6 15:05:41 2000 @@ -0,0 +1,207 @@ +/* + * COPYRIGHT: Folkert van Heusden + * released under GNU GENERAL PUBLIC LICENSE + * AUTHOR : Folkert van Heusden (folkert@vanheusden.com) + * HISTORY: + * 2000- + */ + +/* update this every patch or release */ +#define CTRR_SCHED_VERSION "random scheduler 0.1" + +#include /* dynamic modules */ +#include /* init macro */ + +#include +#include +#include +#include +#include +#include /* file_operations */ + +#include +#include +#include + +#include + + +#if (LINUX_VERSION_CODE >= 0x020400) +struct file_operations ctrr_fops = { +}; +#else +struct file_operations ctrr_fops = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; +#endif +static struct sched_policy *ctrr_of_cpu[NR_CPUS]; +static struct sched_policy round_robin; + +/*------------------------------* + * scheduler-visible routines * + *------------------------------*/ + +static struct task_struct * +ctrr_choose_task(struct task_struct *curr_task, int this_cpu) +{ + register struct task_struct *p, *remember = NULL; + char rnd_val; + int dummy; + +#if (LINUX_VERSION_CODE >= 0x020400) + struct list_head *tmp; + + /* short cut. just keep running current job if we can */ + if ((curr_task->state == TASK_RUNNING)&& + !(curr_task->policy & SCHED_YIELD)&& + (curr_task->counter > 0)){ + return curr_task; + } + + list_for_each(tmp, &runqueue_head) { + p = list_entry(tmp, struct task_struct, run_list); +#ifdef CONFIG_SMP + if (p->has_cpu) + continue; +#endif + + /* get random value */ + get_random_bytes(&rnd_val, 1); + + dummy = (int)rnd_val - ((p->trashing_mem + p->oom_kill_try) << 4); + + /* something random reached? (minus trashing + oom) */ + if (dummy >= 207) + { + remember = p; + goto got_one; + } + else if (dummy > 192) + { + remember = p; + } + } + +got_one: + if (remember) + { + /* remove from front of queue and stick back on the back */ + list_del(&remember->run_list); + list_add_tail(&remember->run_list, &runqueue_head); + + remember->counter = NICE_TO_TICKS(remember->nice); + return remember; + } + +#else /* pre 2.4 */ + register struct task_struct *next; + register struct task_struct *prev; + + if (curr_task->state == TASK_RUNNING){ + if (curr_task->policy & SCHED_YIELD){ + curr_task->policy &= ~SCHED_YIELD; + } else if (curr_task->counter > 0){ + /* short cut. just keep running current job if we can */ + return curr_task; + } + } + + p = init_task.next_run; + +#ifdef __SMP__ + /* skip over the ones already running */ + while (p->has_cpu && p != &init_task) + p = p->next_run; +#endif + + while(p) + { + if (p != &init_task) + { + /* get random value */ + get_random_bytes(&rnd_val, 1); + + dummy = (int)rnd_val - ((p->trashing_mem + p->oom_kill_try) << 4); + + /* something random reached? (minus trashing + oom) */ + if (dummy >= 207) + { + remember = p; + goto got_one; + } + else if (dummy > 192) + { + remember = p; + } + } + + p = p->next_run; + } + +got_one: + if (remember) + { + /* remove from front of queue and stick back on the back */ + next = remember->next_run; + prev = remember->prev_run; + next->prev_run = prev; + prev->next_run = next; + remember->next_run = &init_task; + prev = init_task.prev_run; + init_task.prev_run = remember; + remember->prev_run = prev; + prev->next_run = remember; + + remember->counter = remember->priority; + return remember; + } + +#endif /* end LINUX version */ + return idle_task(this_cpu); +} + +static int +ctrr_preemptability (struct task_struct *curr_task, struct task_struct * thief, int this_cpu) +{ + return (thief->counter - curr_task->counter); +} + +/*-------------------------------* + * load/unload module routines * + *-------------------------------*/ + +#ifdef MODULE +int __init +init_module(void) +{ + int i; + struct task_struct *p; + struct sched_policy *new = &round_robin; + + memset (new, 0, sizeof(struct sched_policy)); + new->sp_choose_task = ctrr_choose_task; + new->sp_preemptability = ctrr_preemptability; + + /* build per-cpu policy */ + for (i = 0; i < NR_CPUS; i++) + ctrr_of_cpu[i] = new; + + if (register_sched (CTRR_SCHED_VERSION, ctrr_of_cpu, &ctrr_fops)){ + printk("rnd_sched: unable to register\n"); + return -EIO; + } + + /* initialize all processes */ + read_lock(&tasklist_lock); + for_each_task(p){ + p->alt_policy = new; + } + read_unlock(&tasklist_lock); + return 0; +} + +void +cleanup_module(void) +{ + unregister_sched(CTRR_SCHED_VERSION); +} +#endif diff -urNbBd linux-2.2.16.orig/drivers/char/Config.in linux-2.2.16.new/drivers/char/Config.in --- linux-2.2.16.orig/drivers/char/Config.in Mon Nov 6 14:22:21 2000 +++ linux-2.2.16.new/drivers/char/Config.in Mon Nov 6 14:22:14 2000 @@ -223,6 +223,7 @@ if [ "$CONFIG_ALTSCHED" != "n" ]; then bool 'processor set module' CONFIG_SCHED_PSET bool 'constant time scheduler' CONFIG_SCHED_CONST + bool 'random scheduler' CONFIG_SCHED_RND fi endmenu diff -urNbBd linux-2.2.16.orig/drivers/sched/Makefile linux-2.2.16.new/drivers/sched/Makefile --- linux-2.2.16.orig/drivers/sched/Makefile Mon Nov 6 14:24:06 2000 +++ linux-2.2.16.new/drivers/sched/Makefile Mon Nov 6 14:00:23 2000 @@ -28,6 +28,10 @@ M_OBJS += const_sched.o #endif +#ifdef CONFIG_SCHED_RND +M_OBJS += rnd_sched.o +#endif + include $(TOPDIR)/Rules.make fastdep: