1 /* Watchdog and associated classes' declaration and inline functions. 2 Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it> 3 Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com) 4 5 This file is part of the Parma Polyhedra Library (PPL). 6 7 The PPL is free software; you can redistribute it and/or modify it 8 under the terms of the GNU General Public License as published by the 9 Free Software Foundation; either version 3 of the License, or (at your 10 option) any later version. 11 12 The PPL is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software Foundation, 19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA. 20 21 For the most up-to-date information see the Parma Polyhedra Library 22 site: http://bugseng.com/products/ppl/ . */ 23 24 #ifndef PPL_Watchdog_defs_hh 25 #define PPL_Watchdog_defs_hh 1 26 27 #include "Watchdog_types.hh" 28 #include "Time_defs.hh" 29 #include "Handler_types.hh" 30 #include "Pending_List_defs.hh" 31 #include <cassert> 32 #include <functional> 33 34 #ifdef PPL_HAVE_SYS_TIME_H 35 # include <sys/time.h> 36 #endif 37 38 namespace Parma_Polyhedra_Library { 39 40 // Set linkage now to declare it friend later. 41 extern "C" void PPL_handle_timeout(int signum); 42 43 struct Watchdog_Traits { 44 typedef Implementation::Watchdog::Time Threshold; less_thanParma_Polyhedra_Library::Watchdog_Traits45 static bool less_than(const Threshold& a, const Threshold& b) { 46 return a < b; 47 } 48 }; 49 50 //! A watchdog timer. 51 class Watchdog { 52 public: 53 template <typename Flag_Base, typename Flag> 54 Watchdog(long csecs, const Flag_Base* volatile& holder, Flag& flag); 55 56 /*! \brief 57 Constructor: if not reset, the watchdog will trigger after \p csecs 58 centiseconds, invoking handler \p function. 59 */ 60 Watchdog(long csecs, void (* const function)()); 61 62 //! Destructor. 63 ~Watchdog(); 64 65 #if PPL_HAVE_DECL_SETITIMER && PPL_HAVE_DECL_SIGACTION 66 67 //! Static class initialization. 68 static void initialize(); 69 //! Static class finalization. 70 static void finalize(); 71 72 private: 73 //! Whether or not this watchdog has expired. 74 bool expired; 75 76 typedef Implementation::Watchdog::Pending_List<Watchdog_Traits> 77 WD_Pending_List; 78 79 typedef Implementation::Watchdog::Handler 80 WD_Handler; 81 82 const WD_Handler& handler; 83 WD_Pending_List::iterator pending_position; 84 85 // Private and not implemented: copy construction is not allowed. 86 Watchdog(const Watchdog&); 87 // Private and not implemented: copy assignment is not allowed. 88 Watchdog& operator=(const Watchdog&); 89 90 // Pass this to getitimer(). 91 static itimerval current_timer_status; 92 93 //! Reads the timer value into \p time. 94 static void get_timer(Implementation::Watchdog::Time& time); 95 96 // Pass this to setitimer(). 97 static itimerval signal_once; 98 99 // Last time value we set the timer to. 100 static Implementation::Watchdog::Time last_time_requested; 101 102 //! Sets the timer value to \p time. 103 static void set_timer(const Implementation::Watchdog::Time& time); 104 105 //! Stops the timer. 106 static void stop_timer(); 107 108 //! Quick reschedule to avoid race conditions. 109 static void reschedule(); 110 111 // Used by the above. 112 static Implementation::Watchdog::Time reschedule_time; 113 114 // Records the time elapsed since last fresh start. 115 static Implementation::Watchdog::Time time_so_far; 116 117 //! The ordered queue of pending watchdog events. 118 static WD_Pending_List pending; 119 120 //! The actual signal handler. 121 static void handle_timeout(int); 122 123 //! Handles the addition of a new watchdog event. 124 static WD_Pending_List::iterator 125 new_watchdog_event(long csecs, 126 const WD_Handler& handler, 127 bool& expired_flag); 128 129 //! Handles the removal of the watchdog event referred by \p position. 130 void remove_watchdog_event(WD_Pending_List::iterator position); 131 132 //! Whether the alarm clock is running. 133 static volatile bool alarm_clock_running; 134 135 //! Whether we are changing data that is also changed by the signal handler. 136 static volatile bool in_critical_section; 137 138 friend void PPL_handle_timeout(int signum); 139 140 #endif // PPL_HAVE_DECL_SETITIMER && PPL_HAVE_DECL_SIGACTION 141 }; 142 143 } // namespace Parma_Polyhedra_Library 144 145 #include "Watchdog_inlines.hh" 146 147 #endif // !defined(PPL_Watchdog_defs_hh) 148 149