iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Watchdog.H
Go to the documentation of this file.
1 /*! @file
2  @author Laurent Itti
3  @copyright GNU Public License (GPL v3)
4  @section License
5  @verbatim
6  // ////////////////////////////////////////////////////////////////////////
7  // The iLab Neuromorphic Robotics Toolkit (NRT) //
8  // Copyright 2010-2012 by the University of Southern California (USC) //
9  // and the iLab at USC. //
10  // //
11  // iLab - University of Southern California //
12  // Hedco Neurociences Building, Room HNB-10 //
13  // Los Angeles, Ca 90089-2520 - USA //
14  // //
15  // See http://ilab.usc.edu for information about this project. //
16  // ////////////////////////////////////////////////////////////////////////
17  // This file is part of The iLab Neuromorphic Robotics Toolkit. //
18  // //
19  // The iLab Neuromorphic Robotics Toolkit is free software: you can //
20  // redistribute it and/or modify it under the terms of the GNU General //
21  // Public License as published by the Free Software Foundation, either //
22  // version 3 of the License, or (at your option) any later version. //
23  // //
24  // The iLab Neuromorphic Robotics Toolkit is distributed in the hope //
25  // that it will be useful, but WITHOUT ANY WARRANTY; without even the //
26  // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
27  // PURPOSE. See the GNU General Public License for more details. //
28  // //
29  // You should have received a copy of the GNU General Public License //
30  // along with The iLab Neuromorphic Robotics Toolkit. If not, see //
31  // <http://www.gnu.org/licenses/>. //
32  // ////////////////////////////////////////////////////////////////////////
33  @endverbatim */
34 
35 #ifndef INCLUDE_NRT_CORE_DESIGN_WATCHDOG_H
36 #define INCLUDE_NRT_CORE_DESIGN_WATCHDOG_H
37 
38 #include <chrono>
39 #include <condition_variable>
40 #include <thread>
41 #include <atomic>
42 
43 namespace nrt
44 {
45  //! Launch a function after some amount of time has passed during which no reset was received
46  /*! A countdown over a given delay passed at construction is initiated, and the function passed at construction will
47  be called, unless the countdown is reset by calling the reset() function. A call to reset() simply sets back
48  the clock to the full delay, and the countdown starts again from there (i.e., it does not stop the clock).
49 
50  This class is thread-safe, i.e., multiple threads can call reset() concurrently without having to worry about
51  locking. If the countdown ever reaches 0, the function will be called in a separate thread.
52 
53  \note If we time out and launch the function, we will then go into a dormant state until reset() is called,
54  which will restart our countdown.
55 
56  \ingroup design */
57  class Watchdog
58  {
59  public:
60  //! Constructor, setting the time delay and function that will be launched should the delay expire
61  /*! @param delay Countdown delay
62  @param func Function that will be called if a full delay has passed with no calls to reset()
63  @param startcounting If true, start the countdown immediately, otherwise, we are initially in dormant state
64  (equivalent to an infinite countdown delay), and conting down will start upon first reset(). */
65  Watchdog(std::chrono::microseconds const delay, std::function<void()> func, bool startcounting = true);
66 
67  //! Destructor, cancels watchdog operation
68  ~Watchdog();
69 
70  //! Reset the countdown to the full delay that was given at construction
71  void reset();
72 
73  //! If counting down, wait until we timeout, otherwise (dormant state) return immediately
74  /*! This function is guaranteed to not block forever (stuck in dormant state) as it will return immediately if
75  dormant, otherwise it will wait until the next timeout and return. It can be used if you need to wait until a
76  timeout gets triggered, but you do not want to wait forever in case we are dormant. */
77  void wait();
78 
79  //! Precipitate a timeout
80  /*! This will call our watchdog function as soon as possible and block until it has completed. This is like
81  calling reset() and then wait() except that the watchdog delay is reduced to zero for this call only. After
82  the function is called, switch to dormant state. */
83  void precipitate();
84 
85 
86  private:
87  std::atomic_bool itsInitialized;
88  std::condition_variable itsCond; // our main condition variable
89  std::condition_variable itsWaiterCond; // condition variable used to block people that called wait()
90  std::chrono::microseconds const itsGivenDelay;
91  std::chrono::microseconds itsDelay;
92  std::function<void()> const itsFunc;
93  std::mutex itsMutex; // protects: itsDelay, itsFunc
94  void run();
95  std::atomic_bool itsRunning;
96  std::atomic_bool itsResetWasCalled; // to avoid spurious awakenings
97  bool itsPrecipitate; // used to precipitate a call to itsFunc
98  std::mutex itsResetMutex;
99 
100  std::thread itsThread;
101  };
102 
103 } // namespace nrt
104 
105 #endif // INCLUDE_NRT_CORE_DESIGN_WATCHDOG_H