diff options
Diffstat (limited to 'src/trex_watchdog.h')
-rw-r--r-- | src/trex_watchdog.h | 181 |
1 files changed, 124 insertions, 57 deletions
diff --git a/src/trex_watchdog.h b/src/trex_watchdog.h index 63255180..1c948d56 100644 --- a/src/trex_watchdog.h +++ b/src/trex_watchdog.h @@ -27,68 +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; - register_signal(); - } + /** + * 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); /** @@ -105,37 +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]; - }; +private: + TrexWatchDog() { + m_thread = NULL; + m_enable = false; + m_active = false; + m_mon_count = 0; + } -private: void register_signal(); void _main(); - std::vector<monitor_st> m_monitors __rte_cache_aligned; - std::mutex m_lock; + static const int MAX_MONITORS = 100; + TrexMonitor *m_monitors[MAX_MONITORS]; + volatile int m_mon_count; + std::mutex m_lock; - 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__ */ |