xref: /titanic_51/usr/src/lib/libast/common/tm/tvsleep.c (revision 32885d593baf8bac788fa78885893a51b3ad0f28)
1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *           Copyright (c) 1985-2007 AT&T Knowledge Ventures            *
5 *                      and is licensed under the                       *
6 *                  Common Public License, Version 1.0                  *
7 *                      by AT&T Knowledge Ventures                      *
8 *                                                                      *
9 *                A copy of the License is available at                 *
10 *            http://www.opensource.org/licenses/cpl1.0.txt             *
11 *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12 *                                                                      *
13 *              Information and Software Systems Research               *
14 *                            AT&T Research                             *
15 *                           Florham Park NJ                            *
16 *                                                                      *
17 *                 Glenn Fowler <gsf@research.att.com>                  *
18 *                  David Korn <dgk@research.att.com>                   *
19 *                   Phong Vo <kpv@research.att.com>                    *
20 *                                                                      *
21 ***********************************************************************/
22 #pragma prototyped
23 
24 #include <tv.h>
25 #include <tm.h>
26 
27 #include "FEATURE/tvlib"
28 
29 #if !_lib_nanosleep
30 # if _lib_select
31 #  if _sys_select
32 #   include <sys/select.h>
33 #  else
34 #   include <sys/socket.h>
35 #  endif
36 # else
37 #  if !_lib_usleep
38 #   if _lib_poll_notimer
39 #    undef _lib_poll
40 #   endif
41 #   if _lib_poll
42 #    include <poll.h>
43 #   endif
44 #  endif
45 # endif
46 #endif
47 
48 /*
49  * sleep for tv
50  * non-zero exit if sleep did not complete
51  * with remaining time in rv
52  */
53 
54 int
55 tvsleep(register const Tv_t* tv, register Tv_t* rv)
56 {
57 
58 #if _lib_nanosleep
59 
60 	struct timespec	stv;
61 	struct timespec	srv;
62 	int		r;
63 
64 	stv.tv_sec = tv->tv_sec;
65 	stv.tv_nsec = tv->tv_nsec;
66 	if ((r = nanosleep(&stv, &srv)) && rv)
67 	{
68 		rv->tv_sec = srv.tv_sec;
69 		rv->tv_nsec = srv.tv_nsec;
70 	}
71 	return r;
72 
73 #else
74 
75 #if _lib_select
76 
77 	struct timeval	stv;
78 
79 	stv.tv_sec = tv->tv_sec;
80 	stv.tv_usec = tv->tv_nsec / 1000;
81 	if (select(0, NiL, NiL, NiL, &stv) < 0)
82 	{
83 		if (rv)
84 			*rv = *tv;
85 		return -1;
86 	}
87 	if (rv)
88 	{
89 		rv->tv_sec = stv.tv_sec;
90 		rv->tv_nsec = stv.tv_usec * 1000;
91 	}
92 	return 0;
93 
94 #else
95 
96 	unsigned int		s = tv->tv_sec;
97 	uint32_t		n = tv->tv_nsec;
98 
99 #if _lib_usleep
100 
101 
102 	unsigned long		t;
103 
104 	if (t = (n + 999L) / 1000L)
105 	{
106 		usleep(t);
107 		s -= t / 1000000L;
108 		n = 0;
109 	}
110 
111 #else
112 
113 #if _lib_poll
114 
115 	struct pollfd		pfd;
116 	int			t;
117 
118 	if ((t = (n + 999999L) / 1000000L) > 0)
119 	{
120 		poll(&pfd, 0, t);
121 		s -= t / 1000L;
122 		n = 0;
123 	}
124 
125 #endif
126 
127 #endif
128 
129 	if ((s += (n + 999999999L) / 1000000000L) && (s = sleep(s)))
130 	{
131 		if (rv)
132 		{
133 			rv->tv_sec = s;
134 			rv->tv_nsec = 0;
135 		}
136 		return -1;
137 	}
138 	return 0;
139 
140 #endif
141 
142 #endif
143 
144 }
145