tile: add clock_gettime support via vDSO

This commit is contained in:
Chris Metcalf 2014-10-01 15:10:04 -04:00
parent 83d641efd1
commit 845a73434c
6 changed files with 81 additions and 6 deletions

View File

@ -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.

View File

@ -13,5 +13,6 @@ libc {
}
GLIBC_PRIVATE {
__syscall_error;
__vdso_clock_gettime;
}
}

View 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 */

View File

@ -24,12 +24,7 @@
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)

View File

@ -21,11 +21,17 @@
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

View File

@ -202,6 +202,65 @@
"=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. */