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

📄 malloc.c

📁 在VC6环境下开发
💻 C
字号:
#include "eDbInit.h"
#define _CHECK_MEM_
#define NR_HOLES         128    /* max entries in hole table */
#define SIZE_EXTRA		4
#define NIL_HOLE (hole *)0

#define TOHEAD(X) ((u8*)((u32*)(X)-1))
#define TOADDR(X) ((void*)((u32*)X+1))
#define SET_SIZE(P,X) (*((u32 *)P) = X)
#define GET_SIZE(P) (*((u32*)TOHEAD(P)))
#define ROUNDUP(X)  ((X+3) & ~3)

#ifdef _CHECK_MEM_
u32 nByteUsedMem = 0;
u32 nByteUsedMemBak = 0;
#endif

#ifndef WIN32
//#define RAM_SIZE	0x1000000	// = 1024*1024*16
//extern u8 Image$$RW$$Limit[];
//extern u8 Image$$RW$$Base[];
//static u8 *raw_mem=&Image$$RW$$Limit[1024];
//#define MAX_DYNAMIC_MEM	(Image$$RW$$Base + RAM_SIZE - Image$$RW$$Limit - 1024)
#define MAX_DYNAMIC_MEM	0x100000
static u8 raw_mem[MAX_DYNAMIC_MEM];
#else
#define MAX_DYNAMIC_MEM	0x100000
static u8 raw_mem[MAX_DYNAMIC_MEM];
#endif

typedef struct hole {
	u8 *h_base;
	u32 h_len; 
	struct hole *h_next;
} hole;

	hole ahole[NR_HOLES];
	hole *hole_head;		/* pointer to first hole */
	hole *free_slots;	/* ptr to list of unused table slots */

void del_slot(hole *prev_ptr, hole *hp){
	/* prev_ptr:	pointer to hole entry just ahead of 'hp' */
	/* hp:	pointer to hole entry to be removed */

	/* Remove an entry from the hole list.  This procedure is called when a
	** request to allocate memory removes a hole in its entirety, thus reducing
	** the numbers of holes in memory, and requiring the elimination of one
	** entry in the hole list.
	*/
	if (hp == hole_head){
		hole_head = hp->h_next;
	}
	else{
		prev_ptr->h_next = hp->h_next;
	}
	hp->h_next = free_slots;
	free_slots = hp;
}


void merge(hole *hp)
/* hp: ptr to hole to merge with its successors */
{
	hole *next_ptr;
	/* If 'hp' points to the last hole, no merging is possible.  If it does not,
	** try to absorb its successor into it and free the successor's table entry.
	*/
	if ( (next_ptr = hp->h_next) == NIL_HOLE) return;
	if (hp->h_base + hp->h_len == next_ptr->h_base) {
		hp->h_len += next_ptr->h_len;   /* first one gets second one's mem */
		del_slot(hp, next_ptr);
	} else {
		hp = next_ptr;
	}
	/* If 'hp' now points to the last hole, return; otherwise, try to absorb its
	** successor into it.
	*/
	if ( (next_ptr = hp->h_next) == NIL_HOLE) return;
	if (hp->h_base + hp->h_len == next_ptr->h_base) {
		hp->h_len += next_ptr->h_len;
		del_slot(hp, next_ptr);
	}
}

void free_mem(void *base){
	/* Return a block of free memory to the hole list.  The parameters tell where
	** the block starts in physical memory and how big it is.  The block is added
	** to the hole list.  If it is contiguous with an existing hole on either end,
	** it is merged with the hole or holes.
	*/
	hole *hp, *new_ptr, *prev_ptr;
	u32 nByte;

	nByte = GET_SIZE(base);		
	if (nByte == 0) return;

#ifdef _CHECK_MEM_
	if(nByteUsedMemBak < nByteUsedMem){
		nByteUsedMemBak = nByteUsedMem;
	}
	nByteUsedMem -= nByte;
#endif

	if ( (new_ptr = free_slots) == NIL_HOLE){
		assert(0);
		return ;
	}
	new_ptr->h_base = TOHEAD(base); 
	new_ptr->h_len = nByte;
	free_slots = new_ptr->h_next;
	hp = hole_head;
	if (hp == NIL_HOLE || TOHEAD(base) <= hp->h_base) {
		new_ptr->h_next = hp; 
		hole_head = new_ptr;
		merge(new_ptr);
	}else{
		while (hp != NIL_HOLE && TOHEAD(base) > hp->h_base) {
			prev_ptr = hp;
			hp = hp->h_next;
		}

		new_ptr->h_next = prev_ptr->h_next;
		prev_ptr->h_next = new_ptr;
		merge(prev_ptr);              /* sequence is 'prev_ptr', 'new_ptr', 'hp' */
	}
}

void *alloc_mem(u32 nByte){
	/* Allocate a block of memory from the free list using first fit. The block
	** consists of a sequence of contiguous bytes, whose length in clicks is
	** given by 'clicks'.  A pointer to the block is returned.  The block is
	** always on a click boundary.  This procedure is called when memory is
	** needed for FORK or EXEC.
	*/
	hole *hp, *prev_ptr;
	u8 *base;
	hp = hole_head;

	nByte += SIZE_EXTRA;	
	nByte = ROUNDUP(nByte);	
	while (hp != NIL_HOLE) {
		if (hp->h_len >= nByte) {
			/* We found a hole that is big enough.  Use it. */

			nByteUsedMem += nByte;

			base = hp->h_base;
			hp->h_base += nByte;
			hp->h_len -= nByte;	
			
			if (hp->h_len != 0){
				SET_SIZE(base,nByte);
				return TOADDR(base);
			}
			/* add it to free list*/
			del_slot(prev_ptr, hp);

			SET_SIZE(base,nByte);
			return TOADDR(base);
		}
		prev_ptr = hp;
		hp = hp->h_next;
	}
	return 0;
}

void *realloc_mem(void *base, u32 nByte){
	u8 *ptr;
	u32 old_size;
	
	if(base == 0){
		return alloc_mem(nByte);
	}
	if(nByte == 0){	
		free_mem(base);
		return 0;
	}
	old_size = GET_SIZE(base)-SIZE_EXTRA;
	ptr = alloc_mem(nByte+old_size);
	if(ptr == 0){
		return 0;
	}	
	memcpy(ptr,base,old_size);
	free_mem(base);
	return ptr;
}


u32 max_hole()
{
	/* Scan the hole list and return the largest hole. */
	hole *hp;
	u32 max;
	hp = hole_head;
	max = 0;
	while (hp != NIL_HOLE) {
		if (hp->h_len > max) max = hp->h_len;
		hp = hp->h_next;
	}
	return max;
}

void mem_init(void)
{		
	hole *hp;
	u8 *base = raw_mem;
	for (hp = &ahole[0]; hp < &ahole[NR_HOLES]; hp++){
		hp->h_len = 0;
		hp->h_base = 0;
		hp->h_next = hp + 1;
	}
	ahole[NR_HOLES-1].h_next = NIL_HOLE;
	ahole[NR_HOLES-1].h_base = 0;
	ahole[NR_HOLES-1].h_len = 0;

	hole_head = NIL_HOLE;
	free_slots= &ahole[0];
	SET_SIZE(base,MAX_DYNAMIC_MEM);
	free_mem(TOADDR(base));
#ifdef _CHECK_MEM_
	nByteUsedMem = 0;
	nByteUsedMemBak = 0;
#endif
}

void check_memory(void){

#ifdef _CHECK_MEM_

	hole *hp = hole_head;
	hole *fr = free_slots;

	fprintf(fdebug,"\nbase mem addr: %x\n",raw_mem);
	fprintf(fdebug,"hole_head addr: %x\n",hp);
	fprintf(fdebug,"free_slots addr: %x\n",fr);
	fprintf(fdebug,"max alloc mem: %x bytes\n",nByteUsedMemBak);
	fprintf(fdebug,"unrelease mem: %x bytes\n",nByteUsedMem);
	while(hp != NIL_HOLE){
		fprintf(fdebug,"hp->h_base: %x\t",hp->h_base);
		fprintf(fdebug,"hp->h_len: %x\t",hp->h_len);
		fprintf(fdebug,"hp->h_next: %x\n",hp->h_next);

		hp = hp->h_next;
	}
	while(fr != NIL_HOLE && fr->h_len != 0){
		fprintf(fdebug,"fr->h_base: %x\t",fr->h_base);
		fprintf(fdebug,"fr->h_len: %x\t",fr->h_len);
		fprintf(fdebug,"fr->h_next: %x\n",fr->h_next);

		fr = fr->h_next;
	}
#endif
}

⌨️ 快捷键说明

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