#include "session/Timer.hpp" #include #include using namespace std; long long Timer::fixedTime; bool Timer::useRealTime(true); long long Timer::now() { if (!useRealTime) return fixedTime; struct timespec ts; #ifndef OSX_10_8 clock_gettime(Timer::getClock(), &ts); #else clock_get_time(Timer::getClock(), &ts); #endif return static_cast(ts.tv_sec) * 1000 + static_cast(ts.tv_nsec) / 1000000; } #ifndef OSX_10_8 clockid_t Timer::getClock() { return CLOCK_REALTIME; } #else clock_t Timer::getClock() { clock_t value; struct timespec ts; #ifdef __MACH__ // OS X does not have clock_gettime, use clock_get_time clock_serv_t cclock; mach_timespec_t mts; host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); clock_get_time(cclock, &mts); mach_port_deallocate(mach_task_self(), cclock); ts.tv_sec = mts.tv_sec; ts.tv_nsec = mts.tv_nsec; return value; #endif } #endif long long Timer::msDiff(long long compareTime) { return now() - compareTime; } void Timer::setTime(const string& time) throw (ParameterSyntaxException) { const char* format = "%Y%m%d.%H%M%S"; if (time == "") { // Revert to wall time for later calls. useRealTime = true; return; } // On success, strptime() should return a pointer to the address of the // null char. struct tm tm; bzero(&tm, sizeof(tm)); // We do not scan for the 'daylight saving setting', so explicitly // undefine it. tm.tm_isdst = -1; time_t t; const char* res = strptime(time.c_str(), format, &tm); if (res == NULL || res != time.c_str() + time.size() || (t = mktime(&tm)) == -1) { throw ParameterSyntaxException( "Time '" + time + "' not in form 'YYYYMMDD.hhmmss' or is an illegal time."); } // mktime is in seconds, Date in milli. fixedTime = static_cast(t) * 1000L; useRealTime = false; } struct timespec Timer::msOffset2abs(long long msOffset) { const unsigned int ms_per_sec = 1000; const unsigned int ns_per_ms = 1000; struct timespec now; struct timespec until; #ifndef OSX_10_8 clock_gettime(Timer::getClock(), &now); until.tv_sec = now.tv_sec + msOffset / ms_per_sec; until.tv_nsec = now.tv_nsec + msOffset * ns_per_ms; #else #endif return until; }