实现的原理是将内存分成小的片段进行管理,代码如下:
- #define MEM_BLOCK_SIZE 4096
- #define MEM_LARGE_BLOCK_THRESHOLD 40960 //>MEM_LARGE_BLOCK_THRESHOLD :requested size is large block
- #define MEM_BASE_ADDRESS (0x90000000)
- #define MEM_ALLOC_TABLE_FIRST_ENTRY 0
- #define MAX_MEM_SIZE 7*1024*1024
- #define MEM_ALLOC_TABLE_SIZE (MAX_MEM_SIZE/MEM_BLOCK_SIZE)
- static INT16 memory_map[MEM_ALLOC_TABLE_SIZE];
- static char isMemoryManagementReady=0;
- void *memset(void *s, int c, size_t count)
- {
- char *xs = s;
- while (count--)
- *xs++ = c;
- return s;
- }
- INT32 ssd_mem_init(void)
- {
- memset(memory_map, 0, sizeof(memory_map));
- isMemoryManagementReady=1;
- }
- INT16 ssd_mem_percentage_used()
- {
- int used=0;
- int i;
- for(i=0;i<MEM_ALLOC_TABLE_SIZE;i++)
- {
- if(memory_map[i])
- {
- used++;
- }
- }
- return used*100/MEM_ALLOC_TABLE_SIZE;
- }
- //return -1:FAIL
- //>=0: return allocated address offset
- INT32 ssd_mem_malloc(UINT32 size)
- {
- int offset=0;
- int startEntry=MEM_ALLOC_TABLE_FIRST_ENTRY;
- int nmemb;
- int i;
- if(!isMemoryManagementReady)
- {
- ssd_mem_init();
- }
- if(size==0)
- {
- return -1;
- }
- nmemb=size/MEM_BLOCK_SIZE;
- if(size%MEM_BLOCK_SIZE)
- {
- nmemb++;
- }
- if(size > MEM_LARGE_BLOCK_THRESHOLD)
- {
- for(offset=startEntry;offset<MEM_ALLOC_TABLE_SIZE-nmemb;offset++)
- {
- if(!memory_map[offset])
- {
- int vacantSize=0;
- for(vacantSize=0;vacantSize<nmemb && !memory_map[offset+vacantSize];vacantSize++);
- if(vacantSize==nmemb)
- {
- for(i=0;i<nmemb;i++)
- {
- memory_map[offset+i]=nmemb;
- }
- return (offset*MEM_BLOCK_SIZE);
- }
- }
- }
- }
- else
- {
- for(offset=MEM_ALLOC_TABLE_SIZE-1;offset>=0;offset--)
- {
- if(!memory_map[offset] && ((offset+nmemb)<=MEM_ALLOC_TABLE_SIZE))//search start of vacant block
- {
- int vacantSize=0;
- for(vacantSize=0;vacantSize<nmemb && !memory_map[offset+vacantSize];vacantSize++);
- if(vacantSize==nmemb)
- {
- for(i=0;i<nmemb;i++)
- {
- memory_map[offset+i]=nmemb;
- }
- return (offset*MEM_BLOCK_SIZE);
- }
- }
- }
- }
- puts("malloc size erorr=");
- putInt32(size);
- return -1;
- }
- //return 0:OK
- //return 1:Out of bound
- INT32 ssd_mem_free(INT32 offset)
- {
- int i;
- if(!isMemoryManagementReady)
- {
- ssd_mem_init();
- return 1;
- }
- if(offset<MAX_MEM_SIZE)
- {
- int index=offset/MEM_BLOCK_SIZE;
- int nmemb=memory_map[index];
- for(i=0;i<nmemb;i++)
- {
- memory_map[index+i]=0;
- }
- return 0;
- }
- else
- {
- return 1;//out of bound
- }
- }
- void free(void *ptr)
- {
- if(ptr==NULL)
- return;
- INT32 offset;
- offset=ptr-MEM_BASE_ADDRESS;
- ssd_mem_free(offset);
- }
- void * malloc(UINT32 size)
- {
- INT32 offset;
- offset=ssd_mem_malloc(size);
- if(offset==-1)
- {
- return NULL;
- }
- else
- return MEM_BASE_ADDRESS+offset;
- }
- void *realloc(void *ptr,UINT32 size)
- {
- INT32 offset;
- offset=ssd_mem_malloc(size);
- if(offset==-1)
- {
- puts("realloc error/n");
- return NULL;
- }
- else
- {
- memcpy((void*)(MEM_BASE_ADDRESS+offset),ptr,size);
- free(ptr);
- return MEM_BASE_ADDRESS+offset;
- }
- }