]> jfr.im git - irc/quakenet/newserv.git/blob - core/nsmalloc.c
Merge.
[irc/quakenet/newserv.git] / core / nsmalloc.c
1 /* nsmalloc: Simple pooled malloc() thing. */
2
3 #include <stdlib.h>
4
5 #include "nsmalloc.h"
6 #define __NSMALLOC_C
7 #undef __NSMALLOC_H
8 #include "nsmalloc.h"
9
10 #include "../core/hooks.h"
11 #include "../core/error.h"
12
13 struct nsmpool nsmpools[MAXPOOL];
14
15 #ifndef USE_NSMALLOC_VALGRIND
16
17 void *nsmalloc(unsigned int poolid, size_t size) {
18 struct nsminfo *nsmp;
19
20 if (poolid >= MAXPOOL)
21 return NULL;
22
23 /* Allocate enough for the structure and the required data */
24 nsmp=(struct nsminfo *)malloc(sizeof(struct nsminfo)+size);
25
26 if (!nsmp)
27 return NULL;
28
29 nsmp->size=size;
30 nsmpools[poolid].size+=size;
31 nsmpools[poolid].count++;
32
33 nsmp->next=nsmpools[poolid].first.next;
34 nsmp->prev=&nsmpools[poolid].first;
35 if (nsmpools[poolid].first.next)
36 nsmpools[poolid].first.next->prev=nsmp;
37 nsmpools[poolid].first.next=nsmp;
38
39 return (void *)nsmp->data;
40 }
41
42 /* we dump core on ptr == NULL */
43 void nsfree(unsigned int poolid, void *ptr) {
44 struct nsminfo *nsmp;
45
46 if (!ptr || poolid >= MAXPOOL)
47 return;
48
49 /* evil */
50 nsmp=(struct nsminfo*)ptr - 1;
51
52 /* always set as we have a sentinel */
53 nsmp->prev->next=nsmp->next;
54 if (nsmp->next)
55 nsmp->next->prev=nsmp->prev;
56
57 nsmpools[poolid].size-=nsmp->size;
58 nsmpools[poolid].count--;
59
60 free(nsmp);
61 return;
62 }
63
64 void *nsrealloc(unsigned int poolid, void *ptr, size_t size) {
65 struct nsminfo *nsmp, *nsmpn;
66
67 if (ptr == NULL)
68 return nsmalloc(poolid, size);
69
70 if (size == 0) {
71 nsfree(poolid, ptr);
72 return NULL;
73 }
74
75 if (poolid >= MAXPOOL)
76 return NULL;
77
78 /* evil */
79 nsmp=(struct nsminfo *)ptr - 1;
80
81 if (size == nsmp->size)
82 return (void *)nsmp->data;
83
84 nsmpn=(struct nsminfo *)realloc(nsmp, sizeof(struct nsminfo)+size);
85 if (!nsmpn)
86 return NULL;
87
88 nsmpools[poolid].size+=size-nsmpn->size;
89 nsmpn->size=size;
90
91 /* always set as we have a sentinel */
92 nsmpn->prev->next=nsmpn;
93
94 if (nsmpn->next)
95 nsmpn->next->prev=nsmpn;
96
97 return (void *)nsmpn->data;
98 }
99
100 void nsfreeall(unsigned int poolid) {
101 struct nsminfo *nsmp, *nnsmp;
102
103 if (poolid >= MAXPOOL)
104 return;
105
106 for (nsmp=nsmpools[poolid].first.next;nsmp;nsmp=nnsmp) {
107 nnsmp=nsmp->next;
108 free(nsmp);
109 }
110
111 nsmpools[poolid].first.next=NULL;
112 nsmpools[poolid].size=0;
113 nsmpools[poolid].count=0;
114 }
115
116 void nscheckfreeall(unsigned int poolid) {
117 if (poolid >= MAXPOOL)
118 return;
119
120 if (nsmpools[poolid].first.next) {
121 Error("core",ERR_INFO,"nsmalloc: Blocks still allocated in pool #%d (%s): %lub, %lu items",poolid,nsmpoolnames[poolid]?nsmpoolnames[poolid]:"??",nsmpools[poolid].size,nsmpools[poolid].count);
122 nsfreeall(poolid);
123 }
124 }
125
126 void nsexit(void) {
127 unsigned int i;
128
129 for (i=0;i<MAXPOOL;i++)
130 nsfreeall(i);
131 }
132
133 #else
134
135 void *nsmalloc(unsigned int poolid, size_t size) {
136 return malloc(size);
137 }
138
139 void *nsrealloc(unsigned int poolid, void *ptr, size_t size) {
140 return realloc(ptr, size);
141 }
142
143 void nsfree(unsigned int poolid, void *ptr) {
144 if(ptr)
145 free(ptr);
146 }
147
148 void nsfreeall(unsigned int poolid) {
149 }
150
151 void nsexit(void) {
152 }
153
154 void nscheckfreeall(unsigned int poolid) {
155 }
156
157 #endif
158