forked from ish-app/ish
-
Notifications
You must be signed in to change notification settings - Fork 12
/
timer.h
73 lines (63 loc) · 1.97 KB
/
timer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#ifndef UTIL_TIMER_H
#define UTIL_TIMER_H
#include <stdbool.h>
#include <time.h>
#include <pthread.h>
#include <assert.h>
#include "util/sync.h"
static inline struct timespec timespec_now(clockid_t clockid) {
assert(clockid == CLOCK_MONOTONIC || clockid == CLOCK_REALTIME);
struct timespec now;
clock_gettime(clockid, &now); // can't fail, according to posix spec
return now;
}
static inline struct timespec timespec_add(struct timespec x, struct timespec y) {
x.tv_sec += y.tv_sec;
x.tv_nsec += y.tv_nsec;
if (x.tv_nsec >= 1000000000) {
x.tv_nsec -= 1000000000;
x.tv_sec++;
}
return x;
}
static inline struct timespec timespec_subtract(struct timespec x, struct timespec y) {
struct timespec result;
if (x.tv_nsec < y.tv_nsec) {
x.tv_sec -= 1;
x.tv_nsec += 1000000000;
}
result.tv_sec = x.tv_sec - y.tv_sec;
result.tv_nsec = x.tv_nsec - y.tv_nsec;
return result;
}
static inline bool timespec_is_zero(struct timespec ts) {
return ts.tv_sec == 0 && ts.tv_nsec == 0;
}
static inline bool timespec_positive(struct timespec ts) {
return ts.tv_sec > 0 || (ts.tv_sec == 0 && ts.tv_nsec > 0);
}
typedef void (*timer_callback_t)(void *data);
struct timer {
clockid_t clockid;
struct timespec start;
struct timespec end;
struct timespec interval;
bool running;
pthread_t thread;
timer_callback_t callback;
void *data;
lock_t lock;
bool dead;
};
struct timer *timer_new(clockid_t clockid, timer_callback_t callback, void *data);
void timer_free(struct timer *timer);
// value is how long to wait until the next fire
// interval is how long after that to wait until the next fire (if non-zero)
// bizzare interface is based off setitimer, because this is going to be used
// to implement setitimer
struct timer_spec {
struct timespec value;
struct timespec interval;
};
int timer_set(struct timer *timer, struct timer_spec spec, struct timer_spec *oldspec);
#endif