usleep.c revision 13545
118334Speter/* 218334Speter * Copyright (c) 1989, 1993 318334Speter * The Regents of the University of California. All rights reserved. 418334Speter * 518334Speter * Redistribution and use in source and binary forms, with or without 618334Speter * modification, are permitted provided that the following conditions 718334Speter * are met: 818334Speter * 1. Redistributions of source code must retain the above copyright 918334Speter * notice, this list of conditions and the following disclaimer. 1018334Speter * 2. Redistributions in binary form must reproduce the above copyright 1118334Speter * notice, this list of conditions and the following disclaimer in the 1218334Speter * documentation and/or other materials provided with the distribution. 1318334Speter * 3. All advertising materials mentioning features or use of this software 1418334Speter * must display the following acknowledgement: 1518334Speter * This product includes software developed by the University of 1618334Speter * California, Berkeley and its contributors. 1718334Speter * 4. Neither the name of the University nor the names of its contributors 1818334Speter * may be used to endorse or promote products derived from this software 1918334Speter * without specific prior written permission. 2018334Speter * 2118334Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2218334Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2318334Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2418334Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2518334Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2618334Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2718334Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2818334Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2918334Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3018334Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3150397Sobrien * SUCH DAMAGE. 3218334Speter */ 3318334Speter 3418334Speter#if defined(LIBC_SCCS) && !defined(lint) 3518334Speterstatic char sccsid[] = "@(#)usleep.c 8.1 (Berkeley) 6/4/93"; 3618334Speter#endif /* LIBC_SCCS and not lint */ 3718334Speter 3818334Speter#include <sys/time.h> 3918334Speter#include <signal.h> 4018334Speter#include <unistd.h> 4118334Speter#ifdef _THREAD_SAFE 4218334Speter#include <pthread.h> 4318334Speter#include "pthread_private.h" 4418334Speter#else 4518334Speter#define TICK 10000 /* system clock resolution in microseconds */ 4618334Speter#define USPS 1000000 /* number of microseconds in a second */ 4718334Speter 4818334Speter#define setvec(vec, a) \ 4918334Speter vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0 5018334Speter 5118334Speterstatic int ringring; 5218334Speter#endif 5318334Speter 5418334Speter 5518334Spetervoid 5618334Speterusleep(useconds) 5718334Speter unsigned int useconds; 5818334Speter{ 5918334Speter#ifdef _THREAD_SAFE 6018334Speter struct timespec time_to_sleep; 6118334Speter 6218334Speter if (useconds) { 6318334Speter time_to_sleep.ts_nsec = (useconds % 1000000) * 1000; 6418334Speter time_to_sleep.ts_sec = useconds / 1000000; 6518334Speter nanosleep(&time_to_sleep,NULL); 6618334Speter } 6718334Speter#else 6818334Speter register struct itimerval *itp; 6918334Speter struct itimerval itv, oitv; 7018334Speter struct sigvec vec, ovec; 7118334Speter long omask; 7218334Speter static void sleephandler(); 7318334Speter 7418334Speter itp = &itv; 7518334Speter if (!useconds) 7618334Speter return; 7718334Speter timerclear(&itp->it_interval); 7818334Speter timerclear(&itp->it_value); 7918334Speter if (setitimer(ITIMER_REAL, itp, &oitv) < 0) 8018334Speter return; 8118334Speter itp->it_value.tv_sec = useconds / USPS; 8218334Speter itp->it_value.tv_usec = useconds % USPS; 8318334Speter if (timerisset(&oitv.it_value)) { 8418334Speter if (timercmp(&oitv.it_value, &itp->it_value, >)) { 8518334Speter oitv.it_value.tv_sec -= itp->it_value.tv_sec; 8618334Speter oitv.it_value.tv_usec -= itp->it_value.tv_usec; 8718334Speter if (oitv.it_value.tv_usec < 0) { 8818334Speter oitv.it_value.tv_usec += USPS; 8918334Speter oitv.it_value.tv_sec--; 9018334Speter } 9118334Speter } else { 9218334Speter itp->it_value = oitv.it_value; 9318334Speter oitv.it_value.tv_sec = 0; 9418334Speter oitv.it_value.tv_usec = 2 * TICK; 9518334Speter } 9618334Speter } 9718334Speter setvec(vec, sleephandler); 98 (void) sigvec(SIGALRM, &vec, &ovec); 99 omask = sigblock(sigmask(SIGALRM)); 100 ringring = 0; 101 (void) setitimer(ITIMER_REAL, itp, (struct itimerval *)0); 102 while (!ringring) 103 sigpause(omask &~ sigmask(SIGALRM)); 104 (void) sigvec(SIGALRM, &ovec, (struct sigvec *)0); 105 (void) sigsetmask(omask); 106 (void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0); 107#endif 108} 109 110#ifndef _THREAD_SAFE 111static void 112sleephandler() 113{ 114 ringring = 1; 115} 116#endif 117