]> git.lizzy.rs Git - dragonstd.git/blob - test/test_refcount_map.c
Add key to add functions
[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 static void *thread_create(unsigned int *result)
36 {
37         while (!cancel) {
38                 DataObject *obj = malloc(sizeof *obj);
39                 obj->id = rand_id();
40
41                 refcount_ini(&obj->rc, obj, &delete_obj);
42
43                 if (map_add(&map, &obj->id, &obj->rc, &cmp_obj, &refcount_inc))
44                         (*result)++;
45
46                 refcount_drp(&obj->rc);
47         }
48
49         return NULL;
50 }
51
52 #define NUM_OBJS 100
53
54 static void *thread_access(unsigned int *result)
55 {
56         DataObject *objs[NUM_OBJS] = {NULL};
57
58         while (!cancel) {
59                 int i = rand() % NUM_OBJS;
60
61                 if (objs[i]) {
62                         refcount_drp(&objs[i]->rc);
63                         objs[i] = NULL;
64                 }
65
66                 while (!objs[i] && !cancel) {
67                         int id = rand_id();
68                         objs[i] = map_get(&map, &id, &cmp_obj, &refcount_grb);
69                 }
70
71                 if (objs[i])
72                         (*result)++;
73         }
74
75         for (int i = 0; i < NUM_OBJS; i++)
76                 if (objs[i])
77                         refcount_drp(&objs[i]->rc);
78
79         return NULL;
80 }
81
82 #undef NUM_OBJS
83
84 static void *thread_delete(unsigned int *result)
85 {
86         while (!cancel) {
87                 unsigned int id = rand_id();
88
89                 if (map_del(&map, &id, &cmp_obj, &refcount_drp, NULL, NULL))
90                         (*result)++;
91         }
92
93         return NULL;
94 }
95
96 int main()
97 {
98         srand(time(NULL));
99
100         printf("------------------------\n");
101         printf("Testing Map and Refcount\n");
102         printf("------------------------\n");
103
104         map_ini(&map);
105
106         void *(*funcs[3])(void *) = {
107                 (void *) &thread_create,
108                 (void *) &thread_access,
109                 (void *) &thread_delete,
110         };
111
112         unsigned int results[3][5] = {0};
113         pthread_t threads[3][5] = {0};
114
115         for (int i = 0; i < 3; i++)
116                 for (int j = 0; j < 5; j++)
117                         pthread_create(&threads[i][j], NULL, funcs[i], &results[i][j]);
118
119         sleep(1);
120
121         cancel = true;
122         for (int i = 0; i < 3; i++)
123                 for (int j = 0; j < 5; j++) {
124                         pthread_join(threads[i][j], NULL);
125
126                         if (j)
127                                 results[i][0] += results[i][j];
128                 }
129
130         map_cnl(&map, &refcount_drp, NULL, NULL, 0);
131         map_dst(&map);
132
133         printf("Time: 1 second\n");
134         printf("Created objects: %u\n", results[0][0]);
135         printf("Accessed objects: %u\n", results[1][0]);
136         printf("Deleted objects: %u\n", results[2][0]);
137 }