Critical Link MityCam SoC Firmware  1.0
Critical Link MityCam SoC Firmware
tcPendingAckWatchdog.h
Go to the documentation of this file.
1 /*
2  * tcPendingAckWatchdog.h
3  *
4  * Created on: Jan 10, 2018
5  * Author: mitydsp
6  */
7 
8 #ifndef TCPENDINGACKWATCHDOG_H_
9 #define TCPENDINGACKWATCHDOG_H_
10 
11 #include <iostream>
12 #include <unordered_map>
13 #include <chrono>
14 #include <algorithm>
15 #include <mutex>
16 #include <vector>
17 
18 #include "Utility/Timer.h"
19 
20 namespace SocCamera {
21 
32 public:
34  virtual ~tcPendingAckWatcher() {}
35 
39  virtual void pendingAckNeeded(const void *id) = 0;
40 };
41 
92 template<class IdType> class tcPendingAckWatchdog : tcTimedObject {
93 private:
94  typedef std::chrono::steady_clock WatchdogClock;
95 
96 public:
98  // 50 ms timer interval time
99  timer_interval = std::chrono::nanoseconds{50000000};
100  if(!timer.initializeTimer()) {
101  std::cout << "Error initializing timer object." << std::endl;
102  }
103  }
104  virtual ~tcPendingAckWatchdog() { timer.stopTimer(); }
105 
114  void setTimeoutPeriod(std::chrono::microseconds duration) {
115  mnDuration = std::chrono::microseconds{(int)(duration.count()*0.85f)};
116  }
117 
123  void addWatcher(tcPendingAckWatcher* apWatcher) {
124  std::lock_guard<std::mutex> guard(mutex);
125  watchers.push_back(apWatcher);
126  }
127 
134  std::lock_guard<std::mutex> guard(mutex);
135  auto it = std::find(watchers.begin(), watchers.end(), apWatcher);
136  if(it != watchers.end())
137  watchers.erase(it);
138  }
139 
145  void newMessage(IdType id) {
146  std::lock_guard<std::mutex> guard(mutex);
147  ids[id] = WatchdogClock::now();
148 
149  if(!timer.isStarted()) {
150  // start a 50 ms timer, repetitive
151  timer.startTimer(this, 0, (uint32_t)timer_interval.count(), false);
152  }
153  }
154 
160  void messageDone(IdType id) {
161  std::lock_guard<std::mutex> guard(mutex);
162  ids.erase(id);
163 
164  // stop running the timer if we have no workers
165  if(ids.size() == 0) {
166  timer.stopTimer();
167  }
168  }
169 
176  virtual void timerTicked(tcTimer*) { this->timerTick(); };
177 
178 protected:
183  void timerTick() {
184  std::lock_guard<std::mutex> guard(mutex);
185  auto current = WatchdogClock::now();
186  auto idIterator = ids.begin();
187  while(idIterator != ids.end()) {
188  auto delta = current - idIterator->second;
189  if(delta > mnDuration) {
190  // update notification time to now so we can fire again if needed
191  idIterator->second = current;
192  notifyWatchers(&idIterator->first);
193  }
194  idIterator++;
195  }
196  }
197 
201  void notifyWatchers(const void* apPtr) {
202  auto it = watchers.begin();
203  while(it != watchers.end()) {
204  (*it)->pendingAckNeeded(apPtr);
205  it++;
206  }
207  }
208 
209 private:
210  std::chrono::nanoseconds timer_interval;
211  std::vector<tcPendingAckWatcher*> watchers;
212  std::unordered_map<IdType, WatchdogClock::time_point> ids;
213 
214  std::chrono::microseconds mnDuration;
215  tcTimer timer;
216 
217  std::mutex mutex;
218 };
219 
220 } /* namespace SocCamera */
221 #endif /* TCPENDINGACKWATCHDOG_H_ */
SocCamera::tcPendingAckWatcher::~tcPendingAckWatcher
virtual ~tcPendingAckWatcher()
Definition: tcPendingAckWatchdog.h:34
SocCamera::tcPendingAckWatchdog::~tcPendingAckWatchdog
virtual ~tcPendingAckWatchdog()
Definition: tcPendingAckWatchdog.h:104
tcTimer::stopTimer
void stopTimer()
Definition: Timer.cpp:64
SocCamera::tcPendingAckWatchdog::newMessage
void newMessage(IdType id)
Definition: tcPendingAckWatchdog.h:145
SocCamera::tcPendingAckWatcher::tcPendingAckWatcher
tcPendingAckWatcher()
Definition: tcPendingAckWatchdog.h:33
SocCamera::tcPendingAckWatchdog::timerTick
void timerTick()
Definition: tcPendingAckWatchdog.h:183
tcTimer
Definition: Timer.h:25
SocCamera::tcPendingAckWatcher
Definition: tcPendingAckWatchdog.h:31
tcTimer::isStarted
bool isStarted()
Definition: Timer.cpp:59
Timer.h
SocCamera::tcPendingAckWatchdog::notifyWatchers
void notifyWatchers(const void *apPtr)
Definition: tcPendingAckWatchdog.h:201
tcTimedObject
Definition: Timer.h:17
SocCamera::tcPendingAckWatchdog::setTimeoutPeriod
void setTimeoutPeriod(std::chrono::microseconds duration)
Definition: tcPendingAckWatchdog.h:114
SocCamera
Definition: CameraTypes.h:7
SocCamera::tcPendingAckWatchdog::timerTicked
virtual void timerTicked(tcTimer *)
Definition: tcPendingAckWatchdog.h:176
tcTimer::startTimer
bool startTimer(tcTimedObject *apTimedObject, uint32_t anSeconds, uint32_t anNanoseconds, bool abSingleShot=false)
Definition: Timer.cpp:21
SocCamera::tcPendingAckWatchdog::messageDone
void messageDone(IdType id)
Definition: tcPendingAckWatchdog.h:160
SocCamera::tcPendingAckWatchdog::tcPendingAckWatchdog
tcPendingAckWatchdog()
Definition: tcPendingAckWatchdog.h:97
SocCamera::tcPendingAckWatchdog::removeWatcher
void removeWatcher(tcPendingAckWatcher *apWatcher)
Definition: tcPendingAckWatchdog.h:133
SocCamera::tcPendingAckWatchdog
Definition: tcPendingAckWatchdog.h:92
tcTimer::initializeTimer
bool initializeTimer()
Definition: Timer.cpp:73
SocCamera::tcPendingAckWatchdog::addWatcher
void addWatcher(tcPendingAckWatcher *apWatcher)
Definition: tcPendingAckWatchdog.h:123
SocCamera::tcPendingAckWatcher::pendingAckNeeded
virtual void pendingAckNeeded(const void *id)=0