1/***********************************************************************
2*                                                                      *
3*               This software is part of the ast package               *
4*          Copyright (c) 1985-2011 AT&T Intellectual Property          *
5*                      and is licensed under the                       *
6*                  Common Public License, Version 1.0                  *
7*                    by AT&T Intellectual Property                     *
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
54int
55tvsleep(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