⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 malloc.c

📁 umon bootloader source code, support mips cpu.
💻 C
📖 第 1 页 / 共 2 页
字号:
	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

char *
calloc(int nelem, int elsize)
{
	return(_calloc(nelem,elsize));
}
#endif


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;
		tmphdr = *mptr->next;
		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
#undef realloc
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);
}

#else

char *
realloc(char *buf, int newsize)
{
	return(_realloc(buf,newsize));
}
#endif


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');
#ifdef MALLOC_DEBUG
			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());
}

/* 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.
 *
 *	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);
}


char *HeapHelp[] = {
	"Display heap statistics.",
	"-[cf:m:qvX: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)",
	" -X{base,size}",
	"           extend heap by 'size' bytes starting at 'base'",
	" -x        clear heap extension",
#endif
	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:qvX: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 '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;
		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);
		if (extendHeap(begin,size) == -1) {
			printf("Extended heap already exists @ 0x%lx\n",
				(ulong)getExtHeapBase());
			return(CMD_FAILURE);
		}
	}

	if (!showheap)
		return(CMD_SUCCESS);

	if (optind == argc)
		heapdump(verbose);

	return(CMD_SUCCESS);
}
#else
char *
malloc(int size)
{
	return(0);
}

void
free(char *buf)
{
}

char *
realloc(char *buf, int newsize, char *fname, int fline)
{
	return(0);
}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -