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