#include "Rts.h" #if x86_64_HOST_ARCH StgWord64 criterion_rdtsc(void) { StgWord32 hi, lo; __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); return ((StgWord64) lo) | (((StgWord64) hi)<<32); } #elif linux_HOST_OS /* * This should work on all Linux. * * Technique by Austin Seipp found here: * * http://neocontra.blogspot.com/2013/05/user-mode-performance-counters-for.html */ #include #include #include static int fddev = -1; __attribute__((constructor)) static void init(void) { 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); } __attribute__((destructor)) static void fini(void) { close(fddev); } StgWord64 criterion_rdtsc (void) { StgWord64 result = 0; if (read (fddev, &result, sizeof(result)) < sizeof(result)) return 0; return result; } #else #error Unsupported OS/architecture/compiler! #endif