/[svn]/vendor/ircservices-5.1.24/memory.c
ViewVC logotype

Contents of /vendor/ircservices-5.1.24/memory.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3389 - (show annotations)
Fri Apr 25 14:12:15 2014 UTC (5 years, 2 months ago) by michael
File MIME type: text/x-chdr
File size: 9121 byte(s)
- Imported ircservices-5.1.24

1 /* Memory management routines.
2 * Leak checking based on code by Kelmar (2001/1/13).
3 *
4 * IRC Services is copyright (c) 1996-2009 Andrew Church.
5 * E-mail: <achurch@achurch.org>
6 * Parts written by Andrew Kempe and others.
7 * This program is free but copyrighted software; see the file GPL.txt for
8 * details.
9 */
10
11 #define NO_MEMREDEF
12 #include "services.h"
13
14 /*************************************************************************/
15 /*************************************************************************/
16
17 /* smalloc, scalloc, srealloc, sstrdup:
18 * Versions of the memory allocation functions which will cause the
19 * program to terminate with an "Out of memory" error if the memory
20 * cannot be allocated. (Hence, the return value from these functions
21 * is never NULL, except for smalloc()/scalloc() called with a size of
22 * zero.)
23 */
24
25 #if MEMCHECKS
26 # define FILELINE , const char *file, int line
27 # define xmalloc(a) MCmalloc(a,file,line)
28 # define xsmalloc(a) smalloc(a,file,line)
29 # define xcalloc(a,b) MCcalloc(a,b,file,line)
30 # define xrealloc(a,b) MCrealloc(a,b,file,line)
31 # define xfree(a) MCfree(a,file,line)
32 #else
33 # define FILELINE /*nothing*/
34 # define xmalloc(a) malloc(a)
35 # define xsmalloc(a) smalloc(a)
36 # define xcalloc(a,b) calloc(a,b)
37 # define xrealloc(a,b) realloc(a,b)
38 # define xfree(a) free(a)
39 #endif
40
41 /*************************************************************************/
42
43 void *smalloc(long size FILELINE)
44 {
45 void *buf;
46
47 if (size == 0)
48 return NULL;
49 buf = xmalloc(size);
50 if (buf == NULL)
51 raise(SIGUSR1);
52 return buf;
53 }
54
55 /*************************************************************************/
56
57 void *scalloc(long els, long elsize FILELINE)
58 {
59 void *buf;
60
61 if (elsize == 0 || els == 0)
62 return NULL;
63 buf = xcalloc(elsize, els);
64 if (buf == NULL)
65 raise(SIGUSR1);
66 return buf;
67 }
68
69 /*************************************************************************/
70
71 void *srealloc(void *oldptr, long newsize FILELINE)
72 {
73 void *buf;
74
75 if (newsize == 0) {
76 xfree(oldptr);
77 return NULL;
78 }
79 buf = xrealloc(oldptr, newsize);
80 if (buf == NULL)
81 raise(SIGUSR1);
82 return buf;
83 }
84
85 /*************************************************************************/
86
87 char *sstrdup(const char *s FILELINE)
88 {
89 char *t = xsmalloc(strlen(s) + 1);
90 strcpy(t, s); /* safe, obviously */
91 return t;
92 }
93
94 /*************************************************************************/
95 /************ Everything from here down is MEMCHECKS-related. ************/
96 /*************************************************************************/
97
98 #if MEMCHECKS
99
100 /*************************************************************************/
101
102 static long allocated = 0; /* Amount of memory currently allocated */
103 static long runtime = 0; /* `allocated' value at init_memory() time */
104
105 # if SHOWALLOCS
106 int showallocs = 1; /* Actually log allocations? */
107 # endif
108
109 typedef struct _smemblock {
110 long size; /* Size of this block */
111 int32 sig; /* Signature word: 0x5AFEC0DE */
112 } MemBlock;
113 # define SIGNATURE 0x5AFEC0DE
114 # define FREE_SIGNATURE 0xDEADBEEF /* Used for freed memory */
115 # define NEW_FILL 0xD017D017 /* New allocs are filled with this */
116 # define FREE_FILL 0xBEEF1E57 /* Freed memory is filled with this */
117
118 # define MEMBLOCK_TO_PTR(mb) ((void *)((char *)(mb) + sizeof(MemBlock)))
119 # define PTR_TO_MEMBLOCK(ptr) ((MemBlock *)((char *)(ptr) - sizeof(MemBlock)))
120
121
122 /*************************************************************************/
123 /*************************************************************************/
124
125 /* Leak-checking initialization and exit code. */
126
127 static void show_leaks(void)
128 {
129 if (runtime >= 0 && (allocated - runtime) > 0) {
130 log("SAFEMEM: There were %ld bytes leaked on exit!",
131 (allocated - runtime));
132 } else {
133 log("SAFEMEM: No memory leaks detected.");
134 }
135 }
136
137 void init_memory(void)
138 {
139 runtime = allocated;
140 log("init_memory(): runtime = %ld", runtime);
141 atexit(show_leaks);
142 }
143
144 /* Used to avoid memory-leak message from the parent process */
145 void uninit_memory(void)
146 {
147 runtime = -1;
148 }
149
150 /*************************************************************************/
151
152 /* Helper to fill memory with a given 32-bit value. */
153
154 static inline void fill32(void *ptr, uint32 value, long size)
155 {
156 register uint32 *ptr32 = ptr;
157 register uint32 v = value;
158 while (size >= 4) {
159 *ptr32++ = v;
160 size -= 4;
161 }
162 if (size > 0)
163 memcpy(ptr32, &value, size);
164 }
165
166 /*************************************************************************/
167 /*************************************************************************/
168
169 /* Substitutes for malloc() and friends. memory.h redefines malloc(), etc.
170 * to these functions if MEMCHECKS is defined. */
171
172 /*************************************************************************/
173
174 void *MCmalloc(long size, const char *file, int line)
175 {
176 MemBlock *mb;
177 void *data;
178
179 if (size == 0)
180 return NULL;
181 mb = malloc(size + sizeof(MemBlock));
182 if (mb) {
183 mb->size = size;
184 mb->sig = SIGNATURE;
185 data = MEMBLOCK_TO_PTR(mb);
186 allocated += size;
187 # if SHOWALLOCS
188 if (showallocs) {
189 log("smalloc(): Allocated %ld bytes at %p (%s:%d)",
190 size, data, file, line);
191 }
192 # endif
193 fill32(data, NEW_FILL, size);
194 return data;
195 } else {
196 # if SHOWALLOCS
197 if (showallocs) {
198 log("mcalloc(): Unable to allocate %ld bytes (%s:%d)",
199 size, file, line);
200 }
201 # endif
202 return NULL;
203 }
204 }
205
206 /*************************************************************************/
207
208 void *MCcalloc(long els, long elsize, const char *file, int line)
209 {
210 MemBlock *mb;
211 void *data;
212
213 if (elsize == 0 || els == 0)
214 return NULL;
215 mb = malloc(els*elsize + sizeof(MemBlock));
216 if (mb) {
217 mb->size = elsize * els;
218 mb->sig = SIGNATURE;
219 data = MEMBLOCK_TO_PTR(mb);
220 memset(data, 0, els*elsize);
221 allocated += mb->size;
222 # if SHOWALLOCS
223 if (showallocs) {
224 log("scalloc(): Allocated %ld bytes at %p (%s:%d)",
225 els*elsize, data, file, line);
226 }
227 # endif
228 return data;
229 } else {
230 # if SHOWALLOCS
231 if (showallocs) {
232 log("scalloc(): Unable to allocate %ld bytes (%s:%d)",
233 els*elsize, file, line);
234 }
235 # endif
236 return NULL;
237 }
238 }
239
240 /*************************************************************************/
241
242 void *MCrealloc(void *oldptr, long newsize, const char *file, int line)
243 {
244 MemBlock *newb, *oldb;
245 long oldsize;
246 void *data;
247
248 if (newsize == 0) {
249 MCfree(oldptr, file, line);
250 return NULL;
251 }
252 if (oldptr == NULL)
253 return MCmalloc(newsize, file, line);
254 oldb = PTR_TO_MEMBLOCK(oldptr);
255 if (oldb->sig != SIGNATURE) {
256 fatal("Attempt to realloc() an invalid pointer (%p) (%s:%d)",
257 oldptr, file, line);
258 }
259 oldsize = oldb->size;
260 newb = realloc(oldb, newsize + sizeof(MemBlock));
261 if (newb) {
262 newb->size = newsize;
263 newb->sig = SIGNATURE; /* should already be set... */
264 data = MEMBLOCK_TO_PTR(newb);
265 allocated += (newsize - oldsize);
266 # if SHOWALLOCS
267 if (showallocs) {
268 log("srealloc(): Adjusted %ld bytes (%p) to %ld bytes (%p)"
269 " (%s:%d)", oldsize, oldptr, newsize, data, file, line);
270 }
271 # endif
272 return data;
273 } else {
274 # if SHOWALLOCS
275 if (showallocs) {
276 log("srealloc(): Unable to adjust %ld bytes (%p) to %ld bytes"
277 " (%s:%d)", oldsize, oldptr, newsize, file, line);
278 }
279 # endif
280 return NULL;
281 }
282 }
283
284 /*************************************************************************/
285
286 void MCfree(void *ptr, const char *file, int line)
287 {
288 MemBlock *mb;
289
290 if (ptr == NULL)
291 return;
292 mb = PTR_TO_MEMBLOCK(ptr);
293 if (mb->sig != SIGNATURE) {
294 fatal("Attempt to free() an invalid pointer (%p) (%s:%d)",
295 ptr, file, line);
296 }
297 allocated -= mb->size;
298 # if SHOWALLOCS
299 if (showallocs) {
300 log("sfree(): Released %ld bytes at %p (%s:%d)",
301 mb->size, ptr, file, line);
302 }
303 # endif
304 mb->size = FREE_FILL;
305 mb->sig = FREE_SIGNATURE;
306 fill32(ptr, FREE_FILL, mb->size);
307 free(mb);
308 }
309
310 /*************************************************************************/
311
312 char *MCstrdup(const char *s, const char *file, int line)
313 {
314 char *t = MCmalloc(strlen(s) + 1, file, line);
315 strcpy(t, s); /* safe, obviously */
316 return t;
317 }
318
319 /*************************************************************************/
320
321 #endif /* MEMCHECKS */
322
323 /*
324 * Local variables:
325 * c-file-style: "stroustrup"
326 * c-file-offsets: ((case-label . *) (statement-case-intro . *))
327 * indent-tabs-mode: nil
328 * End:
329 *
330 * vim: expandtab shiftwidth=4:
331 */

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.26