?? memory.c
字號(hào):
/*********************************************************************
* Copyright (c) 2011-2012,李士偉
* All rights reserved.
*文 件 名:memory.c
*描 述:可變分區(qū)內(nèi)存管理,最先適應(yīng)算法
*當(dāng)前版本:V1.00
*作 者:李士偉
*創(chuàng)建日期:2011.09.29
**********************************************************************/
#include <mm\memory.h>
#include <kernel\asm.h>
INT32U OSMemBase[OS_MEM_SIZE]; /* 配置內(nèi)存 */
OSMEMFreeBlkHead *OSMemFreeList;
OSMEMInf __OSMemInf; /* 內(nèi)存信息 */
/*********************************************************************
*函 數(shù) 名:OS_InitMem
*描 述:初始化內(nèi)存,及相關(guān)的內(nèi)存管理全局變量
*輸入?yún)?shù):無(wú)
*輸出參數(shù):無(wú)
*返 回 值:無(wú)
*注 意:
**********************************************************************/
void OS_InitMem(void)
{
OS_ENTER_CRITICAL();
OSMemFreeList = (OSMEMFreeBlkHead *)(((INT32U)OSMemBase + sizeof(INT32U)-1)
& (~(sizeof(INT32U)-1))); /* 內(nèi)存基址字對(duì)齊 */
OSMemFreeList->BlkNext = NULL;
/* 因內(nèi)存基址字對(duì)齊處理,須重新計(jì)算內(nèi)存大小*/
OSMemFreeList->BlkSize = ((OS_MEM_SIZE << 2) -
((INT32U)OSMemFreeList - (INT32U)OSMemBase)+sizeof(INT32U)-1)
& (~(sizeof(INT32U) - 1));
OSMemFreeList->BlkPrev = NULL;
/* 初始化內(nèi)存信息 */
__OSMemInf.Usage = 0;
__OSMemInf.TotalSize = OSMemFreeList->BlkSize;
__OSMemInf.FreeSize = __OSMemInf.TotalSize;
__OSMemInf.FreeBlks = 1;
__OSMemInf.UsingBlks =0;
OS_EXIT_CRITICAL();
}
/*********************************************************************
*函 數(shù) 名:API_GetMemInf
*描 述:獲取內(nèi)存使用信息
*輸入?yún)?shù):無(wú)
*輸出參數(shù):pMemInf 內(nèi)存信息結(jié)構(gòu)指針,內(nèi)存使用信息寫(xiě)入指針指向結(jié)構(gòu)體
*返 回 值:無(wú)
*注 意:
**********************************************************************/
void API_GetMemInf(OSMEMInf *pMemInf)
{
OS_ENTER_CRITICAL();
__OSMemInf.Usage = ((__OSMemInf.TotalSize - __OSMemInf.FreeSize) * 100)
/ __OSMemInf.TotalSize;
*pMemInf = __OSMemInf;
OS_EXIT_CRITICAL();
}
/*********************************************************************
*函 數(shù) 名:malloc
*描 述:以字為單位分配內(nèi)存塊
*輸入?yún)?shù):size: 分配內(nèi)存塊的字節(jié)數(shù),若分配的字節(jié)數(shù)非字的倍數(shù),
* 會(huì)多分配1~3個(gè)字節(jié)湊齊字的倍數(shù)
*輸出參數(shù):無(wú)
*返 回 值:分配的內(nèi)存塊指針,用戶要保證使用相同的指針值釋放內(nèi)存
*注 意:size 的值不能取0
**********************************************************************/
void* malloc(INT32U size)
{
OSMEMFreeBlkHead *pblk;
OSMEMUsingBlkHead *pUseblk;
/* 按字分配內(nèi)存,計(jì)算需分配的內(nèi)存塊大小(單位字) */
size = (size + sizeof(OSMEMUsingBlkHead) + sizeof(INT32U) -1)
& (~(sizeof(INT32U) - 1));
OS_ENTER_CRITICAL();
pblk = OSMemFreeList;
/* 查找足夠大的內(nèi)存塊 */
while (pblk != NULL)
{
if (pblk->BlkSize >= size)
{
break;
}
pblk = pblk->BlkNext;
}
/* 找到足夠大的內(nèi)存塊 */
if (pblk != NULL)
{
/* 分配整塊內(nèi)存塊出去 */
if ((pblk->BlkSize) < (size + sizeof(OSMEMFreeBlkHead)))
{
if (pblk->BlkNext != NULL)
{
(pblk->BlkNext)->BlkPrev = pblk->BlkPrev;
}
if (pblk->BlkPrev != NULL) /* pblk 不是雙向鏈表頭節(jié)點(diǎn) */
{
(pblk->BlkPrev)->BlkNext = pblk->BlkNext;
}
else /* pblk 是雙向鏈表頭節(jié)點(diǎn) */
{
OSMemFreeList = pblk->BlkNext;
}
size = pblk->BlkSize;
pUseblk = (OSMEMUsingBlkHead *)pblk;
__OSMemInf.FreeBlks--; /* 空閑內(nèi)塊數(shù)量減1 */
}
else /* 從內(nèi)存塊高端地址切分一塊內(nèi)存 */
{
pblk->BlkSize = pblk->BlkSize - size;
pUseblk = (OSMEMUsingBlkHead *)
((INT32U)pblk + (pblk->BlkSize));
}
pUseblk->SizeChk = size;
pUseblk->Size = size;
__OSMemInf.FreeSize = __OSMemInf.FreeSize - size;
__OSMemInf.UsingBlks++;
OS_EXIT_CRITICAL();
return (void *)((INT32U)pUseblk + sizeof(OSMEMUsingBlkHead));
}
/* 未找到足夠大的內(nèi)存塊 */
OS_EXIT_CRITICAL();
return NULL;
}
/*********************************************************************
*函 數(shù) 名:OS_FreeMemErr
*描 述:釋放內(nèi)存校驗(yàn)出錯(cuò)處理
*輸入?yún)?shù):ptr: 釋放內(nèi)存塊的指針
*輸出參數(shù):無(wú)
*返 回 值:無(wú)
*注 意:這個(gè)函數(shù)只是在內(nèi)存釋放出錯(cuò)時(shí)簡(jiǎn)單的重啟系統(tǒng)
**********************************************************************/
void OS_FreeMemErr(void *ptr)
{
Reboot(); /* 重啟系統(tǒng) */
}
/*********************************************************************
*函 數(shù) 名:free
*描 述:釋放內(nèi)存
*輸入?yún)?shù):ptr: 內(nèi)存塊指針
*輸出參數(shù):無(wú)
*返 回 值:無(wú)
*注 意:
**********************************************************************/
void free(void *ptr)
{
OSMEMFreeBlkHead *pFreeblk;
OSMEMUsingBlkHead *pUseblk;
INT32U size;
pUseblk =(OSMEMUsingBlkHead *)((INT32U)ptr - sizeof(OSMEMUsingBlkHead));
OS_ENTER_CRITICAL();
if (pUseblk->SizeChk != pUseblk->Size) /* 內(nèi)存釋放大小校驗(yàn)出錯(cuò) */
{
OS_FreeMemErr(ptr);
return;
}
size = pUseblk->Size;
__OSMemInf.FreeSize +=size;
__OSMemInf.UsingBlks--; /* 使用內(nèi)存塊計(jì)數(shù)減1 */
pFreeblk = OSMemFreeList;
if (pFreeblk == NULL)
{
OSMemFreeList = (OSMEMFreeBlkHead *)pUseblk;
OSMemFreeList->BlkNext = NULL;
OSMemFreeList->BlkSize = size;
OSMemFreeList->BlkPrev = NULL;
__OSMemInf.FreeBlks++; /* 空閑內(nèi)存塊計(jì)數(shù)加1 */
OS_EXIT_CRITICAL();
return ;
}
while (pFreeblk !=NULL)
{
/* 鏈表中存在高于釋放內(nèi)存塊首址的節(jié)點(diǎn) */
if ((INT32U)pUseblk < (INT32U)pFreeblk)
{
if (pFreeblk->BlkPrev == NULL)
{
/* pFreeblk是雙向鏈表的頭節(jié)點(diǎn) */
OSMemFreeList = (OSMEMFreeBlkHead *)pUseblk;
OSMemFreeList->BlkNext = pFreeblk;
OSMemFreeList->BlkSize = size;
OSMemFreeList->BlkPrev = NULL;
pFreeblk->BlkPrev = OSMemFreeList;
__OSMemInf.FreeBlks++; /*空閑內(nèi)存塊計(jì)數(shù)加1 */
/* pFreeblk 指向釋放的內(nèi)存塊節(jié)點(diǎn),
在后面判斷是否與下一塊內(nèi)存合并*/
pFreeblk = OSMemFreeList;
}
else
{
pFreeblk = pFreeblk->BlkPrev;
if ((INT32U)pUseblk == (INT32U)pFreeblk
+ (pFreeblk->BlkSize))
{
/* 與上一個(gè)內(nèi)存塊相鄰則合并 */
pFreeblk->BlkSize += size;
}
else
{
/* 在雙向鏈表中創(chuàng)建一個(gè)新內(nèi)存塊節(jié)點(diǎn) */
((OSMEMFreeBlkHead *)pUseblk)->BlkNext = pFreeblk->BlkNext;
((OSMEMFreeBlkHead *)pUseblk)->BlkSize = size;
((OSMEMFreeBlkHead *)pUseblk)->BlkPrev = pFreeblk;
(pFreeblk->BlkNext)->BlkPrev = (OSMEMFreeBlkHead *)pUseblk;
pFreeblk->BlkNext = (OSMEMFreeBlkHead *)pUseblk;
__OSMemInf.FreeBlks++; /*空閑內(nèi)存塊計(jì)數(shù)加1 */
/* pFreeblk 指向釋放的內(nèi)存塊節(jié)點(diǎn),
在后面判斷是否與下一塊內(nèi)存合并*/
pFreeblk = pFreeblk->BlkNext;
}
}
/* 判斷是否與存在的下一個(gè)內(nèi)存塊相鄰 */
if (pFreeblk->BlkNext !=NULL)
{
/* 與下一個(gè)內(nèi)存塊相鄰則合并 */
if ((INT32U)(pFreeblk->BlkNext) == (INT32U)pFreeblk
+ (pFreeblk->BlkSize))
{
pFreeblk->BlkSize +=(pFreeblk->BlkNext)->BlkSize;
pFreeblk->BlkNext = (pFreeblk->BlkNext)->BlkNext;
if (pFreeblk->BlkNext != NULL)
{
(pFreeblk->BlkNext)->BlkPrev = pFreeblk;
}
__OSMemInf.FreeBlks--; /*空閑內(nèi)存塊計(jì)數(shù)減1 */
}
}
OS_EXIT_CRITICAL();
return ;
}
/* 釋放的內(nèi)存塊首址高于雙向鏈表最后一塊內(nèi)存首址 */
if (pFreeblk->BlkNext == NULL)
{
if ((INT32U)pUseblk == (INT32U)pFreeblk + (pFreeblk->BlkSize))
{
/* 與上一個(gè)內(nèi)存塊相鄰則合并 */
pFreeblk->BlkSize += size;
}
else
{
pFreeblk->BlkNext = (OSMEMFreeBlkHead *)pUseblk;
(pFreeblk->BlkNext)->BlkNext = NULL;
(pFreeblk->BlkNext)->BlkSize = size;
(pFreeblk->BlkNext)->BlkPrev = pFreeblk;
__OSMemInf.FreeBlks++; /*空閑內(nèi)存塊計(jì)數(shù)加1 */
}
OS_EXIT_CRITICAL();
return ;
}
pFreeblk = pFreeblk->BlkNext;
}
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -