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

来源:互联网 发布:mac彩妆北京专柜 编辑:程序博客网 时间:2024/05/10 03:42
/***menmory management module*chenbdchenbd@gmail.com**/#include <stdio.h>#include <stdlib.h>#include <memory.h>#define MM_OK(0x00)#defineMM_NG(0xff)#define MM_UNIT((unsigned int)4)/*least malloc size*/#define MM_SPLIT_NUM ((unsigned int)10)/*table len*/#defineMM_MAX_ONCE_MALLOC((unsigned int)((MM_UNIT << MM_SPLIT_NUM) - sizeof(MEM_BLK_t)) )/*4K - 4*/#defineMM_MAX_UNIT((unsigned int)(MM_UNIT << MM_SPLIT_NUM) )/*4K*/#defineMM_MAX_MEMORY((unsigned int)(MM_MAX_UNIT << MM_SPLIT_NUM))/*4M*/#define MM_MALLOC_MEMORY((unsigned int)(MM_MAX_MEMORY))#defineMM_IDX_NUM(MM_SPLIT_NUM + 1)/*print on/off macro*/#ifdef _DEBUG#define MM_DEBUG(x)x#else#defineMM_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];intmm_init(MEM_BLK_t** mm_ctrl){int i_ret = MM_NG;int i_loop;void* p;intidx;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;}intmm_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;}#endifreturn 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;}intmm_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.1mm_insert(&mm_ctrl[idx], mem_blk);#elsetmp = 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;}}#endifMM_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);}