[pe.cust.sources] code to implement nap via ioctl

dave@lsuc.UUCP (David Sherman) (04/22/85)

A couple of people have asked me for the code which implements nap
(sleep for 1/HZ seconds, in our case 1/100 second) via an ioctl
device rather than a system call. Here goes. The device driver
part is originally from Sean Byrne, onetime garfield!sean and now
philabs!scb. The nap(3) source and manual is by me.

Dave Sherman


============== /usr/sys/conf/conf ====================
Add the following line, right after "mem" and "tty":

nap		* nap in 100th's of a second when ioctl to /dev/nap

============== /usr/sys/conf/mkconf.c ===============
Add the following entry to the end of devconf[] and note the major device
number which results in c.c (on our system, it's 25).

	/* nap 60th's of a second device */

	{
		"nap", CDEV, 0, 0,
		{ 
			0 		}
		,
		{ 
			null, "napclose", null, null, "napioctl", no,
			zero 		}
		,
		{ 
			0 		}
		,
		{ 
			0 		}
		,
	}
	,

=========================== making the device ================
/etc/mknod /dev/nap 25 0
(where the 25 will be the mkconf-supplied major device number and
 will appear in c.c)



=========================== /usr/sys/dev/nap.c ==================
[This is the actual device driver. You'll also want to add nap.c and nap.o
 to CFILES and OFILES in makefile, and run make to update LIB2]

/* 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

=========================== /usr/include/sys/nap.h ==============
#define NNAP 1

========================== /usr/src/libc/gen/nap.c ==============
[This is the nap(3) routine. You'll want to compile it and install
 the nap.o file in /lib/libc.a with "ar rv /lib/libc.a nap.o"]

/*
 *	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);
}

======================= /usr/man/man3/nap.3 ======================
.   \"@(#) xx	5.1		13:59:57 - 83/09/12"
.TH nap 3 local
.SH NAME
nap - nap for hundredths of seconds
.SH SYNOPSIS
nap(hundredths)
.SH DESCRIPTION
Goes to sleep for the specified number of hundredths of a second.
Done via ioctl to /dev/nap. Useful where sleep(3) isn't precise enough.
.SH FILES
/dev/nap
.SH SEE ALSO
sleep(3), ioctl(2)
.SH AUTHOR
Sean Byrne, Memorial University (garfield!sean). Installed
here October 1984 by David Sherman, from the PDP-11/23 version first
installed in May 1983.
.SH BUGS
Should be sixtieths, but the code installed results in hudnredths
due to the setting of HZ in the kernel.

The first call to nap() may cause a fractionally longer
nap, since the /dev/nap device has to be opened. It's not
really noticeable.

It uses up a file descriptor.
-- 
{utzoo pesnta nrcaero utcs hcr}!lsuc!dave
{allegra decvax ihnp4 linus}!utcsri!lsuc!dave