9#include <freeradius-devel/util/timer.h>
10#include <freeradius-devel/util/slab.h>
32 .interval.value = 1 *
NSEC
56 test_slab_list_t *test_slab_list;
63 test_slab_list = test_slab_list_alloc(NULL, NULL, &
def_slab_config, NULL, NULL, NULL,
true,
false);
66 test_elements[0] = test_slab_reserve(test_slab_list);
75 if (test_elements[0]) test_elements[0]->
name =
talloc_strdup(test_elements[0],
"Hello there");
76 if (test_elements[0]) test_slab_element_set_destructor(test_elements[0],
test_element_free, &test_uctx);
78 test_elements[1] = test_slab_reserve(test_slab_list);
80 TEST_CHECK(test_elements[1] != test_elements[0]);
85 test_elements[2] = test_slab_reserve(test_slab_list);
87 if (test_elements[2]) test_elements[2]->
name =
talloc_strdup(test_elements[2],
"Hello there testing");
88 if (test_elements[2]) test_slab_element_set_destructor(test_elements[2],
test_element_free, &test_uctx2);
92 test_elements[3] = test_slab_reserve(test_slab_list);
98 test_elements[4] = test_slab_reserve(test_slab_list);
104 if (test_elements[0]) test_slab_release(test_elements[0]);
109 if (test_elements[1]) test_slab_release(test_elements[1]);
113 if (test_elements[2]) test_slab_release(test_elements[2]);
126 test_slab_list_t *test_slab_list;
134 test_slab_list = test_slab_list_alloc(NULL, NULL, &slab_config, NULL, NULL, NULL,
true,
false);
137 test_elements[0] = test_slab_reserve(test_slab_list);
142 test_elements[1] = test_slab_reserve(test_slab_list);
143 test_elements[2] = test_slab_reserve(test_slab_list);
144 test_elements[3] = test_slab_reserve(test_slab_list);
150 test_elements[4] = test_slab_reserve(test_slab_list);
163 test_slab_list_t *test_slab_list;
167 test_slab_list = test_slab_list_alloc(NULL, NULL, &
def_slab_config, NULL, NULL, NULL,
true,
false);
170 test_elements[0] = test_slab_reserve(test_slab_list);
177 if (test_elements[0]) test_elements[0]->
name =
talloc_strdup(test_elements[0],
"Hello there");
178 if (test_elements[0]) test_slab_element_set_destructor(test_elements[0],
test_element_free, &test_uctx);
180 test_elements[1] = test_slab_reserve(test_slab_list);
182 TEST_CHECK(test_elements[1] != test_elements[0]);
184 test_elements[2] = test_slab_reserve(test_slab_list);
187 test_elements[3] = test_slab_reserve(test_slab_list);
190 if (test_elements[0]) test_slab_release(test_elements[0]);
198 test_elements[4] = test_slab_reserve(test_slab_list);
200 TEST_CHECK(test_elements[4] == test_elements[0]);
210 if (test_elements[4]) test_elements[4]->
name =
talloc_strdup(test_elements[4],
"Different length string");
211 if (test_elements[4]) test_slab_release(test_elements[4]);
222 test_slab_list_t *test_slab_list;
226 test_slab_list = test_slab_list_alloc(NULL, NULL, &
def_slab_config, NULL, NULL, NULL,
false,
false);
229 test_elements[0] = test_slab_reserve(test_slab_list);
236 if (test_elements[0]) test_elements[0]->
name =
talloc_strdup(test_elements[0],
"Hello there");
237 if (test_elements[0]) test_slab_element_set_destructor(test_elements[0],
test_element_free, &test_uctx);
239 test_elements[1] = test_slab_reserve(test_slab_list);
241 TEST_CHECK(test_elements[1] != test_elements[0]);
243 if (test_elements[0]) test_slab_release(test_elements[0]);
251 test_elements[2] = test_slab_reserve(test_slab_list);
253 TEST_CHECK(test_elements[2] == test_elements[0]);
254 if (test_elements[0] && test_elements[2])
TEST_CHECK(test_elements[2]->
name == test_elements[0]->
name);
261 if (test_elements[2]) test_elements[2]->
name =
talloc_strdup(test_elements[2],
"Different length string");
262 if (test_elements[2]) test_slab_release(test_elements[2]);
274 test_slab_list_t *test_slab_list;
281 test_slab_list = test_slab_list_alloc(NULL, NULL, &
def_slab_config, NULL, NULL, NULL,
true,
false);
284 test_elements[0] = test_slab_reserve(test_slab_list);
287 if (test_elements[0]) test_slab_release(test_elements[0]);
289 test_elements[1] = test_slab_reserve(test_slab_list);
291 TEST_CHECK(test_elements[0] != test_elements[1]);
298 test_slab_list = test_slab_list_alloc(NULL, NULL, &
def_slab_config, NULL, NULL, NULL,
true,
true);
301 test_elements[0] = test_slab_reserve(test_slab_list);
304 if (test_elements[0]) test_slab_release(test_elements[0]);
306 test_elements[1] = test_slab_reserve(test_slab_list);
308 TEST_CHECK(test_elements[0] == test_elements[1]);
318 test_slab_list_t *test_slab_list;
324 test_slab_list = test_slab_list_alloc(NULL, NULL, &slab_config, NULL, NULL, NULL,
true,
false);
327 test_element = test_slab_reserve(test_slab_list);
332 if (test_element) test_element->
name =
talloc_strdup(test_element,
"Hello there");
333 if (test_element) test_slab_element_set_destructor(test_element,
test_element_free, &test_uctx);
356 test_slab_list_t *test_slab_list;
362 test_slab_list = test_slab_list_alloc(NULL, NULL, &slab_config,
test_element_alloc, NULL, &test_conf,
false,
false);
365 test_elements[0] = test_slab_reserve(test_slab_list);
367 TEST_CHECK(test_elements[0] && (test_elements[0]->num == 10));
372 if (test_elements[0]) {
373 test_elements[0]->
num = 5;
374 test_slab_release(test_elements[0]);
380 test_elements[1] = test_slab_reserve(test_slab_list);
382 TEST_CHECK(test_elements[1] == test_elements[0]);
383 if (test_elements[1])
TEST_CHECK(test_elements[1]->num == 5);
393 test_slab_list_t *test_slab_list;
399 test_slab_list = test_slab_list_alloc(NULL, NULL, &slab_config, NULL,
test_element_alloc, &test_conf,
false,
false);
402 test_elements[0] = test_slab_reserve(test_slab_list);
404 TEST_CHECK(test_elements[0] && (test_elements[0]->num == 10));
409 if (test_elements[0]) {
410 test_elements[0]->
num = 5;
411 test_slab_release(test_elements[0]);
417 test_elements[1] = test_slab_reserve(test_slab_list);
419 TEST_CHECK(test_elements[1] == test_elements[0]);
420 if (test_elements[1])
TEST_CHECK(test_elements[1]->num == 10);
437 test_slab_list_t *test_slab_list;
446 test_elements[0] = test_slab_reserve(test_slab_list);
448 TEST_CHECK(test_elements[0] && (test_elements[0]->num == 20));
453 if (test_elements[0]) {
454 test_elements[0]->
num = 5;
455 test_slab_release(test_elements[0]);
461 test_elements[1] = test_slab_reserve(test_slab_list);
463 TEST_CHECK(test_elements[1] == test_elements[0]);
464 if (test_elements[1])
TEST_CHECK(test_elements[1]->num == 20);
476 test_slab_list_t *test_slab_list;
485 test_slab_list = test_slab_list_alloc(NULL,
el, &slab_config, NULL, NULL, NULL,
true,
false);
491 for (i = 0; i < 6; i++) {
492 test_elements[i] = test_slab_reserve(test_slab_list);
501 for (i = 0; i < 4; i++) {
502 test_slab_release(test_elements[i]);
529 test_slab_list_t *test_slab_list;
539 test_slab_list = test_slab_list_alloc(NULL,
el, &slab_config, NULL, NULL, NULL,
true,
false);
545 for (i = 0; i < 20; i++) {
546 test_elements[i] = test_slab_reserve(test_slab_list);
555 for (i = 0; i < 20; i++) {
556 test_slab_release(test_elements[i]);
593 test_slab_list_t *test_slab_list;
603 test_slab_list = test_slab_list_alloc(NULL,
el, &slab_config, NULL, NULL, NULL,
true,
false);
609 for (i = 0; i < 20; i++) {
610 test_elements[i] = test_slab_reserve(test_slab_list);
619 for (i = 0; i < 20; i++) {
620 test_slab_release(test_elements[i]);
686 test_slab_list_t *test_slab_list;
696 test_slab_list = test_slab_list_alloc(NULL,
el, &slab_config, NULL, NULL, NULL,
true,
false);
702 for (i = 0; i < 20; i++) {
703 test_elements[i] = test_slab_reserve(test_slab_list);
712 for (i = 0; i < 20; i++) {
713 test_slab_release(test_elements[i]);
732 for (i = 0; i < 20; i++) {
733 test_elements[i] = test_slab_reserve(test_slab_list);
747 test_slab_list_t *test_slab_list;
754 test_slab_list = test_slab_list_alloc(NULL, NULL, &slab_config, NULL, NULL, NULL,
true,
false);
757 for (i = 0; i < 4; i++) {
758 test_elements[i] = test_slab_reserve(test_slab_list);
764 if (test_elements[0]) test_elements[0]->
name =
talloc_strdup(test_elements[0],
"first");
765 if (test_elements[0]) test_slab_element_set_destructor(test_elements[0],
test_element_free, &test_uctx);
770 if (test_elements[0])
talloc_free(test_elements[0]);
774 if (test_elements[1])
talloc_free(test_elements[1]);
777 if (test_elements[2])
talloc_free(test_elements[2]);
780 if (test_elements[3])
talloc_free(test_elements[3]);
794 test_slab_list_t *test_slab_list;
803 test_slab_list = test_slab_list_alloc(NULL, NULL, &
def_slab_config, NULL, NULL, NULL,
true,
false);
806 for (i = 0; i < 4; i++) {
807 test_elements[i] = test_slab_reserve(test_slab_list);
813 if (test_elements[0]) test_elements[0]->
name =
talloc_strdup(test_elements[0],
"bulk teardown");
814 if (test_elements[0]) test_slab_element_set_destructor(test_elements[0],
test_element_free, &test_uctx);
833 test_slab_list_t *test_slab_list;
839 test_slab_list = test_slab_list_alloc(NULL, NULL, &slab_config, NULL, NULL, NULL,
true,
false);
842 test_elements[0] = test_slab_reserve(test_slab_list);
843 test_elements[1] = test_slab_reserve(test_slab_list);
844 test_elements[2] = test_slab_reserve(test_slab_list);
845 test_elements[3] = test_slab_reserve(test_slab_list);
848 test_uctx1.
count = 0;
849 test_uctx2.
count = 0;
850 if (test_elements[0]) test_elements[0]->
name =
talloc_strdup(test_elements[0],
"release me");
851 if (test_elements[0]) test_slab_element_set_destructor(test_elements[0],
test_element_free, &test_uctx1);
852 if (test_elements[1]) test_elements[1]->
name =
talloc_strdup(test_elements[1],
"free me");
853 if (test_elements[1]) test_slab_element_set_destructor(test_elements[1],
test_element_free, &test_uctx2);
858 if (test_elements[0]) test_slab_release(test_elements[0]);
862 if (test_elements[1])
talloc_free(test_elements[1]);
869 if (test_elements[2]) test_slab_release(test_elements[2]);
872 if (test_elements[3]) test_slab_release(test_elements[3]);
882 test_slab_list_t *test_slab_list;
888 test_slab_list = test_slab_list_alloc(NULL, NULL, &slab_config, NULL, NULL, NULL,
true,
false);
894 test_elements[0] = test_slab_reserve(test_slab_list);
895 test_elements[1] = test_slab_reserve(test_slab_list);
905 if (test_elements[0])
talloc_free(test_elements[0]);
912 test_elements[2] = test_slab_reserve(test_slab_list);
921 test_slab_list_t *test_slab_list;
928 test_slab_list = test_slab_list_alloc(NULL, NULL, &slab_config, NULL, NULL, NULL,
false,
false);
931 test_elements[0] = test_slab_reserve(test_slab_list);
933 test_elements[1] = test_slab_reserve(test_slab_list);
943 if (test_elements[0]) {
945 TEST_CHECK((
void *)test_elements[0]->
name > (
void *)test_elements[0]);
946 if (test_elements[1] && (test_elements[1] > test_elements[0])) {
947 TEST_CHECK((
void *)test_elements[0]->
name < (
void *)test_elements[1]);
948 TEST_MSG(
"element 0: %p, name %p, element 1: %p",
949 test_elements[0], test_elements[0]->
name, test_elements[1]);
#define TEST_ASSERT(cond)
#define TEST_CHECK_RET(_got, _exp)
void fr_event_service(fr_event_list_t *el)
Service any outstanding timer or file descriptor events.
int fr_event_corral(fr_event_list_t *el, fr_time_t now, bool wait)
Gather outstanding timer and file descriptor events.
fr_event_list_t * fr_event_list_alloc(TALLOC_CTX *ctx, fr_event_status_cb_t status, void *status_uctx)
Initialise a new event list.
Stores all information relating to an event list.
static fr_event_list_t * events
#define FR_SLAB_FUNCS(_name, _type)
Define type specific wrapper functions for slabs and slab elements.
#define FR_SLAB_TYPES(_name, _type)
Define type specific wrapper structs for slabs and slab elements.
unsigned int min_elements
Minimum number of elements to keep allocated.
unsigned int max_elements
Maximum number of elements to allocate using slabs.
bool at_max_fail
Should requests for additional elements fail when the number in use has reached max_elements.
unsigned int elements_per_slab
Number of elements to allocate per slab.
unsigned int num_children
How many child allocations are expected off each element.
size_t child_pool_size
Size of pool space to be allocated to each element.
bool allow_direct_free
Allow in-use elements to be freed with talloc_free.
Tuneable parameters for slabs.
static fr_time_t test_time(void)
static void test_clearup_3(void)
Test that repeated clearing frees more slabs.
static void test_reserve(void)
Test that a reserve callback correctly initialises slab elements.
static fr_time_t test_time_base
static void test_init_reserve(void)
Test that reserve callback runs after init callback.
static fr_slab_config_t def_slab_config
static void test_reserve_mru(void)
Test that setting reserve_mru to true works.
static void test_clearup_2(void)
Test that slab clearing does not go beyond the minimum.
static void test_reuse_noreset(void)
Test that freeing an element makes it available for reuse with the element not reset between uses.
static void test_child_alloc(void)
static int test_element_reserve(test_element_t *elem, void *uctx)
static void test_clearup_1(void)
Test of clearing unused slabs.
static void test_free(void)
Test that freeing an element results in the destructor being called, and that all accounting is corre...
static void test_alloc(void)
Test basic allocation and reservation of elements.
static void test_reuse_reset(void)
Test that freeing an element makes it available for reuse with the element reset between uses.
static int test_element_free(test_element_t *elem, void *uctx)
static void test_free_and_reserve(void)
Test that reserving after talloc_free of an element still works.
static void test_free_mixed(void)
Test mixed release and talloc_free of elements from the same slab.
static void test_init(void)
Test that a callback correctly initialises slab elements on first use.
static void test_bulk_teardown(void)
Test that talloc free of the slab list with in-use elements does not assert.
static void test_alloc_fail(void)
Test allocation beyond max fails correctly.
static int test_element_alloc(test_element_t *elem, void *uctx)
static void test_realloc(void)
Test that reserving after clearup results in new slab allocation.
static void test_free_multiple(void)
Test that talloc freeing multiple in-use elements correctly updates accounting.
static TALLOC_CTX * talloc_init_const(char const *name)
Allocate a top level chunk with a constant name.
#define talloc_strdup(_ctx, _str)
static fr_time_t fr_time_add_time_delta(fr_time_t a, fr_time_delta_t b)
static fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
#define fr_time_wrap(_time)
void fr_timer_list_set_time_func(fr_timer_list_t *tl, fr_event_time_source_t func)
Override event list time source.
static fr_event_list_t * el