Listing 2: clock.cpp.
// clock.cpp Begin #include <clock.hpp> #ifdef __PALMOS inline clock_t clock(); #elif defined ( __WINDOWS ) inline clock_t clock(); #endif clock_t cClock::_mClockStart = 0; clock_t cClock::_mNumClockCalls = 0; clock_t cClock::_mDesClockRes = 0; clock_t cClock::_mDesClocksPerSec = 0; clock_t cClock::_mNatClockRes = 0; clock_t cClock::_mCalPeriod = 0; clock_t cClock::_mCalCorrection = 0; cClock::cClock( clock_t ClocksPerSec ) { if ( !_mNumClockCalls ) { // First time through so initialize InitClock(); SetClockRes( ClocksPerSec ); } } cClock::cClock( clock_t CalPeriod, clock_t CalCorrection, clock_t ClocksPerSec ) { this->cClock::cClock( ClocksPerSec ); _mCalPeriod = CalPeriod; _mCalCorrection = CalCorrection; } clock_t cClock::StartClock() { _mClockStart = 0; _mClockStart = GetClock(); return ( _mClockStart ); } clock_t cClock::GetClock() { clock_t Clock1, Clock2 = 0, NumCalls = 0; Clock1 = clock(); if ( _mDesClockRes < _mNatClockRes ) { // Use number of clock calls to get finer resolution Clock2 = LoopClock( Clock1, &NumCalls ); if ( NumCalls < _mNumClockCalls ) { // Get fraction of clock tick res that had transpired Clock2 = _mNumClockCalls - NumCalls; Clock2 *= _mNatClockRes; if ( _mDesClocksPerSec > CLOCKS_PER_SEC ) { // Covnert clock value to designated units Clock2 *= _mDesClocksPerSec / CLOCKS_PER_SEC; } Clock2 /= _mNumClockCalls; } else { // clock had just ticked Clock2 = 0; } } if ( _mDesClocksPerSec > CLOCKS_PER_SEC ) { // Covnert clock value to designated units Clock1 *= _mDesClocksPerSec / CLOCKS_PER_SEC; } Clock2 += Clock1; if ( _mDesClocksPerSec < CLOCKS_PER_SEC ) { // Covnert clock value to designated units Clock2 = RoundToRes( Clock2 ); } Clock2 -= _mClockStart; // Get time from start return ( Clock2 ); } clock_t cClock::GetCalClock() { clock_t Clock = GetClock(); if ( _mCalPeriod && _mClockStart ) { // Adjust time by the calibration correction Clock += ( ( _mCalCorrection * Clock ) / _mCalPeriod ); } return ( Clock ); } clock_t cClock::GetClocksPerSec() { return ( _mDesClocksPerSec ); } void cClock::SetCalibration( clock_t CalPeriod, clock_t CalCorrection ) { _mCalPeriod = CalPeriod; _mCalCorrection = CalCorrection; } void cClock::CalcCalibration( clock_t ActualTime, clock_t MeasuredTime, clock_t Correction ) { clock_t Error = ActualTime - MeasuredTime; clock_t Periods = Error / Correction; _mCalPeriod = 0; if ( Periods != 0 ) { _mCalPeriod = MeasuredTime / Periods; _mCalCorrection = Correction; } } void cClock::InitClock() { clock_t Clock1, Clock2, Clock3; clock_t Dummy = 0, NumCalls1 = 0, NumCalls2 = 0; Clock1 = clock(); Clock2 = LoopClock( Clock1, &Dummy ); // Make clock tick Clock3 = LoopClock( Clock2, &NumCalls1 ); Clock1 = LoopClock( Clock3, &NumCalls2 ); // Average two clock ticks _mNumClockCalls = ( NumCalls1 + NumCalls2 ) / 2; _mNatClockRes = ( Clock1 - Clock2 ) / 2; } clock_t cClock::LoopClock( clock_t Clock1, clock_t *NumCalls ) { clock_t Clock2; do { // Call the clock function till it updates (or ticks) (*NumCalls)++; // Count the number of times called Clock2 = clock(); } while ( Clock2 == Clock1 ); return ( Clock2 ); } void cClock::SetClockRes( clock_t ClocksPerSec ) { if ( !ClocksPerSec ) { // Set the designated units to the native value _mDesClocksPerSec = CLOCKS_PER_SEC; } else { _mDesClocksPerSec = ClocksPerSec; } // Calculate the designated resolution // A 0 value means the designated units are finer then the native units _mDesClockRes = CLOCKS_PER_SEC / _mDesClocksPerSec; } clock_t cClock::RoundToRes( clock_t Clock ) { clock_t Remainder = Clock % ( CLOCKS_PER_SEC / _mDesClocksPerSec ); Clock = ( Clock * _mDesClocksPerSec ) / CLOCKS_PER_SEC; if ( Remainder >= 5 ) { // Round the time up by one Clock++; } return ( Clock ); } #ifdef __PALMOS inline clock_t clock() { return ( (clock_t)TimGetTicks() ); } #elif defined( __WINDOWS ) inline clock_t clock() { return ( (clock_t)GetTickCount() ); } #endif // clock.cpp End