////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////// #include #include #include "processclock.h" #include "strutil.h" ////////////////////////////////////////////////////////////////////////////////// #define _NSEC_PER_USEC _PC_NS_PER_US #define _NSEC_PER_MSEC (_NSEC_PER_USEC * _PC_US_PER_MS) #define _NSEC_PER_SEC (_NSEC_PER_MSEC * _PC_MS_PER_S) #define _NSEC_PER_MIN (_NSEC_PER_SEC * 60LL) #define _NSEC_PER_HOUR (_NSEC_PER_MIN * 60LL) ////////////////////////////////////////////////////////////////////////////////// CProcessClock::CProcessClock(bool bInitAtConstr) { if(bInitAtConstr) { clock_gettime(CLOCK_MONOTONIC, &m_tsDueTime); m_bIsInit = true; } else { memset(&m_tsDueTime, 0, sizeof(m_tsDueTime)); m_bIsInit = false; } for(int i = 0; i < _PC_NUM_STOPCLOCKS; i++) { StopclockReset(i); } } CProcessClock::~CProcessClock(void) { } ////////////////////////////////////////////////////////////////////////////////// pc_time64_t CProcessClock::GetNanoTick(struct timespec *pts) { struct timespec ts; if(!pts) pts = &ts; clock_gettime(CLOCK_MONOTONIC, pts); return Timespec2NanoSec(pts); } pc_time64_t CProcessClock::ClockGetElapsed(unsigned int nClockIndex) const { if(nClockIndex >= _PC_NUM_STOPCLOCKS) return -1; struct timespec tsCur; clock_gettime(CLOCK_MONOTONIC, &tsCur); pc_time64_t n1 = Timespec2NanoSec(&m_sc[nClockIndex].tsStopclock); pc_time64_t n2 = Timespec2NanoSec(&tsCur); pc_time64_t nElapsed = n2 - n1; return nElapsed; } CProcessClock::SleepResult CProcessClock::NSleep(pc_time64_t nInterval, bool bResumeOnIntr) { int nRet; pc_time64_t dt; if(!m_bIsInit) { clock_gettime(CLOCK_MONOTONIC, &m_tsDueTime); m_bIsInit = true; } dt = IncTime(&m_tsDueTime, nInterval); if(dt < GetNanoTick()) { clock_gettime(CLOCK_MONOTONIC, &m_tsDueTime); return SR_TimerUnderrun; } if((nRet = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &m_tsDueTime, NULL))) { if(bResumeOnIntr) { while(nRet == EINTR) { nRet = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &m_tsDueTime, NULL); } } } return !nRet ? SR_Ok : ((nRet == EINTR) ? SR_Interrupt : SR_Error); } std::string CProcessClock::Interval2String(pc_time64_t nInterval) { if(nInterval < 0) return "(error negative value)"; if(nInterval < _NSEC_PER_USEC) return formatString("%lld ns", nInterval); else if(nInterval < _NSEC_PER_MSEC) return formatString("%.1f us", (double)nInterval / (double)_NSEC_PER_USEC); else if(nInterval < _NSEC_PER_SEC) return formatString("%.2f ms", (double)nInterval / (double)_NSEC_PER_MSEC); else if(nInterval < _NSEC_PER_MIN) return formatString("%.2f sec", (double)nInterval / (double)_NSEC_PER_SEC); else if(nInterval < _NSEC_PER_HOUR) return formatString("%.2f min", (double)nInterval / (double)_NSEC_PER_MIN); else return formatString("%.2f h", (double)nInterval / (double)_NSEC_PER_HOUR); }