4 * Memory routines with out-of-memory checking.
6 * Copyright 1996-2003 Glyph & Cog, LLC
16 #include <aros/debug.h>
19 typedef struct _GMemHdr
{
23 struct _GMemHdr
*next
, *prev
;
26 #define gMemHdrSize ((sizeof(GMemHdr) + 7) & ~7)
27 #define gMemTrlSize (sizeof(long))
29 #define gMemMagic 0xabcd9999
32 #define gMemDeadVal 0xdeadbeefdeadbeefUL
34 #define gMemDeadVal 0xdeadbeefUL
37 /* round data size so trailer will be aligned */
38 #define gMemDataSize(size) \
39 ((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize)
41 static GMemHdr
*gMemHead
= NULL
;
42 static GMemHdr
*gMemTail
= NULL
;
44 static int gMemIndex
= 0;
45 static int gMemAlloc
= 0;
46 static int gMemInUse
= 0;
48 #endif /* DEBUG_MEM */
50 void *gmalloc(int size
) GMEM_EXCEP
{
56 unsigned long *trl
, *p
;
61 size1
= gMemDataSize(size
);
62 if (!(mem
= (char *)malloc(size1
+ gMemHdrSize
+ gMemTrlSize
))) {
64 throw GMemException();
70 data
= (void *)(mem
+ gMemHdrSize
);
71 trl
= (unsigned long *)(mem
+ gMemHdrSize
+ size1
);
72 hdr
->magic
= gMemMagic
;
74 hdr
->index
= gMemIndex
++;
81 gMemHead
= gMemTail
= hdr
;
86 for (p
= (unsigned long *)data
; p
<= trl
; ++p
) {
96 if (!(p
= malloc(size
))) {
98 throw GMemException();
107 void *grealloc(void *p
, int size
) GMEM_EXCEP
{
120 hdr
= (GMemHdr
*)((char *)p
- gMemHdrSize
);
123 memcpy(q
, p
, size
< oldSize
? size
: oldSize
);
139 q
= realloc(p
, size
);
145 throw GMemException();
154 void *gmallocn(int nObjs
, int objSize
) GMEM_EXCEP
{
161 if (objSize
<= 0 || nObjs
< 0 || nObjs
>= INT_MAX
/ objSize
) {
163 throw GMemException();
171 void *greallocn(void *p
, int nObjs
, int objSize
) GMEM_EXCEP
{
181 if (objSize
<= 0 || nObjs
< 0 || nObjs
>= INT_MAX
/ objSize
) {
183 throw GMemException();
185 bug( "Bogus memory allocation size\n");
189 return grealloc(p
, n
);
192 void gfree(void *p
) {
196 unsigned long *trl
, *clr
;
199 hdr
= (GMemHdr
*)((char *)p
- gMemHdrSize
);
200 if (hdr
->magic
== gMemMagic
&&
201 ((hdr
->prev
== NULL
) == (hdr
== gMemHead
)) &&
202 ((hdr
->next
== NULL
) == (hdr
== gMemTail
))) {
204 hdr
->prev
->next
= hdr
->next
;
206 gMemHead
= hdr
->next
;
209 hdr
->next
->prev
= hdr
->prev
;
211 gMemTail
= hdr
->prev
;
214 gMemInUse
-= hdr
->size
;
215 size
= gMemDataSize(hdr
->size
);
216 trl
= (unsigned long *)((char *)hdr
+ gMemHdrSize
+ size
);
217 if (*trl
!= gMemDeadVal
) {
218 bug( "Overwrite past end of block %d at address %p\n",
221 for (clr
= (unsigned long *)hdr
; clr
<= trl
; ++clr
) {
226 bug( "Attempted to free bad address %p\n", p
);
237 void gMemReport(FILE *f
) {
240 fprintf(f
, "%d memory allocations in all\n", gMemIndex
);
242 fprintf(f
, "%d memory blocks left allocated:\n", gMemAlloc
);
243 fprintf(f
, " index size\n");
244 fprintf(f
, "-------- --------\n");
245 for (p
= gMemHead
; p
; p
= p
->next
) {
246 fprintf(f
, "%8d %8d\n", p
->index
, p
->size
);
249 fprintf(f
, "No memory blocks left allocated\n");
254 char *copyString(char *s
) {
257 s1
= (char *)gmalloc(strlen(s
) + 1);