--- a/src/common/Cycles.h
+++ b/src/common/Cycles.h
@@ -32,6 +32,13 @@
#ifndef CEPH_CYCLES_H
#define CEPH_CYCLES_H
+#if not (defined(__i386__) || defined(__x86_64__) || defined(__amd64__) || \
+ defined(__aarch64__) || defined (__powerpc__) || defined (__powerpc64__))
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <linux/perf_event.h>
+#endif
+
/**
* This class provides static methods that read the fine-grain CPU
* cycle counter and translate between cycle-level times and absolute
@@ -72,8 +79,22 @@ class Cycles {
uint64_t cntvct;
asm volatile ("isb; mrs %0, cntvct_el0; isb; " : "=r" (cntvct) :: "memory");
return cntvct;
+#elif defined(__powerpc__) || defined (__powerpc64__)
+ // Based on:
+ // https://github.com/randombit/botan/blob/net.randombit.botan/src/lib/entropy/hres_timer/hres_timer.cpp
+ uint32_t lo = 0, hi = 0;
+ asm volatile("mftbu %0; mftb %1" : "=r" (hi), "=r" (lo));
+ return (((uint64_t)hi << 32) | lo);
#else
-#error No high-precision counter available for your OS/arch
+ // Fallback on linux perf for cpu cycles
+ static struct perf_event_attr attr;
+ attr.type = PERF_TYPE_HARDWARE;
+ attr.config = PERF_COUNT_HW_CPU_CYCLES;
+ fddev = syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0);
+ uint64_t result = 0;
+ if (read(fddev, &result, sizeof(result)) < sizeof(result)) result = 0;
+ close(fddev);
+ return result;
#endif
}