about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAdhemerval Zanella <azanella@linux.vnet.ibm.com>2013-03-15 10:58:56 -0300
committerAdhemerval Zanella <azanella@linux.vnet.ibm.com>2013-03-15 10:58:56 -0300
commitef26eece6331a1f6d959818e37c438cc7ce68e53 (patch)
tree4c7afee3a37857c9e8a92d801bf1b630c433dad6
parent8cfdb7e0560ab27e70a1d2e898fb4a0a67a13c70 (diff)
downloadglibc-ef26eece6331a1f6d959818e37c438cc7ce68e53.tar.gz
glibc-ef26eece6331a1f6d959818e37c438cc7ce68e53.tar.xz
glibc-ef26eece6331a1f6d959818e37c438cc7ce68e53.zip
PowerPC: gettimeofday optimization by using IFUNC
-rw-r--r--ChangeLog7
-rw-r--r--sysdeps/gnu/configure42
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h10
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/gettimeofday.c48
4 files changed, 53 insertions, 54 deletions
diff --git a/ChangeLog b/ChangeLog
index 2e8affb197..fe92b82479 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2013-03-15  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+	* sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h (VDSO_IFUNC_RET): Add
+	macro to return vdso values correctly in IFUNC implementations.
+	* sysdeps/unix/sysv/linux/powerpc/gettimeofday.c (__gettimeofday):
+	Optimization by using IFUNC.
+
 2013-03-15  Siddhesh Poyarekar  <siddhesh@redhat.com>
 	    Richard Henderson  <rth@redhat.com>
 	    Tulio Magno Quites Machado Filho  <tuliom@linux.vnet.ibm.com>
diff --git a/sysdeps/gnu/configure b/sysdeps/gnu/configure
index 26327ca3b4..e69de29bb2 100644
--- a/sysdeps/gnu/configure
+++ b/sysdeps/gnu/configure
@@ -1,42 +0,0 @@
-# This file is generated from configure.in by Autoconf.  DO NOT EDIT!
-
-# Local configure fragment for sysdeps/gnu.
-
-# The Filesystem Hierarchy Standard prescribes where to place "essential"
-# files.  I.e., when the installation prefix is "/usr" we have to place
-# shared library objects and the configuration files on the root partition
-# in /lib and /etc.
-case "$prefix" in
-/usr | /usr/)
-  # 64-bit libraries on bi-arch platforms go in /lib64 instead of /lib.
-  # Allow earlier configure scripts to handle libc_cv_slibdir, libdir,
-  # and libc_cv_localedir.
-  test -n "$libc_cv_slibdir" || \
-  case $machine in
-  sparc/sparc64 | x86_64* | powerpc/powerpc64 | s390/s390-64)
-    libc_cv_slibdir=/lib64
-    if test "$libdir" = '${exec_prefix}/lib'; then
-      libdir='${exec_prefix}/lib64';
-      # Locale data can be shared between 32bit and 64bit libraries
-      libc_cv_localedir='${exec_prefix}/lib/locale'
-    fi
-    ;;
-  *)
-    libc_cv_slibdir=/lib
-    ;;
-  esac
-  # Allow the user to override the path with --sysconfdir.
-  if test "$sysconfdir" = '${prefix}/etc'; then
-    libc_cv_sysconfdir=/etc
-  else
-    libc_cv_sysconfdir=$sysconfdir
-   fi
-  # Allow the user to override the path with --localstatedir.
-  if test "$localstatedir" = '${prefix}/var'; then
-    libc_cv_localstatedir=/var
-  else
-    libc_cv_localstatedir=$localstatedir
-   fi
-  libc_cv_rootsbindir=/sbin
-  ;;
-esac
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
index 545fda462a..5f5fc1eb3a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
@@ -32,6 +32,16 @@ extern void *__vdso_get_tbfreq;
 
 extern void *__vdso_getcpu;
 
+/* This macro is needed for PPC64 to return a skeleton OPD entry of a vDSO
+   symbol.  This works because _dl_vdso_vsym always return the function
+   address, and no vDSO symbols use the TOC or chain pointers from the OPD
+   so we can allow them to be garbage.  */
+#if defined(__PPC64__) || defined(__powerpc64__)
+#define VDSO_IFUNC_RET(value)  &value
+#else
+#define VDSO_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 f607485072..6506d75e64 100644
--- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
@@ -15,25 +15,49 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <stddef.h>
+
 #include <sys/time.h>
-#include <time.h>
-#include <hp-timing.h>
 
-#include <bits/libc-vdso.h>
+#ifdef SHARED
+
+# include <dl-vdso.h>
+# include <bits/libc-vdso.h>
+
+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)
+{
+  /* If the vDSO is not available we fall back syscall.  */
+  return (__vdso_gettimeofday ? VDSO_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
 
-/* 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 <sysdep.h>
+# include <errno.h>
 
 int
-__gettimeofday (tv, tz)
-     struct timeval *tv;
-     struct timezone *tz;
+__gettimeofday (struct timeval *tv, struct timezone *tz)
 {
-  return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
+  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
 }
 libc_hidden_def (__gettimeofday)
+
+#endif
 weak_alias (__gettimeofday, gettimeofday)
 libc_hidden_weak (gettimeofday)