Delay for a fraction of a second in C

Bill Davidson billd at celerity.UUCP
Sat Nov 5 08:35:31 AEST 1988


In article <1145 at orion.cf.uci.edu>, echarne at orion.cf.uci.edu (Eli B. Charne) writes:
> 
> The Unix sleep command will only go in increments of one second.  I was
> wondering if someone new of a nice little routine I could use, or has
> written one that will let me pause (in the Unix operating system) for
> a fraction of a second.  If it could go to 100th of a second, that would
> be great!

This is a function I wrote almost 2 years ago.  (It comes back to haunt me
now and then).  It works on Celerity 1200, 1230, 1260D and the new FPS
Model 500 and should be relatively portable to BSD systems.  I was kind of
new at using signals when I wrote it, so it could probably be improved a
bit.  I really don't want to spend any time thinking about it.  This is, of
course, not guaranteed to do anything useful.  It's not even guaranteed to
not trash your system (although I can't imagine how it could :-).  Every
architecture is going to generate timer interrupts at different intervals.
Also, there's no guarantee that you'll get the right amount of time even
given the correct intervals because in UNIX, you may be waiting to get
swapped in.  I should probably test it on our VAX but I'm too lazy.

------------------------------ cut here ----------------------------------

/*******************************************************************************
*
*	FSLEEP.C - Fine sleep.  This function allows you to sleep for
*	smaller intervals of time than 1 second.
*
*	SYNOPISIS
*		void fsleep( secs, usecs )
*		long secs, usecs;
*
*	secs is the number of seconds.
*	usecs is the number of milleseconds.
*
*	LIBRARY FUNCTIONS
*		setitimer(2)
*		signal(3C)
*		sigsetmask(2)
*		sigpause(2)
*
*	The number of milliseconds is misleading.  It is limited by the
*	resolution of the actual timers which is 10 milleseconds on an
*	Accel.
*
*	Note that the manual page incorrectly identifies the timer
*	intervals as being setable to microseconds.  It really meant
*	milleseconds (either that, or whoever set up setitimer on our
*	machine made a mistake).  When I first tried it (naively
*	believing the manual) I used 500000 for usecs thinking it
*	would be half a second instead of 500 seconds which is what
*	it was.
*
*******************************************************************************/

#include <stdio.h>
#include <time.h>
#include <signal.h>

#define	valsec	it_value.tv_sec
#define	valusec	it_value.tv_usec
#define	intsec	it_interval.tv_sec
#define	intusec	it_interval.tv_usec

static void fsleeptrap()
{
	/* Zen function */
}

void fsleep( secs, usecs )
unsigned long secs, usecs;
{
    int  omask, (*osig)();
    struct itimerval tval[2];

    osig = signal( SIGALRM, fsleeptrap );	/* set the trap */

    if ( usecs >= 1000L ){			/* fix the interval */
	secs += usecs / 1000L;
	usecs %= 1000L;
    }
    tval[1].intsec  = tval[1].intusec = 0L;
    tval[1].valsec  = secs;
    tval[1].valusec = usecs;

    omask = sigsetmask( ( 1 << (SIGALRM-1) ) );
    setitimer( 0, &tval[1], &tval[0] );
    sigpause( 0 );				/* wait for the timer */

    signal( SIGALRM, osig );			/* reset the old trap */
    setitimer( 0, &tval[0], &tval[1] );
    sigsetmask( omask );

    return;
}

------------------------------ cut here --------------------------------

Ever notice how much more you enjoy sleeping as you get older?

Bill Davidson			.....!ucsd!celerity!billd



More information about the Comp.lang.c mailing list