2021-01-06 14:00:05 +00:00
|
|
|
/* Copyright (c) 2017 - 2021 LiteSpeed Technologies Inc. See LICENSE. */
|
2017-09-22 21:00:03 +00:00
|
|
|
#include <assert.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/queue.h>
|
|
|
|
|
|
|
|
#include "lsquic.h"
|
|
|
|
|
2019-09-11 15:27:58 +00:00
|
|
|
#include "lsquic_packet_common.h"
|
2017-09-22 21:00:03 +00:00
|
|
|
#include "lsquic_alarmset.h"
|
|
|
|
|
|
|
|
|
|
|
|
static lsquic_time_t global_now;
|
|
|
|
|
|
|
|
static struct cb_ctx {
|
|
|
|
lsquic_time_t last_expiry;
|
|
|
|
unsigned n_calls;
|
|
|
|
} global_ctx;
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2019-09-11 15:27:58 +00:00
|
|
|
alarm_cb (enum alarm_id al_id, void *ctx, lsquic_time_t expiry,
|
|
|
|
lsquic_time_t now)
|
2017-09-22 21:00:03 +00:00
|
|
|
{
|
|
|
|
struct cb_ctx *cb_ctx = ctx;
|
|
|
|
assert(cb_ctx == &global_ctx);
|
|
|
|
assert(cb_ctx->last_expiry <= expiry); /* This checks sortedness */
|
|
|
|
assert(global_now == now);
|
|
|
|
++cb_ctx->n_calls;
|
|
|
|
cb_ctx->last_expiry = expiry;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-10-31 16:21:14 +00:00
|
|
|
#if __GNUC__
|
|
|
|
# define popcount __builtin_popcount
|
|
|
|
#else
|
|
|
|
static int
|
|
|
|
popcount (unsigned v)
|
|
|
|
{
|
|
|
|
int count, i;
|
|
|
|
for (i = 0, count = 0; i < sizeof(v) * 8; ++i)
|
|
|
|
if (v & (1 << i))
|
|
|
|
++count;
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2017-09-22 21:00:03 +00:00
|
|
|
int
|
|
|
|
main (void)
|
|
|
|
{
|
|
|
|
unsigned i;
|
|
|
|
lsquic_alarmset_t alset;
|
|
|
|
|
|
|
|
lsquic_alarmset_init(&alset, 0);
|
|
|
|
|
|
|
|
for (i = 0; i < MAX_LSQUIC_ALARMS; ++i)
|
|
|
|
lsquic_alarmset_init_alarm(&alset, i, alarm_cb, &global_ctx);
|
|
|
|
|
|
|
|
lsquic_alarmset_set(&alset, 0, 20);
|
|
|
|
lsquic_alarmset_set(&alset, 1, 5);
|
|
|
|
lsquic_alarmset_set(&alset, 2, 11);
|
|
|
|
lsquic_alarmset_set(&alset, 3, 15);
|
|
|
|
|
|
|
|
assert(lsquic_alarmset_is_set(&alset, 3));
|
|
|
|
lsquic_alarmset_unset(&alset, 3);
|
|
|
|
assert(!lsquic_alarmset_is_set(&alset, 3));
|
|
|
|
lsquic_alarmset_set(&alset, 3, 15);
|
|
|
|
|
|
|
|
global_ctx.last_expiry = 0;
|
|
|
|
global_ctx.n_calls = 0;
|
|
|
|
|
|
|
|
lsquic_alarmset_ring_expired(&alset, global_now = 1);
|
|
|
|
|
|
|
|
assert(0 == global_ctx.n_calls);
|
|
|
|
|
|
|
|
assert(lsquic_alarmset_is_set(&alset, 1));
|
|
|
|
lsquic_alarmset_ring_expired(&alset, global_now = 10);
|
|
|
|
assert(!lsquic_alarmset_is_set(&alset, 1));
|
|
|
|
|
|
|
|
assert(1 == global_ctx.n_calls);
|
|
|
|
assert(5 == global_ctx.last_expiry);
|
|
|
|
|
|
|
|
lsquic_alarmset_ring_expired(&alset, global_now = 12);
|
|
|
|
|
|
|
|
assert(2 == global_ctx.n_calls);
|
|
|
|
assert(11 == global_ctx.last_expiry);
|
|
|
|
|
|
|
|
lsquic_alarmset_ring_expired(&alset, global_now = 20);
|
|
|
|
|
|
|
|
/* expiry must be strictly smaller than current time */
|
|
|
|
assert(3 == global_ctx.n_calls);
|
|
|
|
assert(15 == global_ctx.last_expiry);
|
|
|
|
|
|
|
|
lsquic_alarmset_ring_expired(&alset, global_now = 21);
|
|
|
|
|
|
|
|
assert(4 == global_ctx.n_calls);
|
|
|
|
assert(20 == global_ctx.last_expiry);
|
|
|
|
|
2019-10-31 16:21:14 +00:00
|
|
|
unsigned t = 1;
|
|
|
|
for (i = 1; i < (1u << MAX_LSQUIC_ALARMS); ++i)
|
|
|
|
{
|
|
|
|
alset.as_armed_set = 0; /* Unset all */
|
|
|
|
unsigned const count = popcount(i);
|
|
|
|
unsigned const min_n = i % count;
|
|
|
|
unsigned const min_t = t++;
|
2020-06-03 04:13:30 +00:00
|
|
|
unsigned j, n;
|
|
|
|
enum alarm_id ids[2];
|
2019-10-31 16:21:14 +00:00
|
|
|
for (j = 0, n = 0; j < MAX_LSQUIC_ALARMS; ++j)
|
|
|
|
{
|
|
|
|
if ((1u << j) & i)
|
|
|
|
{
|
|
|
|
if (n == min_n)
|
|
|
|
{
|
|
|
|
ids[0] = j;
|
|
|
|
lsquic_alarmset_set(&alset, j, min_t);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
lsquic_alarmset_set(&alset, j, t++);
|
|
|
|
++n;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
lsquic_time_t found_min_t = lsquic_alarmset_mintime(&alset, &ids[1]);
|
|
|
|
assert(min_t == found_min_t);
|
|
|
|
assert(ids[0] == ids[1]);
|
|
|
|
}
|
|
|
|
|
2017-09-22 21:00:03 +00:00
|
|
|
return 0;
|
|
|
|
}
|