Add implementation
This commit is contained in:
		
							
								
								
									
										60
									
								
								src/timer.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/timer.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| #include <bits/types/struct_itimerspec.h> | ||||
| #include <cmath> | ||||
| #include <signal.h> | ||||
| #include <time.h> | ||||
| #include <libscerror.hpp> | ||||
| #include "timer.hpp" | ||||
|  | ||||
| using namespace sc; | ||||
|  | ||||
| uint64_t timer::next_id = 0; | ||||
| std::mutex timer::mutex; | ||||
|  | ||||
| timer::timer(void(*callback)(union sigval), double time, bool repeat) | ||||
|     : _id {}, _time {time}, _repeat {repeat} | ||||
| { | ||||
|     { | ||||
|         std::lock_guard<std::mutex> lock {mutex}; | ||||
|         _id = ++next_id; | ||||
|     } | ||||
|     struct sigevent se; | ||||
|     se.sigev_notify = SIGEV_THREAD; | ||||
|     se.sigev_value.sival_int = 0; | ||||
|     se.sigev_value.sival_ptr = &_id; | ||||
|     se.sigev_notify_function = callback; | ||||
|     se.sigev_notify_attributes = nullptr; | ||||
|     throw_if_min1_msg(timer_create(CLOCK_MONOTONIC, &se, &_tid), "could not create timer"); | ||||
|     time_t secs = floor(time / 1000); | ||||
|     long ns = (time - 1000 * secs) * 1000000; | ||||
|     struct itimerspec its; | ||||
|     its.it_value.tv_sec = secs; | ||||
|     its.it_value.tv_nsec = ns; | ||||
|     if (repeat) { | ||||
|         its.it_interval.tv_sec = secs; | ||||
|         its.it_interval.tv_nsec = ns; | ||||
|     } else { | ||||
|         its.it_interval.tv_sec = 0; | ||||
|         its.it_interval.tv_nsec = 0; | ||||
|     } | ||||
|     throw_if_min1_msg(timer_settime(_tid, 0, &its, nullptr), "could not set timer"); | ||||
| } | ||||
|  | ||||
| timer::~timer() { | ||||
|     throw_if_min1_msg(timer_delete(_tid), "could not delete timer"); | ||||
| } | ||||
|  | ||||
| void timer::time(struct itimerspec& cur_value) const { | ||||
|     throw_if_min1_msg(timer_gettime(_tid, &cur_value), "could not get time"); | ||||
| } | ||||
|  | ||||
| double timer::time() const { | ||||
|     struct itimerspec its; | ||||
|     time(its); | ||||
|     return its.it_value.tv_sec + its.it_value.tv_nsec * 1000000000; | ||||
| } | ||||
|  | ||||
| bool timer::is_armed() const { | ||||
|     struct itimerspec its; | ||||
|     time(its); | ||||
|     return its.it_value.tv_sec != 0 || its.it_value.tv_nsec != 0; | ||||
| } | ||||
							
								
								
									
										30
									
								
								src/timer.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/timer.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| #ifndef _timer_H_ | ||||
| #define _timer_H_ | ||||
|  | ||||
| #include <cstdint> | ||||
| #include <mutex> | ||||
|  | ||||
| namespace sc { | ||||
|  | ||||
|     class timer { | ||||
|         static uint64_t next_id; | ||||
|         static std::mutex mutex; | ||||
|  | ||||
|         timer_t _tid; | ||||
|         uint64_t _id; | ||||
|         double _time; | ||||
|         bool _repeat; | ||||
|  | ||||
|         public: | ||||
|             timer(void(*callback)(union sigval), double time, bool repeat = false); | ||||
|             ~timer(); | ||||
|  | ||||
|             void time(struct itimerspec& cur_value) const; | ||||
|             double time() const; | ||||
|             bool is_armed() const; | ||||
|             bool repeat() const { return _repeat; } | ||||
|     }; | ||||
|  | ||||
| } | ||||
|  | ||||
| #endif // _timer_H_ | ||||
		Reference in New Issue
	
	Block a user