1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
250aadb33SDmitri Tikhonov#include <assert.h>
350aadb33SDmitri Tikhonov#include <stdint.h>
450aadb33SDmitri Tikhonov#include <stdio.h>
550aadb33SDmitri Tikhonov#include <stdlib.h>
6461e84d8SAmol Deshpande#ifndef WIN32
750aadb33SDmitri Tikhonov#include <unistd.h>
8461e84d8SAmol Deshpande#else
9fb3e20e0SDmitri Tikhonov#include "getopt.h"
10461e84d8SAmol Deshpande#endif
1150aadb33SDmitri Tikhonov
1250aadb33SDmitri Tikhonov#include "lsquic_malo.h"
1350aadb33SDmitri Tikhonov
1450aadb33SDmitri Tikhonovstruct elem {
1550aadb33SDmitri Tikhonov    unsigned        id;
1650aadb33SDmitri Tikhonov};
1750aadb33SDmitri Tikhonov
1850aadb33SDmitri Tikhonov
1950aadb33SDmitri Tikhonov#define N_ELEMS 10000   /* More and it hits swap on smaller VMs */
2050aadb33SDmitri Tikhonov
2150aadb33SDmitri Tikhonovstatic void
2250aadb33SDmitri Tikhonovrun_tests (size_t el_size)
2350aadb33SDmitri Tikhonov{
2450aadb33SDmitri Tikhonov    unsigned i;
2550aadb33SDmitri Tikhonov    struct malo *malo;
2650aadb33SDmitri Tikhonov    struct elem *el;
2750aadb33SDmitri Tikhonov
2850aadb33SDmitri Tikhonov    malo = lsquic_malo_create(el_size);
2950aadb33SDmitri Tikhonov    assert(malo);
3050aadb33SDmitri Tikhonov
3150aadb33SDmitri Tikhonov    for (i = 1; i <= N_ELEMS; ++i)
3250aadb33SDmitri Tikhonov    {
3350aadb33SDmitri Tikhonov        el = lsquic_malo_get(malo);
3450aadb33SDmitri Tikhonov        el->id = i;
3550aadb33SDmitri Tikhonov    }
3650aadb33SDmitri Tikhonov
3750aadb33SDmitri Tikhonov    uint64_t sum = 0, deleted_sum = 0;
3850aadb33SDmitri Tikhonov    for (el = lsquic_malo_first(malo); el; el = lsquic_malo_next(malo))
3950aadb33SDmitri Tikhonov    {
4050aadb33SDmitri Tikhonov        sum += el->id;
4150aadb33SDmitri Tikhonov        if (el->id % 3 == 0)        /* Delete every third element */
4250aadb33SDmitri Tikhonov        {
4350aadb33SDmitri Tikhonov            deleted_sum += el->id;
4450aadb33SDmitri Tikhonov            lsquic_malo_put(el);
4550aadb33SDmitri Tikhonov        }
4650aadb33SDmitri Tikhonov    }
4750aadb33SDmitri Tikhonov
4850aadb33SDmitri Tikhonov    assert(sum == ((uint64_t) N_ELEMS + 1) * ((uint64_t) N_ELEMS / 2));
4950aadb33SDmitri Tikhonov
5050aadb33SDmitri Tikhonov    sum = 0;
5150aadb33SDmitri Tikhonov    for (el = lsquic_malo_first(malo); el; el = lsquic_malo_next(malo))
5250aadb33SDmitri Tikhonov    {
5350aadb33SDmitri Tikhonov        sum += el->id;
5450aadb33SDmitri Tikhonov        lsquic_malo_put(el);
5550aadb33SDmitri Tikhonov    }
5650aadb33SDmitri Tikhonov
5750aadb33SDmitri Tikhonov    assert(sum == ((uint64_t) N_ELEMS + 1) * ((uint64_t) N_ELEMS / 2) -
5850aadb33SDmitri Tikhonov                                                                deleted_sum);
5950aadb33SDmitri Tikhonov
6050aadb33SDmitri Tikhonov    el = lsquic_malo_first(malo);
6150aadb33SDmitri Tikhonov    assert(!el);
6250aadb33SDmitri Tikhonov
6350aadb33SDmitri Tikhonov    lsquic_malo_destroy(malo);
6450aadb33SDmitri Tikhonov}
6550aadb33SDmitri Tikhonov
6650aadb33SDmitri Tikhonov
6750aadb33SDmitri Tikhonovstatic struct elem *elems[10000];
6850aadb33SDmitri Tikhonov
6950aadb33SDmitri Tikhonovstatic void
7050aadb33SDmitri Tikhonovalloc_using_malloc (int n)
7150aadb33SDmitri Tikhonov{
7250aadb33SDmitri Tikhonov    int i;
7350aadb33SDmitri Tikhonov    for (i = 0; i < n; ++i)
7450aadb33SDmitri Tikhonov    {
7550aadb33SDmitri Tikhonov        unsigned j;
7650aadb33SDmitri Tikhonov        for (j = 0; j < sizeof(elems) / sizeof(elems[0]); ++j)
7750aadb33SDmitri Tikhonov        {
7850aadb33SDmitri Tikhonov            elems[j] = malloc(sizeof(*elems[j]));
7950aadb33SDmitri Tikhonov            elems[j]->id = j;
8050aadb33SDmitri Tikhonov        }
8150aadb33SDmitri Tikhonov        for (j = 0; j < sizeof(elems) / sizeof(elems[0]); ++j)
8250aadb33SDmitri Tikhonov        {
8350aadb33SDmitri Tikhonov            free(elems[j]);
8450aadb33SDmitri Tikhonov        }
8550aadb33SDmitri Tikhonov    }
8650aadb33SDmitri Tikhonov}
8750aadb33SDmitri Tikhonov
8850aadb33SDmitri Tikhonov
8950aadb33SDmitri Tikhonovstatic void
9050aadb33SDmitri Tikhonovalloc_using_malo (int n)
9150aadb33SDmitri Tikhonov{
9250aadb33SDmitri Tikhonov    struct malo *malo = lsquic_malo_create(sizeof(struct elem));
9350aadb33SDmitri Tikhonov    int i;
9450aadb33SDmitri Tikhonov    for (i = 0; i < n; ++i)
9550aadb33SDmitri Tikhonov    {
9650aadb33SDmitri Tikhonov        unsigned j;
9750aadb33SDmitri Tikhonov        for (j = 0; j < sizeof(elems) / sizeof(elems[0]); ++j)
9850aadb33SDmitri Tikhonov        {
9950aadb33SDmitri Tikhonov            elems[j] = lsquic_malo_get(malo);
10050aadb33SDmitri Tikhonov            elems[j]->id = j;
10150aadb33SDmitri Tikhonov        }
10250aadb33SDmitri Tikhonov        for (j = 0; j < sizeof(elems) / sizeof(elems[0]); ++j)
10350aadb33SDmitri Tikhonov        {
10450aadb33SDmitri Tikhonov            lsquic_malo_put(elems[j]);
10550aadb33SDmitri Tikhonov        }
10650aadb33SDmitri Tikhonov    }
10750aadb33SDmitri Tikhonov    lsquic_malo_destroy(malo);
10850aadb33SDmitri Tikhonov}
10950aadb33SDmitri Tikhonov
11050aadb33SDmitri Tikhonov
11150aadb33SDmitri Tikhonovint
11250aadb33SDmitri Tikhonovmain (int argc, char **argv)
11350aadb33SDmitri Tikhonov{
11450aadb33SDmitri Tikhonov    int opt, mode = -1, n = 1;
11550aadb33SDmitri Tikhonov    while (-1 != (opt = getopt(argc, argv, "s:n:")))
11650aadb33SDmitri Tikhonov    {
11750aadb33SDmitri Tikhonov        switch (opt)
11850aadb33SDmitri Tikhonov        {
11950aadb33SDmitri Tikhonov        case 's':
12050aadb33SDmitri Tikhonov            mode = atoi(optarg);
12150aadb33SDmitri Tikhonov            break;
12250aadb33SDmitri Tikhonov        case 'n':
12350aadb33SDmitri Tikhonov            n = atoi(optarg);
12450aadb33SDmitri Tikhonov            break;
12550aadb33SDmitri Tikhonov        default:
12650aadb33SDmitri Tikhonov            exit(1);
12750aadb33SDmitri Tikhonov        }
12850aadb33SDmitri Tikhonov    }
12950aadb33SDmitri Tikhonov
13050aadb33SDmitri Tikhonov    switch (mode)
13150aadb33SDmitri Tikhonov    {
13250aadb33SDmitri Tikhonov    case -1:
13350aadb33SDmitri Tikhonov    {
13450aadb33SDmitri Tikhonov        size_t sz;
13550aadb33SDmitri Tikhonov        for (sz = sizeof(struct elem); sz < 0x800; sz <<= 1)
13650aadb33SDmitri Tikhonov        {
13750aadb33SDmitri Tikhonov            run_tests(sz - 3);
13850aadb33SDmitri Tikhonov            run_tests(sz - 1);
13950aadb33SDmitri Tikhonov            run_tests(sz);
14050aadb33SDmitri Tikhonov            run_tests(sz + 1);
14150aadb33SDmitri Tikhonov            run_tests(sz + 3);
14250aadb33SDmitri Tikhonov        }
14350aadb33SDmitri Tikhonov        break;
14450aadb33SDmitri Tikhonov    }
14550aadb33SDmitri Tikhonov    case 0:
14650aadb33SDmitri Tikhonov        alloc_using_malloc(n);
14750aadb33SDmitri Tikhonov        break;
14850aadb33SDmitri Tikhonov    case 1:
14950aadb33SDmitri Tikhonov        alloc_using_malo(n);
15050aadb33SDmitri Tikhonov        break;
15150aadb33SDmitri Tikhonov    default:
15250aadb33SDmitri Tikhonov        fprintf(stderr, "error: invalid mode %d\n", mode);
15350aadb33SDmitri Tikhonov        exit(2);
15450aadb33SDmitri Tikhonov    }
15550aadb33SDmitri Tikhonov
15650aadb33SDmitri Tikhonov    return 0;
15750aadb33SDmitri Tikhonov}
158