-
Notifications
You must be signed in to change notification settings - Fork 2
/
schedule.c
68 lines (54 loc) · 1.46 KB
/
schedule.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
/*
* Paweł Foremski <pjf@iitis.pl> 2011
* IITiS PAN Gliwice
*/
#include "schedule.h"
#include "generator.h"
#include "stats.h"
void mgs_schedule(struct schedule *sch, struct timeval *timeout)
{
struct timeval now, wanted, tv;
stats_count(sch->mg->stats, "scheduler_evt");
/* first "last run" is at the origin */
if (sch->last.tv_sec == 0) {
sch->last.tv_sec = sch->mg->origin.tv_sec;
sch->last.tv_usec = sch->mg->origin.tv_usec;
}
/* compute and update accurate absolute location of requested moment */
timeradd(&sch->last, timeout, &wanted);
/* how it looks compared to time now? */
gettimeofday(&now, NULL);
if (timercmp(&now, &wanted, >)) {
timerclear(&tv);
stats_count(sch->mg->stats, "scheduler_lag");
} else {
timersub(&wanted, &now, &tv);
}
/* schedule */
evtimer_add(&sch->ev, &tv);
/* store last schedule */
sch->last.tv_sec = wanted.tv_sec;
sch->last.tv_usec = wanted.tv_usec;
}
void mgs_uschedule(struct schedule *sch, uint32_t time_us)
{
struct timeval tv;
tv.tv_sec = time_us / 1000000;
tv.tv_usec = time_us % 1000000;
mgs_schedule(sch, &tv);
}
void mgs_sleep(struct line *line, struct timeval *tv)
{
mgs_schedule(&line->schedule, tv ? tv : &line->tv);
}
void mgs_usleep(struct line *line, uint32_t time_us)
{
mgs_uschedule(&line->schedule, time_us);
}
void mgs_setup(struct schedule *sch, struct mg *mg, void (*cb)(int, short, void *), void *arg)
{
sch->mg = mg;
sch->cb = cb;
sch->arg = arg;
evtimer_set(&sch->ev, cb, arg);
}