Shared Persistent Heap Data Environment Manual  1.1.0
sphtimer.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2014 IBM Corporation.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation, Steven Munroe - initial API and implementation
10  * IBM Corporation, Adhemerval Zanella - bugfixes and documentation
11  */
12 
13 #ifndef __SPH_TIMER_H
14 #define __SPH_TIMER_H
15 
57 #ifdef __cplusplus
58 #define __C__ "C"
59 #else
60 #define __C__
61 #endif
62 
66 typedef unsigned long long int sphtimer_t;
67 
68 #if defined(__powerpc64__)
69 #define __TIME_BASE(__time_v) \
70  do { \
71  sphtimer_t __t; \
72  __asm__ __volatile__ ( \
73  "mfspr %0,268" \
74  : "=r" (__t)); \
75  __time_v = __t; \
76  } while (0)
77 #elif defined(__powerpc__)
78 #define __TIME_BASE(__time_v) \
79  do { \
80  unsigned long __tbu, __tbl, __tmp; \
81  __asm__ volatile ( \
82  "0:\n" \
83  "mftbu %0\n" \
84  "mftbl %1\n" \
85  "mftbu %2\n" \
86  "cmpw %0, %2\n" \
87  "bne- 0b" \
88  : "=r" (__tbu), "=r" (__tbl), "=r" (__tmp) ); \
89  __time_v = (( (sphtimer_t) __tbu << 32) | __tbl); \
90  } while (0)
91 #elif defined(__x86_64__) && defined(__x86_64_INVARIANT_TSC)
92 /* TODO: the accuracy might be susceptible to CPU clock throttling (mainly
93  * due to CPU scaling. So we disable rdtsc unless the user explicitly defines
94  * __x86_64_INVARIANT_TSC.
95  */
96 #define __TIME_BASE(__time_v) \
97  do { \
98  unsigned int __t_hi, __t_lo; \
99  __asm__ __volatile__ ( \
100  "rdtsc" \
101  : "=a" (__t_lo), \
102  "=d" (__t_hi)); \
103  __time_v = ((sphtimer_t) __t_hi << 32) | __t_lo; \
104  } while (0)
105 #elif defined(__i386__) && defined(__x86_INVARIANT_TSC)
106 /* TODO: the accuracy might be susceptible to CPU clock throttling (mainly
107  * due to CPU scaling. So we disable rdtsc unless the user explicitly defines
108  * __x86_INVARIANT_TSC.
109  */
110 #define __TIME_BASE(__time_v) \
111  do { \
112  unsigned int __t; \
113  __asm__ __volatile__ ( \
114  "rdtsc" \
115  : "=A" (__t)); \
116  __time_v = __t; \
117  } while (0)
118 #else
119 #include <time.h>
121 #define __TIME_BASE(__time_v) \
122  do { \
123  struct timespec __ts; \
124  sphtimer_t __t; \
125  clock_gettime (CLOCK_MONOTONIC, &__ts); \
126  __t = ((sphtimer_t)__ts.tv_sec * 1000000000L) \
127  + (sphtimer_t)__ts.tv_nsec; \
128  __time_v = __t; \
129  } while (0)
130 
131 #endif
132 
138 static inline sphtimer_t
140 {
141  sphtimer_t t;
142  __TIME_BASE (t);
143  return t;
144 }
145 
153 
161 extern __C__ sphtimer_t
162 sphgetcpufreq (void);
163 
173 static inline sphtimer_t
175 {
176  sphtimer_t result = sph_cpu_frequency;
177 
178  if (__builtin_expect ((result == 0), 0))
179  {
180  result = sphgetcpufreq ();
181  }
182  return result;
183 }
184 
185 #endif /* __SPH_TIMER_H */
unsigned long long int sphtimer_t
Value from TB/TSC register (64-bits on all platforms).
Definition: sphtimer.h:66
static sphtimer_t sphgettimer(void)
Read and return the Timebase value.
Definition: sphtimer.h:139
#define __TIME_BASE(__time_v)
Read the Time Base value.
Definition: sphtimer.h:121
#define __C__
ignore this macro behind the curtain.
Definition: sphtimer.h:60
sphtimer_t sph_cpu_frequency
Frequency which Timebase is updated by system.
static sphtimer_t sphfastcpufreq(void)
Return the Timebase update frequency (fast version).
Definition: sphtimer.h:174
__C__ sphtimer_t sphgetcpufreq(void)
Return the Timebase update frequency.