This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC/PATCH] ARM: VDSO support


Future versions of Linux on 32-bit ARM are expected to provide fast
user-space implementations of the following system calls:

- gettimeofday
- clock_gettime

The kernel implementation depends on the ARMv7 Generic Timers
Extension to accelerate these system calls.  So CPUs such as
Cortex-A15 and -A7 benefit, while Cortex-A9, -A8, and pre-v7 CPUs do
not.

The kernel support is currently in linux-next and is slated for
inclusion in Linux 4.1.  I plan to ping or resubmit this patch once
Linux 4.1 is released, but would appreciate any preliminary review in
the meantime.  For reference, the current kernel patch submission may
be found here:

http://lists.infradead.org/pipermail/linux-arm-kernel/2015-March/332573.html

This patch adds support for the ARM VDSO to glibc.  I have run make
check on OMAP5 using kernels with and without the VDSO, with no new
failures.

ChangeLog:

2015-04-03  Nathan Lynch  <nathan_lynch@codesourcery.com>

	* sysdeps/unix/sysv/linux/arm/Makefile (sysdep_routines):
	Include dl-vdso.
	* sysdeps/unix/sysv/linux/arm/Versions: Add __vdso_clock_gettime
	and __vdso_gettimeofday.
	* sysdeps/unix/sysv/linux/arm/libc-vdso.h: New file: declare
	__vdso_clock_gettime, __vdso_gettimeofday.
	* sysdeps/unix/sysv/linux/arm/init-first.c: New file: Set
	__vdso_gettimeofday, __vdso_clock_gettime to vdso entry points
	if available.
	* sysdeps/unix/sysv/linux/arm/clock_gettime.c: New file:
	define SYSCALL_GETTIME, use __vdso_clock_gettime if set.
	* sysdeps/unix/sysv/linux/arm/gettimeofday.c: New file: define
	__gettimeofday, use __vdso_gettimeofday if set.
---
 sysdeps/unix/sysv/linux/arm/Makefile        |  1 +
 sysdeps/unix/sysv/linux/arm/Versions        |  2 +
 sysdeps/unix/sysv/linux/arm/clock_gettime.c | 48 ++++++++++++++++++++++
 sysdeps/unix/sysv/linux/arm/gettimeofday.c  | 62 +++++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/arm/init-first.c    | 52 ++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/arm/libc-vdso.h     | 32 +++++++++++++++
 6 files changed, 197 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/arm/clock_gettime.c
 create mode 100644 sysdeps/unix/sysv/linux/arm/gettimeofday.c
 create mode 100644 sysdeps/unix/sysv/linux/arm/init-first.c
 create mode 100644 sysdeps/unix/sysv/linux/arm/libc-vdso.h

diff --git a/sysdeps/unix/sysv/linux/arm/Makefile b/sysdeps/unix/sysv/linux/arm/Makefile
index 50410b67b5fc..0ed6f088d574 100644
--- a/sysdeps/unix/sysv/linux/arm/Makefile
+++ b/sysdeps/unix/sysv/linux/arm/Makefile
@@ -1,4 +1,5 @@
 ifeq ($(subdir),elf)
+sysdep_routines	     += dl-vdso
 sysdep-rtld-routines += aeabi_read_tp libc-do-syscall
 endif
 
diff --git a/sysdeps/unix/sysv/linux/arm/Versions b/sysdeps/unix/sysv/linux/arm/Versions
index a251b0fd7d87..7bc5936372bb 100644
--- a/sysdeps/unix/sysv/linux/arm/Versions
+++ b/sysdeps/unix/sysv/linux/arm/Versions
@@ -10,5 +10,7 @@ libc {
   GLIBC_PRIVATE {
     # A copy of sigaction lives in libpthread, and needs these.
     __default_sa_restorer; __default_rt_sa_restorer;
+    __vdso_clock_gettime;
+    __vdso_gettimeofday;
   }
 }
diff --git a/sysdeps/unix/sysv/linux/arm/clock_gettime.c b/sysdeps/unix/sysv/linux/arm/clock_gettime.c
new file mode 100644
index 000000000000..958db42c6b7c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/clock_gettime.c
@@ -0,0 +1,48 @@
+/* Get the current value of a clock.  Linux/arm version.
+   Copyright (C) 2015 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 <sysdep.h>
+#include <sys/time.h>
+#include <libc-vdso.h>
+
+static long int
+clock_gettime_syscall (clockid_t id, struct timespec *tp)
+{
+  INTERNAL_SYSCALL_DECL (err);
+  return INTERNAL_SYSCALL (clock_gettime, err, 2, id, tp);
+}
+
+
+# define SYSCALL_GETTIME(id, tp) \
+  ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
+  long int v_ret;							  \
+  PTR_DEMANGLE (f);							  \
+  if (f)								  \
+    v_ret = (*f) (id, tp);						  \
+  else									  \
+    v_ret = clock_gettime_syscall(id, tp);			          \
+  if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) {				  \
+    __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, ));			  \
+    v_ret = -1;								  \
+  }									  \
+  v_ret; })
+#endif
+
+#include <sysdeps/unix/sysv/linux/clock_gettime.c>
diff --git a/sysdeps/unix/sysv/linux/arm/gettimeofday.c b/sysdeps/unix/sysv/linux/arm/gettimeofday.c
new file mode 100644
index 000000000000..3665ade8f226
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/gettimeofday.c
@@ -0,0 +1,62 @@
+/* gettimeofday - get the time.  Linux/arm version.
+   Copyright (C) 2015 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/>.  */
+
+#include <sysdep.h>
+#include <sys/time.h>
+
+#ifdef SHARED
+
+# include <libc-vdso.h>
+
+static long int
+gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
+{
+  INTERNAL_SYSCALL_DECL (err);
+  return INTERNAL_SYSCALL (gettimeofday, err, 2, tv, tz);
+}
+
+int
+__gettimeofday (struct timeval *tv, struct timezone *tz)
+{
+  long int (*f) (struct timeval *, struct timezone *) = __vdso_gettimeofday;
+  long int v_ret;
+
+  PTR_DEMANGLE (f);
+  if (f)
+    v_ret = (*f) (tv, tz);
+  else
+    v_ret = gettimeofday_syscall(tv, tz);
+  if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) {
+    __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, ));
+    v_ret = -1;
+  }
+  return v_ret;
+}
+
+#else
+
+int
+__gettimeofday (struct timeval *tv, struct timezone *tz)
+{
+  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+}
+
+#endif
+libc_hidden_def (__gettimeofday)
+weak_alias (__gettimeofday, gettimeofday)
+libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/sysv/linux/arm/init-first.c b/sysdeps/unix/sysv/linux/arm/init-first.c
new file mode 100644
index 000000000000..c512d3a3e795
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/init-first.c
@@ -0,0 +1,52 @@
+/* Initialization code run first thing by the ELF startup code.  Linux/arm.
+   Copyright (C) 2015 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 <time.h>
+# include <sysdep.h>
+# include <dl-vdso.h>
+# include <libc-vdso.h>
+
+long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
+  __attribute__ ((nocommon));
+libc_hidden_proto (__vdso_clock_gettime)
+libc_hidden_data_def (__vdso_clock_gettime)
+
+long int (*__vdso_gettimeofday) (struct timeval *tv, struct timezone *tz)
+  __attribute__ ((nocommon));
+libc_hidden_proto (__vdso_gettimeofday)
+libc_hidden_data_def (__vdso_gettimeofday)
+
+static inline void
+__vdso_platform_setup (void)
+{
+  PREPARE_VERSION_KNOWN (linux26, LINUX_2_6);
+
+  void *p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux26);
+  PTR_MANGLE (p);
+  __vdso_clock_gettime = p;
+
+  p = _dl_vdso_vsym ("__vdso_gettimeofday", &linux26);
+  PTR_MANGLE (p);
+  __vdso_gettimeofday = p;
+}
+
+# define VDSO_SETUP __vdso_platform_setup
+#endif
+
+#include <csu/init-first.c>
diff --git a/sysdeps/unix/sysv/linux/arm/libc-vdso.h b/sysdeps/unix/sysv/linux/arm/libc-vdso.h
new file mode 100644
index 000000000000..622ef4dd62c3
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/libc-vdso.h
@@ -0,0 +1,32 @@
+/* Resolve function pointers to VDSO functions.
+   Copyright (C) 2015 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
+
+#include <time.h>
+#include <sys/time.h>
+
+#ifdef SHARED
+
+extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
+extern long int (*__vdso_gettimeofday) (struct timeval *, struct timezone *);
+
+#endif
+
+#endif /* _LIBC_VDSO_H */
-- 
1.9.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]