litespeed-quic/test/unittests/test_malo.c
2017-09-22 17:00:03 -04:00

153 lines
3.1 KiB
C

/* Copyright (c) 2017 LiteSpeed Technologies Inc. See LICENSE. */
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "lsquic_malo.h"
struct elem {
unsigned id;
};
#define N_ELEMS 10000 /* More and it hits swap on smaller VMs */
static void
run_tests (size_t el_size)
{
unsigned i;
struct malo *malo;
struct elem *el;
malo = lsquic_malo_create(el_size);
assert(malo);
for (i = 1; i <= N_ELEMS; ++i)
{
el = lsquic_malo_get(malo);
el->id = i;
}
uint64_t sum = 0, deleted_sum = 0;
for (el = lsquic_malo_first(malo); el; el = lsquic_malo_next(malo))
{
sum += el->id;
if (el->id % 3 == 0) /* Delete every third element */
{
deleted_sum += el->id;
lsquic_malo_put(el);
}
}
assert(sum == ((uint64_t) N_ELEMS + 1) * ((uint64_t) N_ELEMS / 2));
sum = 0;
for (el = lsquic_malo_first(malo); el; el = lsquic_malo_next(malo))
{
sum += el->id;
lsquic_malo_put(el);
}
assert(sum == ((uint64_t) N_ELEMS + 1) * ((uint64_t) N_ELEMS / 2) -
deleted_sum);
el = lsquic_malo_first(malo);
assert(!el);
lsquic_malo_destroy(malo);
}
static struct elem *elems[10000];
static void
alloc_using_malloc (int n)
{
int i;
for (i = 0; i < n; ++i)
{
unsigned j;
for (j = 0; j < sizeof(elems) / sizeof(elems[0]); ++j)
{
elems[j] = malloc(sizeof(*elems[j]));
elems[j]->id = j;
}
for (j = 0; j < sizeof(elems) / sizeof(elems[0]); ++j)
{
free(elems[j]);
}
}
}
static void
alloc_using_malo (int n)
{
struct malo *malo = lsquic_malo_create(sizeof(struct elem));
int i;
for (i = 0; i < n; ++i)
{
unsigned j;
for (j = 0; j < sizeof(elems) / sizeof(elems[0]); ++j)
{
elems[j] = lsquic_malo_get(malo);
elems[j]->id = j;
}
for (j = 0; j < sizeof(elems) / sizeof(elems[0]); ++j)
{
lsquic_malo_put(elems[j]);
}
}
lsquic_malo_destroy(malo);
}
int
main (int argc, char **argv)
{
int opt, mode = -1, n = 1;
while (-1 != (opt = getopt(argc, argv, "s:n:")))
{
switch (opt)
{
case 's':
mode = atoi(optarg);
break;
case 'n':
n = atoi(optarg);
break;
default:
exit(1);
}
}
switch (mode)
{
case -1:
{
size_t sz;
for (sz = sizeof(struct elem); sz < 0x800; sz <<= 1)
{
run_tests(sz - 3);
run_tests(sz - 1);
run_tests(sz);
run_tests(sz + 1);
run_tests(sz + 3);
}
break;
}
case 0:
alloc_using_malloc(n);
break;
case 1:
alloc_using_malo(n);
break;
default:
fprintf(stderr, "error: invalid mode %d\n", mode);
exit(2);
}
return 0;
}