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