64 bit Timer Class.
Revision 3:8396d3e6eb62, committed 2016-03-28
- Comitter:
- tedoyle
- Date:
- Mon Mar 28 16:31:42 2016 +0000
- Parent:
- 2:e89b02820e93
- Child:
- 4:9ca673a83acb
- Child:
- 6:100cf27b43aa
- Commit message:
- Added code to make Timer64 thread safe;
Changed in this revision
Timer64.cpp | Show annotated file Show diff for this revision Revisions of this file |
Timer64.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/Timer64.cpp Sun Mar 27 20:44:54 2016 +0000 +++ b/Timer64.cpp Mon Mar 28 16:31:42 2016 +0000 @@ -23,9 +23,10 @@ _totalTimeUsec(0L), _ticker_data(get_us_ticker_data()), _rollOverCheckTimer(NULL), - _rollOverCheckTimerPeriodInMsec(TIMER64_15MINUTE_ROLLOVER_CHECK_IN_MSECS) + _rollOverCheckTimerPeriodInMsec(TIMER64_DEFAULT_ROLLOVER_CHECK_IN_MSECS), + _sem(NULL) { - reset(); + ; } Timer64::~Timer64() @@ -54,6 +55,7 @@ _totalTimeUsec = 0L; _rollOverCheckTimerPeriodInMsec = rolloverCheckTimeInMsec; _rollOverCheckTimer = new RtosTimer(_rollOverCheck, osTimerPeriodic, this); + _sem = new Semaphore(1); _timerInitialized = true; return(TIMER64_OK); @@ -77,112 +79,198 @@ _rollOverCheckTimer->stop(); delete _rollOverCheckTimer; _rollOverCheckTimer = NULL; + delete _sem; + _sem = NULL; return(TIMER64_OK); } + int Timer64::start(void) { - if (!_timerInitialized) - { - return(TIMER64_ERROR_NOT_INITIALIZED); - } - - if (_timerRunning) + int status = TIMER64_OK; + + _sem->wait(); { - return(TIMER64_WARNING_ALREADY_RUNNING); + if (!_timerInitialized) + { + status = TIMER64_ERROR_NOT_INITIALIZED; + } + else if (_timerRunning) + { + status = TIMER64_WARNING_ALREADY_RUNNING; + } + else + { + _tickerStartTimeUsec = ticker_read(_ticker_data); + _timerRunning = true; + _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec); + } } - - _tickerStartTimeUsec = ticker_read(_ticker_data); - _timerRunning = true; - _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec); - return(TIMER64_OK); + _sem->release(); + + return(status); } int Timer64::stop(void) { - if (!_timerInitialized) - { - return(TIMER64_ERROR_NOT_INITIALIZED); - } - - if (!_timerRunning) + int status = TIMER64_OK; + + _sem->wait(); { - return(TIMER64_WARNING_ALREADY_STOPPED); + if (!_timerInitialized) + { + status = TIMER64_ERROR_NOT_INITIALIZED; + } + else if (!_timerRunning) + { + status = TIMER64_WARNING_ALREADY_STOPPED; + } + else + { + _read_us(this); + _timerRunning = false; + _rollOverCheckTimer->stop(); + } } - - read_us(); - _timerRunning = false; - _rollOverCheckTimer->stop(); + _sem->release(); - return(TIMER64_OK); + return(status); } int Timer64::reset(void) { - if (!_timerInitialized) - { - return(TIMER64_ERROR_NOT_INITIALIZED); - } - - if (_timerRunning) + int status = TIMER64_OK; + + _sem->wait(); { - _tickerStartTimeUsec = ticker_read(_ticker_data); - _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec); + if (!_timerInitialized) + { + status = TIMER64_ERROR_NOT_INITIALIZED; + } + else + { + if (_timerRunning) + { + _tickerStartTimeUsec = ticker_read(_ticker_data); + _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec); + } + + _totalTimeUsec = 0L; + } } + _sem->release(); - _totalTimeUsec = 0L; - return(TIMER64_OK); + return(status); } -uint64_t Timer64::read_us(int* status) +int Timer64::read_us(uint64_t* timeInUsec) { - if (!_timerInitialized) + int status = TIMER64_OK; + + _sem->wait(); { - if (status) + if (!_timerInitialized) { - *status = TIMER64_ERROR_NOT_INITIALIZED; - } - - return(0L); - } - - if (_timerRunning) - { - timestamp_t ticker_current_timeUsec = ticker_read(_ticker_data); - - // check for ticker time rollover - - if (ticker_current_timeUsec >= _tickerStartTimeUsec) - { - _totalTimeUsec += (uint64_t)(ticker_current_timeUsec - _tickerStartTimeUsec); + status = TIMER64_ERROR_NOT_INITIALIZED; } else { - // rollover! - _totalTimeUsec += (4294967296L - ((uint64_t)_tickerStartTimeUsec)) + (uint64_t)ticker_current_timeUsec; - + if (_timerRunning) + { + *timeInUsec = _read_us(this); + } + else + { + *timeInUsec = _totalTimeUsec; + } } - - _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec); - _tickerStartTimeUsec = ticker_current_timeUsec; - } - - return(_totalTimeUsec); + } + _sem->release(); + + return(status); } -uint64_t Timer64::read_ms(int* status) +int Timer64::read_ms(uint64_t* timeInMsec) { - return(read_us(status) / 1000L); + int status = TIMER64_OK; + + _sem->wait(); + { + if (!_timerInitialized) + { + status = TIMER64_ERROR_NOT_INITIALIZED; + } + else + { + if (_timerRunning) + { + *timeInMsec = _read_us(this)/1000L; + } + else + { + *timeInMsec = _totalTimeUsec/1000L; + } + } + } + _sem->release(); + + return(status); } -double Timer64::read(int* status) +int Timer64::read(double* timeInSec) { - return((double)read_us(status) / 1000000.0L); + int status = TIMER64_OK; + + _sem->wait(); + { + if (!_timerInitialized) + { + status = TIMER64_ERROR_NOT_INITIALIZED; + } + else + { + if (_timerRunning) + { + *timeInSec = (double)_read_us(this)/1000000.0L; + } + else + { + *timeInSec = (double)_totalTimeUsec/1000000.0L; + } + } + } + _sem->release(); + + return(status); } void Timer64::_rollOverCheck(void const* args) { Timer64* timer = (Timer64*)args; - timer->read_us(); + timer->_read_us(timer); return; } + +uint64_t Timer64::_read_us(void const* args) +{ + Timer64* timer = (Timer64*)args; + timestamp_t ticker_current_timeUsec = ticker_read(timer->_ticker_data); + + // check for ticker time rollover + + if (ticker_current_timeUsec >= timer->_tickerStartTimeUsec) + { + timer->_totalTimeUsec += (uint64_t)(ticker_current_timeUsec - timer->_tickerStartTimeUsec); + } + else + { + // rollover! + timer->_totalTimeUsec += (4294967296L - ((uint64_t)timer->_tickerStartTimeUsec)) + (uint64_t)ticker_current_timeUsec; + + } + + timer->_rollOverCheckTimer->start(timer->_rollOverCheckTimerPeriodInMsec); + timer->_tickerStartTimeUsec = ticker_current_timeUsec; + return(timer->_totalTimeUsec); +} +
--- a/Timer64.h Sun Mar 27 20:44:54 2016 +0000 +++ b/Timer64.h Mon Mar 28 16:31:42 2016 +0000 @@ -15,9 +15,9 @@ #define TIMER64_WARNING_ALREADY_STOPPED 3 #define TIMER64_WARNING_ALREADY_RELEASED 4 -#define TIMER64_15MINUTE_ROLLOVER_CHECK_IN_MSECS 900000 -#define TIMER64_MIN_ROLLOVER_CHECK_IN_MSECS 60000 // 0:01:00.000 -#define TIMER64_MAX_ROLLOVER_CHECK_IN_MSECS 2147483 // 0:35:47.483 +#define TIMER64_DEFAULT_ROLLOVER_CHECK_IN_MSECS 30000 +#define TIMER64_MIN_ROLLOVER_CHECK_IN_MSECS 1000 +#define TIMER64_MAX_ROLLOVER_CHECK_IN_MSECS 65535 class Timer64 { @@ -48,17 +48,17 @@ */ int reset(void); - /** Get the time passed in seconds + /** Get the time passed in micro-seconds */ - double read(int* status = NULL); + int read_us(uint64_t* timeInUsec = NULL); /** Get the time passed in milli-seconds */ - uint64_t read_ms(int* status = NULL); + int read_ms(uint64_t* timeInMsec = NULL); - /** Get the time passed in micro-seconds + /** Get the time passed in seconds */ - uint64_t read_us(int* status = NULL); + int read(double* timeInSec = NULL); private: bool _timerInitialized; @@ -68,7 +68,10 @@ const ticker_data_t *_ticker_data; RtosTimer* _rollOverCheckTimer; uint32_t _rollOverCheckTimerPeriodInMsec; + Semaphore* _sem; + static void _rollOverCheck(void const* args); + static uint64_t _read_us(void const* args); }; #endif