00001
00002
00003
#include "pch.h"
00004
#include "hrtimer.h"
00005
#include "misc.h"
00006
#include <stddef.h>
00007
#include <time.h>
00008
00009
#if defined(CRYPTOPP_WIN32_AVAILABLE)
00010
#include <windows.h>
00011
#elif defined(CRYPTOPP_UNIX_AVAILABLE)
00012
#include <sys/time.h>
00013
#include <sys/times.h>
00014
#include <unistd.h>
00015
#endif
00016
00017
#include <assert.h>
00018
00019 NAMESPACE_BEGIN(CryptoPP)
00020
00021 double
TimerBase::ConvertTo(word64 t, Unit unit)
00022 {
00023
static unsigned long unitsPerSecondTable[] = {1, 1000, 1000*1000, 1000*1000*1000};
00024
00025 assert(unit <
sizeof(unitsPerSecondTable) /
sizeof(unitsPerSecondTable[0]));
00026
return (
double)t * unitsPerSecondTable[unit] / TicksPerSecond();
00027 }
00028
00029
void TimerBase::StartTimer()
00030 {
00031 m_start = GetCurrentTimerValue();
00032 m_started =
true;
00033 }
00034
00035
double TimerBase::ElapsedTimeAsDouble()
00036 {
00037
if (m_stuckAtZero)
00038
return 0;
00039
else if (m_started)
00040
return ConvertTo(GetCurrentTimerValue() - m_start, m_timerUnit);
00041
else
00042 {
00043 StartTimer();
00044
return 0;
00045 }
00046 }
00047
00048
unsigned long TimerBase::ElapsedTime()
00049 {
00050
double elapsed = ElapsedTimeAsDouble();
00051 assert(elapsed <= ULONG_MAX);
00052
return (
unsigned long)elapsed;
00053 }
00054
00055 word64 ThreadUserTimer::GetCurrentTimerValue()
00056 {
00057
#if defined(CRYPTOPP_WIN32_AVAILABLE)
00058
static bool getCurrentThreadImplemented =
true;
00059
if (getCurrentThreadImplemented)
00060 {
00061 FILETIME now, ignored;
00062
if (!GetThreadTimes(GetCurrentThread(), &ignored, &ignored, &ignored, &now))
00063 {
00064 DWORD lastError = GetLastError();
00065
if (lastError == ERROR_CALL_NOT_IMPLEMENTED)
00066 {
00067 getCurrentThreadImplemented =
false;
00068
goto GetCurrentThreadNotImplemented;
00069 }
00070
throw Exception(Exception::OTHER_ERROR,
"ThreadUserTimer: GetThreadTimes failed with error " + IntToString(lastError));
00071 }
00072
return now.dwLowDateTime + ((word64)now.dwHighDateTime << 32);
00073 }
00074 GetCurrentThreadNotImplemented:
00075
return (word64)clock() * (10*1000*1000 / CLOCKS_PER_SEC);
00076
#elif defined(CRYPTOPP_UNIX_AVAILABLE)
00077
tms now;
00078 times(&now);
00079
return now.tms_utime;
00080
#else
00081
return clock();
00082
#endif
00083
}
00084
00085 word64 ThreadUserTimer::TicksPerSecond()
00086 {
00087
#if defined(CRYPTOPP_WIN32_AVAILABLE)
00088
return 10*1000*1000;
00089
#elif defined(CRYPTOPP_UNIX_AVAILABLE)
00090
static const long ticksPerSecond = sysconf(_SC_CLK_TCK);
00091
return ticksPerSecond;
00092
#else
00093
return CLOCKS_PER_SEC;
00094
#endif
00095
}
00096
00097
#ifdef HIGHRES_TIMER_AVAILABLE
00098
00099 word64 Timer::GetCurrentTimerValue()
00100 {
00101
#if defined(CRYPTOPP_WIN32_AVAILABLE)
00102
LARGE_INTEGER now;
00103
if (!QueryPerformanceCounter(&now))
00104
throw Exception(Exception::OTHER_ERROR,
"Timer: QueryPerformanceCounter failed with error " + IntToString(GetLastError()));
00105
return now.QuadPart;
00106
#elif defined(CRYPTOPP_UNIX_AVAILABLE)
00107
timeval now;
00108 gettimeofday(&now, NULL);
00109
return (word64)now.tv_sec * 1000000 + now.tv_usec;
00110
#endif
00111
}
00112
00113 word64 Timer::TicksPerSecond()
00114 {
00115
#if defined(CRYPTOPP_WIN32_AVAILABLE)
00116
static LARGE_INTEGER freq = {0};
00117
if (freq.QuadPart == 0)
00118 {
00119
if (!QueryPerformanceFrequency(&freq))
00120
throw Exception(Exception::OTHER_ERROR,
"Timer: QueryPerformanceFrequency failed with error " + IntToString(GetLastError()));
00121 }
00122
return freq.QuadPart;
00123
#elif defined(CRYPTOPP_UNIX_AVAILABLE)
00124
return 1000000;
00125
#endif
00126
}
00127
00128
#endif
00129
00130 NAMESPACE_END