steve@nuchat.UUCP (Steve Nuchia) (07/29/90)
Working on a driver recently I needed to sleep waiting for a pending transaction completion interupt in the close routine. Since the interupt wasn't guaranteed to come, I wanted to be able to catch a signal. I found that it works when the user calls close directly but not when close is called from exit. I thought the observation might be due to the signal causing the close routine to be reentered, but a quick printf showed that was not the case. The wakeup just isn't happening. So, I got rid of the sleep, cancelling the pending operation. Lucky the situation was one where that was acceptable. This is in a SysV thing. Is this normal and expected? I couldn't find anything about it in the AT+T driver books. -- Steve Nuchia South Coast Computing Services (713) 964-2462 "To learn which questions are unanswerable, and _not_to_answer_them; this skill is most needful in times of stress and darkness." Ursula LeGuin, _The_Left_Hand_of_Darkness_
buck@siswat.UUCP (A. Lester Buck) (07/30/90)
In article <26789@nuchat.UUCP>, steve@nuchat.UUCP (Steve Nuchia) writes: > Working on a driver recently I needed to sleep waiting for > a pending transaction completion interupt in the close routine. > Since the interupt wasn't guaranteed to come, I wanted to > be able to catch a signal. I found that it works when the > user calls close directly but not when close is called from exit. Since we all know that, unfortunately, interrupts are never guaranteed to come, the only thing to do in an industrial strength driver is have a watchdog timer. At some reasonable interval (every 1-10 sec, maybe) it wakes up and checks hardware registers and driver state variables to see if it should be receiving an interrupt. It then possibly has to go back to sleep for one more time period - if no interrupt has been received then, it does whatever hardware reset is necessary to get things flowing again. > This is in a SysV thing. Is this normal and expected? I couldn't > find anything about it in the AT+T driver books. The exit() system calls I have seen atomicly mask all signals at the beginning, then quite a while later close all files. There isn't much to be done with signals anyway, because once exit() is entered, a process never gets back to user mode, and signal frames (fake calls to signal handlers) are built on the user's stack, to be executed as he is returning to user mode. The standard way to grab signals in a driver is by sleeping with PCATCH or'ed into the sleep priority. Then wakeup has sleep return one instead of zero, and the driver is expected to perform a longjmp(u.u_qsav) when it has cleaned up whatever (canceling outstanding timers, etc.). The driver might even save the u.u_qsav and replace it with it's own jmpbuf to catch a signal directly (wakeup does the longjmp itself if PCATCH is not set), but that is probably not recommended. The PCATCH/u_qsav information is in the AT&T Driver Development Manual, the excellent manual in a three ring binder. I paid $100 last year, but I think it is $200 now. -- A. Lester Buck buck@siswat.lonestar.org ...!texbell!moray!siswat!buck
steve@nuchat.UUCP (Steve Nuchia) (07/30/90)
In article <544@siswat.UUCP> buck@siswat.UUCP (A. Lester Buck) writes: >Since we all know that, unfortunately, interrupts are never guaranteed to >come, the only thing to do in an industrial strength driver is have a >watchdog timer. At some reasonable interval (every 1-10 sec, maybe) it Which brings up another problem -- there does not appear to be a good way to have a watchdog call the interrupt routine if the priority level of the ISR isn't the same as the one timeout uses. The "excellent manual" doesn't even say what priority level you get called at out of timeout. (At least not that I can find now. I thought I had seen it once but I gave up after hunting for it for a couple of hours last week.) Best way I could figure was to use a couple of gate-guard flags. Yuck. There has to be a canonical way to do this, right? This device does need a watchdog, but I've been holding off putting it in so as to get some idea how frequently it loses interupts. Also hoping for inspiration on the above problem. >The standard way to grab signals in a driver is by sleeping with PCATCH >or'ed into the sleep priority. Then wakeup has sleep return one instead of I about half expected this to work even inside exit, but Noooo. >even save the u.u_qsav and replace it with it's own jmpbuf to catch a signal >directly (wakeup does the longjmp itself if PCATCH is not set), but that is >probably not recommended. Not now that PCATCH extists. My understanding is that saving u_qsav used to be The Way. >The PCATCH/u_qsav information is in the AT&T Driver Development Manual, >the excellent manual in a three ring binder. I paid $100 last year, but >I think it is $200 now. I do sincerely hope "excellent" is simply missing a smiley. I've been wearing out my client's copy, and it is infuriating. Aside from about one trivial copy-editing botch per page, it has a very low information density, the customary (for AT+T) nonsensical organization, and it just leaves out a whole lot of necessary information. -- Steve Nuchia South Coast Computing Services (713) 964-2462 "To learn which questions are unanswerable, and _not_to_answer_them; this skill is most needful in times of stress and darkness." Ursula LeGuin, _The_Left_Hand_of_Darkness_
mb@ttidca.TTI.COM (Michael Bloom) (07/31/90)
In article <26789@nuchat.UUCP> steve@nuchat.UUCP (Steve Nuchia) writes: >Since the interupt wasn't guaranteed to come, I wanted to >be able to catch a signal. I found that it works when the >user calls close directly but not when close is called from exit. >This is in a SysV thing. Is this normal and expected? I couldn't >find anything about it in the AT+T driver books. Yes. If you run /etc/crash while your driver is blocked in a close called from exit, you'll see that all signals have been set to SIG_IGN. I dealt with a problem somewhat like yours once with a test of the form "(u.u_signal[SIGKILL -1] == SIG_IGN)", which should only be true in your close routine if it is called from exit. I didn't really like it, but it did the job.
bruner@sp15.csrd.uiuc.edu (John Bruner) (07/31/90)
In article <18901@ttidca.TTI.COM>, mb@ttidca (Michael Bloom) writes: >I dealt with a problem somewhat like yours once with a test of the >form "(u.u_signal[SIGKILL -1] == SIG_IGN)", which should only be true >in your close routine if it is called from exit. I didn't really like >it, but it did the job. On (at least some) BSD systems, u.u_signal[SIGKILL-1] == SIG_IGN for processes 1 and 2. You can't ignore kill signals, but the kernel initializes them this way when it spawns "init" and the pageout daemon. It seems unlikely that either of these will call a device's close routine; however, beware of using this technique in other situations. -- John Bruner Center for Supercomputing R&D, University of Illinois bruner@csrd.uiuc.edu (217) 244-4476
chris@mimsy.umd.edu (Chris Torek) (08/02/90)
In article <544@siswat.UUCP> buck@siswat.UUCP (A. Lester Buck) writes: >Since we all know that, unfortunately, interrupts are never guaranteed to >come, the only thing to do in an industrial strength driver is have a >watchdog timer. (I left this in because it bears repeating. `Expect hardware to malfunction.') >The standard way to grab signals in a driver is by sleeping with PCATCH >or'ed into the sleep priority. Then wakeup has sleep return one instead of >zero, and the driver is expected to perform a longjmp(u.u_qsav) when it has >cleaned up whatever (canceling outstanding timers, etc.). Note that things are quite different in Berkeley Unix. In 4.[123]BSD and derivatives sleep() either returns normally (after a wakeup()) or does not return at all (via longjmp). In 4.3-Reno, and thus eventually in 4.4BSD, sleep does take a PCATCH flag, but: a. the routine is called tsleep(); it has four parameters, and b. one of these is a timeout (in clock ticks); c. tsleep returns an error number from "errno.h", which is either 0, EWOULDBLOCK, ERESTART, or EINTR. ERESTART is a `special' internal error code that causes a system call to be restarted (on the VAX and Tahoe, by backing up the PC so that the call is redone). tsleep returns EWOULDBLOCK if the timeout expires before a wakeup() occurs. It returns ERESTART or EINTR only if the PCATCH flag is set and a signal occurs; in this case, which is chosen depends on whether the SA_RESTART bit is set in the signal action (this is a POSIX thingie). In particular, setjmp and longjmp are both gone in 4.3BSD-Reno. (setexit and reset are still there, if you compile in the kernel debugger.) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris