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.
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)
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
"=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. */