time: use timespec instead of timeval.
[ccan] / ccan / time / time.h
1 /* Licensed under BSD-MIT - see LICENSE file for details */
2 #ifndef CCAN_TIME_H
3 #define CCAN_TIME_H
4 #include "config.h"
5 #include <sys/time.h>
6 #if HAVE_STRUCT_TIMESPEC
7 #include <time.h>
8 #else
9 struct timespec {
10         time_t   tv_sec;        /* seconds */
11         long     tv_nsec;       /* nanoseconds */
12 };
13 #endif
14 #include <stdint.h>
15 #include <stdbool.h>
16
17 /**
18  * time_now - return the current time
19  *
20  * Example:
21  *      printf("Now is %lu seconds since epoch\n", (long)time_now().tv_sec);
22  */
23 struct timespec time_now(void);
24
25 /**
26  * time_greater - is a after b?
27  * @a: one time.
28  * @b: another time.
29  *
30  * Example:
31  *      static bool timed_out(const struct timespec *start)
32  *      {
33  *      #define TIMEOUT time_from_msec(1000)
34  *              return time_greater(time_now(), time_add(*start, TIMEOUT));
35  *      }
36  */
37 bool time_greater(struct timespec a, struct timespec b);
38
39 /**
40  * time_less - is a before b?
41  * @a: one time.
42  * @b: another time.
43  *
44  * Example:
45  *      static bool still_valid(const struct timespec *start)
46  *      {
47  *      #define TIMEOUT time_from_msec(1000)
48  *              return time_less(time_now(), time_add(*start, TIMEOUT));
49  *      }
50  */
51 bool time_less(struct timespec a, struct timespec b);
52
53 /**
54  * time_eq - is a equal to b?
55  * @a: one time.
56  * @b: another time.
57  *
58  * Example:
59  *      #include <sys/types.h>
60  *      #include <sys/wait.h>
61  *
62  *      // Can we fork in under a microsecond?
63  *      static bool fast_fork(void)
64  *      {
65  *              struct timespec start = time_now();
66  *              if (fork() != 0) {
67  *                      exit(0);
68  *              }
69  *              wait(NULL);
70  *              return time_eq(start, time_now());
71  *      }
72  */
73 bool time_eq(struct timespec a, struct timespec b);
74
75 /**
76  * time_sub - subtract two times
77  * @recent: the larger (more recent) time.
78  * @old: the smaller (less recent) time.
79  *
80  * This returns a well formed struct timespec.
81  *
82  * Example:
83  *      static bool was_recent(const struct timespec *start)
84  *      {
85  *              return time_sub(time_now(), *start).tv_sec < 1;
86  *      }
87  */
88 struct timespec time_sub(struct timespec recent, struct timespec old);
89
90 /**
91  * time_add - add two times
92  * @a: one time.
93  * @b: another time.
94  *
95  * The times must not overflow, or the results are undefined.
96  *
97  * Example:
98  *      // We do one every second.
99  *      static struct timespec next_time(void)
100  *      {
101  *              return time_add(time_now(), time_from_msec(1000));
102  *      }
103  */
104 struct timespec time_add(struct timespec a, struct timespec b);
105
106 /**
107  * time_divide - divide a time by a value.
108  * @t: a time.
109  * @div: number to divide it by.
110  *
111  * Example:
112  *      // How long does it take to do a fork?
113  *      static struct timespec forking_time(void)
114  *      {
115  *              struct timespec start = time_now();
116  *              unsigned int i;
117  *
118  *              for (i = 0; i < 1000; i++) {
119  *                      if (fork() != 0) {
120  *                              exit(0);
121  *                      }
122  *                      wait(NULL);
123  *              }
124  *              return time_divide(time_sub(time_now(), start), i);
125  *      }
126  */
127 struct timespec time_divide(struct timespec t, unsigned long div);
128
129 /**
130  * time_multiply - multiply a time by a value.
131  * @t: a time.
132  * @mult: number to multiply it by.
133  *
134  * Example:
135  *      ...
136  *      printf("Time to do 100000 forks would be %u sec\n",
137  *             (unsigned)time_multiply(forking_time(), 1000000).tv_sec);
138  */
139 struct timespec time_multiply(struct timespec t, unsigned long mult);
140
141 /**
142  * time_to_msec - return number of milliseconds
143  * @t: a time
144  *
145  * It's often more convenient to deal with time values as
146  * milliseconds.  Note that this will fit into a 32-bit variable if
147  * it's a time difference of less than ~7 weeks.
148  *
149  * Example:
150  *      ...
151  *      printf("Forking time is %u msec\n",
152  *             (unsigned)time_to_msec(forking_time()));
153  */
154 uint64_t time_to_msec(struct timespec t);
155
156 /**
157  * time_to_usec - return number of microseconds
158  * @t: a time
159  *
160  * It's often more convenient to deal with time values as
161  * microseconds.  Note that this will fit into a 32-bit variable if
162  * it's a time difference of less than ~1 hour.
163  *
164  * Example:
165  *      ...
166  *      printf("Forking time is %u usec\n",
167  *             (unsigned)time_to_usec(forking_time()));
168  *
169  */
170 uint64_t time_to_usec(struct timespec t);
171
172 /**
173  * time_to_nsec - return number of nanoseconds
174  * @t: a time
175  *
176  * It's sometimes more convenient to deal with time values as
177  * nanoseconds.  Note that this will fit into a 32-bit variable if
178  * it's a time difference of less than ~4 seconds.
179  *
180  * Example:
181  *      ...
182  *      printf("Forking time is %u nsec\n",
183  *             (unsigned)time_to_nsec(forking_time()));
184  *
185  */
186 uint64_t time_to_nsec(struct timespec t);
187
188 /**
189  * time_from_msec - convert milliseconds to a timespec
190  * @msec: time in milliseconds
191  *
192  * Example:
193  *      // 1/2 second timeout
194  *      #define TIMEOUT time_from_msec(500)
195  */
196 struct timespec time_from_msec(uint64_t msec);
197
198 /**
199  * time_from_usec - convert microseconds to a timespec
200  * @usec: time in microseconds
201  *
202  * Example:
203  *      // 1/2 second timeout
204  *      #define TIMEOUT time_from_usec(500000)
205  */
206 struct timespec time_from_usec(uint64_t usec);
207
208 /**
209  * time_from_nsec - convert nanoseconds to a timespec
210  * @nsec: time in nanoseconds
211  *
212  * Example:
213  *      // 1/2 second timeout
214  *      #define TIMEOUT time_from_nsec(500000000)
215  */
216 struct timespec time_from_nsec(uint64_t nsec);
217
218 /**
219  * timespec_to_timeval - convert a timespec to a timeval.
220  * @ts: a timespec.
221  *
222  * Example:
223  *      struct timeval tv;
224  *
225  *      tv = timespec_to_timeval(time_now());
226  */
227 static inline struct timeval timespec_to_timeval(struct timespec ts)
228 {
229         struct timeval tv;
230         tv.tv_sec = ts.tv_sec;
231         tv.tv_usec = ts.tv_nsec / 1000;
232         return tv;
233 }
234
235 /**
236  * timeval_to_timespec - convert a timeval to a timespec.
237  * @tv: a timeval.
238  *
239  * Example:
240  *      struct timeval tv = { 0, 500 };
241  *      struct timespec ts;
242  *
243  *      ts = timeval_to_timespec(tv);
244  */
245 static inline struct timespec timeval_to_timespec(struct timeval tv)
246 {
247         struct timespec ts;
248         ts.tv_sec = tv.tv_sec;
249         ts.tv_nsec = tv.tv_usec * 1000;
250         return ts;
251 }
252 #endif /* CCAN_TIME_H */