1 /*
2 * malloc.c --
3 *
4 * Memory allocator.
5 * Magic no longer contains its own version of malloc(), as all modern
6 * operating systems have implementations which are as good or better.
7 *
8 * The main thing this file does is to define mallocMagic and friends.
9 * freeMagic frees the previously requested memory item, not the one
10 * passed as the argument. This allows efficient coding of loops which
11 * run through linked lists and process and free them at the same time.
12 *
13 * ALWAYS use mallocMagic() with freeMagic() and NEVER mix them with
14 * malloc() and free().
15 *
16 * Malloc trace routines have been removed. There are standard methods
17 * to trace memory allocation and magic doesn't need its own built-in
18 * method.
19 *
20 * The Tcl/Tk version of magic makes use of Tcl_Alloc() and Tcl_Free()
21 * which allows the Tcl/Tk version to trace memory using Tcl's methods.
22 *
23 * *********************************************************************
24 * * Copyright (C) 1985, 1990 Regents of the University of California. *
25 * * Permission to use, copy, modify, and distribute this *
26 * * software and its documentation for any purpose and without *
27 * * fee is hereby granted, provided that the above copyright *
28 * * notice appear in all copies. The University of California *
29 * * makes no representations about the suitability of this *
30 * * software for any purpose. It is provided "as is" without *
31 * * express or implied warranty. Export of this software outside *
32 * * of the United States of America may require an export license. *
33 * *********************************************************************
34 */
35
36 #ifndef lint
37 static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/utils/malloc.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
38 #endif /* not lint */
39
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <errno.h>
43 #include <string.h>
44
45 #include "tcltk/tclmagic.h"
46 #include "utils/magic.h"
47 #include "utils/malloc.h"
48
49 /* Normally we're supposed to warn against the use of standard malloc() */
50 /* and free(), but obviously that doesn't apply to this file. */
51
52 #undef malloc
53 #undef free
54
55 /* Imports */
56
57 extern void TxError();
58 extern char *TxGetLine();
59
60 /*
61 * Magic may reference an object after it is free'ed, but only one object.
62 * This is a change from previous versions of Magic, which needed to reference
63 * an arbitrary number of objects before the next call to malloc. Only then
64 * would no further references would be made to free'ed storage.
65 */
66
67 /* Delay free'ing by one call, to accommodate Magic's needs. */
68 static char *freeDelayedItem = NULL;
69
70 /* Local definitions */
71
72 #ifdef MAGIC_WRAPPER
73 #ifdef TCL_MEM_DEBUG
74 #define MallocRoutine(a) ckalloc(a)
75 #define FreeRoutine(a) ckfree(a)
76 #else
77 /* DO NOT USE: Tcl_Alloc is defined with argument (unsigned int) NOT
78 * (size_t) and therefore limits memory allocation to the size of a
79 * 32-bit integer. Just use the normal malloc() and free(). Left as-is
80 * with TCL_MEM_DEBUG with the caveat that one should not use this to
81 * debug a huge design. Valgrind works better anyway.
82 */
83 /* #define MallocRoutine(a) Tcl_Alloc(a) */
84 /* #define FreeRoutine(a) Tcl_Free(a) */
85 #define MallocRoutine(a) malloc(a)
86 #define FreeRoutine(a) free(a)
87 #endif
88 #else
89 #define MallocRoutine(a) malloc(a)
90 #define FreeRoutine(a) free(a)
91 #endif
92
93 /*
94 *---------------------------------------------------------------------
95 * mallocMagic() --
96 *
97 * memory allocator with support for one-delayed-item free'ing
98 *---------------------------------------------------------------------
99 */
100
101 void *
mallocMagic(nbytes)102 mallocMagic(nbytes)
103 size_t nbytes;
104 {
105 void *p;
106
107 if (freeDelayedItem)
108 {
109 /* fprintf(stderr, "freed 0x%x (delayed)\n", freeDelayedItem); fflush(stderr); */
110
111 FreeRoutine(freeDelayedItem);
112 freeDelayedItem=NULL;
113 }
114
115 if ((p = (void *)MallocRoutine(nbytes)) != NULL)
116 {
117 /* fprintf(stderr, "alloc'd %u bytes at 0x%x\n", nbytes, p); fflush(stderr); */
118
119 return p;
120 }
121 else
122 {
123 ASSERT(FALSE, "Can't allocate any more memory.\n");
124 }
125 return NULL;
126 }
127
128 /*
129 *---------------------------------------------------------------------
130 * freeMagic() --
131 *
132 * one-delayed-item memory deallocation
133 *---------------------------------------------------------------------
134 */
135
136 void
freeMagic(cp)137 freeMagic(cp)
138 void *cp;
139 {
140 if (cp == NULL)
141 TxError("freeMagic called with NULL argument.\n");
142 if (freeDelayedItem)
143 {
144 /* fprintf(stderr, "freed 0x%x\n", freeDelayedItem); fflush(stderr); */
145
146 FreeRoutine(freeDelayedItem);
147 }
148 freeDelayedItem=cp;
149 }
150
151 /*
152 *---------------------------------------------------------------------
153 * callocMagic() --
154 *
155 * allocate memory and initialize it to all zero bytes.
156 *---------------------------------------------------------------------
157 */
158
159 void *
callocMagic(nbytes)160 callocMagic(nbytes)
161 size_t nbytes;
162 {
163 void *cp;
164
165 cp = mallocMagic(nbytes);
166 bzero(cp, (size_t) nbytes);
167
168 return (cp);
169 }
170
171