portable way to do nap()

David Sherman dave at lsuc.uucp
Wed Oct 5 12:39:12 AEST 1988


In article <8258 at alice.UUCP> debra at alice.UUCP (Paul De Bra) writes:
>In article <543 at mpx1.UUCP> erik at mpx1.UUCP (Erik Murrey) writes:
>>How can I do a portable nap()?  A nap() (under XENIX) allows
>>a user process to block for a short time, usually a few hundred ms.
>>
>I opened my Unix V9 manual, and yes of course, nap(2) is there.
>So if you wait a few years until the System-V people pick up this
>idea from research (took a while with streams too as I recall)
>nap() will become portable.

If you can't wait that long and you have source (or perhaps
even if you have just enough source to be able to add your
own drivers), here's the device driver nap.c.  You stick this
in your kernel with the right hooks (mail me if you can't
figure out the hooks), mknod /dev/nap, and then compile the
second nap.c, which nap.o gets ar'ed into /lib/libc.a (i.e.,
installed as a library function nap(3)).

The trick is that a call to nap() is really an ioctl to
a device that does the nap.  You use up a file descriptor,
but otherwise it's a pretty nice and clean way to implement it.

===================== nap.c, from /usr/sys/dev ==============
/* nap - nap for hundredths of seconds. By garfield!sean,
 * installed by Dave Sherman October/84, from PDP-11/23 version
 */

#include "sys/nap.h"
#if NNAP > 0
#include "sys/param.h"
#include "sys/systm.h"
#include "sys/tty.h"
#include "sys/dir.h"
#include "sys/user.h"
#include "sys/proc.h"

#define N_NAP	32
#define NAPPRI	31

int ttnap[N_NAP];

napioctl(dev, cmd, addr, flags)
dev_t	dev;
caddr_t addr;
{
	int wakeup();
	int *ptr;

	for(ptr=ttnap; *ptr && (ptr <= &ttnap[N_NAP]); ptr++);
	if(ptr == &ttnap[N_NAP]) {
		u.u_error = ENXIO;
		return;
	}

	*ptr = u.u_procp->p_pid;
	timeout(wakeup, ptr, cmd);
	sleep(ptr, NAPPRI);
	*ptr = 0;
}

napclose(dev, flags)
	dev_t	dev;
{
	int *ptr;
	for(ptr=ttnap; (*ptr != u.u_procp->p_pid) && (ptr <= &ttnap[N_NAP]); ptr++);
	if(*ptr == u.u_procp->p_pid)
		*ptr = 0;
}
#endif

==================== nap.c, from /usr/src/libc/local ========
/*
 *	nap - uses ioctl as set up by garfield!sean
 *
 *	Dave Sherman, June 1983
 */

nap(hundredths)
	register hundredths;
{
	static napfd = -1;

	if(napfd < 0)
	{
		napfd = open("/dev/nap", 0);
		if(napfd < 0)
			return(-1);
	}
	ioctl(napfd, hundredths, 0);
}

======================================================

The above code is for a v7 system; the details may vary
slightly for other versions of UNIX.  Also, the "hundredths"
may be sixtieths (of a second) on many systems.
Thanks to Sean Byrne, once garfield!sean, then philabs!scb,
where are you now?, for the original device driver code.

Please send me mail if you find this useful.

David Sherman
The Law Society of Upper Canada
Toronto
-- 
{ uunet!attcan  att  pyramid!utai  utzoo } !lsuc!dave



More information about the Comp.unix.wizards mailing list