28 static char THIS_FILE[] = __FILE__;
33 using namespace libjmmcg;
35 IMPLEMENT_DYNAMIC(P5_Ticker, CObject)
37 #pragma optimize("",off)
38 inline bool P5_Ticker::Check_Has_RDTSC(
void)
const
41 GetSystemInfo(&sys_info);
42 if (sys_info.dwProcessorType==PROCESSOR_INTEL_PENTIUM)
55 TRACE0(
"RDTSC instruction NOT present.\n");
59 volatile ULARGE_INTEGER ts1,ts2;
78 if (ts2.HighPart==ts1.HighPart)
80 if (ts2.LowPart>ts1.LowPart)
82 TRACE0(
"RDTSC instruction probably present.\n");
87 TRACE0(
"RDTSC instruction NOT present.\n");
91 else if (ts2.HighPart>ts1.HighPart)
93 TRACE0(
"RDTSC instruction probably present.\n");
98 TRACE0(
"RDTSC instruction NOT present.\n");
104 TRACE0(
"RDTSC instruction NOT present.\n");
108 #pragma optimize("",on)
110 P5_Ticker::os_type P5_Ticker::Check_Os(
void)
const
114 osvi.dwOSVersionInfoSize =
sizeof (OSVERSIONINFO);
116 if (osvi.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
120 else if (osvi.dwPlatformId==VER_PLATFORM_WIN32_NT)
127 P5_Ticker::P5_Ticker(
void)
130 Has_RDTSC=Check_Has_RDTSC();
134 inline P5_Ticker::P5_Ticker(
const P5_Ticker &ts)
136 Has_RDTSC=ts.Has_RDTSC;
137 count.QuadPart=ts.count.QuadPart;
140 P5_Ticker &P5_Ticker::operator=(
const P5_Ticker &ts)
142 Has_RDTSC=ts.Has_RDTSC;
143 count.QuadPart=ts.count.QuadPart;
147 P5_Ticker &P5_Ticker::operator=(
const ULARGE_INTEGER &ts)
149 Has_RDTSC=Check_Has_RDTSC();
150 count.QuadPart=ts.QuadPart;
154 inline P5_Ticker P5_Ticker::operator+(
const P5_Ticker &ts1)
const
157 ts.count.QuadPart=count.QuadPart+ts1.count.QuadPart;
161 inline P5_Ticker P5_Ticker::operator-(
const P5_Ticker &ts1)
const
164 ts.count.QuadPart=count.QuadPart-ts1.count.QuadPart;
168 P5_Ticker &P5_Ticker::Get_Time(
void)
174 else if (on_os==win_95)
181 #pragma optimize("",off)
182 inline P5_Ticker &P5_Ticker::Get_Time_NT(
void)
186 volatile ULARGE_INTEGER ts;
192 _emit 0x0f ; cpuid - serialise the processor
201 TRACE1(
"Time stamp counter value: quad=%lu.\n",ts.QuadPart);
202 count.QuadPart=ts.QuadPart;
210 #pragma optimize("",on)
212 #pragma optimize("",off)
213 inline P5_Ticker &P5_Ticker::Get_Time_95(
void)
217 volatile ULARGE_INTEGER ts;
224 _emit 0x0f ; cpuid - serialise the processor
234 TRACE1(
"Time stamp counter value: quad=%lu.\n",ts.QuadPart);
235 count.QuadPart=ts.QuadPart;
243 #pragma optimize("",on)
263 #pragma optimize("",off)
264 double P5_Ticker::Get_Frequency(
double &target_ave_dev,
const unsigned long interval,
const unsigned int max_loops)
const
267 register LARGE_INTEGER goal,period,current;
268 register unsigned int ctr=0;
269 double curr_freq,ave_freq;
270 double ave_dev,tmp=0;
272 if (!QueryPerformanceFrequency(&period))
274 throw no_performance_counter;
276 period.QuadPart*=interval;
277 period.QuadPart/=1000;
280 QueryPerformanceCounter(&goal);
281 goal.QuadPart+=period.QuadPart;
285 QueryPerformanceCounter(¤t);
286 }
while(current.QuadPart<goal.QuadPart);
290 ave_freq=1000*(f-s).To_Ticks()/interval;
294 QueryPerformanceCounter(&goal);
295 goal.QuadPart+=period.QuadPart;
299 QueryPerformanceCounter(¤t);
300 }
while(current.QuadPart<goal.QuadPart);
305 curr_freq=1000*(f-s).To_Ticks()/interval;
306 ave_freq=(curr_freq+ave_freq)/2;
309 tmp+=fabs(curr_freq-ave_freq);
311 }
while (ave_dev>target_ave_dev && ctr<max_loops);
312 target_ave_dev=ave_dev;
313 TRACE2(
"Estimated the processor clock frequency =%gHz, dev.=�%gHz.\n",ave_freq,ave_dev);
316 #pragma optimize("",on)
322 void P5_Ticker::AssertValid(
void)
const
324 CObject::AssertValid();
327 void P5_Ticker::Dump(CDumpContext& dc)
const
331 _T(
"RDTSC instruction detected on target processor:%i.\n")<<Has_RDTSC
332 <<_T(
"Current value of Time Stamp counter (truncated to unsigned long):%lu.\n")<<(
unsigned long)count.QuadPart