1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-09 00:00:03 +01:00
libhermit/usr/benchmarks/rdtsc.h

74 lines
2 KiB
C
Raw Permalink Normal View History

/*
* =====================================================================================
*
* Filename: rdtsc.c
*
* Description:
*
* Version: 1.0
* Created: 24.01.2011 13:41:30
* Revision: none
* Compiler: gcc
*
* Author: Georg Wassen (gw) (),
* Company:
*
* =====================================================================================
*/
#ifndef RDTSC_H
#define RDTSC_H
#include <stdint.h>
/*
* rdtsc_ticks_per_sec(): measure frequency. Takes below a second.
*/
uint64_t rdtsc_ticks_per_sec(void) __attribute__((optimize(3)));
typedef union __attribute__((__transparent_union__))
{
uint64_t *__u64;
struct {uint32_t __low; uint32_t __high;} *__u32;
} tsc_t;
/*
* rdtsc(): Register-save version (compiler may insert additional push/pop)
* (clobbered-registers not given b/c compiler deduces from output-registers)
*/
static inline void __attribute__((__always_inline__, gnu_inline, optimize(3))) rdtsc(tsc_t tsc)
{
__asm__ volatile ("rdtsc" : "=a"(tsc.__u32->__low), "=d"(tsc.__u32->__high) );
}
/*
* rdtsc_serial(): get RDTSC with leading and rear serializing LFENCE instruction
*/
static inline void __attribute__((__always_inline__, gnu_inline, optimize(3))) rdtsc_serialized(tsc_t tsc)
{
#if ! __MIC__
__asm__ volatile (
"lfence\n\t" // serialize (needs SSE2, available since AMD Athlon64, Intel Core)
"rdtsc\n\t"
"lfence\n\t"
: "=a"(tsc.__u32->__low), "=d"(tsc.__u32->__high) );
#else
__asm__ volatile (
"lock; add $0, 0(%%rsp)\n\t" // serialize
"rdtsc\n\t"
"lock; add $0, 0(%%rsp)\n\t" // serialize
: "=a"(tsc.__u32->__low), "=d"(tsc.__u32->__high) :: "memory" );
#endif
}
void rdtsc_loop(uint64_t ticks);
void rdtsc_loop_sec(unsigned seconds);
uint64_t rdtsc_max_freq(int id);
int rdtsc_is_invariant(void);
uint64_t rdtsc_get_overhead(uint64_t iterations);
uint64_t rdtsc_get_overhead_serialized(uint64_t iterations);
#endif