Xref: utzoo comp.lang.c:24615 comp.unix.questions:18528 Path: utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!zephyr.ens.tek.com!tekig5!tekig3!marc From: marc@tekig3.PEN.TEK.COM (Marc Frajola) Newsgroups: comp.lang.c,comp.unix.questions Subject: Re: sleep()ing less than a second Summary: source for nap() call under BSD Keywords: nap() function SysV BSD source Message-ID: <5235@tekig5.PEN.TEK.COM> Date: 19 Dec 89 23:40:54 GMT References: <89348.231211BACON@MTUS5.BITNET> <2754@servax0.essex.ac.uk> Sender: root@tekig5.PEN.TEK.COM Reply-To: marc@tekig3.PEN.TEK.COM (Marc Frajola) Followup-To: comp.unix.questions Organization: Tektronix, Inc., Beaverton, OR. Lines: 139 In article <2754@servax0.essex.ac.uk> peter@essex.ac.uk (Allott P) writes: >In article <89348.231211BACON@MTUS5.BITNET> BACON@MTUS5.BITNET (Jeffery Bacon) writes: >>Given sleep(arg); unsigned arg. Nothing new. >>But what if you want to sleep for less than one second, say, 0.5? > >It is possible to "sleep" for less than one second by doing a >selcect(.......) with an appropriate value in the timeval (5th param I think) >and with no channels to check (2nd through 4th params I think). >See the documentation for full details. Hi... Some time ago, I was posed with the problem of doing the equivalent of nap() on BSD. Since SysV had nap(), I decided to implement nap() with BSD primitives. I've used it in one of my programs for the last two years without problems (so it is SOMEWHAT tested). I distribute it in nap.c and only compile it on BSD systems; SysV already has nap() somewhere in a library. Following is my version of nap() -- please e-mail me if you make useful enhancements/changes... Bon Appetit! ...Marc... -- Marc Frajola, Tektronix Inc., Beaverton, OR Phone: (503) 627-4340 (Tek) or (503) 643-5203 (Home) InterNet-Style Address: marc@tekig3.PEN.TEK.COM UUCP: ..!tektronix.TEK.COM!tekig3.PEN.TEK.COM!marc (Tek - Lab Scopes) ..!tektronix.TEK.COM!tessi.UUCP!escargot!marc (Home System e-mail) ---------- Cut here for 'nap.shar' ------------------------------------- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # nap.c # This archive created: Tue Dec 19 15:39:41 1989 export PATH; PATH=/bin:$PATH echo shar: extracting "'nap.c'" '(2496 characters)' if test -f 'nap.c' then echo shar: will not over-write existing file "'nap.c'" else sed 's/^X//' << \SHAR_EOF > 'nap.c' X/* X * Implementation of System-V style nap() on BSD Unix (4.2 and after) X * X * Copyright (C) 1987, 1988, 1989 by Marc A. Frajola X * X * Permission to use, copy, modify, and distribute this software and X * its documentation for any purpose and without fee is hereby X * granted, provided that the above copyright notice appear in all X * copies and that both that copyright notice and this permission X * notice appear in supporting documentation. This software is X * provided "as is" without express or implied warranty. X * X * The nap() function under SysV may be implemented quite differently, X * but the idea here is to delay a specified number of milliseconds X * since sleep()'s granularity is only every second. X * X * This code is provided here is for BSD, and will function ONLY on a X * 4.2bsd or later UNIX system. X * X * WARNING: This function will blow away any previous alarm setting if X * the alarm() function uses setitimer(). X * X * By Marc A. Frajola, 08/20/87 X * X * $Header: nap.c,v 1.6 89/12/19 14:21:33 marc Exp $ X */ X X#include X#include X Xstatic int napwakeup(); /* Forward reference for wakeup function */ Xstatic int napdone; /* Flag if nap() call is done */ X X/* X * Function for emulating System-V like nap() behavior using BSD X * setitimer() X */ Xnap(msec) X int msec; /* Number of milliseconds to nap */ X{ X struct itimerval value; /* Timer value structure for setitimer() */ X long usec; /* Number of microseconds before alarm */ X int (*oldsig)(); /* Old signal condition */ X X /* Set the timer reload values for no followup SIGALRMs: */ X value.it_interval.tv_sec = 0; X value.it_interval.tv_usec = 0; X X /* Set the current timer for the desired number of milliseconds: */ X usec = msec * 1000; X value.it_value.tv_sec = msec / 1000; X value.it_value.tv_usec = usec % 1000000; X X /* X * Set the timer, done flags, and wakeup procedure: X */ X napdone = 0; X oldsig = signal(SIGALRM, napwakeup); X if (setitimer(ITIMER_REAL, &value, (struct itimerval *)0) < 0) { X perror("setitimer"); X return; X } X X /* Block the process until a SIGALRM comes in: */ X do { X pause(); X } while (napdone != 1); X X /* Reset signal() state back to original condition: */ X signal(SIGALRM, oldsig); X X return; X} X X/* X * This function only gets executed so that pause() will unblock the X * process. X */ Xstatic Xnapwakeup() X{ X /* Set flag so nap() knows the SIGALRM has actually come in: */ X napdone = 1; X X return; X} SHAR_EOF if test 2496 -ne "`wc -c < 'nap.c'`" then echo shar: error transmitting "'nap.c'" '(should have been 2496 characters)' fi fi # end of overwriting check # End of shell archive exit 0