Bad boys run at priority 0

Pavel Machek (pavel@elf.ucw.cz)
Fri, 23 Jan 1998 19:15:45 +0100


Hi!

Once upon a time, I started X, and one application. I switched
consoles back, and watched blinkenlights indicated that CPU is
loaded (not much, but definitely not idle). I looked at top output,
and it indicated machine completely idle (Ie 97% spend in idle task
and 3% spend in top itself). I started to look for ghosts.

Then I found out that it is not ghosts, it is qweb polling for
events. Trouble with that polling was that it used short sleep between
them, which caused qweb to be scheduled immediately after
timetick. And since qweb always finished before next timer tick, no
time was counted to it. And then I realized that on loaded-enough
system (i.e. one background task running forever), almost _every_
process is of this type, synce reschedule is done only after timetick.

So that all 'idle' and such indicators saying that in.telnetd is
eating 0.3% of CPU time are probably lying, and telnetd & friends
probably eat *much* more.

Well, here is a simple code to show this, call it boy.c. When run with
bad on command line, it will try to trick scheduler to think that it
is not running at all (it sometimes succeeds). I got following
results:

..........3.40user 11.90system 0:15.67elapsed 97%CPU (0avgtext+0avgdata 0maxresident)k
..........3.62user 12.23system 0:16.24elapsed 97%CPU (0avgtext+0avgdata 0maxresident)k
..........0.06user 0.18system 2:24.22elapsed 0%CPU (0avgtext+0avgdata 0maxresident)k
..........0.01user 0.01system 0:38.97elapsed 0%CPU (0avgtext+0avgdata 0maxresident)k
..........0.01user 0.05system 0:38.49elapsed 0%CPU (0avgtext+0avgdata 0maxresident)k

Share, enjoy, and run your processes at privilege 0 all the time,
Pavel

/*
* This is simple program which should show weak spots in linux's scheduler
*/

#include <stdio.h>
#include <time.h>
#include <sys/timeb.h>
#include <unistd.h>

int startgame;

int
ticks( void )
{
struct timeb tb;
int sec, msec;
ftime( &tb );
sec = tb.time - startgame;
msec = tb.millitm;
return sec * 1000 + msec;
}

void
main( int argc, char *argv[] )
{
int delta, badboy = 0, count = 1000000;

startgame = time(NULL);
if (argc>1) {
int t1, t2;
badboy = 1;
printf( "I'm a *BAD* boy! " );
usleep( 1 );
startgame = ticks();
t1 = ticks();
usleep( 1 );
t2 = ticks();
delta = t2-t1;
printf( "And bad boys know that jiffie is %dmsec\n", delta );
}
else { printf( "I'm a good boy.\n" ); delta = 20; }
while(1) {
if (ticks() % delta > ((delta * 17)/20))
if (badboy)
usleep(1);
if (!((--count)%100000)) { printf( "." ); fflush( stdout ); }
if (!count) break;
}
}

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