xref: /titanic_41/usr/src/lib/libbc/libc/gen/common/usleep.c (revision 8eea8e29cc4374d1ee24c25a07f45af132db3499)
1 /*
2  * Copyright 1996 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 #pragma ident	"%Z%%M%	%I%	%E% SMI"
7 	/* from UCB 5.1 85/06/05 */
8 
9 /*
10  * Copyright (c) 1985 Regents of the University of California.
11  * All rights reserved.  The Berkeley software License Agreement
12  * specifies the terms and conditions for redistribution.
13  */
14 
15 #include <unistd.h>
16 #include <sys/time.h>
17 #include <signal.h>
18 
19 #define	USPS	1000000		/* number of microseconds in a second */
20 #define	TICK	(USPS / _sysconf(_SC_CLK_TCK))
21 
22 #define	setvec(vec, a) \
23 	vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0
24 
25 static int ringring;
26 
27 usleep(n)
28 	unsigned n;
29 {
30 	static void sleepx();
31 	int omask;
32 	struct itimerval itv, oitv;
33 	register struct itimerval *itp = &itv;
34 	struct sigvec vec, ovec;
35 
36 	if (n == 0)
37 		return;
38 	timerclear(&itp->it_interval);
39 	timerclear(&itp->it_value);
40 	if (setitimer(ITIMER_REAL, itp, &oitv) < 0)
41 		return;
42 	itp->it_value.tv_sec = n / USPS;
43 	itp->it_value.tv_usec = n % USPS;
44 	if (timerisset(&oitv.it_value)) {
45 		if (timercmp(&oitv.it_value, &itp->it_value, >)) {
46 			oitv.it_value.tv_sec -= itp->it_value.tv_sec;
47 			oitv.it_value.tv_usec -= itp->it_value.tv_usec;
48 			if (oitv.it_value.tv_usec < 0) {
49 				oitv.it_value.tv_usec += USPS;
50 				oitv.it_value.tv_sec--;
51 			}
52 		} else {
53 			itp->it_value = oitv.it_value;
54 			oitv.it_value.tv_sec = 0;
55 			oitv.it_value.tv_usec = 2 * TICK;
56 		}
57 	}
58 	setvec(vec, sleepx);
59 	(void) sigvec(SIGALRM, &vec, &ovec);
60 	omask = sigblock(sigmask(SIGALRM));
61 	ringring = 0;
62 	(void) setitimer(ITIMER_REAL, itp, (struct itimerval *)0);
63 	while (!ringring)
64 		sigpause(omask &~ sigmask(SIGALRM));
65 	(void) sigvec(SIGALRM, &ovec, (struct sigvec *)0);
66 	(void) sigsetmask(omask);
67 	(void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0);
68 }
69 
70 static void
71 sleepx()
72 {
73 
74 	ringring = 1;
75 }
76