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

# User Rev Content
1 michael 1194 /* 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 michael 1209 # define FILELINE /*nothing */
34 michael 1194 # 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 michael 1209 void *
44     smalloc(long size FILELINE)
45 michael 1194 {
46 michael 1209 void *buf;
47 michael 1194
48 michael 1209 if (size == 0)
49     return NULL;
50     buf = xmalloc(size);
51     if (buf == NULL)
52     raise(SIGUSR1);
53     return buf;
54 michael 1194 }
55    
56     /*************************************************************************/
57    
58 michael 1209 void *
59     scalloc(long els, long elsize FILELINE)
60 michael 1194 {
61 michael 1209 void *buf;
62 michael 1194
63 michael 1209 if (elsize == 0 || els == 0)
64     return NULL;
65     buf = xcalloc(elsize, els);
66     if (buf == NULL)
67     raise(SIGUSR1);
68     return buf;
69 michael 1194 }
70    
71     /*************************************************************************/
72    
73 michael 1209 void *
74     srealloc(void *oldptr, long newsize FILELINE)
75 michael 1194 {
76 michael 1209 void *buf;
77 michael 1194
78 michael 1209 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 michael 1194 }
88    
89     /*************************************************************************/
90    
91 michael 1209 char *
92     sstrdup(const char *s FILELINE)
93 michael 1194 {
94 michael 1209 char *t = xsmalloc(strlen(s) + 1);
95     strcpy(t, s); /* safe, obviously */
96     return t;
97 michael 1194 }
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 michael 1209 typedef struct _smemblock
115     {
116     long size; /* Size of this block */
117     int32 sig; /* Signature word: 0x5AFEC0DE */
118 michael 1194 } 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 michael 1209 static void
134     show_leaks(void)
135 michael 1194 {
136 michael 1209 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 michael 1194 }
146    
147 michael 1209 void
148     init_memory(void)
149 michael 1194 {
150 michael 1209 runtime = allocated;
151     log("init_memory(): runtime = %ld", runtime);
152     atexit(show_leaks);
153 michael 1194 }
154    
155     /* Used to avoid memory-leak message from the parent process */
156 michael 1209 void
157     uninit_memory(void)
158 michael 1194 {
159 michael 1209 runtime = -1;
160 michael 1194 }
161    
162     /*************************************************************************/
163    
164     /* Helper to fill memory with a given 32-bit value. */
165    
166 michael 1209 static inline void
167     fill32(void *ptr, uint32 value, long size)
168 michael 1194 {
169 michael 1209 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 michael 1194 }
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 michael 1209 void *
189     MCmalloc(long size, const char *file, int line)
190 michael 1194 {
191 michael 1209 MemBlock *mb;
192     void *data;
193 michael 1194
194 michael 1209 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 michael 1194 # if SHOWALLOCS
204 michael 1209 if (showallocs)
205     {
206     log("smalloc(): Allocated %ld bytes at %p (%s:%d)",
207     size, data, file, line);
208     }
209 michael 1194 # endif
210 michael 1209 fill32(data, NEW_FILL, size);
211     return data;
212     }
213     else
214     {
215 michael 1194 # if SHOWALLOCS
216 michael 1209 if (showallocs)
217     {
218     log("mcalloc(): Unable to allocate %ld bytes (%s:%d)",
219     size, file, line);
220     }
221 michael 1194 # endif
222 michael 1209 return NULL;
223     }
224 michael 1194 }
225    
226     /*************************************************************************/
227    
228 michael 1209 void *
229     MCcalloc(long els, long elsize, const char *file, int line)
230 michael 1194 {
231 michael 1209 MemBlock *mb;
232     void *data;
233 michael 1194
234 michael 1209 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 michael 1194 # if SHOWALLOCS
245 michael 1209 if (showallocs)
246     {
247     log("scalloc(): Allocated %ld bytes at %p (%s:%d)",
248     els * elsize, data, file, line);
249     }
250 michael 1194 # endif
251 michael 1209 return data;
252     }
253     else
254     {
255 michael 1194 # if SHOWALLOCS
256 michael 1209 if (showallocs)
257     {
258     log("scalloc(): Unable to allocate %ld bytes (%s:%d)",
259     els * elsize, file, line);
260     }
261 michael 1194 # endif
262 michael 1209 return NULL;
263     }
264 michael 1194 }
265    
266     /*************************************************************************/
267    
268 michael 1209 void *
269     MCrealloc(void *oldptr, long newsize, const char *file, int line)
270 michael 1194 {
271 michael 1209 MemBlock *newb, *oldb;
272     long oldsize;
273     void *data;
274 michael 1194
275 michael 1209 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 michael 1194 }
302     # endif
303 michael 1209 return data;
304     }
305     else
306     {
307 michael 1194 # if SHOWALLOCS
308 michael 1209 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 michael 1194 # endif
314 michael 1209 return NULL;
315     }
316 michael 1194 }
317    
318     /*************************************************************************/
319    
320 michael 1209 void
321     MCfree(void *ptr, const char *file, int line)
322 michael 1194 {
323 michael 1209 MemBlock *mb;
324 michael 1194
325 michael 1209 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 michael 1194 # if SHOWALLOCS
335 michael 1209 if (showallocs)
336     {
337     log("sfree(): Released %ld bytes at %p (%s:%d)",
338     mb->size, ptr, file, line);
339     }
340 michael 1194 # endif
341 michael 1209 mb->size = FREE_FILL;
342     mb->sig = FREE_SIGNATURE;
343     fill32(ptr, FREE_FILL, mb->size);
344     free(mb);
345 michael 1194 }
346    
347     /*************************************************************************/
348    
349 michael 1209 char *
350     MCstrdup(const char *s, const char *file, int line)
351 michael 1194 {
352 michael 1209 char *t = MCmalloc(strlen(s) + 1, file, line);
353     strcpy(t, s); /* safe, obviously */
354     return t;
355 michael 1194 }
356    
357     /*************************************************************************/
358    
359 michael 1209 #endif /* MEMCHECKS */
360 michael 1194
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     */