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