]> jfr.im git - irc/quakenet/newserv.git/blame - core/nsmalloc.c
Add red zone before allocated blocks.
[irc/quakenet/newserv.git] / core / nsmalloc.c
CommitLineData
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 16struct nsmpool nsmpools[MAXPOOL];
34da4416 17
18void *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
51void *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 64void 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
95void *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
140void 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
158void 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
168void nsinit(void) {
169 memset(nsmpools, 0, sizeof(nsmpools));
170}
171
19f37c5c 172void nsexit(void) {
103521a1 173 unsigned int i;
174
f8d5cfcf 175 for (i=0;i<MAXPOOL;i++)
88c8f330 176 nsfreeall(i);
103521a1 177}
178