📄 pagemgr.c
字号:
/******************************************************
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 + -