diff options
author | 2016-05-31 11:04:11 +0300 | |
---|---|---|
committer | 2016-06-02 13:45:12 +0300 | |
commit | b639fb458fb2388164adaf45c4e947a2af2ca0e1 (patch) | |
tree | fcfad63222e8b052e8500c8a0cdd15513541afab /src | |
parent | 7bbba823029e4b6dd00ec5c336832e928cd3685d (diff) |
added watchdog
Diffstat (limited to 'src')
-rw-r--r-- | src/trex_watchdog.cpp | 97 | ||||
-rw-r--r-- | src/trex_watchdog.h | 91 |
2 files changed, 188 insertions, 0 deletions
diff --git a/src/trex_watchdog.cpp b/src/trex_watchdog.cpp new file mode 100644 index 00000000..b3a0733c --- /dev/null +++ b/src/trex_watchdog.cpp @@ -0,0 +1,97 @@ +/* + Itay Marom + Cisco Systems, Inc. +*/ + +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "trex_watchdog.h" +#include "trex_exception.h" + +#include <assert.h> +#include <unistd.h> +#include <sstream> + +int WatchDog::register_monitor(const std::string &name, double timeout_sec) { + monitor_st monitor; + + monitor.name = name; + monitor.timeout_sec = timeout_sec; + monitor.tickled = true; + monitor.ts = 0; + + monitor.handle = m_monitors.size(); + m_monitors.push_back(monitor); + + return monitor.handle; +} + +void WatchDog::tickle(int handle) { + assert(handle < m_monitors.size()); + + /* not nesscary but write gets cache invalidate for nothing */ + if (m_monitors[handle].tickled) { + return; + } + + m_monitors[handle].tickled = true; +} + +void WatchDog::start() { + m_active = true; + m_thread = new std::thread(&WatchDog::_main, this); + if (!m_thread) { + throw TrexException("unable to create watchdog thread"); + } +} + +void WatchDog::stop() { + m_thread->join(); + delete m_thread; +} + +/** + * main loop + * + */ +void WatchDog::_main() { + while (m_active) { + + dsec_t now = now_sec(); + + for (auto &monitor : m_monitors) { + /* if its own - turn it off and write down the time */ + if (monitor.tickled) { + monitor.tickled = false; + monitor.ts = now; + continue; + } + + /* the bit is off - check the time first */ + if ( (now - monitor.ts) > monitor.timeout_sec ) { + std::stringstream ss; + ss << "WATCHDOG: task '" << monitor.name << "' has not responded for more than " << (now - monitor.ts) << " seconds - timeout is " << monitor.timeout_sec << " seconds"; + throw TrexException(ss.str()); + assert(0); + } + + } + + sleep(1); + } +} + diff --git a/src/trex_watchdog.h b/src/trex_watchdog.h new file mode 100644 index 00000000..ecc90960 --- /dev/null +++ b/src/trex_watchdog.h @@ -0,0 +1,91 @@ +/* + Itay Marom + Cisco Systems, Inc. +*/ + +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef __TREX_WATCHDOG_H__ +#define __TREX_WATCHDOG_H__ + +#include <string> +#include <vector> +#include <thread> + +#include "os_time.h" + +class WatchDog { +public: + WatchDog() { + m_thread = NULL; + m_active = false; + } + + /** + * 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 + * + * @return int + */ + int register_monitor(const std::string &name, double timeout_sec); + + /** + * should be called by each thread on it's handle + * + * @author imarom (31-May-16) + * + * @param handle + */ + void tickle(int handle); + + /** + * start the watchdog + * + */ + void start(); + + /** + * stop the watchdog + * + */ + void stop(); + +private: + void _main(); + + struct monitor_st { + int handle; + std::string name; + double timeout_sec; + bool tickled; + dsec_t ts; + }; + + std::vector<monitor_st> m_monitors; + + + volatile bool m_active; + std::thread *m_thread; +}; + +#endif /* __TREX_WATCHDOG_H__ */ |