new collection policy again, much better now experimental_signature
authorChristian Thaeter <ct@pipapo.org>
Tue, 9 Jan 2007 09:19:01 +0000 (10:19 +0100)
committerChristian Thaeter <ct@pipapo.org>
Tue, 9 Jan 2007 09:19:01 +0000 (10:19 +0100)
lib/acogc.c
lib/acogc.h

index ebcc8e5..e18eb3c 100644 (file)
@@ -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);
 
index f3bb6ee..b865c23 100644 (file)
@@ -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.
 */
 
 /*