add typecheck by string literal
[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                      "object");
78 }
79
80 int main(int argc, char* argv[])
81 {
82   struct object* obj;
83   struct object* obj1;
84   struct object* obj2;
85
86   acogc_nobug_init();
87
88   if (argc != 2)
89     {
90       printf("ERROR\n");
91       exit(1);
92     }
93
94   if (strcmp(argv[1], "INIT") == 0)
95     {
96       printf("init\n");
97       init ();
98     }
99   else if (strcmp(argv[1], "INIT_EMPTY_ERASE") == 0)
100     {
101       printf("init-empty-erase\n");
102       init ();
103       acogc_root_erase (&gcroot);
104     }
105   else if (strcmp(argv[1], "ERASE_SOME_OBJECTS") == 0)
106     {
107       printf("erase\n");
108       init ();
109       obj = acogc_factory_alloc (&gcfactory);
110       acogc_addroot (obj);
111       NOTICE (NOBUG_ON, "allocated %p", obj);
112
113       obj2 = acogc_factory_alloc (&gcfactory);
114       obj->ptra = obj2;
115       NOTICE (NOBUG_ON, "allocated %p", obj2);
116
117       for (int j = 0; j < 1000; ++j)
118         {
119           obj1 = acogc_factory_alloc (&gcfactory);
120           obj2->ptra = obj1;
121           NOTICE (NOBUG_ON, "allocated %p", obj1);
122
123           obj2 = acogc_factory_alloc (&gcfactory);
124           obj1->ptra = obj2;
125           NOTICE (NOBUG_ON, "allocated %p", obj2);
126         }
127       acogc_removeroot (obj);
128
129       acogc_root_erase (&gcroot);
130     }
131   else if (strcmp(argv[1], "RANDOM") == 0)
132     {
133       printf("random\n");
134       init ();
135       obj = acogc_factory_alloc (&gcfactory);
136       acogc_addroot (obj);
137       NOTICE (NOBUG_ON, "allocated %p", obj);
138
139       obj2 = acogc_factory_alloc (&gcfactory);
140       acogc_addroot (obj2);
141       obj->ptra = obj2;
142       NOTICE (NOBUG_ON, "allocated %p", obj2);
143
144       for (int j = 0; j < 1000; ++j)
145         {
146           obj1 = acogc_factory_alloc (&gcfactory);
147           acogc_addroot (obj1);
148           if (rand()%2)
149             obj2->ptra = obj1;
150           if (rand()%2)
151             obj2->ptrb = obj1;
152           acogc_removeroot (obj2);
153           if (rand()%2)
154             obj->ptra = obj1;
155           NOTICE (NOBUG_ON, "allocated %p", obj1);
156
157           obj2 = acogc_factory_alloc (&gcfactory);
158           acogc_addroot (obj2);
159           if (rand()%2)
160             obj1->ptra = obj2;
161           if (rand()%2)
162             obj1->ptrb = obj2;
163           acogc_removeroot (obj1);
164           if (rand()%2)
165             obj->ptrb = obj2;
166           NOTICE (NOBUG_ON, "allocated %p", obj2);
167         }
168       acogc_removeroot (obj);
169
170       acogc_root_erase (&gcroot);
171     }
172   else if (strcmp(argv[1], "WEAK_REFS") == 0)
173     {
174       printf("weak-refs\n");
175       init ();
176
177       obj1 = acogc_factory_alloc (&gcfactory);
178
179       // declare reference weak_a
180       acogc_weakref weak_a = ACOGC_WEAKREF_INITIALIZER;
181
182       // declare reference weak_b
183       acogc_weakref weak_b = ACOGC_WEAKREF_INITIALIZER;
184
185       // declare reference weak_c
186       acogc_weakref weak_c = ACOGC_WEAKREF_INITIALIZER;
187
188       // unlink unused weak_b
189       acogc_weakref_unlink (&weak_b);
190       assert (weak_b.ref == NULL);
191       assert (weak_b.next == NULL);
192
193       // link weak_a
194       acogc_weakref_link (&weak_a, obj1);
195       assert (weak_a.ref == obj1);
196
197       //link weak_b
198       acogc_weakref_link (&weak_b, obj1);
199       assert(weak_b.ref == obj1);
200       
201       //link weak_c
202       acogc_weakref_link (&weak_c, obj1);
203       assert (weak_c.ref == obj1);
204       
205       //unlink weak_a
206       acogc_weakref_unlink (&weak_a);
207       assert (weak_a.ref == NULL);
208       assert (weak_a.next == NULL);
209
210       //unlink weak_b
211       acogc_weakref_unlink (&weak_b);
212       assert (weak_b.ref == NULL);
213       assert (weak_b.next == NULL);
214
215       // link weak_b
216       acogc_weakref_link (&weak_b, obj1);
217       assert (weak_b.ref == obj1);
218       assert (weak_b.next == &weak_c);
219
220       // link weak_a
221       acogc_weakref_link (&weak_a, obj1);
222       assert (weak_a.ref == obj1);
223       assert (weak_a.next == &weak_b);
224
225       // link weak_a again
226       acogc_weakref_link (&weak_a, obj1);
227       assert (weak_a.ref == obj1);
228       assert (weak_a.next == &weak_b);
229
230       // test invalidate
231       acogc_object_weakref_invalidate (obj1);
232       assert (weak_a.ref == NULL);
233       assert (weak_a.next == NULL);
234       assert (weak_b.ref == NULL);
235       assert (weak_b.next == NULL);
236
237       // relink for erase
238       acogc_weakref_link (&weak_b, obj1);
239       acogc_weakref_link (&weak_a, obj1);
240
241       acogc_root_erase (&gcroot);
242
243       assert (weak_a.ref == NULL);
244       assert (weak_a.next == NULL);
245       assert (weak_b.ref == NULL);
246       assert (weak_b.next == NULL);
247     }
248   else if (strcmp(argv[1], "REINSTANTIATE") == 0)
249     {
250       printf("reinst\n");
251       init ();
252
253       obj1 = acogc_factory_alloc (&gcfactory);
254
255       acogc_weakref weak = ACOGC_WEAKREF_INITIALIZER;
256
257       acogc_weakref_link (&weak, obj1);
258
259       obj2 = acogc_weakref_reinstget (&weak);
260       assert (obj2 == obj1);
261
262       assert (acogc_weakref_get (&weak) != NULL);
263       acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
264
265       assert (acogc_weakref_get (&weak) == NULL);
266
267       obj2 = acogc_weakref_reinstget (&weak);
268       assert (obj2 == obj1);
269       assert (acogc_weakref_get (&weak) != NULL);
270
271       acogc_root_erase (&gcroot);
272       }
273   else if (strcmp(argv[1], "UNCOLLECTABLE") == 0)
274     {
275       printf("uncollectable\n");
276       init ();
277
278       //ACOGC_OBJECT (UNCOLLECTABLE, &gcfactory, struct object, testobject,
279       //{345, NULL, NULL, LLIST_INITIALIZER(testobject_acogc.object.foo), 123, "test"});
280       ACOGC_OBJECT (UNCOLLECTABLE, &gcfactory, struct object, testobject,
281       {345, NULL, NULL, 123, "test"}); 
282     
283       acogc_addroot (testobject);
284       acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
285       acogc_addroot (testobjectglobal);
286       acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
287
288       obj = acogc_factory_alloc(&gcfactory);
289       testobject->ptra = obj;
290       acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
291
292       obj = acogc_factory_alloc(&gcfactory);
293       testobjectglobal->ptrb = obj;
294       acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
295
296       testobject->ptra = NULL;
297       testobjectglobal->ptrb = NULL;
298       acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
299
300       obj = acogc_factory_alloc(&gcfactory);
301       testobject->ptra = obj;
302
303       obj = acogc_factory_alloc(&gcfactory);
304       testobjectglobal->ptrb = obj;
305
306       acogc_root_erase (&gcroot);
307       /* again, gcroot should be reuseable now */
308       assert(testobject->ptra == NULL);
309       assert(testobjectglobal->ptrb == NULL);
310
311       acogc_addroot (testobject);
312       acogc_addroot (testobjectglobal);
313
314       obj = acogc_factory_alloc(&gcfactory);
315       testobject->ptra = obj;
316
317       obj = acogc_factory_alloc(&gcfactory);
318       testobjectglobal->ptrb = obj;
319
320       testobject->ptra = NULL;
321       testobjectglobal->ptrb = NULL;
322
323       acogc_root_erase (&gcroot);
324     }
325   else if (strcmp(argv[1], "NESTED_ROOT") == 0)
326     {
327       printf("nestedroot\n");
328       init ();
329
330       obj = acogc_factory_alloc (&gcfactory);
331       acogc_addroot (obj);
332       acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
333       acogc_addroot (obj);
334       acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
335       acogc_addroot (obj);
336       acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
337
338       acogc_removeroot (obj);
339       acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
340       acogc_removeroot (obj);
341       acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
342       acogc_removeroot (obj);
343
344       acogc_root_erase (&gcroot);
345     }
346   else
347     {
348       printf("ERROR\n");
349       exit(1);
350     }
351   return 0;
352 }
353 /*
354 // Local Variables:
355 // mode: C
356 // c-file-style: "gnu"
357 // End:
358 // arch-tag: ef8371dc-4862-4bee-9b57-080a66205ef9
359 // end_of_file
360 */