]> git.lizzy.rs Git - dragonstd.git/blob - test/test_refcount_map.c
Use void pointers for callback args
[dragonstd.git] / test / test_refcount_map.c
1 #include <assert.h>
2 #include <stdatomic.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <time.h>
6 #include <unistd.h>
7 #include <limits.h>
8 #include "../map.h"
9 #include "../refcount.h"
10
11 Map map;
12 atomic_bool cancel;
13
14 typedef struct {
15         int id;
16         Refcount rc;
17 } DataObject;
18
19 int rand_id()
20 {
21         return rand() % 1000;
22 }
23
24 void delete_obj(DataObject *obj)
25 {
26         refcount_dst(&obj->rc);
27         free(obj);
28 }
29
30 int cmp_obj(const Refcount *rc, const int *id)
31 {
32         return ((DataObject *) rc->obj)->id - *id;
33 }
34
35 int cmp_obj_sym(const Refcount *rc1, const Refcount *rc2)
36 {
37         return cmp_obj(rc1, &((DataObject *) rc2->obj)->id);
38 }
39
40 static void *thread_create(unsigned int *result)
41 {
42         while (!cancel) {
43                 DataObject *obj = malloc(sizeof *obj);
44                 obj->id = rand_id();
45
46                 refcount_ini(&obj->rc, obj, &delete_obj);
47
48                 if (map_add(&map, &obj->rc, &cmp_obj_sym, &refcount_inc))
49                         (*result)++;
50
51                 refcount_drp(&obj->rc);
52         }
53
54         return NULL;
55 }
56
57 #define NUM_OBJS 100
58
59 static void *thread_access(unsigned int *result)
60 {
61         DataObject *objs[NUM_OBJS] = {NULL};
62
63         while (!cancel) {
64                 int i = rand() % NUM_OBJS;
65
66                 if (objs[i]) {
67                         refcount_drp(&objs[i]->rc);
68                         objs[i] = NULL;
69                 }
70
71                 while (!objs[i] && !cancel) {
72                         int id = rand_id();
73                         objs[i] = map_get(&map, &id, &cmp_obj, &refcount_grb);
74                 }
75
76                 if (objs[i])
77                         (*result)++;
78         }
79
80         for (int i = 0; i < NUM_OBJS; i++)
81                 if (objs[i])
82                         refcount_drp(&objs[i]->rc);
83
84         return NULL;
85 }
86
87 #undef NUM_OBJS
88
89 static void *thread_delete(unsigned int *result)
90 {
91         while (!cancel) {
92                 unsigned int id = rand_id();
93
94                 if (map_del(&map, &id, &cmp_obj, &refcount_drp, NULL, NULL))
95                         (*result)++;
96         }
97
98         return NULL;
99 }
100
101 int main()
102 {
103         srand(time(NULL));
104
105         printf("------------------------\n");
106         printf("Testing Map and Refcount\n");
107         printf("------------------------\n");
108
109         map_ini(&map);
110
111         void *(*funcs[3])(void *) = {
112                 (void *) &thread_create,
113                 (void *) &thread_access,
114                 (void *) &thread_delete,
115         };
116
117         unsigned int results[3][5] = {0};
118         pthread_t threads[3][5] = {0};
119
120         for (int i = 0; i < 3; i++)
121                 for (int j = 0; j < 5; j++)
122                         pthread_create(&threads[i][j], NULL, funcs[i], &results[i][j]);
123
124         sleep(1);
125
126         cancel = true;
127         for (int i = 0; i < 3; i++)
128                 for (int j = 0; j < 5; j++) {
129                         pthread_join(threads[i][j], NULL);
130
131                         if (j)
132                                 results[i][0] += results[i][j];
133                 }
134
135         map_cnl(&map, &refcount_drp, NULL, NULL, 0);
136         map_dst(&map);
137
138         printf("Time: 1 second\n");
139         printf("Created objects: %u\n", results[0][0]);
140         printf("Accessed objects: %u\n", results[1][0]);
141         printf("Deleted objects: %u\n", results[2][0]);
142 }