malloc.c
来自「An complete pmp solution for mattel juic」· C语言 代码 · 共 191 行
C
191 行
#include "malloc.h"
#include "stdint.h"
//User-defined macros
#define chunkSetSize(ptr,size) { \
(*(((u32*) ptr) - 2)) = (u32) size; \
(*(((u32*) ptr) + size)) = (u32) size; \
}
#define chunkSetFreeSize(ptr,size) \
{ \
*(((u32*) ptr) - 2) = ((u32) size )| (u32)0x10000000; \
*(((u32*) ptr) + size) = ((u32) size )| (u32)0x10000000; \
}
#define chunkGetSize(ptr) (*((u32*) ptr - 2) & 0x7FFFFFFF)
#define chunkID(ptr) (*((u32*) ptr - 1))
#define chunkNext(ptr) (ptr + *((u32*) ptr - 2) + 3)
#define chunkPrev(ptr) (ptr - *((u32*) ptr - 3) - 3)
#define chunkFreeNext(ptr) (*((u32*) ptr))
#define chunkFreePrev(ptr) (*((u32*) ptr - 1))
#define chunkFree(ptr) (chunkGetSize(ptr) & 0x80000000)
void wMallocInit()
{
xFreeList = uCRamStart + 2;
u32 size = uCRamSize;
chunkSetFreeSize(xFreeList, size);
chunkFreeNext(xFreeList)=NULL;
chunkFreePrev(xFreeList)=NULL;
}
void *wMalloc (u32 size)
{
size = (size+3)>>2;
xTChunk *xChunk = xFreeList;
xTChunk *xNewChunk;
xTChunk *xNewFreeChunk;
if ( chunkGetSize(xFreeList) > size + 3)
{
xNewChunk = xChunk;
chunkSetSize(xNewChunk, size);
//chunkSetID
//go to the start of the space left
xNewFreeChunk = chunkNext(xNewChunk);
//store the size of left area
chunkSetFreeSize(xNewFreeChunk, chunkGetSize(xFreeList) - size - 3);
//now we only have to correct the links within the freelist
if (xFreeList == xNewChunk)
{
//the case whe we are changing the first item
chunkFreePrev(xNewFreeChunk) = NULL;
chunkFreeNext(xNewFreeChunk) = chunkFreeNext(xNewChunk);
xFreeList = xNewFreeChunk;
return xNewChunk;
}
}
while(chunkFreeNext(xChunk))
{
u32 currSize = chunkGetSize(xChunk);
//if we have a chunk larger than we need
if (currSize > size + 3)
{
xNewChunk = xChunk;
chunkSetSize(xNewChunk, size);
//chunkSetID
//go to the start of the space left
xNewFreeChunk = chunkNext(xNewChunk);
//store the size of left area
chunkSetFreeSize(xNewFreeChunk, currSize - size - 3);
//we have to remove the item from freelist anyway
//because we are probably writing to list end, we must check it
if (chunkFreeNext(xNewChunk))
chunkFreePrev(chunkFreeNext(xNewChunk)) = chunkFreePrev(xNewChunk);
chunkFreeNext(chunkFreePrev(xNewChunk)) = chunkFreeNext(xNewChunk);
//we have removed the item from the list so we now can add it simply
wFree (xNewFreeChunk);
return xNewChunk;
}
if (currSize > size )
{
chunkSetSize (xChunk, currSize);
//we are NOT changing the first item
if (chunkFreeNext(xChunk))
chunkFreePrev(chunkFreeNext(xChunk)) = chunkFreePrev(xChunk);
chunkFreeNext(chunkFreePrev(xChunk)) = chunkFreeNext(xChunk);
return xChunk;
}
xChunk = chunkFreeNext(xChunk);
}
return NULL;
};
//----------------------------------------------------------
void wFree (u32 *mem)
{
return;
if (mem == NULL) return;
xTChunk *xChunk;
u32 size = chunkGetSize(mem);
xChunk = chunkPrev(mem);
//check the block before the freed region
if (chunkFree(xChunk))
{
//remove it from freelist
if (chunkFreeNext(xChunk))
chunkFreePrev(chunkFreeNext(xChunk)) = chunkFreePrev(xChunk);
if (chunkFreePrev(xChunk))
chunkFreeNext(chunkFreePrev(xChunk)) = chunkFreeNext(xChunk);
else
{
if (chunkFreeNext(xChunk))
xFreeList = chunkFreeNext(xChunk);
else
{
size += chunkSize(xChunk) + 3;
chunkSetFreeSize(xChunk, size);
xFreeList = xChunk;
return;
}
}
size += chunkSize(xChunk) + 3;
chunkSetFreeSize(xChunk, size);
mem = xChunk;
}
xChunk = chunkNext(mem);
//check the block next to the freed region
if (chunkFree(xChunk))
{
//remove it from freelist
if (chunkFreeNext(xChunk))
chunkFreePrev(chunkFreeNext(xChunk)) = chunkFreePrev(xChunk);
if (chunkFreePrev(xChunk))
chunkFreeNext(chunkFreePrev(xChunk)) = chunkFreeNext(xChunk);
else
{
if (chunkFreeNext(xChunk))
xFreeList = chunkFreeNext(xChunk);
else
{
size += chunkGetSize(xChunk) + 3;
chunkSetFreeSize(mem, size);
xFreeList = mem;
return;
}
}
size += chunkGetSize(xChunk) + 3;
chunkSetFreeSize(mem, size);
}
if(chunkGetSize(xFreeList)>size)
{
if (chunkFreeNext(xFreeList))
chunkFreePrev(chunkFreeNext(xFreeList)) = mem;
chunkFreePrev(mem) = NULL;
xFreeList = mem;
return;
}
xChunk = xFreeList;
while ((chunkGetSize(xChunk)<size)&&(chunkFreeNext(xChunk)))
{
xChunk = chunkFreeNext(xChunk);
}
if (chunkFreeNext(xFreeList))
{
chunkFreePrev(chunkFreeNext(xFreeList)) = mem;
chunkFreeNext(mem) = chunkFreeNext(xFreeList);
}
chunkFreeNext(chunkFreePrev(xFreeList)) = mem;
chunkFreePrev(mem) = chunkFreePrev(xFreeList);
return;
}
//--------------------------------------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?