[net.unix-wizards] Device driver subtleties

ron@BRL-TGR.ARPA (07/24/84)

From:      Ron Natalie <ron@BRL-TGR.ARPA>

Sleep is independant of SPL level, as it is stating you wish to give
up the processor and then level of the new context is used.  However
you do state something interesting, you say you are sleeping at interrupt
level.  You can't do that.  There is no guarantee that the guy who did
the sleep will still be valid when the wakeup comes around.

With regard to close().  Generally, people don't care what close returns.
Close is only supposed to fail if the file isn't open.  I don't understand
your question about the write failing.

-Ron

dave@uwvax.ARPA (07/25/84)

> From:  Don Speck <speck@CIT-VAX.ARPA>
> 
>    When writing a device driver, what does it mean to call sleep() while
> at ipl 0x14?  I'm using it like this:
> rlpwrite(args) {
> 	...
> 	(void) spl4();	/* Lock out interrupts between test and sleep */
> 	while (! flag_set_by_interrupt_routine) {
> 	    sleep((caddr_t)lp->lp_buf, PZERO+8);
> 	}
> 	(void) spl0();

If you raise your priority like this, it will lock out *ALL* interrupts
for all priorities <= spl4().  How is your 'flag_set_by_interrupt_routine'
going to get set when the interrupt will never get received?  Methinks
you have process priority and device priority confused.  Also, your code
can do unexpected things.  A more correct way of handling the spl's is:

	spx = spl4();	/* save old priority and change to spl 4 */
	< critical section >
	(void) splx(spx);	/* restore priority to normal */

Now, back to your question.  The  sleep() will sleep at priority PZERO (normal)
plus 8.  This means it's interruptable by signals (which won't be sent
because you're at high priority, so noone else is going to run, except maybe
the clock).

-- 
Dave Cohrs @ wisconsin
...!{allegra,heurikon,ihnp4,seismo,ucbvax,uwm-evax}!uwvax!dave
dave@wisc-rsch.arpa

thomson@uthub.UUCP (Brian Thomson) (07/30/84)

Dave Cohrs comments:
> > From:  Don Speck <speck@CIT-VAX.ARPA>
> > 
> >    When writing a device driver, what does it mean to call sleep() while
> > at ipl 0x14?  I'm using it like this:
> > rlpwrite(args) {
> > 	...
> > 	(void) spl4();	/* Lock out interrupts between test and sleep */
> > 	while (! flag_set_by_interrupt_routine) {
> > 	    sleep((caddr_t)lp->lp_buf, PZERO+8);
> > 	}
> > 	(void) spl0();
> 
> If you raise your priority like this, it will lock out *ALL* interrupts
> for all priorities <= spl4().  How is your 'flag_set_by_interrupt_routine'
> going to get set when the interrupt will never get received?

His comment is not correct.  The interrupt will be received,
because sleep() does an spl0() after arranging for the eventual wakeup()
call.  The spl4() call above is correct, for exactly the reason stated
in the comment that follows it:  the interrupt must not be permitted
to occur between testing the flag and performing the sleep().
-- 
		    Brian Thomson,	    CSRI Univ. of Toronto
		    {linus,ihnp4,uw-beaver,floyd,utzoo}!utcsrgv!uthub!thomson