Advertisement
Guest User

Untitled

a guest
Apr 10th, 2016
246
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.53 KB | None | 0 0
  1. class VirtualTimer {
  2.     private:
  3.         static VirtualTimer *volatile _firstVirtualTimer;
  4.        
  5.         uint32_t _period;
  6.        
  7.         TimerCallback _callback;
  8.        
  9.         void *_callbackArg;
  10.        
  11.         VirtualTimer *volatile _next;
  12.        
  13.         timestamp_t _targetTimestamp;
  14.        
  15.         volatile bool _armed;
  16.        
  17.         void fire();
  18.        
  19.         bool doStart();
  20.        
  21.     public:
  22.         VirtualTimer();
  23.        
  24.         VirtualTimer(uint32_t period, TimerCallback callback = NULL, void *arg = NULL);
  25.        
  26.         ~VirtualTimer();
  27.        
  28.         void setCallback(TimerCallback callback, void *arg);
  29.        
  30.         bool setPeriod(uint32_t period);
  31.        
  32.         uint32_t getPeriod() {
  33.             return _period;
  34.         }
  35.        
  36.         void start();
  37.        
  38.         void stop();
  39.        
  40.         bool isArmed() {
  41.             return _armed;
  42.         }
  43.        
  44.         static timestamp_t getDeadline() {
  45.             return (_firstVirtualTimer != NULL) ? (_firstVirtualTimer->_targetTimestamp) : TIME_INFINITE;
  46.         }
  47.        
  48.         static void tick();
  49.        
  50. };
  51.  
  52. VirtualTimer *volatile VirtualTimer::_firstVirtualTimer;
  53.  
  54. VirtualTimer::VirtualTimer() {
  55.     _period = 0;
  56.     _callback = NULL;
  57.     _armed = false;
  58. }
  59.  
  60. VirtualTimer::VirtualTimer(uint32_t period, TimerCallback callback, void *arg) {
  61.     _period = period;
  62.     _callback = callback;
  63.     _callbackArg = arg;
  64.     _armed = false;
  65.     start();
  66. }
  67.  
  68. VirtualTimer::~VirtualTimer() {
  69.     stop();
  70. }
  71.  
  72. void VirtualTimer::setCallback(TimerCallback callback, void *arg) {
  73.     _callback = callback;
  74.     _callbackArg = arg;
  75. }
  76.  
  77. bool VirtualTimer::setPeriod(uint32_t period) {
  78.     _period = period;
  79.     if (_armed) {
  80.         stop();
  81.         start();
  82.     }
  83.     return true;
  84. }
  85.  
  86. bool VirtualTimer::doStart() {
  87.     _targetTimestamp = getCurrentTimestamp() + _period;
  88.     bool deadlineChanged = false;
  89.     if (!_armed) {
  90.         _armed = true;
  91.         VirtualTimer *vt = (VirtualTimer*)_firstVirtualTimer;
  92.         if ((vt == NULL) || (vt->_targetTimestamp >= _targetTimestamp)) {
  93.             _next = vt;
  94.             _firstVirtualTimer = this;
  95.             deadlineChanged = true;
  96.         } else {
  97.             VirtualTimer *prevVT;
  98.             vt = (VirtualTimer*)vt->_next;
  99.             while (vt != NULL) {
  100.                 if (vt->_targetTimestamp >= _targetTimestamp) {
  101.                     break;
  102.                 }
  103.                 prevVT = vt;
  104.                 vt = (VirtualTimer*)vt->_next;
  105.             }
  106.             _next = vt;
  107.             prevVT->_next = this;
  108.         }
  109.     }
  110.     return deadlineChanged;
  111. }
  112.  
  113. void VirtualTimer::start() {
  114.     lockSystem();
  115.     if (doStart()) {
  116.         virtualTimerDeadlineChanged(_targetTimestamp);
  117.     }
  118.     unlockSystem();
  119. }
  120.  
  121. void VirtualTimer::stop() {
  122.     lockSystem();
  123.     if (_armed) {
  124.         VirtualTimer *vt = (VirtualTimer*)_firstVirtualTimer;
  125.         if (vt == this) {
  126.             _firstVirtualTimer = _next;
  127.             if (_next == NULL) {
  128.                 virtualTimerDeadlineChanged(TIME_INFINITE);
  129.             } else if (_next->_targetTimestamp > _targetTimestamp) {
  130.                 virtualTimerDeadlineChanged(_next->_targetTimestamp);
  131.             }
  132.         } else {
  133.             VirtualTimer *prevVT = vt;
  134.             vt = (VirtualTimer*)vt->_next;
  135.             while (vt != NULL) {
  136.                 if (vt == this) {
  137.                     break;
  138.                 }
  139.                 prevVT = vt;
  140.                 vt = (VirtualTimer*)vt->_next;
  141.             }
  142.             assert(vt != NULL);
  143.             prevVT->_next = _next;
  144.         }
  145.         _armed = false;
  146.     }
  147.     unlockSystem();
  148. }
  149.  
  150. void VirtualTimer::fire() {
  151.     _armed = false;
  152.     if ((_callback == NULL) || _callback(_callbackArg)) {
  153.         doStart();
  154.     }
  155. }
  156.  
  157. void VirtualTimer::tick() {
  158.     lockSystem();
  159.     timestamp_t timestamp = getCurrentTimestamp();
  160.     bool deadlineChanged = false;
  161.     while ((_firstVirtualTimer != NULL) && (_firstVirtualTimer->_targetTimestamp <= timestamp)) {
  162.         VirtualTimer *timer = (VirtualTimer*)_firstVirtualTimer;
  163.         _firstVirtualTimer = _firstVirtualTimer->_next;
  164.         timer->fire();
  165.         deadlineChanged = true;
  166.     }
  167.     if (deadlineChanged) {
  168.         virtualTimerDeadlineChanged(getDeadline());
  169.     }
  170.     unlockSystem();
  171. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement