]> sourceware.org Git - glibc.git/commitdiff
tile: add clock_gettime support via vDSO
authorChris Metcalf <cmetcalf@tilera.com>
Wed, 1 Oct 2014 19:10:04 +0000 (15:10 -0400)
committerChris Metcalf <cmetcalf@tilera.com>
Mon, 6 Oct 2014 15:22:14 +0000 (11:22 -0400)
ChangeLog
sysdeps/unix/sysv/linux/tile/Versions
sysdeps/unix/sysv/linux/tile/bits/libc-vdso.h
sysdeps/unix/sysv/linux/tile/gettimeofday.c
sysdeps/unix/sysv/linux/tile/init-first.c
sysdeps/unix/sysv/linux/tile/sysdep.h

index 0ab15a2c53e6557cc328389edd67487e80fd4ed2..e127a08c27661b7518d37ae3b04504735672e02a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2014-10-02  Chris Metcalf  <cmetcalf@tilera.com>
 
+       * sysdeps/unix/sysv/linux/tile/sysdep.h (INLINE_VSYSCALL): Define
+       INLINE_VSYSCALL, INTERNAL_VSYSCALL, and
+       HAVE_CLOCK_GETTIME_VSYSCALL macros.
+       * sysdeps/unix/sysv/linux/tile/gettimeofday.c (__gettimeofday):
+       Use INLINE_VSYSCALL macro.
+       * sysdeps/unix/sysv/linux/tile/bits/libc-vdso: Add declaration of
+       __vdso_clock_gettime.
+       * sysdeps/unix/sysv/linux/tile/init-first.c
+       (_libc_vdso_platform_setup): Set new __vdso_clock_gettime global.
+       * sysdeps/unix/sysv/linux/tile/Versions (GLIBC_PRIVATE): Add
+       __vdso_clock_gettime.
+
        * sysdeps/unix/sysv/linux/tile/clone.S (__clone): Fix code
        to set up frame more cleanly.
 
index 9b40d2839fb326823cd32977b2fc6812646e58e8..13da68fa791535f5a9b5a8f21bf0bde348de0fd2 100644 (file)
@@ -13,5 +13,6 @@ libc {
   }
   GLIBC_PRIVATE {
     __syscall_error;
+    __vdso_clock_gettime;
   }
 }
index c4aec16d19c0bb3f0d89e4448d7f6164708b3541..f5b04ba66959d548d07739ddd5462fdd9e545b2f 100644 (file)
@@ -25,6 +25,8 @@
 extern long int (*__vdso_gettimeofday) (struct timeval *, void *)
   attribute_hidden;
 
+extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
+
 #endif
 
 #endif /* _LIBC_VDSO_H */
index 6f62ab960c6902664c5ff8ab0844eeaa96387467..2168c2a0688d96c7618cabd00da059ba14832cbe 100644 (file)
 int
 __gettimeofday (struct timeval *tv, struct timezone *tz)
 {
-#ifdef SHARED
-  /* If the vDSO is available we use it. */
-  if (__vdso_gettimeofday != NULL)
-    return __vdso_gettimeofday (tv, tz);
-#endif
-  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+  return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
 }
 
 libc_hidden_def (__gettimeofday)
index 9790d223b160334cb691df7836702dc455bea27b..fa39b94a30607dc1d5abe4163b14fef5bfb81974 100644 (file)
 
 long int (*__vdso_gettimeofday) (struct timeval *, void *) attribute_hidden;
 
+long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
+  __attribute__ ((nocommon));
+strong_alias (__vdso_clock_gettime, __GI___vdso_clock_gettime attribute_hidden)
+
+
 static inline void
 _libc_vdso_platform_setup (void)
 {
   PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
   __vdso_gettimeofday = _dl_vdso_vsym ("__vdso_gettimeofday", &linux26);
+  __vdso_clock_gettime = _dl_vdso_vsym ("__vdso_clock_gettime", &linux26);
 }
 
 #define VDSO_SETUP _libc_vdso_platform_setup
index a09f8a4adf0571d8e8c6acbaf967d1ef5127dcab..238b266a8216d436fbc794d86565d59d3c3db716 100644 (file)
   "=R02" (_clobber_r2), "=R03" (_clobber_r3), "=R04" (_clobber_r4),     \
     "=R05" (_clobber_r5), "=R10" (_clobber_r10)
 
+/* This version is for kernels that implement system calls that
+   behave like function calls as far as register saving.
+   It falls back to the syscall in the case that the vDSO doesn't
+   exist or fails for ENOSYS */
+# ifdef SHARED
+#  define INLINE_VSYSCALL(name, nr, args...) \
+  ({                                                                         \
+    __label__ out;                                                           \
+    __label__ iserr;                                                         \
+    INTERNAL_SYSCALL_DECL (sc_err);                                          \
+    long int sc_ret;                                                         \
+                                                                             \
+    __typeof (__vdso_##name) vdsop = __vdso_##name;                          \
+    if (vdsop != NULL)                                                       \
+      {                                                                              \
+        sc_ret = vdsop (args);                                               \
+        if (!INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err))                              \
+          goto out;                                                          \
+        if (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err) != ENOSYS)               \
+          goto iserr;                                                        \
+      }                                                                              \
+                                                                             \
+    sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, ##args);                    \
+    if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err))                           \
+      {                                                                              \
+      iserr:                                                                 \
+        __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err));               \
+        sc_ret = -1L;                                                        \
+      }                                                                              \
+  out:                                                                       \
+    sc_ret;                                                                  \
+  })
+#  define INTERNAL_VSYSCALL(name, err, nr, args...) \
+  ({                                                                         \
+    __label__ out;                                                           \
+    long int v_ret;                                                          \
+                                                                             \
+    __typeof (__vdso_##name) vdsop = __vdso_##name;                          \
+    if (vdsop != NULL)                                                       \
+      {                                                                              \
+        v_ret = vdsop (args);                                                \
+        if (!INTERNAL_SYSCALL_ERROR_P (v_ret, err)                           \
+            || INTERNAL_SYSCALL_ERRNO (v_ret, err) != ENOSYS)                \
+          goto out;                                                          \
+      }                                                                              \
+    v_ret = INTERNAL_SYSCALL (name, err, nr, ##args);                        \
+  out:                                                                       \
+    v_ret;                                                                   \
+  })
+
+/* List of system calls which are supported as vsyscalls.  */
+#  define HAVE_CLOCK_GETTIME_VSYSCALL  1
+
+# else
+#  define INLINE_VSYSCALL(name, nr, args...) \
+  INLINE_SYSCALL (name, nr, ##args)
+#  define INTERNAL_VSYSCALL(name, err, nr, args...) \
+  INTERNAL_SYSCALL (name, err, nr, ##args)
+# endif
 #endif /* not __ASSEMBLER__ */
 
 /* Pointer mangling support.  */
This page took 0.124437 seconds and 5 git commands to generate.