joel@intelisc.UUCP (Joel Clark) (05/19/88)
I was very interested in the recent disscussion of sleep(), PCATCH
and interrupts. In brief:
1) sleep(addr,j) with j < PZERO is uninterruptable.
2) sleep(addr,j) with j > PZERO is interruptable with the sleep
immediately executing "longjmp(u.u_qsav);". The user would
have an errno value EINTR for "interrupted system call", but
would continue executing.
3) sleep(addr,j) with j > PZERO and j | PCATCH is interruptable and
when interrupted will return 1 to the calling process. This
allows the calling process to "cleanup (kernal data)" and
execute its own "longjmp(u.u_qsav)".
Right so far??
Questions:
In #3 above what are the consequences of replacing the longjmp
with a return?
If the process in #2 or #3 above is running under a debugger,
and the user types an interrupt (DEL, ^C, whatever), and then
continues, and the debugger trys to continue the process by
using ptrace(7, , ,0);, why is the sleep interrupted?
ptrace(7, , ,0) is supposed to continue the process with all
pending signals deleted.
An example of this is to run sdb on the following program:
########################################################################
#include <fcntl.h>
main()
{
int fd,n;
char buf[100];
fd = open("/dev/tty",O_RDWR);
perror("sleep");
n = read(fd,buf,10);
perror("sleep2");
printf("Buf = %s\n",buf);
}
##########################################################################
After the first sleep message hit DEL. The read system call will return
with a "Interrupted system call" message.
Though I cannot be sure that sdb is continuing with the 4th argument = 0,
the debugger I am having problems with is not sdb, and I am sure it is
using "ptrace(7, , ,0);"
I am using System V R3.0 for the 80386 as supplied by ATT.
Joel Clark
Intel Scientific Computers joel@intelisc.uucp.com
Beaverton, OR 97006 USA {tektronix}!ogcvax!intelisc!joel
(503) 629-7732
Intel Scientific accepts no liabilities from my statements here.
dave@lsuc.uucp (David Sherman) (09/29/88)
I have a fairly complex CAI system that's used for legal education here. It uses pipes, longjmp, SIGUSER and pause(2) to allow the student to hit an interrupt key and change the level of instruction at any point. It also uses sleep(3) here and there, and SIGALRM to log off idle users. With all the various UNIXisms that interact, the programs occasionally exhibit strange behaviour, which I'd never been able to pinpoint. Today someone asked me why sleep(3) is a library routine rather than a system call, which I'd always thought it was. (This is a v7-based UNIX, Perkin-Elmer's Edition VII.) So I read the code, and was startled to find it uses SIGALRM and pause, with a longjmp to put you back where you were. No wonder I get funny interactions with my other uses of setjmp and SIGALRM. I'm surprised some of it works at all. The manual doesn't suggest sleep(3) shouldn't be used in conjunction with setjmp or SIGALRM. But setjmp's certainly aren't nestable. Has anyone else run into this issue? Comments? David Sherman The Law Society of Upper Canada -- { uunet!attcan att pyramid!utai utzoo } !lsuc!dave
henry@utzoo.uucp (Henry Spencer) (09/30/88)
In article <1988Sep28.135914.25444@lsuc.uucp> dave@lsuc.uucp (David Sherman) writes: >Today someone asked me why sleep(3) is a library routine rather >than a system call, which I'd always thought it was. (This is a >v7-based UNIX, Perkin-Elmer's Edition VII.) So I read the code, >and was startled to find it uses SIGALRM and pause, with a longjmp >to put you back where you were. Yup. Sleep was a system call in V6, but in V7 it was superseded, in theory, by alarm. >No wonder I get funny interactions with my other uses of setjmp >and SIGALRM. I'm surprised some of it works at all. The sleep code does make an attempt to preserve an existing alarm setting, if any. -- The meek can have the Earth; | Henry Spencer at U of Toronto Zoology the rest of us have other plans.|uunet!attcan!utzoo!henry henry@zoo.toronto.edu
djones@megatest.UUCP (Dave Jones) (09/30/88)
From article <1988Sep28.135914.25444@lsuc.uucp), by dave@lsuc.uucp (David Sherman): ) I have a fairly complex CAI system that's used for legal education ) here. It uses pipes, longjmp, SIGUSER and pause(2) to allow the student ) to hit an interrupt key and change the level of instruction at any point. ) It also uses sleep(3) here and there, and SIGALRM to log off idle users. ) With all the various UNIXisms that interact, the programs occasionally ) exhibit strange behaviour, which I'd never been able to pinpoint. ) ) Today someone asked me why sleep(3) is a library routine rather ) than a system call, which I'd always thought it was. (This is a ) v7-based UNIX, Perkin-Elmer's Edition VII.) So I read the code, ) and was startled to find it uses SIGALRM and pause, with a longjmp ) to put you back where you were. The man-page on the Sun3 (BSD4.2 based) is explicit: sleep is implemented by setting an interval timer and paus- ing until it expires. The previous state of this timer is saved and restored. I would recommend that you process all signals, sleeps, selects, etc, through a central location. The "notifier" in Sun's sunview package would suffice, but I don't know if its source is available. In any case, it should not be too difficult to implement it. Good luck.
leo@philmds.UUCP (Leo de Wit) (09/30/88)
In article <1988Sep28.135914.25444@lsuc.uucp> dave@lsuc.uucp (David Sherman) writes: >I have a fairly complex CAI system that's used for legal education >here. It uses pipes, longjmp, SIGUSER and pause(2) to allow the student >to hit an interrupt key and change the level of instruction at any point. >It also uses sleep(3) here and there, and SIGALRM to log off idle users. >With all the various UNIXisms that interact, the programs occasionally >exhibit strange behaviour, which I'd never been able to pinpoint. > >Today someone asked me why sleep(3) is a library routine rather >than a system call, which I'd always thought it was. (This is a >v7-based UNIX, Perkin-Elmer's Edition VII.) So I read the code, >and was startled to find it uses SIGALRM and pause, with a longjmp >to put you back where you were. > >No wonder I get funny interactions with my other uses of setjmp >and SIGALRM. I'm surprised some of it works at all. > >The manual doesn't suggest sleep(3) shouldn't be used in conjunction >with setjmp or SIGALRM. But setjmp's certainly aren't nestable. >Has anyone else run into this issue? Comments? [The following may differ on various Unix systems, because also the system calls differ; I may also be imprecise about in which places exactly a system call or a library routine is used, but this doesn't affect the general idea. So no flames please! ] Talking about library routines: on Ultrix pause() is also a library routine (sigpause presumably being the underlying system call). Sleep() is implemented by setting a timer (setitimer(2) or alarm(3)) and waiting for the wake-up to occur; pause(3) or sigpause(2). Because the code of sleep() has to catch the SIGALRM it does a signal(3) or sigvec(). The reason a longjmp() is used at all here is perhaps that the system wil restart the system call (sigpause) if the interrupt handler just returns, which is not the intention of sleep(). Setjmp's not being nestable? Why should they not be? The tricky bit is you must use the correct jmpbuf with each setjmp(), and longjmp() back to the correct setjmp() (i.e. the code after it), but then it works OK. Since the library sleep() does a setjmp(), it will use its own private jmpbuf, and probably does a signal(SIGALRM,sighandler), where sighandler() is a function that will do the longjmp() back into sleep(), using the private jmpbuf as argument. No conflict with your jmpbuf(s). What may certainly cause you trouble is the setting of the alarm clock in sleep(); this will conflict with your setting of it, unless it is implemented clean enough to restore the original alarm time and setting of the interrupt handler. If it isn't, why not write your own? The strange behaviour of your programs may still have other causes. For instance, it is generally believed to be a bad idea to do a lot of stuff in interrupt handlers (you can get all kinds of trouble with interrupts interrupting interrupt handlers, restarting/not restarting interrupted system calls); this however is again Unix-type dependent. Perhaps you can be a bit more specific than just: strange behaviour? Leo.
peter@stca77.stc.oz (Peter Jeremy) (10/10/88)
In article <823@philmds.UUCP> leo@philmds.UUCP (Leo de Wit) writes: >In article <1988Sep28.135914.25444@lsuc.uucp> dave@lsuc.uucp (David Sherman) writes: >> [ Interactions between sleep(), SIGUSER, longjmp(), pause() ] > [ isn't longjmp() ] >What may certainly cause you trouble is the setting of the alarm clock >in sleep(); this will conflict with your setting of it, unless it is >implemented clean enough to restore the original alarm time and setting >of the interrupt handler. If it isn't, why not write your own? Looking at my XENIX system, sleep() will save and restore your alarm() setting. I did discover a bug with some of my code that used sleep(1) for short timeouts - occasionally it would stop. When I looked at sleep() closely, I found that there is a hole between the alarm() and pause() calls (about 20 usec on a 8MHz 80286 from memory) that would occasionally let the alarm() timeout before it paused - hence the pause() waited until the next signal. A bit embarrasing... I got around it by using nap() or longer sleeps. I suspect the bug exists in all library versions of sleep(), so it may be worth checking if you use 'sleep(1);' at all. -- Peter Jeremy (VK2PJ) peter@stca77.stc.oz Alcatel-STC Australia ...!munnari!stca77.stc.oz!peter 41 Mandible St peter%stca77.stc.oz@uunet.UU.NET ALEXANDRIA NSW 2015