blob: 9e6ac383860c53e17d9fe1279801747e26917068 [file] [log] [blame]
Olivier Houchardcea46c02019-09-23 17:42:42 +02001#include <pthread.h>
2#include <stdio.h>
3#include <stdlib.h>
4#define USE_THREAD
Willy Tarreau853b2972020-05-27 18:01:47 +02005#include <haproxy/list.h>
Olivier Houchardcea46c02019-09-23 17:42:42 +02006
7/* Stress test the mt_lists.
8 * Compile from the haproxy directory with :
Willy Tarreau38ceb552021-04-02 10:33:38 +02009 * cc -I../../include test-list.c -pthread -O2 -o test-list
Olivier Houchardcea46c02019-09-23 17:42:42 +020010 * The only argument it takes is the number of threads to be used.
11 * ./test-list 4
12 */
13
14struct mt_list pouet_list = MT_LIST_HEAD_INIT(pouet_list);
15#define MAX_ACTION 5000000
16
17__thread unsigned int tid;
18struct pouet_lol {
19 struct mt_list list_elt;
20};
21
22void *thread(void *pouet)
23{
24 struct pouet_lol *lol;
25 struct mt_list *elt1, elt2;
26 tid = (uintptr_t)pouet;
27 int i = 0;
28
29 for (int i = 0; i < MAX_ACTION; i++) {
30 struct pouet_lol *lol;
31 struct mt_list *elt1, elt2;
32 switch (random() % 4) {
33 case 0:
34 lol = malloc(sizeof(*lol));
35 MT_LIST_INIT(&lol->list_elt);
Willy Tarreau2b718102021-04-21 07:32:39 +020036 MT_LIST_TRY_INSERT(&pouet_list, &lol->list_elt);
Olivier Houchardcea46c02019-09-23 17:42:42 +020037 break;
38 case 1:
39 lol = malloc(sizeof(*lol));
40 MT_LIST_INIT(&lol->list_elt);
Willy Tarreau2b718102021-04-21 07:32:39 +020041 MT_LIST_TRY_APPEND(&pouet_list, &lol->list_elt);
Olivier Houchardcea46c02019-09-23 17:42:42 +020042 break;
43
44 case 2:
45 lol = MT_LIST_POP(&pouet_list, struct pouet_lol *, list_elt);
46 if (lol)
47 free(lol);
48 break;
49 case 3:
50
51 mt_list_for_each_entry_safe(lol, &pouet_list, list_elt, elt1, elt2)
52
53{
54 if (random() % 2) {
Willy Tarreau2b718102021-04-21 07:32:39 +020055 MT_LIST_DELETE_SAFE(elt1);
Olivier Houchardcea46c02019-09-23 17:42:42 +020056 free(lol);
57 }
58 if (random() % 2) {
59 break;
60 }
61 }
62 break;
63 default:
64 break;
65 }
66 }
67}
68
69int main(int argc, char *argv[])
70{
71 int nb;
72 pthread_t *pth;
73
74 srandom(time(NULL));
75 if (argc != 2) {
76 printf("Usage: %s <nb_threads>\n", argv[0]);
77 exit(1);
78 }
79 nb = atoi(argv[1]);
80#if 0
81 if (nb < 2) {
82 printf("Need at least 2 threads.\n");
83 exit(1);
84 }
85#endif
86 pth = malloc(nb * sizeof(*pth));
87 if (pth == NULL) {
88 printf("Shot failed to connect.\n");
89 exit(1);
90 }
91 for (int i = 0; i < nb; i++) {
92 pthread_create(&pth[i], NULL, thread, (void *)(uintptr_t)i);
93
94 }
95 for (int i = 0; i < nb; i++)
96 pthread_join(pth[i], NULL);
97 return 0;
98}