aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/jiffies.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/jiffies.h')
-rw-r--r--include/linux/jiffies.h222
1 files changed, 19 insertions, 203 deletions
diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index 0ec6e28bccd2..c080f61fb024 100644
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -142,13 +142,13 @@ static inline u64 get_jiffies_64(void)
142 * 142 *
143 * And some not so obvious. 143 * And some not so obvious.
144 * 144 *
145 * Note that we don't want to return MAX_LONG, because 145 * Note that we don't want to return LONG_MAX, because
146 * for various timeout reasons we often end up having 146 * for various timeout reasons we often end up having
147 * to wait "jiffies+1" in order to guarantee that we wait 147 * to wait "jiffies+1" in order to guarantee that we wait
148 * at _least_ "jiffies" - so "jiffies+1" had better still 148 * at _least_ "jiffies" - so "jiffies+1" had better still
149 * be positive. 149 * be positive.
150 */ 150 */
151#define MAX_JIFFY_OFFSET ((~0UL >> 1)-1) 151#define MAX_JIFFY_OFFSET ((LONG_MAX >> 1)-1)
152 152
153/* 153/*
154 * We want to do realistic conversions of time so we need to use the same 154 * We want to do realistic conversions of time so we need to use the same
@@ -259,207 +259,23 @@ static inline u64 get_jiffies_64(void)
259#endif 259#endif
260 260
261/* 261/*
262 * Convert jiffies to milliseconds and back. 262 * Convert various time units to each other:
263 *
264 * Avoid unnecessary multiplications/divisions in the
265 * two most common HZ cases:
266 */
267static inline unsigned int jiffies_to_msecs(const unsigned long j)
268{
269#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
270 return (MSEC_PER_SEC / HZ) * j;
271#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
272 return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC);
273#else
274 return (j * MSEC_PER_SEC) / HZ;
275#endif
276}
277
278static inline unsigned int jiffies_to_usecs(const unsigned long j)
279{
280#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
281 return (USEC_PER_SEC / HZ) * j;
282#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
283 return (j + (HZ / USEC_PER_SEC) - 1)/(HZ / USEC_PER_SEC);
284#else
285 return (j * USEC_PER_SEC) / HZ;
286#endif
287}
288
289static inline unsigned long msecs_to_jiffies(const unsigned int m)
290{
291 if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
292 return MAX_JIFFY_OFFSET;
293#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
294 return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ);
295#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
296 return m * (HZ / MSEC_PER_SEC);
297#else
298 return (m * HZ + MSEC_PER_SEC - 1) / MSEC_PER_SEC;
299#endif
300}
301
302static inline unsigned long usecs_to_jiffies(const unsigned int u)
303{
304 if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET))
305 return MAX_JIFFY_OFFSET;
306#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
307 return (u + (USEC_PER_SEC / HZ) - 1) / (USEC_PER_SEC / HZ);
308#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
309 return u * (HZ / USEC_PER_SEC);
310#else
311 return (u * HZ + USEC_PER_SEC - 1) / USEC_PER_SEC;
312#endif
313}
314
315/*
316 * The TICK_NSEC - 1 rounds up the value to the next resolution. Note
317 * that a remainder subtract here would not do the right thing as the
318 * resolution values don't fall on second boundries. I.e. the line:
319 * nsec -= nsec % TICK_NSEC; is NOT a correct resolution rounding.
320 *
321 * Rather, we just shift the bits off the right.
322 *
323 * The >> (NSEC_JIFFIE_SC - SEC_JIFFIE_SC) converts the scaled nsec
324 * value to a scaled second value.
325 */
326static __inline__ unsigned long
327timespec_to_jiffies(const struct timespec *value)
328{
329 unsigned long sec = value->tv_sec;
330 long nsec = value->tv_nsec + TICK_NSEC - 1;
331
332 if (sec >= MAX_SEC_IN_JIFFIES){
333 sec = MAX_SEC_IN_JIFFIES;
334 nsec = 0;
335 }
336 return (((u64)sec * SEC_CONVERSION) +
337 (((u64)nsec * NSEC_CONVERSION) >>
338 (NSEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC;
339
340}
341
342static __inline__ void
343jiffies_to_timespec(const unsigned long jiffies, struct timespec *value)
344{
345 /*
346 * Convert jiffies to nanoseconds and separate with
347 * one divide.
348 */
349 u64 nsec = (u64)jiffies * TICK_NSEC;
350 value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &value->tv_nsec);
351}
352
353/* Same for "timeval"
354 *
355 * Well, almost. The problem here is that the real system resolution is
356 * in nanoseconds and the value being converted is in micro seconds.
357 * Also for some machines (those that use HZ = 1024, in-particular),
358 * there is a LARGE error in the tick size in microseconds.
359
360 * The solution we use is to do the rounding AFTER we convert the
361 * microsecond part. Thus the USEC_ROUND, the bits to be shifted off.
362 * Instruction wise, this should cost only an additional add with carry
363 * instruction above the way it was done above.
364 */
365static __inline__ unsigned long
366timeval_to_jiffies(const struct timeval *value)
367{
368 unsigned long sec = value->tv_sec;
369 long usec = value->tv_usec;
370
371 if (sec >= MAX_SEC_IN_JIFFIES){
372 sec = MAX_SEC_IN_JIFFIES;
373 usec = 0;
374 }
375 return (((u64)sec * SEC_CONVERSION) +
376 (((u64)usec * USEC_CONVERSION + USEC_ROUND) >>
377 (USEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC;
378}
379
380static __inline__ void
381jiffies_to_timeval(const unsigned long jiffies, struct timeval *value)
382{
383 /*
384 * Convert jiffies to nanoseconds and separate with
385 * one divide.
386 */
387 u64 nsec = (u64)jiffies * TICK_NSEC;
388 long tv_usec;
389
390 value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &tv_usec);
391 tv_usec /= NSEC_PER_USEC;
392 value->tv_usec = tv_usec;
393}
394
395/*
396 * Convert jiffies/jiffies_64 to clock_t and back.
397 */ 263 */
398static inline clock_t jiffies_to_clock_t(long x) 264extern unsigned int jiffies_to_msecs(const unsigned long j);
399{ 265extern unsigned int jiffies_to_usecs(const unsigned long j);
400#if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 266extern unsigned long msecs_to_jiffies(const unsigned int m);
401 return x / (HZ / USER_HZ); 267extern unsigned long usecs_to_jiffies(const unsigned int u);
402#else 268extern unsigned long timespec_to_jiffies(const struct timespec *value);
403 u64 tmp = (u64)x * TICK_NSEC; 269extern void jiffies_to_timespec(const unsigned long jiffies,
404 do_div(tmp, (NSEC_PER_SEC / USER_HZ)); 270 struct timespec *value);
405 return (long)tmp; 271extern unsigned long timeval_to_jiffies(const struct timeval *value);
406#endif 272extern void jiffies_to_timeval(const unsigned long jiffies,
407} 273 struct timeval *value);
408 274extern clock_t jiffies_to_clock_t(long x);
409static inline unsigned long clock_t_to_jiffies(unsigned long x) 275extern unsigned long clock_t_to_jiffies(unsigned long x);
410{ 276extern u64 jiffies_64_to_clock_t(u64 x);
411#if (HZ % USER_HZ)==0 277extern u64 nsec_to_clock_t(u64 x);
412 if (x >= ~0UL / (HZ / USER_HZ)) 278
413 return ~0UL; 279#define TIMESTAMP_SIZE 30
414 return x * (HZ / USER_HZ);
415#else
416 u64 jif;
417
418 /* Don't worry about loss of precision here .. */
419 if (x >= ~0UL / HZ * USER_HZ)
420 return ~0UL;
421
422 /* .. but do try to contain it here */
423 jif = x * (u64) HZ;
424 do_div(jif, USER_HZ);
425 return jif;
426#endif
427}
428
429static inline u64 jiffies_64_to_clock_t(u64 x)
430{
431#if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
432 do_div(x, HZ / USER_HZ);
433#else
434 /*
435 * There are better ways that don't overflow early,
436 * but even this doesn't overflow in hundreds of years
437 * in 64 bits, so..
438 */
439 x *= TICK_NSEC;
440 do_div(x, (NSEC_PER_SEC / USER_HZ));
441#endif
442 return x;
443}
444
445static inline u64 nsec_to_clock_t(u64 x)
446{
447#if (NSEC_PER_SEC % USER_HZ) == 0
448 do_div(x, (NSEC_PER_SEC / USER_HZ));
449#elif (USER_HZ % 512) == 0
450 x *= USER_HZ/512;
451 do_div(x, (NSEC_PER_SEC / 512));
452#else
453 /*
454 * max relative error 5.7e-8 (1.8s per year) for USER_HZ <= 1024,
455 * overflow after 64.99 years.
456 * exact for HZ=60, 72, 90, 120, 144, 180, 300, 600, 900, ...
457 */
458 x *= 9;
459 do_div(x, (unsigned long)((9ull * NSEC_PER_SEC + (USER_HZ/2))
460 / USER_HZ));
461#endif
462 return x;
463}
464 280
465#endif 281#endif