122124Smckusick /* 239170Sbostic * Copyright (c) 1989 The Regents of the University of California. 339170Sbostic * All rights reserved. 439170Sbostic * 5*42628Sbostic * %sccs.include.redist.c% 622124Smckusick */ 722124Smckusick 826610Sdonn #if defined(LIBC_SCCS) && !defined(lint) 9*42628Sbostic static char sccsid[] = "@(#)usleep.c 5.5 (Berkeley) 06/01/90"; 1039170Sbostic #endif /* LIBC_SCCS and not lint */ 1118340Sserge 1218340Sserge #include <sys/time.h> 1339170Sbostic #include <sys/signal.h> 1418340Sserge 1539170Sbostic #define TICK 10000 /* system clock resolution in microseconds */ 1639170Sbostic #define USPS 1000000 /* number of microseconds in a second */ 1718340Sserge 1818340Sserge #define setvec(vec, a) \ 1918340Sserge vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0 2018340Sserge 2118340Sserge static int ringring; 2218340Sserge 2339170Sbostic usleep(useconds) 2439170Sbostic unsigned int useconds; 2518340Sserge { 2639170Sbostic register struct itimerval *itp; 2718340Sserge struct itimerval itv, oitv; 2818340Sserge struct sigvec vec, ovec; 2939170Sbostic long omask; 3039170Sbostic void sleephandler(); 3118340Sserge 3239170Sbostic itp = &itv; 3339170Sbostic if (!useconds) 3418340Sserge return; 3518340Sserge timerclear(&itp->it_interval); 3618340Sserge timerclear(&itp->it_value); 3718340Sserge if (setitimer(ITIMER_REAL, itp, &oitv) < 0) 3818340Sserge return; 3939170Sbostic itp->it_value.tv_sec = useconds / USPS; 4039170Sbostic itp->it_value.tv_usec = useconds % USPS; 4118340Sserge if (timerisset(&oitv.it_value)) { 4218340Sserge if (timercmp(&oitv.it_value, &itp->it_value, >)) { 4318340Sserge oitv.it_value.tv_sec -= itp->it_value.tv_sec; 4418340Sserge oitv.it_value.tv_usec -= itp->it_value.tv_usec; 4518340Sserge if (oitv.it_value.tv_usec < 0) { 4618340Sserge oitv.it_value.tv_usec += USPS; 4718340Sserge oitv.it_value.tv_sec--; 4818340Sserge } 4918340Sserge } else { 5018340Sserge itp->it_value = oitv.it_value; 5118340Sserge oitv.it_value.tv_sec = 0; 5218340Sserge oitv.it_value.tv_usec = 2 * TICK; 5318340Sserge } 5418340Sserge } 5539170Sbostic setvec(vec, sleephandler); 5618340Sserge (void) sigvec(SIGALRM, &vec, &ovec); 5718340Sserge omask = sigblock(sigmask(SIGALRM)); 5818340Sserge ringring = 0; 5918340Sserge (void) setitimer(ITIMER_REAL, itp, (struct itimerval *)0); 6018340Sserge while (!ringring) 6118340Sserge sigpause(omask &~ sigmask(SIGALRM)); 6218340Sserge (void) sigvec(SIGALRM, &ovec, (struct sigvec *)0); 6318340Sserge (void) sigsetmask(omask); 6418340Sserge (void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0); 6518340Sserge } 6618340Sserge 6739170Sbostic static void 6839170Sbostic sleephandler() 6918340Sserge { 7018340Sserge ringring = 1; 7118340Sserge } 72