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