自己动手写的内存管理程序Ver0.1

/*

*

*	menmory management module

*	chenbdchenbd@gmail.com

*

*/

#include <stdio.h>

#include <stdlib.h>

#include <memory.h>



#define MM_OK		(0x00)

#define	MM_NG		(0xff)



#define MM_UNIT		((unsigned int)4)	/*	least malloc size	*/

#define MM_SPLIT_NUM ((unsigned int)10)	/*	table len	*/



#define	MM_MAX_ONCE_MALLOC	((unsigned int)((MM_UNIT << MM_SPLIT_NUM) - sizeof(MEM_BLK_t)) )	/*	4K - 4	*/

#define	MM_MAX_UNIT			((unsigned int)(MM_UNIT << MM_SPLIT_NUM) )	/*	4K	*/

#define	MM_MAX_MEMORY		((unsigned int)(MM_MAX_UNIT << MM_SPLIT_NUM))	/*	4M	*/

#define MM_MALLOC_MEMORY	((unsigned int)(MM_MAX_MEMORY))

#define	MM_IDX_NUM		(MM_SPLIT_NUM + 1)







/*	print on/off macro	*/

#ifdef _DEBUG

#define MM_DEBUG(x)	x

#else

#define	MM_DEBUG(x)

#endif



/*	data construct	*/

typedef union

{

	union MEM_BLK_t*	next;	/*	internal usage	*/

	void*				p;		/*	external usage	*/

}MEM_BLK_t;



static int mm_get_unit(unsigned int size);

static unsigned int mm_get_size(unsigned int size);

int mm_insert(MEM_BLK_t** mem_blk, void* adr);

int mm_chk_merge(void);



MEM_BLK_t* mm_ctrl[MM_IDX_NUM + 1];



int	mm_init(MEM_BLK_t** mm_ctrl)

{

	int i_ret = MM_NG;

	int i_loop;

	void* p;

	int	idx;

	MEM_BLK_t*	mem_blk;



	if (NULL != mm_ctrl)

	{

		/*	init table	*/

		for (i_loop = 0; i_loop < MM_IDX_NUM; i_loop++)

		{

			mm_ctrl[i_loop] = NULL;

		}

		/*	malloc a chunk	*/

		p = malloc(MM_MALLOC_MEMORY);

		if ( NULL != p)

		{

			mm_ctrl[MM_IDX_NUM] = p;	/*	store the pointer	*/

			idx = mm_get_unit(MM_MAX_ONCE_MALLOC);

			mm_ctrl[idx] = mem_blk = p;



			/*	split by MM_MAX_UNIT	*/

			while ((char*)mem_blk < ((char*)mm_ctrl[idx] + MM_MALLOC_MEMORY))

			{

				p = mem_blk;

				mem_blk->next = (MEM_BLK_t*)((char*)p + MM_MAX_UNIT);

//				mem_blk->p = (MEM_BLK_t*)((char*)p + sizeof(MEM_BLK_t));

				mem_blk = mem_blk->next;

			}

			/*	set last NULL	*/

			mem_blk = (MEM_BLK_t*)((char*)mem_blk - MM_MAX_UNIT);

			mem_blk->next = NULL;

			i_ret = MM_OK;

			MM_DEBUG(printf("MM:mm_init init OK!!!/n"));

		}

		else

		{

			MM_DEBUG(printf("MM:mm_init malloc fail!!!/n"));

		}

	}

	return i_ret;

}



int	mm_end(MEM_BLK_t** mm_ctrl)

{

	int i_ret = MM_NG;



	if (NULL != mm_ctrl)

	{



		if (NULL != mm_ctrl[MM_IDX_NUM])

		{

			free(mm_ctrl[MM_IDX_NUM]);

			i_ret = MM_OK;

			MM_DEBUG(printf("MM:mm_end free OK!!!/n"));

		}

		else

		{

			MM_DEBUG(printf("MM:mm_end  free fail!!!/n"));

		}

	}

	return i_ret;

}



void*	mm_malloc(unsigned int size)

{

	MEM_BLK_t* p;

	MEM_BLK_t*	mem_blk;

	int idx = -1;

	int i_loop;

	int tmp;

	unsigned int msize;

	unsigned int msize_tmp;



	if ((0 >= size) || (MM_MAX_ONCE_MALLOC < size))

	{

		MM_DEBUG(printf("MM:mm_malloc invalid argument %08x!!!/n", size));

		return NULL;

	}

	

	idx = mm_get_unit(size);

	if (0 > idx)

		return NULL;

	if (NULL != mm_ctrl[idx])

	{

		mem_blk = mm_ctrl[idx];

		mm_ctrl[idx] = mem_blk->next;

//		mem_blk->p = (void*)((char*)mem_blk + sizeof(MEM_BLK_t));

//		return (void*)mem_blk->p;

		mem_blk->p = (void*)(MM_UNIT << idx);

		p = (void*)((char*)mem_blk + sizeof(MEM_BLK_t));

		MM_DEBUG(printf("MM:mm_malloc ok, address=%08p!!!/n", p));

		return p;

	}

	else

	{

		for (i_loop = idx + 1; i_loop < MM_IDX_NUM ; i_loop++)

		{

			if (NULL != mm_ctrl[i_loop])

			{

				break;

			}

		}

		if (MM_IDX_NUM == i_loop)

		{

			MM_DEBUG(printf("MM:mm_malloc invalid i_loop %08x!!!/n", i_loop));

			if (MM_OK == mm_chk_merge())

			{

				/*	to be worked	*/

			//	goto mm_label;

				i_loop = MM_SPLIT_NUM;

			}

			else

			{

#ifdef _DEBUG

				__asm{

					int 3;

				}

#endif

				return NULL;

			}

		}

		MM_DEBUG(printf("MM:mm_malloc find split position idx=%08x, splitpos=%08x!!!/n", idx, i_loop));

		tmp = i_loop;

		mem_blk = mm_ctrl[i_loop];

		mm_ctrl[i_loop] = mem_blk->next;

		

		/*	split	*/

		p = mem_blk;

		msize = mm_get_size(size);

		msize_tmp = msize;

		for (i_loop = idx; i_loop < tmp ; i_loop++)

		{

			msize = msize_tmp << (i_loop - idx);

			mm_ctrl[i_loop] = (MEM_BLK_t*)((char*)mem_blk + msize);

			p = mm_ctrl[i_loop];

			p->next = NULL;

			//			p->p = ((char*)p + sizeof(MEM_BLK_t));

		}

		//		mem_blk->p = (void*)((char*)mem_blk + sizeof(MEM_BLK_t));

		//		return (void*)mem_blk->p;

		mem_blk->p = (void*)(MM_UNIT << idx);

		p = (void*)((char*)mem_blk + sizeof(MEM_BLK_t));

		MM_DEBUG(printf("MM:mm_malloc ok, address=%08p!!!/n", p));

		return p;

	}



	return NULL;

}



int		mm_free(void* p)

{

	MEM_BLK_t*	mem_blk;

	MEM_BLK_t*	tmp;

	unsigned int msize;

	int idx;



	if (NULL == p)

	{

		MM_DEBUG(printf("MM:mm_free invalid argument %08p!!!/n", p));

		return MM_NG;

	}



	mem_blk = (MEM_BLK_t*)((char*)p -sizeof(MEM_BLK_t));

	if (0 >= (unsigned int)mem_blk->p)

	{

		MM_DEBUG(printf("MM:mm_free check failure p=%08p, mem_blk->p =%08p!!!/n", p, mem_blk->p));

		return MM_NG;

	}



	MM_DEBUG(printf("MM:mm_free, address=%08p!!!/n", p));



	msize = (unsigned int)mem_blk->p;

	mem_blk->next = NULL;



	idx = mm_get_unit(msize - sizeof(MEM_BLK_t));

	if (0 > idx)

		return MM_NG;

	if (NULL == mm_ctrl[idx])

	{

		mm_ctrl[idx] = mem_blk;

//		mem_blk->p = (void*)((char*)mem_blk + sizeof(MEM_BLK_t));

		mem_blk->next = NULL;

		MM_DEBUG(printf("MM:mm_free ok!!!/n"));

	}

	else

	{

#if 1 // ver0.1

		mm_insert(&mm_ctrl[idx], mem_blk);

#else

		tmp = mm_ctrl[idx];

		if (mem_blk < tmp)

		{

			mem_blk->next = tmp;

			mm_ctrl[idx] = mem_blk;

		}

		else

		{

			p = tmp;

			tmp = tmp->next;

			while (tmp)

			{

				if (mem_blk < tmp)

				{

					mem_blk->next = tmp;

					((MEM_BLK_t*)p)->next = mem_blk;

					break;

				}

				p = tmp;

				tmp = tmp->next;

			}

			if (NULL == tmp)

			{

				((MEM_BLK_t*)p)->next = mem_blk;

			}

		}

#endif

		MM_DEBUG(printf("MM:mm_free ok!!!/n"));

	}

	return MM_OK;

}



int mm_insert(MEM_BLK_t** mem_blk, void* adr)

{

	int i_ret = MM_NG;

	MEM_BLK_t* tmp;

	MEM_BLK_t* p;



	if ((NULL != mem_blk))

	{

		if (NULL == *mem_blk)

		{

			if (NULL != adr)

			{

				*mem_blk = adr;

				i_ret = MM_OK;

				MM_DEBUG(printf("MM:mm_insert ok!!!/n"));

			}

		}

		else

		{

			if (NULL != adr)

			{

				tmp = *mem_blk;

				

				if (adr < tmp)

				{

					((MEM_BLK_t*)adr)->next = tmp;

					*mem_blk = adr;

					i_ret = MM_OK;

					MM_DEBUG(printf("MM:mm_insert ok!!!/n"));

				}

				else

				{

					p = tmp;

					tmp = tmp->next;

					while (tmp)

					{

						if (adr < tmp)

						{

							((MEM_BLK_t*)adr)->next = tmp;

							p->next = adr;

							break;

						}

						p = tmp;

						tmp = tmp->next;

					}

					if (NULL == tmp)

					{

						((MEM_BLK_t*)p)->next = adr;

					}

					i_ret = MM_OK;

					MM_DEBUG(printf("MM:mm_insert ok!!!/n"));

				}

			}

		}

	}

	return i_ret;

}



int mm_chk_merge(void)

{

	int i_loop;

	MEM_BLK_t*	mem_blk;

	MEM_BLK_t*	tmp;

	MEM_BLK_t*	tmp1;



	for (i_loop = 0; i_loop < (MM_IDX_NUM -1); i_loop++)

	{

		mem_blk = 	mm_ctrl[i_loop];

lable1:

		if (NULL != mem_blk)

		{

			if (mem_blk->next == ((char*)mem_blk + (MM_UNIT << i_loop)))

			{

				tmp = mem_blk->next;

				if (NULL != tmp)

				{

					tmp = tmp->next;

				}

				mem_blk->next = NULL;

				mm_insert(&mm_ctrl[i_loop + 1], mem_blk);

				mem_blk = tmp;

				mm_ctrl[i_loop] = mem_blk;

				goto lable1;

			}

			else

			{

				tmp1 = mem_blk;

				mem_blk = mem_blk->next;

				while (mem_blk)

				{

					if (mem_blk->next == ((char*)mem_blk + (MM_UNIT << i_loop)))

					{

						tmp = mem_blk->next;

						if (NULL != tmp)

						{

							tmp = tmp->next;

						}

						mem_blk->next = NULL;

						mm_insert(&mm_ctrl[i_loop + 1], mem_blk);

						mem_blk = tmp;

						tmp1->next = mem_blk;

					}

					

					else

					{

						tmp1 = mem_blk;

						mem_blk = mem_blk->next;

					}

				}

			}

		}

	}



	return MM_OK;

}



int main(void)

{

	int i_loop;

	void* a[1500];



	memset(a, 0, sizeof(a));

	mm_init(mm_ctrl);

	

	for (i_loop = 0; i_loop < 1500; i_loop++)

	{

		a[i_loop] = mm_malloc( (rand() % MM_MAX_ONCE_MALLOC));

	}

	for (i_loop = 0; i_loop < 1500; i_loop++)

	{

		mm_free(a[i_loop]);

	}



	for (i_loop = 0; i_loop < 1024; i_loop++)

	{

		a[i_loop] = mm_malloc(MM_MAX_ONCE_MALLOC);

	}

	for (i_loop = 0; i_loop < 1024; i_loop++)

	{

		mm_free(a[i_loop]);

	}



	mm_end(mm_ctrl);

	return 0;

}



int mm_get_unit(unsigned int size)

{

	int i_loop;

	

	for (i_loop = 0; i_loop < MM_IDX_NUM; i_loop++)

	{

		if ((size + sizeof(MEM_BLK_t)) <= (MM_UNIT << i_loop))

		{

			break;

		}

	}

	if ((MM_IDX_NUM) == i_loop)

	{

		i_loop = -1;

		MM_DEBUG(printf("MM:mm_get_unit i_loop %08x!!!/n", i_loop));

	}



	return i_loop;

}



unsigned int mm_get_size(unsigned int size)

{

	int i_loop;

	

	for (i_loop = 0; i_loop < MM_IDX_NUM; i_loop++)

	{

		if ((size + sizeof(MEM_BLK_t)) <= (MM_UNIT  << i_loop))

		{

			break;

		}

	}

	if ((MM_IDX_NUM) == i_loop)

	{

		i_loop = -1;

		MM_DEBUG(printf("MM:mm_get_size i_loop %08x!!!/n", i_loop));

	}



	return (MM_UNIT << i_loop);

}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值