/*
*
* 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))
/* 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_chk_merge(void);
MEM_BLK_t* mm_ctrl[MM_SPLIT_NUM + 1];
int mm_init(MEM_BLK_t** mm_ctrl)
{
int i_ret = MM_NG;
int i_loop;
void* p;
MEM_BLK_t* mem_blk;
if (NULL != mm_ctrl)
{
/* init table */
for (i_loop = 0; i_loop < MM_SPLIT_NUM; i_loop++)
{
mm_ctrl[i_loop] = NULL;
}
/* malloc a chunk */
p = malloc(MM_MALLOC_MEMORY);
if ( NULL != p)
{
mm_ctrl[MM_SPLIT_NUM] = p; /* store the pointer */
mm_ctrl[MM_SPLIT_NUM - 1] = mem_blk = p;
/* split by MM_MAX_UNIT */
while ((char*)mem_blk < ((char*)mm_ctrl[MM_SPLIT_NUM - 1] + 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_SPLIT_NUM])
{
free(mm_ctrl[MM_SPLIT_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_SPLIT_NUM ; i_loop++)
{
if (NULL != mm_ctrl[i_loop])
{
break;
}
}
if (MM_SPLIT_NUM == i_loop)
{
MM_DEBUG(printf("MM:mm_malloc invalid i_loop %08x!!!/n", i_loop));
if (mm_chk_merge())
{
/* to be worked */
}
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
{
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;
}
}
MM_DEBUG(printf("MM:mm_free ok!!!/n"));
}
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]);
}
mm_end(mm_ctrl);
return 0;
}
int mm_get_unit(unsigned int size)
{
int i_loop;
for (i_loop = 0; i_loop < MM_SPLIT_NUM; i_loop++)
{
if ((size + sizeof(MEM_BLK_t)) <= (MM_UNIT << i_loop))
{
break;
}
}
if (MM_SPLIT_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_SPLIT_NUM; i_loop++)
{
if ((size + sizeof(MEM_BLK_t)) <= (MM_UNIT << i_loop))
{
break;
}
}
if (MM_SPLIT_NUM == i_loop)
{
i_loop = -1;
MM_DEBUG(printf("MM:mm_get_size i_loop %08x!!!/n", i_loop));
}
return (MM_UNIT << i_loop);
}
int mm_chk_merge(void)
{
return MM_OK;
}
自己动手写的内存管理程序
最新推荐文章于 2021-05-24 09:20:18 发布