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