1 /* timespec -- System time interface
3 Copyright (C) 2000, 2002, 2004-2005, 2007, 2009-2017 Free Software
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <https://www.gnu.org/licenses/>. */
19 #if ! defined TIMESPEC_H
24 #ifndef _GL_INLINE_HEADER_BEGIN
25 #error "Please include config.h first."
27 _GL_INLINE_HEADER_BEGIN
28 #ifndef _GL_TIMESPEC_INLINE
29 # define _GL_TIMESPEC_INLINE _GL_INLINE
36 /* Resolution of timespec timestamps (in units per second), and log
37 base 10 of the resolution. */
39 enum { TIMESPEC_RESOLUTION
= 1000000000 };
40 enum { LOG10_TIMESPEC_RESOLUTION
= 9 };
42 /* Return a timespec with seconds S and nanoseconds NS. */
44 _GL_TIMESPEC_INLINE
struct timespec
45 make_timespec (time_t s
, long int ns
)
53 /* Return negative, zero, positive if A < B, A == B, A > B, respectively.
55 For each timestamp T, this code assumes that either:
57 * T.tv_nsec is in the range 0..999999999; or
58 * T.tv_sec corresponds to a valid leap second on a host that supports
59 leap seconds, and T.tv_nsec is in the range 1000000000..1999999999; or
60 * T.tv_sec is the minimum time_t value and T.tv_nsec is -1; or
61 T.tv_sec is the maximum time_t value and T.tv_nsec is 2000000000.
62 This allows for special struct timespec values that are less or
63 greater than all possible valid timestamps.
65 In all these cases, it is safe to subtract two tv_nsec values and
66 convert the result to integer without worrying about overflow on
67 any platform of interest to the GNU project, since all such
68 platforms have 32-bit int or wider.
70 Replacing "(int) (a.tv_nsec - b.tv_nsec)" with something like
71 "a.tv_nsec < b.tv_nsec ? -1 : a.tv_nsec > b.tv_nsec" would cause
72 this function to work in some cases where the above assumption is
73 violated, but not in all cases (e.g., a.tv_sec==1, a.tv_nsec==-2,
74 b.tv_sec==0, b.tv_nsec==999999999) and is arguably not worth the
75 extra instructions. Using a subtraction has the advantage of
76 detecting some invalid cases on platforms that detect integer
79 The (int) cast avoids a gcc -Wconversion warning. */
81 _GL_TIMESPEC_INLINE
int _GL_ATTRIBUTE_PURE
82 timespec_cmp (struct timespec a
, struct timespec b
)
84 return (a
.tv_sec
< b
.tv_sec
? -1
85 : a
.tv_sec
> b
.tv_sec
? 1
86 : (int) (a
.tv_nsec
- b
.tv_nsec
));
89 /* Return -1, 0, 1, depending on the sign of A. A.tv_nsec must be
91 _GL_TIMESPEC_INLINE
int _GL_ATTRIBUTE_PURE
92 timespec_sign (struct timespec a
)
94 return a
.tv_sec
< 0 ? -1 : a
.tv_sec
|| a
.tv_nsec
;
97 struct timespec
timespec_add (struct timespec
, struct timespec
)
99 struct timespec
timespec_sub (struct timespec
, struct timespec
)
101 struct timespec
dtotimespec (double)
104 /* Return an approximation to A, of type 'double'. */
105 _GL_TIMESPEC_INLINE
double
106 timespectod (struct timespec a
)
108 return a
.tv_sec
+ a
.tv_nsec
/ 1e9
;
111 void gettime (struct timespec
*);
112 int settime (struct timespec
const *);
118 _GL_INLINE_HEADER_END