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

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

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


Revision 1.1 - (hide annotations) (download) (as text)
Mon Jul 26 21:11:06 2010 UTC (9 years, 2 months ago) by simple
Branch: MAIN
Branch point for: eggheads
File MIME type: text/x-chdr
Initial revision

1 simple 1.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