]> mj.ucw.cz Git - libucw.git/blob - lib/mempool.c
Merge with git+ssh://git.ucw.cz/projects/sherlock/GIT/sherlock.git#v3.10.1
[libucw.git] / lib / mempool.c
1 /*
2  *      UCW Library -- Memory Pools (One-Time Allocation)
3  *
4  *      (c) 1997--2001 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #include "lib/lib.h"
11 #include "lib/mempool.h"
12
13 #include <string.h>
14
15 struct memchunk {
16   struct memchunk *next;
17   byte data[0];
18 };
19
20 struct mempool *
21 mp_new(uns size)
22 {
23   struct mempool *p = xmalloc(sizeof(struct mempool));
24
25   size -= sizeof(struct memchunk);
26   p->free = p->last = NULL;
27   p->first = p->current = p->first_large = NULL;
28   p->plast = &p->first;
29   p->chunk_size = size;
30   p->threshold = size / 3;
31   return p;
32 }
33
34 void
35 mp_delete(struct mempool *p)
36 {
37   struct memchunk *c, *d;
38
39   for(d=p->first; d; d = c)
40     {
41       c = d->next;
42       xfree(d);
43     }
44   for(d=p->first_large; d; d = c)
45     {
46       c = d->next;
47       xfree(d);
48     }
49   xfree(p);
50 }
51
52 void
53 mp_flush(struct mempool *p)
54 {
55   struct memchunk *c;
56
57   p->free = p->last = NULL;
58   p->current = p->first;
59   while (c = p->first_large)
60     {
61       p->first_large = c->next;
62       xfree(c);
63     }
64 }
65
66 void *
67 mp_alloc(struct mempool *p, uns s)
68 {
69   if (s <= p->threshold)
70     {
71       byte *x = (byte *)(((uintptr_t) p->free + POOL_ALIGN - 1) & ~(uintptr_t)(POOL_ALIGN - 1));
72       if (x + s > p->last)
73         {
74           struct memchunk *c;
75
76           if (p->current)
77             {
78               /* Still have free chunks from previous incarnation */
79               c = p->current;
80               p->current = c->next;
81             }
82           else
83             {
84               c = xmalloc(sizeof(struct memchunk) + p->chunk_size);
85               *p->plast = c;
86               p->plast = &c->next;
87               c->next = NULL;
88             }
89           x = c->data;
90           p->last = x + p->chunk_size;
91         }
92       p->free = x + s;
93       return x;
94     }
95   else
96     {
97       struct memchunk *c = xmalloc(sizeof(struct memchunk) + s);
98       c->next = p->first_large;
99       p->first_large = c;
100       return c->data;
101     }
102 }
103
104 void *
105 mp_alloc_zero(struct mempool *p, uns s)
106 {
107   void *x = mp_alloc(p, s);
108   bzero(x, s);
109   return x;
110 }