Bug in sleep
utzoo!decvax!ucbvax!unix-wizards
utzoo!decvax!ucbvax!unix-wizards
Sun Nov 15 23:26:37 AEST 1981
>From harpo!jerry at Berkeley Sun Nov 15 22:21:30 1981
Yes, an interrupt at an inoportune time could cause the V7 sleep to
"pause" forever. It can be corrected (without kernel changes )
by making the following changes at two places.
First at the point where pause is called:
wakecnt = 0 ; /* Added. This is a new global (declared
static in this file) that will count how
many times awake is called */
alarm(sleep_tm); /* Unchanged */
pause(); /* Unchanged */
unslept = alarm(0) ; /* Unchanged */
if ( unslept >= wakecnt ) unslept -= wakecnt ;
else unslept = 0 ;
/* Added. Corrects for the effect of awake reseting the
alarm. In normal circumstances unslept will
be at least one and wakecnt will be exactly
one so the test isn't required. But that
may not hold in some pathological cases. If
the else is taken some ticks will have been
lost, but that's life. */
Second redefine awake:
static
awake() {
++ wakecnt ;
signal(SIGALRM, awake ) ;
alarm(1) ;
}
I haven't tested this code, so it may not be right, but the idea is sound.
It adds two system calls for every invocation of sleep and so may not
be worth installing.
Incidentally, there is another subtle bug in sleep.c. It arises in
the following circumstance. Define
caught() {
< do whatever is to be done >
signal(SIGALRM,caught) ;
alarm(10) ;
}
Somewhere else execute:
signal(SIGALRM,caught) ;
alarm(10) ;
sleep(20) ;
It's probably easier to avoid doing this sort of thing than to fix the
bug in sleep. If you really care, the problem is at the places where
signal(SIGALRM,alrm_sig) is called.
Jerry Schwarz
Bell Labs, Whippany
More information about the Comp.unix.wizards
mailing list