This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH 2/2] PowerPC - Add a faster way to read the Time Base register
- From: Tulio Magno Quites Machado Filho <tuliom at linux dot vnet dot ibm dot com>
- To: libc-alpha at sourceware dot org
- Cc: carlos at systemhalted dot org, sjmunroe at us dot ibm dot com, roland at hack dot frob dot com, joseph at codesourcery dot com, ryan dot arnold at gmail dot com
- Date: Tue, 6 Mar 2012 16:18:09 -0300
- Subject: [PATCH 2/2] PowerPC - Add a faster way to read the Time Base register
- References: <CADZpyiwgvKOJBHvP85esEJkW3OHvsxXiGwT8qBVP+FRHFmAo6A@mail.gmail.com>
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-03-06 Tulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>
* sysdeps/unix/sysv/linux/powerpc/sys/platform.h (__ppc_get_timebase):
New function definition.
* sysdeps/unix/sysv/linux/powerpc/Makefile (tests): Add
test-gettimebase.
* sysdeps/unix/sysv/linux/powerpc/test-gettimebase.c: Test for
__ppc_get_timebase() to catch future ISA opcode/insn changes.
---
sysdeps/unix/sysv/linux/powerpc/Makefile | 2 +
sysdeps/unix/sysv/linux/powerpc/sys/platform.h | 35 +++++++++++++++
sysdeps/unix/sysv/linux/powerpc/test-gettimebase.c | 47 ++++++++++++++++++++
3 files changed, 84 insertions(+), 0 deletions(-)
create mode 100644 sysdeps/unix/sysv/linux/powerpc/test-gettimebase.c
diff --git a/sysdeps/unix/sysv/linux/powerpc/Makefile b/sysdeps/unix/sysv/linux/powerpc/Makefile
index c947362..d0b6a1d 100644
--- a/sysdeps/unix/sysv/linux/powerpc/Makefile
+++ b/sysdeps/unix/sysv/linux/powerpc/Makefile
@@ -17,3 +17,5 @@ sysdep_routines += dl-vdso
endif
sysdep_headers += sys/platform.h
+
+tests += test-gettimebase
diff --git a/sysdeps/unix/sysv/linux/powerpc/sys/platform.h b/sysdeps/unix/sysv/linux/powerpc/sys/platform.h
index 9d1af58..c54d669 100644
--- a/sysdeps/unix/sysv/linux/powerpc/sys/platform.h
+++ b/sysdeps/unix/sysv/linux/powerpc/sys/platform.h
@@ -19,5 +19,40 @@
#define _SYS_PLATFORM_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 of processor frequency.
+ More information in Power ISA 2.06b - Book II - Section 5.2 */
+#ifdef __powerpc64__
+static inline __ppc_timebase
+__ppc_get_timebase (void)
+{
+ __ppc_timebase __tb;
+ __asm__ volatile (
+ "mfspr %0, 268\n"
+ : "=r" (__tb)
+ : );
+ return __tb;
+}
+#else /* not __powerpc64__ */
+static inline __ppc_timebase
+__ppc_get_timebase (void)
+{
+ 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.h */
diff --git a/sysdeps/unix/sysv/linux/powerpc/test-gettimebase.c b/sysdeps/unix/sysv/linux/powerpc/test-gettimebase.c
new file mode 100644
index 0000000..15308da
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/test-gettimebase.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Tulio Magno Quites Machado <tuliom@linux.vnet.ibm.com>, 2012.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* 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.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