The original msecs_to_jiffies is renamed to __msecs_to_jiffies and aside
from the removal of the check for negative values being moved out, is
unaltered.

Signed-off-by: Nicholas Mc Guire <[email protected]>
---

Thanks to Joe Perches <[email protected]> for suggesting this approach and
for his review comments on the first attempts and for the simple
test-case that helped after I confused my self with .lst files.

V2: remove duplicated code by moving it to helper functions
    reformatted the #ifdef to a hopefully more readable code in
    include/linux/jiffies.h and simplified __msecs_to_jiffies()
    by re-using the helpers.

Question: 
    * nameing conventions _msecs_to_jiffies() suitable as helper name ?
    * the suitability of the #ifdef/#elif/#else construct

Patch was compile and boot tested (x86_64) and a few msecs_to_jiffies()
locations verified by inspection of the .s files where constants are
reduced to a load or add instruction and the non-const. call 
__msecs_to_jiffies().

Patch is against 4.0-rc7 (localversion-next is -next-20150410)

 include/linux/jiffies.h |   35 ++++++++++++++++++++++++++++++++++-
 kernel/time/time.c      |   40 ++++++----------------------------------
 2 files changed, 40 insertions(+), 35 deletions(-)

diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index c367cbd..273b093 100644
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -7,6 +7,7 @@
 #include <linux/time.h>
 #include <linux/timex.h>
 #include <asm/param.h>                 /* for HZ */
+#include <generated/timeconst.h>
 
 /*
  * The following defines establish the engineering parameters of the PLL
@@ -288,7 +289,39 @@ static inline u64 jiffies_to_nsecs(const unsigned long j)
        return (u64)jiffies_to_usecs(j) * NSEC_PER_USEC;
 }
 
-extern unsigned long msecs_to_jiffies(const unsigned int m);
+extern unsigned long __msecs_to_jiffies(const unsigned int m);
+#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
+static inline unsigned long _msecs_to_jiffies(const unsigned int m)
+{
+               return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ);
+}
+#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
+static inline unsigned long _msecs_to_jiffies(const unsigned int m)
+{
+               if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
+                       return MAX_JIFFY_OFFSET;
+               return m * (HZ / MSEC_PER_SEC);
+}
+#else
+static inline unsigned long _msecs_to_jiffies(const unsigned int m)
+{
+               if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
+                       return MAX_JIFFY_OFFSET;
+
+               return (MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32)
+                       >> MSEC_TO_HZ_SHR32;
+}
+#endif
+static inline unsigned long msecs_to_jiffies(const unsigned int m)
+{
+       if (__builtin_constant_p(m)) {
+               if ((int)m < 0)
+                       return MAX_JIFFY_OFFSET;
+               return _msecs_to_jiffies(m);
+       } else
+               return __msecs_to_jiffies(m);
+}
+
 extern unsigned long usecs_to_jiffies(const unsigned int u);
 extern unsigned long timespec_to_jiffies(const struct timespec *value);
 extern void jiffies_to_timespec(const unsigned long jiffies,
diff --git a/kernel/time/time.c b/kernel/time/time.c
index 4fa1d26..25bee56 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -488,6 +488,8 @@ EXPORT_SYMBOL(ns_to_timespec64);
  * the following way:
  *
  * - negative values mean 'infinite timeout' (MAX_JIFFY_OFFSET)
+ *   negative values are handled in msecs_to_jiffies in
+ *   include/linux/jiffies.h
  *
  * - 'too large' values [that would result in larger than
  *   MAX_JIFFY_OFFSET values] mean 'infinite timeout' too.
@@ -496,48 +498,18 @@ EXPORT_SYMBOL(ns_to_timespec64);
  *   the input value by a factor or dividing it with a factor
  *
  * We must also be careful about 32-bit overflows.
+ *
  */
-unsigned long msecs_to_jiffies(const unsigned int m)
+unsigned long __msecs_to_jiffies(const unsigned int m)
 {
        /*
         * Negative value, means infinite timeout:
         */
        if ((int)m < 0)
                return MAX_JIFFY_OFFSET;
-
-#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
-       /*
-        * HZ is equal to or smaller than 1000, and 1000 is a nice
-        * round multiple of HZ, divide with the factor between them,
-        * but round upwards:
-        */
-       return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ);
-#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
-       /*
-        * HZ is larger than 1000, and HZ is a nice round multiple of
-        * 1000 - simply multiply with the factor between them.
-        *
-        * But first make sure the multiplication result cannot
-        * overflow:
-        */
-       if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
-               return MAX_JIFFY_OFFSET;
-
-       return m * (HZ / MSEC_PER_SEC);
-#else
-       /*
-        * Generic case - multiply, round and divide. But first
-        * check that if we are doing a net multiplication, that
-        * we wouldn't overflow:
-        */
-       if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
-               return MAX_JIFFY_OFFSET;
-
-       return (MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32)
-               >> MSEC_TO_HZ_SHR32;
-#endif
+       return _msecs_to_jiffies(m);
 }
-EXPORT_SYMBOL(msecs_to_jiffies);
+EXPORT_SYMBOL(__msecs_to_jiffies);
 
 unsigned long usecs_to_jiffies(const unsigned int u)
 {
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to