ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hybrid-ircservices-1/memory.c
Revision: 1209
Committed: Thu Aug 25 19:05:49 2011 UTC (14 years, 11 months ago) by michael
Content type: text/x-csrc
File size: 8797 byte(s)
Log Message:
- run everything thru indent
  "-bli0 -di1 -npcs -nut -cdw -bls -nbbo -bap"

File Contents

# Content
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 *
44 smalloc(long size FILELINE)
45 {
46 void *buf;
47
48 if (size == 0)
49 return NULL;
50 buf = xmalloc(size);
51 if (buf == NULL)
52 raise(SIGUSR1);
53 return buf;
54 }
55
56 /*************************************************************************/
57
58 void *
59 scalloc(long els, long elsize FILELINE)
60 {
61 void *buf;
62
63 if (elsize == 0 || els == 0)
64 return NULL;
65 buf = xcalloc(elsize, els);
66 if (buf == NULL)
67 raise(SIGUSR1);
68 return buf;
69 }
70
71 /*************************************************************************/
72
73 void *
74 srealloc(void *oldptr, long newsize FILELINE)
75 {
76 void *buf;
77
78 if (newsize == 0)
79 {
80 xfree(oldptr);
81 return NULL;
82 }
83 buf = xrealloc(oldptr, newsize);
84 if (buf == NULL)
85 raise(SIGUSR1);
86 return buf;
87 }
88
89 /*************************************************************************/
90
91 char *
92 sstrdup(const char *s FILELINE)
93 {
94 char *t = xsmalloc(strlen(s) + 1);
95 strcpy(t, s); /* safe, obviously */
96 return t;
97 }
98
99 /*************************************************************************/
100 /************ Everything from here down is MEMCHECKS-related. ************/
101 /*************************************************************************/
102
103 #if MEMCHECKS
104
105 /*************************************************************************/
106
107 static long allocated = 0; /* Amount of memory currently allocated */
108 static long runtime = 0; /* `allocated' value at init_memory() time */
109
110 # if SHOWALLOCS
111 int showallocs = 1; /* Actually log allocations? */
112 # endif
113
114 typedef struct _smemblock
115 {
116 long size; /* Size of this block */
117 int32 sig; /* Signature word: 0x5AFEC0DE */
118 } MemBlock;
119 # define SIGNATURE 0x5AFEC0DE
120 # define FREE_SIGNATURE 0xDEADBEEF /* Used for freed memory */
121 # define NEW_FILL 0xD017D017 /* New allocs are filled with this */
122 # define FREE_FILL 0xBEEF1E57 /* Freed memory is filled with this */
123
124 # define MEMBLOCK_TO_PTR(mb) ((void *)((char *)(mb) + sizeof(MemBlock)))
125 # define PTR_TO_MEMBLOCK(ptr) ((MemBlock *)((char *)(ptr) - sizeof(MemBlock)))
126
127
128 /*************************************************************************/
129 /*************************************************************************/
130
131 /* Leak-checking initialization and exit code. */
132
133 static void
134 show_leaks(void)
135 {
136 if (runtime >= 0 && (allocated - runtime) > 0)
137 {
138 log("SAFEMEM: There were %ld bytes leaked on exit!",
139 (allocated - runtime));
140 }
141 else
142 {
143 log("SAFEMEM: No memory leaks detected.");
144 }
145 }
146
147 void
148 init_memory(void)
149 {
150 runtime = allocated;
151 log("init_memory(): runtime = %ld", runtime);
152 atexit(show_leaks);
153 }
154
155 /* Used to avoid memory-leak message from the parent process */
156 void
157 uninit_memory(void)
158 {
159 runtime = -1;
160 }
161
162 /*************************************************************************/
163
164 /* Helper to fill memory with a given 32-bit value. */
165
166 static inline void
167 fill32(void *ptr, uint32 value, long size)
168 {
169 register uint32 *ptr32 = ptr;
170 register uint32 v = value;
171 while (size >= 4)
172 {
173 *ptr32++ = v;
174 size -= 4;
175 }
176 if (size > 0)
177 memcpy(ptr32, &value, size);
178 }
179
180 /*************************************************************************/
181 /*************************************************************************/
182
183 /* Substitutes for malloc() and friends. memory.h redefines malloc(), etc.
184 * to these functions if MEMCHECKS is defined. */
185
186 /*************************************************************************/
187
188 void *
189 MCmalloc(long size, const char *file, int line)
190 {
191 MemBlock *mb;
192 void *data;
193
194 if (size == 0)
195 return NULL;
196 mb = malloc(size + sizeof(MemBlock));
197 if (mb)
198 {
199 mb->size = size;
200 mb->sig = SIGNATURE;
201 data = MEMBLOCK_TO_PTR(mb);
202 allocated += size;
203 # if SHOWALLOCS
204 if (showallocs)
205 {
206 log("smalloc(): Allocated %ld bytes at %p (%s:%d)",
207 size, data, file, line);
208 }
209 # endif
210 fill32(data, NEW_FILL, size);
211 return data;
212 }
213 else
214 {
215 # if SHOWALLOCS
216 if (showallocs)
217 {
218 log("mcalloc(): Unable to allocate %ld bytes (%s:%d)",
219 size, file, line);
220 }
221 # endif
222 return NULL;
223 }
224 }
225
226 /*************************************************************************/
227
228 void *
229 MCcalloc(long els, long elsize, const char *file, int line)
230 {
231 MemBlock *mb;
232 void *data;
233
234 if (elsize == 0 || els == 0)
235 return NULL;
236 mb = malloc(els * elsize + sizeof(MemBlock));
237 if (mb)
238 {
239 mb->size = elsize * els;
240 mb->sig = SIGNATURE;
241 data = MEMBLOCK_TO_PTR(mb);
242 memset(data, 0, els * elsize);
243 allocated += mb->size;
244 # if SHOWALLOCS
245 if (showallocs)
246 {
247 log("scalloc(): Allocated %ld bytes at %p (%s:%d)",
248 els * elsize, data, file, line);
249 }
250 # endif
251 return data;
252 }
253 else
254 {
255 # if SHOWALLOCS
256 if (showallocs)
257 {
258 log("scalloc(): Unable to allocate %ld bytes (%s:%d)",
259 els * elsize, file, line);
260 }
261 # endif
262 return NULL;
263 }
264 }
265
266 /*************************************************************************/
267
268 void *
269 MCrealloc(void *oldptr, long newsize, const char *file, int line)
270 {
271 MemBlock *newb, *oldb;
272 long oldsize;
273 void *data;
274
275 if (newsize == 0)
276 {
277 MCfree(oldptr, file, line);
278 return NULL;
279 }
280 if (oldptr == NULL)
281 return MCmalloc(newsize, file, line);
282 oldb = PTR_TO_MEMBLOCK(oldptr);
283 if (oldb->sig != SIGNATURE)
284 {
285 fatal("Attempt to realloc() an invalid pointer (%p) (%s:%d)",
286 oldptr, file, line);
287 }
288 oldsize = oldb->size;
289 newb = realloc(oldb, newsize + sizeof(MemBlock));
290 if (newb)
291 {
292 newb->size = newsize;
293 newb->sig = SIGNATURE; /* should already be set... */
294 data = MEMBLOCK_TO_PTR(newb);
295 allocated += (newsize - oldsize);
296 # if SHOWALLOCS
297 if (showallocs)
298 {
299 log("srealloc(): Adjusted %ld bytes (%p) to %ld bytes (%p)"
300 " (%s:%d)", oldsize, oldptr, newsize, data, file, line);
301 }
302 # endif
303 return data;
304 }
305 else
306 {
307 # if SHOWALLOCS
308 if (showallocs)
309 {
310 log("srealloc(): Unable to adjust %ld bytes (%p) to %ld bytes"
311 " (%s:%d)", oldsize, oldptr, newsize, file, line);
312 }
313 # endif
314 return NULL;
315 }
316 }
317
318 /*************************************************************************/
319
320 void
321 MCfree(void *ptr, const char *file, int line)
322 {
323 MemBlock *mb;
324
325 if (ptr == NULL)
326 return;
327 mb = PTR_TO_MEMBLOCK(ptr);
328 if (mb->sig != SIGNATURE)
329 {
330 fatal("Attempt to free() an invalid pointer (%p) (%s:%d)",
331 ptr, file, line);
332 }
333 allocated -= mb->size;
334 # if SHOWALLOCS
335 if (showallocs)
336 {
337 log("sfree(): Released %ld bytes at %p (%s:%d)",
338 mb->size, ptr, file, line);
339 }
340 # endif
341 mb->size = FREE_FILL;
342 mb->sig = FREE_SIGNATURE;
343 fill32(ptr, FREE_FILL, mb->size);
344 free(mb);
345 }
346
347 /*************************************************************************/
348
349 char *
350 MCstrdup(const char *s, const char *file, int line)
351 {
352 char *t = MCmalloc(strlen(s) + 1, file, line);
353 strcpy(t, s); /* safe, obviously */
354 return t;
355 }
356
357 /*************************************************************************/
358
359 #endif /* MEMCHECKS */
360
361 /*
362 * Local variables:
363 * c-file-style: "stroustrup"
364 * c-file-offsets: ((case-label . *) (statement-case-intro . *))
365 * indent-tabs-mode: nil
366 * End:
367 *
368 * vim: expandtab shiftwidth=4:
369 */