]> mj.ucw.cz Git - libucw.git/blob - lib/pool.c
8c352f0fa9f83081cbf92551fa09179a52375958
[libucw.git] / lib / pool.c
1 /*
2  *      Sherlock Library -- Memory Pools (One-Time Allocation)
3  *
4  *      (c) 1997 Martin Mares, <mj@atrey.karlin.mff.cuni.cz>
5  */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9
10 #include "lib.h"
11 #include "pools.h"
12
13 struct memchunk {
14   struct memchunk *next;
15   byte data[0];
16 };
17
18 struct mempool *
19 new_pool(uns size)
20 {
21   struct mempool *p = xmalloc(sizeof(struct mempool));
22
23   size -= sizeof(struct memchunk);
24   p->free = p->last = NULL;
25   p->first = p->current = p->first_large = NULL;
26   p->plast = &p->first;
27   p->chunk_size = size;
28   p->threshold = size / 3;
29   return p;
30 }
31
32 void
33 free_pool(struct mempool *p)
34 {
35   struct memchunk *c, *d;
36
37   for(d=p->first; d; d = c)
38     {
39       c = d->next;
40       free(d);
41     }
42   for(d=p->first_large; d; d = c)
43     {
44       c = d->next;
45       free(d);
46     }
47   free(p);
48 }
49
50 void
51 flush_pool(struct mempool *p)
52 {
53   struct memchunk *c;
54
55   p->free = p->last = NULL;
56   p->current = p->first;
57   while (c = p->first_large)
58     {
59       p->first_large = c->next;
60       free(c);
61     }
62 }
63
64 void *
65 pool_alloc(struct mempool *p, uns s)
66 {
67   if (s <= p->threshold)
68     {
69       byte *x = (byte *)(((uns) p->free + POOL_ALIGN - 1) & ~(POOL_ALIGN - 1));
70       if (x + s > p->last)
71         {
72           struct memchunk *c;
73
74           if (p->current && p->current->next)
75             /* Still have free chunks from previous incarnation */
76             c = p->current->next;
77           else
78             {
79               c = xmalloc(sizeof(struct memchunk) + p->chunk_size);
80               *p->plast = c;
81               p->plast = &c->next;
82               c->next = NULL;
83             }
84           p->current = c;
85           x = c->data;
86           p->last = x + p->chunk_size;
87         }
88       p->free = x + s;
89       return x;
90     }
91   else
92     {
93       struct memchunk *c = xmalloc(sizeof(struct memchunk) + s);
94       c->next = p->first_large;
95       p->first_large = c;
96       return c->data;
97     }
98 }