aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdhemerval Zanella <azanella@linux.vnet.ibm.com>2013-03-04 22:02:41 -0300
committerAdhemerval Zanella <azanella@linux.vnet.ibm.com>2013-03-04 22:02:41 -0300
commitcc328ae264f5b97d2811a95d84112bb1c6c7cae3 (patch)
tree53c09058bde18da292e769950a5fa9f094d1a90f
parent36016f626e72f5d1cb6107deeab29768d82ff7e3 (diff)
downloadglibc-cc328ae264f5b97d2811a95d84112bb1c6c7cae3.tar
glibc-cc328ae264f5b97d2811a95d84112bb1c6c7cae3.tar.gz
glibc-cc328ae264f5b97d2811a95d84112bb1c6c7cae3.tar.bz2
glibc-cc328ae264f5b97d2811a95d84112bb1c6c7cae3.zip
PowerPC: gettimeofday optimization by using IFUNC
-rw-r--r--ChangeLog7
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h8
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/gettimeofday.c49
3 files changed, 50 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index 7ba99a7cc1..ca3e120a21 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2013-03-04 Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+
+ * sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h: Add macro to
+ return vdso values correctly in IFUNC implementations.
+ * sysdeps/unix/sysv/linux/powerpc/gettimeofday.c (__gettimeofday):
+ Optimization by using IFUNC.
+
2012-11-20 Thomas Schwinge <thomas@codesourcery.com>
* sysdeps/sh/dl-machine.h (ELF_MACHINE_RUNTIME_FIXUP_PARAMS): New
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
index 646e8c0e8c..97979431f5 100644
--- a/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
@@ -30,6 +30,14 @@ extern void *__vdso_clock_getres;
extern void *__vdso_get_tbfreq;
+/* Macro to return vdso_xxx value on IFUNC implementations.
+ On PPC64 the returned value is actually an OPD entry. */
+#if defined(__PPC64__) || defined(__powerpc64__)
+#define PTR_IFUNC_RET(value) &value
+#else
+#define PTR_IFUNC_RET(value) value
+#endif
+
#endif
#endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
index 737613516f..5943be77ab 100644
--- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
@@ -15,26 +15,47 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include <sysdep.h>
-#include <bp-checks.h>
-#include <stddef.h>
#include <sys/time.h>
-#include <time.h>
-#include <hp-timing.h>
-#include <bits/libc-vdso.h>
+#ifdef SHARED
-/* Get the current time of day and timezone information,
- putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled.
- Returns 0 on success, -1 on errors. */
+# include <dl-vdso.h>
+# include <bits/libc-vdso.h>
-int
-__gettimeofday (tv, tz)
- struct timeval *tv;
- struct timezone *tz;
+void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
+
+static int
+__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
+{
+ return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+}
+
+void *
+gettimeofday_ifunc (void)
{
- return INLINE_VSYSCALL (gettimeofday, 2, CHECK_1 (tv), CHECK_1 (tz));
+ /* If the vDSO is not available we fall back syscall. */
+ return (__vdso_gettimeofday ? PTR_IFUNC_RET(__vdso_gettimeofday)
+ : __gettimeofday_syscall);
+}
+asm (".type __gettimeofday, %gnu_indirect_function");
+
+/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
+ let us do it in C because it doesn't know we're defining __gettimeofday
+ here in this file. */
+asm (".globl __GI___gettimeofday\n"
+ "__GI___gettimeofday = __gettimeofday");
+
+#else
+
+# include <sysdep.h>
+# include <errno.h>
+
+__gettimeofday (struct timeval *tv, struct timezone *tz)
+{
+ return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
}
libc_hidden_def (__gettimeofday)
+
+#endif
weak_alias (__gettimeofday, gettimeofday)
libc_hidden_weak (gettimeofday)