-
Notifications
You must be signed in to change notification settings - Fork 0
/
ticker.c
executable file
·78 lines (66 loc) · 1.97 KB
/
ticker.c
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
74
75
76
77
78
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include "ticker.h"
#include "timestamp.h"
#include "vector.h"
void* tick (void* data) {
ticker_t* ticker = data;
struct timespec spec;
int64_t start;
int64_t end;
int64_t wait;
while (true) {
start = timestamp() * 1000000;
pthread_mutex_lock(&(ticker->terminate_mutex));
if (ticker->terminate) {
pthread_mutex_unlock(&(ticker->terminate_mutex));
break;
}
pthread_mutex_unlock(&(ticker->terminate_mutex));
pthread_mutex_lock(&(ticker->handlers_mutex));
int length = ticker->handlers->length;
pthread_mutex_unlock(&(ticker->handlers_mutex));
int i;
for (i = 0; i < length; i++) {
pthread_mutex_lock(&(ticker->handlers_mutex));
ticker_handler handler = vector_get(*(ticker->handlers), i, ticker_handler);
pthread_mutex_unlock(&(ticker->handlers_mutex));
(*handler)();
}
end = timestamp() * 1000000;
wait = 1000000000LL - (end - start);
if (wait > 999999999LL) {
// This should never happen as it means our loop somehow took less
// than 1ns to execute.
wait = 999999999LL;
} else if (wait < 0) {
wait = 0;
}
spec.tv_sec = 0;
spec.tv_nsec = wait;
nanosleep(&spec, NULL);
}
return NULL;
}
void ticker_register_handler (ticker_t* ticker, ticker_handler handler) {
pthread_mutex_lock(&(ticker->handlers_mutex));
vector_add(ticker->handlers, &handler);
pthread_mutex_unlock(&(ticker->handlers_mutex));
}
void ticker_init (ticker_t* ticker, vector_t* handlers) {
ticker->handlers = handlers;
ticker->terminate = false;
pthread_mutex_init(&(ticker->handlers_mutex), NULL);
pthread_mutex_init(&(ticker->terminate_mutex), NULL);
pthread_create(&(ticker->thread), NULL, tick, (void*) ticker);
}
void ticker_destroy (ticker_t* ticker) {
pthread_mutex_lock(&(ticker->terminate_mutex));
ticker->terminate = true;
pthread_mutex_unlock(&(ticker->terminate_mutex));
pthread_join(ticker->thread, NULL);
vector_free(ticker->handlers);
}