DELAY

Mike Muuss mike at BRL.ARPA
Tue Oct 7 09:27:43 AEST 1986


DELAY(num) causes the kernel to loop hard, at the current ipl.
If entered at spl0(), interupts will still be processed, but
the kernel will just keep looping...  Recall that the kernel
will not context switch unless swtch() is called -- and you DON'T
want to do that in this case.

More likely, what you want to do is to have your driver_close()
routine shut down the DACs, and then execute a bit of code
something like this:

driver_close()
{
	/* Shut down the DACs here */
	timeout( &driver_close, 2*HZ );
	s = spl6();	/* protect against races */
	dac_wait = 1;
	while( dac_wait )
		sleep( &dac_wait, PZERO );
	splx(s);
	/* Handle final cleanups */
}

close_timeout()
{
	dac_wait = 0;
	wakeup( &dac_wait );
}

(Check the arguments to sleep() and timeout() carefully for the version
of UNIX that you are using -- the above code is just to give you the
"flavor" of this operation).

The timeout() routine arranges for the UNIX clock() routine to call your
time-handler after the specified number of clock ticks (2 seconds worth
in this example) have passed.  In the interim, execution proceeds normally.

The sleep() routine causes this process to be de-selected, and a context
switch to another process to occur.  This will allow other users to
continue executing while the timeout runs.  IMPORTANT NOTE:  The
loop around the sleep() is generally very important -- there are
no guarantees that the sleep() will not return from some other cause
(event) than the one you are expecting, so be certain to wait for
the intended condition to happen.  In this case, the transition
from 1 to 0 of the dac_wait flag.  (If you know *exactly* what you
are doing, and know *exactly* the semantics of sleep/wakeup on your
system, this can be avoided, but my advice to you is:  "don't").

Note that when sleep() context switches, it drops the high spl.
When the sleeping context is resumed by wakeup(), the high spl
is restored for you at the right point in the context switch.

Note that the above code is impervious to multiple timeouts
(which *shouldn't* ordinarily occur), because any additional timeouts
will just clear the dac_wait flag.

Note that if you were EXPECTING competing timeout or interupt events
during this close operation, it would be best to protect the
set..while..sleep loop with spl6 [for timeouts] or spl4,5 [for device
interupts], to prevent race conditions on the dac_wait flag.

Hope this helps all you folks out there write better drivers.
Best,
 -Mike Muuss

(301)-278-6678
  AV  298-6678
  FTS 939-6678

ArpaNet:  <Mike @ BRL.ARPA>
UUCP:     decvax!brl-bmd!mike
Postal:
  Mike Muuss
  Leader, Advanced Computer Systems Team
  Computer Science and Mathematics Branch
  Systems Engineering and Concepts Analysis Division
  U.S. Army Ballistic Research Laboratory
  Attn: SLCBR-SECAD (Muuss)
  APG, MD  21005-5066



More information about the Comp.unix.wizards mailing list