LINUX实 *** :SylixOS 定长内存管理

LINUX实 *** :SylixOS 定长内存管理,第1张

概述介绍《LINUX实 *** :SylixOS 定长内存管理》开发教程,希望对您有用。

《liNUX实 *** :SylixOS 定长内存管理》要点:
本文介绍了liNUX实 *** :SylixOS 定长内存管理,希望对您有用。如果有疑问,可以联系我们。

所谓定长内存,指的是用户每次分配获得的内存年夜小是相同的,即使用的是有确定长度的内存块.同时,这些内存块总的个数也是确定的,即整个内存总的年夜小也是确定的.这和通常理解的内存池的概念是一样的.

使用定长内存管理的内存,有两大长处:一是由于事先已经分配好了足够的内存,可极大提高关键应用的稳定性;二是对于定长内存的管理通常有更为简单的算法,分配/释放的效率更高.在 SylixOS 中,将管理的一个定长内存称作 PARTITION,即内存分区.

2. 定长内存管理设置

SylixOS可以通过API *** 作实现定长内存管理功效.

2.1      创立内存分区

#include<SylixOS.h>

LW_OBJECT_HANDLE  Lw_Partition_Create(CPCHAR            pcname,

                                          PVOID              pvLowAddr,

                                          ulONG              ulBlockCounter,

                                          size_t            stBlockByteSize,

                                         ulONG              ulOption,

                                          LW_OBJECT_ID      *pulID)

函数Lw_Partition_Create 原型阐发:

1.此函数成功时返回一个内存分区句柄,失败时返回LW_HANDLE_INVALID并设置差错号;

2.参数pcname指定该内存分区的名称,可以为LW_NulL(最年夜字长为32字节);

3.参数pvLowAddr为用户定义的一片内存的低地址,即起始地址.该地址必需满足一个cpu字长的对齐,如在32位系统中,该地址必需4字节对齐;

4.参数 ulBlockCounter 为该内存分区的定长内存块数目;

5.参数 stBlockByteSize 为内存块的大小,必需不小于一个指针的长度,在32位系统中为4字节;

6.参数ulOption为创立内存分区的选项,如 2-1所示.

2-1  内存分区创立选项

7.输出参数 pulID 保留该内存分区的 ID,与返回值相同.可以为 LW_NulL.

 

注:驱动程序或内核模块才能使用LW_OPTION_OBJECT_GLOBAL 选项,对应的LW_OPTION_OBJECT_LOCAL 选项用于应用程序.为了使应用程序有更好的兼容性,建议使用LW_OPTION_DEFAulT选项,该选项包括了 LW_OPTION_OBJECT_LOCAL 的属性.

SylixOSLw_Partition_Create把已分配好的一块大内存(pvLowAddr)通过一个PARTITION控制块进行管理,PARTITION控制块内容如法式清单 2-1所示.

法式清单2-1  PARTITION控制块

/淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱*

  PARTITION 节制块

淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱淫乱*/

typedefstruct {

    LW_List_MONO        PARTITION_monoresrcList;         /*  余暇资源表             */

    UINT8                PARTITION_ucType;                /*  类型标记               */

    PLW_List_MONO        PARTITION_pmonoFreeBlockList/*  余暇内存块表           */

    size_t              PARTITION_stBlockByteSize;      /*  每一块的年夜小           */

                                                             /*  必需大于 sizeof(PVOID)*/

    ulONG                PARTITION_ulBlockCounter;        /*  块数目                 */

    ulONG                PARTITION_ulFreeBlockCounter;    /*  余暇块数量             */

    UINT16              PARTITION_usIndex;                /*  缓冲区索引            */ 

    CHAR                PARTITION_cPatitionname[LW_CFG_OBJECT_name_SIZE];

                                                             /*  名字                  */

    LW_SPINLOCK_define  (PARTITION_sllock);             /*  自旋锁                */

} LW_CLASS_PARTITION;

Lw_Partition_Create对特定内存管理好后,会返回一个LW_OBJECT_HANDLE句柄.之后用户必要对这块内存进行获取、释放和删除等,都可以通过这个句柄进行 *** 作.

2.2      获取/返还内存块

PVOID  Lw_Partition_Get (LW_OBJECT_HANDLE  ulID)

PVOID  Lw_Partition_Put (LW_OBJECT_HANDLE  ulID,PVOID  pvBlock)

调用 Lw_Partition_Get 函数可以获得一个内存分区的内存块,其大小为创立内存分区时指定的大小,调用Lw_Partition_Put 函数将获得的内存块(Lw_Partition_Get 函数获得)返回给内存分区.

注:如果pvBlockNulL,则设置差错号为 ERROR_PARTITION_NulL.

2.3      删除内存分区

ulONG  Lw_Partition_Delete (LW_OBJECT_HANDLE  *pulID)

ulONG  Lw_Partition_DeleteEx (LW_OBJECT_HANDLE  *pulID,BOol  bForce)

如果一个内存分区中有内存块还在被使用,则理论上不该该立刻被删除.如果bForce LW_TRUE,则 Lw_Partition_DeleteEx 忽略该条件直接删除该分区.通常情况下应用程序不该该使用该方式,这可能会导致内存错误.建议一般情况下使用 Lw_Partition_Delete 函数,它相当于下面调用,这样避免释放还在使用的内存.

Lw_Partition_DeleteEx(pulID,LW_FALSE);

3. 定长内存管理使用

好比程序需要创建一个链表,可以使用定长内存管理.如程序清单 3-1所示.

法式清单 3-1  法式代码

#include<stdio.h>

#include<SylixOS.h>

 

typedefstruct my_element {

    INTiValue;

} MY_ELEMENET;

 

#define   ELEMENT_MAX (8)

 

/*

 * _G_pucMyElementPool 的地址不满足布局体 MY_ELEMENT 的对齐需求时,在有些硬件上,

 * 拜访成员变量 iValue 将产生多字节不对齐拜访的错误(典型的硬件平台如 ARM).

* 应该将_G_pucMyElementPool 的类型定义为UINT8,即单字节拜访,逻辑上它的起始地址可以是任  * 何对齐值.

 */

MY_ELEMENET_G_pmyelement[ELEMENT_MAX];

LW_STACK    _G_pucMyElementPool[sizeof(MY_ELEMENET) * ELEMENT_MAX /

                                   sizeof(LW_STACK)];        /*  申请一段内存空间    */

LW_HANDLE   _G_hMyPartition;                               /*  内存治理句柄         */                         

 

intmain(intargc,char *argv[])

{

    MY_ELEMENET *peletable[ELEMENT_MAX]   = { LW_NulL };

    MY_ELEMENET *peleTmp                  = NulL;

    ulONG        ulError;

    INT          i                       = 0;

 

    _G_hMyPartition = Lw_Partition_Create("my_partition",_G_pucMyElementPool,

                                          ELEMENT_MAX,sizeof(MY_ELEMENET),

                                                LW_OPTION_DEFAulT,

                                                LW_NulL);

    if (_G_hMyPartition == LW_HANDLE_INVALID) {

        fprintf(stderr,"create partition Failed.\n");

        return (-1);

    }

    /*

     * 最多能够得到多少个元素内存

     */

    while (1) {

        peleTmp = (MY_ELEMENET *) Lw_Partition_Get(_G_hMyPartition);

        if (peleTmp != LW_NulL) {

            peletable[i] = peleTmp;

            peleTmp->iValue = i;

            fprintf(stdout,"get element successfully,count = %d.\n",i);

        } else {

            fprintf(stderr,"get element Failed,i);

            break;

        }

        i++;

    }

    /*

     * 在没有全部回收元素内存的环境下删除内存分区

     */

ulError = Lw_Partition_Delete(&_G_hMyPartition); /*无法删除还有未收受接管所有内存*/

    if (ulError != ERROR_NONE) {

        fprintf(stderr,"delete partition error.\n");

    } else {

        return (0);

    }

    /*

     * 收受接管内存块返回给内存分区

     */

    for (i = 0; i < ELEMENT_MAX; i++) {

        peleTmp = peletable[i];

        if (peleTmp != LW_NulL) {

            fprintf(stdout,"element%d value = %d.\n",i,peleTmp->iValue);

            peleTmp = Lw_Partition_Put(_G_hMyPartition,peleTmp);

            if (peleTmp != LW_NulL) {

                fprintf(stderr,"element%d put Failed.\n",i);

            }

        } else {

            break;

        }

    }

    /*

     * 全部收受接管元素内存后删除内存分区

     */

    ulError = Lw_Partition_Delete(&_G_hMyPartition); /*   可以删除内存分区          */

    if (ulError != ERROR_NONE) {

        fprintf(stderr,"delete partition error.\n");

        return (-1);

    } else {

        fprintf(stderr,"delete partition successfully.\n");

    }

    return (0);

}

内存分区不直接分配内存,它只是提供了一个管理内存的办法.因此在创建内存分区时,需要指定需要管理的内存,该内存由使用的元素(即上面所述的内存块)大小以及元素的最大个数决定.在程序清单 31中,创建了一个最大可以容纳 8 个类型为MY_ELEMENT 对象的内存分区,然后通过获取元素对象、使用元素对象以及删除内存分区三方面展示了SylixOS 内存分区的使用.该程序运行后,结果如下所示: 3-1所示.

3-1  程序运行成果

从运行结果可以看出,最大元素个数为8个,因此第9次获取元素时会失败.随后使用Lw_Partition_Delete函数删除内存分区,由于此时元素还未被回收,因此删除失败.当回收完全部的元素后,能力成功删除.

本文永远更新链接地址

内存溢出PHP培训学院每天发布《liNUX实 *** :SylixOS 定长内存管理》等实战技能,PHP、MysqL、liNUX、APP、Js,CSS全面培养人才。

总结

以上是内存溢出为你收集整理的LINUX实 *** :SylixOS 定长内存管理全部内容,希望文章能够帮你解决LINUX实 *** :SylixOS 定长内存管理所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/1041718.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存