haproxy/tests/unit/test-list.c
Willy Tarreau 6cbb5a057b Revert "MAJOR: import: update mt_list to support exponential back-off"
This reverts commit c618ed5ff4.

The list iterator is broken. As found by Fred, running QUIC single-
threaded shows that only the first connection is accepted because the
accepter relies on the element being initialized once detached (which
is expected and matches what MT_LIST_DELETE_SAFE() used to do before).
However while doing this in the quic_sock code seems to work, doing it
inside the macro show total breakage and the unit test doesn't work
anymore (random crashes). Thus it looks like the fix is not trivial,
let's roll this back for the time it will take to fix the loop.
2023-09-15 17:13:43 +02:00

99 lines
1.9 KiB
C

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define USE_THREAD
#include <haproxy/list.h>
/* Stress test the mt_lists.
* Compile from the haproxy directory with :
* cc -I../../include test-list.c -pthread -O2 -o test-list
* The only argument it takes is the number of threads to be used.
* ./test-list 4
*/
struct mt_list pouet_list = MT_LIST_HEAD_INIT(pouet_list);
#define MAX_ACTION 5000000
__thread unsigned int tid;
struct pouet_lol {
struct mt_list list_elt;
};
void *thread(void *pouet)
{
struct pouet_lol *lol;
struct mt_list *elt1, elt2;
tid = (uintptr_t)pouet;
int i = 0;
for (int i = 0; i < MAX_ACTION; i++) {
struct pouet_lol *lol;
struct mt_list *elt1, elt2;
switch (random() % 4) {
case 0:
lol = malloc(sizeof(*lol));
MT_LIST_INIT(&lol->list_elt);
MT_LIST_TRY_INSERT(&pouet_list, &lol->list_elt);
break;
case 1:
lol = malloc(sizeof(*lol));
MT_LIST_INIT(&lol->list_elt);
MT_LIST_TRY_APPEND(&pouet_list, &lol->list_elt);
break;
case 2:
lol = MT_LIST_POP(&pouet_list, struct pouet_lol *, list_elt);
if (lol)
free(lol);
break;
case 3:
mt_list_for_each_entry_safe(lol, &pouet_list, list_elt, elt1, elt2)
{
if (random() % 2) {
MT_LIST_DELETE_SAFE(elt1);
free(lol);
}
if (random() % 2) {
break;
}
}
break;
default:
break;
}
}
}
int main(int argc, char *argv[])
{
int nb;
pthread_t *pth;
srandom(time(NULL));
if (argc != 2) {
printf("Usage: %s <nb_threads>\n", argv[0]);
exit(1);
}
nb = atoi(argv[1]);
#if 0
if (nb < 2) {
printf("Need at least 2 threads.\n");
exit(1);
}
#endif
pth = malloc(nb * sizeof(*pth));
if (pth == NULL) {
printf("Shot failed to connect.\n");
exit(1);
}
for (int i = 0; i < nb; i++) {
pthread_create(&pth[i], NULL, thread, (void *)(uintptr_t)i);
}
for (int i = 0; i < nb; i++)
pthread_join(pth[i], NULL);
return 0;
}