Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!columbia!rutgers!caip!brl-adm!brl-smoke!smoke!mike@BRL.ARPA From: mike@BRL.ARPA (Mike Muuss) Newsgroups: net.unix-wizards Subject: Re: DELAY Message-ID: <4393@brl-smoke.ARPA> Date: Mon, 6-Oct-86 19:27:43 EDT Article-I.D.: brl-smok.4393 Posted: Mon Oct 6 19:27:43 1986 Date-Received: Tue, 7-Oct-86 23:57:01 EDT Sender: news@brl-smoke.ARPA Lines: 78 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: 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