summaryrefslogtreecommitdiff
path: root/absl
diff options
context:
space:
mode:
authorGravatar kgotlinux <60880393+kgotlinux@users.noreply.github.com>2020-02-25 22:27:31 +0100
committerGravatar GitHub <noreply@github.com>2020-02-25 16:27:31 -0500
commit0033c9ea91a52ade7c6b725aa2ef3cbe15463421 (patch)
treeebd3c8565a05c8cac726f11835e25cad98144223 /absl
parent0d5ce2797eb695aee7e019e25323251ef6ffc277 (diff)
Fix build on FreeBSD/powerpc (#616)
* Fix build on FreeBSD/powerpc Only glibc has __ppc_get_timebase(), __ppc_get_timebase_freq() and sys/platform/ppc.h.
Diffstat (limited to 'absl')
-rw-r--r--absl/base/internal/unscaledcycleclock.cc37
1 files changed, 37 insertions, 0 deletions
diff --git a/absl/base/internal/unscaledcycleclock.cc b/absl/base/internal/unscaledcycleclock.cc
index a32936ae..f1e7bbef 100644
--- a/absl/base/internal/unscaledcycleclock.cc
+++ b/absl/base/internal/unscaledcycleclock.cc
@@ -21,7 +21,12 @@
#endif
#if defined(__powerpc__) || defined(__ppc__)
+#ifdef __GLIBC__
#include <sys/platform/ppc.h>
+#elif defined(__FreeBSD__)
+#include <sys/sysctl.h>
+#include <sys/types.h>
+#endif
#endif
#include "absl/base/internal/sysinfo.h"
@@ -57,11 +62,43 @@ double UnscaledCycleClock::Frequency() {
#elif defined(__powerpc__) || defined(__ppc__)
int64_t UnscaledCycleClock::Now() {
+#ifdef __GLIBC__
return __ppc_get_timebase();
+#else
+#ifdef __powerpc64__
+ int64_t tbr;
+ asm volatile("mfspr %0, 268" : "=r"(tbr));
+ return tbr;
+#else
+ int32_t tbu, tbl, tmp;
+ asm volatile(
+ "0:\n"
+ "mftbu %[hi32]\n"
+ "mftb %[lo32]\n"
+ "mftbu %[tmp]\n"
+ "cmpw %[tmp],%[hi32]\n"
+ "bne 0b\n"
+ : [ hi32 ] "=r"(tbu), [ lo32 ] "=r"(tbl), [ tmp ] "=r"(tmp));
+ return (static_cast<int64_t>(tbu) << 32) | tbl;
+#endif
+#endif
}
double UnscaledCycleClock::Frequency() {
+#ifdef __GLIBC__
return __ppc_get_timebase_freq();
+#elif defined(__FreeBSD__)
+ static once_flag init_timebase_frequency_once;
+ static double timebase_frequency = 0.0;
+ base_internal::LowLevelCallOnce(&init_timebase_frequency_once, [&]() {
+ size_t length = sizeof(timebase_frequency);
+ sysctlbyname("kern.timecounter.tc.timebase.frequency", &timebase_frequency,
+ &length, nullptr, 0);
+ });
+ return timebase_frequency;
+#else
+#error Must implement UnscaledCycleClock::Frequency()
+#endif
}
#elif defined(__aarch64__)