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