【uTenux实验】内存池管理(固定内存池和可变内存池)

【uTenux实验】内存池管理(固定内存池和可变内存池)

1、固定内存池管理实验

内存管理是操作系统的一个基础功能。uTenux的内存池管理函数提供了基于软件的内存池管理和内存块分配管理。uTenux的内存池有固定大小的内存池和大小可变的内存池之分,它们被看成是互相独立的对象,需要不同的系统调用集来进行操作。

内存池管理函数管理的内存全部包含在系统空间以内。

1、固定尺寸内存池实验

固定尺寸内存池是一个用来动态管理固定尺寸内存块的对象。每个固定尺寸内存池都有一个用作固定尺寸内存池的内存空间(简称为内存池区)和一个等待内存块分配的任务队列。

uTenux提供了五个供操作固定内存池的API,分别用于创建、删除、获取、释放、查询内存池状态。

创建固定尺寸内存池,需要提供一个T_CMPF类型的结构体。定义如下:

typedef struct t_cmpf {VPexinf;ATRmpfatr;Wmpfcnt;Wblfsz;UBdsname[VPbufptr;} T_CMPF;

内存池属性mpfatr是的定义如下:

mpfatr:=(TA_TFIFO||TA_TPRI)|TA_USERBUF|TA_DSNAME|(TA_RNG0||TA_RNG1 ||TA_RNG2||TA_RNG3)

TA_TFIFO 等待内存分配的任务按FIFO的顺序排队

TA_TPRI 等待内存分配的任务按优先级顺序排队

TA_RNGn 内存访问权设置成保护级别n

TA_USERBUF 指示系统使用用户指定的内存空间

TA_DSNAME 设定DS对象名

由于uTenux没有使用硬件的内存保护功能,服务器空间,TA_RNGn 只能是TA_RNG0。TA_USERBUF是不使用OS提供的内存空间时候使用的。TA_DSNAME基本没什么用。

获取内存池函数:ER ercd= tk_get_mpf(ID mpfid,VP *p_blf,TMO tmout);中,p_blf为获取的内存块的起始地址。为VP类型,即一个void*的指针。使用时需要注意。

【实验描述】

1、创建两个任务一个包含5块区域的内存池。

2、启动TaskB,在TaskB中启动TaskA,TaskA开始执行就立即休眠。等待TaskB唤醒

3、TaskB继续执行。先输出当前可用内存块数目,申请一块内存后再次输出内存块数目。

4、最后将一段数据放入这块内存。之后唤醒TaskA。

5、TaskA输出由TaskB放入内存块的数据之后,释放内存块。再次输出可用内存块数。。然后进入休眠状态,TaskB继续执行。

【代码及输出】

固定内存池使用:

#include MpfSampleTaskA(W stacd,VP exinf);void MpfSampleTaskB(W stacd,VP exinf);void MpfSamplePutCnt(void);static ID TaskID_A;static ID TaskID_B;static ID mpfid;static VP blf=NULL;ER MpfSample( void){ER ercd = E_OK;T_CTSK ctsk;T_CMPF cmpf;tm_putstring((UB*));ctsk.exinf = (VP)NULL;ctsk.tskatr = TA_HLNG | TA_RNG0;ctsk.task = MpfSampleTaskA;ctsk.itskpri = 24;ctsk.stksz = 512;TaskID_A = tk_cre_tsk(&ctsk);if(TaskID_A < E_OK) {ercd=TaskID_A;return ercd;}tm_putstring((UB*));ctsk.task = MpfSampleTaskB;ctsk.itskpri = 26;TaskID_B = tk_cre_tsk(&ctsk);if(TaskID_B < E_OK) {ercd=TaskID_B;return ercd;}tm_putstring((UB*));cmpf.bufptr = NULL;cmpf.exinf = (VP)NULL;cmpf.blfsz = 100; //100Bytecmpf.mpfcnt = 5; //5块cmpf.mpfatr = TA_TFIFO | TA_RNG0; //内存池属性,先到先得 不使用保护mpfid = tk_cre_mpf(&cmpf);tm_putstring((UB*));MpfSamplePutCnt();tm_putstring((UB*));tk_sta_tsk(TaskID_B,0);return TRUE;}void MpfSampleTaskA(W stacd,VP exinf){ tm_putstring((UB*)); tk_slp_tsk(-1); while(1) {tm_putstring((UB*));tm_putstring((UB*)blf);tk_rel_mpf(mpfid,blf);MpfSamplePutCnt();tk_slp_tsk(-1); }}void MpfSampleTaskB(W stacd,VP exinf){ B* buf = ; B blfadd[10]; tm_putstring((UB*)); tk_sta_tsk(TaskID_A,0); tm_putstring((UB*)); while(1) {MpfSamplePutCnt();tm_putstring((UB*));if(E_OK == tk_get_mpf(mpfid,&blf,-1)) //申请内存块 {MpfSamplePutCnt();tm_putstring((UB*));ltostr((UW)blf,blfadd,16,10);tm_putstring((UB*)blfadd); //以字符串形式输出地址tm_putstring((UB*));memcpy(blf,buf,strlen(buf)+1);}else{tm_putstring((UB*));break;}tm_putstring((UB*));tk_wup_tsk(TaskID_A);Delay(0x1000000); }}void MpfSamplePutCnt(void){B frbcnt[10];T_RMPF rmpf;tm_putstring((UB*));tk_ref_mpf(mpfid, &rmpf);ltostr(rmpf.frbcnt,frbcnt,10,10);tm_putstring((UB*)frbcnt);tm_putstring((UB*));}

输出:

与其临渊羡鱼,不如退而结网。

【uTenux实验】内存池管理(固定内存池和可变内存池)

相关文章:

你感兴趣的文章:

标签云: