📄 memory_management.cpp
字号:
#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 + -