From cc989498013e9f76d9ce1db53cc2be62e7894de1 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Tue, 9 Jan 2007 10:19:01 +0100 Subject: [PATCH] new collection policy again, much better now --- lib/acogc.c | 23 ++++++++++++++++++++--- lib/acogc.h | 5 +---- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/lib/acogc.c b/lib/acogc.c index ebcc8e5..e18eb3c 100644 --- a/lib/acogc.c +++ b/lib/acogc.c @@ -49,6 +49,7 @@ acogc_root_init (AcogcRoot self) INFO (acogc, "self %p", self); llist_init (&self->factories); self->allocation_counter = 0; + self->collection_freq = 32; self->stack = NULL; self->last = NULL; self->nomemhandler = NULL; @@ -187,10 +188,15 @@ acogc_root_collect (AcogcRoot self, acogc_freeing_policy pol) abort(); } + unsigned long had_objects = 0; + unsigned long freed_objects = 0; + LLIST_FOREACH (&self->factories, fnode) { AcogcFactory f = LLIST_TO_STRUCTP (fnode, acogc_factory, factories); + had_objects += f->objects_allocated; + unsigned keep_limit = 0; switch (pol) { @@ -218,6 +224,8 @@ acogc_root_collect (AcogcRoot self, acogc_freeing_policy pol) while (!llist_is_empty (&f->dead) && (f->objects_used * 100 / f->objects_allocated > keep_limit)) { + ++freed_objects; + NOTICE (acogc_collect, "free rate: %lu", f->objects_used * 100 / f->objects_allocated); AcogcObject tmp = LLIST_TO_STRUCTP (llist_get_head (&f->dead), acogc_object, node); @@ -235,6 +243,9 @@ acogc_root_collect (AcogcRoot self, acogc_freeing_policy pol) NOTICE (acogc_collect, "allocated %lu, used %lu, ", f->objects_allocated,f->objects_used); } + if (freed_objects > 16) + self->collection_freq = self->collection_freq * (had_objects-freed_objects) / had_objects +1; + NOTICE_DBG (acogc_collect, "collection complete"); } @@ -297,16 +308,22 @@ acogc_factory_alloc (AcogcFactory self) /* maybe call a collection if the freelist is empty */ if (llist_is_empty (&self->dead) && - self->objects_allocated - ? self->objects_new * 100 / self->objects_allocated > (self->low_water + self->high_water)/2 - : 0) + self->root->allocation_counter > self->root->collection_freq) { acogc_root_collect (self->root, ACOGC_COLLECT_NORMAL); + if (self->objects_allocated && + 100 - (self->objects_used * 100 / self->objects_allocated) < self->low_water) + { + // collected less than low_water, increase collection_freq and allocate + self->root->collection_freq = self->root->collection_freq*3/2 +1; + goto allocate; + } } if (llist_is_empty (&self->dead)) { /* allocate a new object */ + allocate: object = NULL; acogc_alloc (&object, sizeof (acogc_object) + self->size, self->root); diff --git a/lib/acogc.h b/lib/acogc.h index f3bb6ee..b865c23 100644 --- a/lib/acogc.h +++ b/lib/acogc.h @@ -186,6 +186,7 @@ struct acogc_root_struct AcogcStack stack; unsigned long allocation_counter; /* counts every allocation since the last collection */ + unsigned long collection_freq; /* number of objects allocated since last collection */ AcogcObject last; /* buffer for last-call marking*/ @@ -424,10 +425,6 @@ acogc_weakref_assert_cleared (AcogcWeakref p); if no memory is available and call the registered nomemhandler. This functions are guranteed to be interchangeable with malloc/realloc/free as long the pointer doesn't hold a reference, see below. - - as special feature a address can be setref'ed to another address, - the lowest bit is used to indicate this. So only aligned addresses are - allowed for this. use the acogc_deref() function to mask it out. */ /* -- 2.11.4.GIT