sphtimer.h
Go to the documentation of this file.
/*
* Copyright (c) 2010-2014 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation, Steven Munroe - initial API and implementation
* IBM Corporation, Adhemerval Zanella - bugfixes and documentation
*/
#ifndef __SPH_TIMER_H
#define __SPH_TIMER_H
#ifdef __cplusplus
#define __C__ "C"
#else
#define __C__
#endif
typedef unsigned long long int sphtimer_t;
#if defined(__powerpc64__)
#define __TIME_BASE(__time_v) \
do { \
sphtimer_t __t; \
__asm__ __volatile__ ( \
"mfspr %0,268" \
: "=r" (__t)); \
__time_v = __t; \
} while (0)
#elif defined(__powerpc__)
#define __TIME_BASE(__time_v) \
do { \
unsigned long __tbu, __tbl, __tmp; \
__asm__ volatile ( \
"0:\n" \
"mftbu %0\n" \
"mftbl %1\n" \
"mftbu %2\n" \
"cmpw %0, %2\n" \
"bne- 0b" \
: "=r" (__tbu), "=r" (__tbl), "=r" (__tmp) ); \
__time_v = (( (sphtimer_t) __tbu << 32) | __tbl); \
} while (0)
#elif defined(__x86_64__) && defined(__x86_64_INVARIANT_TSC)
/* TODO: the accuracy might be susceptible to CPU clock throttling (mainly
* due to CPU scaling. So we disable rdtsc unless the user explicitly defines
* __x86_64_INVARIANT_TSC.
*/
#define __TIME_BASE(__time_v) \
do { \
unsigned int __t_hi, __t_lo; \
__asm__ __volatile__ ( \
"rdtsc" \
: "=a" (__t_lo), \
"=d" (__t_hi)); \
__time_v = ((sphtimer_t) __t_hi << 32) | __t_lo; \
} while (0)
#elif defined(__i386__) && defined(__x86_INVARIANT_TSC)
/* TODO: the accuracy might be susceptible to CPU clock throttling (mainly
* due to CPU scaling. So we disable rdtsc unless the user explicitly defines
* __x86_INVARIANT_TSC.
*/
#define __TIME_BASE(__time_v) \
do { \
unsigned int __t; \
__asm__ __volatile__ ( \
"rdtsc" \
: "=A" (__t)); \
__time_v = __t; \
} while (0)
#else
#include <time.h>
#define __TIME_BASE(__time_v) \
do { \
struct timespec __ts; \
sphtimer_t __t; \
clock_gettime (CLOCK_MONOTONIC, &__ts); \
__t = ((sphtimer_t)__ts.tv_sec * 1000000000L) \
+ (sphtimer_t)__ts.tv_nsec; \
__time_v = __t; \
} while (0)
#endif
static inline sphtimer_t
sphgettimer (void)
{
sphtimer_t t;
__TIME_BASE (t);
return t;
}
extern sphtimer_t sph_cpu_frequency;
extern __C__ sphtimer_t
sphgetcpufreq (void);
static inline sphtimer_t
sphfastcpufreq (void)
{
sphtimer_t result = sph_cpu_frequency;
if (__builtin_expect ((result == 0), 0))
{
result = sphgetcpufreq ();
}
return result;
}
#endif /* __SPH_TIMER_H */
sphtimer_t
unsigned long long int sphtimer_t
Value from TB/TSC register (64-bits on all platforms).
Definition: sphtimer.h:66
sph_cpu_frequency
sphtimer_t sph_cpu_frequency
Frequency which Timebase is updated by system.
__TIME_BASE
#define __TIME_BASE(__time_v)
Read the Time Base value.
Definition: sphtimer.h:121
__C__
#define __C__
ignore this macro behind the curtain.
Definition: sphtimer.h:60
sphgettimer
static sphtimer_t sphgettimer(void)
Read and return the Timebase value.
Definition: sphtimer.h:139
sphgetcpufreq
__C__ sphtimer_t sphgetcpufreq(void)
Return the Timebase update frequency.
sphfastcpufreq
static sphtimer_t sphfastcpufreq(void)
Return the Timebase update frequency (fast version).
Definition: sphtimer.h:174