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 : : /* Nanosecond scalar representation for kernel time values */
28 : : typedef s64 ktime_t;
29 : :
30 : : /**
31 : : * ktime_set - Set a ktime_t variable from a seconds/nanoseconds value
32 : : * @secs: seconds to set
33 : : * @nsecs: nanoseconds to set
34 : : *
35 : : * Return: The ktime_t representation of the value.
36 : : */
37 : : static inline ktime_t ktime_set(const s64 secs, const unsigned long nsecs)
38 : : {
39 [ + + + - : 1312662 : if (unlikely(secs >= KTIME_SEC_MAX))
# # + - +
- + - ]
40 : : return KTIME_MAX;
41 : :
42 : 1312936 : return secs * NSEC_PER_SEC + (s64)nsecs;
43 : : }
44 : :
45 : : /* Subtract two ktime_t variables. rem = lhs -rhs: */
46 : : #define ktime_sub(lhs, rhs) ((lhs) - (rhs))
47 : :
48 : : /* Add two ktime_t variables. res = lhs + rhs: */
49 : : #define ktime_add(lhs, rhs) ((lhs) + (rhs))
50 : :
51 : : /*
52 : : * Same as ktime_add(), but avoids undefined behaviour on overflow; however,
53 : : * this means that you must check the result for overflow yourself.
54 : : */
55 : : #define ktime_add_unsafe(lhs, rhs) ((u64) (lhs) + (rhs))
56 : :
57 : : /*
58 : : * Add a ktime_t variable and a scalar nanosecond value.
59 : : * res = kt + nsval:
60 : : */
61 : : #define ktime_add_ns(kt, nsval) ((kt) + (nsval))
62 : :
63 : : /*
64 : : * Subtract a scalar nanosecod from a ktime_t variable
65 : : * res = kt - nsval:
66 : : */
67 : : #define ktime_sub_ns(kt, nsval) ((kt) - (nsval))
68 : :
69 : : /* convert a timespec to ktime_t format: */
70 : : static inline ktime_t timespec_to_ktime(struct timespec ts)
71 : : {
72 : : return ktime_set(ts.tv_sec, ts.tv_nsec);
73 : : }
74 : :
75 : : /* convert a timespec64 to ktime_t format: */
76 : : static inline ktime_t timespec64_to_ktime(struct timespec64 ts)
77 : : {
78 : 679069 : return ktime_set(ts.tv_sec, ts.tv_nsec);
79 : : }
80 : :
81 : : /* convert a timeval to ktime_t format: */
82 : : static inline ktime_t timeval_to_ktime(struct timeval tv)
83 : : {
84 : 632765 : return ktime_set(tv.tv_sec, tv.tv_usec * NSEC_PER_USEC);
85 : : }
86 : :
87 : : /* Map the ktime_t to timespec conversion to ns_to_timespec function */
88 : : #define ktime_to_timespec(kt) ns_to_timespec((kt))
89 : :
90 : : /* Map the ktime_t to timespec conversion to ns_to_timespec function */
91 : : #define ktime_to_timespec64(kt) ns_to_timespec64((kt))
92 : :
93 : : /* Map the ktime_t to timeval conversion to ns_to_timeval function */
94 : : #define ktime_to_timeval(kt) ns_to_timeval((kt))
95 : :
96 : : /* Convert ktime_t to nanoseconds */
97 : 2501837 : static inline s64 ktime_to_ns(const ktime_t kt)
98 : : {
99 : 2501837 : return kt;
100 : : }
101 : :
102 : : /**
103 : : * ktime_compare - Compares two ktime_t variables for less, greater or equal
104 : : * @cmp1: comparable1
105 : : * @cmp2: comparable2
106 : : *
107 : : * Return: ...
108 : : * cmp1 < cmp2: return <0
109 : : * cmp1 == cmp2: return 0
110 : : * cmp1 > cmp2: return >0
111 : : */
112 : : static inline int ktime_compare(const ktime_t cmp1, const ktime_t cmp2)
113 : : {
114 [ + + - + : 3247029 : if (cmp1 < cmp2)
# # # # ]
115 : : return -1;
116 [ + - # # : 2 : if (cmp1 > cmp2)
# # # # ]
117 : : return 1;
118 : : return 0;
119 : : }
120 : :
121 : : /**
122 : : * ktime_after - Compare if a ktime_t value is bigger than another one.
123 : : * @cmp1: comparable1
124 : : * @cmp2: comparable2
125 : : *
126 : : * Return: true if cmp1 happened after cmp2.
127 : : */
128 : : static inline bool ktime_after(const ktime_t cmp1, const ktime_t cmp2)
129 : : {
130 : 0 : return ktime_compare(cmp1, cmp2) > 0;
131 : : }
132 : :
133 : : /**
134 : : * ktime_before - Compare if a ktime_t value is smaller than another one.
135 : : * @cmp1: comparable1
136 : : * @cmp2: comparable2
137 : : *
138 : : * Return: true if cmp1 happened before cmp2.
139 : : */
140 : : static inline bool ktime_before(const ktime_t cmp1, const ktime_t cmp2)
141 : : {
142 : : return ktime_compare(cmp1, cmp2) < 0;
143 : : }
144 : :
145 : : #if BITS_PER_LONG < 64
146 : : extern s64 __ktime_divns(const ktime_t kt, s64 div);
147 : 1302102 : static inline s64 ktime_divns(const ktime_t kt, s64 div)
148 : : {
149 : : /*
150 : : * Negative divisors could cause an inf loop,
151 : : * so bug out here.
152 : : */
153 [ - + ]: 1302102 : BUG_ON(div < 0);
154 [ + + + - ]: 1302102 : if (__builtin_constant_p(div) && !(div >> 32)) {
155 : : s64 ns = kt;
156 : 988659 : u64 tmp = ns < 0 ? -ns : ns;
157 : :
158 [ + - - + : 1977318 : do_div(tmp, div);
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - -
+ # # # #
# # # # #
# # # # #
- + - + +
- # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
159 [ - + ]: 988659 : return ns < 0 ? -tmp : tmp;
160 : : } else {
161 : 313443 : return __ktime_divns(kt, div);
162 : : }
163 : : }
164 : : #else /* BITS_PER_LONG < 64 */
165 : : static inline s64 ktime_divns(const ktime_t kt, s64 div)
166 : : {
167 : : /*
168 : : * 32-bit implementation cannot handle negative divisors,
169 : : * so catch them on 64bit as well.
170 : : */
171 : : WARN_ON(div < 0);
172 : : return kt / div;
173 : : }
174 : : #endif
175 : :
176 : : static inline s64 ktime_to_us(const ktime_t kt)
177 : : {
178 : 988659 : return ktime_divns(kt, NSEC_PER_USEC);
179 : : }
180 : :
181 : : static inline s64 ktime_to_ms(const ktime_t kt)
182 : : {
183 : 0 : return ktime_divns(kt, NSEC_PER_MSEC);
184 : : }
185 : :
186 : : static inline s64 ktime_us_delta(const ktime_t later, const ktime_t earlier)
187 : : {
188 : 0 : return ktime_to_us(ktime_sub(later, earlier));
189 : : }
190 : :
191 : : static inline s64 ktime_ms_delta(const ktime_t later, const ktime_t earlier)
192 : : {
193 : : return ktime_to_ms(ktime_sub(later, earlier));
194 : : }
195 : :
196 : : static inline ktime_t ktime_add_us(const ktime_t kt, const u64 usec)
197 : : {
198 : 76743 : return ktime_add_ns(kt, usec * NSEC_PER_USEC);
199 : : }
200 : :
201 : : static inline ktime_t ktime_add_ms(const ktime_t kt, const u64 msec)
202 : : {
203 : 0 : return ktime_add_ns(kt, msec * NSEC_PER_MSEC);
204 : : }
205 : :
206 : : static inline ktime_t ktime_sub_us(const ktime_t kt, const u64 usec)
207 : : {
208 : : return ktime_sub_ns(kt, usec * NSEC_PER_USEC);
209 : : }
210 : :
211 : : static inline ktime_t ktime_sub_ms(const ktime_t kt, const u64 msec)
212 : : {
213 : : return ktime_sub_ns(kt, msec * NSEC_PER_MSEC);
214 : : }
215 : :
216 : : extern ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs);
217 : :
218 : : /**
219 : : * ktime_to_timespec_cond - convert a ktime_t variable to timespec
220 : : * format only if the variable contains data
221 : : * @kt: the ktime_t variable to convert
222 : : * @ts: the timespec variable to store the result in
223 : : *
224 : : * Return: %true if there was a successful conversion, %false if kt was 0.
225 : : */
226 : : static inline __must_check bool ktime_to_timespec_cond(const ktime_t kt,
227 : : struct timespec *ts)
228 : : {
229 [ # # # # ]: 0 : if (kt) {
230 : 0 : *ts = ktime_to_timespec(kt);
231 : : return true;
232 : : } else {
233 : : return false;
234 : : }
235 : : }
236 : :
237 : : /**
238 : : * ktime_to_timespec64_cond - convert a ktime_t variable to timespec64
239 : : * format only if the variable contains data
240 : : * @kt: the ktime_t variable to convert
241 : : * @ts: the timespec variable to store the result in
242 : : *
243 : : * Return: %true if there was a successful conversion, %false if kt was 0.
244 : : */
245 : : static inline __must_check bool ktime_to_timespec64_cond(const ktime_t kt,
246 : : struct timespec64 *ts)
247 : : {
248 [ # # # # ]: 0 : if (kt) {
249 : 0 : *ts = ktime_to_timespec64(kt);
250 : : return true;
251 : : } else {
252 : : return false;
253 : : }
254 : : }
255 : :
256 : : /*
257 : : * The resolution of the clocks. The resolution value is returned in
258 : : * the clock_getres() system call to give application programmers an
259 : : * idea of the (in)accuracy of timers. Timer values are rounded up to
260 : : * this resolution values.
261 : : */
262 : : #define LOW_RES_NSEC TICK_NSEC
263 : : #define KTIME_LOW_RES (LOW_RES_NSEC)
264 : :
265 : : static inline ktime_t ns_to_ktime(u64 ns)
266 : : {
267 : 6829847 : return ns;
268 : : }
269 : :
270 : : static inline ktime_t ms_to_ktime(u64 ms)
271 : : {
272 : 0 : return ms * NSEC_PER_MSEC;
273 : : }
274 : :
275 : : # include <linux/timekeeping.h>
276 : : # include <linux/timekeeping32.h>
277 : :
278 : : #endif
|