?? memmgr.cpp
字號(hào):
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.
{
{
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;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -