Commit | Line | Data |
---|---|---|
b8f253e8 | 1 | /* |
dc51c380 KB |
2 | * Copyright (c) 1989 The Regents of the University of California. |
3 | * All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms are permitted | |
6 | * provided that the above copyright notice and this paragraph are | |
7 | * duplicated in all such forms and that any documentation, | |
8 | * advertising materials, and other materials related to such | |
9 | * distribution and use acknowledge that the software was developed | |
10 | * by the University of California, Berkeley. The name of the | |
11 | * University may not be used to endorse or promote products derived | |
12 | * from this software without specific prior written permission. | |
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | |
14 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | |
15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
b8f253e8 KM |
16 | */ |
17 | ||
2ce81398 | 18 | #if defined(LIBC_SCCS) && !defined(lint) |
dc51c380 KB |
19 | static char sccsid[] = "@(#)usleep.c 5.4 (Berkeley) %G%"; |
20 | #endif /* LIBC_SCCS and not lint */ | |
c75c7775 S |
21 | |
22 | #include <sys/time.h> | |
dc51c380 | 23 | #include <sys/signal.h> |
c75c7775 | 24 | |
dc51c380 KB |
25 | #define TICK 10000 /* system clock resolution in microseconds */ |
26 | #define USPS 1000000 /* number of microseconds in a second */ | |
c75c7775 S |
27 | |
28 | #define setvec(vec, a) \ | |
29 | vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0 | |
30 | ||
31 | static int ringring; | |
32 | ||
dc51c380 KB |
33 | usleep(useconds) |
34 | unsigned int useconds; | |
c75c7775 | 35 | { |
dc51c380 | 36 | register struct itimerval *itp; |
c75c7775 | 37 | struct itimerval itv, oitv; |
c75c7775 | 38 | struct sigvec vec, ovec; |
dc51c380 KB |
39 | long omask; |
40 | void sleephandler(); | |
c75c7775 | 41 | |
dc51c380 KB |
42 | itp = &itv; |
43 | if (!useconds) | |
c75c7775 S |
44 | return; |
45 | timerclear(&itp->it_interval); | |
46 | timerclear(&itp->it_value); | |
47 | if (setitimer(ITIMER_REAL, itp, &oitv) < 0) | |
48 | return; | |
dc51c380 KB |
49 | itp->it_value.tv_sec = useconds / USPS; |
50 | itp->it_value.tv_usec = useconds % USPS; | |
c75c7775 S |
51 | if (timerisset(&oitv.it_value)) { |
52 | if (timercmp(&oitv.it_value, &itp->it_value, >)) { | |
53 | oitv.it_value.tv_sec -= itp->it_value.tv_sec; | |
54 | oitv.it_value.tv_usec -= itp->it_value.tv_usec; | |
55 | if (oitv.it_value.tv_usec < 0) { | |
56 | oitv.it_value.tv_usec += USPS; | |
57 | oitv.it_value.tv_sec--; | |
58 | } | |
59 | } else { | |
60 | itp->it_value = oitv.it_value; | |
61 | oitv.it_value.tv_sec = 0; | |
62 | oitv.it_value.tv_usec = 2 * TICK; | |
63 | } | |
64 | } | |
dc51c380 | 65 | setvec(vec, sleephandler); |
c75c7775 S |
66 | (void) sigvec(SIGALRM, &vec, &ovec); |
67 | omask = sigblock(sigmask(SIGALRM)); | |
68 | ringring = 0; | |
69 | (void) setitimer(ITIMER_REAL, itp, (struct itimerval *)0); | |
70 | while (!ringring) | |
71 | sigpause(omask &~ sigmask(SIGALRM)); | |
72 | (void) sigvec(SIGALRM, &ovec, (struct sigvec *)0); | |
73 | (void) sigsetmask(omask); | |
74 | (void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0); | |
75 | } | |
76 | ||
dc51c380 KB |
77 | static void |
78 | sleephandler() | |
c75c7775 | 79 | { |
c75c7775 S |
80 | ringring = 1; |
81 | } |