]> mj.ucw.cz Git - libucw.git/blobdiff - lib/pool.c
sign mismatch fixed
[libucw.git] / lib / pool.c
index 8b6c73e1427fdbe97ec8547d58d15b93e70b66fe..4eea7bf700f8e0ab0981bd22c0f2b3933050f546 100644 (file)
@@ -1,14 +1,14 @@
 /*
  *     Sherlock Library -- Memory Pools (One-Time Allocation)
  *
- *     (c) 1997 Martin Mares, <mj@atrey.karlin.mff.cuni.cz>
+ *     (c) 1997--2001 Martin Mares <mj@ucw.cz>
  */
 
-#include <stdio.h>
-#include <stdlib.h>
+#include "lib/lib.h"
+#include "lib/pools.h"
 
-#include "lib.h"
-#include "pools.h"
+#include <stdlib.h>
+#include <string.h>
 
 struct memchunk {
   struct memchunk *next;
@@ -16,43 +16,74 @@ struct memchunk {
 };
 
 struct mempool *
-new_pool(uns size)
+mp_new(uns size)
 {
   struct mempool *p = xmalloc(sizeof(struct mempool));
 
   size -= sizeof(struct memchunk);
-  p->chunks = NULL;
   p->free = p->last = NULL;
+  p->first = p->current = p->first_large = NULL;
+  p->plast = &p->first;
   p->chunk_size = size;
   p->threshold = size / 3;
   return p;
 }
 
 void
-free_pool(struct mempool *p)
+mp_delete(struct mempool *p)
 {
-  struct memchunk *c = p->chunks;
+  struct memchunk *c, *d;
 
-  while (c)
+  for(d=p->first; d; d = c)
     {
-      struct memchunk *n = c->next;
-      free(c);
-      c = n;
+      c = d->next;
+      xfree(d);
+    }
+  for(d=p->first_large; d; d = c)
+    {
+      c = d->next;
+      xfree(d);
+    }
+  xfree(p);
+}
+
+void
+mp_flush(struct mempool *p)
+{
+  struct memchunk *c;
+
+  p->free = p->last = NULL;
+  p->current = p->first;
+  while (c = p->first_large)
+    {
+      p->first_large = c->next;
+      xfree(c);
     }
-  free(p);
 }
 
 void *
-pool_alloc(struct mempool *p, uns s)
+mp_alloc(struct mempool *p, uns s)
 {
   if (s <= p->threshold)
     {
       byte *x = (byte *)(((uns) p->free + POOL_ALIGN - 1) & ~(POOL_ALIGN - 1));
       if (x + s > p->last)
        {
-         struct memchunk *c = xmalloc(sizeof(struct memchunk) + p->chunk_size);
-         c->next = p->chunks;
-         p->chunks = c;
+         struct memchunk *c;
+
+         if (p->current)
+           {
+             /* Still have free chunks from previous incarnation */
+             c = p->current;
+             p->current = c->next;
+           }
+         else
+           {
+             c = xmalloc(sizeof(struct memchunk) + p->chunk_size);
+             *p->plast = c;
+             p->plast = &c->next;
+             c->next = NULL;
+           }
          x = c->data;
          p->last = x + p->chunk_size;
        }
@@ -62,8 +93,16 @@ pool_alloc(struct mempool *p, uns s)
   else
     {
       struct memchunk *c = xmalloc(sizeof(struct memchunk) + s);
-      c->next = p->chunks;
-      p->chunks = c;
+      c->next = p->first_large;
+      p->first_large = c;
       return c->data;
     }
 }
+
+void *
+mp_alloc_zero(struct mempool *p, uns s)
+{
+  void *x = mp_alloc(p, s);
+  bzero(x, s);
+  return x;
+}