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