Subversion Repositories Kolibri OS

Rev

Rev 5270 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #ifndef _LINUX_TIME64_H
  2. #define _LINUX_TIME64_H
  3.  
  4. #include <uapi/linux/time.h>
  5. #include <linux/math64.h>
  6.  
  7. typedef __s64 time64_t;
  8.  
  9. /*
  10.  * This wants to go into uapi/linux/time.h once we agreed about the
  11.  * userspace interfaces.
  12.  */
  13. #if __BITS_PER_LONG == 64
  14. # define timespec64 timespec
  15. #define itimerspec64 itimerspec
  16. #else
  17. struct timespec64 {
  18.         time64_t        tv_sec;                 /* seconds */
  19.         long            tv_nsec;                /* nanoseconds */
  20. };
  21.  
  22. struct itimerspec64 {
  23.         struct timespec64 it_interval;
  24.         struct timespec64 it_value;
  25. };
  26.  
  27. #endif
  28.  
  29. /* Parameters used to convert the timespec values: */
  30. #define MSEC_PER_SEC    1000L
  31. #define USEC_PER_MSEC   1000L
  32. #define NSEC_PER_USEC   1000L
  33. #define NSEC_PER_MSEC   1000000L
  34. #define USEC_PER_SEC    1000000L
  35. #define NSEC_PER_SEC    1000000000L
  36. #define FSEC_PER_SEC    1000000000000000LL
  37.  
  38. /* Located here for timespec[64]_valid_strict */
  39. #define TIME64_MAX                      ((s64)~((u64)1 << 63))
  40. #define KTIME_MAX                       ((s64)~((u64)1 << 63))
  41. #define KTIME_SEC_MAX                   (KTIME_MAX / NSEC_PER_SEC)
  42.  
  43. #if __BITS_PER_LONG == 64
  44.  
  45. static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64)
  46. {
  47.         return ts64;
  48. }
  49.  
  50. static inline struct timespec64 timespec_to_timespec64(const struct timespec ts)
  51. {
  52.         return ts;
  53. }
  54.  
  55. static inline struct itimerspec itimerspec64_to_itimerspec(struct itimerspec64 *its64)
  56. {
  57.         return *its64;
  58. }
  59.  
  60. static inline struct itimerspec64 itimerspec_to_itimerspec64(struct itimerspec *its)
  61. {
  62.         return *its;
  63. }
  64.  
  65. # define timespec64_equal               timespec_equal
  66. # define timespec64_compare             timespec_compare
  67. # define set_normalized_timespec64      set_normalized_timespec
  68. # define timespec64_add_safe            timespec_add_safe
  69. # define timespec64_add                 timespec_add
  70. # define timespec64_sub                 timespec_sub
  71. # define timespec64_valid               timespec_valid
  72. # define timespec64_valid_strict        timespec_valid_strict
  73. # define timespec64_to_ns               timespec_to_ns
  74. # define ns_to_timespec64               ns_to_timespec
  75. # define timespec64_add_ns              timespec_add_ns
  76.  
  77. #else
  78.  
  79. static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64)
  80. {
  81.         struct timespec ret;
  82.  
  83.         ret.tv_sec = (time_t)ts64.tv_sec;
  84.         ret.tv_nsec = ts64.tv_nsec;
  85.         return ret;
  86. }
  87.  
  88. static inline struct timespec64 timespec_to_timespec64(const struct timespec ts)
  89. {
  90.         struct timespec64 ret;
  91.  
  92.         ret.tv_sec = ts.tv_sec;
  93.         ret.tv_nsec = ts.tv_nsec;
  94.         return ret;
  95. }
  96.  
  97. static inline struct itimerspec itimerspec64_to_itimerspec(struct itimerspec64 *its64)
  98. {
  99.         struct itimerspec ret;
  100.  
  101.         ret.it_interval = timespec64_to_timespec(its64->it_interval);
  102.         ret.it_value = timespec64_to_timespec(its64->it_value);
  103.         return ret;
  104. }
  105.  
  106. static inline struct itimerspec64 itimerspec_to_itimerspec64(struct itimerspec *its)
  107. {
  108.         struct itimerspec64 ret;
  109.  
  110.         ret.it_interval = timespec_to_timespec64(its->it_interval);
  111.         ret.it_value = timespec_to_timespec64(its->it_value);
  112.         return ret;
  113. }
  114.  
  115. static inline int timespec64_equal(const struct timespec64 *a,
  116.                                    const struct timespec64 *b)
  117. {
  118.         return (a->tv_sec == b->tv_sec) && (a->tv_nsec == b->tv_nsec);
  119. }
  120.  
  121. /*
  122.  * lhs < rhs:  return <0
  123.  * lhs == rhs: return 0
  124.  * lhs > rhs:  return >0
  125.  */
  126. static inline int timespec64_compare(const struct timespec64 *lhs, const struct timespec64 *rhs)
  127. {
  128.         if (lhs->tv_sec < rhs->tv_sec)
  129.                 return -1;
  130.         if (lhs->tv_sec > rhs->tv_sec)
  131.                 return 1;
  132.         return lhs->tv_nsec - rhs->tv_nsec;
  133. }
  134.  
  135. extern void set_normalized_timespec64(struct timespec64 *ts, time64_t sec, s64 nsec);
  136.  
  137. /*
  138.  * timespec64_add_safe assumes both values are positive and checks for
  139.  * overflow. It will return TIME_T_MAX if the returned value would be
  140.  * smaller then either of the arguments.
  141.  */
  142. extern struct timespec64 timespec64_add_safe(const struct timespec64 lhs,
  143.                                          const struct timespec64 rhs);
  144.  
  145.  
  146. static inline struct timespec64 timespec64_add(struct timespec64 lhs,
  147.                                                 struct timespec64 rhs)
  148. {
  149.         struct timespec64 ts_delta;
  150.         set_normalized_timespec64(&ts_delta, lhs.tv_sec + rhs.tv_sec,
  151.                                 lhs.tv_nsec + rhs.tv_nsec);
  152.         return ts_delta;
  153. }
  154.  
  155. /*
  156.  * sub = lhs - rhs, in normalized form
  157.  */
  158. static inline struct timespec64 timespec64_sub(struct timespec64 lhs,
  159.                                                 struct timespec64 rhs)
  160. {
  161.         struct timespec64 ts_delta;
  162.         set_normalized_timespec64(&ts_delta, lhs.tv_sec - rhs.tv_sec,
  163.                                 lhs.tv_nsec - rhs.tv_nsec);
  164.         return ts_delta;
  165. }
  166.  
  167. /*
  168.  * Returns true if the timespec64 is norm, false if denorm:
  169.  */
  170. static inline bool timespec64_valid(const struct timespec64 *ts)
  171. {
  172.         /* Dates before 1970 are bogus */
  173.         if (ts->tv_sec < 0)
  174.                 return false;
  175.         /* Can't have more nanoseconds then a second */
  176.         if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC)
  177.                 return false;
  178.         return true;
  179. }
  180.  
  181. static inline bool timespec64_valid_strict(const struct timespec64 *ts)
  182. {
  183.         if (!timespec64_valid(ts))
  184.                 return false;
  185.         /* Disallow values that could overflow ktime_t */
  186.         if ((unsigned long long)ts->tv_sec >= KTIME_SEC_MAX)
  187.                 return false;
  188.         return true;
  189. }
  190.  
  191. /**
  192.  * timespec64_to_ns - Convert timespec64 to nanoseconds
  193.  * @ts:         pointer to the timespec64 variable to be converted
  194.  *
  195.  * Returns the scalar nanosecond representation of the timespec64
  196.  * parameter.
  197.  */
  198. static inline s64 timespec64_to_ns(const struct timespec64 *ts)
  199. {
  200.         return ((s64) ts->tv_sec * NSEC_PER_SEC) + ts->tv_nsec;
  201. }
  202.  
  203. /**
  204.  * ns_to_timespec64 - Convert nanoseconds to timespec64
  205.  * @nsec:       the nanoseconds value to be converted
  206.  *
  207.  * Returns the timespec64 representation of the nsec parameter.
  208.  */
  209. extern struct timespec64 ns_to_timespec64(const s64 nsec);
  210.  
  211. /**
  212.  * timespec64_add_ns - Adds nanoseconds to a timespec64
  213.  * @a:          pointer to timespec64 to be incremented
  214.  * @ns:         unsigned nanoseconds value to be added
  215.  *
  216.  * This must always be inlined because its used from the x86-64 vdso,
  217.  * which cannot call other kernel functions.
  218.  */
  219. static __always_inline void timespec64_add_ns(struct timespec64 *a, u64 ns)
  220. {
  221.         a->tv_sec += __iter_div_u64_rem(a->tv_nsec + ns, NSEC_PER_SEC, &ns);
  222.         a->tv_nsec = ns;
  223. }
  224.  
  225. #endif
  226.  
  227. #endif /* _LINUX_TIME64_H */
  228.