64 bit Timer Class.

Files at this revision

API Documentation at this revision

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