Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

# hrtimer.cpp

    00001 // hrtimer.cpp - written and placed in the public domain by Wei Dai
    00002
    00003 #include "pch.h"
    00004 #include "hrtimer.h"
    00005 #include "misc.h"
    00006 #include <stddef.h>             // for NULL
    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