]>
Commit | Line | Data |
---|---|---|
34da4416 | 1 | /* nsmalloc: Simple pooled malloc() thing. */ |
2 | ||
3 | #include <stdlib.h> | |
f358bcd6 | 4 | #include <string.h> |
03d0dab2 | 5 | #include <assert.h> |
34da4416 | 6 | |
7 | #include "nsmalloc.h" | |
271ef2d2 CP |
8 | #define __NSMALLOC_C |
9 | #undef __NSMALLOC_H | |
10 | #include "nsmalloc.h" | |
11 | ||
bf7e91f1 GB |
12 | #include "../lib/valgrind.h" |
13 | #include "../lib/memcheck.h" | |
19f37c5c | 14 | #include "../core/hooks.h" |
34da4416 | 15 | #include "../core/error.h" |
16 | ||
ed24756c | 17 | struct nsmpool nsmpools[MAXPOOL]; |
34da4416 | 18 | |
19 | void *nsmalloc(unsigned int poolid, size_t size) { | |
20 | struct nsminfo *nsmp; | |
21 | ||
22 | if (poolid >= MAXPOOL) | |
23 | return NULL; | |
24 | ||
20d694a5 | 25 | /* Allocate enough for the structure and the required data */ |
26 | nsmp=(struct nsminfo *)malloc(sizeof(struct nsminfo)+size); | |
34da4416 | 27 | |
28 | if (!nsmp) | |
29 | return NULL; | |
bf7e91f1 GB |
30 | |
31 | VALGRIND_CREATE_MEMPOOL(nsmp, 0, 0); | |
32 | ||
48005496 | 33 | nsmp->size=size; |
ed24756c CP |
34 | nsmpools[poolid].size+=size; |
35 | nsmpools[poolid].count++; | |
48005496 | 36 | |
bf7e91f1 | 37 | if (nsmpools[poolid].blocks) { |
bf7e91f1 | 38 | nsmpools[poolid].blocks->prev = nsmp; |
bf7e91f1 GB |
39 | } |
40 | nsmp->next=nsmpools[poolid].blocks; | |
41 | nsmp->prev=NULL; | |
42 | nsmpools[poolid].blocks=nsmp; | |
43 | ||
44 | VALGRIND_MEMPOOL_ALLOC(nsmp, nsmp->data, nsmp->size); | |
b19d9f45 GB |
45 | |
46 | nsmp->redzone = REDZONE_MAGIC; | |
47 | VALGRIND_MAKE_MEM_NOACCESS(&nsmp->redzone, sizeof(nsmp->redzone)); | |
48005496 | 48 | |
34da4416 | 49 | return (void *)nsmp->data; |
50 | } | |
51 | ||
f358bcd6 CP |
52 | void *nscalloc(unsigned int poolid, size_t nmemb, size_t size) { |
53 | size_t total = nmemb * size; | |
54 | void *m; | |
55 | ||
56 | m = nsmalloc(poolid, total); | |
57 | if(!m) | |
58 | return NULL; | |
59 | ||
60 | memset(m, 0, total); | |
61 | ||
62 | return m; | |
63 | } | |
64 | ||
34da4416 | 65 | void nsfree(unsigned int poolid, void *ptr) { |
48005496 | 66 | struct nsminfo *nsmp; |
34da4416 | 67 | |
7b74d6e6 | 68 | if (!ptr || poolid >= MAXPOOL) |
34da4416 | 69 | return; |
48005496 CP |
70 | |
71 | /* evil */ | |
72 | nsmp=(struct nsminfo*)ptr - 1; | |
73 | ||
b19d9f45 GB |
74 | VALGRIND_MAKE_MEM_DEFINED(&nsmp->redzone, sizeof(nsmp->redzone)); |
75 | assert(nsmp->redzone == REDZONE_MAGIC); | |
bf7e91f1 GB |
76 | |
77 | if (nsmp->prev) { | |
bf7e91f1 | 78 | nsmp->prev->next = nsmp->next; |
bf7e91f1 GB |
79 | } else |
80 | nsmpools[poolid].blocks = NULL; | |
81 | ||
82 | if (nsmp->next) { | |
bf7e91f1 | 83 | nsmp->next->prev = nsmp->prev; |
bf7e91f1 | 84 | } |
48005496 | 85 | |
ed24756c CP |
86 | nsmpools[poolid].size-=nsmp->size; |
87 | nsmpools[poolid].count--; | |
48005496 | 88 | |
bf7e91f1 | 89 | VALGRIND_MEMPOOL_FREE(nsmp, nsmp->data); |
48005496 | 90 | free(nsmp); |
bf7e91f1 GB |
91 | VALGRIND_DESTROY_MEMPOOL(nsmp); |
92 | ||
48005496 CP |
93 | return; |
94 | } | |
95 | ||
96 | void *nsrealloc(unsigned int poolid, void *ptr, size_t size) { | |
97 | struct nsminfo *nsmp, *nsmpn; | |
98 | ||
99 | if (ptr == NULL) | |
100 | return nsmalloc(poolid, size); | |
101 | ||
102 | if (size == 0) { | |
103 | nsfree(poolid, ptr); | |
104 | return NULL; | |
34da4416 | 105 | } |
48005496 CP |
106 | |
107 | if (poolid >= MAXPOOL) | |
108 | return NULL; | |
109 | ||
110 | /* evil */ | |
111 | nsmp=(struct nsminfo *)ptr - 1; | |
112 | ||
bf7e91f1 GB |
113 | VALGRIND_MAKE_MEM_DEFINED(nsmp, sizeof(struct nsminfo)); |
114 | ||
b19d9f45 | 115 | if (size == nsmp->size) |
48005496 CP |
116 | return (void *)nsmp->data; |
117 | ||
118 | nsmpn=(struct nsminfo *)realloc(nsmp, sizeof(struct nsminfo)+size); | |
b19d9f45 | 119 | if (!nsmpn) |
48005496 | 120 | return NULL; |
bf7e91f1 GB |
121 | |
122 | VALGRIND_MOVE_MEMPOOL(nsmp, nsmpn); | |
48005496 | 123 | |
ed24756c | 124 | nsmpools[poolid].size+=size-nsmpn->size; |
48005496 CP |
125 | nsmpn->size=size; |
126 | ||
bf7e91f1 | 127 | if (nsmpn->prev) { |
bf7e91f1 | 128 | nsmpn->prev->next=nsmpn; |
bf7e91f1 GB |
129 | } else |
130 | nsmpools[poolid].blocks = nsmpn; | |
48005496 | 131 | |
bf7e91f1 | 132 | if (nsmpn->next) { |
271ef2d2 | 133 | nsmpn->next->prev=nsmpn; |
bf7e91f1 GB |
134 | } |
135 | ||
136 | VALGRIND_MEMPOOL_CHANGE(nsmpn, nsmp->data, nsmpn->data, nsmpn->size); | |
48005496 CP |
137 | |
138 | return (void *)nsmpn->data; | |
34da4416 | 139 | } |
140 | ||
141 | void nsfreeall(unsigned int poolid) { | |
142 | struct nsminfo *nsmp, *nnsmp; | |
143 | ||
144 | if (poolid >= MAXPOOL) | |
145 | return; | |
146 | ||
bf7e91f1 | 147 | for (nsmp=nsmpools[poolid].blocks;nsmp;nsmp=nnsmp) { |
34da4416 | 148 | nnsmp=nsmp->next; |
bf7e91f1 | 149 | VALGRIND_MEMPOOL_FREE(nsmp, nsmp->data); |
34da4416 | 150 | free(nsmp); |
bf7e91f1 | 151 | VALGRIND_DESTROY_MEMPOOL(nsmp); |
34da4416 | 152 | } |
153 | ||
bf7e91f1 | 154 | nsmpools[poolid].blocks=NULL; |
ed24756c CP |
155 | nsmpools[poolid].size=0; |
156 | nsmpools[poolid].count=0; | |
34da4416 | 157 | } |
158 | ||
f8d5cfcf CP |
159 | void nscheckfreeall(unsigned int poolid) { |
160 | if (poolid >= MAXPOOL) | |
161 | return; | |
162 | ||
bf7e91f1 | 163 | if (nsmpools[poolid].blocks) { |
a05832ea | 164 | Error("core",ERR_INFO,"nsmalloc: Blocks still allocated in pool #%d (%s): %zub, %lu items",poolid,nsmpoolnames[poolid]?nsmpoolnames[poolid]:"??",nsmpools[poolid].size,nsmpools[poolid].count); |
f8d5cfcf CP |
165 | nsfreeall(poolid); |
166 | } | |
167 | } | |
168 | ||
bf7e91f1 GB |
169 | void nsinit(void) { |
170 | memset(nsmpools, 0, sizeof(nsmpools)); | |
171 | } | |
172 | ||
19f37c5c | 173 | void nsexit(void) { |
103521a1 | 174 | unsigned int i; |
175 | ||
f8d5cfcf | 176 | for (i=0;i<MAXPOOL;i++) |
88c8f330 | 177 | nsfreeall(i); |
103521a1 | 178 | } |
179 |