⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memory.cpp

📁 一个更为先进的嵌入式操作系统.采用RMS线程调度算法,具有信号量等同步对象.亦包括GUI. 通过该系统您可以极大知道Windows的内部秘密.
💻 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 + -