2 acogc.h - 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.
25 only real references are used for marking objects instead scanning all objects
28 the programmer has to supply functions which mark references in his datastructures
34 #include <valgrind/valgrind.h>
38 #ifdef EBUG_ACOGC /* CFLAGS+=-DEBUG_ACOGC */
42 #define ACOGC_TRACE(lvl,fmt,...) do{if(lvl<=EBUG_ACOGC)VALGRIND_PRINTF("DEBUG: %s@%d %s " fmt, strrchr(__FILE__, '/')?strrchr(__FILE__, '/') + 1 : __FILE__,__LINE__, __func__ , ## __VA_ARGS__);}while(0)
43 #define ACOGC_ASSERT(expr,fmt,...) do{if(!(expr)){VALGRIND_PRINTF_BACKTRACE("ASSERT: %s:%d %s " fmt, __FILE__, __LINE__, #expr, ## __VA_ARGS__);abort();}}while(0)
46 #define ACOGC_CLEANUP(fn) __attribute__((cleanup(fn)))
48 #define ACOGC_CLEANUP(fn)
52 #define ACOGC_TRACE(fmt,...) (void)0
53 #define ACOGC_ASSERT(expr,fmt,...) (void)0
54 #define ACOGC_CLEANUP(fn)
58 object types and handles
60 #define ACOGC_DECLARE(name,Handle) \
61 struct acogc_##name##_struct; \
62 typedef struct acogc_##name##_struct acogc_##name;\
63 typedef const acogc_##name * const_Acogc##Handle;\
64 typedef acogc_##name * Acogc##Handle;\
65 typedef acogc_##name ** Acogc##Handle##_ref;\
66 typedef const acogc_##name ** const_Acogc##Handle##_ref
68 ACOGC_DECLARE(root
,Root
);
69 ACOGC_DECLARE(stack
,Stack
);
70 ACOGC_DECLARE(factory
,Factory
);
71 ACOGC_DECLARE(object
,Object
);
72 ACOGC_DECLARE(weakref
,Weakref
);
79 uncollectable objects (static or stack) have to be defined with this macro
81 #define ACOGC_OBJECT(state, factory, type, name, ...) \
82 struct { acogc_object acogc_header; type object;} \
83 name ## _acogc = {ACOGC_OBJECT_INITIALIZER( state, \
86 type* name=&name ## _acogc.object
88 #define ACOGC_OBJECT_INITIALIZER(state, factory, name) \
89 {LLIST_INITIALIZER (name ## _acogc.acogc_header.node ), \
90 factory, NULL, ACOGC_STATE_ ## state}
93 tracking pointers on the stack with the GC
95 #define ACOGC_STACK_ENTER(gcroot) \
96 AcogcStack_ref acogc_stack_root = &gcroot->stack; \
97 AcogcStack acogc_stack_entry ACOGC_CLEANUP (acogc_assert_stackframeleft) = *acogc_stack_root
99 #define ACOGC_STACK_PTR(ptrtype, name) \
103 }name; name.ptr = NULL; \
104 name.stack.prev = *acogc_stack_root; \
105 *acogc_stack_root = &name.stack
107 #define ACOGC_STACK_LEAVE \
108 *acogc_stack_root = acogc_stack_entry; \
109 acogc_stack_entry = (AcogcStack)&acogc_stack_entry
111 struct acogc_stack_struct
118 acogc_assert_stackframeleft (AcogcStack_ref p
);
120 /* declare a weak reference als automatic variable, asserts that the reference gets unlinked when the stackframe is left (-DEBUG_ACOGC on gcc only) */
121 #define ACOGC_WEAK_REFERENCE(name) acogc_weakref name ACOGC_CLEANUP(acogc_weakref_assert_cleared) = ACOGC_WEAKREF_INITIALIZER
122 #define ACOGC_WEAKREF_INITIALIZER {NULL, NULL}
127 in case no memory is available the GC will gradually free more unused memory
128 when this has no effect it calls a user setable routine 3 times to give the user a chance to handle the situation
129 this user routine gets the current policy and a pointer to supplemental data (hint: use a jmp_buf) as parameter
130 if all fails it will call abort() finally
132 enum acogc_freeing_policy
134 ACOGC_COLLECT_DONTFREE
, /* just collect, do not free */
135 ACOGC_COLLECT_NORMAL
, /* normal collection freeing down to highwater */
136 ACOGC_COLLECT_FORCEMID
, /* freeing down to (lowwater+highwater)/2 */
137 ACOGC_COLLECT_FORCELOW
, /* freeing down to lowwater */
138 ACOGC_COLLECT_FORCEALL
, /* free all freeable objects */
139 ACOGC_COLLECT_USER1
, /* call userhook first time (free some mem) */
140 ACOGC_COLLECT_USER2
, /* call userhook second time (free memory hardly) */
141 ACOGC_COLLECT_USER3
, /* call userhook third time (handle memory failure or free memory even harder) */
142 ACOGC_COLLECT_FAILED
/* still no memory available, will abort() */
145 enum acogc_object_state
147 ACOGC_STATE_ROOT
= -1,
148 ACOGC_STATE_UNCOLLECTABLE_NONFINALIZEABLE
,
149 ACOGC_STATE_UNCOLLECTABLE
,
153 ACOGC_STATE_LAST
= INT_MAX
156 enum acogc_mark_result
158 ACOGC_COLLECT
, /* collect the object */
159 ACOGC_KEEP
, /* let the GC mark the object */
165 typedef void (*acogc_initize_func
)(void*);
166 typedef void (*acogc_finalize_func
)(void*);
167 typedef enum acogc_mark_result (*acogc_mark_func
)(void*);
172 the acogc_root manages all memory allocated with acogc.
173 A program can use more than one acogc_root for implementing diffrent memory domains which must not cross-reference objects
175 struct acogc_root_struct
179 int state
; /* actually a counter, 0 is reserved for root objects */
183 unsigned long collection_freq_avg
; /* every how much allocations did we do a collection on average */
184 unsigned long allocation_counter
; /* counts every allocation since the last collection */
186 void (*nomemhandler
)(void*, enum acogc_freeing_policy
); /* called when no memory can be allocated */
187 void* nomemsupp
; /* supplemental data for the nomem handler*/
192 initialize a acogc_root structure
195 acogc_root_init (AcogcRoot self
);
199 free all memory associated with a acogc_root,
202 acogc_root_erase (AcogcRoot self
);
205 do a collection, ususaly automatically triggered
208 acogc_root_collect (AcogcRoot self
, enum acogc_freeing_policy pol
);
214 the factory holds the static size for all objects it manages. objects are allocated with 'acogc_factory_alloc'. collected objects are cached and freed based on the high_water/low_water policies. collected, not-yet-freed objects can be reinstantiated and the user can implement fancy caching schemes.
216 struct acogc_factory_struct
218 AcogcRoot root
; /* points back to the root */
219 llist factories
; /* links all factories of one root together */
221 llist roots
; /* root objects for this factory */
222 llist alive
; /* objects in use */
223 llist dead
; /* unused objects (might still be referenced by weak pointers and reinstantiated on demand) */
224 llist tmp
; /* temporary list for collection */
226 unsigned long objects_allocated
; /* number of allocated objects */
227 unsigned long objects_used
; /* number of objects in use at the last collection + freshly allocated objects */
229 unsigned was_free
; /* percent of free objects at the last collection */
231 unsigned low_water
; /* allocate more when less than this % of objects are unused */
232 unsigned high_water
; /* start freeing when more than this % of objects are unused */
234 size_t size
; /* size od objects allocated by this factory */
236 acogc_mark_func mark
; /* proactive collection check */
237 acogc_initize_func initize
; /* finalizer called before a object is free()'ed */
238 acogc_finalize_func finalize
; /* finalizer called before a object is free()'ed */
242 initialize a acogc_factory
244 the user has to supply arrays with offsetof() values of pointers and weakrefs terminated with SIZE_MAX,
245 the GC takes care to initialize them
248 acogc_factory_init (AcogcFactory self
,
253 acogc_mark_func mark
,
254 acogc_initize_func initize
,
255 acogc_finalize_func finalize
);
258 /* alloc memory from factory */
260 acogc_factory_alloc (AcogcFactory self
);
266 a acogc_object prepends each user allocated block
268 struct acogc_object_struct
271 AcogcFactory factory
;
272 AcogcWeakref weakrefs
;
276 /* register a object as GC root object, should be done as soon as possible after allocation */
278 acogc_addroot (void* object
);
280 /* unregister a GC root object, it becomes normal collectable by this. */
282 acogc_removeroot (void* object
);
285 acogc_adduncollectableroot (void* object
);
288 acogc_removeuncollectableroot (void* object
);
294 acogc_memory_from_object (const_AcogcObject
const self
)
296 return (void*)self
+ sizeof (acogc_object
);
299 static inline AcogcObject
300 acogc_object_from_memory (const void * const self
)
302 return (AcogcObject
)(self
- sizeof (acogc_object
));
306 acogc_object_markreally (AcogcObject object
);
309 acogc_object_mark (void * o
)
311 ACOGC_TRACE (3, "object %p", o
);
316 AcogcObject object
= acogc_object_from_memory (o
);
318 ACOGC_TRACE (4, "state %d", object
->state
);
319 ACOGC_TRACE (4, "factory %p", object
->factory
);
320 ACOGC_TRACE (4, "factory->root %p", object
->factory
->root
);
321 ACOGC_TRACE (4, "factory->root->state %d", object
->factory
->root
->state
);
323 if (object
->state
>= ACOGC_STATE_FIRST
&& object
->state
< object
->factory
->root
->state
)
324 acogc_object_markreally (object
);
332 weak references are lists which must be maintained by the programmer
334 struct acogc_weakref_struct
341 acogc_weakref_init (AcogcWeakref self
)
343 self
->next
= self
->ref
= NULL
;
347 acogc_weakref_link (AcogcWeakref self
, void* object
);
350 acogc_weakref_unlink (AcogcWeakref self
);
353 acogc_object_weakref_invalidate (void* memory
);
357 when a object is swept but still not freed it can be reinstatiated (for example if a weak-reference points to it)
360 /* dereference a weak reference, reinstantiate it if required */
362 acogc_weakref_reinstget (AcogcWeakref self
);
364 /* dereference a weak reference, do not reinstantiate it if swept, return NULL */
366 acogc_weakref_get (AcogcWeakref self
);
369 acogc_weakref_assert_cleared (AcogcWeakref p
);
372 manual allocation not garbagge collected, needs to be acogc_free()'d
373 the advantage of these are that malloc will initiate a garbagge collection
374 if no memory is available and call the registered nomemhandler.
375 This functions are guranteed to be interchangeable with malloc/realloc/free as
376 long the pointer doesn't hold a reference, see below.
378 as special feature a address can be setref'ed to another address,
379 the lowest bit is used to indicate this. So only aligned addresses are
380 allowed for this. use the acogc_deref() function to mask it out.
384 try to (re-)allocate some block of memory with a new size
385 *addr has to be initialized to NULL
386 trying to reallocate a reference is illegal.
388 unfotunally we need some ugly casts here
391 acogc_alloc_ (void ** addr
, size_t size
, AcogcRoot factory
);
392 #define acogc_alloc(addr, size, root) acogc_alloc_ ((void*)addr, size, root)
395 realloc a memory block to at least needed size, min 16 bytes, increased by a 1.5 factor on resizing
396 return the amount really reserved
397 when resizing is finsished one might fixate it by calling acogc_alloc with the real required size at last,
398 some realloc implementations might free some memory thereafter.
401 acogc_reserve_ (void ** addr
, size_t actual
, size_t needed
, AcogcRoot root
);
402 #define acogc_reserve(addr, actual, needed, root) acogc_reserve_ ((void*)addr, actual, needed, root)
405 free *addr if not a reference and set it to NULL
408 acogc_free_ (void ** addr
);
409 #define acogc_free(addr) acogc_free_ ((void*)addr)
412 acogc_assert_stackframeleft (AcogcStack_ref p
);
418 // c-file-style: "gnu"
420 // arch-tag: 855b7025-8227-4892-ac25-9b0a3d57dd0b