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

📄 memory_management.cpp

📁 扩展的动态内存机制 任务综述 本任务扩展了自己私有的内存管理机制。首先使用预先规划的思想
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "vxworks.h"
#include "stdio.h"
#include "semlib.h"
#include "tasklib.h"
#include "msgQLib.h"
#include "logLib.h"

/* 参数定义 */
#define MAX_BUF_NUM		256				/* 内存池消息队列最大内存个数*/
#define STACK_SIZE		20000				/* 任务堆栈大小 */
#define MAX_LOG_MSGS	100					/* 最大logMsg个数 */
#define MAX_ALLOC_NUM   50					/* 一次申请最多*/



/* 全局变量的定义 */
unsigned int alloc_num_Buffer_16, alloc_num_Buffer_256;		/* 预先设置16和256的缓冲池大小 */

char *pbuf16_store[256];					/* 用来存放已经申请的16内存块地址 */
int buf_16_num = 0;

char *pbuf256_store[256];					/* 用来存放已经申请的256内存块地址 */
int buf_256_num = 0;

char *pbufsys_store[256];					/* 用来存放已经申请的系统内存块地址 */
int buf_sys_num = 0;



/* 消息队列ID */
MSG_Q_ID msgQId_pool16;						/* 存放静态16内存池块地址的消息队列 */
MSG_Q_ID msgQId_pool256;					/* 存放静态256内存池块地址的消息队列 */

/* 消息结构 */
typedef struct _PBUFFER
{
	char *buffer;
}PBUFFER;


/* 内存分区ID */
char *pTotalPool;
PART_ID pPart16;
PART_ID pPart256;


/* LogMsg */
#ifdef INCLUDE_LOGGING
logInit(consolefd, MAX_LOG_MSGS);
#endif

/* 任务标识 */
int tidTask1;

/* 互斥信号量标识 */
SEM_ID semId = NULL;						/* 保证临界资源的安全 */


/* 函数声名 */
STATUS tTask1();							/* 任务1 */
STATUS Total_MemPool_Initial();				/* 初始化静态内存池函数 */
STATUS bufGet(unsigned int &alloc_buf_size, unsigned int &alloc_num);	/* 申请内存块函数 */
STATUS bufReturn(unsigned int &buffer_type,unsigned int &free_num);		/* 释放内存块函数 */
STATUS bufStatus();														/* 查看内存使用情况函数 */
STATUS exit();															/* 系统退出函数 */


/****************************************************************************/
/************************** 程序入口函数 progStart **************************/
/****************************************************************************/

STATUS progStart(void)
{
	/* 创建互斥信号量 */
	semId = semBCreate(SEM_Q_FIFO,SEM_FULL);

	/* 创建内存池消息队列 */
	msgQId_pool16 = msgQCreate(MAX_BUF_NUM, sizeof(PBUFFER), MSG_Q_FIFO);	/* 16内存缓冲池 */
	if(msgQId_pool16 == NULL)
		return (ERROR);

	msgQId_pool256 = msgQCreate(MAX_BUF_NUM, sizeof(PBUFFER), MSG_Q_FIFO);	/* 256内存缓冲池 */
	if(msgQId_pool256 == NULL)
		return (ERROR);

	/* 创建进程 */
	tidTask1 = taskSpawn("tTask1", 200, 0, STACK_SIZE, (FUNCPTR)tTask1,	/*创建Task1进程 优先级220*/
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0);

	return (OK);
}

/****************************************************************************/
/**************************** 系统主进程 tTask1 *****************************/
/****************************************************************************/

STATUS tTask1()
{
	int option;		/* 用户选择操作 */

	/* 调用初始化静态内存池函数 */
	if(Total_MemPool_Initial() == ERROR)
	{
		printf("\nERROR: Memory pool failed to initialize.\n");
		return (ERROR);
	}

	FOREVER
	{
		/* 等待用户选择操作 */
		/* 操作1: Alloc Buffers -- 申请若干个自定义大小的内存块 */
		/* 操作2: Free Buffers  -- 释放若干个自定义类型的内存块 */
		/* 操作3: Status	    -- 查看当前内存池使用状态 */
		/* 操作4: Exit			-- 释放内存池并退出系统 */
		printf("\nPlease choose your option: (1~4)\n1.\tAlloc Buffers\n2.\tFree buffers\n3.\tStatus\n4.\tExit\n");
		scanf("%d",&option);
		/* 判断用户输入 */
		switch (option) {
			/* 如果选择1 */
			case 1:
				/* 用户输入需要申请的内存块大小和个数 */
				unsigned int alloc_buf_size;			/* 需要申请内存块大小 */
				unsigned int alloc_num;					/* 需要申请内存块个数 */

				printf("Please Input the SIZE of the buffer to alloc:\n");
				scanf("%u",&alloc_buf_size);
				printf("Please Input the AMOUNT of buffers to alloc:\n");
				scanf("%u",&alloc_num);

				/* 调用bufGet()即申请内存块函数 */
				if(bufGet(alloc_buf_size,alloc_num) == ERROR)
				{
					printf("\nERROR: Memory allocation Fail.\n");
					return (ERROR);
				}
				break;
			/* 如果选择2 */
			case 2:
				/* 用户输入需要释放的内存块类型和个数 */
				unsigned int buffer_type;				/* 释放类型 */
				unsigned int free_num;					/* 释放个数 */
				printf("Please Input the TYPE of buffer to free:\n 1. 16_buffer\t2. 256_buffer\t3. system buffer\n");
				scanf("%u",&buffer_type);

				/* 如果是释放系统内存则默认全部删除 */
				if(buffer_type == 1 || buffer_type == 2)
				{
					printf("Please Input the AMOUNT of buffers to free:\n");
					scanf("%u",&free_num);
				}
				/* 调用bufReturn()即内存释放函数 */
				if(bufReturn(buffer_type, free_num) == ERROR)
				{
					printf("\nERROR: Memory Free Fail.\n");
					return (ERROR);
				}
				break;
			/* 如果选择3 */
			case 3:
				/* 调用bufStatus()即监视函数 */
				if(bufStatus()== ERROR)
				{
					printf("\nERROR: Status Check fail.\n");
					return (ERROR);
				}
				break;
			/* 如果选择4 */
			case 4:
				/* 调用系统退出函数 */
				if(exit() == ERROR)
				{
					return (ERROR);
				}
				break;
			/* 其它 */
			default:
				printf("Wrong Input, Try again.\n");
				break;
		}
	}
	return (OK);
}

/****************************************************************************/
/******************** 功能函数 Total_MemPool_Initial() **********************/
/****************************************************************************/

/* 实现功能: 根据用户配置的大小初始化两个不同类型的内存池, */
/* 分别为大小为16和大小为256的内存池,保存内存池中各内存    */
/* 块的首地址,并发送到已经创建的两个内存池消息队列中.      */

STATUS Total_MemPool_Initial()
{
	/* 初始化参数和消息发送对象 */
	int Total_MemPool_Size;
	PBUFFER pBuff16_sd;
	PBUFFER pBuff256_sd;

	/* 提示用户输入两种类型内存池的大小 */
	printf("\n****************************Initialization*****************************\n");
	printf("Please Input the amount of 16 buffers.(3~256)\n");
	scanf("%d",&alloc_num_Buffer_16);
	printf("Please Input the amount of 256 buffers.(3~256)\n");
	scanf("%d",&alloc_num_Buffer_256);

	semTake(semId, WAIT_FOREVER);			/* 互斥信号量 */

	/* 初始化内存池 */
	if(alloc_num_Buffer_16 >= 3 && alloc_num_Buffer_256 >= 3
		&& alloc_num_Buffer_16 <= MAX_BUF_NUM 
		&& alloc_num_Buffer_256 <= MAX_BUF_NUM)          /* 判断输入大小,合法为3~MAX_BUF_NUM个 */
	{
		/* 申请总内存池pTotalPool */
		Total_MemPool_Size = (16+8) * alloc_num_Buffer_16 + (256+8) * alloc_num_Buffer_256 + 10000;
		pTotalPool = (char *)malloc(Total_MemPool_Size);
		
		/* 在总内存池当中创建两个分区 */
		pPart16 = memPartCreate((char*)pTotalPool, (16+8) * alloc_num_Buffer_16);
		pPart256 = memPartCreate((char*)pTotalPool, (256+8) * alloc_num_Buffer_256 + 10000);

		/* 初始化块大小为16的内存池 */
		/* 在分区中分配内存块,并输出地址 */
		printf("\n16_Buffer address:\n");		
		for(int i = 0; i < alloc_num_Buffer_16; ++i)
		{
			pBuff16_sd.buffer = (char*)memPartAlloc(pPart16, 16);
			printf("0x%07x\t",pBuff16_sd.buffer);
			if((i + 1) % 5 == 0)
				printf("\n");
			/* 将申请到的内存块地址发送到对应的内存池消息对列中 */
			if(msgQSend(msgQId_pool16,(char*)&pBuff16_sd, sizeof(PBUFFER), WAIT_FOREVER, MSG_PRI_NORMAL) == ERROR)
			{
				printf("Buffer 16 allocation failed.\n");
				return (ERROR);
			}
		}

		/* 初始化块大小为256的内存池 */
		/* 同上 */
		printf("\n256_Buffer address:\n");
		for(int j = 0; j < alloc_num_Buffer_256; ++j)
		{
			pBuff256_sd.buffer = (char*)memPartAlloc(pPart256, 256);
			printf("0x%07x\t",pBuff256_sd.buffer);
			if((j + 1) % 5 == 0)
				printf("\n");
			if(msgQSend(msgQId_pool256, (char*)&pBuff256_sd, sizeof(PBUFFER), WAIT_FOREVER, MSG_PRI_NORMAL) == ERROR)
			{
				printf("Buffer 256 allocation failed.\n");
				return (ERROR);
			}
		}
		printf("\n*************************************************\nYou have successfully allocated Total Memory Pool\nwith %d 16_buffers and %d 256_buffers.\nNow Program Starting......\n*************************************************\n", alloc_num_Buffer_16, alloc_num_Buffer_256);
	} else {
		printf("Total Memory Pool allocation failed.\nPlease input the valid amount of buffers.\n");
		return (ERROR);
	}

	semGive(semId);							/* 互斥信号量 */

	return (OK);
}

/****************************************************************************/
/**************************** 功能函数 bufGet() *****************************/
/****************************************************************************/

/* 实现功能: 按照用户需求分配若干个自定义大小内存块, */
/* 并输出分配到的内存块的地址.内存的分配实现统一管理 */

STATUS bufGet(unsigned int &alloc_buf_size, unsigned int &alloc_num)
{
	/* 初始化接收消息对象 */
	PBUFFER pBuff16_rc;
	PBUFFER pBuff256_rc;

	/* 内存申请 */
	/* 1.如果申请内存块大小小于16 */
	if(alloc_buf_size > 0 && alloc_buf_size <= 16)		
	{
		/* 如果需要分配的内存块个数小于当前16内存池中未分配内存块的个数	*/
		/* 则直接在16内存池中申请 */
		if(alloc_num > 0 && alloc_num <= msgQNumMsgs(msgQId_pool16)) 
		{
			for(int i = 0; i < alloc_num; ++i)
			{
				/* 从消息队列中接收内存块地址 */
				if(msgQReceive(msgQId_pool16, (char*)&pBuff16_rc, sizeof(PBUFFER), WAIT_FOREVER)==ERROR)
				{
					return(ERROR);
				}
				/* 将已分配地址保存并输出 */
				pbuf16_store[buf_16_num] = pBuff16_rc.buffer;
				printf("0x%07x\t",pbuf16_store[buf_16_num]);
				++buf_16_num;
				if((i + 1) % 5 == 0)
					printf("\n");
			}
			/* 内存不足告警提示信息 */
			if(msgQNumMsgs(msgQId_pool16) <= 3)
			{
				printf("\nCAUTION:You got %d 16_buffer left.\n",msgQNumMsgs(msgQId_pool16));
			}

		/* 如果需要分配的内存块个数大于当前16内存池未分配内存块的个数,	*/
		/* 但小于16内存池和256内存池中未分配的内存总数之和,则先在16内存	*/
		/* 池中申请完所有的内存块,再在256内存池中申请剩下的内存块		*/
		} else if (alloc_num > msgQNumMsgs(msgQId_pool16) 
			&& alloc_num <= msgQNumMsgs(msgQId_pool16) + msgQNumMsgs(msgQId_pool256)) {

				int b16_num = msgQNumMsgs(msgQId_pool16);
				int b256_num = alloc_num - msgQNumMsgs(msgQId_pool16);
				printf("\nCAUTION:No 16_buffer left. So 256_buffer will be used.\n");
				printf("16_buffer address:\n");
				
				/* 先在16内存池中申请 */
				for(int i = 0; i < b16_num; ++i)
				{
					/* 从消息队列中接收内存块地址 */
					if(msgQReceive(msgQId_pool16,(char*)&pBuff16_rc,sizeof(PBUFFER),WAIT_FOREVER)==ERROR)
					{
						return(ERROR);
					}
					/* 将已分配地址保存并输出 */
					pbuf16_store[buf_16_num] = pBuff16_rc.buffer;
					printf("0x%07x\t",pbuf16_store[buf_16_num]);
					++buf_16_num;
					if((i + 1) % 5 == 0)

⌨️ 快捷键说明

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