some preliminaries for vdso clock support
authorRich Felker <dalias@aerifal.cx>
Sun, 24 Jul 2011 03:45:33 +0000 (23:45 -0400)
committerRich Felker <dalias@aerifal.cx>
Sun, 24 Jul 2011 03:45:33 +0000 (23:45 -0400)
these changes also make it so clock_gettime(CLOCK_REALTIME, &ts) works
even on pre-2.6 kernels, emulated via the gettimeofday syscall. there
is no cost for the fallback check, as it falls under the error case
that already must be checked for storing the error code in errno, but
which would normally be hidden inside __syscall_ret.

src/time/clock_gettime.c
src/time/gettimeofday.c
src/time/time.c

index c345c46e03e5be739dc1871b7706bf23424fac6a..c27c9e9e4ed0b77636e05532778c0bf0782f3268 100644 (file)
@@ -1,7 +1,28 @@
 #include <time.h>
+#include <errno.h>
+#include <stdint.h>
 #include "syscall.h"
+#include "libc.h"
 
-int clock_gettime(clockid_t clk, struct timespec *ts)
+int __vdso_clock_gettime(clockid_t, struct timespec *) __attribute__((weak));
+static int (*cgt)(clockid_t, struct timespec *) = __vdso_clock_gettime;
+
+int __clock_gettime(clockid_t clk, struct timespec *ts)
 {
-       return syscall(SYS_clock_gettime, clk, ts);
+       int r;
+       if (cgt) return cgt(clk, ts);
+       r = __syscall(SYS_clock_gettime, clk, ts);
+       if (!r) return r;
+       if (r == -ENOSYS) {
+               if (clk == CLOCK_REALTIME) {
+                       __syscall(SYS_gettimeofday, clk, ts, 0);
+                       ts->tv_nsec = (int)ts->tv_nsec * 1000;
+                       return 0;
+               }
+               r = -EINVAL;
+       }
+       errno = -r;
+       return -1;
 }
+
+weak_alias(__clock_gettime, clock_gettime);
index 2436e490410707a69d20ea820b5f4294cc1420ea..09afb70bf8ef4f8ba7ccb12fe381319023f105f0 100644 (file)
@@ -1,8 +1,13 @@
+#include <time.h>
 #include <sys/time.h>
 #include "syscall.h"
 
 int gettimeofday(struct timeval *tv, void *tz)
 {
-       __syscall(SYS_gettimeofday, tv, 0);
+       struct timespec ts;
+       if (!tv) return 0;
+       clock_gettime(CLOCK_REALTIME, &ts);
+       tv->tv_sec = ts.tv_sec;
+       tv->tv_usec = (int)ts.tv_nsec / 1000;
        return 0;
 }
index 05e075b95273466114941e2bf3c20f62f19a060c..22754850d8e4bf4e6792779714610b018ee63825 100644 (file)
@@ -2,10 +2,12 @@
 #include <sys/time.h>
 #include "syscall.h"
 
+int __clock_gettime(clockid_t, struct timespec *);
+
 time_t time(time_t *t)
 {
-       struct timeval tv;
-       __syscall(SYS_gettimeofday, &tv, 0);
-       if (t) *t = tv.tv_sec;
-       return tv.tv_sec;
+       struct timespec ts;
+       __clock_gettime(CLOCK_REALTIME, &ts);
+       if (t) *t = ts.tv_sec;
+       return ts.tv_sec;
 }