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中物理内存分配算法的更多相关文章

  1. Java实现操作系统中四种动态内存分配算法:BF+NF+WF+FF

    1 概述 本文是利用Java实现操作系统中的四种动态内存分配方式 ,分别是: BF NF WF FF 分两部分,第一部分是介绍四种分配方式的概念以及例子,第二部分是代码实现以及讲解. 2 四种分配方式 ...

  2. Buddy内存分配算法

    Buddy(伙伴的定义): 这里给出伙伴的概念,满足以下三个条件的称为伙伴:1)两个块大小相同:2)两个块地址连续:3)两个块必须是同一个大块中分离出来的: Buddy算法的优缺点: 1)尽管伙伴内存 ...

  3. 浅谈PHP5中垃圾回收算法

    原文链接:http://www.cnblogs.com/leoo2sk/archive/2011/02/27/php-gc.html PHP是一门托管型语言,在PHP编程中程序员不需要手工处理内存资源 ...

  4. TLFS 内存分配算法详解

    文章目录 1. DSA 背景介绍 1.1 mmheap 1.2 mmblk 2. TLFS 原理 2.1 存储结构 2.2 内存池初始化 2.3 free 2.4 malloc 参考资料 1. DSA ...

  5. STL笔记(6)标准库:标准库中的排序算法

    STL笔记(6)标准库:标准库中的排序算法 标准库:标准库中的排序算法The Standard Librarian: Sorting in the Standard Library Matthew A ...

  6. C语言中内存分配 (转)

    在任何程序设计环境及语言中,内存管理都十分重要.在目前的计算机系统或嵌入式系统中,内存资源仍然是有限的.因此在程序设计中,有效地管理内存资源是程序员首先考虑的问题. 第1节主要介绍内存管理基本概念,重 ...

  7. 【转】C语言中内存分配

    原文:C语言中内存分配 在任何程序设计环境及语言中,内存管理都十分重要.在目前的计算机系统或嵌入式系统中,内存资源仍然是有限的.因此在程序设计中,有效地管理内存资源是程序员首先考虑的问题. 第1节主要 ...

  8. Java实现内存分配算法 FF(首次适应算法) BF(最佳适应算法)

    一.概述 因为这次os作业对用户在控制台的输入输出有要求,所以我花了挺多的代码来完善控制台的显示. MemoryAlgorithm类里只是和控制台输入输出有关的操作,而对内存的所有逻辑操作都是用Mem ...

  9. C语言中内存分配

     C语言中内存分配   在任何程序设计环境及语言中,内存管理都十分重要.在目前的计算机系统或嵌入式系统中,内存资源仍然是有限的.因此在程序设计中,有效地管理内存资源是程序员首先考虑的问题. 第1节主要 ...

  10. 【旧文章搬运】Windows句柄分配算法(二)

    原文发表于百度空间,2009-04-04========================================================================== 在创建句柄 ...

随机推荐

  1. 实现无限存储:基于JuiceFS 创建 Samba 和 NFS 共享

    随着企业数据量的持续增长,存储容量需求日益增大.如何采用没有容量上限的云存储替换本容量有限的本地磁盘,已成为广泛的需求和共识.特别是在企业中常用的 Samba 和 NFS 共享,如果能够使用云存储作为 ...

  2. [db2]数据库管理

    前言 db2版本:10.5 实例所有者:db2inst1 待新建数据库:ticm,授权用户:ticm/123456.(用户是系统用户) 创建数据库 建库 # create database ticm: ...

  3. IDApython练习1-脚本去花

    IDApython练习1-脚本去花 这里主要是练习IDApython脚本去花 1 这里 jz跳转条件是zf=1, jnz跳转条件是zf=0, 但是zf就2种可能,所以无论如何都会跳转到loc_411D ...

  4. 用ChatGPT三分钟免费做出数字人视频- 提升自媒体魅力

    本教程收集于:AIGC从入门到精通教程汇总 操作指引 ChatGPT产生文案=>腾讯智影数字人播报=>粘贴文案=>导出视频. 说明:部分资源只有会员才能用~,非会员可生成5分钟视频. ...

  5. 弹性数据库连接池探活策略调研(二)——Druid

    前言 在上一篇文章中,我们介绍了弹性数据库连接失效的背景,并探讨了HikariCP连接池探活策略的相关内容.在本文中,我们将会继续探讨另一个线上常用的连接池--Druid,并为您介绍如何在使用Drui ...

  6. 正则表达式快速入门一:正则表达式(regex)基本语法及概念

    Regex quickstart :正则表达式快速入门 author: wclsn reference quick start 如果想要了解正则表达式的基本概念且英文ok的话,完全可以从我上面所附网站 ...

  7. KRPANO资源分析工具下载720YUN全景图

    提示:目前分析工具中的全景图下载功能将被极速全景图下载大师替代,相比分析工具,极速全景图下载大师支持更多的网站(包括各类KRPano全景网站,和百度街景) 详细可以查看如下的链接: 极速全景图下载大师 ...

  8. 图解 LeetCode 算法汇总——双指针

    双指针算法是一种比较常用于搜索链表或数组相关的问题,很多算法的基本的解题思路就是使用暴力搜索法.而双指针是对暴力搜索的一种优化,通过双指针可以减少数据的遍历次数.通常双指针是有两个指针,叫做 ligh ...

  9. 用Rust手把手编写一个Proxy(代理), 动工

    用Rust手把手编写一个Proxy(代理), 动工 项目 ++wmproxy++ gitee 传送门 github 传送门 设计流程图 flowchart LR A[客户端] -->|Http| ...

  10. 织梦dede邮箱发信配置教程

    环境要求 主机465端口是开启和放行的 php扩展openssl是开启的 php扩展sockets是开启的 1.QQ邮箱或者163邮箱.126邮箱,开启SMTP服务,拿到授权码,根据自己的来 QQ邮箱 ...