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

📄 pagemgr.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************
Copyright(c) 版权所有,1998-2005微逻辑。保留所有权利。
******************************************************/

/*****************************************************
文件说明:页管理模块,该模块将系统所有空闲内存以页为单位组织起来;
          这是一个最基本的内存管理模块,其他所有内存分配函数都从该
		  模块得到以页为单位的内存


版本号:2.0.0
开发时期:2000
作者:李林
修改记录:
******************************************************/


#include <eframe.h>
#include <epcore.h>
#include <pagemgr.h>
#include <oemfunc.h>
#include <cpu.h>

#define FLAG_USED 1
#define FLAG_FREE 0
#define MAX_USED_COUNT 0xff


LPBYTE  lpbSysMainMem;   // 系统主内存开始位置
LPBYTE  lpbSysMainMemEnd; // 系统主内存结束位置
DWORD   dwHandleBase;  // 句柄的内存基本位置
ULONG   ulSysMainMemLength; //系统主内存大小

#ifdef INLINE_PROGRAM
//extern UINT _uiHeapSize = 0;
#endif

// 由地址和该地址所在的段得到该地址对应的索引号
#define GET_INDEX( lpSegInfo, lpvMemAdr ) ( ( (LPBYTE)(lpvMemAdr) - (lpSegInfo)->lpbFreePageStart ) / PAGE_SIZE )

// 内存配置信息
static MEMINFO memInfo;
// 空闲页链表
static LPPAGELIST lpFreePageList = NULL;
// 空闲页数
static UINT    uiFreePages = 0;

// ********************************************************************
//声明:void Page_LinkToList( LPPAGELIST lpList ) 
//参数:
//	IN lpList - 以PAGELIST结构指针表示的空闲页
//返回值:
//	无
//功能描述:
//	将一个空闲页插入空闲链表
//引用:
// ********************************************************************
static void Page_LinkToList( LPPAGELIST lpList ) 
{
	lpList->lpNext = lpFreePageList;
	lpList->lpPrev = NULL;
	if( lpFreePageList )
		lpFreePageList->lpPrev = lpList;
	lpFreePageList = lpList;
}

// ********************************************************************
//声明:void Page_UnlinkFromList( LPPAGELIST lpList )
//参数:
//	IN lpList - 以PAGELIST结构指针表示的空闲页
//返回值:
//	无
//功能描述:
//	将一个空闲页移出空闲链表
//引用:
// ********************************************************************

static void Page_UnlinkFromList( LPPAGELIST lpList )
{
	if( lpList->lpNext )
	{
		ASSERT( lpList->lpNext->lpPrev == lpList );
		lpList->lpNext->lpPrev = lpList->lpPrev;
	}
	if( lpList->lpPrev )
	{
		ASSERT( lpList->lpPrev->lpNext == lpList );
		lpList->lpPrev->lpNext = lpList->lpNext;
	}
	if( lpFreePageList == lpList )
		lpFreePageList = lpList->lpNext;
	lpList->lpNext = lpList->lpPrev = NULL;
}

// ********************************************************************
//声明:void Page_AddToFreeList( LPPAGELIST lpList )
//参数:
//	IN lpList - 以PAGELIST结构指针表示的页
//返回值:
// 无
//功能描述:
//	将一个页插入空闲链表并增加空闲页计数
//引用:
// ********************************************************************

static void Page_AddToFreeList( LPPAGELIST lpList )
{
	Page_LinkToList( lpList );
    uiFreePages++;
}

// ********************************************************************
//声明:void * Page_RemoveFromFreeList( BOOL bUpdateFreePages )
//参数:
//  IN bUpdateFreePages - 是否更新空闲页计数

//返回值:
// 无
//功能描述:
//	将一个页移出空闲链表并根据需要减少空闲页计数,在调用该函数之前必须锁住中断!!
//引用:
// ********************************************************************

static void * Page_RemoveFromFreeList( BOOL bUpdateFreePages )
{
	LPPAGELIST lpList = lpFreePageList;
	Page_UnlinkFromList( lpFreePageList );//lpList );
	if( bUpdateFreePages )
	    uiFreePages--;
	return lpList;
}

// ********************************************************************
//声明:LPSEGMENTINFO Page_GetSeg( void * lpvMemAdr  )
//参数:
//	IN lpvMemAdr - 内存地址
//返回值:
//	假如成功,返回该地址所在的内存段信息;否则NULL
//功能描述:
//	得到一个地址所在的内存段信息,一个内存段是一个连续的能够存取的内存空间
//引用:
// ********************************************************************

static LPSEGMENTINFO Page_GetSeg( void * lpvMemAdr  )
{
	LPSEGMENTINFO lpSegInfo = memInfo.lpSectionInfo;
	DWORD dwSections = memInfo.dwSections;

	for( ; dwSections; dwSections-- )
	{
		if( (LPBYTE)lpvMemAdr >= lpSegInfo->lpbFreePageStart &&
			(LPBYTE)lpvMemAdr < lpSegInfo->lpbFreePageEnd )
		{
			return lpSegInfo;
		}
		lpSegInfo++;
	}
	return NULL;
}

// ********************************************************************
//声明:BOOL Page_Duplicate( void * lpvMemAdr )
//参数:
//	IN lpvMemAdr - 内存地址
//返回值:
//	假如成功,返回TRUE;否则返回FALSE
//功能描述:
//	增加对该内存的引用计数
//引用:
// ********************************************************************

BOOL Page_Duplicate( void * lpvMemAdr )
{
	LPSEGMENTINFO lpSegInfo;
	UINT uiSave;
	int index;

	lpvMemAdr = (LPVOID)CACHE_TO_UNCACHE( lpvMemAdr );

	lpSegInfo = Page_GetSeg( lpvMemAdr );
//	ASSERT( lpSegInfo );

	LockIRQSave( &uiSave );

	index = GET_INDEX( lpSegInfo, lpvMemAdr );
	ASSERT( lpSegInfo->lpbFreeMemMap[index] != FLAG_FREE );
	if( lpSegInfo->lpbFreeMemMap[index] < MAX_USED_COUNT ) 
	    lpSegInfo->lpbFreeMemMap[index]++;

	UnlockIRQRestore( &uiSave );

	return TRUE;
}

// ********************************************************************
//声明:BOOL Page_GetSpecific( LPSEGMENTINFO lpSegInfo, DWORD dwIndex )
//参数:
//	IN lpSegInfo - 内存段指针
//	IN dwIndex - 页索引号
//返回值:
//	假如成功,返回TRUE;否则FALSE
//功能描述:
//	假如一个特定的页是空闲的,则将其设为占用状态
//引用:
// ********************************************************************

static BOOL Page_GetSpecific( LPSEGMENTINFO lpSegInfo, DWORD dwIndex )
{
	UINT uiSave;

    LockIRQSave( &uiSave );

	ASSERT( dwIndex < lpSegInfo->dwTotalPages );
	if( lpSegInfo->lpbMemStart[dwIndex] == FLAG_FREE )
	{	//空闲的
		lpSegInfo->lpbMemStart[dwIndex] = FLAG_USED;
		Page_UnlinkFromList( (LPPAGELIST)( lpSegInfo->lpbFreePageStart + dwIndex * PAGE_SIZE ) );
		
		UnlockIRQRestore( &uiSave );
		return TRUE;
	}

    UnlockIRQRestore( &uiSave );
	return FALSE;	
}

// ********************************************************************
//声明:BOOL Page_ReleaseSpecific( LPSEGMENTINFO lpSegInfo, DWORD dwIndex )
//参数:
//	IN lpSegInfo - 内存段指针
//	IN dwIndex - 页索引号
//返回值:
//	假如成功,返回TRUE;否则返回FALSE
//功能描述:
//	与Page_GetSpecific相对应,假如一个特定的页是占用状态,则将其设为空闲状态
//引用:
// ********************************************************************

static BOOL Page_ReleaseSpecific( LPSEGMENTINFO lpSegInfo, DWORD dwIndex )
{
	UINT uiSave;

    LockIRQSave( &uiSave );

	ASSERT( dwIndex < lpSegInfo->dwTotalPages );
	ASSERT( lpSegInfo->lpbMemStart[dwIndex] == FLAG_USED );

	if( lpSegInfo->lpbMemStart[dwIndex] == FLAG_USED )
	{	// 增加到链表
		lpSegInfo->lpbMemStart[dwIndex] = FLAG_FREE;
		Page_LinkToList( (LPPAGELIST)( lpSegInfo->lpbFreePageStart + dwIndex * PAGE_SIZE ) );
	}

	UnlockIRQRestore( &uiSave );
	return TRUE;
}

// ********************************************************************
//声明:UINT Page_CountFreePages( void )
//参数:
//	无
//返回值:
//	返回空闲页数
//功能描述:
//	得到系统空闲页数
//引用:
// ********************************************************************

UINT Page_CountFreePages( void )
{
	return uiFreePages;
}

// ********************************************************************
//声明:BOOL Page_Lock( DWORD dwPages )
//参数:
// IN dwPages - 页数
//
//返回值:
//	假如成功,返回TRUE;否则返回FALSE
//功能描述:
//	锁住相应的页数
//引用:
// ********************************************************************

BOOL Page_Lock( DWORD dwPages )
{
	BOOL bRetv;
	UINT uiSave;

    LockIRQSave( &uiSave );

	if( uiFreePages >= dwPages )
	{	//	假如空闲页满足需要的页数,则减去需要的页数
		uiFreePages -= dwPages;
		bRetv = TRUE;
	}
	else
		bRetv = FALSE;


	UnlockIRQRestore( &uiSave );
	return bRetv;
}

// ********************************************************************
//声明:BOOL Page_Unlock( DWORD dwPages )
//参数:
//	IN dwPages - 页数 
//
//返回值:
//	假如成功,返回TRUE;否则返回FALSE
//功能描述:
//	与Page_Lock相对应,解锁相应的页数
//引用:
//
// ********************************************************************

BOOL Page_Unlock( DWORD dwPages )
{
	UINT uiSave;

    LockIRQSave( &uiSave );

    uiFreePages += dwPages;

    UnlockIRQRestore( &uiSave );

	return TRUE;
}

// ********************************************************************
//声明:void * Page_Alloc( BOOL bUpdateFreePages )
//参数:
//	IN bUpdateFreePages - 是否更新空闲页计数,如果为TRUE,则要检查 uiFreePages 是否 > 0; 如果为FALSE, 则不检查(之前用Page_Lock已经更新了uiFreePages)
//

⌨️ 快捷键说明

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