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
37union ktime {
38 s64 tv64;
39};
40
41typedef union ktime ktime_t;
42
43
44
45
46
47
48
49
50static inline ktime_t ktime_set(const s64 secs, const unsigned long nsecs)
51{
52 if (unlikely(secs >= KTIME_SEC_MAX))
53 return (ktime_t){ .tv64 = KTIME_MAX };
54
55 return (ktime_t) { .tv64 = secs * NSEC_PER_SEC + (s64)nsecs };
56}
57
58
59#define ktime_sub(lhs, rhs) \
60 ({ (ktime_t){ .tv64 = (lhs).tv64 - (rhs).tv64 }; })
61
62
63#define ktime_add(lhs, rhs) \
64 ({ (ktime_t){ .tv64 = (lhs).tv64 + (rhs).tv64 }; })
65
66
67
68
69
70#define ktime_add_ns(kt, nsval) \
71 ({ (ktime_t){ .tv64 = (kt).tv64 + (nsval) }; })
72
73
74
75
76
77#define ktime_sub_ns(kt, nsval) \
78 ({ (ktime_t){ .tv64 = (kt).tv64 - (nsval) }; })
79
80
81static inline ktime_t timespec_to_ktime(struct timespec ts)
82{
83 return ktime_set(ts.tv_sec, ts.tv_nsec);
84}
85
86
87static inline ktime_t timespec64_to_ktime(struct timespec64 ts)
88{
89 return ktime_set(ts.tv_sec, ts.tv_nsec);
90}
91
92
93static inline ktime_t timeval_to_ktime(struct timeval tv)
94{
95 return ktime_set(tv.tv_sec, tv.tv_usec * NSEC_PER_USEC);
96}
97
98
99#define ktime_to_timespec(kt) ns_to_timespec((kt).tv64)
100
101
102#define ktime_to_timespec64(kt) ns_to_timespec64((kt).tv64)
103
104
105#define ktime_to_timeval(kt) ns_to_timeval((kt).tv64)
106
107
108#define ktime_to_ns(kt) ((kt).tv64)
109
110
111
112
113
114
115
116
117
118
119
120static inline int ktime_equal(const ktime_t cmp1, const ktime_t cmp2)
121{
122 return cmp1.tv64 == cmp2.tv64;
123}
124
125
126
127
128
129
130
131
132
133
134
135static inline int ktime_compare(const ktime_t cmp1, const ktime_t cmp2)
136{
137 if (cmp1.tv64 < cmp2.tv64)
138 return -1;
139 if (cmp1.tv64 > cmp2.tv64)
140 return 1;
141 return 0;
142}
143
144
145
146
147
148
149
150
151static inline bool ktime_after(const ktime_t cmp1, const ktime_t cmp2)
152{
153 return ktime_compare(cmp1, cmp2) > 0;
154}
155
156
157
158
159
160
161
162
163static inline bool ktime_before(const ktime_t cmp1, const ktime_t cmp2)
164{
165 return ktime_compare(cmp1, cmp2) < 0;
166}
167
168#if BITS_PER_LONG < 64
169extern s64 __ktime_divns(const ktime_t kt, s64 div);
170static inline s64 ktime_divns(const ktime_t kt, s64 div)
171{
172
173
174
175
176 BUG_ON(div < 0);
177 if (__builtin_constant_p(div) && !(div >> 32)) {
178 s64 ns = kt.tv64;
179 u64 tmp = ns < 0 ? -ns : ns;
180
181 do_div(tmp, div);
182 return ns < 0 ? -tmp : tmp;
183 } else {
184 return __ktime_divns(kt, div);
185 }
186}
187#else
188static inline s64 ktime_divns(const ktime_t kt, s64 div)
189{
190
191
192
193
194 WARN_ON(div < 0);
195 return kt.tv64 / div;
196}
197#endif
198
199static inline s64 ktime_to_us(const ktime_t kt)
200{
201 return ktime_divns(kt, NSEC_PER_USEC);
202}
203
204static inline s64 ktime_to_ms(const ktime_t kt)
205{
206 return ktime_divns(kt, NSEC_PER_MSEC);
207}
208
209static inline s64 ktime_us_delta(const ktime_t later, const ktime_t earlier)
210{
211 return ktime_to_us(ktime_sub(later, earlier));
212}
213
214static inline s64 ktime_ms_delta(const ktime_t later, const ktime_t earlier)
215{
216 return ktime_to_ms(ktime_sub(later, earlier));
217}
218
219static inline ktime_t ktime_add_us(const ktime_t kt, const u64 usec)
220{
221 return ktime_add_ns(kt, usec * NSEC_PER_USEC);
222}
223
224static inline ktime_t ktime_add_ms(const ktime_t kt, const u64 msec)
225{
226 return ktime_add_ns(kt, msec * NSEC_PER_MSEC);
227}
228
229static inline ktime_t ktime_sub_us(const ktime_t kt, const u64 usec)
230{
231 return ktime_sub_ns(kt, usec * NSEC_PER_USEC);
232}
233
234extern ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs);
235
236
237
238
239
240
241
242
243
244static inline __must_check bool ktime_to_timespec_cond(const ktime_t kt,
245 struct timespec *ts)
246{
247 if (kt.tv64) {
248 *ts = ktime_to_timespec(kt);
249 return true;
250 } else {
251 return false;
252 }
253}
254
255
256
257
258
259
260
261
262
263static inline __must_check bool ktime_to_timespec64_cond(const ktime_t kt,
264 struct timespec64 *ts)
265{
266 if (kt.tv64) {
267 *ts = ktime_to_timespec64(kt);
268 return true;
269 } else {
270 return false;
271 }
272}
273
274
275
276
277
278
279
280#define LOW_RES_NSEC TICK_NSEC
281#define KTIME_LOW_RES (ktime_t){ .tv64 = LOW_RES_NSEC }
282
283static inline ktime_t ns_to_ktime(u64 ns)
284{
285 static const ktime_t ktime_zero = { .tv64 = 0 };
286
287 return ktime_add_ns(ktime_zero, ns);
288}
289
290static inline ktime_t ms_to_ktime(u64 ms)
291{
292 static const ktime_t ktime_zero = { .tv64 = 0 };
293
294 return ktime_add_ms(ktime_zero, ms);
295}
296
297# include <linux/timekeeping.h>
298
299#endif
300