VDSO support for MIPS
This patch adds support for using the implementations of gettimeofday() and clock_gettime() provided by the kernel in the VDSO. The VDSO will always provide clock_gettime() as CLOCK_{REALTIME,MONOTONIC}_COARSE can be implemented regardless of platform. CLOCK_{REALTIME,MONOTONIC}, along with gettimeofday(), are only implemented on platforms which make use of either the CP0 count or GIC as their clocksource. On other platforms, the VDSO does not provide the __vdso_gettimeofday symbol, as it is never useful. The VDSO functions return ENOSYS when they encounter an unsupported request, in which case glibc should fall back to the standard syscall. Tested with upstream kernel 4.5 and QEMU emulating Malta. ./vdsotest gettimeofday bench gettimeofday: syscall: 1021 nsec/call gettimeofday: libc: 262 nsec/call gettimeofday: vdso: 174 nsec/call * sysdeps/unix/sysv/linux/mips/Makefile (sysdep_routines): Include dl-vdso. * sysdeps/unix/sysv/linux/mips/Versions: Add __vdso_clock_gettime. * sysdeps/unix/sysv/linux/mips/init-first.c: New file. * sysdeps/unix/sysv/linux/mips/libc-vdso.h: New file. * sysdeps/unix/sysv/linux/mips/mips32/sysdep.h: (INTERNAL_VSYSCALL_CALL): Define to be compatible with MIPS definitions of INTERNAL_SYSCALL_{ERROR_P,ERRNO}. (HAVE_CLOCK_GETTIME_VSYSCALL): Define. (HAVE_GETTIMEOFDAY_VSYSCALL): Define. * sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h: Likewise.
This commit is contained in:
parent
071af4769f
commit
b39d84adff
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
|||
2016-04-12 Alex Smith <alex.smith@imgtec.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/mips/Makefile (sysdep_routines):
|
||||
Include dl-vdso.
|
||||
* sysdeps/unix/sysv/linux/mips/Versions: Add
|
||||
__vdso_clock_gettime.
|
||||
* sysdeps/unix/sysv/linux/mips/init-first.c: New file.
|
||||
* sysdeps/unix/sysv/linux/mips/libc-vdso.h: New file.
|
||||
* sysdeps/unix/sysv/linux/mips/mips32/sysdep.h:
|
||||
(INTERNAL_VSYSCALL_CALL): Define to be compatible with MIPS
|
||||
definitions of INTERNAL_SYSCALL_{ERROR_P,ERRNO}.
|
||||
(HAVE_CLOCK_GETTIME_VSYSCALL): Define.
|
||||
(HAVE_GETTIMEOFDAY_VSYSCALL): Define.
|
||||
* sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h: Likewise.
|
||||
* sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h: Likewise.
|
||||
|
||||
2016-04-11 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
* sysdeps/unix/sysv/linux/arm/pwrite.c: Remove file.
|
||||
|
|
|
@ -96,6 +96,8 @@ ifeq ($(subdir),elf)
|
|||
ifeq ($(build-shared),yes)
|
||||
# This is needed for DSO loading from static binaries.
|
||||
sysdep-dl-routines += dl-static
|
||||
|
||||
sysdep_routines += dl-vdso
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
|
@ -37,4 +37,8 @@ libc {
|
|||
GLIBC_2.11 {
|
||||
fallocate64;
|
||||
}
|
||||
GLIBC_PRIVATE {
|
||||
# nptl/pthread_cond_timedwait.c uses INTERNAL_VSYSCALL(clock_gettime).
|
||||
__vdso_clock_gettime;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/* Initialization code run first thing by the ELF startup code.
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifdef SHARED
|
||||
# include <dl-vdso.h>
|
||||
# include <libc-vdso.h>
|
||||
|
||||
int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *) attribute_hidden;
|
||||
int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
|
||||
|
||||
static inline void
|
||||
_libc_vdso_platform_setup (void)
|
||||
{
|
||||
PREPARE_VERSION_KNOWN (linux26, LINUX_2_6);
|
||||
|
||||
void *p = _dl_vdso_vsym ("__vdso_gettimeofday", &linux26);
|
||||
PTR_MANGLE (p);
|
||||
VDSO_SYMBOL (gettimeofday) = p;
|
||||
|
||||
p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux26);
|
||||
PTR_MANGLE (p);
|
||||
VDSO_SYMBOL (clock_gettime) = p;
|
||||
}
|
||||
|
||||
# define VDSO_SETUP _libc_vdso_platform_setup
|
||||
#endif
|
||||
|
||||
#include <csu/init-first.c>
|
|
@ -0,0 +1,33 @@
|
|||
/* VDSO function pointer declarations.
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _LIBC_VDSO_H
|
||||
#define _LIBC_VDSO_H
|
||||
|
||||
#ifdef SHARED
|
||||
|
||||
# include <sysdep-vdso.h>
|
||||
|
||||
extern int (*VDSO_SYMBOL(gettimeofday)) (struct timeval *, void *)
|
||||
attribute_hidden;
|
||||
extern int (*VDSO_SYMBOL(clock_gettime)) (clockid_t, struct timespec *);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _LIBC_VDSO_H */
|
|
@ -371,6 +371,22 @@
|
|||
#define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
|
||||
"$14", "$15", "$24", "$25", "hi", "lo", "memory"
|
||||
|
||||
/* Standard MIPS syscalls have an error flag, and return a positive errno
|
||||
when the error flag is set. Emulate this behaviour for vsyscalls so that
|
||||
the INTERNAL_SYSCALL_{ERROR_P,ERRNO} macros work correctly. */
|
||||
#define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...) \
|
||||
({ \
|
||||
long _ret = funcptr (args); \
|
||||
err = ((unsigned long) (_ret) >= (unsigned long) -4095L); \
|
||||
if (err) \
|
||||
_ret = -_ret; \
|
||||
_ret; \
|
||||
})
|
||||
|
||||
/* List of system calls which are supported as vsyscalls. */
|
||||
#define HAVE_CLOCK_GETTIME_VSYSCALL 1
|
||||
#define HAVE_GETTIMEOFDAY_VSYSCALL 1
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
/* Pointer mangling is not yet supported for MIPS. */
|
||||
|
|
|
@ -295,6 +295,23 @@
|
|||
|
||||
#define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", \
|
||||
"$14", "$15", "$24", "$25", "hi", "lo", "memory"
|
||||
|
||||
/* Standard MIPS syscalls have an error flag, and return a positive errno
|
||||
when the error flag is set. Emulate this behaviour for vsyscalls so that
|
||||
the INTERNAL_SYSCALL_{ERROR_P,ERRNO} macros work correctly. */
|
||||
#define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...) \
|
||||
({ \
|
||||
long _ret = funcptr (args); \
|
||||
err = ((unsigned long) (_ret) >= (unsigned long) -4095L); \
|
||||
if (err) \
|
||||
_ret = -_ret; \
|
||||
_ret; \
|
||||
})
|
||||
|
||||
/* List of system calls which are supported as vsyscalls. */
|
||||
#define HAVE_CLOCK_GETTIME_VSYSCALL 1
|
||||
#define HAVE_GETTIMEOFDAY_VSYSCALL 1
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
/* Pointer mangling is not yet supported for MIPS. */
|
||||
|
|
|
@ -291,6 +291,23 @@
|
|||
|
||||
#define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", \
|
||||
"$14", "$15", "$24", "$25", "hi", "lo", "memory"
|
||||
|
||||
/* Standard MIPS syscalls have an error flag, and return a positive errno
|
||||
when the error flag is set. Emulate this behaviour for vsyscalls so that
|
||||
the INTERNAL_SYSCALL_{ERROR_P,ERRNO} macros work correctly. */
|
||||
#define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...) \
|
||||
({ \
|
||||
long _ret = funcptr (args); \
|
||||
err = ((unsigned long) (_ret) >= (unsigned long) -4095L); \
|
||||
if (err) \
|
||||
_ret = -_ret; \
|
||||
_ret; \
|
||||
})
|
||||
|
||||
/* List of system calls which are supported as vsyscalls. */
|
||||
#define HAVE_CLOCK_GETTIME_VSYSCALL 1
|
||||
#define HAVE_GETTIMEOFDAY_VSYSCALL 1
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
/* Pointer mangling is not yet supported for MIPS. */
|
||||
|
|
Loading…
Reference in New Issue