?? memmgr.cpp
字號:
}
}
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return dwDescIndex;
}
//
//The implementation of ReserveChunk.
//
static LPVOID ReserveChunk(__COMMON_OBJECT* lpThis,
DWORD dwIndex,
DWORD dwChunkType,
DWORD dwChunkSize)
{
LPVOID lpRetVal = NULL;
__MEMORY_MANAGER* lpMemManager = NULL;
__CHUNK_CONTROL_BLOCK* lpChunk = NULL;
DWORD dwSize = 0L;
__VIRTUAL_MEMORY_DESCRIPTOR* lpDesc = NULL;
if((NULL == lpThis) || (dwIndex >= INVALID_DESC_INDEX))
goto __TERMINAL; //Parameter check failed.
lpMemManager = (__MEMORY_MANAGER*)lpThis;
if(lpMemManager->MemDescArray[dwIndex].dwDescriptorFlag & VM_DESCRIPTOR_FLAG_FREE)
//The Descriptor indicated by dwIndex is free.
goto __TERMINAL;
lpDesc = &lpMemManager->MemDescArray[dwIndex];
if(dwChunkSize > MAX_CHUNK_SIZE) //Exceed the maximal chunk size.
goto __TERMINAL;
if(dwChunkType == CHUNK_FLAG_HEAP) //If reserve a heap.
{
if(lpDesc->wHeapNum >= MAX_HEAP_CHUNK_NUM)
goto __TERMINAL;
}
dwSize = (dwChunkSize % PAGE_FRAME_SIZE) ? (dwChunkSize +
(PAGE_FRAME_SIZE - (dwChunkSize % PAGE_FRAME_SIZE))) : dwChunkSize; //Align to
//Page Frame.
//
//Now,we create a chunk control block,to countain the chunk will be created.
//
lpChunk = (__CHUNK_CONTROL_BLOCK*)KMemAlloc(sizeof(__CHUNK_CONTROL_BLOCK),
KMEM_SIZE_TYPE_ANY);
if(NULL == lpChunk) //Failed to create chunk control block.
goto __TERMINAL;
//
//Now,create a block of frame.
//
lpRetVal = PageFrameManager.FrameAlloc((__COMMON_OBJECT*)&PageFrameManager,
dwSize,
0L);
if(NULL == lpRetVal) //Failed to allocate frame.
goto __TERMINAL;
//
//Initialize the chunk control block.
//
lpChunk->dwChunkFlag = dwChunkType;
lpChunk->lpAvlLeft = NULL;
lpChunk->lpAvlRight = NULL;
lpChunk->wAvlHeight = 0;
lpChunk->wReserved = 0;
lpChunk->lpStartAddr = lpRetVal;
lpChunk->lpEndAddr = (LPVOID)((DWORD)lpRetVal + dwSize - 1);
if(CHUNK_FLAG_HEAP == dwChunkType) //If this is a heap.
{
lpDesc->HeapChunkArray[lpDesc->wHeapNum] = lpChunk;
lpChunk->lpNextChunk = NULL;
lpChunk->lpPrevChunk = NULL;
lpDesc->wHeapNum ++;
lpDesc->wChunkNum ++;
goto __TERMINAL;
}
//
//Now,insert the control block into the current kernel thread's memory descriptor.
//
if(lpDesc->wChunkNum > AVL_SWITCH_CHUNK_NUM) //Insert into AVL tree.
{
}
else //Insert into bidirect link list.
{
lpDesc->wChunkNum ++;
if(NULL != lpDesc->lpChunkListRoot)
{
lpDesc->lpChunkListRoot->lpPrevChunk = lpChunk;
}
lpChunk->lpNextChunk = lpDesc->lpChunkListRoot;
lpChunk->lpPrevChunk = NULL;
lpDesc->lpChunkListRoot = lpChunk;
}
__TERMINAL:
if(NULL == lpRetVal) //Failed.
{
if(NULL != lpChunk) //Free the chunk.
KMemFree((LPVOID)lpChunk,KMEM_SIZE_TYPE_ANY,0L);
}
return lpRetVal;
}
//
//The implementation of ReleaseChunk.
//
static VOID ReleaseChunk(__COMMON_OBJECT* lpThis,
DWORD dwIndex,
LPVOID lpStartAddr)
{
__MEMORY_MANAGER* lpMemManager = NULL;
__VIRTUAL_MEMORY_DESCRIPTOR* lpDesc = NULL;
__CHUNK_CONTROL_BLOCK* lpChunk = NULL;
WORD i = 0;
WORD j = 0;
DWORD dwChunkSize = 0L;
if((NULL == lpThis) || (dwIndex >= INVALID_DESC_INDEX) ||
(NULL == lpStartAddr)) //Parameters check.
return;
lpMemManager = (__MEMORY_MANAGER*)lpThis;
lpDesc = &lpMemManager->MemDescArray[dwIndex];
if(lpDesc->dwDescriptorFlag & VM_DESCRIPTOR_FLAG_FREE) //The descriptor is free.
return;
//
//Now,we must find the chunk control block of the chunk will be released.
//
for(i = 0;i < lpDesc->wHeapNum;i ++) //First,search the heap array.
{
if(lpStartAddr == lpDesc->HeapChunkArray[i]->lpStartAddr) //Found,delete it.
{
lpChunk = lpDesc->HeapChunkArray[i];
for(j = i;j < lpDesc->wHeapNum - 1;j ++)
{
lpDesc->HeapChunkArray[j] = lpDesc->HeapChunkArray[j + 1];
}
lpDesc->wHeapNum --;
lpDesc->wChunkNum --;
dwChunkSize = (DWORD)lpChunk->lpEndAddr - (DWORD)lpChunk->lpStartAddr + 1;
PageFrameManager.FrameFree((__COMMON_OBJECT*)&PageFrameManager,
lpChunk->lpStartAddr,
dwChunkSize); //Delete the page frame this chunk occupies.
KMemFree((LPVOID)lpChunk,KMEM_SIZE_TYPE_ANY,0L);
return;
}
}
//
//If can not find the chunk in heap array,then search the chunk list.
//
lpChunk = lpDesc->lpChunkListRoot;
while(lpChunk)
{
if(lpStartAddr == lpChunk->lpStartAddr) //Found.
break;
lpChunk = lpChunk->lpNextChunk;
}
if(NULL == lpChunk) //Can not find the chunk to be released.
return;
if(NULL == lpChunk->lpPrevChunk) //This is the first chunk in the list.
{
if(NULL == lpChunk->lpNextChunk) //This is the last chunk in the list.
{
lpDesc->lpChunkListRoot = NULL; //Only delete the chunk.
}
else //This is not the last chunk.
{
lpChunk->lpNextChunk->lpPrevChunk = NULL;
lpDesc->lpChunkListRoot = lpChunk->lpNextChunk;
}
}
else //This is not the first chunk in the list.
{
if(NULL == lpChunk->lpNextChunk) //This is the last chunk.
{
lpChunk->lpPrevChunk->lpNextChunk = NULL; //Delete the chunk.
}
else //This is not the last chunk.
{
lpChunk->lpPrevChunk->lpNextChunk = lpChunk->lpNextChunk;
lpChunk->lpNextChunk->lpPrevChunk = lpChunk->lpPrevChunk;
}
}
//
//Now,we release the chunk page frames and control block.
//
dwChunkSize = (DWORD)lpChunk->lpEndAddr - (DWORD)lpChunk->lpStartAddr + 1;
PageFrameManager.FrameFree((__COMMON_OBJECT*)&PageFrameManager,
lpChunk->lpStartAddr,
dwChunkSize); //Free the page frame.
KMemFree((LPVOID)lpChunk,KMEM_SIZE_TYPE_ANY,0L);
}
//
//The implementation of ReleaseAllChunk.
//The routine does the following:
// 1. Release all chunk(s) the kernel thread reserved(by dwIndex value);
// 2. Set the descriptor's status to free.
//
static VOID ReleaseDescIndex(__COMMON_OBJECT* lpThis,
DWORD dwIndex)
{
__VIRTUAL_MEMORY_DESCRIPTOR* lpDesc = NULL;
__MEMORY_MANAGER* lpMemManager = NULL;
LPVOID lpStartAddr = NULL;
__CHUNK_CONTROL_BLOCK* lpChunk = NULL;
WORD i = 0;
WORD wHeapNum = 0;
if((NULL == lpThis) || (dwIndex >= INVALID_DESC_INDEX)) //Parameters check.
return;
lpMemManager = (__MEMORY_MANAGER*)lpThis;
lpDesc = &lpMemManager->MemDescArray[dwIndex];
if(lpDesc->dwDescriptorFlag & VM_DESCRIPTOR_FLAG_FREE) //The descriptor is free.
return;
wHeapNum = lpDesc->wHeapNum;
for(i = 0;i < wHeapNum;i ++)
{
lpStartAddr = lpDesc->HeapChunkArray[0]->lpStartAddr; //Caution: The index is
//ZERO,not i.
lpMemManager->ReleaseChunk((__COMMON_OBJECT*)lpMemManager,
dwIndex,
lpStartAddr); //Release all heap chunk(s).
}
lpChunk = lpDesc->lpChunkListRoot;
while(lpChunk) //Release all chunk(s).
{
lpStartAddr = lpChunk->lpStartAddr;
//lpChunk = lpChunk->lpNextChunk;
lpMemManager->ReleaseChunk((__COMMON_OBJECT*)lpMemManager,
dwIndex,
lpStartAddr);
lpChunk = lpDesc->lpChunkListRoot;
}
//
//Now,set the descriptor's status to free.
//
lpDesc->dwDescriptorFlag |= VM_DESCRIPTOR_FLAG_FREE;
return;
}
//
//The implementation of MemoryAlloc.
//
//
//In current implementation,we simply the implementation of the MemoryAlloc and
//MemoryFree routine. :))))))))))))
//
static LPVOID MemoryAlloc(__COMMON_OBJECT* lpThis,
DWORD dwDescIndex,
DWORD dwSize)
{
LPVOID lpRetVal = NULL;
if((NULL == lpThis) || (dwSize > MAX_CHUNK_SIZE)) //Parameter check.
return lpRetVal;
if(0 == dwSize) //Invalid size parameter.
return lpRetVal;
lpRetVal = PageFrameManager.FrameAlloc((__COMMON_OBJECT*)&PageFrameManager,
dwSize,
0L);
return lpRetVal;
}
//
//The implementation of MemoryFree.
//
static VOID MemoryFree(__COMMON_OBJECT* lpThis,
DWORD dwDescIndex,
LPVOID lpStartAddr,
DWORD dwSize)
{
if((NULL == lpThis) || (NULL == lpStartAddr)) //Parameters check.
return;
PageFrameManager.FrameFree((__COMMON_OBJECT*)&PageFrameManager,
lpStartAddr,
dwSize);
}
/*************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
*************************************************************************/
//
//The definition of global object MemoryManager.
//
__MEMORY_MANAGER MemoryManager = {
{0}, //MemDiscArray.
MemMgrInitialize, //Initialize routine.
ReserveDescIndex, //ReserveDescIndex routine.
ReserveChunk, //ReserveChunk routine.
ReleaseChunk, //ReleaseChunk routine.
ReleaseDescIndex, //ReleaseAllChunk routine.
MemoryAlloc, //MemoryAlloc routine.
MemoryFree //MemoryFree routine.
};
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -