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>
37 #ifdef EBUG_ACOGC /* CFLAGS+=-DEBUG_ACOGC */
41 #define ACOGC_TRACE(lvl,fmt,...) do{if(lvl<=EBUG_ACOGC)VALGRIND_PRINTF("%s@%d %s " fmt, strrchr(__FILE__, '/')?strrchr(__FILE__, '/') + 1 : __FILE__,__LINE__, __func__ , ## __VA_ARGS__);}while(0)
42 #define ACOGC_ASSERT(expr,fmt,...) do{if(!(expr)){VALGRIND_PRINTF_BACKTRACE("%s " fmt, #expr, ## __VA_ARGS__);abort();}}while(0)
45 #define ACOGC_CLEANUP(fn) __attribute__((cleanup(fn)))
49 #define ACOGC_TRACE(fmt,...) do{}while(0)
50 #define ACOGC_ASSERT(expr,fmt,...) do{}while(0)
54 #define ACOGC_CLEANUP(fn) __attribute__((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(marker,Marker);
69 ACOGC_DECLARE(factory
,Factory
);
70 ACOGC_DECLARE(object
,Object
);
71 ACOGC_DECLARE(weakreference
,WeakReference
);
77 //typedef void (*acogc_initize_func)(void*, size_t);
80 the user needs to provide custom scan functions for his objects,
81 ?TODO? returning !0 normally but 1 if the object should not be marked (unmarked)
83 typedef void (*acogc_scan_func
)(void* obj
);
84 typedef void (*acogc_finalize_func
)(void*);
90 enum acogc_emergency_level
92 ACOGC_COLLECT_DONTFREE
, /* just collect, do not free */
93 ACOGC_COLLECT_NORMAL
, /* normal collection */
94 ACOGC_COLLECT_FORCELOW
, /* free down to lowwater in this factory */
95 ACOGC_COLLECT_ALLFORCELOW
, /* free down to lowwater in all factories */
96 ACOGC_COLLECT_FREEABLE
, /* free all freeable objects in this factory */
97 ACOGC_COLLECT_ALLFREEABLE
, /* free all freeable objects in all factories */
98 ACOGC_COLLECT_FAILED
/* can' reclaim any memory */
103 ACOGC_FLAG_UNINITIALIZED
= 0x0, // allocated but not yet initialized object (keeps GC locked, becomes black)
104 /* the interpretation of colors cycles through 3 states 001 010 100 starting with ecru == 001 followed by white and black */
105 ACOGC_COLOR_1
= 0x1, // 001
106 ACOGC_COLOR_2
= 0x2, // 010
107 ACOGC_COLOR_3
= 0x4, // 100
108 /* next some values are reserved for special purposes where flags > 0x4 */
109 ACOGC_FLAG_ROOT_COLLECTABLE
= 0x5, // 101
110 ACOGC_FLAG_ROOT_STATIC
= 0x6, // 110
111 ACOGC_FLAG_RESERVED
= 0x7 // 111 unused for now
115 manual allocation not garbagge collected, needs to be acogc_free()'d
116 the advantage of these are that malloc will initiate a garbagge collection
117 if no memory is available and call the registered nomemhandler.
118 This functions are guranteed to be interchangeable with malloc/realloc/free as
119 long the pointer doesn't hold a reference, see below.
121 as special feature a address can be setref'ed to another address,
122 the lowest bit is used to indicate this. So only aligned addresses are
123 allowed for this. use the acogc_deref() function to mask it out.
127 unfortunally C doesn't require to align string literals, which is needed when you use the reference feature.
128 This can be enforced with this macro.
131 #define ACOGC_ALIGNED_STRING(string) (const char*)&((char __attribute__((aligned(sizeof(int))))[sizeof(string)]){string})
132 #else // fallback for other compilers
133 #define ACOGC_ALIGNED_STRING(string) (const char*)(&((struct {int nil; char str [sizeof(string)];}){0,string}.str))
137 try to (re-)allocate some block of memory with a new size
138 *addr has to be initialized to NULL
139 trying to reallocate a reference is illegal.
142 acogc_alloc_ (void ** addr
, size_t size
, AcogcFactory factory
);
143 #define acogc_alloc(addr, size, root) acogc_alloc_ ((void**)addr, size, root)
146 realloc a memory block to at least needed size, min 16 bytes, increased by a 1.5 factor on resizing
147 return the amount really reserved
148 when resizing is finsished one might fixate it by calling acogc_alloc with the real required size at last,
149 some realloc implementations might free some memory thereafter.
152 acogc_reserve_ (void ** addr
, size_t actual
, size_t needed
, AcogcFactory factory
);
153 #define acogc_reserve(addr, actual, needed, root) acogc_reserve_ ((void**)addr, actual, needed, root)
156 free *addr if not a reference and set it to NULL
159 acogc_free_ (void ** addr
);
160 #define acogc_free(addr) acogc_free_ ((void**)addr)
163 set addr as reference to ref
166 acogc_set_ref_ (void ** addr
, const void * ref
)
168 *addr
= ref
?(void*) (((uintptr_t)ref
) | 1):NULL
;
170 #define acogc_set_ref(addr, ref) acogc_set_ref_ ((void**)addr, ref)
174 just return the real address value from a possible reference
177 acogc_ref_get_ (void * addr
)
179 return (void*) (((uintptr_t)addr
) & ~(uintptr_t)1);
181 #define acogc_ref_get(addr) (typeof(addr)) acogc_ref_get_ ((void*)addr)
184 acogc_is_ref (void * addr
)
186 return (int)(((uintptr_t)addr
) & 1);
190 // TODO cleanup check does not work
191 #define ACOGC_ROOT_REGISTER(name, marker, gcroot, data) \
192 acogc_marker name##_acogc_marker \
193 ACOGC_CLEANUP (acogc_marker_assert_unregistered_root) \
194 = {NULL, marker, &name, data}; \
195 acogc_root_register_marker (gcroot, &name##_acogc_marker)
197 #define ACOGC_ROOT_UNREGISTER(name, gcroot) \
198 acogc_root_marker_unregister (gcroot, &name##_acogc_marker)
203 factories are manage classes of memory objects, there are 2 modes in which these factories can operate:
205 first the factory holds the static size for all objects it manages. objects are allocated with 'acogc_factory_alloc'. In this mode swept objects are cached and freed based on the high_water/low_water values. objects can be reinstantiated and the user can implement fancy caching schemes.
207 second when the 'size' is initialized to 0, dynamic sized objects will be allocated with 'acogc_factory_alloc_size', the swept-queue will not be used for allocations
211 adaptive auto configuration:
213 ideally a collection (all grey nodes scanned) should be finish just before the freelist
214 gets empty this would give the optimal memory utilization.
216 If it finishes earlier the time spend in incremental collecting was not ideally distributed which has a small performance impact or there are too much free objects available for the required working set.
218 if the collection is not complete when the freelist becomes empty we have to force a scan if the GC is not locked to get a new freelist or allocate new objects despite there may be enough potential free objects which we cant use yet.
220 So the goal is to optimize the scan_freq in a way that the collection completes before the freelist becomes empty and avoid cases where the collection takes to long.
224 struct acogc_factory_struct
236 int gc_lock
; // if >0 then dont flip (collector locked)
237 int ecru_color
; // 001 010 100 .. current value which tags ecru
240 unsigned scan_freq
; // scan every this actions (alloc or touch)
241 unsigned scan_at_once
; // scan this much elements in a scan-round
243 /* statistics counters */
244 unsigned scan_counter
; // decremented from scan_freq to 0 to initiate a scan an then reset
245 unsigned objects_allocated
; // how many objects are in this factory
246 unsigned objects_black
; // how many objects are marked black (in use when the collection is complete)
247 unsigned objects_white
; // how many objects are marked free
249 unsigned scanned
; // count scanned objects
250 signed idle
; // increment for scan attempts after collection completed,
251 // decrement for each allocation when the collection is not yet complete
253 /* statistics state */
254 unsigned scan_freq_avg
; // cumulating average of the scan freq
255 signed idle_avg
; // count scan attempts after collection completed
257 unsigned free_limit
; /* keep at most free_limit% objects free else start really freeing objects */
258 unsigned object_cluster
; /* this many objects are allocated or freed at once */
260 size_t size
; /* 0 for dynamic sized factory */
262 acogc_finalize_func finalize_func
; /* called when a object is freed or reused (but not reinstantiated) */
263 acogc_scan_func scan_func
; /* called when a object is marked */
264 //void * touch_data; /* supplemental user data passed to touch */
265 //void (*nomemhandler)(void); /* called when no memory can be allocated, defaults to abort() */
269 initialize a acogc_factory
270 when size==0 this factory will be used for dynamic sized allocations
271 the user must supply a custom mark function which calls acogc_object_mark for all (nonweak) references within his object
274 acogc_factory_new (AcogcFactory other
,
277 unsigned object_cluster
,
278 acogc_scan_func scan
,
279 acogc_finalize_func finalize
);
282 acogc_factory_erase (AcogcFactory self
);
285 acogc_factory_free (AcogcFactory self
);
288 acogc_factory_init (AcogcFactory self
,
292 unsigned object_cluster
,
293 acogc_scan_func scan
,
294 acogc_finalize_func finalize
);
300 /* alloc memory from factory with predefined size */
302 acogc_factory_alloc (AcogcFactory self
);
304 // TODO macro for ensuring a acogc_object_initialized?
306 /* free() swept objects, normally called automatically by the collector */
308 //acogc_factory_collectfree (AcogcFactory self, enum acogc_emergency_level elvl);
312 acogc_factory_scan (AcogcFactory self
);
315 acogc_factory_flip (AcogcFactory self
);
322 a acogc_object prepends each user allocated block
324 struct acogc_object_struct
327 AcogcFactory factory
; /* last bits are used as flags */
328 AcogcWeakReference weakrefs
;
331 // rotate last 3 bits left
332 static inline unsigned
333 acogc_flags_rol_ (unsigned x
)
338 // rotate last 3 bits right
339 static inline unsigned
340 acogc_flags_ror_ (unsigned x
)
345 static inline AcogcObject
346 acogc_object_from_memory_ (void * object
)
348 return (AcogcObject
)(object
- sizeof (acogc_object
));
352 acogc_memory_from_object_ (AcogcObject object
)
354 return (void*)object
+ sizeof (acogc_object
);
357 static inline AcogcObject
358 acogc_object_from_list_ (LList object
)
360 return LLIST_TO_STRUCTP (object
, acogc_object
, objects
);
364 acogc_memory_from_list_ (LList object
)
366 return acogc_memory_from_object_ (LLIST_TO_STRUCTP (object
, acogc_object
, objects
));
369 static inline AcogcFactory
370 acogc_object_factory_get_ (AcogcObject object
)
372 return (AcogcFactory
)((uintptr_t)(object
->factory
) & (uintptr_t)~0x7);
375 static inline unsigned
376 acogc_object_flags_get_ (AcogcObject object
)
378 return (unsigned)((uintptr_t)(object
->factory
) & (uintptr_t)0x7);
382 acogc_object_set_factory_flags_ (AcogcObject object
, AcogcFactory factory
, const unsigned flags
)
384 object
->factory
= (AcogcFactory
)((uintptr_t)factory
| (uintptr_t)flags
);
388 acogc_object_set_flags_ (AcogcObject object
, const unsigned flags
)
390 uintptr_t f
= (uintptr_t)object
->factory
& (uintptr_t)~0x7;
391 object
->factory
= (AcogcFactory
)(f
| (uintptr_t)flags
);
394 static inline unsigned
395 acogc_object_factory_ecru_ (AcogcObject object
)
397 return acogc_object_factory_get_ (object
)->ecru_color
;
400 static inline unsigned
401 acogc_object_factory_white_ (AcogcObject object
)
403 return acogc_flags_ror_ (acogc_object_factory_ecru_ (object
));
406 static inline unsigned
407 acogc_object_factory_black_ (AcogcObject object
)
409 return acogc_flags_rol_ (acogc_object_factory_ecru_ (object
));
412 /* implements a read barrier */
414 acogc_object_touch_really_ (AcogcObject object
);
417 acogc_object_touch (void* object
)
419 AcogcObject o
= acogc_object_from_memory_ (object
);
420 if (acogc_object_flags_get_ (o
) == acogc_object_factory_ecru_ (o
))
421 acogc_object_touch_really_ (o
);
425 acogc_object_initialized (void* object
)
427 AcogcObject o
= acogc_object_from_memory_ (object
);
428 ACOGC_ASSERT (acogc_object_flags_get_ (o
) == ACOGC_FLAG_UNINITIALIZED
, "object is not uninitialized");
429 acogc_object_set_flags_ (o
, acogc_object_factory_black_ (o
));
430 --acogc_object_factory_get_ (o
)->gc_lock
;
434 /* register a object as GC root object, should be done as soon as possible after allocation */
436 acogc_object_addroot (void* object
);
438 /* unregister a GC root object, it becomes normal collectable by this. */
440 acogc_object_removeroot (void* object
);
448 weak references are lists which must be maintained by the programmer
450 struct acogc_weakreference_struct
452 AcogcWeakReference next
;
457 acogc_weakreference_init (AcogcWeakReference self
)
459 self
->next
= self
->ref
= NULL
;
463 intrusive weak references:
464 objects which allow weak references to them need to implement a
466 AcogcReference member; head of a linked list, initialized to NULL
468 when the object is collected one must use acogc_reference_weak_invalidate with this pointer to invalidate all weak refs. This can be done in sweep_finalizer or in free_finalizer. It becomes possible that weak references point to dead, not yet freed objects one should then use acogc_object_reinstantiate to make the object life again and establish a some normal reference to this object, else it will be collected soon again and become dead.
470 A weak reference is of type acogc_reference with both members initialized to NULL
472 a weak reference is set up with acogc_reference_link_weak and one must not forget to acogc_reference_weak_unlink before the reference object gets deleted
476 acogc_weakreference_link (AcogcWeakReference self
, void* object
);
479 acogc_weakreference_unlink (AcogcWeakReference self
);
482 acogc_object_weakreference_invalidate (void* object
);
486 when a object is swept but still not freed it can be reinstatiated (for example if a weak-reference points to it)
489 /* dereference a weak reference, reinstantiate it if required */
491 acogc_weakreference_reinstget (AcogcWeakReference self
);
493 /* dereference a weak reference, do not reinstantiate it, return NULL if in freelist */
495 acogc_weakreference_get (AcogcWeakReference self
);
498 //enum acogc_reference_state
499 //acogc_reference_state (AcogcWeakReference self);
502 acogc_reference_assert_cleared (AcogcWeakReference p
);
504 /* declare a weak reference als automatic variable, asserts that the reference gets unlinked when the stackframe is left (-DEBUG_ACOGC on gcc only) */
505 #define ACOGC_WEAKREFERENCE(name) acogc_weakreference name ACOGC_CLEANUP(acogc_weakreference_assert_cleared) = {NULL, NULL}
507 #define ACOGC_REFERENCE_INIT(name) acogc_weakreference name ACOGC_CLEANUP(acogc_weakreference_assert_cleared) = {NULL, NULL}
514 // c-file-style: "gnu"
516 // arch-tag: 855b7025-8227-4892-ac25-9b0a3d57dd0b