📄 mem_admin.c
字号:
#include "mem_define.h"
#ifndef XU_SIM
#include "mem_admin.h"
#endif
#include "mem_fun.h"
void *G_StartAddr; //要进行管理的启初位置
void *G_EndAddr; //要结束管理的结束位置
uint32 G_ManageSpace; //全部空闲空间大小
PMEMCB ROOT_CB; //根节点
PLISTHEADER IDLE_LIST; //指向空闲链表
PLISTHEADER BUSY_LIST; //指向忙链表
//extern void Uart_printf(char const *fmt, ...);
/*******************************************************************************************************
**函 数:Fun_FindItemInList
**功 能:在指定的链表中找出相应的表项
**输 入:*DestListHeader要查找的链表
** *DestParam相应表项的关键参数
**输 出:链表中的表项
**受影响的全局变量:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void *Fun_FindItemInList(PLISTHEADER DestListHeader, void *DestParam)
{
//uint32 xu_temp;
PMEMCB temp_sp;
//Uart_printf("\n\n\nFun_Free Fail 1!!!\n");
if(DestListHeader->FirstItem == NULL)
{
//Uart_printf("\n\n\nFun_Free Fail First NULL!!!\n");
return NULL;
}
temp_sp = (PMEMCB)DestListHeader->FirstItem;
do
{
if((DestParam >= temp_sp->Addr) &&
(DestParam <= (void *)((uint32)temp_sp->Addr + temp_sp->spacesize - CBSIZE)))
{
//Uart_printf("Find BusyList Item\n\n\n");
return (void *)temp_sp;
}
else
{
temp_sp = (PMEMCB)temp_sp->Next;
}
}while(temp_sp != (PMEMCB)DestListHeader->LastItem);
if((DestParam >= temp_sp->Addr) && (DestParam <= (void *)((uint32)temp_sp->Addr + temp_sp->spacesize - CBSIZE)))
{
//Uart_printf("Find BusyList Item Last\n\n\n");
return (void *)temp_sp;
}
//Uart_printf("Fun_Free Fail!!!\n\n\n");
return NULL;
}
/*******************************************************************************************************
**函 数:Sub_ListAdd
**功 能:向相相应的链表内追加一个表项
**输 入:*DestListHeader要加入新表项的链表
** *SrcListItem要被加入的表项
**输 出:
**受影响的全局变量:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void Sub_ListAdd(PLISTHEADER DestListHeader, PMEMCB SrcListItem)
{
PMEMCB temp_sp;
if(DestListHeader->FirstItem == NULL)
{
//空的链表
DestListHeader->FirstItem = (void *)SrcListItem;
DestListHeader->LastItem = DestListHeader->FirstItem;
}
else
{
temp_sp = (PMEMCB)DestListHeader->LastItem;
temp_sp->Next = (void *)SrcListItem;
SrcListItem->Prev = (void *)temp_sp;
SrcListItem->Next = NULL;
DestListHeader->LastItem = (void *)SrcListItem;
}
}
/****************************************Copyright (c)**************************************************
**函 数:Fun_MemInit
**功 能:初始化内存管理程序
**输 入:*StartAdmin_Sp需要开始管理的内存地址
** *EndAdmin_Sp结束管理的内存地址
**输 出:1成功启动的内存管理
** -1无法启动内存管理
**受影响的全局变量:G_StartAddr,G_EndAddr, G_AllSpace
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int32 Fun_MemInit(void *StartAdmin_Sp, void *EndAdmin_Sp)
{
G_StartAddr = StartAdmin_Sp;
G_EndAddr = EndAdmin_Sp;
G_ManageSpace = (uint32)G_EndAddr - (uint32)G_StartAddr + 1;
if(G_ManageSpace <= 1024)
{
//小于1K不用管理
return -1;
}
IDLE_LIST = (PLISTHEADER)G_StartAddr;
BUSY_LIST = (PLISTHEADER)((int8 *)IDLE_LIST + HEADERSIZE);
ROOT_CB = (PMEMCB)((int8 *)G_StartAddr + HEADERSIZE + HEADERSIZE);
ROOT_CB->Addr = (void *)((uint32)G_StartAddr + CBSIZE + HEADERSIZE + HEADERSIZE);
ROOT_CB->spacesize = G_ManageSpace - HEADERSIZE - HEADERSIZE;
ROOT_CB->Busy_Flag = IDLE_FLAG;
ROOT_CB->Mem_LB = NULL;
ROOT_CB->Mem_RB = NULL;
ROOT_CB->Next = NULL;
ROOT_CB->Prev = NULL;
IDLE_LIST->FirstItem = ROOT_CB;
IDLE_LIST->LastItem = ROOT_CB;
BUSY_LIST->FirstItem = NULL;
BUSY_LIST->LastItem = NULL;
return 1;
}
/*******************************************************************************************************
**函 数:Fun_FindIdle
**功 能:查找出一个IDLE的叶节点
**输 入:Size所需要的内存大小
**输 出:一个IDLE叶节点
** 失败返回NULL
**受影响的全局变量:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
PMEMCB Fun_FindIdle(uint32 Dest_Size)
{
PMEMCB temp_sp;
temp_sp = (PMEMCB)IDLE_LIST->FirstItem;
while(temp_sp != NULL)
{
if((temp_sp->Busy_Flag == IDLE_FLAG) && (temp_sp->spacesize >= (Dest_Size + CBSIZE)))
{
return temp_sp;
}
else
{
temp_sp = (PMEMCB)temp_sp->Next;
}
}
return NULL;
}
/*******************************************************************************************************
**函 数:Fun_Malloc
**功 能:分配一块指定大小的内存给用户用
**输 入:size 用户要的大小
**输 出:成功返回该块内存的启始地址
** 失败返回NULL
**受影响的全局变量:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void *Fun_Malloc(uint32 size)
{
PMEMCB temp_sp;
PMEMCB temp_sp2;
//uint xu_temp;
if((size & 0x11) != 0x00)
{
//没有按字对齐
switch((size & 0x11))
{
case 0x01:
size += 0x11;
break;
case 0x10:
size += 0x10;
break;
case 0x11:
size += 0x01;
break;
}
}
if((size & (CBSIZE - 1)) != 0x00)
{
//不是CBSIZE的倍数
size += (CBSIZE - (size & (CBSIZE - 1)));
}
temp_sp = Fun_FindIdle(size);
if(temp_sp != NULL)
{
//找到了适合的表项
if(temp_sp->spacesize <= (size + CBSIZE + CBSIZE + CBSIZE))
{
//余下的空间没有必要再一个控制块了,把余下的空间一起分配了
//以下是处理IDLE_LIST链表
if((IDLE_LIST->FirstItem == (void *)temp_sp) && (IDLE_LIST->LastItem == (void *)temp_sp))
{
IDLE_LIST->FirstItem = NULL;
IDLE_LIST->LastItem = NULL;
}
else
{
if(IDLE_LIST->FirstItem == (void *)temp_sp)
{
IDLE_LIST->FirstItem = temp_sp->Next;
((PMEMCB)temp_sp->Next)->Prev = NULL;
}
else if(IDLE_LIST->LastItem == (void *)temp_sp)
{
IDLE_LIST->LastItem = temp_sp->Prev;
((PMEMCB)temp_sp->Prev)->Next = NULL;
}
else
{
((PMEMCB)(temp_sp->Prev))->Next = temp_sp->Next;
((PMEMCB)(temp_sp->Next))->Prev = temp_sp->Prev;
}
}
//以下是加入到BUSY_LIST链表
temp_sp->Busy_Flag = BUSY_FLAG;
temp_sp->Next = NULL;
temp_sp->Prev = NULL;
Sub_ListAdd(BUSY_LIST, temp_sp);
return temp_sp->Addr;
}
/* 分割这个内存控制块变为一个Busy与一个Idle */
temp_sp2 = (PMEMCB)((uint8 *)temp_sp->Addr + size); //把这个块分成两个块
temp_sp2->Busy_Flag = IDLE_FLAG;
temp_sp2->Addr = ((uint8 *)temp_sp2 + CBSIZE);
temp_sp2->spacesize = temp_sp->spacesize - size - CBSIZE;
temp_sp2->Mem_LB = (void *)temp_sp;
temp_sp2->Mem_RB = (void *)(temp_sp->Mem_RB);
if(temp_sp->Mem_RB != NULL)
{
((PMEMCB)temp_sp->Mem_RB)->Mem_LB = (void *)temp_sp2;
}
temp_sp->Mem_RB = (void *)temp_sp2;
/* 要用新的空闲表项,替换掉旧的表项 */
if(IDLE_LIST->FirstItem != NULL)
{
if(IDLE_LIST->FirstItem == IDLE_LIST->LastItem)
{
//原链表中就只有一个表项
IDLE_LIST->FirstItem = (void *)temp_sp2;
IDLE_LIST->LastItem = IDLE_LIST->FirstItem;
temp_sp2->Next = NULL;
temp_sp2->Prev = NULL;
}
else
{
temp_sp2->Next = temp_sp->Next; //temp_sp2是新分出来的
temp_sp2->Prev = temp_sp->Prev;
if(IDLE_LIST->FirstItem == (void *)temp_sp)
{
IDLE_LIST->FirstItem = (void *)temp_sp2;
((PMEMCB)(temp_sp->Next))->Prev = (void *)temp_sp2;
}
else if(IDLE_LIST->LastItem == (void *)temp_sp)
{
IDLE_LIST->LastItem = (void *)temp_sp2;
((PMEMCB)(temp_sp->Prev))->Next = (void *)temp_sp2;
}
else
{
((PMEMCB)(temp_sp->Next))->Prev = (void *)temp_sp2;
((PMEMCB)(temp_sp->Prev))->Next = (void *)temp_sp2;
}
}
}
/* 把新的忙表项追加入忙链表中 */
temp_sp->Busy_Flag = BUSY_FLAG;
temp_sp->spacesize = size + CBSIZE;
temp_sp->Next = NULL;
temp_sp->Prev = NULL;
Sub_ListAdd(BUSY_LIST, temp_sp);
return temp_sp->Addr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -