1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#ifndef _LINUX_KTIME_H
22#define _LINUX_KTIME_H
23
24#include <linux/time.h>
25#include <linux/jiffies.h>
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46union ktime {
47 s64 tv64;
48#if BITS_PER_LONG != 64 && !defined(CONFIG_KTIME_SCALAR)
49 struct {
50# ifdef __BIG_ENDIAN
51 s32 sec, nsec;
52# else
53 s32 nsec, sec;
54# endif
55 } tv;
56#endif
57};
58
59typedef union ktime ktime_t;
60
61#define KTIME_MAX ((s64)~((u64)1 << 63))
62#if (BITS_PER_LONG == 64)
63# define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC)
64#else
65# define KTIME_SEC_MAX LONG_MAX
66#endif
67
68
69
70
71
72#if (BITS_PER_LONG == 64) || defined(CONFIG_KTIME_SCALAR)
73
74
75
76
77
78
79
80
81static inline ktime_t ktime_set(const long secs, const unsigned long nsecs)
82{
83#if (BITS_PER_LONG == 64)
84 if (unlikely(secs >= KTIME_SEC_MAX))
85 return (ktime_t){ .tv64 = KTIME_MAX };
86#endif
87 return (ktime_t) { .tv64 = (s64)secs * NSEC_PER_SEC + (s64)nsecs };
88}
89
90
91#define ktime_sub(lhs, rhs) \
92 ({ (ktime_t){ .tv64 = (lhs).tv64 - (rhs).tv64 }; })
93
94
95#define ktime_add(lhs, rhs) \
96 ({ (ktime_t){ .tv64 = (lhs).tv64 + (rhs).tv64 }; })
97
98
99
100
101
102#define ktime_add_ns(kt, nsval) \
103 ({ (ktime_t){ .tv64 = (kt).tv64 + (nsval) }; })
104
105
106
107
108
109#define ktime_sub_ns(kt, nsval) \
110 ({ (ktime_t){ .tv64 = (kt).tv64 - (nsval) }; })
111
112
113static inline ktime_t timespec_to_ktime(struct timespec ts)
114{
115 return ktime_set(ts.tv_sec, ts.tv_nsec);
116}
117
118
119static inline ktime_t timeval_to_ktime(struct timeval tv)
120{
121 return ktime_set(tv.tv_sec, tv.tv_usec * NSEC_PER_USEC);
122}
123
124
125#define ktime_to_timespec(kt) ns_to_timespec((kt).tv64)
126
127
128#define ktime_to_timeval(kt) ns_to_timeval((kt).tv64)
129
130
131#define ktime_to_ns(kt) ((kt).tv64)
132
133#else
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151static inline ktime_t ktime_set(const long secs, const unsigned long nsecs)
152{
153 return (ktime_t) { .tv = { .sec = secs, .nsec = nsecs } };
154}
155
156
157
158
159
160
161
162
163static inline ktime_t ktime_sub(const ktime_t lhs, const ktime_t rhs)
164{
165 ktime_t res;
166
167 res.tv64 = lhs.tv64 - rhs.tv64;
168 if (res.tv.nsec < 0)
169 res.tv.nsec += NSEC_PER_SEC;
170
171 return res;
172}
173
174
175
176
177
178
179
180
181static inline ktime_t ktime_add(const ktime_t add1, const ktime_t add2)
182{
183 ktime_t res;
184
185 res.tv64 = add1.tv64 + add2.tv64;
186
187
188
189
190
191
192
193
194 if (res.tv.nsec >= NSEC_PER_SEC)
195 res.tv64 += (u32)-NSEC_PER_SEC;
196
197 return res;
198}
199
200
201
202
203
204
205
206
207extern ktime_t ktime_add_ns(const ktime_t kt, u64 nsec);
208
209
210
211
212
213
214
215
216extern ktime_t ktime_sub_ns(const ktime_t kt, u64 nsec);
217
218
219
220
221
222
223
224static inline ktime_t timespec_to_ktime(const struct timespec ts)
225{
226 return (ktime_t) { .tv = { .sec = (s32)ts.tv_sec,
227 .nsec = (s32)ts.tv_nsec } };
228}
229
230
231
232
233
234
235
236static inline ktime_t timeval_to_ktime(const struct timeval tv)
237{
238 return (ktime_t) { .tv = { .sec = (s32)tv.tv_sec,
239 .nsec = (s32)tv.tv_usec * 1000 } };
240}
241
242
243
244
245
246
247
248static inline struct timespec ktime_to_timespec(const ktime_t kt)
249{
250 return (struct timespec) { .tv_sec = (time_t) kt.tv.sec,
251 .tv_nsec = (long) kt.tv.nsec };
252}
253
254
255
256
257
258
259
260static inline struct timeval ktime_to_timeval(const ktime_t kt)
261{
262 return (struct timeval) {
263 .tv_sec = (time_t) kt.tv.sec,
264 .tv_usec = (suseconds_t) (kt.tv.nsec / NSEC_PER_USEC) };
265}
266
267
268
269
270
271
272
273static inline s64 ktime_to_ns(const ktime_t kt)
274{
275 return (s64) kt.tv.sec * NSEC_PER_SEC + kt.tv.nsec;
276}
277
278#endif
279
280
281
282
283
284
285
286
287static inline int ktime_equal(const ktime_t cmp1, const ktime_t cmp2)
288{
289 return cmp1.tv64 == cmp2.tv64;
290}
291
292static inline s64 ktime_to_us(const ktime_t kt)
293{
294 struct timeval tv = ktime_to_timeval(kt);
295 return (s64) tv.tv_sec * USEC_PER_SEC + tv.tv_usec;
296}
297
298static inline s64 ktime_to_ms(const ktime_t kt)
299{
300 struct timeval tv = ktime_to_timeval(kt);
301 return (s64) tv.tv_sec * MSEC_PER_SEC + tv.tv_usec / USEC_PER_MSEC;
302}
303
304static inline s64 ktime_us_delta(const ktime_t later, const ktime_t earlier)
305{
306 return ktime_to_us(ktime_sub(later, earlier));
307}
308
309static inline ktime_t ktime_add_us(const ktime_t kt, const u64 usec)
310{
311 return ktime_add_ns(kt, usec * 1000);
312}
313
314static inline ktime_t ktime_sub_us(const ktime_t kt, const u64 usec)
315{
316 return ktime_sub_ns(kt, usec * 1000);
317}
318
319extern ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs);
320
321
322
323
324
325
326
327#define LOW_RES_NSEC TICK_NSEC
328#define KTIME_LOW_RES (ktime_t){ .tv64 = LOW_RES_NSEC }
329
330
331extern void ktime_get_ts(struct timespec *ts);
332
333
334#define ktime_get_real_ts(ts) getnstimeofday(ts)
335
336static inline ktime_t ns_to_ktime(u64 ns)
337{
338 static const ktime_t ktime_zero = { .tv64 = 0 };
339 return ktime_add_ns(ktime_zero, ns);
340}
341
342#endif
343