[PATCH] PowerPC - Add a faster way to read the Time Base register

Ryan S. Arnold ryan.arnold@gmail.com
Tue Apr 24 20:35:00 GMT 2012


On Tue, Apr 17, 2012 at 3:22 PM, Tulio Magno Quites Machado Filho
<tuliom@linux.vnet.ibm.com> wrote:
> Add function __ppc_get_timebase() to directly read the Time Base register.
> This is required for applications that measure time at high frequencies
> with high precision that can't afford a syscall.
>
> 2012-04-09 Tulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>
>
>        [BZ #13743]
>        * sysdeps/powerpc/sys/platform/ppc.h: New file for PowerPC features.
>        * sysdeps/powerpc/Makefile (tests): Add test-gettimebase.
>        (sysdep_headers): Include sys/platform/ppc.h.
>        * sysdeps/powerpc/test-gettimebase.c: Test for
>        __ppc_get_timebase() to catch future ISA opcode/insn changes.
>        * manual/Makefile (appendices): Include platform.texi.
>        * manual/contrib.texi: Likewise.
>        * manual/maint.texi: Document how to include platform-specific
>        headers.
>        * manual/platform.texi: New file. Document the new features.
> ---
>  manual/Makefile                    |    3 +-
>  manual/contrib.texi                |    2 +-
>  manual/maint.texi                  |   76 +++++++++++++++++++++++++++++++++++-
>  manual/platform.texi               |   28 +++++++++++++
>  sysdeps/powerpc/Makefile           |    4 ++
>  sysdeps/powerpc/sys/platform/ppc.h |   53 +++++++++++++++++++++++++
>  sysdeps/powerpc/test-gettimebase.c |   46 ++++++++++++++++++++++
>  7 files changed, 209 insertions(+), 3 deletions(-)
>  create mode 100644 manual/platform.texi
>  create mode 100644 sysdeps/powerpc/sys/platform/ppc.h
>  create mode 100644 sysdeps/powerpc/test-gettimebase.c
>
> diff --git a/manual/Makefile b/manual/Makefile
> index daddd29..2dd7c96 100644
> --- a/manual/Makefile
> +++ b/manual/Makefile
> @@ -58,7 +58,8 @@ chapters = $(addsuffix .texi, \
>                       resource setjmp signal startup process job nss   \
>                       users sysinfo conf crypt debug)
>  add-chapters = $(wildcard $(foreach d, $(add-ons), ../$d/$d.texi))
> -appendices = lang.texi header.texi install.texi maint.texi contrib.texi
> +appendices = lang.texi header.texi install.texi maint.texi platform.texi \
> +            contrib.texi
>  licenses = freemanuals.texi lgpl-2.1.texi fdl-1.3.texi
>
>  -include texis
> diff --git a/manual/contrib.texi b/manual/contrib.texi
> index ed10656..8de97be 100644
> --- a/manual/contrib.texi
> +++ b/manual/contrib.texi
> @@ -1,4 +1,4 @@
> -@node Contributors, Free Manuals, Maintenance, Top
> +@node Contributors, Free Manuals, Platform, Top
>  @c %MENU% Who wrote what parts of the GNU C Library
>  @appendix Contributors to @theglibc{}
>
> diff --git a/manual/maint.texi b/manual/maint.texi
> index e1fdbdb..ba22d7c 100644
> --- a/manual/maint.texi
> +++ b/manual/maint.texi
> @@ -1,4 +1,4 @@
> -@node Maintenance, Contributors, Installation, Top
> +@node Maintenance, Platform, Installation, Top
>  @c %MENU% How to enhance and port the GNU C Library
>  @appendix Library Maintenance
>
> @@ -104,6 +104,80 @@ This variable is used for secondary object files needed to build
>  @code{others} or @code{tests}.
>  @end table
>
> +@menu
> +* Adding Platform-specific Features::    Adding platform-specific features.
> +@end menu
> +
> +@node Adding Platform-specific Features
> +@appendixsubsec Platform-specific types, macros and functions
> +
> +It's sometimes necessary to provide nonstandard, platform-specific
> +features to developers.  The C library is traditionally the
> +lowest library layer, so it makes sense for it to provide these
> +low-level features.  However, including these features in the C
> +library may be a disadvantage if another package provides them
> +as well as there will be two conflicting versions of them.  Also,
> +the features won't be available to projects that do not use
> +@theglibc{} but use other GNU tools, like GCC.
> +
> +The current guidelines are:
> +@itemize @bullet
> +@item
> +If the header provides features that only make sense on a particular machine
> +architecture and have nothing to do with an operating system, then the
> +features should be provided as GCC builtins.
> +
> +@item
> +If the header provides features that are specific to an operating system,
> +both GCC and @theglibc{} could provide it, but @theglibc{} is preferred
> +as it already has a lot of information about the operating system.
> +
> +@item
> +If the header provides features that are specific to an operating system
> +but used by @theglibc{}, then @theglibc{} should provide them.
> +
> +@end itemize
> +
> +The general solution for providing low-level features is to export them as
> +follows:
> +
> +@itemize @bullet
> +@item
> +Nonstandard low-level headers that define macros and static inline
> +functions go in @file{sys/platform/}.
> +
> +@item
> +Each is uniquely named per platform to avoid users thinking they have
> +anything in common e.g.,  @file{sys/platform/@var{arch}.h} or
> +@file{sys/platform/ppc.h}, but not @file{sys/platform.h}.
> +
> +@item
> +The platform header provided by @theglibc{} should coordinate with GCC such
> +that compiler built-in versions of the functions and macros are
> +preferred if available.  This means that user programs will only ever need to
> +include @file{sys/platform/@var{arch}.h}, keeping the same names of types,
> +macros, and functions for convenience and portability.
> +
> +@item
> +Each included symbol must have the prefix @file{__@var{arch}_}, e.g.,
> +@file{__ppc_get_timebase}.
> +
> +@end itemize
> +
> +
> +The easiest way to ship a header is to add it to the @code{sysdep_headers}
> +variable. For example, the combination of Linux-specific headers on
> +PowerPC could be provided like this:
> +
> +@smallexample
> +sysdep_header += sys/platform/ppc.h
> +@end smallexample
> +
> +Then ensure that you have added a @file{sys/platform/ppc.h}
> +header underneath your target platform sysdeps directory, e.g.,
> +@file{sysdeps/powerpc/sys/platform/ppc.h}.
> +
> +
>  @node Porting
>  @appendixsec Porting @theglibc{}
>
> diff --git a/manual/platform.texi b/manual/platform.texi
> new file mode 100644
> index 0000000..f893040
> --- /dev/null
> +++ b/manual/platform.texi
> @@ -0,0 +1,28 @@
> +@node Platform, Contributors, Maintenance, Top
> +@c %MENU% Describe all platform-specific facilities provided
> +@appendix Summary of platform-specific facilities
> +
> +@Theglibc{} can provide platform-specific functionality.
> +@ref{Adding Platform-specific Features} describes the process to include
> +these facilities in @theglibc{} and whether they should be included in
> +GCC as well.
> +
> +@menu
> +* PowerPC Architecture Facilities::      Summary of Facilities Specific
> +                                   to the PowerPC Architecture
> +@end menu
> +
> +@node PowerPC Architecture Facilities
> +@appendixsec Summary of Facilities Specific to the PowerPC Architecture
> +
> +All the facilities specific to the PowerPC Architecture that aren't OS
> +specific are provided by the header @file{sys/platform/ppc.h}.
> +
> +@deftp {Data Type} {__ppc_timebase}
> +This is an unsigned long long type that represents the value read from the
> +timebase register.
> +@end deftp
> +
> +@deftypefun {__ppc_timebase} __ppc_get_timebase (void)
> +Read the timebase register without the need of a system call.
> +@end deftypefun
> diff --git a/sysdeps/powerpc/Makefile b/sysdeps/powerpc/Makefile
> index 23a9a16..54cda7c 100644
> --- a/sysdeps/powerpc/Makefile
> +++ b/sysdeps/powerpc/Makefile
> @@ -26,3 +26,7 @@ gen-as-const-headers += rtld-global-offsets.sym
>  # get offset to __locale_struct.__ctype_tolower
>  gen-as-const-headers += locale-defines.sym
>  endif
> +
> +sysdep_headers += sys/platform/ppc.h
> +
> +tests += test-gettimebase
> diff --git a/sysdeps/powerpc/sys/platform/ppc.h b/sysdeps/powerpc/sys/platform/ppc.h
> new file mode 100644
> index 0000000..af3b9cd
> --- /dev/null
> +++ b/sysdeps/powerpc/sys/platform/ppc.h
> @@ -0,0 +1,53 @@
> +/* Copyright (C) 2012 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 _SYS_PLATFORM_PPC_H
> +#define _SYS_PLATFORM_PPC_H    1
> +
> +typedef unsigned long long int __ppc_timebase;
> +
> +/* Read the Time Base Register
> +   The Time Base Register is a 64-bit register that stores a monotonically
> +   incremented value updated at a system-dependent frequency that may be
> +   different from the processor frequency.
> +   More information in Power ISA 2.06b - Book II - Section 5.2   */
> +static inline __ppc_timebase
> +__ppc_get_timebase (void)
> +{
> +#ifdef __powerpc64__
> +  __ppc_timebase __tb;
> +  __asm__ volatile (
> +                   "mfspr %0, 268\n"
> +                   : "=r" (__tb)
> +                   : );
> +  return __tb;
> +#else  /* not __powerpc64__ */
> +  register unsigned long __tbu, __tbl, __tmp; \
> +  __asm__ volatile (
> +                   "0:\n"
> +                   "mftbu %0\n"
> +                   "mftbl %1\n"
> +                   "mftbu %2\n"
> +                   "cmpw %0, %2\n"
> +                   "bne- 0b\n"
> +                   : "=r" (__tbu), "=r" (__tbl), "=r" (__tmp)
> +                   : );
> +  return (( (__ppc_timebase) __tbu << 32) | __tbl);
> +#endif  /* not __powerpc64__ */
> +}
> +
> +#endif  /* sys/platform/ppc.h */
> diff --git a/sysdeps/powerpc/test-gettimebase.c b/sysdeps/powerpc/test-gettimebase.c
> new file mode 100644
> index 0000000..0496bd9
> --- /dev/null
> +++ b/sysdeps/powerpc/test-gettimebase.c
> @@ -0,0 +1,46 @@
> +/* Check __ppc_get_timebase() for architecture changes
> +   Copyright (C) 2012 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/>.  */
> +
> +/* Test if __ppc_get_timebase() is compatible with the current processor and if
> +   it's changing between reads.
> +   In case of a read failure it may indicate a future Power ISA or a binutils
> +   change.  */
> +
> +#include <stdio.h>
> +
> +#include <sys/platform/ppc.h>
> +
> +static int
> +do_test (void)
> +{
> +  __ppc_timebase t1, t2, t3;
> +  t1 = __ppc_get_timebase ();
> +  printf ("Time Base = %llx\n", t1);
> +  t2 = __ppc_get_timebase ();
> +  printf ("Time Base = %llx\n", t2);
> +  t3 = __ppc_get_timebase ();
> +  printf ("Time Base = %llx\n", t3);
> +  if (t1 != t2 && t1 != t3 && t2 != t3)
> +    return 0;
> +
> +  printf ("Fail: timebase reads should always be different.");
> +  return 1;
> +}
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> --
> 1.7.4.4
>

Hi Roland,

Does Tulio's latest patch satisfy your concerns regarding the manual changes?

Ryan



More information about the Libc-alpha mailing list