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

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

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


Revision 1.12 - (hide 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 guppy 1.10 /*
2 segfault 1.1 * mem.c -- handles:
3 guppy 1.10 * memory allocation and deallocation
4     * keeping track of what memory is being used by whom
5 segfault 1.1 *
6     * dprintf'ized, 15nov1995
7 guppy 1.10 *
8 per 1.12 * $Id: mem.c,v 1.11 1999/12/30 23:23:45 guppy Exp $
9 segfault 1.1 */
10 guppy 1.10 /*
11     * Copyright (C) 1997 Robey Pointer
12 per 1.12 * Copyright (C) 1999, 2000 Eggheads
13 guppy 1.10 *
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 segfault 1.1 */
28    
29     #define LOG_MISC 32
30     #define MEMTBLSIZE 25000 /* yikes! */
31    
32     #if HAVE_CONFIG_H
33 guppy 1.8 # include <config.h>
34 segfault 1.1 #endif
35     #include <stdio.h>
36     #include <stdlib.h>
37     #include <string.h>
38 guppy 1.11 #include <errno.h>
39    
40 segfault 1.1 typedef int (*Function) ();
41 guppy 1.11 #include "mod/modvals.h"
42 segfault 1.1
43     extern module_entry *module_list;
44 guppy 1.11 void fatal(char *, int);
45 segfault 1.1
46 guppy 1.9 #ifdef DEBUG_MEM
47 segfault 1.1 unsigned long memused = 0;
48     static int lastused = 0;
49    
50     struct {
51     void *ptr;
52 poptix 1.2 int size;
53 segfault 1.1 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 guppy 1.7 #if !defined(HAVE_PRE7_5_TCL) && defined(__STDC__)
67 segfault 1.1 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 guppy 1.9 #ifdef DEBUG_MEM
93 segfault 1.1 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 guppy 1.9 #ifdef DEBUG_MEM
104 segfault 1.1 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 guppy 1.9 #ifdef DEBUG_MEM
117 segfault 1.1 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 guppy 1.9 #ifdef DEBUG_MEM
135 segfault 1.1 #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 guppy 1.9 #ifdef DEBUG_MEM
310 segfault 1.1 int i = 0;
311 guppy 1.11 #endif
312 segfault 1.1
313     x = (void *) malloc(size);
314     if (x == NULL) {
315 guppy 1.11 putlog(LOG_MISC, "*", "*** FAILED MALLOC %s (%d) (%d): %s", file, line,
316     size, strerror(errno));
317     fatal("Memory allocation failed", 0);
318 segfault 1.1 }
319 guppy 1.9 #ifdef DEBUG_MEM
320 segfault 1.1 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 poptix 1.3 /* ptr == NULL is valid. Avoiding duplicate code further down */
342     if (!ptr)
343     return n_malloc(size, file, line);
344    
345 segfault 1.1 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 guppy 1.9 #ifdef DEBUG_MEM
352 segfault 1.1 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 guppy 1.9 #ifdef DEBUG_MEM
380 segfault 1.1 /* 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