[comp.unix.wizards] usleep by poll

libes@cme.nist.gov (Don Libes) (04/02/91)

I've seen lots of statements to the effect that poll can, cannot,
might be able, might not be able, etc to simulate usleep, but I've yet
to see code.  The FAQ is similarly helpful, showing a BSD implemention
(courtesy of Doug Gwyn) but no SV implementation.

Here's an implementation of usleep on top of poll that I actually use.

Don Libes          libes@cme.nist.gov      ...!uunet!cme-durer!libes

/*

subseconds sleeps for System V - or anything that has poll()
Don Libes, 4/1/1991

The BSD analog to this function is defined in terms of microseconds
while poll() is defined in terms of milliseconds.  For compatibility,
this function provides accuracy "over the long run" by truncating
actual requests to milliseconds and accumulating microseconds across
calls with the idea that you are probably calling it in a tight loop,
and that over the long run, the error will even out.

If you aren't calling it in a tight loop, then you almost certainly
aren't making microsecond-resolution requests anyway, in which case
you don't care about microseconds.  And if you did, you wouldn't be
using UNIX anyway because random system indigestion (i.e., scheduling)
can make mincemeat out of any timing code.

Returns 0 if successful timeout, -1 if unsuccessful.

*/

#include <poll.h>

int
usleep(usec)
unsigned int usec;		/* microseconds */
{
	static subtotal = 0;	/* microseconds */
	int msec;		/* milliseconds */

	subtotal += usec;
	/* if less then 1 msec request, do nothing but remember it */
	if (subtotal < 1000) return(0);
	msec = subtotal/1000;
	subtotal = subtotal%1000;
	return poll((struct pollfd *)0,(unsigned long)0,msec);
}

rbj@uunet.UU.NET (Root Boy Jim) (04/02/91)

In article <999@muffin.cme.nist.gov> libes@cme.nist.gov (Don Libes) writes:
>
>The BSD analog to this function is defined in terms of microseconds
>while poll() is defined in terms of milliseconds.  For compatibility,
>this function provides accuracy "over the long run" by truncating
>actual requests to milliseconds and accumulating microseconds across
>calls with the idea that you are probably calling it in a tight loop,
>and that over the long run, the error will even out.

Yeah, but what's the best resolution you've ever seen?
Ten milliseconds seems to be the lowest. Since the average
error is have the smallest scheduling interval, why bother?

Perhaps they replaced the monster in 225's basement with a Cray?
-- 
		[rbj@uunet 1] stty sane
		unknown mode: sane

libes@cme.nist.gov (Don Libes) (04/02/91)

In article <127226@uunet.UU.NET> rbj@uunet.UU.NET (Root Boy Jim) writes:
}In article <999@muffin.cme.nist.gov> libes@cme.nist.gov (Don Libes) writes:
}The BSD analog to this function is defined in terms of microseconds
}>while poll() is defined in terms of milliseconds.  For compatibility,
}>this function provides accuracy "over the long run" by truncating
}>actual requests to milliseconds and accumulating microseconds across
}>calls with the idea that you are probably calling it in a tight loop,
}>and that over the long run, the error will even out.

}Yeah, but what's the best resolution you've ever seen?
}Ten milliseconds seems to be the lowest. Since the average
}error is have the smallest scheduling interval, why bother?

Room for improvement in the future, and compatibility with such.
Why did BSD provide usleep in the first place?

}Perhaps they replaced the monster in 225's basement with a Cray?

In fact, they did.  NIST just received a Cray YMP.  

Don Libes          libes@cme.nist.gov      ...!uunet!cme-durer!libes

torek@elf.ee.lbl.gov (Chris Torek) (04/03/91)

In article <999@muffin.cme.nist.gov> libes@cme.nist.gov (Don Libes)
[posts real code.  Commendable.  Now for a tangent :-) ]
>[System V's] poll() is defined in terms of milliseconds.

Good grief---first Bill Joy (most likely candidate at least) makes the
mistake of defining `timeval' structures as seconds+microseconds, then
System V compounds it by going the *wrong direction*!

Time values, including delays, should be in nanosecond granularity,
if not finer.  (Nanoseconds has the advantage of fitting easily in 64
bits as divided into `struct timevalue { long tv_sec; long tv_nsec; };'.)
-- 
In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427)
Berkeley, CA		Domain:	torek@ee.lbl.gov

andy@xwkg.Icom.Com (Andrew H. Marrinson) (04/03/91)

libes@cme.nist.gov (Don Libes) writes:

I recommend one slight fix to this usleep routine.  Some versions of
5.3 have a bug where the first argument to poll is checked for a valid
memory address even if the second argument is zero.  Thus, the version
you posted will fail with an EFAULT on systems with the bug.  Changing
it as follows will improve this:
>/*

>subseconds sleeps for System V - or anything that has poll()
>Don Libes, 4/1/1991

>[...]

>Returns 0 if successful timeout, -1 if unsuccessful.

>*/

>#include <poll.h>

>int
>usleep(usec)
>unsigned int usec;		/* microseconds */
>{
>	static subtotal = 0;	/* microseconds */
>	int msec;		/* milliseconds */
	struct pollfd foo;	/* ADD!!! */

>	subtotal += usec;
>	/* if less then 1 msec request, do nothing but remember it */
>	if (subtotal < 1000) return(0);
>	msec = subtotal/1000;
>	subtotal = subtotal%1000;
>	return poll(&foo,(unsigned long)0,msec);	/* CHANGE!!! */
>}

Hope this helps those who couldn't get the above to work on System
V/386 and perhaps others...
--
		Andrew H. Marrinson
		Icom Systems, Inc.
		Wheeling, IL, USA
		(andy@icom.icom.com)

rbj@uunet.UU.NET (Root Boy Jim) (04/04/91)

In article <11691@dog.ee.lbl.gov> torek@elf.ee.lbl.gov (Chris Torek) writes:
?In article <999@muffin.cme.nist.gov> libes@cme.nist.gov (Don Libes)
?[posts real code.  Commendable.  Now for a tangent :-) ]

No for a cotangent :-)

?Time values, including delays, should be in nanosecond granularity,
?if not finer.  (Nanoseconds has the advantage of fitting easily in 64
?bits as divided into `struct timevalue { long tv_sec; long tv_nsec; };'.)

By giving up a few bits for resolution, one can extend the range of
time values represented. A standard I have seen DEC use (first in
VMS/RSX RMS code) uses "hundreds of nanoseconds since [sometime in 1858]",
the date of the first photographic exposure by the Smithsonian.
I think this may actually a real ANSI time specification.

?In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427)
?Berkeley, CA		Domain:	torek@ee.lbl.gov
-- 
		[rbj@uunet 1] stty sane
		unknown mode: sane