summaryrefslogtreecommitdiffstats
path: root/src/trex_watchdog.h
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2016-06-19 18:05:54 +0300
committerimarom <imarom@cisco.com>2016-06-20 11:55:13 +0300
commit3ca8be805c26eddfe40c254bdca4e5ae71eee792 (patch)
treefd2b06c04de32b6bad4f5d71203422fa7292efe2 /src/trex_watchdog.h
parent1bc9c49fa89a3942d3d1516217635d0c6e6b0c56 (diff)
WATCHDOG - refactor due to trex-211
Diffstat (limited to 'src/trex_watchdog.h')
-rw-r--r--src/trex_watchdog.h183
1 files changed, 124 insertions, 59 deletions
diff --git a/src/trex_watchdog.h b/src/trex_watchdog.h
index 0c1969b1..1c948d56 100644
--- a/src/trex_watchdog.h
+++ b/src/trex_watchdog.h
@@ -27,69 +27,142 @@ limitations under the License.
#include <thread>
#include <mutex>
-//#include "rte_memory.h"
#include "mbuf.h"
#include "os_time.h"
-class TrexWatchDog {
+/**
+ * every thread creates its own monitor from its own memory
+ *
+ * @author imarom (19-Jun-16)
+ */
+class TrexMonitor {
+
public:
- TrexWatchDog() {
- m_thread = NULL;
- m_active = false;
- m_pending = 0;
- m_enable = false;
- }
- void init(bool enable);
+ /**
+ * create a monitor
+ *
+ * @author imarom (31-May-16)
+ *
+ * @param name
+ * @param timeout
+ *
+ * @return int
+ */
+ void create(const std::string &name, double timeout_sec);
/**
- * registering a monitor happens from another thread
- * this make sure that start will be able to block until
- * all threads has registered
+ * disable the monitor - it will be ignored
*
- * @author imarom (01-Jun-16)
*/
- void mark_pending_monitor(int count = 1);
-
+ void disable() {
+ m_active = false;
+ }
/**
- * blocks while monitors are pending registeration
+ * tickle the monitor - this should be called from the thread
+ * to avoid the watchdog from detecting a stuck thread
*
- * @author imarom (01-Jun-16)
+ * @author imarom (19-Jun-16)
*/
- void block_on_pending(int max_block_time_ms = 200);
-
+ void tickle() {
+ /* to avoid useless writes - first check */
+ if (!m_tickled) {
+ m_tickled = true;
+ }
+ }
/**
- * add a monitor to the watchdog
- * this thread will be monitored and if timeout
- * has passed without calling tick - an exception will be called
- *
- * @author imarom (31-May-16)
- *
- * @param name
- * @param timeout
+ * called by the watchdog to reset the monitor for a new round
*
- * @return int
*/
- int register_monitor(const std::string &name, double timeout_sec);
+ void reset(dsec_t now) {
+ m_tickled = false;
+ m_ts = now;
+ }
+
+
+ /* return how much time has passed since last tickle */
+ dsec_t get_interval(dsec_t now) const {
+ return (now - m_ts);
+ }
+
+ pthread_t get_tid() const {
+ return m_tid;
+ }
+
+ const std::string &get_name() const {
+ return m_name;
+ }
+
+ dsec_t get_timeout_sec() const {
+ return m_timeout_sec;
+ }
+
+ volatile bool is_active() const {
+ return m_active;
+ }
+ volatile bool is_tickled() const {
+ return m_tickled;
+ }
+
+ bool is_expired(dsec_t now) const {
+ return ( get_interval(now) > m_timeout_sec );
+ }
+
+
+private:
+
+ /* write fields are first */
+ volatile bool m_active;
+ volatile bool m_tickled;
+ dsec_t m_ts;
+
+ int m_handle;
+ double m_timeout_sec;
+ pthread_t m_tid;
+ std::string m_name;
+
+ /* for for a full cacheline */
+ uint8_t pad[15];
+
+} __rte_cache_aligned;
+
+
+/**
+ * a watchdog is a list of registered monitors
+ *
+ * @author imarom (19-Jun-16)
+ */
+class TrexWatchDog {
+public:
/**
- * disable a monitor - it will no longer be watched
+ * singleton entry
+ *
+ * @author imarom (19-Jun-16)
*
+ * @return TrexWatchDog&
*/
- void disable_monitor(int handle);
+ static TrexWatchDog& getInstance() {
+ static TrexWatchDog instance;
+ return instance;
+ }
+ void init(bool enable);
+
/**
- * should be called by each thread on it's handle
+ * add a monitor to the watchdog
+ * from now on this monitor will be watched
+ *
+ * @author imarom (19-Jun-16)
*
- * @author imarom (31-May-16)
+ * @param monitor - a pointer to the object
*
- * @param handle
*/
- void tickle(int handle);
+ void register_monitor(TrexMonitor *monitor);
/**
@@ -106,38 +179,30 @@ public:
void stop();
- /* should be cache aligned to avoid false sharing */
- struct monitor_st {
- /* write fields are first */
- volatile bool active;
- volatile bool tickled;
- dsec_t ts;
-
- int handle;
- double timeout_sec;
- pthread_t tid;
- std::string name;
-
- /* for for a full cacheline */
- uint8_t pad[15];
- } __rte_cache_aligned ;
+private:
+ TrexWatchDog() {
+ m_thread = NULL;
+ m_enable = false;
+ m_active = false;
+ m_mon_count = 0;
+ }
-private:
void register_signal();
void _main();
+ static const int MAX_MONITORS = 100;
+ TrexMonitor *m_monitors[MAX_MONITORS];
+ volatile int m_mon_count;
+ std::mutex m_lock;
- std::vector<monitor_st> m_monitors __rte_cache_aligned;
- std::mutex m_lock;
- bool m_enable;
- volatile bool m_active;
- std::thread *m_thread;
- volatile int m_pending;
+ bool m_enable;
+ volatile bool m_active;
+ std::thread *m_thread;
- static bool g_signal_init;
+ static bool g_signal_init;
};
-static_assert(sizeof(TrexWatchDog::monitor_st) == RTE_CACHE_LINE_SIZE, "sizeof(monitor_st) != RTE_CACHE_LINE_SIZE" );
+static_assert(sizeof(TrexMonitor) == RTE_CACHE_LINE_SIZE, "sizeof(TrexMonitor) != RTE_CACHE_LINE_SIZE" );
#endif /* __TREX_WATCHDOG_H__ */