test improvement
[acogc.git] / tests / test-acogc.c
blob6d539349bb109186e24c77dee48c2f46f5919480
1 /*
2 test-acogc.c - simple accurate/cooperative garbage collector
4 Copyright (C) 2006, Christian Thaeter <chth@gmx.net>
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.
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.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, contact me.
20 #include <stdlib.h>
21 #include <assert.h>
22 #include <stdio.h>
23 #include <string.h>
25 #include "../lib/acogc.h"
27 struct object
29 int notused;
30 struct object* ptra;
31 struct object* ptrb;
32 //llist foo;
33 int test;
34 char pad[20];
37 void
38 object_init_acogc (void* obj)
40 struct object* o = obj;
41 o->ptra = NULL;
42 o->ptrb = NULL;
43 //llist_init (&o->foo);
46 acogc_mark_result
47 object_mark_acogc (void* obj)
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;
57 acogc_root gcroot;
58 acogc_factory gcfactory;
60 //ACOGC_OBJECT (UNCOLLECTABLE_NONFINALIZEABLE, &gcfactory, struct object, testobjectglobal, {345, NULL, NULL, LLIST_INITIALIZER(testobjectglobal_acogc.object.foo), 123, "test"});
62 ACOGC_OBJECT (UNCOLLECTABLE_NONFINALIZEABLE, &gcfactory, struct object, testobjectglobal, {345, NULL, NULL, 123, "test"});
65 void init()
67 acogc_root_init(&gcroot);
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);
79 int main(int argc, char* argv[])
81 struct object* obj;
82 struct object* obj1;
83 struct object* obj2;
85 acogc_nobug_init();
87 if (argc != 2)
89 printf("ERROR\n");
90 exit(1);
93 if (strcmp(argv[1], "INIT") == 0)
95 printf("init\n");
96 init ();
98 else if (strcmp(argv[1], "INIT_EMPTY_ERASE") == 0)
100 printf("init-empty-erase\n");
101 init ();
102 acogc_root_erase (&gcroot);
104 else if (strcmp(argv[1], "ERASE_SOME_OBJECTS") == 0)
106 printf("erase\n");
107 init ();
108 obj = acogc_factory_alloc (&gcfactory);
109 acogc_addroot (obj);
110 NOTICE (NOBUG_ON, "allocated %p", obj);
112 obj2 = acogc_factory_alloc (&gcfactory);
113 obj->ptra = obj2;
114 NOTICE (NOBUG_ON, "allocated %p", obj2);
116 for (int j = 0; j < 1000; ++j)
118 obj1 = acogc_factory_alloc (&gcfactory);
119 obj2->ptra = obj1;
120 NOTICE (NOBUG_ON, "allocated %p", obj1);
122 obj2 = acogc_factory_alloc (&gcfactory);
123 obj1->ptra = obj2;
124 NOTICE (NOBUG_ON, "allocated %p", obj2);
126 acogc_removeroot (obj);
128 acogc_root_erase (&gcroot);
130 else if (strcmp(argv[1], "RANDOM") == 0)
132 printf("random\n");
133 init ();
134 obj = acogc_factory_alloc (&gcfactory);
135 acogc_addroot (obj);
136 NOTICE (NOBUG_ON, "allocated %p", obj);
138 obj2 = acogc_factory_alloc (&gcfactory);
139 acogc_addroot (obj2);
140 obj->ptra = obj2;
141 NOTICE (NOBUG_ON, "allocated %p", obj2);
143 for (int j = 0; j < 1000; ++j)
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);
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);
167 acogc_removeroot (obj);
169 acogc_root_erase (&gcroot);
171 else if (strcmp(argv[1], "WEAK_REFS") == 0)
173 printf("weak-refs\n");
174 init ();
176 obj1 = acogc_factory_alloc (&gcfactory);
178 // declare reference weak_a
179 acogc_weakref weak_a = ACOGC_WEAKREF_INITIALIZER;
181 // declare reference weak_b
182 acogc_weakref weak_b = ACOGC_WEAKREF_INITIALIZER;
184 // declare reference weak_c
185 acogc_weakref weak_c = ACOGC_WEAKREF_INITIALIZER;
187 // unlink unused weak_b
188 acogc_weakref_unlink (&weak_b);
189 assert (weak_b.ref == NULL);
190 assert (weak_b.next == NULL);
192 // link weak_a
193 acogc_weakref_link (&weak_a, obj1);
194 assert (weak_a.ref == obj1);
196 //link weak_b
197 acogc_weakref_link (&weak_b, obj1);
198 assert(weak_b.ref == obj1);
200 //link weak_c
201 acogc_weakref_link (&weak_c, obj1);
202 assert (weak_c.ref == obj1);
204 //unlink weak_a
205 acogc_weakref_unlink (&weak_a);
206 assert (weak_a.ref == NULL);
207 assert (weak_a.next == NULL);
209 //unlink weak_b
210 acogc_weakref_unlink (&weak_b);
211 assert (weak_b.ref == NULL);
212 assert (weak_b.next == NULL);
214 // link weak_b
215 acogc_weakref_link (&weak_b, obj1);
216 assert (weak_b.ref == obj1);
217 assert (weak_b.next == &weak_c);
219 // link weak_a
220 acogc_weakref_link (&weak_a, obj1);
221 assert (weak_a.ref == obj1);
222 assert (weak_a.next == &weak_b);
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);
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);
236 // relink for erase
237 acogc_weakref_link (&weak_b, obj1);
238 acogc_weakref_link (&weak_a, obj1);
240 acogc_root_erase (&gcroot);
242 assert (weak_a.ref == NULL);
243 assert (weak_a.next == NULL);
244 assert (weak_b.ref == NULL);
245 assert (weak_b.next == NULL);
247 else if (strcmp(argv[1], "REINSTANTIATE") == 0)
249 printf("reinst\n");
250 init ();
252 obj1 = acogc_factory_alloc (&gcfactory);
254 acogc_weakref weak = ACOGC_WEAKREF_INITIALIZER;
256 acogc_weakref_link (&weak, obj1);
258 obj2 = acogc_weakref_reinstget (&weak);
259 assert (obj2 == obj1);
261 assert (acogc_weakref_get (&weak) != NULL);
262 acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
264 assert (acogc_weakref_get (&weak) == NULL);
266 obj2 = acogc_weakref_reinstget (&weak);
267 assert (obj2 == obj1);
268 assert (acogc_weakref_get (&weak) != NULL);
270 acogc_root_erase (&gcroot);
272 else if (strcmp(argv[1], "UNCOLLECTABLE") == 0)
274 printf("uncollectable\n");
275 init ();
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"});
282 acogc_addroot (testobject);
283 acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
284 acogc_addroot (testobjectglobal);
285 acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
287 obj = acogc_factory_alloc(&gcfactory);
288 testobject->ptra = obj;
289 acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
291 obj = acogc_factory_alloc(&gcfactory);
292 testobjectglobal->ptrb = obj;
293 acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
295 testobject->ptra = NULL;
296 testobjectglobal->ptrb = NULL;
297 acogc_root_collect (&gcroot, ACOGC_COLLECT_DONTFREE);
299 obj = acogc_factory_alloc(&gcfactory);
300 testobject->ptra = obj;
302 obj = acogc_factory_alloc(&gcfactory);
303 testobjectglobal->ptrb = obj;
305 acogc_root_erase (&gcroot);
306 /* again, gcroot should be reuseable now */
307 assert(testobject->ptra == NULL);
308 assert(testobjectglobal->ptrb == NULL);
310 acogc_addroot (testobject);
311 acogc_addroot (testobjectglobal);
313 obj = acogc_factory_alloc(&gcfactory);
314 testobject->ptra = obj;
316 obj = acogc_factory_alloc(&gcfactory);
317 testobjectglobal->ptrb = obj;
319 testobject->ptra = NULL;
320 testobjectglobal->ptrb = NULL;
322 acogc_root_erase (&gcroot);
324 else if (strcmp(argv[1], "NESTED_ROOT") == 0)
326 printf("nestedroot\n");
327 init ();
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);
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);
343 acogc_root_erase (&gcroot);
345 else
347 printf("ERROR\n");
348 exit(1);
350 return 0;
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