Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class VirtualTimer {
- private:
- static VirtualTimer *volatile _firstVirtualTimer;
- uint32_t _period;
- TimerCallback _callback;
- void *_callbackArg;
- VirtualTimer *volatile _next;
- timestamp_t _targetTimestamp;
- volatile bool _armed;
- void fire();
- bool doStart();
- public:
- VirtualTimer();
- VirtualTimer(uint32_t period, TimerCallback callback = NULL, void *arg = NULL);
- ~VirtualTimer();
- void setCallback(TimerCallback callback, void *arg);
- bool setPeriod(uint32_t period);
- uint32_t getPeriod() {
- return _period;
- }
- void start();
- void stop();
- bool isArmed() {
- return _armed;
- }
- static timestamp_t getDeadline() {
- return (_firstVirtualTimer != NULL) ? (_firstVirtualTimer->_targetTimestamp) : TIME_INFINITE;
- }
- static void tick();
- };
- VirtualTimer *volatile VirtualTimer::_firstVirtualTimer;
- VirtualTimer::VirtualTimer() {
- _period = 0;
- _callback = NULL;
- _armed = false;
- }
- VirtualTimer::VirtualTimer(uint32_t period, TimerCallback callback, void *arg) {
- _period = period;
- _callback = callback;
- _callbackArg = arg;
- _armed = false;
- start();
- }
- VirtualTimer::~VirtualTimer() {
- stop();
- }
- void VirtualTimer::setCallback(TimerCallback callback, void *arg) {
- _callback = callback;
- _callbackArg = arg;
- }
- bool VirtualTimer::setPeriod(uint32_t period) {
- _period = period;
- if (_armed) {
- stop();
- start();
- }
- return true;
- }
- bool VirtualTimer::doStart() {
- _targetTimestamp = getCurrentTimestamp() + _period;
- bool deadlineChanged = false;
- if (!_armed) {
- _armed = true;
- VirtualTimer *vt = (VirtualTimer*)_firstVirtualTimer;
- if ((vt == NULL) || (vt->_targetTimestamp >= _targetTimestamp)) {
- _next = vt;
- _firstVirtualTimer = this;
- deadlineChanged = true;
- } else {
- VirtualTimer *prevVT;
- vt = (VirtualTimer*)vt->_next;
- while (vt != NULL) {
- if (vt->_targetTimestamp >= _targetTimestamp) {
- break;
- }
- prevVT = vt;
- vt = (VirtualTimer*)vt->_next;
- }
- _next = vt;
- prevVT->_next = this;
- }
- }
- return deadlineChanged;
- }
- void VirtualTimer::start() {
- lockSystem();
- if (doStart()) {
- virtualTimerDeadlineChanged(_targetTimestamp);
- }
- unlockSystem();
- }
- void VirtualTimer::stop() {
- lockSystem();
- if (_armed) {
- VirtualTimer *vt = (VirtualTimer*)_firstVirtualTimer;
- if (vt == this) {
- _firstVirtualTimer = _next;
- if (_next == NULL) {
- virtualTimerDeadlineChanged(TIME_INFINITE);
- } else if (_next->_targetTimestamp > _targetTimestamp) {
- virtualTimerDeadlineChanged(_next->_targetTimestamp);
- }
- } else {
- VirtualTimer *prevVT = vt;
- vt = (VirtualTimer*)vt->_next;
- while (vt != NULL) {
- if (vt == this) {
- break;
- }
- prevVT = vt;
- vt = (VirtualTimer*)vt->_next;
- }
- assert(vt != NULL);
- prevVT->_next = _next;
- }
- _armed = false;
- }
- unlockSystem();
- }
- void VirtualTimer::fire() {
- _armed = false;
- if ((_callback == NULL) || _callback(_callbackArg)) {
- doStart();
- }
- }
- void VirtualTimer::tick() {
- lockSystem();
- timestamp_t timestamp = getCurrentTimestamp();
- bool deadlineChanged = false;
- while ((_firstVirtualTimer != NULL) && (_firstVirtualTimer->_targetTimestamp <= timestamp)) {
- VirtualTimer *timer = (VirtualTimer*)_firstVirtualTimer;
- _firstVirtualTimer = _firstVirtualTimer->_next;
- timer->fire();
- deadlineChanged = true;
- }
- if (deadlineChanged) {
- virtualTimerDeadlineChanged(getDeadline());
- }
- unlockSystem();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement