sleep.c revision 25870
11573Srgrimes/* 21573Srgrimes * Copyright (c) 1989, 1993 31573Srgrimes * The Regents of the University of California. All rights reserved. 41573Srgrimes * 51573Srgrimes * Redistribution and use in source and binary forms, with or without 61573Srgrimes * modification, are permitted provided that the following conditions 71573Srgrimes * are met: 81573Srgrimes * 1. Redistributions of source code must retain the above copyright 91573Srgrimes * notice, this list of conditions and the following disclaimer. 101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111573Srgrimes * notice, this list of conditions and the following disclaimer in the 121573Srgrimes * documentation and/or other materials provided with the distribution. 131573Srgrimes * 3. All advertising materials mentioning features or use of this software 141573Srgrimes * must display the following acknowledgement: 151573Srgrimes * This product includes software developed by the University of 161573Srgrimes * California, Berkeley and its contributors. 171573Srgrimes * 4. Neither the name of the University nor the names of its contributors 181573Srgrimes * may be used to endorse or promote products derived from this software 191573Srgrimes * without specific prior written permission. 201573Srgrimes * 211573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311573Srgrimes * SUCH DAMAGE. 321573Srgrimes */ 331573Srgrimes 341573Srgrimes#if defined(LIBC_SCCS) && !defined(lint) 351573Srgrimesstatic char sccsid[] = "@(#)sleep.c 8.1 (Berkeley) 6/4/93"; 361573Srgrimes#endif /* LIBC_SCCS and not lint */ 371573Srgrimes 381573Srgrimes#include <sys/time.h> 3911659Sphk#include <signal.h> 401573Srgrimes#include <unistd.h> 4125861Sache#ifdef _THREAD_SAFE 4225861Sache#include <pthread.h> 4325861Sache#include "pthread_private.h" 4425862Speter#endif 451573Srgrimes 4625862Speter#if !defined(_THREAD_SAFE) && !defined(USE_NANOSLEEP) 4725861Sache#define setvec(vec, a) \ 4825861Sache vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0 4925861Sache 5025861Sachestatic int ringring; 5125862Speter 5225862Speterstatic void 5325862Spetersleephandler() 5425862Speter{ 5525862Speter ringring = 1; 5625862Speter} 5725861Sache#endif 5825861Sache 591573Srgrimesunsigned int 601573Srgrimessleep(seconds) 611573Srgrimes unsigned int seconds; 621573Srgrimes{ 6325862Speter#if defined(_THREAD_SAFE) || defined(USE_NANOSLEEP) 6425862Speter struct timespec time_to_sleep; 6525862Speter struct timespec time_remaining; 6613545Sjulian 6725862Speter if (seconds != 0) { 6825862Speter time_to_sleep.tv_sec = seconds; 6925862Speter time_to_sleep.tv_nsec = 0; 7025862Speter nanosleep(&time_to_sleep, &time_remaining); 7125862Speter seconds = time_remaining.tv_sec; 7225870Speter if (time_remaining.tv_nsec > 0) 7325870Speter seconds++; /* round up */ 7425862Speter } 7525862Speter return (seconds); 7625861Sache#else 7725861Sache register struct itimerval *itp; 7825861Sache struct itimerval itv, oitv; 7925861Sache struct sigvec vec, ovec; 8025861Sache long omask; 8125861Sache static void sleephandler(); 8225861Sache 8325861Sache itp = &itv; 8425861Sache if (!seconds) 8525861Sache return 0; 8625861Sache timerclear(&itp->it_interval); 8725861Sache timerclear(&itp->it_value); 8825861Sache if (setitimer(ITIMER_REAL, itp, &oitv) < 0) 8925861Sache return seconds; 9025861Sache itp->it_value.tv_sec = seconds; 9125861Sache if (timerisset(&oitv.it_value)) { 9225861Sache if (timercmp(&oitv.it_value, &itp->it_value, >)) 9325861Sache oitv.it_value.tv_sec -= itp->it_value.tv_sec; 9425861Sache else { 9525861Sache itp->it_value = oitv.it_value; 9625861Sache /* 9725861Sache * This is a hack, but we must have time to return 9825861Sache * from the setitimer after the alarm or else it'll 9925861Sache * be restarted. And, anyway, sleep never did 10025861Sache * anything more than this before. 10125861Sache */ 10225861Sache oitv.it_value.tv_sec = 1; 10325861Sache oitv.it_value.tv_usec = 0; 10425861Sache } 1051573Srgrimes } 10625861Sache setvec(vec, sleephandler); 10725861Sache (void) sigvec(SIGALRM, &vec, &ovec); 10825861Sache omask = sigblock(sigmask(SIGALRM)); 10925861Sache ringring = 0; 11025861Sache (void) setitimer(ITIMER_REAL, itp, (struct itimerval *)0); 11125861Sache while (!ringring) 11225861Sache sigpause(omask &~ sigmask(SIGALRM)); 11325861Sache (void) sigvec(SIGALRM, &ovec, (struct sigvec *)0); 11425861Sache (void) sigsetmask(omask); 11525861Sache (void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0); 11625861Sache return 0; 11725861Sache#endif 1181573Srgrimes} 119