diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/Versions | 1 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h | 6 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/init-first.c | 4 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/time.c | 62 |
5 files changed, 81 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog index ed888db3fa..8bfb5521cc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2013-04-30 Adhemerval Zanella <azanella@linux.vnet.ibm.com> + + * sysdeps/unix/sysv/linux/powerpc/Versions: Add __vdso_time symbol. + * sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h: Add __vdso_time + definition. + (VDSO_IFUNC_RET): Cast to void * to silence compiler warning. + * sysdeps/unix/sysv/linux/powerpc/init-first.c + (_libc_vdso_platform_setup): Add __vdso_time initialization. + * sysdeps/unix/sysv/linux/powerpc/time.c: New file: time implementation + for PowerPC using vDSO where is avaliable or gettimeofday as a fallback. + 2013-05-03 Joseph Myers <joseph@codesourcery.com> * math/libm-test.inc (lgamma_test): Consistently use TEST_f_f1 to diff --git a/sysdeps/unix/sysv/linux/powerpc/Versions b/sysdeps/unix/sysv/linux/powerpc/Versions index 396a4236c1..289c4fe9b7 100644 --- a/sysdeps/unix/sysv/linux/powerpc/Versions +++ b/sysdeps/unix/sysv/linux/powerpc/Versions @@ -4,5 +4,6 @@ libc { __vdso_clock_gettime; __vdso_clock_getres; __vdso_getcpu; + __vdso_time; } } diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h index 5f5fc1eb3a..8b195db1bf 100644 --- a/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h +++ b/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h @@ -32,14 +32,16 @@ extern void *__vdso_get_tbfreq; extern void *__vdso_getcpu; +extern void *__vdso_time; + /* 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 +#define VDSO_IFUNC_RET(value) ((void *) &(value)) #else -#define VDSO_IFUNC_RET(value) value +#define VDSO_IFUNC_RET(value) ((void *) (value)) #endif #endif diff --git a/sysdeps/unix/sysv/linux/powerpc/init-first.c b/sysdeps/unix/sysv/linux/powerpc/init-first.c index 204c0c60a4..f6f05f0ba2 100644 --- a/sysdeps/unix/sysv/linux/powerpc/init-first.c +++ b/sysdeps/unix/sysv/linux/powerpc/init-first.c @@ -28,7 +28,7 @@ void *__vdso_clock_gettime; void *__vdso_clock_getres; void *__vdso_get_tbfreq; void *__vdso_getcpu; - +void *__vdso_time; static inline void _libc_vdso_platform_setup (void) @@ -44,6 +44,8 @@ _libc_vdso_platform_setup (void) __vdso_get_tbfreq = _dl_vdso_vsym ("__kernel_get_tbfreq", &linux2615); __vdso_getcpu = _dl_vdso_vsym ("__kernel_getcpu", &linux2615); + + __vdso_time = _dl_vdso_vsym ("__kernel_time", &linux2615); } # define VDSO_SETUP _libc_vdso_platform_setup diff --git a/sysdeps/unix/sysv/linux/powerpc/time.c b/sysdeps/unix/sysv/linux/powerpc/time.c new file mode 100644 index 0000000000..66b4eb3049 --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/time.c @@ -0,0 +1,62 @@ +/* time system call for Linux/PowerPC. + Copyright (C) 2013 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 <bits/libc-vdso.h> + +void *time_ifunc (void) asm ("time"); + +static time_t +time_syscall (time_t *t) +{ + struct timeval tv; + time_t result; + + if (INLINE_VSYSCALL (gettimeofday, 2, &tv, NULL) < 0) + result = (time_t) -1; + else + result = (time_t) tv.tv_sec; + + if (t != NULL) + *t = result; + return result; +} + +void * +time_ifunc (void) +{ + /* If the vDSO is not available we fall back to the syscall. */ + return (__vdso_time ? VDSO_IFUNC_RET (__vdso_time) + : time_syscall); +} +asm (".type time, %gnu_indirect_function"); + +/* This is doing "libc_hidden_def (time)" but the compiler won't + * let us do it in C because it doesn't know we're defining time + * here in this file. */ +asm (".globl __GI_time\n" + "__GI_time = time"); + +#else + +#include <sysdeps/posix/time.c> + +#endif |