scc  2022.4.0
SystemC components library
watchdog.cpp
1 /*******************************************************************************
2  * Copyright 2020-2022 MINRES Technologies GmbH
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *******************************************************************************/
16 
17 #include <util/watchdog.h>
18 
19 #include <utility>
20 
21 using namespace util;
22 using namespace std::chrono;
23 
24 watchdog::watchdog(system_clock::duration timeout, std::function<void(void)> alarm_cb, system_clock::duration sleep_duration)
25 : timeout(timeout)
26 , sleep_duration(sleep_duration)
27 , alarm_cb(std::move(alarm_cb)) {
28  idle.store(true);
29  live.store(true);
30  guard_thread = std::thread([this] { guard(); });
31 }
32 
33 watchdog::watchdog(system_clock::duration timeout, std::function<void(void)> alarm)
34 : watchdog(timeout, alarm, timeout / 10){};
35 
36 watchdog::~watchdog() {
37  live.store(false);
38  wakeup.notify_all();
39  guard_thread.join();
40 }
41 
42 void watchdog::guard() {
43  while(live.load()) {
44  if(idle.load()) {
45  // Sleep indefinitely until either told to become active or destruct
46  std::unique_lock<std::mutex> live_lock(guard_mutex);
47  wakeup.wait(live_lock, [this]() { return !this->idle.load() || !this->live.load(); });
48  };
49  if(!live.load())
50  break;
51  // the actual timeout checking
52  auto now = system_clock::now();
53  if((now - touched.load()) > timeout) {
54  idle.store(true);
55  alarm_cb();
56  continue; // skip waiting for next timeout
57  }
58  {
59  // sleep until next timeout check or destruction
60  std::unique_lock<std::mutex> live_lock(guard_mutex);
61  wakeup.wait_for(live_lock, sleep_duration, [this]() { return !this->live.load(); });
62  }
63  };
64 }
65 
66 void watchdog::arm() {
67  re_arm();
68  idle.store(false);
69  wakeup.notify_all();
70 }
71 
72 void watchdog::re_arm() { touched.store(system_clock::now()); }
a watch dog based on https://github.com/didenko/TimeoutGuard
Definition: watchdog.h:37
watchdog(std::chrono::system_clock::duration timeout, std::function< void(void)> alarm_cb, std::chrono::system_clock::duration sleep_duration)
void re_arm()
Definition: watchdog.cpp:72
SCC common utilities.
Definition: bit_field.h:30