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