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