--- 2.2.18pre21aa1/include/linux/sched.h.~1~ Tue Nov 14 16:16:02 2000 +++ 2.2.18pre21aa1/include/linux/sched.h Tue Nov 14 16:59:50 2000 @@ -244,6 +244,7 @@ long counter; long priority; cycles_t avg_slice; + int counter_refresh; /* SMP and runqueue state */ int has_cpu; int processor; @@ -372,7 +373,7 @@ */ #define INIT_TASK \ /* state etc */ { 0,0,0,KERNEL_DS,&default_exec_domain,0, \ -/* counter */ DEF_PRIORITY,DEF_PRIORITY,0, \ +/* counter */ DEF_PRIORITY,DEF_PRIORITY,0,0, \ /* SMP */ 0,0,0,-1, \ /* schedlink */ &init_task,&init_task, &init_task, &init_task, \ /* binfmt */ NULL, \ --- 2.2.18pre21aa1/kernel/exit.c.~1~ Sun Apr 2 21:07:50 2000 +++ 2.2.18pre21aa1/kernel/exit.c Tue Nov 14 17:04:15 2000 @@ -56,6 +56,17 @@ current->cmin_flt += p->min_flt + p->cmin_flt; current->cmaj_flt += p->maj_flt + p->cmaj_flt; current->cnswap += p->nswap + p->cnswap; + /* + * Potentially available timeslices are retrieved + * here - this way the parent does not get penalized + * for creating too many processes. + * + * (this cannot be used to artificially 'generate' + * timeslices, because any timeslice recovered here + * was given away by the parent in the first place.) + */ + if (!p->counter_refresh) + current->counter += p->counter; free_task_struct(p); } else { printk("task releasing itself\n"); @@ -150,6 +161,7 @@ p->exit_signal = SIGCHLD; p->self_exec_id++; p->p_opptr = child_reaper; /* init */ + p->counter_refresh = 1; if (p->pdeath_signal) send_sig(p->pdeath_signal, p, 0); } } --- 2.2.18pre21aa1/kernel/fork.c.~1~ Tue Nov 14 16:06:13 2000 +++ 2.2.18pre21aa1/kernel/fork.c Tue Nov 14 16:51:30 2000 @@ -700,6 +700,8 @@ */ current->counter >>= 1; p->counter = current->counter; + /* Tell the parent if it can get back its timeslice when child exits */ + p->counter_refresh = 0; /* * Ok, add it to the run-queues and make it --- 2.2.18pre21aa1/kernel/sched.c.~1~ Tue Nov 14 16:06:12 2000 +++ 2.2.18pre21aa1/kernel/sched.c Tue Nov 14 16:50:03 2000 @@ -801,8 +801,10 @@ struct task_struct *p; spin_unlock_irq(&runqueue_lock); read_lock(&tasklist_lock); - for_each_task(p) + for_each_task(p) { p->counter = (p->counter >> 1) + p->priority; + p->counter_refresh = 1; + } read_unlock(&tasklist_lock); spin_lock_irq(&runqueue_lock); goto repeat_schedule;