📄 memory.cpp
字号:
#include "GOS.h"
#include "Memory.h"
#define TRACE(x)
#define HA_INTSIZE sizeof(DWORD)
#define HA_GROUPLAST 11
#define HA_GROUPFIRST 4
#define HA_BLOCKALIGN(nGroup) (1<<(nGroup))
#define HA_PAGEALIGN(nSize) ((((nSize)+4095)>>12)<<12)
#define HA_PTRADDINT(p,i) PDWORD((DWORD(p)+(i)))
#define HA_PAGECOUNT ((*(m_pHeap-1)+4059)>>12)
#define HA_HEADINTCOUNT ((*(m_pHeap-1)+0x11ffdb)>>17)
#define HA_BLOCKOFFSET(pBlock) (DWORD(pBlock)-DWORD(m_pHeap+HA_HEADINTCOUNT)) //调试用
PVOID operator new(UINT nSize){return malloc(nSize);}
VOID operator delete(PVOID pData){free(pData);}
PVOID operator new[](UINT nSize){return malloc(nSize);}
VOID operator delete[](PVOID pData){free(pData);}
PVOID operator new(UINT nSize,PVOID pObj){return realloc(pObj,nSize);}
VOID operator delete(PVOID pData,PVOID pObj){pData=pObj;}
void CHeap::Create(PVOID pBlock)
{
DEBUG_ONLY(m_nPushCnt=0);
m_pHeap=PDWORD(pBlock);
ZeroMemory(m_pHeap,HA_HEADINTCOUNT*HA_INTSIZE);
}
PVOID CHeap::Delete()
{
ASSERT(!m_nPushCnt);
return m_pHeap;
}
BOOL CHeap::IncludePtr(PCVOID pBlock)
{
return DWORD(pBlock) > DWORD(m_pHeap)
&& DWORD(pBlock) < DWORD(m_pHeap) + *(PDWORD(m_pHeap)-1);
}
PVOID CHeap::Alloc(DWORD nSize)
{
PDWORD pBlock;
DWORD i,nGroup=i=Group(nSize+HA_INTSIZE);
TRACE("\r\n",nSize);
while(i<=HA_GROUPLAST && !m_pHeap[i-HA_GROUPFIRST])
i++;
if(i<=HA_GROUPLAST)
pBlock=ChainPop(i);
else
pBlock=(PDWORD)PageAlloc(NULL,HA_PAGEALIGN(nSize+HA_INTSIZE));
if(pBlock)
{
SplitBlock(pBlock,i,nGroup);
pBlock[0]=nSize;
TRACE("HeapAlloc(%d),Addr=%d\r\n",nSize,HA_BLOCKOFFSET(pBlock));
pBlock++;
}
else
{
TRACE("HeapAlloc(%d),Addr=-1\r\n",nSize);
}
return pBlock;
}
PVOID CHeap::ReAlloc(PVOID pBlock,DWORD nSize)
{
if(!pBlock)
return Alloc(nSize);
if(!nSize)
{
Free(pBlock);
return NULL;
}
PDWORD pData=(PDWORD)pBlock-1;
DWORD i=Group(*pData+HA_INTSIZE);
DWORD nToGroup,j=nToGroup=Group(nSize+HA_INTSIZE);
TRACE("\r\n",nSize);
if(j>i)
{
pBlock=MergeBlock(pData,i,&nToGroup);
if(nToGroup<j)
pBlock=NULL;
}
else if(j<i)
SplitBlock(pData,i,j);
//页分配
i=HA_PAGEALIGN(*pData+HA_INTSIZE);
j=HA_PAGEALIGN(nSize+HA_INTSIZE);
if(pBlock)
{
if(j>i)
pBlock=PageAlloc(HA_PTRADDINT(pData,i),j-i);
else if(j<i)
PageFree(HA_PTRADDINT(pData,j),i-j);
}
//数据复制
if(pBlock)
{
if(pBlock<pData)
{
CopyMemory(HA_PTRADDINT(pBlock,1),pData+1,*pData);
pData=PDWORD(pBlock);
}
pData[0]=nSize;
pBlock=pData+1;
}
else
{
if(nToGroup>HA_GROUPLAST)
PageFree(pData,i);
pBlock=Alloc(nSize);
if(pBlock)
CopyMemory(pBlock,pData+1,*pData);
if(nToGroup<=HA_GROUPLAST)
ChainPush(pData,nToGroup);
}
TRACE("HeapReAlloc(%d),Addr=%d\r\n",nSize,HA_BLOCKOFFSET(pBlock)-4);
return pBlock;
}
void CHeap::Free(PVOID pBlock)
{
if(!pBlock)
return;
PDWORD pData=PDWORD(pBlock)-1;
DWORD nSize=*pData;
DWORD nGroup=Group(nSize+HA_INTSIZE);
DWORD nToGroup=HA_GROUPLAST+1;
TRACE("\r\n",nSize);
if(nGroup<=HA_GROUPLAST)
{
pData=MergeBlock(pData,nGroup,&nToGroup);
}
if(nToGroup>HA_GROUPLAST)
PageFree(pData,HA_PAGEALIGN(nSize+HA_INTSIZE));
else
ChainPush(pData,nToGroup);
TRACE("HeapFree(%d),Size=%d\r\n",HA_BLOCKOFFSET(pData),nSize);
}
//决定组大小,HeapAlloc的Size需要上HA_INTSIZE;
//返回为HA_GROUPLAST+1时是位图
DWORD CHeap::Group(DWORD nSize)
{
DWORD i=HA_GROUPFIRST;
while((1UL<<i)<nSize)
i++;
return i>HA_GROUPLAST?HA_GROUPLAST+1:i;
}
//合并组,如果可以合并就把伙伴块从空闲链移除,组增大
//返回时Group可达B12
PDWORD CHeap::MergeBlock(PVOID pBlock,DWORD nGroup,PDWORD pToGroup)
{
PDWORD pBuffer=m_pHeap+HA_HEADINTCOUNT;
PDWORD pData,pData2;
DWORD nPartner,nBlockSize;
DWORD nPos=DWORD(pBlock)-DWORD(pBuffer);
while(nGroup<*pToGroup)
{
nBlockSize=HA_BLOCKALIGN(nGroup);
if((nPos>>nGroup)&1)
nPartner=nPos-nBlockSize;
else
nPartner=nPos+nBlockSize;
pData=HA_PTRADDINT(pBuffer,nPartner);
if(*pData!=~nGroup)
break;
if(pData[1])
{
DEBUG_ONLY(m_nPushCnt--);
TRACE("MergeRemove(%d),Group=%d(PushCnt=%d)\r\n",HA_BLOCKOFFSET(pData),nGroup,m_nPushCnt);
pData2=PDWORD(pData[2]);
pData=PDWORD(pData[1]);
pData[2]=DWORD(pData2);
if(pData2)
pData2[1]=DWORD(pData);
}
else
pData=ChainPop(nGroup);
if(nPartner<nPos)
nPos=nPartner;
nGroup++;
}
*pToGroup=nGroup;
pData=HA_PTRADDINT(pBuffer,nPos);
return pData;
}
//把多余的块放入空闲链表
//nGroup最大值可是B12
void CHeap::SplitBlock(PVOID pBlock,DWORD nGroup,DWORD nToGroup)
{
PDWORD pFree;
DWORD nBlockSize;
while(nGroup>nToGroup)
{
nGroup--;
nBlockSize=HA_BLOCKALIGN(nGroup);
pFree=HA_PTRADDINT(pBlock,nBlockSize);
ChainPush(pFree,nGroup);
}
}
void CHeap::ChainPush(PDWORD pBlock,DWORD nGroup)
{
DEBUG_ONLY(m_nPushCnt++);
TRACE("ChainPush(%d),Group=%d(PushCnt=%d)\r\n",HA_BLOCKOFFSET(pBlock),nGroup,m_nPushCnt);
PDWORD pChain=&m_pHeap[nGroup-HA_GROUPFIRST];
pBlock[0]=~nGroup;
pBlock[1]=NULL;
pBlock[2]=DWORD(*pChain);
if(pBlock[2])
*(PDWORD(pBlock[2])+1)=DWORD(pBlock);
*pChain=DWORD(pBlock);
}
PDWORD CHeap::ChainPop(DWORD nGroup)
{
PDWORD pChain=&m_pHeap[nGroup-HA_GROUPFIRST];
PDWORD pBlock=PDWORD(*pChain);
DEBUG_ONLY(m_nPushCnt--);
TRACE("ChainPop(%d),Group=%d(PushCnt=%d)\r\n",HA_BLOCKOFFSET(pBlock),nGroup,m_nPushCnt);
*pChain=pBlock[2];
if(*pChain)
*(PDWORD(*pChain)+1)=NULL;
return pBlock;
}
//如果pBlock为空,自动分配
//否则如果pBlock对应处有nSize空页,返回pBlock;
//否则返回Null;
PVOID CHeap::PageAlloc(PVOID pBlock,DWORD nSize)
{
DWORD i=pBlock?(DWORD(pBlock)-DWORD(m_pHeap+HA_HEADINTCOUNT))>>12:0;
DWORD nPage=-1,nPages=HA_PAGECOUNT;
PDWORD pBitmap=m_pHeap+8;
for(nSize>>=12;i<nPages;i++)
{
if(pBitmap[i>>5] & (1<<(i&31)))
{
if(pBlock)
{
i=nPages;
break;
}
nPage=-1;
}
else
{
if(nPage==-1)
nPage=i;
if(i-nPage+1==nSize)
break;
}
}
if(i<nPages)
{
nSize+=nPage;
for(i=nPage;i<nSize;i++)
{
pBitmap[i>>5] |=1<<(i & 31);
}
DEBUG_ONLY(m_nPushCnt+=nSize-nPage);
TRACE("PageAlloc(HA_PAGECOUNT=%d,PageStart=%d,PushCnt=%d)\r\n",nSize-nPage,nPage,m_nPushCnt);
pBlock=HA_PTRADDINT(m_pHeap+HA_HEADINTCOUNT,nPage<<12);
}
else
pBlock=NULL;
return pBlock;
}
//从位图中将对应的位标记为空闲
void CHeap::PageFree(PVOID pBlock,DWORD nSize)
{
DWORD i=(DWORD(pBlock)-DWORD(m_pHeap+HA_HEADINTCOUNT))>>12;
PDWORD pBitmap=m_pHeap+8;
DEBUG_ONLY(m_nPushCnt-=nSize>>12);
TRACE("PageFree(HA_PAGECOUNT=%d,PageStart=%d,PushCnt=%d)\r\n",nSize>>12,i,m_nPushCnt);
nSize=i+(nSize>>12);
for(;i<nSize;i++)
{
pBitmap[i>>5] &=~(1<<(i & 31));
}
}
int CHeap::ElementCount(int nElementBytes,int nCount,int nReservedBytes)
{
int nBytes=HA_INTSIZE+nReservedBytes;
if(nCount>0)
nBytes+=nCount*nElementBytes;
else
nBytes-=nCount?nCount:-128;
nCount=16;
while(nCount<nBytes)
nCount<<=1;
nCount-=HA_INTSIZE+nReservedBytes;
nCount/=nElementBytes;
ASSERT(nCount>0);
return nCount;
}
void FillMemory(PVOID pDest,DWORD nLength,BYTE nFill)
{
DWORD p=DWORD(pDest);
DWORD i,nData=nFill;
nData=nFill;
nData=(nData<<8)|nData;
nData=(nData<<16)|nData;
nLength=DWORD(pDest)+nLength;
if((DWORD(pDest) & ~0x03) == (nLength & ~0x03))
{
i=DWORD(pDest) & 0x03;
if(i)
{
p-=i;
i=(1<<(i<<3))-1;
}
nLength &= 0x03;
nLength=(1<<(nLength<<3))-1;
i |= ~nLength;
*(PDWORD)p &= i;
*(PDWORD)p |= ~i & nData ;
}
else
{
i=DWORD(pDest) & 0x03;
if(i)
{
p-=i;
i=(1<<(i<<3))-1;
*(PDWORD)p &= i;
*(PDWORD)p |= ~i & nData ;
p+=4;
}
i=nLength & ~0x03;
while(p<i)
{
*PDWORD(p)=nData;
p+=4;
}
i=nLength & 0x03;
if(i)
{
i=(1<<(i<<3))-1;
*PDWORD(p) &= ~i;
*PDWORD(p) |= i & nData ;
}
}
}
void CopyMemory(PVOID pDest,PCVOID pSrc,DWORD nLength)
{
DWORD i,p,s;
if(nLength<4 || (DWORD(pDest) & 0x03)!=(DWORD(pSrc) & 0x03))
{
nLength=DWORD(pDest)+nLength;
if(pDest<pSrc)
{
p=DWORD(pDest);
s=DWORD(pSrc);
while(p<nLength)
{
*PBYTE(p)=*PBYTE(s);
p++;
s++;
}
}
else if(pDest>pSrc)
{
p=DWORD(pDest);
s=DWORD(pSrc)+nLength-p;
while(nLength>p)
{
nLength--;
s--;
*PBYTE(nLength)=*PBYTE(s);
}
}
}
else if(pDest<pSrc)
{
nLength=DWORD(pDest)+nLength;
p=DWORD(pDest);
s=DWORD(pSrc);
i=p & 0x03;
if(i)
{
p-=i;
s-=i;
i=(1<<(i<<3))-1;
*(PDWORD)p &= i;
*(PDWORD)p |= ~i & *PDWORD(s);
p+=4;
s+=4;
}
i=nLength & ~0x03;
while(p<i)
{
*PDWORD(p)=*PDWORD(s);
p+=4;
s+=4;
}
i=nLength & 0x03;
if(i)
{
i=(1<<(i<<3))-1;
*PDWORD(p) &= ~i;
*PDWORD(p) |= i & *PDWORD(s);
}
}
else if(pDest>pSrc)
{
nLength=DWORD(pDest)+nLength;
p=nLength & ~0x03;
s=DWORD(pSrc)+p-DWORD(pDest);
i=nLength & 0x03;
if(i)
{
i=(1<<(i<<3))-1;
*PDWORD(p) &= ~i;
*PDWORD(p) |= i & *PDWORD(s);
}
i=(DWORD(pDest) & ~0x03)+4;
while(p>i)
{
p-=4;
s-=4;
*PDWORD(p)=*PDWORD(s);
}
p-=4;s-=4;
i=DWORD(pDest) & 0x03;
if(i)
{
i=(1<<(i<<3))-1;
*(PDWORD)p &= i;
*(PDWORD)p |= ~i & *PDWORD(s);
}
else
{
*PDWORD(p)=*PDWORD(s);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -