首页 > 系统相关 >Proj4:改进LiteOS中物理内存分配算法

Proj4:改进LiteOS中物理内存分配算法

时间:2023-11-27 15:45:52浏览次数:50  
标签:__ Proj4 LiteOS MEM allocSize --- 内存 tmpNode pool

Proj4:改进LiteOS中物理内存分配算法

实验目的

掌握LiteOS系统调用的自定义方法

实验环境

Ubantu和IMX6ULL mini

实验内容

(从代码角度详细描述实验的步骤和过程)

原先代码:

 1 /*
 2 
 3  * Description : find suitable free block use "best fit" algorithm
 4 
 5  * Input       : pool      --- Pointer to memory pool
 6 
 7  *               allocSize --- Size of memory in bytes which note need allocate
 8 
 9  * Return      : NULL      --- no suitable block found
10 
11  *               tmpNode   --- pointer a suitable free block
12 
13  */
14 
15 STATIC INLINE LosMemDynNode *OsMemFindSuitableFreeBlock(VOID *pool, UINT32 allocSize)
16 
17 {
18 
19     LOS_DL_LIST *listNodeHead = NULL;
20 
21     LosMemDynNode *tmpNode = NULL;
22 
23     UINT32 maxCount = (LOS_MemPoolSizeGet(pool) / allocSize) << 1;
24 
25     UINT32 count;
26 
27 #ifdef LOSCFG_MEM_HEAD_BACKUP
28 
29     UINT32 ret = LOS_OK;
30 
31 #endif
32 
33     for (listNodeHead = OS_MEM_HEAD(pool, allocSize); listNodeHead != NULL;
34 
35          listNodeHead = OsDLnkNextMultiHead(OS_MEM_HEAD_ADDR(pool), listNodeHead)) {
36 
37         count = 0;
38 
39         LOS_DL_LIST_FOR_EACH_ENTRY(tmpNode, listNodeHead, LosMemDynNode, selfNode.freeNodeInfo) {
40 
41             if (count++ >= maxCount) {
42 
43                 PRINT_ERR("[%s:%d]node: execute too much time\n", __FUNCTION__, __LINE__);
44 
45                 break;
46 
47             }
48 
49 #ifdef LOSCFG_MEM_HEAD_BACKUP
50 
51             if (!OsMemChecksumVerify(&tmpNode->selfNode)) {
52 
53                 PRINT_ERR("[%s]: the node information of current node is bad !!\n", __FUNCTION__);
54 
55                 OsMemDispCtlNode(&tmpNode->selfNode);
56 
57                 ret = OsMemBackupRestore(pool, tmpNode);
58 
59             }
60 
61             if (ret != LOS_OK) {
62 
63                 break;
64 
65             }
66 
67 #endif
68 
69             if (((UINTPTR)tmpNode & (OS_MEM_ALIGN_SIZE - 1)) != 0) {
70 
71                 LOS_Panic("[%s:%d]Mem node data error:OS_MEM_HEAD_ADDR(pool)=%p, listNodeHead:%p,"
72 
73                           "allocSize=%u, tmpNode=%p\n",
74 
75                           __FUNCTION__, __LINE__, OS_MEM_HEAD_ADDR(pool), listNodeHead, allocSize, tmpNode);
76 
77                 break;
78 
79             }
80 
81             if (tmpNode->selfNode.sizeAndFlag >= allocSize) {
82 
83                 return tmpNode;
84 
85             }
86 
87         }
88 
89     }
90 
91     return NULL;
92 
93 }

 


修改后的代码:

/*

 * Description : find suitable free block use "best fit" algorithm

 * Input       : pool      --- Pointer to memory pool

 *               allocSize --- Size of memory in bytes which note need allocate

 * Return      : NULL      --- no suitable block found

 *               tmpNode   --- pointer a suitable free block

 */

STATIC INLINE LosMemDynNode *OsMemFindSuitableFreeBlock(VOID *pool, UINT32 allocSize)

{

    LOS_DL_LIST *listNodeHead = NULL;

    LosMemDynNode *tmpNode = NULL;

    UINT32 maxCount = (LOS_MemPoolSizeGet(pool) / allocSize) << 1;

    UINT32 count;

#ifdef LOSCFG_MEM_HEAD_BACKUP

    UINT32 ret = LOS_OK;

#endif//I have updated the listNodeHead so that we can have a better performence in time,but also waste some space

    for (listNodeHead = OsDLnkNextMultiHead(OS_MEM_HEAD_ADDR(pool), OS_MEM_HEAD(pool, allocSize))==NULL?OS_MEM_HEAD(pool, allocSize):OsDLnkNextMultiHead(OS_MEM_HEAD_ADDR(pool), OS_MEM_HEAD(pool, allocSize));

    listNodeHead != NULL;

         listNodeHead = OsDLnkNextMultiHead(OS_MEM_HEAD_ADDR(pool), listNodeHead)) {

        count = 0;

        LOS_DL_LIST_FOR_EACH_ENTRY(tmpNode, listNodeHead, LosMemDynNode, selfNode.freeNodeInfo) {

            if (count++ >= maxCount) {

                PRINT_ERR("[%s:%d]node: execute too much time\n", __FUNCTION__, __LINE__);

                break;

            }

#ifdef LOSCFG_MEM_HEAD_BACKUP

            if (!OsMemChecksumVerify(&tmpNode->selfNode)) {

                PRINT_ERR("[%s]: the node information of current node is bad !!\n", __FUNCTION__);

                OsMemDispCtlNode(&tmpNode->selfNode);

                ret = OsMemBackupRestore(pool, tmpNode);

            }

            if (ret != LOS_OK) {

                break;

            }

#endif

            if (((UINTPTR)tmpNode & (OS_MEM_ALIGN_SIZE - 1)) != 0) {

                LOS_Panic("[%s:%d]Mem node data error:OS_MEM_HEAD_ADDR(pool)=%p, listNodeHead:%p,"

                          "allocSize=%u, tmpNode=%p\n",

                          __FUNCTION__, __LINE__, OS_MEM_HEAD_ADDR(pool), listNodeHead, allocSize, tmpNode);

                break;

            }

            if (tmpNode->selfNode.sizeAndFlag >= allocSize) {

                return tmpNode;

            }

        }

    }

    return NULL;

}

 


主要修改了这一块:

原理如下:

  1. 起初对这个代码与它的注释挺疑惑的,best-fit是在我们可以分配的空闲块中找到一个最适合目前申请内存的空间,并且我们申请内存后(还有剩余时,还会分割)
  2. 但是函数代码逻辑上是直接找到就返回,而按道理我们应该是需要遍历所有空闲块的,但是没有,那么答案就很可能是空闲块是从小到大有序排放的(某种数据结构)
  3. 于是把他for循环起始位置+1,自然可以优化时间复杂度(相当于跳过这个目前最小的空闲块,这么改不会有损代码健壮性(如果直接+1的话,是不可行的,因为它的数据结构是链表(不连续存储),然后我写的复杂了点,主要是为了防止我们这个最小空间在能够使用的情况下永远不会去使用到),for里的判断条件排除了我们这么改有问题的可能))

实验结果

把best-fit算法改为good-fit算法

实验分析

  • 测试了以往的算法,发现可用
  • 相比以往算法实现,时间复杂度上有所优势

参考文献

Ppt

LiteOS内核源码分析:动态内存之Bestfit分配算法 - 知乎 (zhihu.com)

网课

附录

 

标签:__,Proj4,LiteOS,MEM,allocSize,---,内存,tmpNode,pool
From: https://www.cnblogs.com/seamount3/p/17859497.html

相关文章

  • 共享内存的创建和映射过程
    消息队列、共享内存、信号量的机制:它们在使用之前都要生成key,然后通过key得到唯一的id,并且都是通过xxxget函数。在内核里面,这三种进程间通信机制是使用统一的机制管理起来的,都叫ipcxxx。为了维护这三种进程间通信进制,在内核里面,我们声明了一个有三项的数组。通过这段代码,来......
  • 分区内存管理分区选择法
    注意:上图是我的解答,下面的图不是的。我在阅读教材后,对三种分区选择法有了一定的了解,作出了如下解答:但我又有一个疑惑:一个分区只能放一个程序吗?于是我上网查询,并浏览到这篇文章,学习其中的例题后,我认为只要内存空间足够,一个分区就能放多个程序。并作出了最开始那张图片的解答。......
  • curl 中减少内存分配操作
    今天我在libcurl内部又做了一个小改动[1],使其做更少的malloc。这一次,泛型链表函数被转换成更少的malloc(这才是链表函数应有的方式,真的)。研究malloc几周前我开始研究内存分配。这很容易,因为多年前我们curl中就已经有内存调试和日志记录系统了。使用curl的调试版本,并......
  • 自定义的结构的内存问题-字节对齐
    字节对齐在写结构体时养成习惯,一定要按内存从小到大写,要不然在创建结构体的时候会导致创建的结构体明显的大。因为每创建一个结构体时,内存都需要对齐。一般都是1,4,8的整数倍//字符对齐时,字符可以和整数在一起,字符数组可以任意拆分。structA{ chara; //1+3 intb; //......
  • python 打印当前函数的内存地址
    Python打印当前函数的内存地址在Python中,函数也是对象。每个函数对象在内存中都有一个唯一的地址。如果我们想要获取当前函数的内存地址,可以使用id()函数。本文将介绍如何在Python中打印当前函数的内存地址,并提供相应的代码示例。函数是对象在Python中,函数是一种特殊的对象。它......
  • 【转】32位程序使用大内存
    原文:对.NET程序2G虚拟地址紧张崩溃的最后一次反思-一线码农-博客园(cnblogs.com)https://www.cnblogs.com/huangxincheng/p/17853851.html 第1步:使用 DnSpy工具修改exe的文件头 LargeAddressAware 第2步:开始操作系统的支持 一:背景1.讲故事最近接连遇到了......
  • C语言【自定义数据类型、typedef、动态内存分配】
    C语言【自定义数据类型、typedef、动态内存分配】一、自定义数据类型。​ 关于下面讲到的所有自定义数据类型(enum、struct、union),有一点要说的是:定义类型不是声明变量,做这步操作时不分配内存,也不能在定义类型时赋值(枚举那个不是赋值,是做一个限定,赋值时赋限定之外的值也不报错。)......
  • 3.2 Windows驱动开发:内核CR3切换读写内存
    CR3是一种控制寄存器,它是CPU中的一个专用寄存器,用于存储当前进程的页目录表的物理地址。在x86体系结构中,虚拟地址的翻译过程需要借助页表来完成。页表是由页目录表和页表组成的,页目录表存储了页表的物理地址,而页表存储了实际的物理页框地址。因此,页目录表的物理地址是虚拟地址翻译......
  • java 关于 Finalizer 过多导致内存(Res)缓慢上涨
     病因:事情的起因是由Flume的项目采集问题引发的.测试人员发现用top命令查看采集进程的Res一直不断上涨姿势.所以怀疑是内存泄漏.  一,对症下药首先,第一步肯定是先瞅瞅代码,看看有没有那些资源啥的没关闭,正如读者所想----没有发现.二,通过辅助工具最......
  • JVM 内存分析工具 MAT 的深度讲解与实践
     1.MAT工具简介MAT(全名:MemoryAnalyzerTool),是一款快速便捷且功能强大丰富的JVM堆内存离线分析工具。其通过展现JVM异常时所记录的运行时堆转储快照(Heapdump)状态(正常运行时也可以做堆转储分析),帮助定位内存泄漏问题或优化大内存消耗逻辑。1.1MAT使用场景及主要解决问......