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. [golang]获取本机IP

    前言 方便在内网环境中获取服务器本机IP,省了在脚本中过滤ip或ifconfig的结果. 如果内网中有nginx的话,通过nginx获取本机IP也很方便,可参考 借助nginx自动获取本机IP 示例代 ...

  2. 深入理解 Flutter 图片加载原理

    前言 随着Flutter稳定版本逐步迭代更新,京东APP内部的Flutter业务也日益增多,Flutter开发为我们提供了高效的开发环境.优秀的跨平台适配.丰富的功能组件及动画.接近原生的交互体验,但 ...

  3. Codeforces 1463D Pairs

    题意 对于数字\(1\)~\(2n\),可以构造出\(n\)个二元组,对于\(n\)个二元组,选择一个数组\(x\),留下\(x\)个二元组的最小值,留下\(n-x\)个二元组的最大值,其构成了一个集 ...

  4. nginx Ingress Controller Packaged by Bitnami

    环境介绍 节点 master01 work01 work02 主机/ip calico-master01/192.168.195.135 calico-master01/192.168.195.135 ...

  5. Pisces.IM.Mood 前言

    关于 Pisces.IM.Mood Mood Pisces.IM.Mood 一款基于TCP协议的即时通讯开源系统 多个客户端目前支持以下功能: 支持文字,图片,文件,emoji表情的发送 文件限制为5 ...

  6. Oracle:Ora-01652无法通过128(在temp表空间中)扩展temp段的过程-解决步骤

    现象:查询select * from v$sql时提示"Ora-01652无法通过128(在temp表空间中)扩展temp段的过程" 临时文件是不存储的,可以将数据库重启,重启后重 ...

  7. SSM(Spring+SpringMVC+MyBatis)框架集成

    引言 进行SSM(Spring+SpringMVC+MyBatis)集成的主要原因是为了提高开发效率和代码可维护性.SSM是一套非常流行的Java Web开发框架,它集成了Spring框架.Sprin ...

  8. 其它——Apache-ab压力测试工具使用

    文章目录 一 介绍 二 安装 2.1 windows安装 2.2 Linux安装 三 使用 四 参数介绍 一 介绍 Apache Benchmark(简称ab) 是Apache安装包中自带的压力测试工 ...

  9. Django-rest-framework框架——过滤排序分页异常处理、自动生成接口文档、JWT认证

    @ 目录 一 过滤Filtering 二 排序 三 分页Pagination 可选分页器 应用 四 异常处理 Exceptions 4.1 使用方式 4.2 案例 4.3 REST framework ...

  10. 2023_10_10_MYSQL_DAY_02_课后题

    2023_10_10_MYSQL_DAY_02_课后题 #06章1--7题 #1. 查询10号部门所有员工的员工姓名,员工工资,工资级别. SELECT e.ename 员工姓名,e.`sal` 员工 ...