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. Android-JAR包的引用

    一.JAR的定义     JAR文件(Java归档,英语:Java Archive)是一种软件包文件格式,以ZIP格式构建,以.jar为文件扩展名,通常用于聚合大量的Java类文件.相关的元数据和资源 ...

  2. 重要变更 | Hugging Face Hub 的 Git 操作不再支持使用密码验证

    在 Hugging Face,我们一直致力于提升服务安全性,因此,我们将对通过 Git 与 Hugging Face Hub 交互时的认证方式进行更改.从 2023 年 10 月 1 日 开始,我们将 ...

  3. fastapi启动后访问docs不显示页面的问题

    笔者之前正常使用fastapi的docs接口进行各种接口调试,使用很正常,之前安装也都是正常安装流程,没有做任何修改,可以突然有一天不知道为啥,docs接口打开是空白的,接口也没有报错,就是空白,摸索 ...

  4. chatglm2-6b在P40上做LORA微调

    背景: 目前,大模型的技术应用已经遍地开花.最快的应用方式无非是利用自有垂直领域的数据进行模型微调.chatglm2-6b在国内开源的大模型上,效果比较突出.本文章分享的内容是用chatglm2-6b ...

  5. 响应式编程——初识 Flux 和 Mono

    by emanjusaka from ​ https://www.emanjusaka.top/archives/4 彼岸花开可奈何 本文欢迎分享与聚合,全文转载请留下原文地址. 前言 Reactor ...

  6. [Python] 今天开始学习Python3了, 纪念一下

    #! /usr/bin/env python3 import time print("你好, 请告诉我你的名字.") name = input("名前: ") ...

  7. HTML一键打包APK工具最新版1.9.2更新(附下载地址)

    HMTL网址打包APK,可以把本地HTML项目, Egret游戏,网页游戏,或者网站打包为一个安卓应用APK文件,无需编写任何代码,也无需配置安卓开发环境,支持在最新的安卓设备上安装运行. 打包软件会 ...

  8. 使用C#发送邮件支持 Implicit SSL

    安装Package: Install-Package AIM 使用下面的代码发送: class Mail { private static string mailAddress = "{yo ...

  9. 已发布:Oracle Database 23c 免费版 — 开发人员版!

    注:甲骨文云技术公众号文章备份 2023/04/12. 翻译新闻稿. 1.新发布 Oracle Database 23c 免费版 - 开发人员版 在 Oracle CloudWorld 2022 上, ...

  10. 若依(ruoyi)开源系统-多数据源问题踩坑实录

    内容概要 上一节内容   介绍了用开源系统若依(ruoyi)搭建页面的过程.在实际项目中,经常遇到多数据源后者主从库的情况.本节记录若依多数据源配置过程中遇到的问题排查过程. 背景描述 1.上一节在r ...