cxxitimer 2.0.5
A C++ library to handle linux interval timer
Loading...
Searching...
No Matches
cxxitimer.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2022 Nikolas Koesling <nikolas@koesling.info>.
3 * This program is free software. You can redistribute it and/or modify it under the terms of the MIT License.
4 */
5
6#pragma once
7
8#include <fstream>
9#include <sys/time.h>
10
11namespace cxxitimer {
12
13/**
14 * @brief abstract class ITimer
15 */
16class ITimer {
17private:
18 //* timer value (speed factor 1.0)
19 timeval timer_value;
20
21 //* timer interval (speed factor 1.0)
23
24 //* timer type (REAL/VIRTUAL/PROF see man getitimer)
25 int type;
26
27 /**
28 * @brief speed adjustment factor
29 * @details
30 * - ]0;1[ --> slower
31 * - ]1;inf[ --> faster
32 * - 1 --> normal speed
33 */
35
36 //* timer running indicator
37 bool running;
38
39 //* internal use only!
40 virtual void adjust_speed(double new_factor);
41
42protected:
43 //* internal use only!
44 explicit ITimer(int type, const timeval &interval = {.tv_sec = 1, .tv_usec = 0}) noexcept;
45
46 //* internal use only!
47 ITimer(int type, const timeval &interval, const timeval &value) noexcept;
48
49 //* internal use only!
50 ITimer(int type, double interval) noexcept;
51
52 //* internal use only!
53 ITimer(int type, double interval, double value) noexcept;
54
55public:
56 //! copying is not possible
57 ITimer(const ITimer &other) = delete;
58 //! moving is not possible
59 ITimer(ITimer &&other) = delete;
60 //! copying is not possible
61 ITimer &operator=(const ITimer &other) = delete;
62 //! moving is not possible
63 ITimer &operator=(ITimer &&other) = delete;
64
65 /**
66 * @brief Destroy the timer instance
67 *
68 * @details
69 * Timer is stopped if running, however, the timer should be stopped beforehand if possible.
70 * If the timer is still running and the call of stop() fails, the process will be terminated.
71 */
72 virtual ~ITimer();
73
74 /**
75 * @brief start timer
76 * @exception std::logic_error timer already started
77 * @exception std::runtime_error invalid timer values due to a too small speed factor
78 * @exception std::system_error call of setitimer failed
79 */
80 void start();
81
82 /**
83 * @brief stop timer
84 * @exception std::logic_error timer already stopped
85 * @exception std::system_error call of setitimer failed
86 */
87 void stop();
88
89 /**
90 * @brief set speed factor
91 * @details is applied directly, even if the timer is running
92 * - ]0;1[ --> slower
93 * - ]1;inf[ --> faster
94 * - 1 --> normal speed
95 * @param factor speed factor
96 * @exception std::invalid_argument negative values or nan/inf
97 * @exception std::system_error call of setitimer failed
98 */
99 void set_speed_factor(double factor);
100
101 /**
102 * @brief set interval (timeval)
103 * @details
104 * only allowed if the timer is stopped!
105 * set the timer value to the same time
106 * @param interval timer interval
107 * @exception std::logic_error timer is started
108 */
109 inline void set_interval(const timeval &interval) { set_interval_value(interval, interval); }
110
111 /**
112 * @brief set interval (double)
113 * @details
114 * only allowed if the timer is stopped!
115 * set the timer value to the same time
116 * @param interval timer interval (seconds)
117 * @exception std::logic_error timer is started
118 */
119 inline void set_interval(double interval) { set_interval_value(interval, interval); }
120
121 /**
122 * @brief set interval and value
123 * @details only allowed if the timer is stopped
124 * @param interval timer interval
125 * @param value timer value
126 * @exception std::logic_error timer is started
127 */
128 void set_interval_value(const timeval &interval, const timeval &value);
129
130 /**
131 * @brief set interval and value
132 * @details only allowed if the timer is stopped
133 * @param interval timer interval (seconds)
134 * @param value timer value (seconds)
135 * @exception std::logic_error timer is started
136 */
137 void set_interval_value(double interval, double value);
138
139 /**
140 * @brief set speed to normal
141 * @details like calling set_speed_factor with 1.0
142 * @exception std::system_error call of setitimer failed
143 */
144 void set_speed_to_normal();
145
146 /**
147 * @brief write to binary file stream
148 * @details
149 * writes interval and value to file stream.
150 * type and speed factor is not stored!
151 * @param fstream file stream to write to
152 * @exception std::system_error call of getitimer failed
153 */
154 void to_fstream(std::ofstream &fstream) const;
155
156 /**
157 * @brief read from binary filestream
158 * @param fstream file stream to read from
159 * @exception std::logic_error timer is running
160 */
161 void from_fstream(std::ifstream &fstream);
162
163 /**
164 * @brief get timer value
165 * @details returns the stored timer value if the timer is stopped or the actual timer value if running
166 * @return timer value
167 */
168 [[nodiscard]] timeval get_timer_value() const;
169
170 /**
171 * @brief check if timer is running
172 * @return true timer is running
173 * @return false timer is stopped
174 */
175 [[nodiscard]] inline bool is_running() const noexcept { return running; }
176};
177
178/** @brief class ITimer_Real
179 *
180 * @details
181 * "This timer counts down in real (i.e., wall clock) time.
182 * At each expiration, a SIGALRM signal is generated." (man getitimer)
183 */
184class ITimer_Real : public ITimer {
185 //* only one instance per process allowed
186 static bool instance_exists;
187
188public:
189 /**
190 * @brief create ITimer_Real instance
191 * @details only one instance is allowed
192 * @param interval timer interval
193 * @exception std::logic_error instance exists
194 */
195 explicit ITimer_Real(const timeval &interval = {.tv_sec = 1, .tv_usec = 0});
196
197 /**
198 * @brief create ITimer_Real instance
199 * @details only one instance is allowed
200 * @param interval interval at which the timer is triggered
201 * @param value ime period after which the timer expires for the first time
202 * @exception std::logic_error instance exists
203 */
204 ITimer_Real(const timeval &interval, const timeval &value);
205
206 /**
207 * @brief create ITimer_Real instance
208 * @details only one instance is allowed
209 * @param interval timer interval
210 * @exception std::logic_error instance exists
211 */
212 explicit ITimer_Real(double interval);
213
214 /**
215 * @brief create ITimer_Real instance
216 * @details only one instance is allowed
217 * @param interval interval at which the timer is triggered
218 * @param value ime period after which the timer expires for the first time
219 * @exception std::logic_error instance exists
220 */
221 ITimer_Real(double interval, double value);
222
223 //* destroy instance
224 ~ITimer_Real() override;
225
226 //* copying is not possible
227 ITimer_Real(const ITimer_Real &other) = delete;
228 //* moving is not possible
229 ITimer_Real(ITimer_Real &&other) = delete;
230 //* copying is not possible
231 ITimer_Real &operator=(const ITimer_Real &other) = delete;
232 //* moving is not possible
233 ITimer_Real &operator=(ITimer_Real &&other) = delete;
234};
235
236/**
237 * @brief class ITimer_Virtual
238 *
239 * @details
240 * "This timer counts down against the user-mode CPU time consumed by the process. (The measurement includes CPU
241 * time consumed by all threads in the process.) At each expiration, a SIGVTALRM signal is generated." (man getitimer)
242 */
243class ITimer_Virtual : public ITimer {
244 //* only one instance per process allowed
245 static bool instance_exists;
246
247public:
248 /**
249 * @brief create ITimer_Virtual instance
250 * @details only one instance is allowed
251 * @param interval timer interval
252 * @exception std::logic_error instance exists
253 */
254 explicit ITimer_Virtual(const timeval &interval = {.tv_sec = 1, .tv_usec = 0});
255
256 /**
257 * @brief create ITimer_Virtual instance
258 * @details only one instance is allowed
259 * @param interval interval at which the timer is triggered
260 * @param value ime period after which the timer expires for the first time
261 * @exception std::logic_error instance exists
262 */
263 ITimer_Virtual(const timeval &interval, const timeval &value);
264
265 /**
266 * @brief create ITimer_Virtual instance
267 * @details only one instance is allowed
268 * @param interval timer interval
269 * @exception std::logic_error instance exists
270 */
271 explicit ITimer_Virtual(double interval);
272
273 /**
274 * @brief create ITimer_Virtual instance
275 * @details only one instance is allowed
276 * @param interval interval at which the timer is triggered
277 * @param value ime period after which the timer expires for the first time
278 * @exception std::logic_error instance exists
279 */
280 ITimer_Virtual(double interval, double value);
281
282 //* destroy instance
283 ~ITimer_Virtual() override;
284
285 //* copying is not possible
286 ITimer_Virtual(const ITimer_Virtual &other) = delete;
287 //* moving is not possible
289 //* copying is not possible
290 ITimer_Virtual &operator=(const ITimer_Virtual &other) = delete;
291 //* moving is not possible
293};
294
295/**
296 * @brief class ITimer_Prof
297 *
298 * @details
299 * "This timer counts down against the total (i.e., both user and system) CPU time consumed by the process. (The
300 * measurement includes CPU time consumed by all threads in the process.) At each expiration, a SIGPROF signal is
301 * generated.
302 * In conjunction with ITIMER_VIRTUAL, this timer can be used to profile user and system CPU time consumed by the
303 * process." (man getitimer)
304 */
305class ITimer_Prof : public ITimer {
306 //* only one instance per process allowed
307 static bool instance_exists;
308
309public:
310 /**
311 * @brief create ITimer_Prof instance
312 * @details only one instance is allowed
313 * @param interval timer interval
314 * @exception std::logic_error instance exists
315 */
316 explicit ITimer_Prof(const timeval &interval = {.tv_sec = 1, .tv_usec = 0});
317
318 /**
319 * @brief create ITimer_Prof instance
320 * @details only one instance is allowed
321 * @param interval interval at which the timer is triggered
322 * @param value ime period after which the timer expires for the first time
323 * @exception std::logic_error instance exists
324 */
325 ITimer_Prof(const timeval &interval, const timeval &value);
326
327 /**
328 * @brief create ITimer_Prof instance
329 * @details only one instance is allowed
330 * @param interval timer interval
331 * @exception std::logic_error instance exists
332 */
333 explicit ITimer_Prof(double interval);
334
335 /**
336 * @brief create ITimer_Prof instance
337 * @details only one instance is allowed
338 * @param interval interval at which the timer is triggered
339 * @param value ime period after which the timer expires for the first time
340 * @exception std::logic_error instance exists
341 */
342 ITimer_Prof(double interval, double value);
343
344 //* destroy instance
345 ~ITimer_Prof() override;
346
347 //* copying is not possible
348 ITimer_Prof(const ITimer_Prof &other) = delete;
349 //* moving is not possible
350 ITimer_Prof(ITimer_Prof &&other) = delete;
351 //* copying is not possible
352 ITimer_Prof &operator=(const ITimer_Prof &other) = delete;
353 //* moving is not possible
354 ITimer_Prof &operator=(ITimer_Prof &&other) = delete;
355};
356
357//* multiply timeval with double factor
358timeval &operator*=(timeval &left, double right) noexcept;
359
360//* multiply each timeval of itimerval with double factor
361itimerval &operator*=(itimerval &left, double right) noexcept;
362
363//* multiply timeval with double factor
364timeval operator*(const timeval &left, double right) noexcept;
365
366//* multiply each timeval of itimerval with double factor
367itimerval operator*(const itimerval &left, double right) noexcept;
368
369//* divide timeval by double factor
370timeval &operator/=(timeval &left, double right) noexcept;
371
372//* divide each timeval of itimerval by double factor
373itimerval &operator/=(itimerval &left, double right) noexcept;
374
375//* divide timeval by double factor
376timeval operator/(const timeval &left, double right) noexcept;
377
378//* divide each timeval of itimerval by double factor
379itimerval operator/(const itimerval &left, double right) noexcept;
380
381//* convert timeval to double (seconds)
382double timeval_to_double(const timeval &time) noexcept;
383
384//* convert double (seconds) to timeval
385timeval double_to_timeval(double time) noexcept;
386
387} // namespace cxxitimer
class ITimer_Prof
ITimer_Prof(double interval)
create ITimer_Prof instance
ITimer_Prof(double interval, double value)
create ITimer_Prof instance
ITimer_Prof & operator=(ITimer_Prof &&other)=delete
ITimer_Prof(const timeval &interval={.tv_sec=1,.tv_usec=0})
create ITimer_Prof instance
static bool instance_exists
ITimer_Prof(ITimer_Prof &&other)=delete
ITimer_Prof & operator=(const ITimer_Prof &other)=delete
ITimer_Prof(const timeval &interval, const timeval &value)
create ITimer_Prof instance
ITimer_Prof(const ITimer_Prof &other)=delete
class ITimer_Real
ITimer_Real(const timeval &interval={.tv_sec=1,.tv_usec=0})
create ITimer_Real instance
ITimer_Real(double interval)
create ITimer_Real instance
ITimer_Real(const timeval &interval, const timeval &value)
create ITimer_Real instance
ITimer_Real(ITimer_Real &&other)=delete
static bool instance_exists
ITimer_Real & operator=(const ITimer_Real &other)=delete
ITimer_Real & operator=(ITimer_Real &&other)=delete
ITimer_Real(double interval, double value)
create ITimer_Real instance
ITimer_Real(const ITimer_Real &other)=delete
class ITimer_Virtual
ITimer_Virtual & operator=(const ITimer_Virtual &other)=delete
ITimer_Virtual(const timeval &interval, const timeval &value)
create ITimer_Virtual instance
ITimer_Virtual(const timeval &interval={.tv_sec=1,.tv_usec=0})
create ITimer_Virtual instance
ITimer_Virtual(const ITimer_Virtual &other)=delete
ITimer_Virtual & operator=(ITimer_Virtual &&other)=delete
ITimer_Virtual(double interval, double value)
create ITimer_Virtual instance
ITimer_Virtual(ITimer_Virtual &&other)=delete
ITimer_Virtual(double interval)
create ITimer_Virtual instance
abstract class ITimer
Definition cxxitimer.hpp:16
void start()
start timer
Definition cxxitimer.cpp:96
void to_fstream(std::ofstream &fstream) const
write to binary file stream
double speed_factor
speed adjustment factor
Definition cxxitimer.hpp:34
ITimer(int type, double interval, double value) noexcept
Definition cxxitimer.cpp:50
ITimer(int type, const timeval &interval={.tv_sec=1,.tv_usec=0}) noexcept
Definition cxxitimer.cpp:26
ITimer(ITimer &&other)=delete
moving is not possible
ITimer(const ITimer &other)=delete
copying is not possible
ITimer(int type, double interval) noexcept
Definition cxxitimer.cpp:34
timeval get_timer_value() const
get timer value
timeval timer_interval
Definition cxxitimer.hpp:22
void from_fstream(std::ifstream &fstream)
read from binary filestream
void set_interval(const timeval &interval)
set interval (timeval)
ITimer & operator=(ITimer &&other)=delete
moving is not possible
void set_interval(double interval)
set interval (double)
ITimer & operator=(const ITimer &other)=delete
copying is not possible
bool is_running() const noexcept
check if timer is running
void set_interval_value(double interval, double value)
set interval and value
virtual ~ITimer()
Destroy the timer instance.
Definition cxxitimer.cpp:59
void set_speed_to_normal()
set speed to normal
void set_speed_factor(double factor)
set speed factor
ITimer(int type, const timeval &interval, const timeval &value) noexcept
Definition cxxitimer.cpp:42
void set_interval_value(const timeval &interval, const timeval &value)
set interval and value
void stop()
stop timer
virtual void adjust_speed(double new_factor)
Definition cxxitimer.cpp:71
itimerval & operator/=(itimerval &left, double right) noexcept
timeval double_to_timeval(const double time) noexcept
timeval & operator*=(timeval &left, double right) noexcept
constexpr auto USEC_PER_SEC
Definition cxxitimer.cpp:19
timeval operator*(const timeval &left, double right) noexcept
itimerval operator*(const itimerval &left, double right) noexcept
itimerval operator/(const itimerval &left, double right) noexcept
itimerval & operator*=(itimerval &left, double right) noexcept
timeval & operator/=(timeval &left, double right) noexcept
double timeval_to_double(const timeval &time) noexcept
static constexpr itimerval STOP_TIMER
Definition cxxitimer.cpp:16
timeval operator/(const timeval &left, double right) noexcept