The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
lst_tests.c
Go to the documentation of this file.
1#include "acutest.h"
2#include"acutest_helpers.h"
3#include <freeradius-devel/util/rand.h>
4#include <freeradius-devel/util/time.h>
5#include <freeradius-devel/util/heap.h>
6
7/*
8 * This counterintuitive #include gives these separately-compiled tests
9 * access to fr_lst_t internals that lst.h doesn't reveal
10 * to those who #include it.
11 */
12#include "../lst.c"
13
14typedef struct {
15 unsigned int data;
17 bool visited; /* Only used by iterator test */
18} lst_thing;
19
20#if 0
21static void lst_validate(fr_lst_t *lst);
22#endif
23
24static bool fr_lst_contains(fr_lst_t *lst, void *data)
25{
26 unsigned int size = fr_lst_num_elements(lst);
27
28 for (unsigned int i = 0; i < size; i++) if (item(lst, i + lst->idx) == data) return true;
29
30 return false;
31}
32
33static int8_t lst_cmp(void const *one, void const *two)
34{
35 lst_thing const *item1 = one, *item2 = two;
36
37 return CMP(item1->data, item2->data);
38}
39
40static void populate_values(lst_thing values[], unsigned int len)
41{
42 unsigned int i;
43 fr_fast_rand_t rand_ctx;
44
45 for (i = 0; i < len; i++) {
46 values[i].data = i;
47 values[i].idx = 0;
48 values[i].visited = false;
49 }
50
51 /* shuffle values before insertion, so the heap has to work to give them back in order */
52 rand_ctx.a = fr_rand();
53 rand_ctx.b = fr_rand();
54
55 for (i = 0; i < len; i++) {
56 unsigned int j = fr_fast_rand(&rand_ctx) % len;
57 int temp = values[i].data;
58
59 values[i].data = values[j].data;
60 values[j].data = temp;
61 }
62}
63
64#define NVALUES 20
65static void lst_test_basic(void)
66{
67 fr_lst_t *lst;
68 lst_thing values[NVALUES];
69
70 lst = fr_lst_alloc(NULL, lst_cmp, lst_thing, idx, NVALUES);
71 TEST_ASSERT(lst != NULL);
72
73 populate_values(values, NUM_ELEMENTS(values));
74
75 for (unsigned int i = 0; i < NUM_ELEMENTS(values); i++) {
76 TEST_CHECK(fr_lst_insert(lst, &values[i]) >= 0);
77 TEST_CHECK(fr_lst_entry_inserted(values[i].idx));
78 }
79
80 for (unsigned int i = 0; i < NUM_ELEMENTS(values); i++) {
82
83 TEST_CHECK(value != NULL);
85 TEST_CHECK(value->data == i);
86 TEST_MSG("iteration %u, popped %u", i, value->data);
87 }
88 talloc_free(lst);
89}
90
91#define LST_TEST_SIZE (4096)
92
93static void lst_test(int skip)
94{
95 fr_lst_t *lst;
96 int i;
97 lst_thing *values;
98 int left;
99 int ret;
100
101 lst = fr_lst_alloc(NULL, lst_cmp, lst_thing, idx, 0);
102 TEST_ASSERT(lst != NULL);
103
104 values = calloc(LST_TEST_SIZE, sizeof(lst_thing));
105
106 /*
107 * Initialise random values
108 */
110
111 TEST_CASE("insertions");
112 for (i = 0; i < LST_TEST_SIZE; i++) {
113 FR_LST_VERIFY(lst);
114 TEST_CHECK((ret = fr_lst_insert(lst, &values[i])) >= 0);
115 TEST_MSG("insert failed, returned %i - %s", ret, fr_strerror());
116
117 TEST_CHECK(fr_lst_contains(lst, &values[i]));
118 TEST_MSG("element %i inserted but not in LST", i);
119 }
120
121 TEST_CASE("deletions");
122 for (int entry = 0; entry < LST_TEST_SIZE; entry += skip) {
123 FR_LST_VERIFY(lst);
124 TEST_CHECK(values[entry].idx != 0);
125 TEST_MSG("element %i removed out of order", entry);
126
127 TEST_CHECK((ret = fr_lst_extract(lst, &values[entry])) >= 0);
128 TEST_MSG("element %i removal failed, returned %i", entry, ret);
129
130 TEST_CHECK(!fr_lst_contains(lst, &values[entry]));
131 TEST_MSG("element %i removed but still in LST", entry);
132
133 TEST_CHECK(values[entry].idx == 0);
134 TEST_MSG("element %i removed out of order", entry);
135 }
136
137 left = fr_lst_num_elements(lst);
138 for (i = 0; i < left; i++) {
139 FR_LST_VERIFY(lst);
140 TEST_CHECK(fr_lst_pop(lst) != NULL);
141 TEST_MSG("expected %i elements remaining in the lst", left - i);
142 TEST_MSG("failed extracting %i", i);
143 }
144
145 TEST_CHECK((ret = fr_lst_num_elements(lst)) == 0);
146 TEST_MSG("%i elements remaining", ret);
147
148 talloc_free(lst);
149 free(values);
150}
151
152static void lst_test_skip_1(void)
153{
154 lst_test(1);
155}
156
157static void lst_test_skip_2(void)
158{
159 lst_test(2);
160}
161
162static void lst_test_skip_10(void)
163{
164 lst_test(10);
165}
166
167
168static void lst_stress_realloc(void)
169{
170 fr_lst_t *lst;
171 fr_heap_t *hp;
172 lst_thing *lst_array, *hp_array;
173 fr_fast_rand_t rand_ctx;
174 int ret;
175 lst_thing *from_lst, *from_hp;
176
177 rand_ctx.a = fr_rand();
178 rand_ctx.b = fr_rand();
179
180 lst = fr_lst_alloc(NULL, lst_cmp, lst_thing, idx, 0);
181 TEST_ASSERT(lst != NULL);
182 hp = fr_heap_alloc(NULL, lst_cmp, lst_thing, idx, 0);
183 TEST_ASSERT(hp != NULL);
184
185 lst_array = calloc(2 * INITIAL_CAPACITY, sizeof(lst_thing));
186 hp_array = calloc(2 * INITIAL_CAPACITY, sizeof(lst_thing));
187
188 /*
189 * Initialise random values
190 */
191 for (unsigned int i = 0; i < 2 * INITIAL_CAPACITY; i++) {
192 lst_array[i].data = hp_array[i].data = fr_fast_rand(&rand_ctx) % 65537;
193 }
194
195 /* Add the first INITIAL_CAPACITY values to lst and to hp */
196 TEST_CASE("partial fill");
197 for (int i = 0; i < INITIAL_CAPACITY; i++) {
198 TEST_CHECK((ret = fr_lst_insert(lst, &lst_array[i])) >= 0);
199 TEST_MSG("lst insert failed, iteration %d; returned %i - %s", i, ret, fr_strerror());
200 TEST_CHECK((ret = fr_heap_insert(&hp, &hp_array[i])) >= 0);
201 TEST_MSG("heap insert failed, iteration %d; returned %i - %s", i, ret, fr_strerror());
202 }
203
204 /* Pop INITIAL_CAPACITY / 2 values from each (they should all be equal) */
205 TEST_CASE("partial pop");
206 for (unsigned int i = 0; i < INITIAL_CAPACITY / 2; i++) {
207 TEST_CHECK((from_lst = fr_lst_pop(lst)) != NULL);
208 TEST_CHECK((from_hp = fr_heap_pop(&hp)) != NULL);
209 TEST_CHECK(lst_cmp(from_lst, from_hp) == 0);
210 }
211
212 /*
213 * Add the second INITIAL_CAPACITY values to lst and to hp.
214 * This should force lst to move entries to maintain adjacency,
215 * which is what we're testing here.
216 */
217 TEST_CASE("force move with expansion");
218 for (unsigned int i = INITIAL_CAPACITY; i < 2 * INITIAL_CAPACITY; i++) {
219 TEST_CHECK((ret = fr_lst_insert(lst, &lst_array[i])) >= 0);
220 TEST_MSG("lst insert failed, iteration %u; returned %i - %s", i, ret, fr_strerror());
221 TEST_CHECK((ret = fr_heap_insert(&hp, &hp_array[i])) >= 0);
222 TEST_MSG("heap insert failed, iteration %u; returned %i - %s", i, ret, fr_strerror());
223 }
224
225 /* pop the remaining 3 * INITIAL_CAPACITY / 2 values from each (they should all be equal) */
226 TEST_CASE("complete pop");
227 for (unsigned int i = 0; i < 3 * INITIAL_CAPACITY / 2; i++) {
228 TEST_CHECK((from_lst = fr_lst_pop(lst)) != NULL);
229 TEST_CHECK((from_hp = fr_heap_pop(&hp)) != NULL);
230 TEST_CHECK(lst_cmp(from_lst, from_hp) == 0);
231 }
232
235
236 talloc_free(lst);
237 talloc_free(hp);
238 free(lst_array);
239 free(hp_array);
240}
241
242#define BURN_IN_OPS (10000000)
243
244static void lst_burn_in(void)
245{
246 fr_lst_t *lst = NULL;
247 lst_thing *array = NULL;
248 fr_fast_rand_t rand_ctx;
249 int insert_count = 0;
250
251 rand_ctx.a = fr_rand();
252 rand_ctx.b = fr_rand();
253
254 array = calloc(BURN_IN_OPS, sizeof(lst_thing));
255 for (unsigned int i = 0; i < BURN_IN_OPS; i++) array[i].data = fr_fast_rand(&rand_ctx) % 65537;
256
257 /* Make init small to exercise growing the pivot stack. */
258 lst = fr_lst_alloc(NULL, lst_cmp, lst_thing, idx, 32);
259
260 for (unsigned int i = 0; i < BURN_IN_OPS; i++) {
261 lst_thing *ret_thing = NULL;
262 int ret_insert = -1;
263
264 if (fr_lst_num_elements(lst) == 0) {
265 insert:
266 TEST_CHECK((ret_insert = fr_lst_insert(lst, &array[insert_count])) >= 0);
267 insert_count++;
268 } else {
269 switch (fr_fast_rand(&rand_ctx) % 3) {
270 case 0: /* insert */
271 goto insert;
272
273 case 1: /* pop */
274 ret_thing = fr_lst_pop(lst);
275 TEST_CHECK(ret_thing != NULL);
276 break;
277 case 2: /* peek */
278 ret_thing = fr_lst_peek(lst);
279 TEST_CHECK(ret_thing != NULL);
280 break;
281 }
282 }
283 }
284
285 talloc_free(lst);
286 free(array);
287}
288
289#define LST_CYCLE_SIZE (1600000)
290
291static void lst_cycle(void)
292{
293 fr_lst_t *lst;
294 int i;
295 lst_thing *values;
296 int to_remove;
297 int inserted, removed;
298 int ret;
299 fr_time_t start_insert, start_remove, start_swap, end;
300
301 lst = fr_lst_alloc(NULL, lst_cmp, lst_thing, idx, 0);
302 TEST_ASSERT(lst != NULL);
303
304 values = calloc(LST_CYCLE_SIZE, sizeof(lst_thing));
305
306 /*
307 * Initialise random values
308 */
310
311 start_insert = fr_time();
312 TEST_CASE("insertions");
313 for (i = 0; i < LST_CYCLE_SIZE; i++) {
314 TEST_CHECK((ret = fr_lst_insert(lst, &values[i])) >= 0);
315 TEST_MSG("insert failed, returned %i - %s", ret, fr_strerror());
316 }
318
319 TEST_CASE("pop");
320
321 /*
322 * Remove a random number of elements from the LST
323 */
324 to_remove = fr_lst_num_elements(lst) / 2;
325 start_remove = fr_time();
326 for (i = 0; i < to_remove; i++) {
327 TEST_CHECK(fr_lst_pop(lst) != NULL);
328 TEST_MSG("failed extracting %i", i);
329 TEST_MSG("expected %i elements remaining in the LST", to_remove - i);
330 }
331
332 /*
333 * Now swap the inserted and removed set creating churn
334 */
335 start_swap = fr_time();
336
337 inserted = 0;
338 removed = 0;
339
340 for (i = 0; i < LST_CYCLE_SIZE; i++) {
341 if (values[i].idx == 0) {
342 TEST_CHECK((ret = fr_lst_insert(lst, &values[i])) >= 0);
343 TEST_MSG("insert failed, returned %i - %s", ret, fr_strerror());
344 inserted++;
345 } else {
346 TEST_CHECK((ret = fr_lst_extract(lst, &values[i])) >= 0);
347 TEST_MSG("element %i removal failed, returned %i", i, ret);
348 removed++;
349 }
350 }
351
352 TEST_CHECK(removed == (LST_CYCLE_SIZE - to_remove));
353 TEST_MSG("expected %i", LST_CYCLE_SIZE - to_remove);
354 TEST_MSG("got %i", removed);
355
356 TEST_CHECK(inserted == to_remove);
357 TEST_MSG("expected %i", to_remove);
358 TEST_MSG("got %i", inserted);
359
360 end = fr_time();
361
362 TEST_MSG_ALWAYS("\ncycle size: %d\n", LST_CYCLE_SIZE);
363 TEST_MSG_ALWAYS("insert: %.2fs\n", fr_time_delta_unwrap(fr_time_sub(start_remove, start_insert)) / (double)NSEC);
364 TEST_MSG_ALWAYS("extract: %.2fs\n", fr_time_delta_unwrap(fr_time_sub(start_swap, start_remove)) / (double)NSEC);
365 TEST_MSG_ALWAYS("swap: %.2fs\n", fr_time_delta_unwrap(fr_time_sub(end, start_swap)) / (double)NSEC);
366
367 talloc_free(lst);
368 free(values);
369}
370
371static void lst_iter(void)
372{
373 fr_lst_t *lst;
374 fr_lst_iter_t iter;
375 lst_thing values[NVALUES], *data;
376 unsigned int total;
377
378 lst = fr_lst_alloc(NULL, lst_cmp, lst_thing, idx, 0);
379 TEST_ASSERT(lst != NULL);
380
381 populate_values(values, NUM_ELEMENTS(values));
382
383 for (unsigned int i = 0; i < NUM_ELEMENTS(values); i++) TEST_CHECK(fr_lst_insert(lst, &values[i]) == 0);
384
385 data = fr_lst_iter_init(lst, &iter);
386
387 for (unsigned int i = 0; i < NUM_ELEMENTS(values); i++, data = fr_lst_iter_next(lst, &iter)) {
388 TEST_CHECK(data != NULL);
389 TEST_CHECK(!data->visited);
390 TEST_CHECK(data->idx > 0);
391 data->visited = true;
392 }
393
394 TEST_CHECK(data == NULL);
395
396 total = 0;
398 total += item->data;
399 }}
400 TEST_CHECK(total == 190);
401
403}
404
405static CC_HINT(noinline) lst_thing *array_pop(lst_thing **array, unsigned int count)
406{
407 lst_thing *low = NULL;
408 unsigned int idx = 0;
409
410 for (unsigned int j = 0; j < count; j++) {
411 if (!array[j]) continue;
412
413 if (!low || (lst_cmp(array[j], low) < 0)) {
414 idx = j;
415 low = array[j];
416 }
417 }
418 if (low) array[idx] = NULL;
419
420 return low;
421}
422
423/** Benchmarks for LSTs vs heaps when used as queues
424 *
425 */
426static void queue_cmp(unsigned int count)
427{
428 fr_lst_t *lst;
429 fr_heap_t *hp;
430
431 lst_thing *values;
432
433 unsigned int i;
434
435 values = talloc_array(NULL, lst_thing, count);
436
437 /*
438 * Check times for LST alloc, insert, pop
439 */
440 {
441 fr_time_t start_alloc, end_alloc, start_insert, end_insert, start_pop, end_pop, end_pop_first = fr_time_wrap(0);
442
443 populate_values(values, count);
444
445 start_alloc = fr_time();
446 lst = fr_lst_alloc(NULL, lst_cmp, lst_thing, idx, 0);
447 end_alloc = fr_time();
448 TEST_ASSERT(lst != NULL);
449
450 start_insert = fr_time();
451 for (i = 0; i < count; i++) TEST_CHECK(fr_lst_insert(lst, &values[i]) == 0);
452 end_insert = fr_time();
453
454 start_pop = fr_time();
455 for (i = 0; i < count; i++) {
456 TEST_CHECK(fr_lst_pop(lst) != NULL);
457 if (i == 0) end_pop_first = fr_time();
458
459 TEST_MSG("expected %u elements remaining in the lst", count - i);
460 TEST_MSG("failed extracting %u", i);
461 }
462 end_pop = fr_time();
463
464 TEST_MSG_ALWAYS("\nlst size: %u\n", count);
465 TEST_MSG_ALWAYS("alloc: %"PRId64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_alloc, start_alloc)) / 1000);
466 TEST_MSG_ALWAYS("insert: %"PRId64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_insert, start_insert)) / 1000);
467 TEST_MSG_ALWAYS("pop-first: %"PRId64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_pop_first, start_pop)) / 1000);
468 TEST_MSG_ALWAYS("pop: %"PRId64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_pop, start_pop)) / 1000);
469
470 talloc_free(lst);
471 }
472
473 /*
474 * Check times for heap alloc, insert, pop
475 */
476 {
477 fr_time_t start_alloc, end_alloc, start_insert, end_insert, start_pop, end_pop, end_pop_first = fr_time_wrap(0);
478
479 populate_values(values, count);
480
481 start_alloc = fr_time();
482 hp = fr_heap_alloc(NULL, lst_cmp, lst_thing, idx, count);
483 end_alloc = fr_time();
484 TEST_ASSERT(hp != NULL);
485
486 start_insert = fr_time();
487 for (i = 0; i < count; i++) fr_heap_insert(&hp, &values[i]);
488 end_insert = fr_time();
489
490 start_pop = fr_time();
491 for (i = 0; i < count; i++) {
492 TEST_CHECK(fr_heap_pop(&hp) != NULL);
493 if (i == 0) end_pop_first = fr_time();
494
495 TEST_MSG("expected %u elements remaining in the heap", count - i);
496 TEST_MSG("failed extracting %u", i);
497 }
498 end_pop = fr_time();
499
500 TEST_MSG_ALWAYS("\nheap size: %u\n", count);
501 TEST_MSG_ALWAYS("alloc: %"PRId64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_alloc, start_alloc)) / 1000);
502 TEST_MSG_ALWAYS("insert: %"PRId64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_insert, start_insert)) / 1000);
503 TEST_MSG_ALWAYS("pop-first: %"PRId64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_pop_first, start_pop)) / 1000);
504 TEST_MSG_ALWAYS("pop: %"PRId64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_pop, start_pop)) / 1000);
505
506 talloc_free(hp);
507 }
508
509 /*
510 * Array
511 */
512 {
513 lst_thing **array;
514 fr_time_t start_alloc, end_alloc, start_insert, end_insert, start_pop, end_pop, end_pop_first;
515
516 populate_values(values, count);
517 end_pop_first = fr_time_wrap(0);
518
519 start_alloc = fr_time();
520 array = talloc_array(NULL, lst_thing *, count);
521 end_alloc = fr_time();
522
523 start_insert = fr_time();
524 for (i = 0; i < count; i++) array[i] = &values[i];
525 end_insert = fr_time();
526
527 start_pop = fr_time();
528 for (i = 0; i < count; i++) {
529 TEST_CHECK(array_pop(array, count) != NULL);
530 if (i == 0) end_pop_first = fr_time();
531 }
532 end_pop = fr_time();
533
534 TEST_MSG_ALWAYS("\narray size: %u\n", count);
535 TEST_MSG_ALWAYS("alloc: %"PRId64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_alloc, start_alloc)) / 1000);
536 TEST_MSG_ALWAYS("insert: %"PRId64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_insert, start_insert)) / 1000);
537 TEST_MSG_ALWAYS("pop-first: %"PRId64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_pop_first, start_pop)) / 1000);
538 TEST_MSG_ALWAYS("pop: %"PRId64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_pop, start_pop)) / 1000);
539
540 talloc_free(array);
541 }
542
543 talloc_free(values);
544}
545
546static void queue_cmp_10(void)
547{
548 queue_cmp(10);
549}
550
551static void queue_cmp_50(void)
552{
553 queue_cmp(50);
554}
555
556static void queue_cmp_100(void)
557{
558 queue_cmp(100);
559}
560
561static void queue_cmp_1000(void)
562{
563 queue_cmp(1000);
564}
565
567 /*
568 * Basic tests
569 */
570 { "lst_test_basic", lst_test_basic },
571 { "lst_test_skip_1", lst_test_skip_1 },
572 { "lst_test_skip_2", lst_test_skip_2 },
573 { "lst_test_skip_10", lst_test_skip_10 },
574 { "lst_stress_realloc", lst_stress_realloc },
575 { "lst_burn_in", lst_burn_in },
576 { "lst_cycle", lst_cycle },
577 { "lst_iter", lst_iter },
578 { "queue_cmp_10", queue_cmp_10 },
579 { "queue_cmp_50", queue_cmp_50 },
580 { "queue_cmp_100", queue_cmp_100 },
581 { "queue_cmp_1000", queue_cmp_1000 },
583};
#define TEST_MSG_ALWAYS(...)
Definition acutest.h:224
#define TEST_CHECK(cond)
Definition acutest.h:87
#define TEST_CASE(name)
Definition acutest.h:186
#define TEST_ASSERT(cond)
Definition acutest.h:110
#define TEST_TERMINATOR
Definition acutest.h:64
#define TEST_MSG(...)
Definition acutest.h:217
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
Definition build.h:112
#define NUM_ELEMENTS(_t)
Definition build.h:339
Test enumeration values.
Definition dict_test.h:92
#define INITIAL_CAPACITY
Definition heap.c:31
int fr_heap_insert(fr_heap_t **hp, void *data)
Insert a new element into the heap.
Definition heap.c:146
void * fr_heap_pop(fr_heap_t **hp)
Remove a node from the heap.
Definition heap.c:325
#define fr_heap_alloc(_ctx, _cmp, _type, _field, _init)
Creates a heap that can be used with non-talloced elements.
Definition heap.h:100
static unsigned int fr_heap_num_elements(fr_heap_t *h)
Return the number of elements in the heap.
Definition heap.h:179
The main heap structure.
Definition heap.h:66
free(array)
#define fr_time()
Definition event.c:60
void * fr_lst_iter_next(fr_lst_t *lst, fr_lst_iter_t *iter)
Get the next entry in an LST.
Definition lst.c:785
int fr_lst_extract(fr_lst_t *lst, void *data)
Remove an element from an LST.
Definition lst.c:715
void * fr_lst_iter_init(fr_lst_t *lst, fr_lst_iter_t *iter)
Iterate over entries in LST.
Definition lst.c:766
static void * item(fr_lst_t const *lst, fr_lst_index_t idx)
Definition lst.c:122
void * fr_lst_pop(fr_lst_t *lst)
Definition lst.c:695
fr_lst_index_t idx
Starting index, initially zero.
Definition lst.c:62
int fr_lst_insert(fr_lst_t *lst, void *data)
Definition lst.c:731
unsigned int fr_lst_num_elements(fr_lst_t *lst)
Definition lst.c:750
void * fr_lst_peek(fr_lst_t *lst)
Definition lst.c:701
Definition lst.c:60
#define FR_LST_VERIFY(_lst)
Definition lst.h:114
#define fr_lst_alloc(_ctx, _cmp, _type, _field, _init)
Creates an LST that can be used with non-talloced elements.
Definition lst.h:60
static bool fr_lst_entry_inserted(fr_lst_index_t lst_id)
Check if an entry is inserted into an LST.
Definition lst.h:92
fr_lst_index_t fr_lst_iter_t
Definition lst.h:46
unsigned int fr_lst_index_t
Definition lst.h:44
#define fr_lst_foreach(_lst, _type, _data)
Iterate over the contents of an LST.
Definition lst.h:135
static void queue_cmp_100(void)
Definition lst_tests.c:556
static void queue_cmp(unsigned int count)
Benchmarks for LSTs vs heaps when used as queues.
Definition lst_tests.c:426
TEST_LIST
Definition lst_tests.c:566
static lst_thing * array_pop(lst_thing **array, unsigned int count)
Definition lst_tests.c:405
static void lst_test_skip_10(void)
Definition lst_tests.c:162
#define NVALUES
Definition lst_tests.c:64
static void lst_test(int skip)
Definition lst_tests.c:93
unsigned int data
Definition lst_tests.c:15
static int8_t lst_cmp(void const *one, void const *two)
Definition lst_tests.c:33
#define LST_TEST_SIZE
Definition lst_tests.c:91
#define BURN_IN_OPS
Definition lst_tests.c:242
fr_lst_index_t idx
Definition lst_tests.c:16
static void queue_cmp_50(void)
Definition lst_tests.c:551
static void lst_cycle(void)
Definition lst_tests.c:291
static void lst_burn_in(void)
Definition lst_tests.c:244
static void lst_test_basic(void)
Definition lst_tests.c:65
static void lst_iter(void)
Definition lst_tests.c:371
#define LST_CYCLE_SIZE
Definition lst_tests.c:289
static void queue_cmp_1000(void)
Definition lst_tests.c:561
static void lst_test_skip_2(void)
Definition lst_tests.c:157
static void queue_cmp_10(void)
Definition lst_tests.c:546
static bool fr_lst_contains(fr_lst_t *lst, void *data)
Definition lst_tests.c:24
static void lst_test_skip_1(void)
Definition lst_tests.c:152
static void lst_stress_realloc(void)
Definition lst_tests.c:168
static void populate_values(lst_thing values[], unsigned int len)
Definition lst_tests.c:40
bool visited
Definition lst_tests.c:17
talloc_free(lst)
uint32_t fr_fast_rand(fr_fast_rand_t *ctx)
Definition rand.c:279
uint32_t fr_rand(void)
Return a 32-bit random number.
Definition rand.c:105
uint32_t b
Definition rand.h:55
uint32_t a
Definition rand.h:55
Smaller fast random number generator.
Definition rand.h:54
return count
Definition module.c:155
static int64_t fr_time_delta_unwrap(fr_time_delta_t time)
Definition time.h:154
#define fr_time_wrap(_time)
Definition time.h:145
#define NSEC
Definition time.h:379
#define fr_time_sub(_a, _b)
Subtract one time from another.
Definition time.h:229
"server local" time.
Definition time.h:69
char const * fr_strerror(void)
Get the last library error.
Definition strerror.c:553
static fr_slen_t data
Definition value.h:1340