Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6082 serge 1
/*
2
 *  include/linux/ktime.h
3
 *
4
 *  ktime_t - nanosecond-resolution time format.
5
 *
6
 *   Copyright(C) 2005, Thomas Gleixner 
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 
25
#include 
26
 
27
/*
28
 * ktime_t:
29
 *
30
 * 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
 */
37
union ktime {
38
	s64	tv64;
39
};
40
 
41
typedef union ktime ktime_t;		/* Kill this */
42
 
43
/**
44
 * ktime_set - Set a ktime_t variable from a seconds/nanoseconds value
45
 * @secs:	seconds to set
46
 * @nsecs:	nanoseconds to set
47
 *
48
 * Return: The ktime_t representation of the value.
49
 */
50
static 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
/* Subtract two ktime_t variables. rem = lhs -rhs: */
59
#define ktime_sub(lhs, rhs) \
60
		({ (ktime_t){ .tv64 = (lhs).tv64 - (rhs).tv64 }; })
61
 
62
/* Add two ktime_t variables. res = lhs + rhs: */
63
#define ktime_add(lhs, rhs) \
64
		({ (ktime_t){ .tv64 = (lhs).tv64 + (rhs).tv64 }; })
65
 
66
/*
67
 * Add a ktime_t variable and a scalar nanosecond value.
68
 * res = kt + nsval:
69
 */
70
#define ktime_add_ns(kt, nsval) \
71
		({ (ktime_t){ .tv64 = (kt).tv64 + (nsval) }; })
72
 
73
/*
74
 * Subtract a scalar nanosecod from a ktime_t variable
75
 * res = kt - nsval:
76
 */
77
#define ktime_sub_ns(kt, nsval) \
78
		({ (ktime_t){ .tv64 = (kt).tv64 - (nsval) }; })
79
 
80
/* convert a timespec to ktime_t format: */
81
static inline ktime_t timespec_to_ktime(struct timespec ts)
82
{
83
	return ktime_set(ts.tv_sec, ts.tv_nsec);
84
}
85
 
86
/* convert a timespec64 to ktime_t format: */
87
static inline ktime_t timespec64_to_ktime(struct timespec64 ts)
88
{
89
	return ktime_set(ts.tv_sec, ts.tv_nsec);
90
}
91
 
92
/* convert a timeval to ktime_t format: */
93
static 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
/* Map the ktime_t to timespec conversion to ns_to_timespec function */
99
#define ktime_to_timespec(kt)		ns_to_timespec((kt).tv64)
100
 
101
/* Map the ktime_t to timespec conversion to ns_to_timespec function */
102
#define ktime_to_timespec64(kt)		ns_to_timespec64((kt).tv64)
103
 
104
/* Map the ktime_t to timeval conversion to ns_to_timeval function */
105
#define ktime_to_timeval(kt)		ns_to_timeval((kt).tv64)
106
 
107
/* Convert ktime_t to nanoseconds - NOP in the scalar storage format: */
108
#define ktime_to_ns(kt)			((kt).tv64)
109
 
110
 
111
/**
112
 * ktime_equal - Compares two ktime_t variables to see if they are equal
113
 * @cmp1:	comparable1
114
 * @cmp2:	comparable2
115
 *
116
 * Compare two ktime_t variables.
117
 *
118
 * Return: 1 if equal.
119
 */
120
static inline int ktime_equal(const ktime_t cmp1, const ktime_t cmp2)
121
{
122
	return cmp1.tv64 == cmp2.tv64;
123
}
124
 
125
/**
126
 * ktime_compare - Compares two ktime_t variables for less, greater or equal
127
 * @cmp1:	comparable1
128
 * @cmp2:	comparable2
129
 *
130
 * Return: ...
131
 *   cmp1  < cmp2: return <0
132
 *   cmp1 == cmp2: return 0
133
 *   cmp1  > cmp2: return >0
134
 */
135
static 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
 * ktime_after - Compare if a ktime_t value is bigger than another one.
146
 * @cmp1:	comparable1
147
 * @cmp2:	comparable2
148
 *
149
 * Return: true if cmp1 happened after cmp2.
150
 */
151
static inline bool ktime_after(const ktime_t cmp1, const ktime_t cmp2)
152
{
153
	return ktime_compare(cmp1, cmp2) > 0;
154
}
155
 
156
/**
157
 * ktime_before - Compare if a ktime_t value is smaller than another one.
158
 * @cmp1:	comparable1
159
 * @cmp2:	comparable2
160
 *
161
 * Return: true if cmp1 happened before cmp2.
162
 */
163
static 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
169
extern s64 __ktime_divns(const ktime_t kt, s64 div);
170
static inline s64 ktime_divns(const ktime_t kt, s64 div)
171
{
172
	/*
173
	 * Negative divisors could cause an inf loop,
174
	 * so bug out here.
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 /* BITS_PER_LONG < 64 */
188
static inline s64 ktime_divns(const ktime_t kt, s64 div)
189
{
190
	/*
191
	 * 32-bit implementation cannot handle negative divisors,
192
	 * so catch them on 64bit as well.
193
	 */
194
	WARN_ON(div < 0);
195
	return kt.tv64 / div;
196
}
197
#endif
198
 
199
static inline s64 ktime_to_us(const ktime_t kt)
200
{
201
	return ktime_divns(kt, NSEC_PER_USEC);
202
}
203
 
204
static inline s64 ktime_to_ms(const ktime_t kt)
205
{
206
	return ktime_divns(kt, NSEC_PER_MSEC);
207
}
208
 
209
static 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
 
214
static 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
 
219
static 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
 
224
static 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
 
229
static 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
 
234
extern ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs);
235
 
236
/**
237
 * ktime_to_timespec_cond - convert a ktime_t variable to timespec
238
 *			    format only if the variable contains data
239
 * @kt:		the ktime_t variable to convert
240
 * @ts:		the timespec variable to store the result in
241
 *
242
 * Return: %true if there was a successful conversion, %false if kt was 0.
243
 */
244
static 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
 * ktime_to_timespec64_cond - convert a ktime_t variable to timespec64
257
 *			    format only if the variable contains data
258
 * @kt:		the ktime_t variable to convert
259
 * @ts:		the timespec variable to store the result in
260
 *
261
 * Return: %true if there was a successful conversion, %false if kt was 0.
262
 */
263
static 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
 * The resolution of the clocks. The resolution value is returned in
276
 * the clock_getres() system call to give application programmers an
277
 * idea of the (in)accuracy of timers. Timer values are rounded up to
278
 * this resolution values.
279
 */
280
#define LOW_RES_NSEC		TICK_NSEC
281
#define KTIME_LOW_RES		(ktime_t){ .tv64 = LOW_RES_NSEC }
282
 
283
ktime_t ktime_get(void);
284
 
285
static inline ktime_t ns_to_ktime(u64 ns)
286
{
287
	static const ktime_t ktime_zero = { .tv64 = 0 };
288
 
289
	return ktime_add_ns(ktime_zero, ns);
290
}
291
 
292
static inline ktime_t ms_to_ktime(u64 ms)
293
{
294
	static const ktime_t ktime_zero = { .tv64 = 0 };
295
 
296
	return ktime_add_ms(ktime_zero, ms);
297
}
298
 
299
static inline u64 ktime_get_raw_ns(void)
300
{
301
    return ktime_get().tv64;
302
}
303
 
304
#endif