1 /*-
2  * Copyright (c) 2018 Limelight Networks, Inc.
3  * Copyright (c) 2014-2018 Mellanox Technologies, Ltd.
4  * Copyright (c) 2015 François Tigeot
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice unmodified, this list of conditions, and the following
12  *    disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * $FreeBSD$
29  */
30 
31 #ifndef _LINUXKPI_LINUX_KTIME_H
32 #define	_LINUXKPI_LINUX_KTIME_H
33 
34 #include <linux/types.h>
35 #include <linux/time.h>
36 #include <linux/jiffies.h>
37 
38 /* time values in nanoseconds */
39 typedef s64 ktime_t;
40 
41 #define	KTIME_MAX			((s64)~((u64)1 << 63))
42 #define	KTIME_SEC_MAX			(KTIME_MAX / NSEC_PER_SEC)
43 
44 static inline int64_t
45 ktime_to_ns(ktime_t kt)
46 {
47 	return (kt);
48 }
49 
50 static inline ktime_t
51 ns_to_ktime(uint64_t nsec)
52 {
53 	return (nsec);
54 }
55 
56 static inline int64_t
57 ktime_divns(const ktime_t kt, int64_t div)
58 {
59 	return (kt / div);
60 }
61 
62 static inline int64_t
63 ktime_to_us(ktime_t kt)
64 {
65 	return (ktime_divns(kt, NSEC_PER_USEC));
66 }
67 
68 static inline int64_t
69 ktime_to_ms(ktime_t kt)
70 {
71 	return (ktime_divns(kt, NSEC_PER_MSEC));
72 }
73 
74 static inline struct timeval
75 ktime_to_timeval(ktime_t kt)
76 {
77 	return (ns_to_timeval(kt));
78 }
79 
80 static inline ktime_t
81 ktime_add_ns(ktime_t kt, int64_t ns)
82 {
83 	return (kt + ns);
84 }
85 
86 static inline ktime_t
87 ktime_add_ms(ktime_t kt, int64_t ms)
88 {
89 
90 	return (ktime_add_ns(kt, ms * NSEC_PER_MSEC));
91 }
92 
93 static inline ktime_t
94 ktime_add_us(ktime_t kt, int64_t us)
95 {
96 
97 	return (ktime_add_ns(kt, us * NSEC_PER_USEC));
98 }
99 
100 static inline ktime_t
101 ktime_sub_ns(ktime_t kt, int64_t ns)
102 {
103 	return (kt - ns);
104 }
105 
106 static inline ktime_t
107 ktime_set(const long secs, const unsigned long nsecs)
108 {
109 	ktime_t retval = {(s64) secs * NSEC_PER_SEC + (s64) nsecs};
110 
111 	return (retval);
112 }
113 
114 static inline ktime_t
115 ktime_sub(ktime_t lhs, ktime_t rhs)
116 {
117 	return (lhs - rhs);
118 }
119 
120 static inline int64_t
121 ktime_us_delta(ktime_t later, ktime_t earlier)
122 {
123 	ktime_t diff = ktime_sub(later, earlier);
124 
125 	return (ktime_to_us(diff));
126 }
127 
128 static inline int64_t
129 ktime_ms_delta(ktime_t later, ktime_t earlier)
130 {
131 	ktime_t diff = ktime_sub(later, earlier);
132 
133 	return (ktime_to_ms(diff));
134 }
135 
136 static inline ktime_t
137 ktime_add(ktime_t lhs, ktime_t rhs)
138 {
139 	return (lhs + rhs);
140 }
141 
142 static inline int
143 ktime_compare(const ktime_t cmp1, const ktime_t cmp2)
144 {
145 
146 	if (cmp1 > cmp2)
147 		return (1);
148 	else if (cmp1 < cmp2)
149 		return (-1);
150 	else
151 		return (0);
152 }
153 
154 static inline bool
155 ktime_after(const ktime_t cmp1, const ktime_t cmp2)
156 {
157 
158 	return (ktime_compare(cmp1, cmp2) > 0);
159 }
160 
161 static inline bool
162 ktime_before(const ktime_t cmp1, const ktime_t cmp2)
163 {
164 
165 	return (ktime_compare(cmp1, cmp2) < 0);
166 }
167 
168 static inline ktime_t
169 timespec_to_ktime(struct timespec ts)
170 {
171 	return (ktime_set(ts.tv_sec, ts.tv_nsec));
172 }
173 
174 static inline ktime_t
175 timeval_to_ktime(struct timeval tv)
176 {
177 	return (ktime_set(tv.tv_sec, tv.tv_usec * NSEC_PER_USEC));
178 }
179 
180 static inline int64_t
181 timespec64_to_ns(struct timespec64 *ts)
182 {
183 	return (timespec_to_ns(ts));
184 }
185 
186 #define	ktime_to_timespec(kt)		ns_to_timespec(kt)
187 #define	ktime_to_timespec64(kt)		ns_to_timespec(kt)
188 #define	ktime_to_timeval(kt)		ns_to_timeval(kt)
189 #define	ktime_to_ns(kt)			(kt)
190 #define	ktime_get_ts(ts)		getnanouptime(ts)
191 #define	ktime_get_ts64(ts)		getnanouptime(ts)
192 #define	ktime_get_raw_ts64(ts)		getnanouptime(ts)
193 #define	getrawmonotonic64(ts)		getnanouptime(ts)
194 
195 static inline int64_t
196 ktime_get_ns(void)
197 {
198 	struct timespec ts;
199 
200 	ktime_get_ts(&ts);
201 
202 	return (ktime_to_ns(timespec_to_ktime(ts)));
203 }
204 
205 static inline ktime_t
206 ktime_get(void)
207 {
208 	struct timespec ts;
209 
210 	ktime_get_ts(&ts);
211 	return (timespec_to_ktime(ts));
212 }
213 
214 static inline ktime_t
215 ktime_get_boottime(void)
216 {
217 	struct timespec ts;
218 
219 	nanouptime(&ts);
220 	return (timespec_to_ktime(ts));
221 }
222 
223 static inline uint64_t
224 ktime_get_boottime_ns(void)
225 {
226 
227 	return (ktime_to_ns(ktime_get_boottime()));
228 }
229 
230 static inline ktime_t
231 ktime_get_real(void)
232 {
233 	struct timespec ts;
234 
235 	nanotime(&ts);
236 	return (timespec_to_ktime(ts));
237 }
238 
239 static inline ktime_t
240 ktime_get_real_seconds(void)
241 {
242 	struct timespec ts;
243 
244 	nanotime(&ts);
245 	return (ts.tv_sec);
246 }
247 
248 static inline ktime_t
249 ktime_get_raw(void)
250 {
251 	struct timespec ts;
252 
253 	nanouptime(&ts);
254 	return (timespec_to_ktime(ts));
255 }
256 
257 static inline u64
258 ktime_get_raw_ns(void)
259 {
260 	struct timespec ts;
261 
262 	nanouptime(&ts);
263 	return (ktime_to_ns(timespec_to_ktime(ts)));
264 }
265 
266 #endif /* _LINUXKPI_LINUX_KTIME_H */
267