Now that the time getter functions use the clockid as index into the
storage array for the base time access, the switch case can be replaced.

- Check for clockid >= MAX_CLOCKS and for negative clockid (CPU/FD) first
  and call the fallback function right away.

- After establishing that clockid is < MAX_CLOCKS, convert the clockid to a
  bitmask

- Check for the supported high resolution and coarse functions by anding
  the bitmask of supported clocks and check whether a bit is set.

This completely avoids jump tables, reduces the number of conditionals and
makes the VDSO extensible for other clock ids.

Signed-off-by: Thomas Gleixner <t...@linutronix.de>
---
 arch/x86/entry/vdso/vclock_gettime.c |   38 ++++++++++++++++-------------------
 1 file changed, 18 insertions(+), 20 deletions(-)

--- a/arch/x86/entry/vdso/vclock_gettime.c
+++ b/arch/x86/entry/vdso/vclock_gettime.c
@@ -239,29 +239,27 @@ notrace static void do_coarse(clockid_t
 
 notrace int __vdso_clock_gettime(clockid_t clock, struct timespec *ts)
 {
-       switch (clock) {
-       case CLOCK_REALTIME:
-               if (do_hres(CLOCK_REALTIME, ts) == VCLOCK_NONE)
-                       goto fallback;
-               break;
-       case CLOCK_MONOTONIC:
-               if (do_hres(CLOCK_MONOTONIC, ts) == VCLOCK_NONE)
-                       goto fallback;
-               break;
-       case CLOCK_REALTIME_COARSE:
-               do_coarse(CLOCK_REALTIME_COARSE, ts);
-               break;
-       case CLOCK_MONOTONIC_COARSE:
-               do_coarse(CLOCK_MONOTONIC_COARSE, ts);
-               break;
-       default:
-               goto fallback;
-       }
+       unsigned int msk;
+
+       /* Sort out negative (CPU/FD) and invalid clocks */
+       if (unlikely((unsigned int) clock >= MAX_CLOCKS))
+               return vdso_fallback_gettime(clock, ts);
 
-       return 0;
-fallback:
+       /*
+        * Convert the clockid to a bitmask and use it to check which
+        * clocks are handled in the VDSO directly.
+        */
+       msk = 1U << clock;
+       if (likely(msk & VGTOD_HRES)) {
+               if (do_hres(clock, ts) != VCLOCK_NONE)
+                       return 0;
+       } else if (msk & VGTOD_COARSE) {
+               do_coarse(clock, ts);
+               return 0;
+       }
        return vdso_fallback_gettime(clock, ts);
 }
+
 int clock_gettime(clockid_t, struct timespec *)
        __attribute__((weak, alias("__vdso_clock_gettime")));
 


_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to