Commit 948cacb5 authored by William Ahern's avatar William Ahern

Merge branch 'nmathewson-fixing_intervals'

parents a8a62b4f 43a85424
...@@ -226,6 +226,7 @@ struct intervals_cfg { ...@@ -226,6 +226,7 @@ struct intervals_cfg {
int n_timeouts; int n_timeouts;
timeout_t start_at; timeout_t start_at;
timeout_t end_at; timeout_t end_at;
timeout_t skip;
}; };
int int
...@@ -261,23 +262,35 @@ check_intervals(struct intervals_cfg *cfg) ...@@ -261,23 +262,35 @@ check_intervals(struct intervals_cfg *cfg)
while (now < cfg->end_at) { while (now < cfg->end_at) {
timeout_t delay = timeouts_timeout(tos); timeout_t delay = timeouts_timeout(tos);
if (cfg->skip && delay < cfg->skip)
delay = cfg->skip;
timeouts_step(tos, delay); timeouts_step(tos, delay);
now += delay; now += delay;
while (NULL != (to = timeouts_get(tos))) { while (NULL != (to = timeouts_get(tos))) {
i = to - &t[0]; i = to - &t[0];
assert(&t[i] == to); assert(&t[i] == to);
fired[i]++; fired[i]++;
if (0 != (to->expires - cfg->start_at) % cfg->timeouts[i])
FAIL();
if (to->expires <= now)
FAIL();
if (to->expires > now + cfg->timeouts[i])
FAIL();
} }
if (!timeouts_check(tos, stderr)) if (!timeouts_check(tos, stderr))
FAIL(); FAIL();
} }
timeout_t duration = cfg->end_at - cfg->start_at; timeout_t duration = now - cfg->start_at;
for (i = 0; i < cfg->n_timeouts; ++i) { for (i = 0; i < cfg->n_timeouts; ++i) {
if (fired[i] != duration / cfg->timeouts[i]) if (cfg->skip) {
FAIL(); if (fired[i] > duration / cfg->timeouts[i])
FAIL();
} else {
if (fired[i] != duration / cfg->timeouts[i])
FAIL();
}
if (!timeout_pending(&t[i])) if (!timeout_pending(&t[i]))
FAIL(); FAIL();
} }
...@@ -420,25 +433,36 @@ main(int argc, char **argv) ...@@ -420,25 +433,36 @@ main(int argc, char **argv)
.n_timeouts = sizeof(primes)/sizeof(timeout_t), .n_timeouts = sizeof(primes)/sizeof(timeout_t),
.start_at = 50, .start_at = 50,
.end_at = 5322, .end_at = 5322,
.skip = 0,
}; };
DO(check_intervals(&icfg1)); DO(check_intervals(&icfg1));
struct intervals_cfg icfg2 = { struct intervals_cfg icfg2 = {
.timeouts = primes, .timeouts = factors_of_1337,
.n_timeouts = sizeof(factors_of_1337)/sizeof(timeout_t), .n_timeouts = sizeof(factors_of_1337)/sizeof(timeout_t),
.start_at = 50, .start_at = 50,
.end_at = 50000, .end_at = 50000,
.skip = 0,
}; };
DO(check_intervals(&icfg2)); DO(check_intervals(&icfg2));
struct intervals_cfg icfg3 = { struct intervals_cfg icfg3 = {
.timeouts = primes, .timeouts = multiples_of_five,
.n_timeouts = sizeof(multiples_of_five)/sizeof(timeout_t), .n_timeouts = sizeof(multiples_of_five)/sizeof(timeout_t),
.start_at = 49, .start_at = 49,
.end_at = 5333, .end_at = 5333,
.skip = 0,
}; };
DO(check_intervals(&icfg3)); DO(check_intervals(&icfg3));
struct intervals_cfg icfg4 = {
.timeouts = primes,
.n_timeouts = sizeof(primes)/sizeof(timeout_t),
.start_at = 50,
.end_at = 5322,
.skip = 16,
};
DO(check_intervals(&icfg4));
if (n_failed) { if (n_failed) {
puts("\nFAIL"); puts("\nFAIL");
......
...@@ -358,18 +358,13 @@ static void timeouts_readd(struct timeouts *T, struct timeout *to) { ...@@ -358,18 +358,13 @@ static void timeouts_readd(struct timeouts *T, struct timeout *to) {
to->expires += to->interval; to->expires += to->interval;
if (to->expires <= T->curtime) { if (to->expires <= T->curtime) {
if (to->expires < T->curtime) { /* If we've missed the next firing of this timeout, reschedule
timeout_t n = T->curtime - to->expires; * it to occur at the next multiple of its interval after
timeout_t q = n / to->interval; * the last time that it fired.
timeout_t r = n % to->interval; */
timeout_t n = T->curtime - to->expires;
if (r) timeout_t r = n % to->interval;
to->expires += (to->interval * q) + (to->interval - r); to->expires = T->curtime + (to->interval - r);
else
to->expires += (to->interval * q);
} else {
to->expires += to->interval;
}
} }
timeouts_sched(T, to, to->expires); timeouts_sched(T, to, to->expires);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment