/[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.2.2.2 - (show annotations) (download) (as text)
Wed Nov 17 13:58:37 2010 UTC (8 years, 6 months ago) by pseudo
Branch: gettext
Changes since 1.2.2.1: +9 -16 lines
File MIME type: text/x-chdr
Removed the old lang system.

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.2.2.1 2010/11/08 10:02:30 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_tcldcc();
67 int expmem_dns();
68 #ifdef TLS
69 int expmem_tls();
70 #endif
71
72 /* Initialize the memory structure
73 */
74 void init_mem()
75 {
76 #ifdef DEBUG_MEM
77 int i;
78
79 for (i = 0; i < MEMTBLSIZE; i++)
80 memtbl[i].ptr = NULL;
81 #endif
82 }
83
84 /* Tell someone the gory memory details
85 */
86 void tell_mem_status(char *nick)
87 {
88 #ifdef DEBUG_MEM
89 float per;
90
91 per = ((lastused * 1.0) / (MEMTBLSIZE * 1.0)) * 100.0;
92 dprintf(DP_HELP, _("NOTICE %s :Memory table usage: %d/%d (%.1f%% full)\n"),
93 nick, lastused, MEMTBLSIZE, per);
94 #endif
95 dprintf(DP_HELP, _("NOTICE %s :Think I'm using about %dk.\n"), nick,
96 (int) (expected_memory() / 1024));
97 }
98
99 void tell_mem_status_dcc(int idx)
100 {
101 #ifdef DEBUG_MEM
102 int exp;
103 float per;
104
105 exp = expected_memory(); /* in main.c ? */
106 per = ((lastused * 1.0) / (MEMTBLSIZE * 1.0)) * 100.0;
107 dprintf(idx, _("Memory table: %d/%d (%.1f%% full)\n"), lastused, MEMTBLSIZE,
108 per);
109 per = ((exp * 1.0) / (memused * 1.0)) * 100.0;
110 if (per != 100.0)
111 dprintf(idx, _("Memory fault: only accounting for %d/%ld (%.1f%%)\n"),
112 exp, memused, per);
113 dprintf(idx, _("Memory table itself occupies an additional %dk static\n"),
114 (int) (sizeof(memtbl) / 1024));
115 #endif
116 }
117
118 void debug_mem_to_dcc(int idx)
119 {
120 #ifdef DEBUG_MEM
121 # ifdef TLS
122 # define MAX_MEM 13
123 # else
124 # define MAX_MEM 12
125 # endif
126 unsigned long exp[MAX_MEM], use[MAX_MEM], l;
127 int i, j;
128 char fn[20], sofar[81];
129 module_entry *me;
130 char *p;
131
132 exp[0] = expmem_dns();
133 exp[1] = expmem_chanprog();
134 exp[2] = expmem_misc();
135 exp[3] = expmem_users();
136 exp[4] = expmem_net();
137 exp[5] = expmem_dccutil();
138 exp[6] = expmem_botnet();
139 exp[7] = expmem_tcl();
140 exp[8] = expmem_tclhash();
141 exp[9] = expmem_tclmisc();
142 exp[10] = expmem_modules(1);
143 exp[11] = expmem_tcldcc();
144 #ifdef TLS
145 exp[12] = expmem_tls();
146 #endif
147
148 for (me = module_list; me; me = me->next)
149 me->mem_work = 0;
150
151 for (i = 0; i < MAX_MEM; i++)
152 use[i] = 0;
153
154 for (i = 0; i < lastused; i++) {
155 strcpy(fn, memtbl[i].file);
156 p = strchr(fn, ':');
157 if (p)
158 *p = 0;
159 l = memtbl[i].size;
160 if (!strcmp(fn, "dns.c"))
161 use[0] += l;
162 else if (!strcmp(fn, "chanprog.c"))
163 use[1] += l;
164 else if (!strcmp(fn, "misc.c"))
165 use[2] += l;
166 else if (!strcmp(fn, "userrec.c"))
167 use[3] += l;
168 else if (!strcmp(fn, "net.c"))
169 use[4] += l;
170 else if (!strcmp(fn, "dccutil.c"))
171 use[5] += l;
172 else if (!strcmp(fn, "botnet.c"))
173 use[6] += l;
174 else if (!strcmp(fn, "tcl.c"))
175 use[7] += l;
176 else if (!strcmp(fn, "tclhash.c"))
177 use[8] += l;
178 else if (!strcmp(fn, "tclmisc.c"))
179 use[9] += l;
180 else if (!strcmp(fn, "modules.c"))
181 use[10] += l;
182 else if (!strcmp(fn, "tcldcc.c"))
183 use[11] += l;
184 #ifdef TLS
185 else if (!strcmp(fn, "tls.c"))
186 use[12] += l;
187 #endif
188 else if (p) {
189 for (me = module_list; me; me = me->next)
190 if (!strcmp(fn, me->name))
191 me->mem_work += l;
192 } else
193 dprintf(idx, _("Not logging file %s!\n"), fn);
194 }
195
196 for (i = 0; i < MAX_MEM; i++) {
197 switch (i) {
198 case 0:
199 strcpy(fn, "dns.c");
200 break;
201 case 1:
202 strcpy(fn, "chanprog.c");
203 break;
204 case 2:
205 strcpy(fn, "misc.c");
206 break;
207 case 3:
208 strcpy(fn, "userrec.c");
209 break;
210 case 4:
211 strcpy(fn, "net.c");
212 break;
213 case 5:
214 strcpy(fn, "dccutil.c");
215 break;
216 case 6:
217 strcpy(fn, "botnet.c");
218 break;
219 case 7:
220 strcpy(fn, "tcl.c");
221 break;
222 case 8:
223 strcpy(fn, "tclhash.c");
224 break;
225 case 9:
226 strcpy(fn, "tclmisc.c");
227 break;
228 case 10:
229 strcpy(fn, "modules.c");
230 break;
231 case 11:
232 strcpy(fn, "tcldcc.c");
233 break;
234 #ifdef TLS
235 case 12:
236 strcpy(fn, "tls.c");
237 break;
238 #endif
239 }
240
241 if (use[i] == exp[i])
242 dprintf(idx, _("File '%-10s' accounted for %lu/%lu (ok)\n"), fn, exp[i],
243 use[i]);
244 else {
245 dprintf(idx, _("File '%-10s' accounted for %lu/%lu (debug follows:)\n"),
246 fn, exp[i], use[i]);
247 strcpy(sofar, " ");
248 for (j = 0; j < lastused; j++) {
249 if ((p = strchr(memtbl[j].file, ':')))
250 *p = 0;
251 if (!egg_strcasecmp(memtbl[j].file, fn)) {
252 if (p)
253 sprintf(&sofar[strlen(sofar)], "%-10s/%-4d:(%04d) ",
254 p + 1, memtbl[j].line, memtbl[j].size);
255 else
256 sprintf(&sofar[strlen(sofar)], "%-4d:(%04d) ",
257 memtbl[j].line, memtbl[j].size);
258
259 if (strlen(sofar) > 60) {
260 sofar[strlen(sofar) - 1] = 0;
261 dprintf(idx, "%s\n", sofar);
262 strcpy(sofar, " ");
263 }
264 }
265 if (p)
266 *p = ':';
267 }
268 if (sofar[0]) {
269 sofar[strlen(sofar) - 1] = 0;
270 dprintf(idx, "%s\n", sofar);
271 }
272 }
273 }
274
275 for (me = module_list; me; me = me->next) {
276 Function *f = me->funcs;
277 int expt = 0;
278
279 if ((f != NULL) && (f[MODCALL_EXPMEM] != NULL))
280 expt = f[MODCALL_EXPMEM] ();
281 if (me->mem_work == expt)
282 dprintf(idx, _("Module '%-10s' accounted for %lu/%lu (ok)\n"), me->name,
283 expt, me->mem_work);
284 else {
285 dprintf(idx, _("Module '%-10s' accounted for %lu/%lu (debug follows:)\n"),
286 me->name, expt, me->mem_work);
287 strcpy(sofar, " ");
288 for (j = 0; j < lastused; j++) {
289 strcpy(fn, memtbl[j].file);
290 if ((p = strchr(fn, ':')) != NULL) {
291 *p = 0;
292 if (!egg_strcasecmp(fn, me->name)) {
293 sprintf(&sofar[strlen(sofar)], "%-10s/%-4d:(%04X) ", p + 1,
294 memtbl[j].line, memtbl[j].size);
295 if (strlen(sofar) > 60) {
296 sofar[strlen(sofar) - 1] = 0;
297 dprintf(idx, "%s\n", sofar);
298 strcpy(sofar, " ");
299 }
300 *p = ':';
301 }
302 }
303 }
304 if (sofar[0]) {
305 sofar[strlen(sofar) - 1] = 0;
306 dprintf(idx, "%s\n", sofar);
307 }
308 }
309 }
310
311 dprintf(idx, _("--- End of debug memory list.\n"));
312 #else
313 dprintf(idx, _("Compiled without extensive memory debugging (sorry).\n"));
314 #endif
315 tell_netdebug(idx);
316 }
317
318 void *n_malloc(int size, const char *file, int line)
319 {
320 void *x;
321
322 #ifdef DEBUG_MEM
323 int i = 0;
324 char *p;
325 #endif
326
327 x = (void *) malloc(size);
328 if (x == NULL) {
329 putlog(LOG_MISC, "*", _("*** FAILED MALLOC %s (%d) (%d): %s"), file, line,
330 size, strerror(errno));
331 fatal(_("Memory allocation failed"), 0);
332 }
333 #ifdef DEBUG_MEM
334 if (lastused == MEMTBLSIZE) {
335 putlog(LOG_MISC, "*", _("*** MEMORY TABLE FULL: %s (%d)"), file, line);
336 fatal(_("Memory table full"), 0);
337 }
338 i = lastused;
339 memtbl[i].ptr = x;
340 memtbl[i].line = line;
341 memtbl[i].size = size;
342 p = strrchr(file, '/');
343 strncpy(memtbl[i].file, p ? p + 1 : file, 19);
344 memtbl[i].file[19] = 0;
345 memused += size;
346 lastused++;
347 #endif
348 return x;
349 }
350
351 void *n_realloc(void *ptr, int size, const char *file, int line)
352 {
353 void *x;
354 int i = 0;
355
356 #ifdef DEBUG_MEM
357 char *p;
358 #endif
359
360 /* ptr == NULL is valid. Avoiding duplicate code further down */
361 if (!ptr)
362 return n_malloc(size, file, line);
363
364 x = (void *) realloc(ptr, size);
365 if (x == NULL && size > 0) {
366 i = i;
367 putlog(LOG_MISC, "*", _("*** FAILED REALLOC %s (%d)"), file, line);
368 return NULL;
369 }
370 #ifdef DEBUG_MEM
371 for (i = 0; (i < lastused) && (memtbl[i].ptr != ptr); i++);
372 if (i == lastused) {
373 putlog(LOG_MISC, "*", _("*** ATTEMPTING TO REALLOC NON-MALLOC'D PTR: %s (%d)"),
374 file, line);
375 return NULL;
376 }
377 memused -= memtbl[i].size;
378 memtbl[i].ptr = x;
379 memtbl[i].line = line;
380 memtbl[i].size = size;
381 p = strrchr(file, '/');
382 strncpy(memtbl[i].file, p ? p + 1 : file, 19);
383 memtbl[i].file[19] = 0;
384 memused += size;
385 #endif
386 return x;
387 }
388
389 void n_free(void *ptr, const char *file, int line)
390 {
391 int i = 0;
392
393 if (ptr == NULL) {
394 putlog(LOG_MISC, "*", _("*** ATTEMPTING TO FREE NULL PTR: %s (%d)"),
395 file, line);
396 i = i;
397 return;
398 }
399 #ifdef DEBUG_MEM
400 /* Give tcl builtins an escape mechanism */
401 if (line) {
402 for (i = 0; (i < lastused) && (memtbl[i].ptr != ptr); i++);
403 if (i == lastused) {
404 putlog(LOG_MISC, "*", _("*** ATTEMPTING TO FREE NON-MALLOC'D PTR: %s (%d)"),
405 file, line);
406 return;
407 }
408 memused -= memtbl[i].size;
409 lastused--;
410 /* We don't want any holes, so if this wasn't the last entry, swap it. */
411 if (i != lastused) {
412 memtbl[i].ptr = memtbl[lastused].ptr;
413 memtbl[i].size = memtbl[lastused].size;
414 memtbl[i].line = memtbl[lastused].line;
415 strcpy(memtbl[i].file, memtbl[lastused].file);
416 }
417 }
418 #endif
419 free(ptr);
420 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23