Subversion Repositories Kolibri OS

Rev

Rev 4244 | Rev 6082 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include <linux/jiffies.h>
  2.  
  3.  
  4.  
  5. #define HZ_TO_MSEC_MUL32 0xA0000000
  6. #define HZ_TO_MSEC_ADJ32 0x0
  7. #define HZ_TO_MSEC_SHR32 28
  8. #define HZ_TO_MSEC_MUL64 0xA000000000000000
  9. #define HZ_TO_MSEC_ADJ64 0x0
  10. #define HZ_TO_MSEC_SHR64 60
  11. #define MSEC_TO_HZ_MUL32 0xCCCCCCCD
  12. #define MSEC_TO_HZ_ADJ32 0x733333333
  13. #define MSEC_TO_HZ_SHR32 35
  14. #define MSEC_TO_HZ_MUL64 0xCCCCCCCCCCCCCCCD
  15. #define MSEC_TO_HZ_ADJ64 0x73333333333333333
  16. #define MSEC_TO_HZ_SHR64 67
  17. #define HZ_TO_MSEC_NUM 10
  18. #define HZ_TO_MSEC_DEN 1
  19. #define MSEC_TO_HZ_NUM 1
  20. #define MSEC_TO_HZ_DEN 10
  21.  
  22. #define HZ_TO_USEC_MUL32 0x9C400000
  23. #define HZ_TO_USEC_ADJ32 0x0
  24. #define HZ_TO_USEC_SHR32 18
  25. #define HZ_TO_USEC_MUL64 0x9C40000000000000
  26. #define HZ_TO_USEC_ADJ64 0x0
  27. #define HZ_TO_USEC_SHR64 50
  28. #define USEC_TO_HZ_MUL32 0xD1B71759
  29. #define USEC_TO_HZ_ADJ32 0x1FFF2E48E8A7
  30. #define USEC_TO_HZ_SHR32 45
  31. #define USEC_TO_HZ_MUL64 0xD1B71758E219652C
  32. #define USEC_TO_HZ_ADJ64 0x1FFF2E48E8A71DE69AD4
  33. #define USEC_TO_HZ_SHR64 77
  34. #define HZ_TO_USEC_NUM 10000
  35. #define HZ_TO_USEC_DEN 1
  36. #define USEC_TO_HZ_NUM 1
  37. #define USEC_TO_HZ_DEN 10000
  38.  
  39.  
  40. #define MSEC_PER_SEC    1000L
  41. #define USEC_PER_MSEC   1000L
  42. #define NSEC_PER_USEC   1000L
  43. #define NSEC_PER_MSEC   1000000L
  44. #define USEC_PER_SEC    1000000L
  45. #define NSEC_PER_SEC    1000000000L
  46. #define FSEC_PER_SEC    1000000000000000LL
  47.  
  48.  
  49. unsigned int jiffies_to_msecs(const unsigned long j)
  50. {
  51. #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
  52.         return (MSEC_PER_SEC / HZ) * j;
  53. #elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
  54.         return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC);
  55. #else
  56. # if BITS_PER_LONG == 32
  57.         return (HZ_TO_MSEC_MUL32 * j) >> HZ_TO_MSEC_SHR32;
  58. # else
  59.         return (j * HZ_TO_MSEC_NUM) / HZ_TO_MSEC_DEN;
  60. # endif
  61. #endif
  62. }
  63.  
  64. unsigned int jiffies_to_usecs(const unsigned long j)
  65. {
  66. #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
  67.         return (USEC_PER_SEC / HZ) * j;
  68. #elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
  69.         return (j + (HZ / USEC_PER_SEC) - 1)/(HZ / USEC_PER_SEC);
  70. #else
  71. # if BITS_PER_LONG == 32
  72.         return (HZ_TO_USEC_MUL32 * j) >> HZ_TO_USEC_SHR32;
  73. # else
  74.         return (j * HZ_TO_USEC_NUM) / HZ_TO_USEC_DEN;
  75. # endif
  76. #endif
  77. }
  78.  
  79.  
  80. /*
  81.  * When we convert to jiffies then we interpret incoming values
  82.  * the following way:
  83.  *
  84.  * - negative values mean 'infinite timeout' (MAX_JIFFY_OFFSET)
  85.  *
  86.  * - 'too large' values [that would result in larger than
  87.  *   MAX_JIFFY_OFFSET values] mean 'infinite timeout' too.
  88.  *
  89.  * - all other values are converted to jiffies by either multiplying
  90.  *   the input value by a factor or dividing it with a factor
  91.  *
  92.  * We must also be careful about 32-bit overflows.
  93.  */
  94. unsigned long msecs_to_jiffies(const unsigned int m)
  95. {
  96.     /*
  97.      * Negative value, means infinite timeout:
  98.      */
  99.     if ((int)m < 0)
  100.         return MAX_JIFFY_OFFSET;
  101.  
  102. #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
  103.     /*
  104.      * HZ is equal to or smaller than 1000, and 1000 is a nice
  105.      * round multiple of HZ, divide with the factor between them,
  106.      * but round upwards:
  107.      */
  108.     return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ);
  109. #elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
  110.     /*
  111.      * HZ is larger than 1000, and HZ is a nice round multiple of
  112.      * 1000 - simply multiply with the factor between them.
  113.      *
  114.      * But first make sure the multiplication result cannot
  115.      * overflow:
  116.      */
  117.     if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
  118.         return MAX_JIFFY_OFFSET;
  119.  
  120.     return m * (HZ / MSEC_PER_SEC);
  121. #else
  122.     /*
  123.      * Generic case - multiply, round and divide. But first
  124.      * check that if we are doing a net multiplication, that
  125.      * we wouldn't overflow:
  126.      */
  127.     if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
  128.         return MAX_JIFFY_OFFSET;
  129.  
  130.     return (MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32)
  131.         >> MSEC_TO_HZ_SHR32;
  132. #endif
  133. }
  134. EXPORT_SYMBOL(msecs_to_jiffies);
  135.  
  136. unsigned long usecs_to_jiffies(const unsigned int u)
  137. {
  138.     if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET))
  139.         return MAX_JIFFY_OFFSET;
  140. #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
  141.     return (u + (USEC_PER_SEC / HZ) - 1) / (USEC_PER_SEC / HZ);
  142. #elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
  143.     return u * (HZ / USEC_PER_SEC);
  144. #else
  145.     return (USEC_TO_HZ_MUL32 * u + USEC_TO_HZ_ADJ32)
  146.         >> USEC_TO_HZ_SHR32;
  147. #endif
  148. }
  149. EXPORT_SYMBOL(usecs_to_jiffies);
  150.  
  151. /*
  152.  * The TICK_NSEC - 1 rounds up the value to the next resolution.  Note
  153.  * that a remainder subtract here would not do the right thing as the
  154.  * resolution values don't fall on second boundries.  I.e. the line:
  155.  * nsec -= nsec % TICK_NSEC; is NOT a correct resolution rounding.
  156.  * Note that due to the small error in the multiplier here, this
  157.  * rounding is incorrect for sufficiently large values of tv_nsec, but
  158.  * well formed timespecs should have tv_nsec < NSEC_PER_SEC, so we're
  159.  * OK.
  160.  *
  161.  * Rather, we just shift the bits off the right.
  162.  *
  163.  * The >> (NSEC_JIFFIE_SC - SEC_JIFFIE_SC) converts the scaled nsec
  164.  * value to a scaled second value.
  165.  */
  166. static unsigned long
  167. __timespec_to_jiffies(unsigned long sec, long nsec)
  168. {
  169.         nsec = nsec + TICK_NSEC - 1;
  170.  
  171.     if (sec >= MAX_SEC_IN_JIFFIES){
  172.             sec = MAX_SEC_IN_JIFFIES;
  173.             nsec = 0;
  174.     }
  175.     return (((u64)sec * SEC_CONVERSION) +
  176.             (((u64)nsec * NSEC_CONVERSION) >>
  177.              (NSEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC;
  178.  
  179. }
  180.  
  181. unsigned long
  182. timespec_to_jiffies(const struct timespec *value)
  183. {
  184.         return __timespec_to_jiffies(value->tv_sec, value->tv_nsec);
  185. }
  186.  
  187. EXPORT_SYMBOL(timespec_to_jiffies);
  188.  
  189. void
  190. jiffies_to_timespec(const unsigned long jiffies, struct timespec *value)
  191. {
  192.         /*
  193.          * Convert jiffies to nanoseconds and separate with
  194.          * one divide.
  195.          */
  196.         u32 rem;
  197.         value->tv_sec = div_u64_rem((u64)jiffies * TICK_NSEC,
  198.                                     NSEC_PER_SEC, &rem);
  199.         value->tv_nsec = rem;
  200. }
  201. EXPORT_SYMBOL(jiffies_to_timespec);
  202.  
  203. s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder)
  204. {
  205.         u64 quotient;
  206.  
  207.         if (dividend < 0) {
  208.                 quotient = div_u64_rem(-dividend, abs(divisor), (u32 *)remainder);
  209.                 *remainder = -*remainder;
  210.                 if (divisor > 0)
  211.                         quotient = -quotient;
  212.         } else {
  213.                 quotient = div_u64_rem(dividend, abs(divisor), (u32 *)remainder);
  214.                 if (divisor < 0)
  215.                         quotient = -quotient;
  216.         }
  217.         return quotient;
  218. }
  219.  
  220. struct timespec ns_to_timespec(const s64 nsec)
  221. {
  222.         struct timespec ts;
  223.         s32 rem;
  224.  
  225.         if (!nsec)
  226.                 return (struct timespec) {0, 0};
  227.  
  228.         ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem);
  229.         if (unlikely(rem < 0)) {
  230.                 ts.tv_sec--;
  231.                 rem += NSEC_PER_SEC;
  232.         }
  233.         ts.tv_nsec = rem;
  234.  
  235.         return ts;
  236. }
  237.  
  238.