248 lines
4.3 KiB
C
248 lines
4.3 KiB
C
#include "general.h"
|
|
#include "gmem.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#ifdef DEBUG
|
|
|
|
typedef struct _GMemHdr
|
|
{
|
|
int size;
|
|
int index;
|
|
struct _GMemHdr *next;
|
|
} GMemHdr;
|
|
|
|
#define gMemHdrSize (( sizeof(GMemHdr) + 7) & ~7)
|
|
#define gMemTrlSize 4
|
|
#define gMemDeadVal 0xFFFFFFFFUL
|
|
|
|
/* round data size so trailer will be aligned */
|
|
#define gMemDataSize(size) ((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize)
|
|
|
|
#define gMemNLists 64
|
|
#define gMemListShift 4
|
|
#define gMemListMask (gMemNLists - 1)
|
|
static GMemHdr *gMemList[gMemNLists] = {
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
|
};
|
|
|
|
static int gMemIndex = 0;
|
|
static int gMemAlloc = 0;
|
|
|
|
#endif /* DEBUG */
|
|
|
|
void *gmalloc(int size)
|
|
{
|
|
#ifdef DEBUG
|
|
int size1;
|
|
char *mem;
|
|
GMemHdr *hdr;
|
|
void *data;
|
|
int lst;
|
|
unsigned long *trl, *p;
|
|
|
|
if (size <= 0)
|
|
return NULL;
|
|
|
|
size1 = gMemDataSize(size);
|
|
|
|
mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize);
|
|
|
|
if ( mem == NULL)
|
|
{
|
|
zdebug( "Out of memory");
|
|
return NULL;
|
|
}
|
|
|
|
hdr = (GMemHdr *)mem;
|
|
data = (void *)(mem + gMemHdrSize);
|
|
trl = (unsigned long *)(mem + gMemHdrSize + size1);
|
|
hdr->size = size;
|
|
hdr->index = gMemIndex++;
|
|
lst = ((int)hdr >> gMemListShift) & gMemListMask;
|
|
hdr->next = gMemList[lst];
|
|
gMemList[lst] = hdr;
|
|
++gMemAlloc;
|
|
|
|
for (p = (unsigned long *)data; p <= trl; ++p)
|
|
*p = gMemDeadVal;
|
|
|
|
return data;
|
|
#else
|
|
void *p;
|
|
|
|
if (size <= 0)
|
|
return NULL;
|
|
|
|
p = malloc(size);
|
|
|
|
if ( p == NULL)
|
|
{
|
|
zdebug( "Out of memory");
|
|
return NULL;
|
|
}
|
|
|
|
return p;
|
|
#endif
|
|
}
|
|
|
|
void *grealloc(void *p, int size)
|
|
{
|
|
#ifdef DEBUG
|
|
GMemHdr *hdr;
|
|
void *q;
|
|
int oldSize;
|
|
|
|
if (size <= 0)
|
|
{
|
|
if (p)
|
|
gfree(p);
|
|
return NULL;
|
|
}
|
|
if (p)
|
|
{
|
|
hdr = (GMemHdr *)((char *)p - gMemHdrSize);
|
|
oldSize = hdr->size;
|
|
q = gmalloc(size);
|
|
memcpy(q, p, size < oldSize ? size : oldSize);
|
|
gfree(p);
|
|
}
|
|
else
|
|
{
|
|
q = gmalloc(size);
|
|
}
|
|
return q;
|
|
#else
|
|
void *q;
|
|
|
|
if (size <= 0)
|
|
{
|
|
if (p)
|
|
free(p);
|
|
return NULL;
|
|
}
|
|
|
|
if (p)
|
|
q = realloc( p, size);
|
|
else
|
|
q = malloc(size);
|
|
|
|
if (!q)
|
|
{
|
|
zdebug( "Out of memory");
|
|
return NULL;
|
|
}
|
|
return q;
|
|
#endif
|
|
}
|
|
|
|
void gfree(void *p)
|
|
{
|
|
#ifdef DEBUG
|
|
int size;
|
|
GMemHdr *hdr;
|
|
GMemHdr *prevHdr, *q;
|
|
int lst;
|
|
unsigned long *trl, *clr;
|
|
|
|
if (p)
|
|
{
|
|
hdr = (GMemHdr *)((char *)p - gMemHdrSize);
|
|
lst = ((int)hdr >> gMemListShift) & gMemListMask;
|
|
|
|
for (prevHdr = NULL, q = gMemList[lst]; q; prevHdr = q, q = q->next)
|
|
{
|
|
if ( q == hdr)
|
|
break;
|
|
}
|
|
|
|
if( q)
|
|
{
|
|
if (prevHdr)
|
|
prevHdr->next = hdr->next;
|
|
else
|
|
gMemList[lst] = hdr->next;
|
|
|
|
--gMemAlloc;
|
|
size = gMemDataSize(hdr->size);
|
|
trl = (unsigned long *)((char *)hdr + gMemHdrSize + size);
|
|
|
|
if (*trl != gMemDeadVal)
|
|
{
|
|
zdebug( "Overwrite past end of block %d at address %p", hdr->index, p);
|
|
}
|
|
|
|
for (clr = (unsigned long *)hdr; clr <= trl; ++clr)
|
|
*clr = gMemDeadVal;
|
|
|
|
free(hdr);
|
|
}
|
|
else
|
|
{
|
|
zdebug( "Attempted to free bad address %p", p);
|
|
}
|
|
}
|
|
#else
|
|
if (p)
|
|
free(p);
|
|
#endif
|
|
}
|
|
|
|
void gMemReport( void)
|
|
{
|
|
#ifdef DEBUG
|
|
FILE *inffile;
|
|
GMemHdr *p;
|
|
int lst;
|
|
|
|
if (( inffile = fopen( "C:\\ztkdebug.txt", "wb+")) == NULL)
|
|
return;
|
|
|
|
fprintf( inffile, "%d memory allocations in all\n", gMemIndex);
|
|
|
|
if( gMemAlloc > 0)
|
|
{
|
|
fprintf( inffile, "%d memory blocks left allocated:\n", gMemAlloc);
|
|
fprintf( inffile, " index size\n");
|
|
fprintf( inffile, "-------- --------\n");
|
|
|
|
for (lst = 0; lst < gMemNLists; ++lst)
|
|
{
|
|
for (p = gMemList[lst]; p; p = p->next)
|
|
fprintf( inffile, "%8d %8d\n", p->index, p->size);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fprintf( inffile, "No memory blocks left allocated\n");
|
|
}
|
|
|
|
fprintf( inffile, "--= End =--");
|
|
|
|
fclose( inffile);
|
|
#endif
|
|
}
|
|
|
|
|
|
char *copyString(char *s)
|
|
{
|
|
char *s1;
|
|
|
|
s1 = (char *)gmalloc(strlen(s) + 1);
|
|
strcpy(s1, s);
|
|
return s1;
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|