?? buffmgr.cpp
字號:
//***********************************************************************/
// Author : Garry
// Original Date : Aug,25 2004
// Module Name : buffmgr.cpp
// Module Funciton :
// This module countains the buffer manager
// implementation code.
// Last modified Author :
// Last modified Date :
// Last modified Content :
// 1.
// 2.
// Lines number :
//***********************************************************************/
#ifndef __STDAFX_H__
#include "..\INCLUDE\StdAfx.h"
#endif
//
//Create buffer routine,used by buffer manager to allocate a new buffer pool,and
//initializes the buffer control block.
//
//The following routine create a buffer pool by calling KMemAlloc.
static BOOL CreateBuffer1(__BUFFER_CONTROL_BLOCK* pControlBlock,DWORD dwPoolSize)
{
BOOL bResult = FALSE;
LPVOID lpBufferPool = NULL;
DWORD dwSize = 0L;
__FREE_BUFFER_HEADER* pFreeHdr = NULL;
dwSize = RoundTo4k(dwPoolSize);
lpBufferPool = KMemAlloc(dwPoolSize,KMEM_SIZE_TYPE_4K);
if(NULL == lpBufferPool) //Fail to allocate memory.
goto __TERMINAL;
pControlBlock->dwPoolSize = dwSize; //Initialize the buffer control block.
pControlBlock->dwFlags |= CREATED_BY_SELF;
pControlBlock->dwFlags |= POOL_INITIALIZED; //Set the pool initialized bit.
pControlBlock->lpPoolStartAddress = lpBufferPool;
pControlBlock->dwFreeSize = dwSize;
pFreeHdr = (__FREE_BUFFER_HEADER*)lpBufferPool;
pControlBlock->lpFreeBufferHeader = pFreeHdr;
pFreeHdr->dwFlags = BUFFER_STATUS_FREE;
pFreeHdr->lpNextBlock = NULL;
pFreeHdr->lpPrevBlock = NULL; /*pControlBlock->lpFreeBufferHeader;*/
pFreeHdr->dwBlockSize = dwSize - sizeof(__FREE_BUFFER_HEADER);
pControlBlock->dwFreeSize = pFreeHdr->dwBlockSize;
bResult = TRUE;
__TERMINAL:
return bResult;
}
//
//The following routine create a buffer pool by using client created memory,and initialize
//the buffer control block.
//
static BOOL CreateBuffer2(__BUFFER_CONTROL_BLOCK* pControlBlock,
LPVOID lpBufferPool,
DWORD dwPoolSize)
{
BOOL bResult = FALSE;
DWORD dwSize = 0L;
__FREE_BUFFER_HEADER* pFreeHdr = NULL;
dwSize = dwPoolSize;
pControlBlock->dwPoolSize = dwSize; //Initialize the buffer control block.
pControlBlock->dwFlags |= CREATED_BY_CLIENT;
pControlBlock->dwFlags |= POOL_INITIALIZED; //Set the pool initialized bit.
pControlBlock->lpPoolStartAddress = lpBufferPool;
pFreeHdr = (__FREE_BUFFER_HEADER*)lpBufferPool;
pControlBlock->lpFreeBufferHeader = pFreeHdr;
pFreeHdr->dwFlags = BUFFER_STATUS_FREE;
pFreeHdr->lpNextBlock = NULL;
pFreeHdr->lpPrevBlock = NULL; /*pControlBlock->lpFreeBufferHeader;*/
pFreeHdr->dwBlockSize = dwSize - sizeof(__FREE_BUFFER_HEADER);
pControlBlock->dwFreeSize = pFreeHdr->dwBlockSize;
bResult = TRUE;
return bResult;
}
//
//The following is a helper function,it combines continuous free blocks into one
//big free block,and update the other free blocks's data structure,such as lpNextBlock,
//lpPrevBlock.
//
static VOID CombineFreeBlock(__BUFFER_CONTROL_BLOCK* lpControlBlock, //The control block.
LPVOID lpStartCombine) //The first block's
//address where to
//start combine.
//This function scans
//the buffer pool
//from this position
//to end.
//If this parameter
//is NULL,then start
//at the pool's original
//address,which can
//be get from
//lpControlBlock's member.
{
LPVOID lpEndAddr = NULL;
__FREE_BUFFER_HEADER* lpFreeHeader = NULL;
__FREE_BUFFER_HEADER* lpNextHeader = NULL;
__USED_BUFFER_HEADER* lpUsedHeader = NULL;
DWORD dwFlags = 0L;
if(NULL == lpControlBlock) //Parameters check.
{
return;
}
//ENTER_CRITICAL_SECTION(); //The following code must not be interrupted.
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
lpFreeHeader = (NULL == lpStartCombine) ? (__FREE_BUFFER_HEADER*)(lpControlBlock->lpPoolStartAddress) :
(__FREE_BUFFER_HEADER*)lpStartCombine;
lpEndAddr = (LPVOID)((DWORD)lpControlBlock->lpPoolStartAddress + lpControlBlock->dwPoolSize);
lpNextHeader = lpFreeHeader ? (__FREE_BUFFER_HEADER*)((DWORD)lpFreeHeader +
sizeof(__FREE_BUFFER_HEADER) +
lpFreeHeader->dwBlockSize) : NULL;
while(TRUE)
{
if(lpEndAddr == (LPVOID)lpNextHeader) //Now,seek to the end of the buffer pool.
break;
if(lpFreeHeader->dwFlags & BUFFER_STATUS_USED) //The current block is used.
{
lpFreeHeader = lpNextHeader;
lpNextHeader = (__FREE_BUFFER_HEADER*)((DWORD)lpFreeHeader +
sizeof(__USED_BUFFER_HEADER) +
lpFreeHeader->dwBlockSize); //Skip the current block.
continue; //Continue to check next block.
}
if(lpNextHeader->dwFlags & BUFFER_STATUS_USED) //If the next block is used,then
//skip two blocks.
{
lpFreeHeader = (__FREE_BUFFER_HEADER*)((DWORD)lpNextHeader +
sizeof(__FREE_BUFFER_HEADER) +
lpNextHeader->dwBlockSize);
if((LPVOID)lpFreeHeader == lpEndAddr) //Seek to the end of the buffer pool.
break;
lpNextHeader = (__FREE_BUFFER_HEADER*)((DWORD)lpFreeHeader +
sizeof(__FREE_BUFFER_HEADER) +
lpFreeHeader->dwBlockSize);
//lpNextHeader = NULL;
continue;
}
else //The next block is free too,so we combine the two blocks,and update the
//free block list.
{
if(NULL == lpNextHeader->lpPrevBlock) //The next block is the first free block.
{
lpNextHeader->lpNextBlock->lpPrevBlock = NULL;
lpControlBlock->lpFreeBufferHeader = lpNextHeader->lpNextBlock;
}
else //The next block is not the first block.
{
if(NULL == lpNextHeader->lpNextBlock) //Is the last block.
{
lpNextHeader->lpPrevBlock->lpNextBlock = NULL;
}
else //Not the last block.
{
lpNextHeader->lpNextBlock->lpPrevBlock = lpNextHeader->lpPrevBlock;
lpNextHeader->lpPrevBlock->lpNextBlock = lpNextHeader->lpNextBlock;
}
}
lpFreeHeader->dwBlockSize += sizeof(__FREE_BUFFER_HEADER); //Combine the two block.
lpFreeHeader->dwBlockSize += lpNextHeader->dwBlockSize;
lpNextHeader = (__FREE_BUFFER_HEADER*)((DWORD)lpFreeHeader +
sizeof(__FREE_BUFFER_HEADER) +
lpFreeHeader->dwBlockSize);
}
}
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
}
//
//Allocate buffer routine,this routine allocates a buffer from buffer pool,according
//the size of the client request,and returns the start address of the buffer.
//
static LPVOID Allocate(__BUFFER_CONTROL_BLOCK* pControlBlock,DWORD dwSize)
{
LPVOID lpBuffer = NULL;
__FREE_BUFFER_HEADER* lpFreeHeader = NULL;
__FREE_BUFFER_HEADER* lpTmpHeader = NULL;
__USED_BUFFER_HEADER* lpUsedHeader = NULL;
DWORD dwBoundrySize = 0L;
BOOL bFind = FALSE;
DWORD dwFlags = 0L;
if((NULL == pControlBlock) || (0 == dwSize)) //Parameters check.
goto __TERMINAL;
__BEGIN:
if(dwSize < MIN_BUFFER_SIZE)
dwSize = MIN_BUFFER_SIZE;
dwBoundrySize = dwSize + MIN_BUFFER_SIZE + sizeof(__FREE_BUFFER_HEADER);
//ENTER_CRITICAL_SECTION(); //The following operation must not be interrupted.
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
lpFreeHeader = pControlBlock->lpFreeBufferHeader;
while(lpFreeHeader)
{
if(lpFreeHeader->dwBlockSize < dwSize) //The current block is not fitable.
{
lpFreeHeader = lpFreeHeader->lpNextBlock;
continue;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -