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

📄 memmgr.cpp

📁 小型的操作系统开发的原代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		}
	}

	//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 + -