Add start/stop methods

This commit is contained in:
Bob Polis 2024-01-24 09:59:11 +01:00
parent 96e5cc193e
commit fe4bbe77f9
2 changed files with 49 additions and 15 deletions

View File

@ -12,6 +12,22 @@ void sc::timer::callback(union sigval sv) {
self->_expired_func(*self); self->_expired_func(*self);
} }
void sc::timer::setup_timer(double time, bool repeat) {
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");
}
sc::timer::timer(double time, sc::timer::timer(double time,
bool repeat, bool repeat,
void(*expired_func)(const timer&), void(*expired_func)(const timer&),
@ -29,19 +45,7 @@ sc::timer::timer(double time,
se.sigev_notify_function = callback; se.sigev_notify_function = callback;
se.sigev_notify_attributes = nullptr; se.sigev_notify_attributes = nullptr;
throw_if_min1_msg(timer_create(CLOCK_MONOTONIC, &se, &_tid), "could not create timer"); throw_if_min1_msg(timer_create(CLOCK_MONOTONIC, &se, &_tid), "could not create timer");
time_t secs = floor(time / 1000); setup_timer(time, repeat);
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");
} }
sc::timer::~timer() { sc::timer::~timer() {
@ -63,3 +67,26 @@ bool sc::timer::is_armed() const {
time_left(its); time_left(its);
return its.it_value.tv_sec != 0 || its.it_value.tv_nsec != 0; return its.it_value.tv_sec != 0 || its.it_value.tv_nsec != 0;
} }
void sc::timer::stop() {
if (is_armed()) {
struct itimerspec its;
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = 0;
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 0;
throw_if_min1_msg(timer_settime(_tid, 0, &its, nullptr), "could not stop timer");
}
}
void sc::timer::start() {
if (!is_armed()) {
setup_timer(_time, _repeat);
}
}
void sc::timer::start(double time, bool repeat) {
if (!is_armed()) {
setup_timer(time, repeat);
}
}

View File

@ -17,8 +17,6 @@ namespace sc {
mutable void* _context {}; mutable void* _context {};
timer_t _tid; timer_t _tid;
static void callback(union sigval);
public: public:
timer(double time, timer(double time,
bool repeat, bool repeat,
@ -34,6 +32,15 @@ namespace sc {
bool is_armed() const; bool is_armed() const;
void time_left(struct itimerspec& cur_value) const; void time_left(struct itimerspec& cur_value) const;
double time_left() const; double time_left() const;
void stop();
void start();
void start(double time, bool repeat);
private:
static void callback(union sigval);
void setup_timer(double time, bool repeat);
}; };
} }