1*22124Smckusick /* 2*22124Smckusick * Copyright (c) 1985 Regents of the University of California. 3*22124Smckusick * All rights reserved. The Berkeley software License Agreement 4*22124Smckusick * specifies the terms and conditions for redistribution. 5*22124Smckusick */ 6*22124Smckusick 718340Sserge #ifndef lint 8*22124Smckusick static char sccsid[] = "@(#)usleep.c 5.1 (Berkeley) 06/05/85"; 9*22124Smckusick #endif not lint 1018340Sserge 1118340Sserge #include <sys/time.h> 1218340Sserge #include <signal.h> 1318340Sserge 1418340Sserge #define USPS 1000000 /* number of microseconds in a second */ 1518340Sserge #define TICK 10000 /* system clock resolution in microseconds */ 1618340Sserge 1718340Sserge #define setvec(vec, a) \ 1818340Sserge vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0 1918340Sserge 2018340Sserge static int ringring; 2118340Sserge 2218340Sserge usleep(n) 2318340Sserge unsigned n; 2418340Sserge { 2518340Sserge int sleepx(), omask; 2618340Sserge struct itimerval itv, oitv; 2718340Sserge register struct itimerval *itp = &itv; 2818340Sserge struct sigvec vec, ovec; 2918340Sserge 3018340Sserge if (n == 0) 3118340Sserge return; 3218340Sserge timerclear(&itp->it_interval); 3318340Sserge timerclear(&itp->it_value); 3418340Sserge if (setitimer(ITIMER_REAL, itp, &oitv) < 0) 3518340Sserge return; 3618340Sserge itp->it_value.tv_sec = n / USPS; 3718340Sserge itp->it_value.tv_usec = n % USPS; 3818340Sserge if (timerisset(&oitv.it_value)) { 3918340Sserge if (timercmp(&oitv.it_value, &itp->it_value, >)) { 4018340Sserge oitv.it_value.tv_sec -= itp->it_value.tv_sec; 4118340Sserge oitv.it_value.tv_usec -= itp->it_value.tv_usec; 4218340Sserge if (oitv.it_value.tv_usec < 0) { 4318340Sserge oitv.it_value.tv_usec += USPS; 4418340Sserge oitv.it_value.tv_sec--; 4518340Sserge } 4618340Sserge } else { 4718340Sserge itp->it_value = oitv.it_value; 4818340Sserge oitv.it_value.tv_sec = 0; 4918340Sserge oitv.it_value.tv_usec = 2 * TICK; 5018340Sserge } 5118340Sserge } 5218340Sserge setvec(vec, sleepx); 5318340Sserge (void) sigvec(SIGALRM, &vec, &ovec); 5418340Sserge omask = sigblock(sigmask(SIGALRM)); 5518340Sserge ringring = 0; 5618340Sserge (void) setitimer(ITIMER_REAL, itp, (struct itimerval *)0); 5718340Sserge while (!ringring) 5818340Sserge sigpause(omask &~ sigmask(SIGALRM)); 5918340Sserge (void) sigvec(SIGALRM, &ovec, (struct sigvec *)0); 6018340Sserge (void) sigsetmask(omask); 6118340Sserge (void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0); 6218340Sserge } 6318340Sserge 6418340Sserge static 6518340Sserge sleepx() 6618340Sserge { 6718340Sserge 6818340Sserge ringring = 1; 6918340Sserge } 70