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

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

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


Revision 1.12 - (show annotations) (download) (as text)
Sat Jan 8 21:23:14 2000 UTC (19 years, 7 months ago) by per
Branch: MAIN
CVS Tags: eggdrop104030RC2, eggdrop10403RC1, eggdrop10402RC1, eggdrop10404, eggdrop10403, eggdrop10402, HEAD
Changes since 1.11: +2 -2 lines
File MIME type: text/x-chdr
copyright

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23