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. Qt+GDAL开发笔记(二):在windows系统msvc207x64编译GDAL库、搭建开发环境和基础Demo

    前言   上一篇使用mingw32版本的gdal,过程曲折,为更好的更方便搭建环境,在windows上msvc方式对于库比较友好.   大地坐标简介 概述   大地坐标(Geodetic coordi ...

  2. 事务,不只ACID

    1. 什么是事务? 应用在运行时可能会发生数据库.硬件的故障,应用与数据库的网络连接断开或多个客户端端并发修改数据导致预期之外的数据覆盖问题,为了提高应用的可靠性和数据的一致性,事务应运而生. 从概念 ...

  3. VMware中的虚拟机Debian10的服务器配置,使主机(win10)能够通过本地域名(如www.xxx.com)访问该服务器

    VMware中的虚拟机Debian10的服务器配置,使主机(win10)能够通过本地域名(如www.xxx.com)访问该服务器 安装过程 下载debian-10.13.0-amd64-DVD-1.i ...

  4. Stable Diffusion基础:ControlNet之图片风格迁移

    今天继续给大家分享AI绘画中 ControlNet 的强大功能,本次的主角是 Reference,它可以将参照图片的风格迁移到新生成的图片中,这句话理解起来很困难,我们将通过几个实例来加深体会,比如照 ...

  5. Anaconda+PyCharm+Pytorch/tensorflow环境配置个人总结

    Anaconda是一个非常方便的python版本管理工具,可以很方便地切换不同版本的Python进行测试.同时不同版本之间也不存在相互的干扰. PyCharm是一款常见的Python IDE,pyto ...

  6. 抢先体验!超强的 Anchor Positioning 锚点定位

    本文,将向大家介绍 CSS 规范中,最新的 Anchor Positioning,翻译为锚点定位. Anchor Position 的出现,极大的丰富了 CSS 的能力,虽然语法稍显复杂,但是有了它, ...

  7. [ABC305C] Snuke the Cookie Picker题解

    题目大意 有一个 \(H\times W\) 的网格,一种有一个矩形,矩形中间有一个点被挖空,求这个点的坐标.(. 表示空白,# 表示矩形内的点) 解析 观察我们可以发现,每一矩形内的个点上下左右至少 ...

  8. Java爬虫实战系列——常用的Java网络爬虫库

    常用的Java网络爬虫库 Java 开发语言是业界使用最广泛的开发语言之一,在互联网从业者中具有广泛的使用者,Java 网络爬虫可以帮助 Java 开发人员以快速.简单但广泛的方式为各种目的抓取数据. ...

  9. 商品详情api接口的应用方向有哪些?

    ​ 商品详情API接口的应用方向非常广泛,可以应用于以下领域: 电子商务平台:商品详情API接口可以提供商品的基本信息,如名称.描述.价格.图片等,帮助电子商务平台展示和推荐商品.此外,还可以提供商品 ...

  10. 银河麒麟使用kickstart二次打包制作安装镜像ISO

    系统:银河麒麟 V10 SP2 服务器:百信恒山 TS02F-F30 安装方式:服务器挂载ISO镜像进行安装 1.安装 mkisofs 软件包: #yum install genisoimage 2. ...