1 /* 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #if defined(LIBC_SCCS) && !defined(lint) 9 static char sccsid[] = "@(#)usleep.c 5.5 (Berkeley) 06/01/90"; 10 #endif /* LIBC_SCCS and not lint */ 11 12 #include <sys/time.h> 13 #include <sys/signal.h> 14 15 #define TICK 10000 /* system clock resolution in microseconds */ 16 #define USPS 1000000 /* number of microseconds in a second */ 17 18 #define setvec(vec, a) \ 19 vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0 20 21 static int ringring; 22 23 usleep(useconds) 24 unsigned int useconds; 25 { 26 register struct itimerval *itp; 27 struct itimerval itv, oitv; 28 struct sigvec vec, ovec; 29 long omask; 30 void sleephandler(); 31 32 itp = &itv; 33 if (!useconds) 34 return; 35 timerclear(&itp->it_interval); 36 timerclear(&itp->it_value); 37 if (setitimer(ITIMER_REAL, itp, &oitv) < 0) 38 return; 39 itp->it_value.tv_sec = useconds / USPS; 40 itp->it_value.tv_usec = useconds % USPS; 41 if (timerisset(&oitv.it_value)) { 42 if (timercmp(&oitv.it_value, &itp->it_value, >)) { 43 oitv.it_value.tv_sec -= itp->it_value.tv_sec; 44 oitv.it_value.tv_usec -= itp->it_value.tv_usec; 45 if (oitv.it_value.tv_usec < 0) { 46 oitv.it_value.tv_usec += USPS; 47 oitv.it_value.tv_sec--; 48 } 49 } else { 50 itp->it_value = oitv.it_value; 51 oitv.it_value.tv_sec = 0; 52 oitv.it_value.tv_usec = 2 * TICK; 53 } 54 } 55 setvec(vec, sleephandler); 56 (void) sigvec(SIGALRM, &vec, &ovec); 57 omask = sigblock(sigmask(SIGALRM)); 58 ringring = 0; 59 (void) setitimer(ITIMER_REAL, itp, (struct itimerval *)0); 60 while (!ringring) 61 sigpause(omask &~ sigmask(SIGALRM)); 62 (void) sigvec(SIGALRM, &ovec, (struct sigvec *)0); 63 (void) sigsetmask(omask); 64 (void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0); 65 } 66 67 static void 68 sleephandler() 69 { 70 ringring = 1; 71 } 72