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

📄 memmgr.cpp

📁 小型的操作系统开发的原代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	j = i;
	while(j < PAGE_FRAME_BLOCK_NUM)
	{
		if(NULL == lpFrameManager->FrameBlockArray[j].lpNextBlock)
		{
			j ++;
			continue;
		}
		else
			break;    //Find the fitable block list to allocate from.
	}

	if(PAGE_FRAME_BLOCK_NUM == j)  //There is not page frame block to fit the request.
	{
		//LEAVE_CRITICAL_SECTION();
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		goto __TERMINAL;
	}

	//
	//Now,we have found the block list countains the correct block,the block can fit the
	//request,so we delete the first block from the block list,spit it into more small
	//blocks,insert the less block into appropriate block list,and return one correct to
	//the caller.
	//
	lpPageFrame = lpFrameManager->FrameBlockArray[j].lpNextBlock;
	if(NULL != lpPageFrame->lpNextFrame)
		lpPageFrame->lpPrevFrame = NULL;
	lpFrameManager->FrameBlockArray[j].lpNextBlock = lpPageFrame->lpNextFrame; //Delete the block.

	dwOffset = (DWORD)lpPageFrame - (DWORD)lpFrameManager->lpPageFrameArray;
	k        = dwOffset / sizeof(__PAGE_FRAME);

	//
	//The return value can be calculated as following:
	//

	lpResult = (LPVOID)((DWORD)lpFrameManager->lpStartAddress + k * PAGE_FRAME_SIZE);
	k       /= (FrameBlockSize[j] / PAGE_FRAME_SIZE);
	ClearBitmapBit(lpFrameManager->FrameBlockArray[j].lpdwBitmap,k);  //Clear the bit.

	while(j > i)    //Split the block into more small block,and insert into block list.
	{
		k  = FrameBlockSize[j - 1] / PAGE_FRAME_SIZE;
		k *= sizeof(__PAGE_FRAME);
		lpTempFrame = (__PAGE_FRAME*)((DWORD)lpPageFrame + k);
		if(NULL != lpFrameManager->FrameBlockArray[j - 1].lpNextBlock)
		{
			lpFrameManager->FrameBlockArray[j - 1].lpNextBlock->lpPrevFrame = 
				lpTempFrame;
		}
		lpTempFrame->lpNextFrame = lpFrameManager->FrameBlockArray[j - 1].lpNextBlock;
		lpTempFrame->lpPrevFrame = NULL;
		lpFrameManager->FrameBlockArray[j - 1].lpNextBlock = lpTempFrame;
		dwOffset = (DWORD)lpTempFrame - (DWORD)lpFrameManager->lpPageFrameArray;
		k        = dwOffset / sizeof(__PAGE_FRAME);
		k       /= FrameBlockSize[j - 1] / PAGE_FRAME_SIZE;
		SetBitmapBit(lpFrameManager->FrameBlockArray[j - 1].lpdwBitmap,k);  //Set bit.
		j --;
	}

	//LEAVE_CRITICAL_SECTION();
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);

__TERMINAL:
	return lpResult;
}

//
//FrameFree routine of PageFrameManager.
//The routine does the following:
// 1. Check the buddy block's status of the block which will be freed;
// 2. If the status of buddy block is free,then combine the two blocks,and 
//    insert the combined block into up level block list;
// 3. Check the up level block list,this is a recursive process.
//
//CAUTION: The dwSize parameter of this routine,must equal to the dwSize
//parameter of FrameAlloc routine of Page Frame Manager.
//

static VOID FrameFree(__COMMON_OBJECT*  lpThis,
					  LPVOID            lpStartAddr,
					  DWORD             dwSize)
{
	__PAGE_FRAME_MANAGER*               lpFrameManager  = NULL;
	__PAGE_FRAME*                       lpPageFrame     = NULL;
	__PAGE_FRAME*                       lpTempFrame     = NULL;
	DWORD                               i               = 0L;
	DWORD                               j               = 0L;
	DWORD                               k               = 0L;
	DWORD                               dwOffset        = 0L;
	DWORD                               dwFlags         = 0L;

	if((NULL == lpThis) || (NULL == lpStartAddr) ||
	   (0 == dwSize))   //Parameter check.
		goto __TERMINAL;

	if((DWORD)lpStartAddr % PAGE_FRAME_SIZE)   //The address is not page frame alignable.
		goto __TERMINAL;

	for(i = 0;i < PAGE_FRAME_BLOCK_NUM;i ++)
	{
		if(dwSize <= FrameBlockSize[i])
			break;
	}

	if(PAGE_FRAME_BLOCK_NUM == i)    //The dwSize is too large,invalid parameter.
		goto __TERMINAL;

	lpFrameManager = (__PAGE_FRAME_MANAGER*)lpThis;
	dwOffset       = (DWORD)lpStartAddr - (DWORD)lpFrameManager->lpStartAddress;
	k              = dwOffset / FrameBlockSize[i];  //The k-th block.

	lpPageFrame    = (__PAGE_FRAME*)((DWORD)lpFrameManager->lpPageFrameArray + 
		(dwOffset / PAGE_FRAME_SIZE) * sizeof(__PAGE_FRAME));    
	//Now,lpPageFrame pointes the page frame control block.

	if(k % 2)    //Get this block's buddy block index.
	{
		k -= 1;
	}
	else
	{
		k += 1;
	}

	//ENTER_CRITICAL_SECTION();
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);

	if(TestBit(lpFrameManager->FrameBlockArray[i].lpdwBitmap,k))  //If the current block's
		                                                          //buddy block also free,
																  //then combine the two blocks,
																  //and insert into up level
																  //block list.
	{
		while(i < PAGE_FRAME_BLOCK_NUM - 1)
		{
			if(k % 2)    //The behind block of lpPageFrame is it's buddy block.
			{
				lpTempFrame = (__PAGE_FRAME*)((DWORD)lpPageFrame + (FrameBlockSize[i] / 
					PAGE_FRAME_SIZE) * sizeof(__PAGE_FRAME));
				//lpLargeFrame = lpPageFrame;
			}
			else         //The previous block of lpPageFrame is it's buddy block.
			{
				lpTempFrame = (__PAGE_FRAME*)((DWORD)lpPageFrame - (FrameBlockSize[i] /
					PAGE_FRAME_SIZE) * sizeof(__PAGE_FRAME));
				//lpLargeFrame = lpTempFrame;
				lpPageFrame = lpTempFrame;
			}

			//The following code delete the buddy block from the current list,and insert
			//the combined block into up level block list.
			if(NULL == lpTempFrame->lpPrevFrame)    //This is the first block.
			{
				if(NULL == lpTempFrame->lpNextFrame)  //This is the last block.
				{
					//lpTempFrame->lpNextFrame->lpPrevFrame = NULL;
					lpFrameManager->FrameBlockArray[i].lpNextBlock = lpTempFrame->lpNextFrame;
				}
				else
				{
					lpTempFrame->lpNextFrame->lpPrevFrame = NULL;
					lpFrameManager->FrameBlockArray[i].lpNextBlock = lpTempFrame->lpNextFrame;
				}
			}
			else  //This is not the first block.
			{
				if(NULL == lpTempFrame->lpNextFrame) //This is the last block.
				{
					lpTempFrame->lpPrevFrame->lpNextFrame = NULL;
				}
				else  //This is not the last block.
				{
					lpTempFrame->lpPrevFrame->lpNextFrame = lpTempFrame->lpNextFrame;
					lpTempFrame->lpNextFrame->lpPrevFrame = lpTempFrame->lpPrevFrame;
				}
			}

			ClearBitmapBit(lpFrameManager->FrameBlockArray[i].lpdwBitmap,k);  //Clear bit.

			i ++;  //To check up level block link.

			k  = (DWORD)lpPageFrame - (DWORD)lpFrameManager->lpPageFrameArray;
			k /= sizeof(__PAGE_FRAME);
			k /= (FrameBlockSize[i] / PAGE_FRAME_SIZE);

			if(k % 2)
				k -= 1;
			else
				k += 1;

			if(!TestBit(lpFrameManager->FrameBlockArray[i].lpdwBitmap,k))
				break;
		}

		//
		//The following code inserts the combined block into up level block list.
		//

		if(NULL != lpFrameManager->FrameBlockArray[i].lpNextBlock)
		{
			lpFrameManager->FrameBlockArray[i].lpNextBlock->lpPrevFrame = 
				lpPageFrame;
		}
		lpPageFrame->lpNextFrame = lpFrameManager->FrameBlockArray[i].lpNextBlock;
		lpPageFrame->lpPrevFrame = NULL;

		lpFrameManager->FrameBlockArray[i].lpNextBlock = lpPageFrame;

		if(k % 2)    //Adjust k.
			k -= 1;
		else
			k += 1;

		SetBitmapBit(lpFrameManager->FrameBlockArray[i].lpdwBitmap,k); //Set bit.
	}
	else      //The buddy of the current block is occupied.
		      //So,only insert the current block into the block
			  //list.
	{
		if(NULL != lpFrameManager->FrameBlockArray[i].lpNextBlock)
		{
			lpFrameManager->FrameBlockArray[i].lpNextBlock->lpPrevFrame = 
				lpPageFrame;
		}
		lpPageFrame->lpNextFrame = lpFrameManager->FrameBlockArray[i].lpNextBlock;
		lpPageFrame->lpPrevFrame = NULL;

		lpFrameManager->FrameBlockArray[i].lpNextBlock = lpPageFrame;

		if(k % 2)    //Adjust k.
			k -= 1;
		else
			k += 1;

		SetBitmapBit(lpFrameManager->FrameBlockArray[i].lpdwBitmap,k);  //Set bit.
	}

	//LEAVE_CRITICAL_SECTION();
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);

__TERMINAL:
	return;
}

/*************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
*************************************************************************/

//
//The definition of object PageFrameManager.
//

__PAGE_FRAME_MANAGER PageFrameManager = {
	NULL,                                  //lpPageFrameArray.
	{0},                                   //FrameBlockArray.
	0L,                                    //dwTotalFrameNum.
	0L,                                    //dwFreeFrameNum.
	NULL,                                  //lpStartAddress.
	PageFrameMgrInit,                      //Initialize routine.
	FrameAlloc,                            //FrameAlloc routine.
	FrameFree                              //FrameFree routine.
};

//------------------------------------------------------------------------
//
//    The implementation code of Memory Manager.
//
//------------------------------------------------------------------------

//
//The implementation of Initialize routine of Memory Manager.
//The routine does the following:
// 1. Set all Memory Descriptor Entry's status to FREE (VM_DESCRIPTOR_FLAG_FREE);
//
//Then return.
//

static BOOL MemMgrInitialize(__COMMON_OBJECT*    lpThis)
{
	BOOL                             bResult     = FALSE;
	__MEMORY_MANAGER*                lpMemoryMgr = NULL;
	DWORD                            i           = 0L;

	if(NULL == lpThis)
		return bResult;

	lpMemoryMgr = (__MEMORY_MANAGER*)lpThis;

	for(i = 0;i < MAX_KERNEL_THREAD_NUM;i ++)
	{
		lpMemoryMgr->MemDescArray[i].dwDescriptorFlag |= VM_DESCRIPTOR_FLAG_FREE;
	}

	bResult = TRUE;

	return bResult;
}

//
//The implementation of ReserveDescIndex routine.
//The routine does the following:
// 1. Check all memory descriptor,to find a free one;
// 2. If can not find a free descriptor,then return INVALID_DESC_INDEX;
// 3. If find a free descriptor,then set the descriptor's status to OCCUPIED,
//    and return the index to caller.
//

static DWORD ReserveDescIndex(__COMMON_OBJECT*    lpThis)
{
	DWORD                     dwDescIndex         = INVALID_DESC_INDEX;
	__MEMORY_MANAGER*         lpMemManager        = NULL;
	DWORD                     i                   = 0L;
	DWORD                     dwFlags             = 0L;

	if(NULL == lpThis)
		return dwDescIndex;

	lpMemManager = (__MEMORY_MANAGER*)lpThis;

	//ENTER_CRITICAL_SECTION();    //The following must not be interrupted.
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);

	for(i = 0;i < MAX_KERNEL_THREAD_NUM;i ++)
	{
		if(lpMemManager->MemDescArray[i].dwDescriptorFlag & VM_DESCRIPTOR_FLAG_FREE)
			//Find a descriptor whose status is FREE.
		{
			dwDescIndex = i;
			//
			//Clear the free bit of this descriptor.
			//
			lpMemManager->MemDescArray[i].dwDescriptorFlag &= ~VM_DESCRIPTOR_FLAG_FREE;

			lpMemManager->MemDescArray[i].lpChunkListRoot  = NULL;
			lpMemManager->MemDescArray[i].lpChunkTreeRoot  = NULL;
			lpMemManager->MemDescArray[i].wChunkNum        = 0;
			lpMemManager->MemDescArray[i].wHeapNum         = 0;
			break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -