/[cvs]/eggdrop1.8/src/mem.c
ViewVC logotype

Contents of /eggdrop1.8/src/mem.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1.1.1 - (show annotations) (download) (as text) (vendor branch)
Mon Jul 26 21:11:06 2010 UTC (8 years, 10 months ago) by simple
Branch: eggheads
CVS Tags: v1
Changes since 1.1: +0 -0 lines
File MIME type: text/x-chdr
Imported Eggdrop 1.6.20

1 /*
2 * mem.c -- handles:
3 * memory allocation and deallocation
4 * keeping track of what memory is being used by whom
5 *
6 * $Id: mem.c,v 1.29 2010/01/03 13:27:32 pseudo Exp $
7 */
8 /*
9 * Copyright (C) 1997 Robey Pointer
10 * Copyright (C) 1999 - 2010 Eggheads Development Team
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 */
26
27 #define MEMTBLSIZE 25000 /* yikes! */
28 #define COMPILING_MEM
29
30 #include "main.h"
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <errno.h>
35
36 #include "mod/modvals.h"
37
38
39 extern module_entry *module_list;
40
41 #ifdef DEBUG_MEM
42 unsigned long memused = 0;
43 static int lastused = 0;
44
45 struct {
46 void *ptr;
47 int size;
48 short line;
49 char file[20];
50 } memtbl[MEMTBLSIZE];
51 #endif
52
53 /* Prototypes */
54 int expected_memory();
55 int expmem_chanprog();
56 int expmem_misc();
57 int expmem_fileq();
58 int expmem_users();
59 int expmem_dccutil();
60 int expmem_botnet();
61 int expmem_tcl();
62 int expmem_tclhash();
63 int expmem_tclmisc();
64 int expmem_net();
65 int expmem_modules();
66 int expmem_language();
67 int expmem_tcldcc();
68 int expmem_dns();
69
70
71 /* Initialize the memory structure
72 */
73 void init_mem()
74 {
75 #ifdef DEBUG_MEM
76 int i;
77
78 for (i = 0; i < MEMTBLSIZE; i++)
79 memtbl[i].ptr = NULL;
80 #endif
81 }
82
83 /* Tell someone the gory memory details
84 */
85 void tell_mem_status(char *nick)
86 {
87 #ifdef DEBUG_MEM
88 float per;
89
90 per = ((lastused * 1.0) / (MEMTBLSIZE * 1.0)) * 100.0;
91 dprintf(DP_HELP, "NOTICE %s :Memory table usage: %d/%d (%.1f%% full)\n",
92 nick, lastused, MEMTBLSIZE, per);
93 #endif
94 dprintf(DP_HELP, "NOTICE %s :Think I'm using about %dk.\n", nick,
95 (int) (expected_memory() / 1024));
96 }
97
98 void tell_mem_status_dcc(int idx)
99 {
100 #ifdef DEBUG_MEM
101 int exp;
102 float per;
103
104 exp = expected_memory(); /* in main.c ? */
105 per = ((lastused * 1.0) / (MEMTBLSIZE * 1.0)) * 100.0;
106 dprintf(idx, "Memory table: %d/%d (%.1f%% full)\n", lastused, MEMTBLSIZE,
107 per);
108 per = ((exp * 1.0) / (memused * 1.0)) * 100.0;
109 if (per != 100.0)
110 dprintf(idx, "Memory fault: only accounting for %d/%ld (%.1f%%)\n",
111 exp, memused, per);
112 dprintf(idx, "Memory table itself occupies an additional %dk static\n",
113 (int) (sizeof(memtbl) / 1024));
114 #endif
115 }
116
117 void debug_mem_to_dcc(int idx)
118 {
119 #ifdef DEBUG_MEM
120 # define MAX_MEM 13
121 unsigned long exp[MAX_MEM], use[MAX_MEM], l;
122 int i, j;
123 char fn[20], sofar[81];
124 module_entry *me;
125 char *p;
126
127 exp[0] = expmem_language();
128 exp[1] = expmem_chanprog();
129 exp[2] = expmem_misc();
130 exp[3] = expmem_users();
131 exp[4] = expmem_net();
132 exp[5] = expmem_dccutil();
133 exp[6] = expmem_botnet();
134 exp[7] = expmem_tcl();
135 exp[8] = expmem_tclhash();
136 exp[9] = expmem_tclmisc();
137 exp[10] = expmem_modules(1);
138 exp[11] = expmem_tcldcc();
139 exp[12] = expmem_dns();
140
141 for (me = module_list; me; me = me->next)
142 me->mem_work = 0;
143
144 for (i = 0; i < MAX_MEM; i++)
145 use[i] = 0;
146
147 for (i = 0; i < lastused; i++) {
148 strcpy(fn, memtbl[i].file);
149 p = strchr(fn, ':');
150 if (p)
151 *p = 0;
152 l = memtbl[i].size;
153 if (!strcmp(fn, "language.c"))
154 use[0] += l;
155 else if (!strcmp(fn, "chanprog.c"))
156 use[1] += l;
157 else if (!strcmp(fn, "misc.c"))
158 use[2] += l;
159 else if (!strcmp(fn, "userrec.c"))
160 use[3] += l;
161 else if (!strcmp(fn, "net.c"))
162 use[4] += l;
163 else if (!strcmp(fn, "dccutil.c"))
164 use[5] += l;
165 else if (!strcmp(fn, "botnet.c"))
166 use[6] += l;
167 else if (!strcmp(fn, "tcl.c"))
168 use[7] += l;
169 else if (!strcmp(fn, "tclhash.c"))
170 use[8] += l;
171 else if (!strcmp(fn, "tclmisc.c"))
172 use[9] += l;
173 else if (!strcmp(fn, "modules.c"))
174 use[10] += l;
175 else if (!strcmp(fn, "tcldcc.c"))
176 use[11] += l;
177 else if (!strcmp(fn, "dns.c"))
178 use[12] += l;
179 else if (p) {
180 for (me = module_list; me; me = me->next)
181 if (!strcmp(fn, me->name))
182 me->mem_work += l;
183 } else
184 dprintf(idx, "Not logging file %s!\n", fn);
185 }
186
187 for (i = 0; i < MAX_MEM; i++) {
188 switch (i) {
189 case 0:
190 strcpy(fn, "language.c");
191 break;
192 case 1:
193 strcpy(fn, "chanprog.c");
194 break;
195 case 2:
196 strcpy(fn, "misc.c");
197 break;
198 case 3:
199 strcpy(fn, "userrec.c");
200 break;
201 case 4:
202 strcpy(fn, "net.c");
203 break;
204 case 5:
205 strcpy(fn, "dccutil.c");
206 break;
207 case 6:
208 strcpy(fn, "botnet.c");
209 break;
210 case 7:
211 strcpy(fn, "tcl.c");
212 break;
213 case 8:
214 strcpy(fn, "tclhash.c");
215 break;
216 case 9:
217 strcpy(fn, "tclmisc.c");
218 break;
219 case 10:
220 strcpy(fn, "modules.c");
221 break;
222 case 11:
223 strcpy(fn, "tcldcc.c");
224 break;
225 case 12:
226 strcpy(fn, "dns.c");
227 break;
228 }
229
230 if (use[i] == exp[i])
231 dprintf(idx, "File '%-10s' accounted for %lu/%lu (ok)\n", fn, exp[i],
232 use[i]);
233 else {
234 dprintf(idx, "File '%-10s' accounted for %lu/%lu (debug follows:)\n",
235 fn, exp[i], use[i]);
236 strcpy(sofar, " ");
237 for (j = 0; j < lastused; j++) {
238 if ((p = strchr(memtbl[j].file, ':')))
239 *p = 0;
240 if (!egg_strcasecmp(memtbl[j].file, fn)) {
241 if (p)
242 sprintf(&sofar[strlen(sofar)], "%-10s/%-4d:(%04d) ",
243 p + 1, memtbl[j].line, memtbl[j].size);
244 else
245 sprintf(&sofar[strlen(sofar)], "%-4d:(%04d) ",
246 memtbl[j].line, memtbl[j].size);
247
248 if (strlen(sofar) > 60) {
249 sofar[strlen(sofar) - 1] = 0;
250 dprintf(idx, "%s\n", sofar);
251 strcpy(sofar, " ");
252 }
253 }
254 if (p)
255 *p = ':';
256 }
257 if (sofar[0]) {
258 sofar[strlen(sofar) - 1] = 0;
259 dprintf(idx, "%s\n", sofar);
260 }
261 }
262 }
263
264 for (me = module_list; me; me = me->next) {
265 Function *f = me->funcs;
266 int expt = 0;
267
268 if ((f != NULL) && (f[MODCALL_EXPMEM] != NULL))
269 expt = f[MODCALL_EXPMEM] ();
270 if (me->mem_work == expt)
271 dprintf(idx, "Module '%-10s' accounted for %lu/%lu (ok)\n", me->name,
272 expt, me->mem_work);
273 else {
274 dprintf(idx, "Module '%-10s' accounted for %lu/%lu (debug follows:)\n",
275 me->name, expt, me->mem_work);
276 strcpy(sofar, " ");
277 for (j = 0; j < lastused; j++) {
278 strcpy(fn, memtbl[j].file);
279 if ((p = strchr(fn, ':')) != NULL) {
280 *p = 0;
281 if (!egg_strcasecmp(fn, me->name)) {
282 sprintf(&sofar[strlen(sofar)], "%-10s/%-4d:(%04X) ", p + 1,
283 memtbl[j].line, memtbl[j].size);
284 if (strlen(sofar) > 60) {
285 sofar[strlen(sofar) - 1] = 0;
286 dprintf(idx, "%s\n", sofar);
287 strcpy(sofar, " ");
288 }
289 *p = ':';
290 }
291 }
292 }
293 if (sofar[0]) {
294 sofar[strlen(sofar) - 1] = 0;
295 dprintf(idx, "%s\n", sofar);
296 }
297 }
298 }
299
300 dprintf(idx, "--- End of debug memory list.\n");
301 #else
302 dprintf(idx, "Compiled without extensive memory debugging (sorry).\n");
303 #endif
304 tell_netdebug(idx);
305 }
306
307 void *n_malloc(int size, const char *file, int line)
308 {
309 void *x;
310
311 #ifdef DEBUG_MEM
312 int i = 0;
313 char *p;
314 #endif
315
316 x = (void *) malloc(size);
317 if (x == NULL) {
318 putlog(LOG_MISC, "*", "*** FAILED MALLOC %s (%d) (%d): %s", file, line,
319 size, strerror(errno));
320 fatal("Memory allocation failed", 0);
321 }
322 #ifdef DEBUG_MEM
323 if (lastused == MEMTBLSIZE) {
324 putlog(LOG_MISC, "*", "*** MEMORY TABLE FULL: %s (%d)", file, line);
325 fatal("Memory table full", 0);
326 }
327 i = lastused;
328 memtbl[i].ptr = x;
329 memtbl[i].line = line;
330 memtbl[i].size = size;
331 p = strrchr(file, '/');
332 strncpy(memtbl[i].file, p ? p + 1 : file, 19);
333 memtbl[i].file[19] = 0;
334 memused += size;
335 lastused++;
336 #endif
337 return x;
338 }
339
340 void *n_realloc(void *ptr, int size, const char *file, int line)
341 {
342 void *x;
343 int i = 0;
344
345 #ifdef DEBUG_MEM
346 char *p;
347 #endif
348
349 /* ptr == NULL is valid. Avoiding duplicate code further down */
350 if (!ptr)
351 return n_malloc(size, file, line);
352
353 x = (void *) realloc(ptr, size);
354 if (x == NULL && size > 0) {
355 i = i;
356 putlog(LOG_MISC, "*", "*** FAILED REALLOC %s (%d)", file, line);
357 return NULL;
358 }
359 #ifdef DEBUG_MEM
360 for (i = 0; (i < lastused) && (memtbl[i].ptr != ptr); i++);
361 if (i == lastused) {
362 putlog(LOG_MISC, "*", "*** ATTEMPTING TO REALLOC NON-MALLOC'D PTR: %s (%d)",
363 file, line);
364 return NULL;
365 }
366 memused -= memtbl[i].size;
367 memtbl[i].ptr = x;
368 memtbl[i].line = line;
369 memtbl[i].size = size;
370 p = strrchr(file, '/');
371 strncpy(memtbl[i].file, p ? p + 1 : file, 19);
372 memtbl[i].file[19] = 0;
373 memused += size;
374 #endif
375 return x;
376 }
377
378 void n_free(void *ptr, const char *file, int line)
379 {
380 int i = 0;
381
382 if (ptr == NULL) {
383 putlog(LOG_MISC, "*", "*** ATTEMPTING TO FREE NULL PTR: %s (%d)",
384 file, line);
385 i = i;
386 return;
387 }
388 #ifdef DEBUG_MEM
389 /* Give tcl builtins an escape mechanism */
390 if (line) {
391 for (i = 0; (i < lastused) && (memtbl[i].ptr != ptr); i++);
392 if (i == lastused) {
393 putlog(LOG_MISC, "*", "*** ATTEMPTING TO FREE NON-MALLOC'D PTR: %s (%d)",
394 file, line);
395 return;
396 }
397 memused -= memtbl[i].size;
398 lastused--;
399 /* We don't want any holes, so if this wasn't the last entry, swap it. */
400 if (i != lastused) {
401 memtbl[i].ptr = memtbl[lastused].ptr;
402 memtbl[i].size = memtbl[lastused].size;
403 memtbl[i].line = memtbl[lastused].line;
404 strcpy(memtbl[i].file, memtbl[lastused].file);
405 }
406 }
407 #endif
408 free(ptr);
409 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23