]> jfr.im git - irc/quakenet/newserv.git/blob - core/nsmalloc.c
Add red zone before allocated blocks.
[irc/quakenet/newserv.git] / core / nsmalloc.c
1 /* nsmalloc: Simple pooled malloc() thing. */
2
3 #include <stdlib.h>
4 #include <string.h>
5
6 #include "nsmalloc.h"
7 #define __NSMALLOC_C
8 #undef __NSMALLOC_H
9 #include "nsmalloc.h"
10
11 #include "../lib/valgrind.h"
12 #include "../lib/memcheck.h"
13 #include "../core/hooks.h"
14 #include "../core/error.h"
15
16 struct nsmpool nsmpools[MAXPOOL];
17
18 void *nsmalloc(unsigned int poolid, size_t size) {
19 struct nsminfo *nsmp;
20
21 if (poolid >= MAXPOOL)
22 return NULL;
23
24 /* Allocate enough for the structure and the required data */
25 nsmp=(struct nsminfo *)malloc(sizeof(struct nsminfo)+size);
26
27 if (!nsmp)
28 return NULL;
29
30 VALGRIND_CREATE_MEMPOOL(nsmp, 0, 0);
31
32 nsmp->size=size;
33 nsmpools[poolid].size+=size;
34 nsmpools[poolid].count++;
35
36 if (nsmpools[poolid].blocks) {
37 nsmpools[poolid].blocks->prev = nsmp;
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);
44
45 nsmp->redzone = REDZONE_MAGIC;
46 VALGRIND_MAKE_MEM_NOACCESS(&nsmp->redzone, sizeof(nsmp->redzone));
47
48 return (void *)nsmp->data;
49 }
50
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
64 void nsfree(unsigned int poolid, void *ptr) {
65 struct nsminfo *nsmp;
66
67 if (!ptr || poolid >= MAXPOOL)
68 return;
69
70 /* evil */
71 nsmp=(struct nsminfo*)ptr - 1;
72
73 VALGRIND_MAKE_MEM_DEFINED(&nsmp->redzone, sizeof(nsmp->redzone));
74 assert(nsmp->redzone == REDZONE_MAGIC);
75
76 if (nsmp->prev) {
77 nsmp->prev->next = nsmp->next;
78 } else
79 nsmpools[poolid].blocks = NULL;
80
81 if (nsmp->next) {
82 nsmp->next->prev = nsmp->prev;
83 }
84
85 nsmpools[poolid].size-=nsmp->size;
86 nsmpools[poolid].count--;
87
88 VALGRIND_MEMPOOL_FREE(nsmp, nsmp->data);
89 free(nsmp);
90 VALGRIND_DESTROY_MEMPOOL(nsmp);
91
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;
104 }
105
106 if (poolid >= MAXPOOL)
107 return NULL;
108
109 /* evil */
110 nsmp=(struct nsminfo *)ptr - 1;
111
112 VALGRIND_MAKE_MEM_DEFINED(nsmp, sizeof(struct nsminfo));
113
114 if (size == nsmp->size)
115 return (void *)nsmp->data;
116
117 nsmpn=(struct nsminfo *)realloc(nsmp, sizeof(struct nsminfo)+size);
118 if (!nsmpn)
119 return NULL;
120
121 VALGRIND_MOVE_MEMPOOL(nsmp, nsmpn);
122
123 nsmpools[poolid].size+=size-nsmpn->size;
124 nsmpn->size=size;
125
126 if (nsmpn->prev) {
127 nsmpn->prev->next=nsmpn;
128 } else
129 nsmpools[poolid].blocks = nsmpn;
130
131 if (nsmpn->next) {
132 nsmpn->next->prev=nsmpn;
133 }
134
135 VALGRIND_MEMPOOL_CHANGE(nsmpn, nsmp->data, nsmpn->data, nsmpn->size);
136
137 return (void *)nsmpn->data;
138 }
139
140 void nsfreeall(unsigned int poolid) {
141 struct nsminfo *nsmp, *nnsmp;
142
143 if (poolid >= MAXPOOL)
144 return;
145
146 for (nsmp=nsmpools[poolid].blocks;nsmp;nsmp=nnsmp) {
147 nnsmp=nsmp->next;
148 VALGRIND_MEMPOOL_FREE(nsmp, nsmp->data);
149 free(nsmp);
150 VALGRIND_DESTROY_MEMPOOL(nsmp);
151 }
152
153 nsmpools[poolid].blocks=NULL;
154 nsmpools[poolid].size=0;
155 nsmpools[poolid].count=0;
156 }
157
158 void nscheckfreeall(unsigned int poolid) {
159 if (poolid >= MAXPOOL)
160 return;
161
162 if (nsmpools[poolid].blocks) {
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);
164 nsfreeall(poolid);
165 }
166 }
167
168 void nsinit(void) {
169 memset(nsmpools, 0, sizeof(nsmpools));
170 }
171
172 void nsexit(void) {
173 unsigned int i;
174
175 for (i=0;i<MAXPOOL;i++)
176 nsfreeall(i);
177 }
178