zeeff@b-tech.ann-arbor.mi.us (Jon Zeeff) (03/29/89)
#! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of shell archive." # Contents: ft.c nap.c test.c # Wrapped by zeeff@b-tech on Mon Oct 17 10:17:48 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f ft.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"ft.c\" else echo shar: Extracting \"ft.c\" \(1082 characters\) sed "s/^X//" >ft.c <<'END_OF_ft.c' X X/* X Written by Jon Zeeff umix!b-tech!zeeff X X This "device driver" uses the kernel delay() call to allow calls X to nap() from user processes. Nap() is like sleep, but with finer X resolution. X X Compile with cc -O -c ft.c X X Written for a Sys V.3 system, but should work on others. X X For Sys V.3: X X Make a new kernel according to the instructions and then: X mknod /dev/ft c 28 0 X X modules/ft/config: X character(28) X prefix = ft X functions = open, close, read X X Edit systems/system.std and add ft. X Copy ft.o to modules/ft/config X X*/ X X#include <sys/signal.h> X#include <sys/types.h> X#include <sys/sysmacros.h> X#include <sys/param.h> X#include <sys/systm.h> X#include <sys/buf.h> X#include <sys/iobuf.h> X#include <sys/conf.h> X#include <sys/dir.h> X#include <sys/user.h> X#include <sys/utsname.h> X#include <sys/elog.h> X#include <sys/errno.h> X#include <sys/trap.h> X#include <sys/seg.h> X#include <sys/map.h> X X/* use a raw device interface */ X Xftopen() {} X Xftread(dev) Xint dev; X{ Xdelay(u.u_count); Xu.u_count = 0; X} X Xftwrite() {} Xftclose() {} X END_OF_ft.c if test 1082 -ne `wc -c <ft.c`; then echo shar: \"ft.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f nap.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"nap.c\" else echo shar: Extracting \"nap.c\" \(115 characters\) sed "s/^X//" >nap.c <<'END_OF_nap.c' X Xnap(ticks) Xunsigned ticks; X{ Xstatic int fd=0; X Xif (fd == 0) fd = open("/dev/ft",0); Xread(fd,(char *)0,ticks); X X} X END_OF_nap.c if test 115 -ne `wc -c <nap.c`; then echo shar: \"nap.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f test.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"test.c\" else echo shar: Extracting \"test.c\" \(26 characters\) sed "s/^X//" >test.c <<'END_OF_test.c' X Xmain() X{ X Xnap(1000); X X} X END_OF_test.c if test 26 -ne `wc -c <test.c`; then echo shar: \"test.c\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of shell archive. exit 0 -- Jon Zeeff zeeff@b-tech.ann-arbor.mi.us Ann Arbor, MI mailrus!b-tech!zeeff
heiby@mcdchg.chi.il.us (Ron Heiby) (04/01/89)
I made some changes to an earlier posting of Sys V nap() to run a bit more reliably and be of sufficient quality and documentation that I could hand the stuff (below) to one of my customers and wish them luck. Some of it is specific to the Motorola Delta Series, but most of it is pretty generic. ----- cut here ----- #!/bin/sh # to extract, remove the header and type "sh filename" if `test ! -s ./README` then echo "writing ./README" cat > ./README << '\Rogue\Monster\' nap() - 12/88 This file describes the nap() package for the Motorola VME Delta Series computer systems. This work was based on ideas from several people on the Usenet and skeletal code written by Jon Zeeff. From there, it has been enhanced to eliminate the possibility of causing a system panic as well as in several smaller ways. nap() has been tested under System V/68 Release 3 version 4 and under System V/68 Release 3 version 5 (FE83.26). To install the package, cd into the directory into which the files were extracted and type "make". This will build all the files you will need. The file "lib.nap" must be copied into the directory /usr/src/uts/m68k/cf. The file "nap.o" contains the definition of the nap() function call and may be explicitly linked with code that calls it or may be placed into a library of routines. The file "sysgen.ft" should be copied to /usr/src/uts/m68k/sysgen/descriptions/ft (file "ft" in the "descriptions" directory). This file declares that the "Major Character Device Number" is 28. This is the same number used by OfficeLAN. If you are using the OfficeLAN product in your system, you must choose a different number for nap() and use it in place of 28 here, and in the "mknod" command below. (See below for how to choose a number.) Using the "sysgen" command, select ON the "Nap device" entry. As you "q" out of sysgen, answer "y" to all questions, causing the new kernel to be built with the "Nap device" driver included. Execute the command "mknod /dev/ft c 28 0". Set permissions on it to allow its use. Users of nap() must have read permission on /dev/ft. It may be desirable to restrict access to this device. Once the system has been re-booted and the mknod command executed, the nap() function is ready for use. Included in this package is a program called "naptest" which takes as it's argument the number to be passed to nap(). If zero or more than one arguments are given to naptest, it will call nap with a default of 600. The ft driver attempts to ensure that the system resource it uses does not become exhausted. It does this by returning -1 with errno set to EBUSY if the number of available slots becomes "small". ("Small" is about 20 as delivered.) The resource is called the "callout table", and the number of slots in it is the NCALL tunable parameter in sysgen (default 50). If other drivers in your system cause more than about 15 callout table entries to be used sporadically, you must change the "20" in ft.c to a larger value, reserving more spare slots. This is not likely. The callout table can be examined by using the "callout" request within the "crash" command. Here is the synopsis of the nap() routine. ------- int nap(ticks) unsigned ticks; ------- The nap() call is similar to the sleep() call, documented in section 3C of the Programmer's Reference. There are some significant differences, though. 1) Processes that call nap() pass an argument which is the number of clock ticks to sleep, rather than the number of seconds. (The number of clock ticks per second is #defined as HZ in the file /usr/include/sys/param.h. On VME Delta systems, this is 60.) 2) Wakeups do not occur at fixed one-second intervals. They happen on the requested clock tick. 3) The process "napping" will not process *ANY* signals, including SIGKILL, until it leaves it's nap. 4) nap() has nothing to do with the use of the alarm(2) signal. Remember though, that SIGALRM will not be recognized until the nap is over. 5) nap() will return 0 if the nap took place. It will return -1 with errno set to EBUSY if the nap was not done. -------------------------------------------------- Choosing a Different Major Character Device Number -------------------------------------------------- This section is for those using OfficeLAN, since it is set up as Character Device number 28, as is the "ft" driver used by nap(). In the directory /usr/src/uts/m68k/cf, is a file named "conf.c". In this file, is the declaration: struct cdevsw cdevsw[] = { ... }; The initialization lines (represented above as "...") each begin with a number in comments, like /*28*/ and continue with names of driver routines that "belong to" that major device number. On systems where OfficeLAN has not been configured into the kernel, the line for major device 28 looks something like /*28*/ nodev, nodev, nodev, nodev, nodev, notty, nostr, If it does not, then you must either remove OfficeLAN from your configuration or find a line that *does* look similar to the above and choose that line's number to use. Remember to change the "ft" file in the "descriptions" directory to use the new number instead of "28" and to use the new number in the "mknod" command for the /dev/ft device. \Rogue\Monster\ else echo "will not over write ./README" fi if `test ! -s ./ft.c` then echo "writing ./ft.c" cat > ./ft.c << '\Rogue\Monster\' /* Written by Jon Zeeff umix!b-tech!zeeff Modified by Ron Heiby mcdchg!heiby 12/88 to protect against too many simultaneous calls causing a system panic from being out of callout table entries. A check is made to ensure that there is a fair buffer of free entries before making the call to delay(). If the test fails, we cause EBUSY to be returned. Also, deleted some unnecessary #include lines. This "device driver" uses the kernel delay() call to allow calls to nap() from user processes. Nap() is like sleep, but with finer resolution. */ #include <sys/types.h> #include <sys/signal.h> #include <sys/dir.h> #include <sys/user.h> #include <sys/errno.h> #include <sys/callo.h> #include <sys/var.h> /* use a raw device interface */ ftopen() {} ftread(dev) int dev; { if (callout[v.v_call-20].c_func) { u.u_error = EBUSY; return; } delay(u.u_count); u.u_count = 0; } ftclose() {} \Rogue\Monster\ else echo "will not over write ./ft.c" fi if `test ! -s ./makefile` then echo "writing ./makefile" cat > ./makefile << '\Rogue\Monster\' CFLAGS = -O -DINKERNEL all: lib.nap naptest naptest: nap.o naptest.o cc -o naptest naptest.o nap.o lib.nap: ft.o rm -f lib.nap ar r lib.nap ft.o \Rogue\Monster\ else echo "will not over write ./makefile" fi if `test ! -s ./nap.c` then echo "writing ./nap.c" cat > ./nap.c << '\Rogue\Monster\' /* User-level library function that makes use of the "ft" device to sleep after scheduling a clock callout event for "ticks" clock ticks into the future. Returns either 0 (success) or -1 (failure). Leaves errno alone (as set by the last system call). */ int nap(ticks) unsigned ticks; { static int fd=0; static int ret; if (fd == 0) fd = open("/dev/ft",0); ret = read(fd,(char *)0,ticks); return( (ret == -1) ? -1 : 0 ); } \Rogue\Monster\ else echo "will not over write ./nap.c" fi if `test ! -s ./naptest.c` then echo "writing ./naptest.c" cat > ./naptest.c << '\Rogue\Monster\' #include <sys/types.h> #include <time.h> #include <stdio.h> #include <errno.h> #define NAP_DEFAULT 600 main(argc, argv) int argc; char **argv; { time_t clock; unsigned nap_time; int nap_returns; if (argc == 2) { nap_time = atoi(argv[1]); } else { nap_time = NAP_DEFAULT; printf("Using default nap time of %d ticks.\n", nap_time); } clock = time(0); puts(ctime(&clock)); nap_returns = nap(nap_time); clock = time(0); puts(ctime(&clock)); printf("nap(%u) returned: %d. errno = %d.\n", nap_time, nap_returns, errno); exit(0); } \Rogue\Monster\ else echo "will not over write ./naptest.c" fi if `test ! -s ./sysgen.ft` then echo "writing ./sysgen.ft" cat > ./sysgen.ft << '\Rogue\Monster\' * ft * Description File: "Nap device" * * ft #1 * Board Description: "Nap device #1" Description Keyword: "ft #1" Device Type: "ft" Bus Request Level: 0 Address: 0 Interrupt Vector Location: 0 Default Number Of Devices: 0 * * ft * Device Description: "Nap device driver" Description Keyword: "ft" Device Name: "ft" Handler Prefix: "ft" Interrupt Vectors Size: 0 Major Block Device Number: 0 Major Character Device Number: 28 Maximum Bus Request Level: 0 Maximum Devices Per Controller: 1 Page Registers Size: 0 Block Or Character Device Handler Lines: Has an open handler. Has a close handler. Has a read handler. Device Type Information: Do not create an interrupt vector for this device. This is a character device. Device Configuration Tables Declarations: \Rogue\Monster\ else echo "will not over write ./sysgen.ft" fi echo "Finished archive 1 of 1" exit -- Ron Heiby, heiby@mcdchg.chi.il.us Moderator: comp.newprod "Life is indeed an inexplicable sequence of imponderable surprises."