summaryrefslogtreecommitdiffstats
path: root/main/common/malloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/common/malloc.c')
-rw-r--r--main/common/malloc.c1134
1 files changed, 584 insertions, 550 deletions
diff --git a/main/common/malloc.c b/main/common/malloc.c
index 8050e05..46e35be 100644
--- a/main/common/malloc.c
+++ b/main/common/malloc.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
* Copyright (c) 2013 Alcatel-Lucent
- *
+ *
* Alcatel Lucent licenses this file to You under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. A copy of the License is contained the
@@ -20,7 +20,7 @@
*
* malloc():
*
- * A simple memory allocator useful for embedded systems to provide
+ * A simple memory allocator useful for embedded systems to provide
* some level of debug, plus the ability to increase heap space into
* additional memory that is not contiguous with the intial statically
* allocated array of memory. The reason for supporting the ability to
@@ -29,7 +29,7 @@
* if the application is going to also use this malloc, it can do so
* by simply extending the heap. The monitor would not have to be
* specifically built to support the large heap allocation.
- *
+ *
* The allocator data structures are part of the memory space used for
* the allocation. To test for memory overruns (using memory after the
* end of the allocated space) or underruns (using memory prior to the
@@ -49,7 +49,7 @@
* ALLOCATOR, IT IS SLOW! Every call to malloc/free does a sanity check
* on all allocation structures, so it is fairly good at detecting illegal
* use of the allocated memory.
- *
+ *
* Original author: Ed Sutter (ed.sutter@alcatel-lucent.com)
*
*/
@@ -59,53 +59,53 @@
#include "stddefs.h"
#include "cli.h"
-#define FNAMESIZE 32
+#define FNAMESIZE 32
-#define PRETAG 0xDEAD
-#define POSTTAG 0xBEEF
-#define MHDRSIZE sizeof(struct mhdr)
+#define PRETAG 0xDEAD
+#define POSTTAG 0xBEEF
+#define MHDRSIZE sizeof(struct mhdr)
-extern char *GetMemory(int);
-extern int GetMemoryLeft(void);
-extern int extendHeap(char *,int);
-extern void unExtendHeap(void);
-extern char *getExtHeapBase(void);
+extern char *GetMemory(int);
+extern int GetMemoryLeft(void);
+extern int extendHeap(char *,int);
+extern void unExtendHeap(void);
+extern char *getExtHeapBase(void);
/* mhdr:
The control structure used by the memory allocator.
*/
-struct mhdr {
- ushort pretag; /* Fixed value used as an overrun sanity
- * check for the previous memory block.
- */
- int size; /* Size of useable memory block. Size is
- * positive if block is free and negative if
- * block is not free.
- */
- struct mhdr *next; /* Points to next mhdr structure (not
- * necessarily in contiguous memory space).
- */
- struct mhdr *prev; /* Points to previous mhdr structure (not
- * necessarily in contiguous memory space).
- */
- ushort posttag; /* Fixed value used as an underrun sanity
- * check for this memory block.
- */
+struct mhdr {
+ ushort pretag; /* Fixed value used as an overrun sanity
+ * check for the previous memory block.
+ */
+ int size; /* Size of useable memory block. Size is
+ * positive if block is free and negative if
+ * block is not free.
+ */
+ struct mhdr *next; /* Points to next mhdr structure (not
+ * necessarily in contiguous memory space).
+ */
+ struct mhdr *prev; /* Points to previous mhdr structure (not
+ * necessarily in contiguous memory space).
+ */
+ ushort posttag; /* Fixed value used as an underrun sanity
+ * check for this memory block.
+ */
#ifdef MALLOC_DEBUG
- char fname[FNAMESIZE];
- int fline;
+ char fname[FNAMESIZE];
+ int fline;
#endif
};
/* mcalls, fcalls & mfails:
- * Used to keep track of malloc and free calls. Plus keep track
- * of the number of times malloc is called, but it returns 0.
+ * Used to keep track of malloc and free calls. Plus keep track
+ * of the number of times malloc is called, but it returns 0.
*/
static int mcalls, rcalls, fcalls, mfails;
/* mtot, ftot & highwater:
- * Keep track of total amount of memory allocated.
+ * Keep track of total amount of memory allocated.
*/
static int mtot, ftot, highwater;
@@ -122,161 +122,174 @@ static char mquiet;
static char mtrace;
/* heapbase:
- * Initially zero, this pointer is set to the base of the heap on
- * the first call to malloc().
+ * Initially zero, this pointer is set to the base of the heap on
+ * the first call to malloc().
*/
-static struct mhdr *heapbase;
+static struct mhdr *heapbase;
static void
heapinit(void)
{
- mcalls = rcalls = fcalls = mfails = 0;
- mtot = ftot = highwater = 0;
- heapbase = (struct mhdr *)GetMemory(ALLOCSIZE);
- heapbase->pretag = PRETAG;
- heapbase->posttag = POSTTAG;
- heapbase->size = ALLOCSIZE - MHDRSIZE;
- if (heapbase->size < 0)
- printf("heapinit(): ALLOCSIZE too small!\n");
- heapbase->next = (struct mhdr *)0;
- heapbase->prev = (struct mhdr *)0;
+ mcalls = rcalls = fcalls = mfails = 0;
+ mtot = ftot = highwater = 0;
+ heapbase = (struct mhdr *)GetMemory(ALLOCSIZE);
+ heapbase->pretag = PRETAG;
+ heapbase->posttag = POSTTAG;
+ heapbase->size = ALLOCSIZE - MHDRSIZE;
+ if(heapbase->size < 0) {
+ printf("heapinit(): ALLOCSIZE too small!\n");
+ }
+ heapbase->next = (struct mhdr *)0;
+ heapbase->prev = (struct mhdr *)0;
}
/* heapcheck():
- * Called with an mhdr pointer (or NULL). This function just steps through
- * the heap control structures to make sure there is some level of sanity.
- * If the incoming mhdr pointer is non-zero, then it will also verify that
- * the pointer is a valid control pointer in the heap.
+ * Called with an mhdr pointer (or NULL). This function just steps through
+ * the heap control structures to make sure there is some level of sanity.
+ * If the incoming mhdr pointer is non-zero, then it will also verify that
+ * the pointer is a valid control pointer in the heap.
*/
int
heapcheck(struct mhdr *mp,char *msg)
{
- int i, mpok;
- register struct mhdr *mptr;
-
- mpok = 0;
- if (!heapbase)
- heapinit();
-
- mptr = heapbase;
- for(i=0;mptr;i++,mptr=mptr->next) {
- if (mp == mptr)
- mpok = 1;
- if ((mptr->pretag != PRETAG) || (mptr->posttag != POSTTAG)) {
- if (!mquiet) {
- printf("\007MALLOC ERROR: heap corrupted at entry %d",i);
- if (msg)
- printf(" (%s)",msg);
- printf("\n");
- }
- return(-1);
- }
- }
- if ((mp) && (!mpok)) {
- if (!mquiet) {
- printf("\007MALLOC ERROR: 0x%lx (mem @ 0x%lx) invalid heap pointer",
- (ulong)mp,(ulong)(mp+1));
- if (msg)
- printf(" (%s)",msg);
- printf("\n");
- }
- return(-1);
- }
- return(0);
+ int i, mpok;
+ register struct mhdr *mptr;
+
+ mpok = 0;
+ if(!heapbase) {
+ heapinit();
+ }
+
+ mptr = heapbase;
+ for(i=0; mptr; i++,mptr=mptr->next) {
+ if(mp == mptr) {
+ mpok = 1;
+ }
+ if((mptr->pretag != PRETAG) || (mptr->posttag != POSTTAG)) {
+ if(!mquiet) {
+ printf("\007MALLOC ERROR: heap corrupted at entry %d",i);
+ if(msg) {
+ printf(" (%s)",msg);
+ }
+ printf("\n");
+ }
+ return(-1);
+ }
+ }
+ if((mp) && (!mpok)) {
+ if(!mquiet) {
+ printf("\007MALLOC ERROR: 0x%lx (mem @ 0x%lx) invalid heap pointer",
+ (ulong)mp,(ulong)(mp+1));
+ if(msg) {
+ printf(" (%s)",msg);
+ }
+ printf("\n");
+ }
+ return(-1);
+ }
+ return(0);
}
static char *
_malloc(int size)
{
- register struct mhdr *mptr, *mptr1;
-
- if (mtrace)
- printf("malloc(%d) = ",size);
-
- if (size <= 0) {
- if (mtrace)
- printf("0\n");
- return(0);
- }
-
- /* Start by checking sanity of heap. */
- if (heapcheck(0,0) < 0) {
- if (mtrace)
- printf("00\n");
- return((char *)0);
- }
-
- /* Keep track of number of calls to malloc for debug. */
- mcalls++;
-
- /* Make size divisible by 4: */
- if (size & 3) {
- size += 4;
- size &= 0xfffffffc;
- }
-
- mptr = (struct mhdr *)heapbase;
- while(1) {
- /* If request size is equal to the free block size or
- * if the free block size is only slightly larger than the
- * request size, then just use that free block as is.
- * If the request size is at least "MHDRSIZE * 2"
- * bytes smaller than free block size, then break
- * that block up into 2 smaller chunks with one of the chunks
- * being the size of the request and the size of the other chunk
- * being whatever is left over.
- */
- if (mptr->size >= size) {
- if (mptr->size <= (int)(size + (MHDRSIZE * 2))) {
- mtot += mptr->size;
- if ((mtot - ftot) > highwater)
- highwater = (mtot - ftot);
- mptr->size = -mptr->size;
- }
- else {
- mptr1 = (struct mhdr *)((char *)(mptr+1) + size);
- mptr1->pretag = PRETAG;
- mptr1->posttag = POSTTAG;
- mptr1->next = mptr->next;
- mptr->next = mptr1;
- if (mptr1->next)
- mptr1->next->prev = mptr1;
- mptr1->prev = mptr;
- mptr1->size = (mptr->size - size) - MHDRSIZE;
- mptr->size = -size;
- mtot += size;
- if ((mtot - ftot) > highwater)
- highwater = (mtot - ftot);
- }
- if (mtrace)
- printf("0x%lx\n",(long)(mptr+1));
- return((char *)(mptr+1));
- }
- if (mptr->next == (struct mhdr *)0) {
- struct mhdr *moremem;
- int getsize;
-
- getsize = size + MHDRSIZE;
- moremem = (struct mhdr *)GetMemory(getsize);
- if (!moremem) {
- mfails++;
- if (!mquiet)
- printf("\007MALLOC ERROR: no more memory\n");
- if (mtrace)
- printf("000\n");
- return((char *)0);
- }
- mptr->next = moremem;
- mptr->next->prev = mptr;
- mptr = mptr->next;
- mptr->next = (struct mhdr *)0;
- mptr->pretag = PRETAG;
- mptr->posttag = POSTTAG;
- mptr->size = getsize - MHDRSIZE;
- }
- else
- mptr = mptr->next;
- }
+ register struct mhdr *mptr, *mptr1;
+
+ if(mtrace) {
+ printf("malloc(%d) = ",size);
+ }
+
+ if(size <= 0) {
+ if(mtrace) {
+ printf("0\n");
+ }
+ return(0);
+ }
+
+ /* Start by checking sanity of heap. */
+ if(heapcheck(0,0) < 0) {
+ if(mtrace) {
+ printf("00\n");
+ }
+ return((char *)0);
+ }
+
+ /* Keep track of number of calls to malloc for debug. */
+ mcalls++;
+
+ /* Make size divisible by 4: */
+ if(size & 3) {
+ size += 4;
+ size &= 0xfffffffc;
+ }
+
+ mptr = (struct mhdr *)heapbase;
+ while(1) {
+ /* If request size is equal to the free block size or
+ * if the free block size is only slightly larger than the
+ * request size, then just use that free block as is.
+ * If the request size is at least "MHDRSIZE * 2"
+ * bytes smaller than free block size, then break
+ * that block up into 2 smaller chunks with one of the chunks
+ * being the size of the request and the size of the other chunk
+ * being whatever is left over.
+ */
+ if(mptr->size >= size) {
+ if(mptr->size <= (int)(size + (MHDRSIZE * 2))) {
+ mtot += mptr->size;
+ if((mtot - ftot) > highwater) {
+ highwater = (mtot - ftot);
+ }
+ mptr->size = -mptr->size;
+ } else {
+ mptr1 = (struct mhdr *)((char *)(mptr+1) + size);
+ mptr1->pretag = PRETAG;
+ mptr1->posttag = POSTTAG;
+ mptr1->next = mptr->next;
+ mptr->next = mptr1;
+ if(mptr1->next) {
+ mptr1->next->prev = mptr1;
+ }
+ mptr1->prev = mptr;
+ mptr1->size = (mptr->size - size) - MHDRSIZE;
+ mptr->size = -size;
+ mtot += size;
+ if((mtot - ftot) > highwater) {
+ highwater = (mtot - ftot);
+ }
+ }
+ if(mtrace) {
+ printf("0x%lx\n",(long)(mptr+1));
+ }
+ return((char *)(mptr+1));
+ }
+ if(mptr->next == (struct mhdr *)0) {
+ struct mhdr *moremem;
+ int getsize;
+
+ getsize = size + MHDRSIZE;
+ moremem = (struct mhdr *)GetMemory(getsize);
+ if(!moremem) {
+ mfails++;
+ if(!mquiet) {
+ printf("\007MALLOC ERROR: no more memory\n");
+ }
+ if(mtrace) {
+ printf("000\n");
+ }
+ return((char *)0);
+ }
+ mptr->next = moremem;
+ mptr->next->prev = mptr;
+ mptr = mptr->next;
+ mptr->next = (struct mhdr *)0;
+ mptr->pretag = PRETAG;
+ mptr->posttag = POSTTAG;
+ mptr->size = getsize - MHDRSIZE;
+ } else {
+ mptr = mptr->next;
+ }
+ }
}
#ifdef MALLOC_DEBUG
@@ -285,123 +298,128 @@ _malloc(int size)
char *
malloc(int size, char *fname, int fline)
{
- char *cp;
- struct mhdr *mptr;
-
- cp = _malloc(size);
- if (cp) {
- mptr = (struct mhdr *)cp;
- mptr--;
- strncpy(mptr->fname,fname,FNAMESIZE-1);
- mptr->fline = fline;
- mptr->fname[FNAMESIZE-1] = 0;
- mptr->fline = fline;
- }
- return(cp);
+ char *cp;
+ struct mhdr *mptr;
+
+ cp = _malloc(size);
+ if(cp) {
+ mptr = (struct mhdr *)cp;
+ mptr--;
+ strncpy(mptr->fname,fname,FNAMESIZE-1);
+ mptr->fline = fline;
+ mptr->fname[FNAMESIZE-1] = 0;
+ mptr->fline = fline;
+ }
+ return(cp);
}
#else
char *
malloc(int size)
{
- return(_malloc(size));
+ return(_malloc(size));
}
#endif
void
free(void *vp)
{
- char *cp = vp;
- struct mhdr *mptr;
-
- if (mtrace)
- printf("free(0x%lx)\n",(long)cp);
-
- /* Keep track of number of calls to free for debug. */
- fcalls++;
-
- mptr = (struct mhdr *)cp - 1;
-
- /* Start by checking sanity of heap and make sure that the incoming
- * pointer corresponds to a valid entry in the heap.
- */
- if (heapcheck(mptr,0) < 0)
- return;
-
- /* The first thing to do to free the block is to make the size
- * positive.
- */
- mptr->size = abs(mptr->size);
-
- /* Keep track of how much memory is freed for debug. */
- ftot += mptr->size;
-
- /* To defragment the memory, see if previous and/or
- * next block is free; if yes, then join them into one larger
- * block. Note that the blocks will only be joined if they are in
- * contiguous memory space.
- */
- if (mptr->next) {
- if ((mptr->next->size > 0) &&
- (mptr->next == (struct mhdr *)
- ((char *)mptr + mptr->size + MHDRSIZE))) {
- mptr->size += mptr->next->size + MHDRSIZE;
- mptr->next = mptr->next->next;
- if (mptr->next)
- mptr->next->prev = mptr;
- }
- }
- if (mptr->prev) {
- if ((mptr->prev->size > 0) &&
- (mptr->prev == (struct mhdr *)
- ((char *)mptr-mptr->prev->size - MHDRSIZE))) {
- if (mptr->next)
- mptr->next->prev = mptr->prev;
- mptr->prev->next = mptr->next;
- mptr->prev->size += mptr->size + MHDRSIZE;
- }
- }
+ char *cp = vp;
+ struct mhdr *mptr;
+
+ if(mtrace) {
+ printf("free(0x%lx)\n",(long)cp);
+ }
+
+ /* Keep track of number of calls to free for debug. */
+ fcalls++;
+
+ mptr = (struct mhdr *)cp - 1;
+
+ /* Start by checking sanity of heap and make sure that the incoming
+ * pointer corresponds to a valid entry in the heap.
+ */
+ if(heapcheck(mptr,0) < 0) {
+ return;
+ }
+
+ /* The first thing to do to free the block is to make the size
+ * positive.
+ */
+ mptr->size = abs(mptr->size);
+
+ /* Keep track of how much memory is freed for debug. */
+ ftot += mptr->size;
+
+ /* To defragment the memory, see if previous and/or
+ * next block is free; if yes, then join them into one larger
+ * block. Note that the blocks will only be joined if they are in
+ * contiguous memory space.
+ */
+ if(mptr->next) {
+ if((mptr->next->size > 0) &&
+ (mptr->next == (struct mhdr *)
+ ((char *)mptr + mptr->size + MHDRSIZE))) {
+ mptr->size += mptr->next->size + MHDRSIZE;
+ mptr->next = mptr->next->next;
+ if(mptr->next) {
+ mptr->next->prev = mptr;
+ }
+ }
+ }
+ if(mptr->prev) {
+ if((mptr->prev->size > 0) &&
+ (mptr->prev == (struct mhdr *)
+ ((char *)mptr-mptr->prev->size - MHDRSIZE))) {
+ if(mptr->next) {
+ mptr->next->prev = mptr->prev;
+ }
+ mptr->prev->next = mptr->next;
+ mptr->prev->size += mptr->size + MHDRSIZE;
+ }
+ }
}
/* calloc():
- * Allocate space for an array of nelem elements of size elsize.
- * Initialize the space to zero.
+ * Allocate space for an array of nelem elements of size elsize.
+ * Initialize the space to zero.
*/
static char *
_calloc(int nelem, int elsize)
{
- register char *cp, *end;
- char *base;
- int size;
-
- size = nelem * elsize;
- base = _malloc(size);
- if (base) {
- cp = base;
- end = base+size;
- while(cp<end)
- *cp++ = 0;
- }
- return(base);
+ register char *cp, *end;
+ char *base;
+ int size;
+
+ size = nelem * elsize;
+ base = _malloc(size);
+ if(base) {
+ cp = base;
+ end = base+size;
+ while(cp<end) {
+ *cp++ = 0;
+ }
+ }
+ return(base);
}
#ifdef MALLOC_DEBUG
char *
calloc(int nelem, int elsize, char *fname, int fline)
{
- char *cp;
- struct mhdr *mptr;
-
- cp = _calloc(nelem, elsize);
- if (cp) {
- mptr = (struct mhdr *)cp;
- mptr--;
- strncpy(mptr->fname,fname,FNAMESIZE-1);
- mptr->fline = fline;
- mptr->fname[FNAMESIZE-1] = 0;
- mptr->fline = fline;
- }
- return(cp);
+ char *cp;
+ struct mhdr *mptr;
+
+ cp = _calloc(nelem, elsize);
+ if(cp) {
+ mptr = (struct mhdr *)cp;
+ mptr--;
+ strncpy(mptr->fname,fname,FNAMESIZE-1);
+ mptr->fline = fline;
+ mptr->fname[FNAMESIZE-1] = 0;
+ mptr->fline = fline;
+ }
+ return(cp);
}
#else
@@ -409,7 +427,7 @@ calloc(int nelem, int elsize, char *fname, int fline)
char *
calloc(int nelem, int elsize)
{
- return(_calloc(nelem,elsize));
+ return(_calloc(nelem,elsize));
}
#endif
@@ -417,100 +435,105 @@ calloc(int nelem, int elsize)
static char *
_realloc(char *cp,int newsize)
{
- char *new;
- int asize, delta;
- struct mhdr *mptr, tmphdr;
-
- rcalls++;
-
- /* If incoming pointer is NULL, then do a regular malloc. */
- if (!cp)
- return(_malloc(newsize));
-
- /* If newsize is zero and pointer is not null, then do a free. */
- if (!newsize) {
- free(cp);
- return((char *)0);
- }
-
- /* Set the mhdr pointer to the header attached to the incoming
- * char pointer. We assume here that the incoming pointer is the
- * base address of the block of memory that is being reallocated.
- */
- mptr = (struct mhdr *)cp - 1;
-
- /* Start by checking sanity of heap and make sure that the incoming
- * pointer corresponds to a valid entry in the heap.
- */
- if (heapcheck(mptr,0) < 0)
- return((char *)0);
-
- /* Recall that mptr->size is negative since the block is not free, so
- * use the absolute value of mptr->size...
- */
- asize = abs(mptr->size);
-
- /* Make requested size divisible by 4:
- */
- if (newsize & 3) {
- newsize += 4;
- newsize &= 0xfffffffc;
- }
-
- /* If newsize is less than or equal to current size, just return with
- * the same pointer. At some point, this should be improved so that
- * the memory made made available by this reallocation is put back in
- * the pool.
- */
- if (newsize <= asize)
- return(cp);
-
- /* Now we do the actual reallocation...
- * If there is a fragment after this one (next != NULL) AND it is
- * available (size > 0) AND the combined size of the next fragment
- * along with the current fragment exceeds the request, then we can
- * reallocate quickly.
- * Otherwise, we have to just malloc a whole new block and copy the
- * old buffer to the new larger space.
- */
- if ((mptr->next) && (mptr->next->size > 0) &&
- ((asize + mptr->next->size + MHDRSIZE) > newsize)) {
-
- /* At this point we know we have the space to reallocate without
- * the malloc/free step. Now we need to add the necessary space
- * to the current fragment, and take that much away from the next
- * fragment...
- */
- delta = newsize - asize;
- /* next line used to be: tmphdr = *mptr->next... */
- memcpy((char *)&tmphdr,(char *)mptr->next, sizeof(struct mhdr));
- mptr->size = -newsize;
- mptr->next = (struct mhdr *)(delta + (int)(mptr->next));
- mptr->next->size = (abs(tmphdr.size) - delta);
- mptr->next->pretag = PRETAG;
- mptr->next->posttag = POSTTAG;
- mptr->next->next = tmphdr.next;
- mptr->next->prev = tmphdr.prev;
-
- /* Keep track of totals and highwater:
- */
- mtot += (newsize - asize);
- if ((mtot - ftot) > highwater)
- highwater = (mtot - ftot);
- return(cp);
- }
-
- /* If the next fragment is not large enough, then malloc new space,
- * copy the existing data to that block, free the old space and return
- * a pointer to the new block.
- */
- new = _malloc(newsize);
- if (!new)
- return((char *)0);
-
- memcpy(new,cp,asize);
- free(cp);
- return(new);
+ char *new;
+ int asize, delta;
+ struct mhdr *mptr, tmphdr;
+
+ rcalls++;
+
+ /* If incoming pointer is NULL, then do a regular malloc. */
+ if(!cp) {
+ return(_malloc(newsize));
+ }
+
+ /* If newsize is zero and pointer is not null, then do a free. */
+ if(!newsize) {
+ free(cp);
+ return((char *)0);
+ }
+
+ /* Set the mhdr pointer to the header attached to the incoming
+ * char pointer. We assume here that the incoming pointer is the
+ * base address of the block of memory that is being reallocated.
+ */
+ mptr = (struct mhdr *)cp - 1;
+
+ /* Start by checking sanity of heap and make sure that the incoming
+ * pointer corresponds to a valid entry in the heap.
+ */
+ if(heapcheck(mptr,0) < 0) {
+ return((char *)0);
+ }
+
+ /* Recall that mptr->size is negative since the block is not free, so
+ * use the absolute value of mptr->size...
+ */
+ asize = abs(mptr->size);
+
+ /* Make requested size divisible by 4:
+ */
+ if(newsize & 3) {
+ newsize += 4;
+ newsize &= 0xfffffffc;
+ }
+
+ /* If newsize is less than or equal to current size, just return with
+ * the same pointer. At some point, this should be improved so that
+ * the memory made made available by this reallocation is put back in
+ * the pool.
+ */
+ if(newsize <= asize) {
+ return(cp);
+ }
+
+ /* Now we do the actual reallocation...
+ * If there is a fragment after this one (next != NULL) AND it is
+ * available (size > 0) AND the combined size of the next fragment
+ * along with the current fragment exceeds the request, then we can
+ * reallocate quickly.
+ * Otherwise, we have to just malloc a whole new block and copy the
+ * old buffer to the new larger space.
+ */
+ if((mptr->next) && (mptr->next->size > 0) &&
+ ((asize + mptr->next->size + MHDRSIZE) > newsize)) {
+
+ /* At this point we know we have the space to reallocate without
+ * the malloc/free step. Now we need to add the necessary space
+ * to the current fragment, and take that much away from the next
+ * fragment...
+ */
+ delta = newsize - asize;
+ /* next line used to be: tmphdr = *mptr->next... */
+ memcpy((char *)&tmphdr,(char *)mptr->next, sizeof(struct mhdr));
+ mptr->size = -newsize;
+ mptr->next = (struct mhdr *)(delta + (int)(mptr->next));
+ mptr->next->size = (abs(tmphdr.size) - delta);
+ mptr->next->pretag = PRETAG;
+ mptr->next->posttag = POSTTAG;
+ mptr->next->next = tmphdr.next;
+ mptr->next->prev = tmphdr.prev;
+
+ /* Keep track of totals and highwater:
+ */
+ mtot += (newsize - asize);
+ if((mtot - ftot) > highwater) {
+ highwater = (mtot - ftot);
+ }
+ return(cp);
+ }
+
+ /* If the next fragment is not large enough, then malloc new space,
+ * copy the existing data to that block, free the old space and return
+ * a pointer to the new block.
+ */
+ new = _malloc(newsize);
+ if(!new) {
+ return((char *)0);
+ }
+
+ memcpy(new,cp,asize);
+ free(cp);
+ return(new);
}
#ifdef MALLOC_DEBUG
@@ -518,19 +541,19 @@ _realloc(char *cp,int newsize)
char *
realloc(char *buf, int newsize, char *fname, int fline)
{
- char *cp;
- struct mhdr *mptr;
-
- cp = _realloc(buf, newsize);
- if (cp) {
- mptr = (struct mhdr *)cp;
- mptr--;
- strncpy(mptr->fname,fname,FNAMESIZE-1);
- mptr->fline = fline;
- mptr->fname[FNAMESIZE-1] = 0;
- mptr->fline = fline;
- }
- return(cp);
+ char *cp;
+ struct mhdr *mptr;
+
+ cp = _realloc(buf, newsize);
+ if(cp) {
+ mptr = (struct mhdr *)cp;
+ mptr--;
+ strncpy(mptr->fname,fname,FNAMESIZE-1);
+ mptr->fline = fline;
+ mptr->fname[FNAMESIZE-1] = 0;
+ mptr->fline = fline;
+ }
+ return(cp);
}
#else
@@ -538,7 +561,7 @@ realloc(char *buf, int newsize, char *fname, int fline)
char *
realloc(char *buf, int newsize)
{
- return(_realloc(buf,newsize));
+ return(_realloc(buf,newsize));
}
#endif
@@ -546,207 +569,218 @@ realloc(char *buf, int newsize)
void
heapdump(int verbose)
{
- register struct mhdr *mptr;
- char freenow;
- int i, alloctot, freetot, size;
-
- heapcheck(0,0);
-
- mptr = heapbase;
- i=0;
- freetot = 0;
- alloctot = 0;
- if (verbose)
- printf(" addr size free? mptr nxt prv ascii@addr\n");
- else
- printf("Heap summary:\n");
- for(i=0;mptr;i++) {
- if (mptr->size < 0) {
- freenow = 'n';
- size = -mptr->size;
- alloctot += size;
- }
- else {
- freenow = 'y';
- size = mptr->size;
- freetot += size;
- }
- if (verbose) {
- printf("%3d: 0x%08lx %5d %c 0x%08lx 0x%08lx 0x%08lx ",
- i,(ulong)(mptr+1),size,freenow,(ulong)mptr,
- (ulong)(mptr->next),(ulong)(mptr->prev));
- prascii((unsigned char *)(mptr+1),size > 16 ? 16 : size);
- putchar('\n');
+ register struct mhdr *mptr;
+ char freenow;
+ int i, alloctot, freetot, size;
+
+ heapcheck(0,0);
+
+ mptr = heapbase;
+ i=0;
+ freetot = 0;
+ alloctot = 0;
+ if(verbose) {
+ printf(" addr size free? mptr nxt prv ascii@addr\n");
+ } else {
+ printf("Heap summary:\n");
+ }
+ for(i=0; mptr; i++) {
+ if(mptr->size < 0) {
+ freenow = 'n';
+ size = -mptr->size;
+ alloctot += size;
+ } else {
+ freenow = 'y';
+ size = mptr->size;
+ freetot += size;
+ }
+ if(verbose) {
+ printf("%3d: 0x%08lx %5d %c 0x%08lx 0x%08lx 0x%08lx ",
+ i,(ulong)(mptr+1),size,freenow,(ulong)mptr,
+ (ulong)(mptr->next),(ulong)(mptr->prev));
+ prascii((unsigned char *)(mptr+1),size > 16 ? 16 : size);
+ putchar('\n');
#ifdef MALLOC_DEBUG
- if (freenow == 'n')
- printf(" %s %d\n",mptr->fname,mptr->fline);
+ if(freenow == 'n') {
+ printf(" %s %d\n",mptr->fname,mptr->fline);
+ }
#endif
- }
- mptr = mptr->next;
- }
- if (verbose)
- putchar('\n');
- printf(" Malloc/realloc/free calls: %d/%d/%d\n",mcalls,rcalls,fcalls);
- printf(" Malloc/free totals: %d/%d\n",mtot,ftot);
- printf(" High-water level: %d\n",highwater);
- printf(" Malloc failures: %d\n",mfails);
- printf(" Bytes overhead: %d\n",i * MHDRSIZE);
- printf(" Bytes currently allocated: %d\n",alloctot);
- printf(" Bytes free on current heap: %d\n",freetot);
- printf(" Bytes left in allocation pool: %d\n",GetMemoryLeft());
+ }
+ mptr = mptr->next;
+ }
+ if(verbose) {
+ putchar('\n');
+ }
+ printf(" Malloc/realloc/free calls: %d/%d/%d\n",mcalls,rcalls,fcalls);
+ printf(" Malloc/free totals: %d/%d\n",mtot,ftot);
+ printf(" High-water level: %d\n",highwater);
+ printf(" Malloc failures: %d\n",mfails);
+ printf(" Bytes overhead: %d\n",i * MHDRSIZE);
+ printf(" Bytes currently allocated: %d\n",alloctot);
+ printf(" Bytes free on current heap: %d\n",freetot);
+ printf(" Bytes left in allocation pool: %d\n",GetMemoryLeft());
}
/* releaseExtendedHeap():
- * If memory has been allocated through the extended heap established
- * by the heap -x{start,size} command, this function will attempt
- * to "undo" that. It can only be un-done if there is no currently active
- * allocations in that range.
+ * If memory has been allocated through the extended heap established
+ * by the heap -x{start,size} command, this function will attempt
+ * to "undo" that. It can only be un-done if there is no currently active
+ * allocations in that range.
*
- * This function is accessible by the application through monlib.
+ * This function is accessible by the application through monlib.
*/
int
releaseExtendedHeap(int verbose)
{
- int i;
- struct mhdr *mptr, *extbase;
-
- extbase = (struct mhdr *)getExtHeapBase();
- if (!extbase) {
- if (verbose)
- printf("Heap extension not set\n");
- return(-1);
- }
-
- heapcheck(0,0);
- mptr = heapbase;
- for(i=0;mptr;i++) {
- if (mptr->next == extbase) {
- if (mptr->next->next == (struct mhdr *)0) {
- mptr->next = (struct mhdr *)0;
- unExtendHeap();
- if (verbose)
- printf("Heap extension cleared\n");
- return(0);
- }
- else if (verbose)
- printf("Extended heap space is in use.\n");
- break;
- }
- mptr = mptr->next;
- }
- if (!mptr) { /* Heap was extended, but not used. */
- unExtendHeap(); /* Remove the extension. */
- if (verbose)
- printf("Heap extension cleared.\n");
- }
- return(0);
+ int i;
+ struct mhdr *mptr, *extbase;
+
+ extbase = (struct mhdr *)getExtHeapBase();
+ if(!extbase) {
+ if(verbose) {
+ printf("Heap extension not set\n");
+ }
+ return(-1);
+ }
+
+ heapcheck(0,0);
+ mptr = heapbase;
+ for(i=0; mptr; i++) {
+ if(mptr->next == extbase) {
+ if(mptr->next->next == (struct mhdr *)0) {
+ mptr->next = (struct mhdr *)0;
+ unExtendHeap();
+ if(verbose) {
+ printf("Heap extension cleared\n");
+ }
+ return(0);
+ } else if(verbose) {
+ printf("Extended heap space is in use.\n");
+ }
+ break;
+ }
+ mptr = mptr->next;
+ }
+ if(!mptr) { /* Heap was extended, but not used. */
+ unExtendHeap(); /* Remove the extension. */
+ if(verbose) {
+ printf("Heap extension cleared.\n");
+ }
+ }
+ return(0);
}
char *HeapHelp[] = {
- "Display heap statistics.",
- "-[cf:m:qtvX:x]",
+ "Display heap statistics.",
+ "-[cf:m:qtvX:x]",
#if INCLUDE_VERBOSEHELP
- "Options:",
- " -c clear high-water level and malloc/free totals",
- " -f{ptr} free block @ 'ptr'",
- " -m{size} malloc 'size' bytes",
- " -q quiet runtime (don't print MALLOC ERROR msgs)",
- " -v verbose (more detail)",
- " -t toggle runtime malloc/free trace",
- " -X{base,size}",
- " extend heap by 'size' bytes starting at 'base'",
- " -x clear heap extension",
+ "Options:",
+ " -c clear high-water level and malloc/free totals",
+ " -f{ptr} free block @ 'ptr'",
+ " -m{size} malloc 'size' bytes",
+ " -q quiet runtime (don't print MALLOC ERROR msgs)",
+ " -v verbose (more detail)",
+ " -t toggle runtime malloc/free trace",
+ " -X{base,size}",
+ " extend heap by 'size' bytes starting at 'base'",
+ " -x clear heap extension",
#endif
- 0
+ 0
};
int
Heap(int argc,char *argv[])
{
- char *establish_extended_heap, buf[32];
- int verbose, release_extended_heap, showheap, opt;
-
- showheap = 1;
- establish_extended_heap = (char *)0;
- release_extended_heap = verbose = 0;
- while((opt=getopt(argc,argv,"cf:m:qtvX:x")) != -1) {
- switch(opt) {
- case 'c':
- mcalls = fcalls = 0;
- mtot = ftot = highwater = 0;
- showheap = 0;
- break;
- case 'f':
- free((char *)strtoul(optarg,0,0));
- showheap = 0;
- break;
- case 'm':
- shell_sprintf("MALLOC","0x%lx",
- (ulong)_malloc(strtoul(optarg,0,0)));
- if (verbose)
- printf("%s\n",buf);
- showheap = 0;
- break;
- case 'q':
- showheap = 0;
- mquiet = 1;
- break;
- case 't':
- mtrace = ~mtrace;
- printf("Runtime trace: %sabled\n",
- mtrace ? "en" : "dis");
- return(CMD_SUCCESS);
- case 'v':
- verbose = 1;
- break;
- case 'X':
- establish_extended_heap = optarg;
- showheap = 0;
- break;
- case 'x':
- release_extended_heap = 1;
- showheap = 0;
- break;
- default:
- return(CMD_PARAM_ERROR);
- }
- }
- if (release_extended_heap)
- releaseExtendedHeap(verbose);
-
- if (establish_extended_heap) {
- int size, rc;
- char *comma, *begin;
-
- comma = strchr(establish_extended_heap,',');
- if (!comma)
- return(CMD_PARAM_ERROR);
- *comma = 0;
- begin = (char *)strtoul(establish_extended_heap,0,0);
- size = (int)strtoul(comma+1,0,0);
- rc = extendHeap(begin,size);
- if (rc == -1) {
- printf("Extended heap already exists @ 0x%lx\n",
- (ulong)getExtHeapBase());
- }
- if (rc < 0)
- return(CMD_FAILURE);
- }
-
- if (!showheap)
- return(CMD_SUCCESS);
-
- if (optind == argc)
- heapdump(verbose);
-
- return(CMD_SUCCESS);
+ char *establish_extended_heap, buf[32];
+ int verbose, release_extended_heap, showheap, opt;
+
+ showheap = 1;
+ establish_extended_heap = (char *)0;
+ release_extended_heap = verbose = 0;
+ while((opt=getopt(argc,argv,"cf:m:qtvX:x")) != -1) {
+ switch(opt) {
+ case 'c':
+ mcalls = fcalls = 0;
+ mtot = ftot = highwater = 0;
+ showheap = 0;
+ break;
+ case 'f':
+ free((char *)strtoul(optarg,0,0));
+ showheap = 0;
+ break;
+ case 'm':
+ shell_sprintf("MALLOC","0x%lx",
+ (ulong)_malloc(strtoul(optarg,0,0)));
+ if(verbose) {
+ printf("%s\n",buf);
+ }
+ showheap = 0;
+ break;
+ case 'q':
+ showheap = 0;
+ mquiet = 1;
+ break;
+ case 't':
+ mtrace = ~mtrace;
+ printf("Runtime trace: %sabled\n",
+ mtrace ? "en" : "dis");
+ return(CMD_SUCCESS);
+ case 'v':
+ verbose = 1;
+ break;
+ case 'X':
+ establish_extended_heap = optarg;
+ showheap = 0;
+ break;
+ case 'x':
+ release_extended_heap = 1;
+ showheap = 0;
+ break;
+ default:
+ return(CMD_PARAM_ERROR);
+ }
+ }
+ if(release_extended_heap) {
+ releaseExtendedHeap(verbose);
+ }
+
+ if(establish_extended_heap) {
+ int size, rc;
+ char *comma, *begin;
+
+ comma = strchr(establish_extended_heap,',');
+ if(!comma) {
+ return(CMD_PARAM_ERROR);
+ }
+ *comma = 0;
+ begin = (char *)strtoul(establish_extended_heap,0,0);
+ size = (int)strtoul(comma+1,0,0);
+ rc = extendHeap(begin,size);
+ if(rc == -1) {
+ printf("Extended heap already exists @ 0x%lx\n",
+ (ulong)getExtHeapBase());
+ }
+ if(rc < 0) {
+ return(CMD_FAILURE);
+ }
+ }
+
+ if(!showheap) {
+ return(CMD_SUCCESS);
+ }
+
+ if(optind == argc) {
+ heapdump(verbose);
+ }
+
+ return(CMD_SUCCESS);
}
#else
char *
malloc(int size)
{
- return(0);
+ return(0);
}
void
@@ -757,7 +791,7 @@ free(char *buf)
char *
realloc(char *buf, int newsize, char *fname, int fline)
{
- return(0);
+ return(0);
}
#endif