Scheduler fixes

Pavel Machek (pavel@bug.ucw.cz)
Wed, 24 Jun 1998 14:01:09 +0200


Hi!

Linux tries to measure times spend in
processes... Somehow. Unfortunately, it is optimistic: it will show
less than real values under some pretty common
circumstances. (Application sleeping for short times and doing small
ammount of processing is marked as eating 0% of system time. There are
some applications which do this - for example ksame, qweb (and I think
that everything using qt) - which do evil busy waiting.)

This patch changes it: now, kernel is pesimistic. It just finds
someone to accound him spend time. This way, busy waiting applications
get accounted, so they can be identified. I think this is good, or at
least it is much better than current state.

It also includes small fixes to sched.c. This is for experimentation
and comments, not for inclusion. [Well, small fixes maybe should be
included...]

Pavel

PS: Comments welcome, testers welcome.

PPS: I know that 'need_update_times' name for variable is misleading,
does anyone have something better?

--- clean/kernel/sched.c Tue Jun 23 23:10:49 1998
+++ linux/kernel/sched.c Wed Jun 24 00:56:32 1998
@@ -82,6 +82,8 @@
long time_adjust_step = 0;

int need_resched = 0;
+int need_update_times = 0;
+int need_update_times_system = 0;
unsigned long event = 0;

extern int do_setitimer(int, struct itimerval *, struct itimerval *);
@@ -495,10 +494,14 @@
next->processor = this_cpu;
#endif

+
+ if (need_update_times)
+ update_process_times( next, need_update_times, need_update_times_system );
+
if (prev != next) {
struct timer_list timer;

kstat.context_swtch++;
if (timeout) {
init_timer(&timer);
timer.expires = timeout;
@@ -767,10 +774,7 @@
struct timer_struct timer_table[32];

/*
- * Hmm.. Changed this, as the GNU make sources (load.c) seems to
- * imply that avenrun[] is the standard name for this kind of thing.
- * Nothing else seems to be standardized: the fractional size etc
- * all seem to differ on different machines.
+ * This is famous 'load average'
*/
unsigned long avenrun[3] = { 0,0,0 };

@@ -1046,14 +1050,15 @@
do_it_prof(p, ticks);
}

-static void update_process_times(unsigned long ticks, unsigned long system)
+static void update_process_times(struct task_struct *p, unsigned long ticks, unsigned long system)
{
/*
* SMP does this on a per-CPU basis elsewhere
*/
#ifndef __SMP__
- struct task_struct * p = current;
unsigned long user = ticks - system;
+ need_update_times = need_update_times_system = 0;
+
if (p->pid) {
p->counter -= ticks;
if (p->counter < 0) {
@@ -1091,8 +1096,8 @@
calc_load(ticks);
update_wall_time(ticks);
restore_flags(flags);
-
- update_process_times(ticks, system);
+
+// update_process_times(current, ticks, system);

} else
restore_flags(flags);
@@ -1100,6 +1105,8 @@

static void timer_bh(void)
{
+ if (need_update_times>1)
+ update_process_times( current, need_update_times, need_update_times_system );
update_times();
run_old_timers();
run_timer_list();
@@ -1107,11 +1114,14 @@

void do_timer(struct pt_regs * regs)
{
- (*(unsigned long *)&jiffies)++;
+ (*(unsigned long * volatile)&jiffies)++;
lost_ticks++;
mark_bh(TIMER_BH);
- if (!user_mode(regs))
+ need_update_times++;
+ if (!user_mode(regs)) {
lost_ticks_system++;
+ need_update_times_system++;
+ }
if (tq_timer)
mark_bh(TQUEUE_BH);
}
@@ -1532,7 +1545,7 @@
printk(stat_nam[p->state]);
else
printk(" ");
-#if ((~0UL) == 0xffffffff)
+#if (BITS_PER_LONG == 32)
if (p == current)
printk(" current ");
else
@@ -1595,7 +1608,7 @@
{
struct task_struct *p;

-#if ((~0UL) == 0xffffffff)
+#if (BITS_PER_LONG == 32)
printk("\n"
" free sibling\n");
printk(" task PC stack pid father child younger older\n");

-- 
I'm really pavel@atrey.karlin.mff.cuni.cz. 	   Pavel
Look at http://atrey.karlin.mff.cuni.cz/~pavel/ ;-).

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu