Branch data Line data Source code
1 : : /*
2 : : * include/linux/ktime.h
3 : : *
4 : : * ktime_t - nanosecond-resolution time format.
5 : : *
6 : : * Copyright(C) 2005, Thomas Gleixner <tglx@linutronix.de>
7 : : * Copyright(C) 2005, Red Hat, Inc., Ingo Molnar
8 : : *
9 : : * data type definitions, declarations, prototypes and macros.
10 : : *
11 : : * Started by: Thomas Gleixner and Ingo Molnar
12 : : *
13 : : * Credits:
14 : : *
15 : : * Roman Zippel provided the ideas and primary code snippets of
16 : : * the ktime_t union and further simplifications of the original
17 : : * code.
18 : : *
19 : : * For licencing details see kernel-base/COPYING
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 : : * ktime_t:
29 : : *
30 : : * On 64-bit CPUs a single 64-bit variable is used to store the hrtimers
31 : : * internal representation of time values in scalar nanoseconds. The
32 : : * design plays out best on 64-bit CPUs, where most conversions are
33 : : * NOPs and most arithmetic ktime_t operations are plain arithmetic
34 : : * operations.
35 : : *
36 : : * On 32-bit CPUs an optimized representation of the timespec structure
37 : : * is used to avoid expensive conversions from and to timespecs. The
38 : : * endian-aware order of the tv struct members is chosen to allow
39 : : * mathematical operations on the tv64 member of the union too, which
40 : : * for certain operations produces better code.
41 : : *
42 : : * For architectures with efficient support for 64/32-bit conversions the
43 : : * plain scalar nanosecond based representation can be selected by the
44 : : * config switch CONFIG_KTIME_SCALAR.
45 : : */
46 : : union 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 : :
59 : : typedef union ktime ktime_t; /* Kill this */
60 : :
61 : : /*
62 : : * ktime_t definitions when using the 64-bit scalar representation:
63 : : */
64 : :
65 : : #if (BITS_PER_LONG == 64) || defined(CONFIG_KTIME_SCALAR)
66 : :
67 : : /**
68 : : * ktime_set - Set a ktime_t variable from a seconds/nanoseconds value
69 : : * @secs: seconds to set
70 : : * @nsecs: nanoseconds to set
71 : : *
72 : : * Return: The ktime_t representation of the value.
73 : : */
74 : : static inline ktime_t ktime_set(const long secs, const unsigned long nsecs)
75 : : {
76 : : #if (BITS_PER_LONG == 64)
77 : : if (unlikely(secs >= KTIME_SEC_MAX))
78 : : return (ktime_t){ .tv64 = KTIME_MAX };
79 : : #endif
80 : 61682044 : return (ktime_t) { .tv64 = (s64)secs * NSEC_PER_SEC + (s64)nsecs };
81 : : }
82 : :
83 : : /* Subtract two ktime_t variables. rem = lhs -rhs: */
84 : : #define ktime_sub(lhs, rhs) \
85 : : ({ (ktime_t){ .tv64 = (lhs).tv64 - (rhs).tv64 }; })
86 : :
87 : : /* Add two ktime_t variables. res = lhs + rhs: */
88 : : #define ktime_add(lhs, rhs) \
89 : : ({ (ktime_t){ .tv64 = (lhs).tv64 + (rhs).tv64 }; })
90 : :
91 : : /*
92 : : * Add a ktime_t variable and a scalar nanosecond value.
93 : : * res = kt + nsval:
94 : : */
95 : : #define ktime_add_ns(kt, nsval) \
96 : : ({ (ktime_t){ .tv64 = (kt).tv64 + (nsval) }; })
97 : :
98 : : /*
99 : : * Subtract a scalar nanosecod from a ktime_t variable
100 : : * res = kt - nsval:
101 : : */
102 : : #define ktime_sub_ns(kt, nsval) \
103 : : ({ (ktime_t){ .tv64 = (kt).tv64 - (nsval) }; })
104 : :
105 : : /* convert a timespec to ktime_t format: */
106 : : static inline ktime_t timespec_to_ktime(struct timespec ts)
107 : : {
108 : 849869 : return ktime_set(ts.tv_sec, ts.tv_nsec);
109 : : }
110 : :
111 : : /* convert a timeval to ktime_t format: */
112 : : static inline ktime_t timeval_to_ktime(struct timeval tv)
113 : : {
114 : 25311 : return ktime_set(tv.tv_sec, tv.tv_usec * NSEC_PER_USEC);
115 : : }
116 : :
117 : : /* Map the ktime_t to timespec conversion to ns_to_timespec function */
118 : : #define ktime_to_timespec(kt) ns_to_timespec((kt).tv64)
119 : :
120 : : /* Map the ktime_t to timeval conversion to ns_to_timeval function */
121 : : #define ktime_to_timeval(kt) ns_to_timeval((kt).tv64)
122 : :
123 : : /* Convert ktime_t to nanoseconds - NOP in the scalar storage format: */
124 : : #define ktime_to_ns(kt) ((kt).tv64)
125 : :
126 : : #else /* !((BITS_PER_LONG == 64) || defined(CONFIG_KTIME_SCALAR)) */
127 : :
128 : : /*
129 : : * Helper macros/inlines to get the ktime_t math right in the timespec
130 : : * representation. The macros are sometimes ugly - their actual use is
131 : : * pretty okay-ish, given the circumstances. We do all this for
132 : : * performance reasons. The pure scalar nsec_t based code was nice and
133 : : * simple, but created too many 64-bit / 32-bit conversions and divisions.
134 : : *
135 : : * Be especially aware that negative values are represented in a way
136 : : * that the tv.sec field is negative and the tv.nsec field is greater
137 : : * or equal to zero but less than nanoseconds per second. This is the
138 : : * same representation which is used by timespecs.
139 : : *
140 : : * tv.sec < 0 and 0 >= tv.nsec < NSEC_PER_SEC
141 : : */
142 : :
143 : : /* Set a ktime_t variable to a value in sec/nsec representation: */
144 : : static inline ktime_t ktime_set(const long secs, const unsigned long nsecs)
145 : : {
146 : : return (ktime_t) { .tv = { .sec = secs, .nsec = nsecs } };
147 : : }
148 : :
149 : : /**
150 : : * ktime_sub - subtract two ktime_t variables
151 : : * @lhs: minuend
152 : : * @rhs: subtrahend
153 : : *
154 : : * Return: The remainder of the subtraction.
155 : : */
156 : : static inline ktime_t ktime_sub(const ktime_t lhs, const ktime_t rhs)
157 : : {
158 : : ktime_t res;
159 : :
160 : : res.tv64 = lhs.tv64 - rhs.tv64;
161 : : if (res.tv.nsec < 0)
162 : : res.tv.nsec += NSEC_PER_SEC;
163 : :
164 : : return res;
165 : : }
166 : :
167 : : /**
168 : : * ktime_add - add two ktime_t variables
169 : : * @add1: addend1
170 : : * @add2: addend2
171 : : *
172 : : * Return: The sum of @add1 and @add2.
173 : : */
174 : : static inline ktime_t ktime_add(const ktime_t add1, const ktime_t add2)
175 : : {
176 : : ktime_t res;
177 : :
178 : : res.tv64 = add1.tv64 + add2.tv64;
179 : : /*
180 : : * performance trick: the (u32) -NSEC gives 0x00000000Fxxxxxxx
181 : : * so we subtract NSEC_PER_SEC and add 1 to the upper 32 bit.
182 : : *
183 : : * it's equivalent to:
184 : : * tv.nsec -= NSEC_PER_SEC
185 : : * tv.sec ++;
186 : : */
187 : : if (res.tv.nsec >= NSEC_PER_SEC)
188 : : res.tv64 += (u32)-NSEC_PER_SEC;
189 : :
190 : : return res;
191 : : }
192 : :
193 : : /**
194 : : * ktime_add_ns - Add a scalar nanoseconds value to a ktime_t variable
195 : : * @kt: addend
196 : : * @nsec: the scalar nsec value to add
197 : : *
198 : : * Return: The sum of @kt and @nsec in ktime_t format.
199 : : */
200 : : extern ktime_t ktime_add_ns(const ktime_t kt, u64 nsec);
201 : :
202 : : /**
203 : : * ktime_sub_ns - Subtract a scalar nanoseconds value from a ktime_t variable
204 : : * @kt: minuend
205 : : * @nsec: the scalar nsec value to subtract
206 : : *
207 : : * Return: The subtraction of @nsec from @kt in ktime_t format.
208 : : */
209 : : extern ktime_t ktime_sub_ns(const ktime_t kt, u64 nsec);
210 : :
211 : : /**
212 : : * timespec_to_ktime - convert a timespec to ktime_t format
213 : : * @ts: the timespec variable to convert
214 : : *
215 : : * Return: A ktime_t variable with the converted timespec value.
216 : : */
217 : : static inline ktime_t timespec_to_ktime(const struct timespec ts)
218 : : {
219 : : return (ktime_t) { .tv = { .sec = (s32)ts.tv_sec,
220 : : .nsec = (s32)ts.tv_nsec } };
221 : : }
222 : :
223 : : /**
224 : : * timeval_to_ktime - convert a timeval to ktime_t format
225 : : * @tv: the timeval variable to convert
226 : : *
227 : : * Return: A ktime_t variable with the converted timeval value.
228 : : */
229 : : static inline ktime_t timeval_to_ktime(const struct timeval tv)
230 : : {
231 : : return (ktime_t) { .tv = { .sec = (s32)tv.tv_sec,
232 : : .nsec = (s32)(tv.tv_usec *
233 : : NSEC_PER_USEC) } };
234 : : }
235 : :
236 : : /**
237 : : * ktime_to_timespec - convert a ktime_t variable to timespec format
238 : : * @kt: the ktime_t variable to convert
239 : : *
240 : : * Return: The timespec representation of the ktime value.
241 : : */
242 : : static inline struct timespec ktime_to_timespec(const ktime_t kt)
243 : : {
244 : : return (struct timespec) { .tv_sec = (time_t) kt.tv.sec,
245 : : .tv_nsec = (long) kt.tv.nsec };
246 : : }
247 : :
248 : : /**
249 : : * ktime_to_timeval - convert a ktime_t variable to timeval format
250 : : * @kt: the ktime_t variable to convert
251 : : *
252 : : * Return: The timeval representation of the ktime value.
253 : : */
254 : : static inline struct timeval ktime_to_timeval(const ktime_t kt)
255 : : {
256 : : return (struct timeval) {
257 : : .tv_sec = (time_t) kt.tv.sec,
258 : : .tv_usec = (suseconds_t) (kt.tv.nsec / NSEC_PER_USEC) };
259 : : }
260 : :
261 : : /**
262 : : * ktime_to_ns - convert a ktime_t variable to scalar nanoseconds
263 : : * @kt: the ktime_t variable to convert
264 : : *
265 : : * Return: The scalar nanoseconds representation of @kt.
266 : : */
267 : : static inline s64 ktime_to_ns(const ktime_t kt)
268 : : {
269 : : return (s64) kt.tv.sec * NSEC_PER_SEC + kt.tv.nsec;
270 : : }
271 : :
272 : : #endif /* !((BITS_PER_LONG == 64) || defined(CONFIG_KTIME_SCALAR)) */
273 : :
274 : : /**
275 : : * ktime_equal - Compares two ktime_t variables to see if they are equal
276 : : * @cmp1: comparable1
277 : : * @cmp2: comparable2
278 : : *
279 : : * Compare two ktime_t variables.
280 : : *
281 : : * Return: 1 if equal.
282 : : */
283 : : static inline int ktime_equal(const ktime_t cmp1, const ktime_t cmp2)
284 : : {
285 : : return cmp1.tv64 == cmp2.tv64;
286 : : }
287 : :
288 : : /**
289 : : * ktime_compare - Compares two ktime_t variables for less, greater or equal
290 : : * @cmp1: comparable1
291 : : * @cmp2: comparable2
292 : : *
293 : : * Return: ...
294 : : * cmp1 < cmp2: return <0
295 : : * cmp1 == cmp2: return 0
296 : : * cmp1 > cmp2: return >0
297 : : */
298 : : static inline int ktime_compare(const ktime_t cmp1, const ktime_t cmp2)
299 : : {
300 : : if (cmp1.tv64 < cmp2.tv64)
301 : : return -1;
302 : : if (cmp1.tv64 > cmp2.tv64)
303 : : return 1;
304 : : return 0;
305 : : }
306 : :
307 : : static inline s64 ktime_to_us(const ktime_t kt)
308 : : {
309 : 8814180 : struct timeval tv = ktime_to_timeval(kt);
310 : 17382892 : return (s64) tv.tv_sec * USEC_PER_SEC + tv.tv_usec;
311 : : }
312 : :
313 : : static inline s64 ktime_to_ms(const ktime_t kt)
314 : : {
315 : 87 : struct timeval tv = ktime_to_timeval(kt);
316 : 87 : return (s64) tv.tv_sec * MSEC_PER_SEC + tv.tv_usec / USEC_PER_MSEC;
317 : : }
318 : :
319 : : static inline s64 ktime_us_delta(const ktime_t later, const ktime_t earlier)
320 : : {
321 : 55505 : return ktime_to_us(ktime_sub(later, earlier));
322 : : }
323 : :
324 : : static inline ktime_t ktime_add_us(const ktime_t kt, const u64 usec)
325 : : {
326 : : return ktime_add_ns(kt, usec * NSEC_PER_USEC);
327 : : }
328 : :
329 : : static inline ktime_t ktime_add_ms(const ktime_t kt, const u64 msec)
330 : : {
331 : : return ktime_add_ns(kt, msec * NSEC_PER_MSEC);
332 : : }
333 : :
334 : : static inline ktime_t ktime_sub_us(const ktime_t kt, const u64 usec)
335 : : {
336 : : return ktime_sub_ns(kt, usec * NSEC_PER_USEC);
337 : : }
338 : :
339 : : extern ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs);
340 : :
341 : : /**
342 : : * ktime_to_timespec_cond - convert a ktime_t variable to timespec
343 : : * format only if the variable contains data
344 : : * @kt: the ktime_t variable to convert
345 : : * @ts: the timespec variable to store the result in
346 : : *
347 : : * Return: %true if there was a successful conversion, %false if kt was 0.
348 : : */
349 : : static inline __must_check bool ktime_to_timespec_cond(const ktime_t kt,
350 : : struct timespec *ts)
351 : : {
352 [ # # ][ # # ]: 0 : if (kt.tv64) {
[ # # ]
353 : 0 : *ts = ktime_to_timespec(kt);
354 : : return true;
355 : : } else {
356 : : return false;
357 : : }
358 : : }
359 : :
360 : : /*
361 : : * The resolution of the clocks. The resolution value is returned in
362 : : * the clock_getres() system call to give application programmers an
363 : : * idea of the (in)accuracy of timers. Timer values are rounded up to
364 : : * this resolution values.
365 : : */
366 : : #define LOW_RES_NSEC TICK_NSEC
367 : : #define KTIME_LOW_RES (ktime_t){ .tv64 = LOW_RES_NSEC }
368 : :
369 : : /* Get the monotonic time in timespec format: */
370 : : extern void ktime_get_ts(struct timespec *ts);
371 : :
372 : : /* Get the real (wall-) time in timespec format: */
373 : : #define ktime_get_real_ts(ts) getnstimeofday(ts)
374 : :
375 : : static inline ktime_t ns_to_ktime(u64 ns)
376 : : {
377 : : static const ktime_t ktime_zero = { .tv64 = 0 };
378 : :
379 : 6739803 : return ktime_add_ns(ktime_zero, ns);
380 : : }
381 : :
382 : : static inline ktime_t ms_to_ktime(u64 ms)
383 : : {
384 : : static const ktime_t ktime_zero = { .tv64 = 0 };
385 : :
386 : : return ktime_add_ms(ktime_zero, ms);
387 : : }
388 : :
389 : : #endif
|