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

📄 mem_admin.c

📁 一个ARM内核通用的内存管理程序。通过使用三个链表进行管理
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -