edw@IUS1.CS.CMU.EDU (Eddie Wyatt) (11/09/87)
/************************************************************************** * * * msleep * * * ************************************************************************** Purpose : What you all been waiting for -- A sleep that works in microseconds!!!. Actually it depends on the granularity of the interrupt timer, but at least its better than the second wait. Programmer : Eddie Wyatt (orginally written by Paul Allen) Date : November 1987 Input : sec - number of seconds to sleep msec - number of micro seconds to sleep Output : None Locals : off - itimer value to turn off the timer interrupt. time - wait time oldtime - old itime value bob - the old interrupt handler Globals : ************************************************************************/ #include <signal.h> #include <sys/time.h> /* ARGSUSED */ static int signal_handler(sig,code,scp) int sig, code; struct sigcontext *scp; { return(1); } static struct itimerval off = {{0,0},{0,0}}; void msleep(sec,msec) int sec, msec; { struct itimerval time; struct itimerval oldtime; int (*bob)(); if ((sec == 0) && (msec == 0)) return; /* note that we have the timer interrupting continously as oppose to just once. This is because if we were to install the itimer to interrupt just once, there would be a critial section (the space between setitimer and sigpause) where if the interrupt sound then, it would be lost and we would wait forever in sigpause */ time.it_interval.tv_sec = sec; time.it_interval.tv_usec = msec; time.it_value.tv_sec = sec; time.it_value.tv_usec = msec; /* insert my interrupt handler and itimer val (order matters) while saving old values to be re-instated */ bob = signal(SIGALRM, signal_handler); if (setitimer(ITIMER_REAL, &time, &oldtime) < 0) perror("setitimer"); /* wait until an interrupt happens, hopefully a timer interrupt - but it need not be. */ sigpause(0); /* turn timer off while returning timer and interrupt handler back to the old state (order matters) */ if (setitimer(ITIMER_REAL, &off, (struct itimerval *) 0) < 0) perror("setitimer"); if ((int) signal(SIGALRM, bob) == -1) perror("signal"); if (setitimer(ITIMER_REAL, &oldtime, (struct itimerval *) 0)) perror("setitimer"); } -- That one looks Jewish -- And that one's a coon -- Who let all this riff raff into the room -- There's one smoking a joint -- and Anoter with spots -- If I had my way -- I'd have all of you shot ... Pink Floyd, "In the Flesh" Eddie Wyatt e-mail: edw@ius1.cs.cmu.edu
bader+@andrew.cmu.edu (Miles Bader) (11/10/87)
> Purpose : What you all been waiting for -- A sleep that works in > microseconds!!!. Actually it depends on the granularity I've always used select(0,0,0,0,&tv) for this; is there anything wrong with doing this? -Miles
ruiu@tic.UUCP (Dragos Ruiu) (11/10/87)
In article <UVZXqQy00UkayG00yf@andrew.cmu.edu>, bader+@andrew.cmu.edu (Miles Bader) writes: > > Purpose : What you all been waiting for -- A sleep that works in > > microseconds!!!. Actually it depends on the granularity > I've always used select(0,0,0,0,&tv) for this; is there anything wrong with > doing this? > -Miles It only works if you happen to be using BSD. Some people don't have sockets! -- Dragos Ruiu Disclaimer: My opinons are my employer's, I'm unemployed! UUCP:{ubc-vision,mnetor,vax135,ihnp4}!alberta!edson!tic!dragos!work (403) 432-0090 #1705, 8515 112th Street, Edmonton, Alta. Canada T6G 1K7 Never play leapfrog with Unicorns...
chris@mimsy.UUCP (Chris Torek) (11/12/87)
In article <332@PT.CS.CMU.EDU> edw@IUS1.CS.CMU.EDU (Eddie Wyatt) writes: >/************************************************************************** > * * > * msleep * > * * > ************************************************************************** > > Purpose : What you all been waiting for -- A sleep that works in > microseconds!!!. Actually it depends on the granularity > of the interrupt timer, but at least its better than > the second wait. ... followed by code that uses setitimer. 0) Only certain 4BSD-based operating systems *have* setitimer. (What this *really* means is that if you need a sleep that works in milliseconds or microseconds or whatever, using a routine like msleep is imperative. Then the victim, er, user, of your code need rewrite only msleep.) 1) you can (and, I think, should) avoid the critical section by using sigblock and sigsetmask (see man 2 sigblock). 2) using setitimer is more expensive than calling select with three `(fd_set *)0' arguments. Select does have one problem: like sigpause, it is interrupted by signals; unlike sigpause, it does not take a signal mask, so it sometimes has unavoidable critical sections. (Yes, I want a sixth argument to select!) 3) The actual granularity of interval timers (including select timers): system granularity 4.[23]BSD Vax 10 ms Sun[23] running SunOS 3.x 20 ms -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
edw@IUS1.CS.CMU.EDU (Eddie Wyatt) (11/17/87)
In article <9310@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes: > > 0) Only certain 4BSD-based operating systems *have* setitimer. > (What this *really* means is that if you need a sleep that works > in milliseconds or microseconds or whatever, using a routine > like msleep is imperative. Then the victim, er, user, of your > code need rewrite only msleep.) > > 1) you can (and, I think, should) avoid the critical section by using > sigblock and sigsetmask (see man 2 sigblock). > > 2) using setitimer is more expensive than calling select with three > `(fd_set *)0' arguments. Select does have one problem: like > sigpause, it is interrupted by signals; unlike sigpause, it does > not take a signal mask, so it sometimes has unavoidable critical > sections. (Yes, I want a sixth argument to select!) > > 3) The actual granularity of interval timers (including select timers): > > system granularity > 4.[23]BSD Vax 10 ms > Sun[23] running SunOS 3.x 20 ms > -- > In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) > Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris Sorry about #0, I didn't know SYSV doesn't provide itimers. #1 Sorry, I think critical section was a misnomer for what I meant. The problem that I was describing had to do with setting the itimer up such that it interrupts only once (the second half of the structure set to zeros). If the ONLY timer interrupt was to come during the period between the call to setitimer and sigpause, my interrupt handle would be called and then NOTHING would happen in sigpause to make sigpause exit. The only timer interrupt sounded would not have caused sigpause to exit, since it sounded BEFORE entering into sigpause. This is the rational behind using continuous interrupts (the second half of the structure not set to zeros) when at first glance, someone might think you could get away with just one. BTW, yes I'm very familiar with the sigblock and sigsetmask functions, they are not needed to implement this facility, setitimer suffices. Point two about setitimer being slower. Does that really make sense to complain about how long setitimer takes as compared to select!!! If the interrupt timer's granularity is 10 millisecs, both select and msleep will usually time out at the same time (setitimer has to be in the order of 100 micros per call). Statistically though, msleep should have a mean wait time that is a little longer than select. Also, don't you consider the use of select as a timer to be an abuse of the function? Then again, are you one that argues, vfork is avid way to get shared mem in BSD. ;-) -- That one looks Jewish -- And that one's a coon -- Who let all this riff raff into the room -- There's one smoking a joint -- and Anoter with spots -- If I had my way -- I'd have all of you shot ... Pink Floyd, "In the Flesh" Eddie Wyatt e-mail: edw@ius1.cs.cmu.edu