ext-cryptopp/hrtimer.cpp

125 lines
3.0 KiB
C++
Raw Normal View History

2002-10-04 17:31:41 +00:00
// hrtimer.cpp - written and placed in the public domain by Wei Dai
#include "pch.h"
#include "hrtimer.h"
2003-06-19 19:09:57 +00:00
#include "misc.h"
2002-10-04 17:31:41 +00:00
#include <stddef.h> // for NULL
#ifdef HIGHRES_TIMER_AVAILABLE
#if defined(CRYPTOPP_WIN32_AVAILABLE)
#include <windows.h>
2002-10-04 21:45:04 +00:00
#elif defined(CRYPTOPP_UNIX_AVAILABLE)
2002-10-04 17:31:41 +00:00
#include <sys/time.h>
2004-04-08 01:23:05 +00:00
#include <unistd.h>
2002-10-04 17:31:41 +00:00
#endif
#include <assert.h>
NAMESPACE_BEGIN(CryptoPP)
word64 Timer::GetCurrentTimerValue()
{
#if defined(CRYPTOPP_WIN32_AVAILABLE)
2003-06-19 17:09:07 +00:00
LARGE_INTEGER now;
if (!QueryPerformanceCounter(&now))
throw Exception(Exception::OTHER_ERROR, "Timer: QueryPerformanceCounter failed with error " + IntToString(GetLastError()));
return now.QuadPart;
2002-10-04 21:45:04 +00:00
#elif defined(CRYPTOPP_UNIX_AVAILABLE)
2002-10-04 17:31:41 +00:00
timeval now;
gettimeofday(&now, NULL);
return (word64)now.tv_sec * 1000000 + now.tv_usec;
#endif
}
2003-06-19 17:09:07 +00:00
word64 Timer::TicksPerSecond()
2002-10-04 17:31:41 +00:00
{
2003-06-19 17:09:07 +00:00
#if defined(CRYPTOPP_WIN32_AVAILABLE)
static LARGE_INTEGER freq = {0};
2003-06-19 17:09:07 +00:00
if (freq.QuadPart == 0)
2002-10-04 17:31:41 +00:00
{
2003-06-19 17:09:07 +00:00
if (!QueryPerformanceFrequency(&freq))
throw Exception(Exception::OTHER_ERROR, "Timer: QueryPerformanceFrequency failed with error " + IntToString(GetLastError()));
2002-10-04 17:31:41 +00:00
}
2003-06-19 17:09:07 +00:00
return freq.QuadPart;
2004-04-08 01:23:05 +00:00
#elif defined(CRYPTOPP_UNIX_AVAILABLE)
2003-06-19 17:09:07 +00:00
return 1000000;
#endif
}
2004-04-08 01:23:05 +00:00
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)
2003-06-19 17:09:07 +00:00
{
static unsigned long unitsPerSecondTable[] = {1, 1000, 1000*1000, 1000*1000*1000};
assert(unit < sizeof(unitsPerSecondTable) / sizeof(unitsPerSecondTable[0]));
2004-04-08 01:23:05 +00:00
return (double)t * unitsPerSecondTable[unit] / TicksPerSecond();
2002-10-04 17:31:41 +00:00
}
2004-04-08 01:23:05 +00:00
void TimerBase::StartTimer()
2002-10-04 17:31:41 +00:00
{
m_start = GetCurrentTimerValue();
m_started = true;
}
2004-04-08 01:23:05 +00:00
double TimerBase::ElapsedTimeAsDouble()
2002-10-04 17:31:41 +00:00
{
if (m_stuckAtZero)
return 0;
else if (m_started)
return ConvertTo(GetCurrentTimerValue() - m_start, m_timerUnit);
else
{
StartTimer();
return 0;
}
}
2004-04-08 01:23:05 +00:00
unsigned long TimerBase::ElapsedTime()
2003-06-19 17:09:07 +00:00
{
2004-04-08 01:23:05 +00:00
double elapsed = ElapsedTimeAsDouble();
2003-06-19 17:09:07 +00:00
assert(elapsed <= ULONG_MAX);
return (unsigned long)elapsed;
}
2002-10-04 17:31:41 +00:00
NAMESPACE_END
#endif