ab897c1f3388c587b68d36dda2709bf8fb0a8b86
[yaz-moved-to-github.git] / util / nmem.c
1 /*
2  * Copyright (c) 1995-1997, Index Data.
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: nmem.c,v $
7  * Revision 1.3  1997-07-21 12:47:38  adam
8  * Moved definition of nmem_control and nmem_block.
9  *
10  * Revision 1.2  1995/12/13 13:44:37  quinn
11  * Modified Data1-system to use nmem
12  *
13  * Revision 1.1  1995/11/13  09:27:52  quinn
14  * Fiddling with the variant stuff.
15  *
16  *
17  */
18
19 /*
20  * This is a simple and fairly wasteful little module for nibble memory
21  * allocation. Evemtually we'll put in something better.
22  */
23
24 #include <xmalloc.h>
25 #include <nmem.h>
26
27 #define NMEM_CHUNK (10*1024)
28
29 static nmem_block *freelist = 0;           /* global freelists */
30 static nmem_control *cfreelist = 0;
31
32 static void free_block(nmem_block *p)
33 {
34     p->next = freelist;
35     freelist = p;
36 }
37
38 /*
39  * acquire a block with a minimum of size free bytes.
40  */
41 static nmem_block *get_block(int size)
42 {
43     nmem_block *r, *l;
44
45     for (r = freelist, l = 0; r; l = r, r = r->next)
46         if (r->size >= size)
47             break;
48     if (r)
49         if (l)
50             l->next = r->next;
51         else
52             freelist = r->next;
53     else
54     {
55         int get = NMEM_CHUNK;
56
57         if (get < size)
58             get = size;
59         r = xmalloc(sizeof(*r));
60         r->buf = xmalloc(r->size = get);
61     }
62     r->top = 0;
63     return r;
64 }
65
66 void nmem_reset(NMEM n)
67 {
68     nmem_block *t;
69
70     if (!n)
71         return;
72     while (n->blocks)
73     {
74         t = n->blocks;
75         n->blocks = n->blocks->next;
76         free_block(t);
77     }
78     n->total = 0;
79 }
80
81 void *nmem_malloc(NMEM n, int size)
82 {
83     struct nmem_block *p;
84     char *r;
85
86     if (!n)
87         return xmalloc(size);
88     p = n->blocks;
89     if (!p || p->size - p->top < size)
90     {
91         p = get_block(size);
92         p->next = n->blocks;
93         n->blocks = p;
94     }
95     r = p->buf + p->top;
96     /* align size */
97     p->top += (size + (sizeof(long) - 1)) & ~(sizeof(long) - 1);
98     n->total += size;
99     return r;
100 }
101
102 int nmem_total(NMEM n)
103 {
104     return n->total;
105 }
106
107 NMEM nmem_create(void)
108 {
109     NMEM r = cfreelist;
110     
111     if (r)
112         cfreelist = cfreelist->next;
113     else
114         r = xmalloc(sizeof(*r));
115     r->blocks = 0;
116     r->total = 0;
117     r->next = 0;
118     return r;
119 }
120
121 void nmem_destroy(NMEM n)
122 {
123     if (!n)
124         return;
125     nmem_reset(n);
126     n->next = cfreelist;
127     cfreelist = n;
128 }