This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: PowerPC: Add time vDSO support
- From: Adhemerval Zanella <azanella at linux dot vnet dot ibm dot com>
- To: libc-alpha at sourceware dot org
- Date: Fri, 03 May 2013 08:32:27 -0300
- Subject: Re: PowerPC: Add time vDSO support
- References: <517EB999 dot 5000504 at linux dot vnet dot ibm dot com> <20130429182738 dot 7563D2C069 at topped-with-meat dot com> <517FDDF5 dot 5040501 at linux dot vnet dot ibm dot com>
Ping.
On 04/30/2013 12:06 PM, Adhemerval Zanella wrote:
> Thanks for the review Roland, I have fixed all your comments.
> Ok to apply now?
>
> ---
>
> 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.
>
> --
>
> diff --git a/sysdeps/unix/sysv/linux/powerpc/Versions b/sysdeps/unix/sysv/linux/powerpc/Versions
> index 396a423..289c4fe 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 5f5fc1e..8b195db 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 204c0c6..f6f05f0 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 0000000..66b4eb3
> --- /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