Upgrade diffutils from 3.0 to 3.2 on the vendor branch
[dragonfly.git] / contrib / diffutils / lib / timespec.h
1 /* timespec -- System time interface
2
3    Copyright (C) 2000, 2002, 2004-2005, 2007, 2009-2011 Free Software
4    Foundation, Inc.
5
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.
10
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.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18
19 #if ! defined TIMESPEC_H
20 # define TIMESPEC_H
21
22 # include <time.h>
23
24 /* Return negative, zero, positive if A < B, A == B, A > B, respectively.
25
26    For each time stamp T, this code assumes that either:
27
28      * T.tv_nsec is in the range 0..999999999; or
29      * T.tv_sec corresponds to a valid leap second on a host that supports
30        leap seconds, and T.tv_nsec is in the range 1000000000..1999999999; or
31      * T.tv_sec is the minimum time_t value and T.tv_nsec is -1; or
32        T.tv_sec is the maximum time_t value and T.tv_nsec is 2000000000.
33        This allows for special struct timespec values that are less or
34        greater than all possible valid time stamps.
35
36    In all these cases, it is safe to subtract two tv_nsec values and
37    convert the result to integer without worrying about overflow on
38    any platform of interest to the GNU project, since all such
39    platforms have 32-bit int or wider.
40
41    Replacing "(int) (a.tv_nsec - b.tv_nsec)" with something like
42    "a.tv_nsec < b.tv_nsec ? -1 : a.tv_nsec > b.tv_nsec" would cause
43    this function to work in some cases where the above assumption is
44    violated, but not in all cases (e.g., a.tv_sec==1, a.tv_nsec==-2,
45    b.tv_sec==0, b.tv_nsec==999999999) and is arguably not worth the
46    extra instructions.  Using a subtraction has the advantage of
47    detecting some invalid cases on platforms that detect integer
48    overflow.
49
50    The (int) cast avoids a gcc -Wconversion warning.  */
51
52 static inline int
53 timespec_cmp (struct timespec a, struct timespec b)
54 {
55   return (a.tv_sec < b.tv_sec ? -1
56           : a.tv_sec > b.tv_sec ? 1
57           : (int) (a.tv_nsec - b.tv_nsec));
58 }
59
60 /* Return -1, 0, 1, depending on the sign of A.  A.tv_nsec must be
61    nonnegative.  */
62 static inline int
63 timespec_sign (struct timespec a)
64 {
65   return a.tv_sec < 0 ? -1 : a.tv_sec || a.tv_nsec;
66 }
67
68 struct timespec timespec_add (struct timespec, struct timespec);
69 struct timespec timespec_sub (struct timespec, struct timespec);
70 struct timespec dtotimespec (double);
71
72 /* Return an approximation to A, of type 'double'.  */
73 static inline double
74 timespectod (struct timespec a)
75 {
76   return a.tv_sec + a.tv_nsec / 1e9;
77 }
78
79 void gettime (struct timespec *);
80 int settime (struct timespec const *);
81
82 #endif