vserver 1.9.3
[linux-2.6.git] / include / linux / times.h
index a682537..0c5aa07 100644 (file)
@@ -2,15 +2,21 @@
 #define _LINUX_TIMES_H
 
 #ifdef __KERNEL__
+#include <linux/timex.h>
 #include <asm/div64.h>
 #include <asm/types.h>
 #include <asm/param.h>
 
-#if (HZ % USER_HZ)==0
-# define jiffies_to_clock_t(x) ((x) / (HZ / USER_HZ))
+static inline clock_t jiffies_to_clock_t(long x)
+{
+#if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
+       return x / (HZ / USER_HZ);
 #else
-# define jiffies_to_clock_t(x) ((clock_t) jiffies_64_to_clock_t((u64) x))
+       u64 tmp = (u64)x * TICK_NSEC;
+       do_div(tmp, (NSEC_PER_SEC / USER_HZ));
+       return (long)tmp;
 #endif
+}
 
 static inline unsigned long clock_t_to_jiffies(unsigned long x)
 {
@@ -34,7 +40,7 @@ static inline unsigned long clock_t_to_jiffies(unsigned long x)
 
 static inline u64 jiffies_64_to_clock_t(u64 x)
 {
-#if (HZ % USER_HZ)==0
+#if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
        do_div(x, HZ / USER_HZ);
 #else
        /*
@@ -42,13 +48,33 @@ static inline u64 jiffies_64_to_clock_t(u64 x)
         * but even this doesn't overflow in hundreds of years
         * in 64 bits, so..
         */
-       x *= USER_HZ;
-       do_div(x, HZ);
+       x *= TICK_NSEC;
+       do_div(x, (NSEC_PER_SEC / USER_HZ));
 #endif
        return x;
 }
 #endif
 
+static inline u64 nsec_to_clock_t(u64 x)
+{
+#if (NSEC_PER_SEC % USER_HZ) == 0
+       do_div(x, (NSEC_PER_SEC / USER_HZ));
+#elif (USER_HZ % 512) == 0
+       x *= USER_HZ/512;
+       do_div(x, (NSEC_PER_SEC / 512));
+#else
+       /*
+         * max relative error 5.7e-8 (1.8s per year) for USER_HZ <= 1024,
+         * overflow after 64.99 years.
+         * exact for HZ=60, 72, 90, 120, 144, 180, 300, 600, 900, ...
+         */
+       x *= 9;
+       do_div(x, (unsigned long)((9ull * NSEC_PER_SEC + (USER_HZ/2))
+                                 / USER_HZ));
+#endif
+       return x;
+}
+
 struct tms {
        clock_t tms_utime;
        clock_t tms_stime;