6d539349bb109186e24c77dee48c2f46f5919480
[acogc] / tests / test-acogc.c
1 /*
2   test-acogc.c - simple accurate/cooperative garbage collector
3
4   Copyright (C) 2006, Christian Thaeter <chth@gmx.net>
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License version 2 as
8   published by the Free Software Foundation.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program; if not, contact me.
17
18 */
19
20 #include <stdlib.h>
21 #include <assert.h>
22 #include <stdio.h>
23 #include <string.h>
24
25 #include "../lib/acogc.h"
26
27 struct object
28 {
29   int notused;
30   struct object* ptra;
31   struct object* ptrb;
32   //llist foo;
33   int test;
34   char pad[20];
35 };
36
37 void
38 object_init_acogc (void* obj)
39 {
40   struct object* o = obj;
41   o->ptra = NULL;
42   o->ptrb = NULL;
43   //llist_init (&o->foo);
44 }
45
46 acogc_mark_result
47 object_mark_acogc (void* obj)
48 {
49   struct object* o = obj;
50   acogc_object_mark (o->ptra);
51   acogc_object_mark (o->ptrb);
52   //if (!llist_is_empty (&o->foo))
53   //  acogc_object_mark (LLIST_TO_STRUCTP (&o->foo, struct object, foo));
54   return ACOGC_KEEP;
55 }
56
57 acogc_root gcroot;
58 acogc_factory gcfactory;
59
60 //ACOGC_OBJECT (UNCOLLECTABLE_NONFINALIZEABLE, &gcfactory, struct object, testobjectglobal, {345, NULL, NULL, LLIST_INITIALIZER(testobjectglobal_acogc.object.foo), 123, "test"});
61
62 ACOGC_OBJECT (UNCOLLECTABLE_NONFINALIZEABLE, &gcfactory, struct object, testobjectglobal, {345, NULL, NULL, 123, "test"});
63
64
65 void init()
66 {
67   acogc_root_init(&gcroot);
68
69   acogc_factory_init(&gcfactory,
70                      &gcroot,
71                      sizeof(struct object),
72                      25,
73                      50,
74                      (acogc_mark_func)object_mark_acogc,
75                      (acogc_initize_func)object_init_acogc,
76                      NULL);
77 }
78
79 int main(int argc, char* argv[])
80 {
81   struct object* obj;
82   struct object* obj1;
83   struct object* obj2;
84
85   acogc_nobug_init();
86
87   if (argc != 2)
88     {
89       printf("ERROR\n");
90       exit(1);
91     }
92
93   if (strcmp(argv[1], "INIT") == 0)
94     {
95       printf("init\n");
96       init ();
97     }
98   else if (strcmp(argv[1], "INIT_EMPTY_ERASE") == 0)
99     {
100       printf("init-empty-erase\n");
101       init ();
102       acogc_root_erase (&gcroot);
103     }
104   else if (strcmp(argv[1], "ERASE_SOME_OBJECTS") == 0)
105     {
106       printf("erase\n");
107       init ();
108       obj = acogc_factory_alloc (&gcfactory);
109       acogc_addroot (obj);
110       NOTICE (NOBUG_ON, "allocated %p", obj);
111
112       obj2 = acogc_factory_alloc (&gcfactory);
113       obj->ptra = obj2;
114       NOTICE (NOBUG_ON, "allocated %p", obj2);
115
116       for (int j = 0; j < 1000; ++j)
117         {
118           obj1 = acogc_factory_alloc (&gcfactory);
119           obj2->ptra = obj1;
120           NOTICE (NOBUG_ON, "allocated %p", obj1);
121
122           obj2 = acogc_factory_alloc (&gcfactory);
123           obj1->ptra = obj2;
124           NOTICE (NOBUG_ON, "allocated %p", obj2);
125         }
126       acogc_removeroot (obj);
127
128       acogc_root_erase (&gcroot);
129     }
130   else if (strcmp(argv[1], "RANDOM") == 0)
131     {
132       printf("random\n");
133       init ();
134       obj = acogc_factory_alloc (&gcfactory);
135       acogc_addroot (obj);
136       NOTICE (NOBUG_ON, "allocated %p", obj);
137
138       obj2 = acogc_factory_alloc (&gcfactory);
139       acogc_addroot (obj2);
140       obj->ptra = obj2;
141       NOTICE (NOBUG_ON, "allocated %p", obj2);
142
143       for (int j = 0; j < 1000; ++j)
144         {
145           obj1 = acogc_factory_alloc (&gcfactory);
146           acogc_addroot (obj1);
147           if (rand()%2)
148             obj2->ptra = obj1;
149           if (rand()%2)
150             obj2->ptrb = obj1;
151           acogc_removeroot (obj2);
152           if (rand()%2)
153             obj->ptra = obj1;
154           NOTICE (NOBUG_ON, "allocated %p", obj1);
155
156           obj2 = acogc_factory_alloc (&gcfactory);
157           acogc_addroot (obj2);
158           if (rand()%2)
159             obj1->ptra = obj2;
160           if (rand()%2)
161             obj1->ptrb = obj2;
162           acogc_removeroot (obj1);
163           if (rand()%2)
164             obj->ptrb = obj2;
165           NOTICE (NOBUG_ON, "allocated %p", obj2);
166         }
167       acogc_removeroot (obj);
168
169       acogc_root_erase (&gcroot);
170     }
171   else if (strcmp(argv[1], "WEAK_REFS") == 0)
172     {
173       printf("weak-refs\n");
174       init ();
175
176       obj1 = acogc_factory_alloc (&gcfactory);
177
178       // declare reference weak_a
179       acogc_weakref weak_a = ACOGC_WEAKREF_INITIALIZER;
180
181       // declare reference weak_b
182       acogc_weakref weak_b = ACOGC_WEAKREF_INITIALIZER;
183
184       // declare reference weak_c
185       acogc_weakref weak_c = ACOGC_WEAKREF_INITIALIZER;
186
187       // unlink unused weak_b
188       acogc_weakref_unlink (&weak_b);
189       assert (weak_b.ref == NULL);
190       assert (weak_b.next == NULL);
191
192       // link weak_a
193       acogc_weakref_link (&weak_a, obj1);
194       assert (weak_a.ref == obj1);
195
196       //link weak_b
197       acogc_weakref_link (&weak_b, obj1);
198       assert(weak_b.ref == obj1);
199       
200       //link weak_c
201       acogc_weakref_link (&weak_c, obj1);
202       assert (weak_c.ref == obj1);
203       
204       //unlink weak_a
205       acogc_weakref_unlink (&weak_a);
206       assert (weak_a.ref == NULL);
207       assert (weak_a.next == NULL);
208
209       //unlink weak_b
210       acogc_weakref_unlink (&weak_b);
211       assert (weak_b.ref == NULL);
212       assert (weak_b.next == NULL);
213
214       // link weak_b
215       acogc_weakref_link (&weak_b, obj1);
216       assert (weak_b.ref == obj1);
217       assert (weak_b.next == &weak_c);
218
219       // link weak_a
220       acogc_weakref_link (&weak_a, obj1);
221       assert (weak_a.ref == obj1);
222       assert (weak_a.next == &weak_b);
223
224       // link weak_a again
225       acogc_weakref_link (&weak_a, obj1);
226       assert (weak_a.ref == obj1);
227       assert (weak_a.next == &weak_b);
228
229       // test invalidate
230       acogc_object_weakref_invalidate (obj1);
231       assert (weak_a.ref == NULL);
232       assert (weak_a.next == NULL);
233       assert (weak_b.ref == NULL);
234       assert (weak_b.next == NULL);
235
236       // relink for erase
237       acogc_weakref_link (&weak_b, obj1);
238       acogc_weakref_link (&weak_a, obj1);
239
240       acogc_root_erase (&gcroot);
241
242       assert (weak_a.ref == NULL);
243       assert (weak_a.next == NULL);
244       assert (weak_b.ref == NULL);
245       assert (weak_b.next == NULL);
246     }
247   else if (strcmp(argv[1], "REINSTANTIATE") == 0)
248     {
249       printf("reinst\n");
250       init ();
251
252       obj1 = acogc_factory_alloc (&gcfactory);
253
254       acogc_weakref weak = ACOGC_WEAKREF_INITIALIZER;
255
256       acogc_weakref_link (&weak, obj1);
257
258       obj2 = acogc_weakref_reinstget (&weak);
259       assert (obj2 == obj1);
260
261       assert (acogc_weakref_get (&weak) != NULL);
262       acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
263
264       assert (acogc_weakref_get (&weak) == NULL);
265
266       obj2 = acogc_weakref_reinstget (&weak);
267       assert (obj2 == obj1);
268       assert (acogc_weakref_get (&weak) != NULL);
269
270       acogc_root_erase (&gcroot);
271       }
272   else if (strcmp(argv[1], "UNCOLLECTABLE") == 0)
273     {
274       printf("uncollectable\n");
275       init ();
276
277       //ACOGC_OBJECT (UNCOLLECTABLE, &gcfactory, struct object, testobject,
278       //{345, NULL, NULL, LLIST_INITIALIZER(testobject_acogc.object.foo), 123, "test"});
279       ACOGC_OBJECT (UNCOLLECTABLE, &gcfactory, struct object, testobject,
280       {345, NULL, NULL, 123, "test"}); 
281     
282       acogc_addroot (testobject);
283       acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
284       acogc_addroot (testobjectglobal);
285       acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
286
287       obj = acogc_factory_alloc(&gcfactory);
288       testobject->ptra = obj;
289       acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
290
291       obj = acogc_factory_alloc(&gcfactory);
292       testobjectglobal->ptrb = obj;
293       acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
294
295       testobject->ptra = NULL;
296       testobjectglobal->ptrb = NULL;
297       acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
298
299       obj = acogc_factory_alloc(&gcfactory);
300       testobject->ptra = obj;
301
302       obj = acogc_factory_alloc(&gcfactory);
303       testobjectglobal->ptrb = obj;
304
305       acogc_root_erase (&gcroot);
306       /* again, gcroot should be reuseable now */
307       assert(testobject->ptra == NULL);
308       assert(testobjectglobal->ptrb == NULL);
309
310       acogc_addroot (testobject);
311       acogc_addroot (testobjectglobal);
312
313       obj = acogc_factory_alloc(&gcfactory);
314       testobject->ptra = obj;
315
316       obj = acogc_factory_alloc(&gcfactory);
317       testobjectglobal->ptrb = obj;
318
319       testobject->ptra = NULL;
320       testobjectglobal->ptrb = NULL;
321
322       acogc_root_erase (&gcroot);
323     }
324   else if (strcmp(argv[1], "NESTED_ROOT") == 0)
325     {
326       printf("nestedroot\n");
327       init ();
328
329       obj = acogc_factory_alloc (&gcfactory);
330       acogc_addroot (obj);
331       acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
332       acogc_addroot (obj);
333       acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
334       acogc_addroot (obj);
335       acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
336
337       acogc_removeroot (obj);
338       acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
339       acogc_removeroot (obj);
340       acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
341       acogc_removeroot (obj);
342
343       acogc_root_erase (&gcroot);
344     }
345   else
346     {
347       printf("ERROR\n");
348       exit(1);
349     }
350   return 0;
351 }
352 /*
353 // Local Variables:
354 // mode: C
355 // c-file-style: "gnu"
356 // End:
357 // arch-tag: ef8371dc-4862-4bee-9b57-080a66205ef9
358 // end_of_file
359 */