]> jfr.im git - irc/quakenet/newserv.git/blob - core/nsmalloc.c
NEWSEARCH: check for NULL subset pointer in parseopts.
[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 "../core/hooks.h"
12 #include "../core/error.h"
13
14 struct nsmpool nsmpools[MAXPOOL];
15
16 #ifndef USE_NSMALLOC_VALGRIND
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 nsmp->size=size;
31 nsmpools[poolid].size+=size;
32 nsmpools[poolid].count++;
33
34 nsmp->next=nsmpools[poolid].first.next;
35 nsmp->prev=&nsmpools[poolid].first;
36 if (nsmpools[poolid].first.next)
37 nsmpools[poolid].first.next->prev=nsmp;
38 nsmpools[poolid].first.next=nsmp;
39
40 return (void *)nsmp->data;
41 }
42
43 void *nscalloc(unsigned int poolid, size_t nmemb, size_t size) {
44 size_t total = nmemb * size;
45 void *m;
46
47 m = nsmalloc(poolid, total);
48 if(!m)
49 return NULL;
50
51 memset(m, 0, total);
52
53 return m;
54 }
55
56 /* we dump core on ptr == NULL */
57 void nsfree(unsigned int poolid, void *ptr) {
58 struct nsminfo *nsmp;
59
60 if (!ptr || poolid >= MAXPOOL)
61 return;
62
63 /* evil */
64 nsmp=(struct nsminfo*)ptr - 1;
65
66 /* always set as we have a sentinel */
67 nsmp->prev->next=nsmp->next;
68 if (nsmp->next)
69 nsmp->next->prev=nsmp->prev;
70
71 nsmpools[poolid].size-=nsmp->size;
72 nsmpools[poolid].count--;
73
74 free(nsmp);
75 return;
76 }
77
78 void *nsrealloc(unsigned int poolid, void *ptr, size_t size) {
79 struct nsminfo *nsmp, *nsmpn;
80
81 if (ptr == NULL)
82 return nsmalloc(poolid, size);
83
84 if (size == 0) {
85 nsfree(poolid, ptr);
86 return NULL;
87 }
88
89 if (poolid >= MAXPOOL)
90 return NULL;
91
92 /* evil */
93 nsmp=(struct nsminfo *)ptr - 1;
94
95 if (size == nsmp->size)
96 return (void *)nsmp->data;
97
98 nsmpn=(struct nsminfo *)realloc(nsmp, sizeof(struct nsminfo)+size);
99 if (!nsmpn)
100 return NULL;
101
102 nsmpools[poolid].size+=size-nsmpn->size;
103 nsmpn->size=size;
104
105 /* always set as we have a sentinel */
106 nsmpn->prev->next=nsmpn;
107
108 if (nsmpn->next)
109 nsmpn->next->prev=nsmpn;
110
111 return (void *)nsmpn->data;
112 }
113
114 void nsfreeall(unsigned int poolid) {
115 struct nsminfo *nsmp, *nnsmp;
116
117 if (poolid >= MAXPOOL)
118 return;
119
120 for (nsmp=nsmpools[poolid].first.next;nsmp;nsmp=nnsmp) {
121 nnsmp=nsmp->next;
122 free(nsmp);
123 }
124
125 nsmpools[poolid].first.next=NULL;
126 nsmpools[poolid].size=0;
127 nsmpools[poolid].count=0;
128 }
129
130 void nscheckfreeall(unsigned int poolid) {
131 if (poolid >= MAXPOOL)
132 return;
133
134 if (nsmpools[poolid].first.next) {
135 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);
136 nsfreeall(poolid);
137 }
138 }
139
140 void nsexit(void) {
141 unsigned int i;
142
143 for (i=0;i<MAXPOOL;i++)
144 nsfreeall(i);
145 }
146
147 #else
148
149 void *nsmalloc(unsigned int poolid, size_t size) {
150 return malloc(size);
151 }
152
153 void *nscalloc(unsigned int poolid, size_t nmemb, size_t size) {
154 return calloc(nmemb, size);
155 }
156
157 void *nsrealloc(unsigned int poolid, void *ptr, size_t size) {
158 return realloc(ptr, size);
159 }
160
161 void nsfree(unsigned int poolid, void *ptr) {
162 if(ptr)
163 free(ptr);
164 }
165
166 void nsfreeall(unsigned int poolid) {
167 }
168
169 void nsexit(void) {
170 }
171
172 void nscheckfreeall(unsigned int poolid) {
173 }
174
175 #endif
176