]>
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); |
e4e0d5a9 | 90 | |
bf7e91f1 | 91 | VALGRIND_DESTROY_MEMPOOL(nsmp); |
e4e0d5a9 | 92 | free(nsmp); |
bf7e91f1 | 93 | |
48005496 CP |
94 | return; |
95 | } | |
96 | ||
97 | void *nsrealloc(unsigned int poolid, void *ptr, size_t size) { | |
98 | struct nsminfo *nsmp, *nsmpn; | |
99 | ||
100 | if (ptr == NULL) | |
101 | return nsmalloc(poolid, size); | |
102 | ||
103 | if (size == 0) { | |
104 | nsfree(poolid, ptr); | |
105 | return NULL; | |
34da4416 | 106 | } |
48005496 CP |
107 | |
108 | if (poolid >= MAXPOOL) | |
109 | return NULL; | |
110 | ||
111 | /* evil */ | |
112 | nsmp=(struct nsminfo *)ptr - 1; | |
113 | ||
bf7e91f1 GB |
114 | VALGRIND_MAKE_MEM_DEFINED(nsmp, sizeof(struct nsminfo)); |
115 | ||
b19d9f45 | 116 | if (size == nsmp->size) |
48005496 CP |
117 | return (void *)nsmp->data; |
118 | ||
119 | nsmpn=(struct nsminfo *)realloc(nsmp, sizeof(struct nsminfo)+size); | |
b19d9f45 | 120 | if (!nsmpn) |
48005496 | 121 | return NULL; |
bf7e91f1 GB |
122 | |
123 | VALGRIND_MOVE_MEMPOOL(nsmp, nsmpn); | |
48005496 | 124 | |
ed24756c | 125 | nsmpools[poolid].size+=size-nsmpn->size; |
48005496 CP |
126 | nsmpn->size=size; |
127 | ||
bf7e91f1 | 128 | if (nsmpn->prev) { |
bf7e91f1 | 129 | nsmpn->prev->next=nsmpn; |
bf7e91f1 GB |
130 | } else |
131 | nsmpools[poolid].blocks = nsmpn; | |
48005496 | 132 | |
bf7e91f1 | 133 | if (nsmpn->next) { |
271ef2d2 | 134 | nsmpn->next->prev=nsmpn; |
bf7e91f1 GB |
135 | } |
136 | ||
137 | VALGRIND_MEMPOOL_CHANGE(nsmpn, nsmp->data, nsmpn->data, nsmpn->size); | |
48005496 CP |
138 | |
139 | return (void *)nsmpn->data; | |
34da4416 | 140 | } |
141 | ||
142 | void nsfreeall(unsigned int poolid) { | |
143 | struct nsminfo *nsmp, *nnsmp; | |
144 | ||
145 | if (poolid >= MAXPOOL) | |
146 | return; | |
147 | ||
bf7e91f1 | 148 | for (nsmp=nsmpools[poolid].blocks;nsmp;nsmp=nnsmp) { |
34da4416 | 149 | nnsmp=nsmp->next; |
bf7e91f1 | 150 | VALGRIND_MEMPOOL_FREE(nsmp, nsmp->data); |
e4e0d5a9 | 151 | |
bf7e91f1 | 152 | VALGRIND_DESTROY_MEMPOOL(nsmp); |
e4e0d5a9 | 153 | free(nsmp); |
34da4416 | 154 | } |
155 | ||
bf7e91f1 | 156 | nsmpools[poolid].blocks=NULL; |
ed24756c CP |
157 | nsmpools[poolid].size=0; |
158 | nsmpools[poolid].count=0; | |
34da4416 | 159 | } |
160 | ||
f8d5cfcf CP |
161 | void nscheckfreeall(unsigned int poolid) { |
162 | if (poolid >= MAXPOOL) | |
163 | return; | |
164 | ||
bf7e91f1 | 165 | if (nsmpools[poolid].blocks) { |
a05832ea | 166 | 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 |
167 | nsfreeall(poolid); |
168 | } | |
169 | } | |
170 | ||
bf7e91f1 GB |
171 | void nsinit(void) { |
172 | memset(nsmpools, 0, sizeof(nsmpools)); | |
173 | } | |
174 | ||
19f37c5c | 175 | void nsexit(void) { |
103521a1 | 176 | unsigned int i; |
177 | ||
f8d5cfcf | 178 | for (i=0;i<MAXPOOL;i++) |
88c8f330 | 179 | nsfreeall(i); |
103521a1 | 180 | } |
181 |