00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef _TIMING
00017 #define _TIMING
00018
00019 #ifdef __cplusplus
00020 extern "C" {
00021 #endif
00022
00023 #include <stdio.h>
00024 #include <ctype.h>
00025 #include <math.h>
00026
00027 #include <assert.h>
00028 #include <time.h>
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 struct util_timing_t
00040 {
00041 u_int32_t high;
00042 u_int32_t low;
00043 };
00044
00045 typedef struct util_timing_t util_timing_t;
00046
00047
00048 extern double PROCESSOR_FREQUENCY;
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 #define rdmsr(msr,val1,val2) \
00061 __asm__ __volatile__("rdmsr" \
00062 : "=a" (val1), "=d" (val2) : "c" (msr))
00063
00064 #define wrmsr(msr,val1,val2) \
00065 __asm__ __volatile__("wrmsr" \
00066 : \
00067 : "c" (msr), "a" (val1), "d" (val2))
00068
00069 #define rdtsc(low,high) \
00070 __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
00071
00072 #define rdtscl(low) \
00073 __asm__ __volatile__("rdtsc" : "=a" (low) : : "edx")
00074
00075 #define rdtscll(val) \
00076 __asm__ __volatile__("rdtsc" : "=A" (val))
00077
00078 #define write_tsc(val1,val2) wrmsr(0x10, val1, val2)
00079
00080 #define rdpmc(counter,low,high) \
00081 __asm__ __volatile__("rdpmc" \
00082 : "=a" (low), "=d" (high) \
00083 : "c" (counter))
00084
00085
00086
00087
00088
00089
00090 static inline void
00091 util_timing_set (util_timing_t * time)
00092 {
00093 rdtsc (time->low, time->high);
00094 }
00095
00096
00097
00098
00099
00100
00101
00102 static inline util_timing_t
00103 util_timing_diff (util_timing_t arg1, util_timing_t arg2)
00104 {
00105 util_timing_t result;
00106
00107 if (arg1.low >= arg2.low)
00108 {
00109
00110
00111 result.low = arg1.low - arg2.low;
00112 result.high = arg1.high - arg2.high;
00113 }
00114 else
00115 {
00116
00117 assert (arg1.high > arg2.high);
00118 result.low = (~((u_int32_t) (0)) - arg2.low) + arg1.low;
00119 result.high = arg1.high - arg2.high - 1;
00120 }
00121 return result;
00122 }
00123
00124
00125
00126
00127
00128
00129
00130 static inline double
00131 util_timing_secs (util_timing_t time)
00132 {
00133 double low = (double) time.low;
00134 double high = (double) time.high;
00135
00136 double maxInt = 1.0 + (double) (~((u_int32_t) 0));
00137 double tick = 1.0 / PROCESSOR_FREQUENCY;
00138
00139 double delta = (tick) * ((low) + maxInt * high);
00140
00141 return delta;
00142 }
00143
00144
00145
00146
00147
00148
00149 static inline double
00150 util_timing_now ()
00151 {
00152 util_timing_t now;
00153 double result;
00154 util_timing_set (&now);
00155 result = util_timing_secs (now);
00156
00157 return result;
00158 }
00159
00160
00161
00162
00163
00164
00165
00166 static inline int
00167 util_timing_compare (util_timing_t arg1, util_timing_t arg2)
00168 {
00169 if (arg1.high < arg2.high)
00170 {
00171 return 1;
00172 }
00173 else if ((arg1.high == arg2.high) && (arg1.low < arg2.low))
00174 {
00175 return 1;
00176 }
00177 else
00178 {
00179 return 0;
00180 }
00181 }
00182
00183
00184
00185
00186
00187
00188
00189 static inline util_timing_t
00190 util_timing_pair (double time)
00191 {
00192 util_timing_t result;
00193 double maxInt = 1.0 + (double) (~((u_int32_t) 0));
00194 double tick = 1.0 / PROCESSOR_FREQUENCY;
00195
00196 double tickTime = time / tick;
00197
00198 double hightime = floor (tickTime / maxInt);
00199 double lowtime = tickTime - (hightime * maxInt);
00200
00201 result.low = lowtime;
00202 result.high = hightime;
00203
00204 return result;
00205 }
00206
00207
00208
00209
00210
00211 static inline void
00212 util_timing_pause (util_timing_t pauseTime)
00213 {
00214 util_timing_t startTime, currentTime, diffTime;
00215 if ((pauseTime.low == 0) && (pauseTime.high == 0))
00216 {
00217 return;
00218 }
00219 util_timing_set (&startTime);
00220
00221 while (1)
00222 {
00223 util_timing_set (¤tTime);
00224 diffTime = util_timing_diff (currentTime, startTime);
00225
00226 if (util_timing_compare (pauseTime, diffTime))
00227 {
00228 return;
00229 }
00230 }
00231 }
00232
00233
00234
00235
00236
00237
00238 static inline void
00239 util_timing_pause_secs (double T)
00240 {
00241 util_timing_t pauseTime = util_timing_pair (T);
00242 util_timing_pause (pauseTime);
00243 }
00244
00245 #ifdef __cplusplus
00246 }
00247 #endif
00248
00249 #endif