add ThreadUserTimer
parent
e317188acc
commit
38663cf6dd
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue