Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  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.  * 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
  305.