add ThreadUserTimer

import/raw
weidai 2004-04-08 01:23:05 +00:00
parent e317188acc
commit 38663cf6dd
3 changed files with 74 additions and 28 deletions

View File

@ -193,7 +193,7 @@ NAMESPACE_END
#define CRYPTOPP_UNIX_AVAILABLE #define CRYPTOPP_UNIX_AVAILABLE
#endif #endif
#if defined(WORD64_AVAILABLE) && (defined(CRYPTOPP_WIN32_AVAILABLE) || defined(CRYPTOPP_UNIX_AVAILABLE) || defined(macintosh)) #if defined(WORD64_AVAILABLE) && (defined(CRYPTOPP_WIN32_AVAILABLE) || defined(CRYPTOPP_UNIX_AVAILABLE))
# define HIGHRES_TIMER_AVAILABLE # define HIGHRES_TIMER_AVAILABLE
#endif #endif

View File

@ -11,8 +11,7 @@
#include <windows.h> #include <windows.h>
#elif defined(CRYPTOPP_UNIX_AVAILABLE) #elif defined(CRYPTOPP_UNIX_AVAILABLE)
#include <sys/time.h> #include <sys/time.h>
#elif defined(macintosh) #include <unistd.h>
#include <Timer.h>
#endif #endif
#include <assert.h> #include <assert.h>
@ -30,10 +29,6 @@ word64 Timer::GetCurrentTimerValue()
timeval now; timeval now;
gettimeofday(&now, NULL); gettimeofday(&now, NULL);
return (word64)now.tv_sec * 1000000 + now.tv_usec; return (word64)now.tv_sec * 1000000 + now.tv_usec;
#elif defined(macintosh)
UnsignedWide now;
Microseconds(&now);
return now.lo + ((word64)now.hi << 32);
#endif #endif
} }
@ -47,32 +42,64 @@ word64 Timer::TicksPerSecond()
throw Exception(Exception::OTHER_ERROR, "Timer: QueryPerformanceFrequency failed with error " + IntToString(GetLastError())); throw Exception(Exception::OTHER_ERROR, "Timer: QueryPerformanceFrequency failed with error " + IntToString(GetLastError()));
} }
return freq.QuadPart; return freq.QuadPart;
#elif defined(CRYPTOPP_UNIX_AVAILABLE) || defined(macintosh) #elif defined(CRYPTOPP_UNIX_AVAILABLE)
return 1000000; return 1000000;
#endif #endif
} }
word64 Timer::ConvertTo(word64 t, Unit unit) word64 ThreadUserTimer::GetCurrentTimerValue()
{
#if defined(CRYPTOPP_WIN32_AVAILABLE)
static bool getCurrentThreadImplemented = true;
if (getCurrentThreadImplemented)
{
FILETIME now, ignored;
if (!GetThreadTimes(GetCurrentThread(), &ignored, &ignored, &ignored, &now))
{
DWORD lastError = GetLastError();
if (lastError == ERROR_CALL_NOT_IMPLEMENTED)
{
getCurrentThreadImplemented = false;
goto GetCurrentThreadNotImplemented;
}
throw Exception(Exception::OTHER_ERROR, "ThreadUserTimer: GetThreadTimes failed with error " + IntToString(lastError));
}
return now.dwLowDateTime + ((word64)now.dwHighDateTime << 32);
}
GetCurrentThreadNotImplemented:
return (word64)clock() * (10*1000*1000 / CLOCKS_PER_SEC);
#elif defined(CRYPTOPP_UNIX_AVAILABLE)
tms now;
times(&now);
return now.tms_utime;
#endif
}
word64 ThreadUserTimer::TicksPerSecond()
{
#if defined(CRYPTOPP_WIN32_AVAILABLE)
return 10*1000*1000;
#elif defined(CRYPTOPP_UNIX_AVAILABLE)
static const long ticksPerSecond = sysconf(_SC_CLK_TCK);
return ticksPerSecond;
#endif
}
double TimerBase::ConvertTo(word64 t, Unit unit)
{ {
static unsigned long unitsPerSecondTable[] = {1, 1000, 1000*1000, 1000*1000*1000}; static unsigned long unitsPerSecondTable[] = {1, 1000, 1000*1000, 1000*1000*1000};
assert(unit < sizeof(unitsPerSecondTable) / sizeof(unitsPerSecondTable[0])); assert(unit < sizeof(unitsPerSecondTable) / sizeof(unitsPerSecondTable[0]));
unsigned long unitsPerSecond = unitsPerSecondTable[unit]; return (double)t * unitsPerSecondTable[unit] / TicksPerSecond();
const word64 freq = TicksPerSecond();
if (freq % unitsPerSecond == 0)
return t / (freq / unitsPerSecond);
else
return word64((double)t * unitsPerSecond / freq);
} }
void Timer::StartTimer() void TimerBase::StartTimer()
{ {
m_start = GetCurrentTimerValue(); m_start = GetCurrentTimerValue();
m_started = true; m_started = true;
} }
word64 Timer::ElapsedTimeInWord64() double TimerBase::ElapsedTimeAsDouble()
{ {
if (m_stuckAtZero) if (m_stuckAtZero)
return 0; return 0;
@ -85,9 +112,9 @@ word64 Timer::ElapsedTimeInWord64()
} }
} }
unsigned long Timer::ElapsedTime() unsigned long TimerBase::ElapsedTime()
{ {
word64 elapsed = ElapsedTimeInWord64(); double elapsed = ElapsedTimeAsDouble();
assert(elapsed <= ULONG_MAX); assert(elapsed <= ULONG_MAX);
return (unsigned long)elapsed; return (unsigned long)elapsed;
} }

View File

@ -7,28 +7,47 @@ NAMESPACE_BEGIN(CryptoPP)
#ifdef HIGHRES_TIMER_AVAILABLE #ifdef HIGHRES_TIMER_AVAILABLE
//! high resolution timer class TimerBase
class Timer
{ {
public: public:
enum Unit {SECONDS = 0, MILLISECONDS, MICROSECONDS, NANOSECONDS}; enum Unit {SECONDS = 0, MILLISECONDS, MICROSECONDS, NANOSECONDS};
Timer(Unit unit, bool stuckAtZero = false) : m_timerUnit(unit), m_stuckAtZero(stuckAtZero), m_started(false) {} TimerBase(Unit unit, bool stuckAtZero) : m_timerUnit(unit), m_stuckAtZero(stuckAtZero), m_started(false) {}
static word64 GetCurrentTimerValue(); // GetCurrentTime is a macro in MSVC 6.0 virtual word64 GetCurrentTimerValue() =0; // GetCurrentTime is a macro in MSVC 6.0
static word64 ConvertTo(word64 t, Unit unit); virtual word64 TicksPerSecond() =0; // this is not the resolution, just a conversion factor into seconds
// this is not the resolution, just a conversion factor into seconds
static word64 TicksPerSecond();
void StartTimer(); void StartTimer();
word64 ElapsedTimeInWord64(); double ElapsedTimeAsDouble();
unsigned long ElapsedTime(); unsigned long ElapsedTime();
private: private:
double ConvertTo(word64 t, Unit unit);
Unit m_timerUnit; // HPUX workaround: m_unit is a system macro on HPUX Unit m_timerUnit; // HPUX workaround: m_unit is a system macro on HPUX
bool m_stuckAtZero, m_started; bool m_stuckAtZero, m_started;
word64 m_start; word64 m_start;
}; };
//! high resolution timer
class Timer : public TimerBase
{
public:
Timer(Unit unit = TimerBase::SECONDS, bool stuckAtZero = false) : TimerBase(unit, stuckAtZero) {}
word64 GetCurrentTimerValue();
word64 TicksPerSecond();
};
//! measure CPU time spent executing instructions of this thread (if supported by OS)
/*! /note This only works correctly on Windows NT or later. On Unix it reports process time, and on Windows 98 wall clock time.
*/
class ThreadUserTimer : public TimerBase
{
public:
ThreadUserTimer(Unit unit = TimerBase::SECONDS, bool stuckAtZero = false) : TimerBase(unit, stuckAtZero) {}
word64 GetCurrentTimerValue();
word64 TicksPerSecond();
};
#endif #endif
NAMESPACE_END NAMESPACE_END