ThreadX学习(4)——内存管理

  • 学习参考
  • 内存分配
    • 内存字节池 memory byte pool
      • 字节池大小
      • 碎片整理
      • API
        • 1.tx_byte_pool_create
        • 2.tx_byte_allocate
        • 3.tx_byte_pool_delete
        • 4.tx_byte_pool_info_get
        • 5.tx_byte_pool_prioritize
        • 6.tx_byte_release
    • 内存块池 Memory block pool
      • 优点
      • 缺点
      • 内存块池大小
      • API
        • 1.tx_block_pool_create
        • 2.tx_block_allocate
        • 3.tx_block_pool_delete
        • 4.tx_block_pool_info_get
        • 5.tx_block_pool_prioritize
        • 6.tx_block_release

学习参考

  • 《Real-Time Embedded Multithreading: Using ThreadX and ARM》
    (链接:https://pan.baidu.com/s/1GMScXSlHq13yS4AVxP_zPw 提取码:ysuw )
  • 安富莱_STM32-V7开发板ThreadX内核教程(V0.7)——硬汉嵌入式论坛

内存分配

ThreadX中的内存分配有两种方法:内存字节池内存块池

用户可提前创建内存池,在之后可以随意分配池里的空间。

一般而言,字节块池更能满足用户的各种需求。

由于可能存在内存池空间不足,需要等待被占用空间释放的情况,所以每个内存池也有类似于互斥锁挂起列表的数据结构,即内存池挂起列表

内存字节池 memory byte pool

顾名思义,内存字节池是可用于任何资源的字节的顺序集合。

内存字节池类似于一个标准的C语言堆。与C堆不同,内存字节池的数量没有限制。此外,线程可以挂起在池上,直到请求的内存可用为止。

内存字节池中的分配基于指定的字节数。ThreadX以优先匹配的方式从字节池中分配内存,即使用满足请求的第一个空闲内存块。

字节池大小

内存字节池中可分配的字节数略小于创建期间指定的字节数。这是因为对空闲内存区域的管理引入了一些开销。池中的每个空闲内存块需要相当于两个C指针的开销。

此外,当创建池时,ThreadX会自动将其划分为两个块,一个是大的空闲块,另一个是内存区域末端永久分配的小块。

该分配的末端块用于提高分配算法的性能。它消除了在合并期间不断检查池区域末端的需要。

当分配奇数个字节时,ThreadX填充块以确保下一个内存块的正确对齐。此外,随着池变得更加碎片化,开销也会增加。

碎片整理

来自这个块的多余内存被转换为一个新的块,并放回空闲内存列表中,这通常会导致碎片问题。

在随后的分配搜索(tx_byte_pool_search)中,如果第一个找到的空闲块大小不足,则会向后合并空闲块,若这一段空闲区域全部合并也无法满足大小,则寻找下一个空闲块区域,以获取足够大的空闲内存块。这个过程称为碎片整理。

也就是说,碎片整理过程随着搜索过程进行的。

API

1.tx_byte_pool_create

TX_BYTE_POOL my_pool;//先定义一个内存字节池UINT  tx_byte_pool_create(  TX_BYTE_POOL *pool_ptr, CHAR *name_ptr,  VOID *pool_start, ULONG pool_size)

创建内存字节池:

  • 第 1 个参数 pool_ptr 是内存字节池控制块指针。
  • 第 2 个参数 name_ptr 是字节池名。
  • 第 3 个参数 pool_start 是字节池的首地址。
  • 第 4 个参数 pool_size 是字节池的长度。
  • 返回值:
    • TX_SUCCESS(0x00)成功创建字节池。
    • TX_POOL_ERROR:(0x02)无效的内存池指针。要么指针是NULL,要么池已经创建。
    • TX_PTR_ERROR: (0x03)无效的池起始地址。
    • TX_SIZE_ERROR: (0x05)池大小无效。
    • TX_CALLER_ERROR:(0x13)无效的服务调用者。

2.tx_byte_allocate

UINT  tx_byte_allocate( TX_BYTE_POOL *pool_ptr, VOID **memory_ptr, ULONG memory_size,  ULONG wait_option)

分配内存字节池空间:

  • 第 1 个参数 pool_ptr 是内存字节池控制块指针。
  • 第 2 个参数 memory_ptr 是字节池分配空间首地址的指针。
  • 第 3 个参数 memory_size是字节池分配空间大小。
  • 第 4 个参数 wait_option是字节池分配等待选项:
    • TX_NO_WAIT:不等待,直接返回结果。
    • TX_WAIT_FOREVER:一直等待直到获取字节池空间。
    • timeout value:设置等待时间(时钟脉冲)。
  • 返回值:
    • TX_SUCCESS(0x00)成功分配字节池。
    • TX_DELETED: (0x01)线程挂起时内存池被删除。
    • TX_NO_MEMORY: (0x10) 无法在指定的等待时间内分配内存。
    • TX_WAIT_ABORTED: (0x1A)挂起被另一个线程、计时器或ISR中止。
    • TX_POOL_ERROR:(0x02)无效的内存池指针。
    • TX_PTR_ERROR:(0x03)指向目标指针的指针无效。
    • TX_SIZE_ERROR: (0X05)请求的大小是0或大于池的总大小。
    • TX_WAIT_ERROR: (0x04)在非线程调用时指定了TX_NO_WAIT以外的等待选项。
    • TX_CALLER_ERROR:(0x13)无效的服务调用者。

3.tx_byte_pool_delete

UINT  tx_byte_pool_delete(TX_BYTE_POOL *pool_ptr)

删除内存字节池:

  • 第 1 个参数 pool_ptr 是内存字节池控制块指针。
  • 返回值:
    • TX_SUCCESS(0x00)成功删除字节池。
    • TX_POOL_ERROR:(0x02)无效的内存池指针。
    • TX_CALLER_ERROR:(0x13)无效的服务调用者。

字节池挂起的所有线程都将恢复,并接收TX_DELETED返回状态。

4.tx_byte_pool_info_get

UINT  tx_byte_pool_info_get(TX_BYTE_POOL *pool_ptr, CHAR **name, ULONG *available_bytes, ULONG *fragments, TX_THREAD **first_suspended, ULONG *suspended_count, TX_BYTE_POOL **next_pool)

获取字节池信息:

  • 第 1 个参数 pool_ptr 是内存字节池控制块指针。
  • 第 2 个参数 name 是字节池名字符串,获取后存储的指针。
  • 第 3 个参数 available_bytes 是可用字节数,获取后存储的指针。
  • 第 4 个参数 fragments 是碎片数量,获取后存储的指针。
  • 第 5 个参数 first_suspended 是等待该字节池的第一个线程TCB指针,获取后存储的指针。
  • 第 6 个参数 suspended_count 是等待该字节池的线程数,获取后存储的指针。
  • 第 7 个参数 next_pool 是字节池列表的下一个字节池控制块指针,获取后存储的指针。
  • 返回值:
    • TX_SUCCESS(0x00)成功获取字节池信息。
    • TX_POOL_ERROR:(0x02)无效的内存池指针。

5.tx_byte_pool_prioritize

UINT  tx_byte_pool_prioritize(TX_BYTE_POOL *pool_ptr)

字节池挂起列表的最高优先级线程置队头:

  • 第 1 个参数 pool_ptr 是内存字节池控制块指针。
  • 返回值:
    • TX_SUCCESS(0x00)成功或挂起列表为空。
    • TX_POOL_ERROR:(0x02)无效的内存池指针。

6.tx_byte_release

UINT  tx_byte_release(VOID *memory_ptr)

字节池释放空间:

  • 第 1 个参数 memory_ptr 是要释放的空间首地址。
  • 返回值:
    • TX_SUCCESS(0x00)成功释放。
    • TX_PTR_ERROR:(0x03)无效的内存区域指针。
    • TX_CALLER_ERROR:(0x13)无效的服务调用者。

tx_byte_release将先前分配的内存区域释放,挂起列表按顺序开始分配,直至内存池空间不足或挂起列表为空。

内存块池 Memory block pool

优点

通常,内存块池优于内存字节池,因为可以消除碎片问题,而且对池的分配和释放更快。

内存块池分配和释放时不必搜索块列表,它总是在可用列表的开头分配和释放内存块。

这提供了尽可能快的链表处理,并可能有助于将当前使用的内存块保持在缓存中。

缺点

缺乏灵活性是固定大小内存池的主要缺点。

池的块大小必须足够大,以处理其用户最坏情况下的内存需求。从同一个池中发出许多不同大小的内存请求可能会造成内存浪费。

一种可能的解决方案是创建几个不同的内存块池,其中包含不同大小的内存块。

内存块池大小

内存块池的大小除了每个内存块的大小和之外,还包括每个内存块的指针(一般包括所有者指针和下一个内存块指针)。

内存块数量 = 内存块池总大小 / (每个内存块大小 + 每块的指针大小)

比如一个1000B的内存块池,每个内存块50B,指针4B,那么:

内存块数量 = 1000 / (50 + 4)= 18.52 块

API

1.tx_block_pool_create

TX_BLOCK_POOL my_pool;//先定义一个内存块池UINT  tx_block_pool_create( TX_BLOCK_POOL *pool_ptr, CHAR *name_ptr, ULONG block_size,VOID *pool_start, ULONG pool_size)

创建内存字节池:

  • 第 1 个参数 pool_ptr 是内存块池控制块指针。
  • 第 2 个参数 name_ptr 是内存块池名。
  • 第 3 个参数 block_size 是单个内存块的大小。
  • 第 4 个参数 pool_start 是内存块池的首地址。
  • 第 5 个参数 pool_size 是内存块池的总大小。
  • 返回值:
    • TX_SUCCESS(0x00)成功创建内存块池。
    • TX_POOL_ERROR:(0x02)无效的内存块池指针。要么指针是NULL,要么池已经创建。
    • TX_PTR_ERROR: (0x03)无效的池起始地址。
    • TX_SIZE_ERROR: (0x05)池大小无效。
    • TX_CALLER_ERROR:(0x13)无效的服务调用者。

2.tx_block_allocate

UINT  tx_block_allocate(TX_BLOCK_POOL *pool_ptr, VOID **block_ptr, ULONG wait_option)

分配内存块:

  • 第 1 个参数 pool_ptr 是内存块池控制块指针。
  • 第 2 个参数 block_ptr 是分配得到的内存块首地址的指针,需要提前定义。
  • 第 3 个参数 wait_option 是内存块池分配等待选项:
    • TX_NO_WAIT:不等待,直接返回结果。
    • TX_WAIT_FOREVER:一直等待直到获取内存块。
    • timeout value:设置等待时间(时钟脉冲)。
  • 返回值:
    • TX_SUCCESS(0x00)成功分配。
    • TX_DELETED: (0x01)线程挂起时内存块池被删除。
    • TX_NO_MEMORY: (0x10) 无法在指定的等待时间内分配内存块。
    • TX_WAIT_ABORTED: (0x1A)挂起被另一个线程、定时器或ISR中止。
    • TX_POOL_ERROR:(0x02)无效的内存块池指针。
    • TX_PTR_ERROR:(0x03)无效的分配指针。
    • TX_WAIT_ERROR: (0x04)在非线程调用时指定了TX_NO_WAIT以外的等待选项。

3.tx_block_pool_delete

UINT  tx_block_pool_delete(TX_BLOCK_POOL *pool_ptr)

删除内存块池:

  • 第 1 个参数 pool_ptr 是内存块池控制块指针。
  • 返回值:
    • TX_SUCCESS(0x00)成功删除内存块池。
    • TX_POOL_ERROR:(0x02)无效的内存块池指针。
    • TX_CALLER_ERROR:(0x13)无效的服务调用者。

内存块池挂起的所有线程都将恢复,并接收TX_DELETED返回状态。

4.tx_block_pool_info_get

UINT  tx_block_pool_info_get(   TX_BLOCK_POOL *pool_ptr, CHAR **name, ULONG *available_blocks, ULONG *total_blocks, TX_THREAD **first_suspended, ULONG *suspended_count, TX_BLOCK_POOL **next_pool)

获取内存块池信息:

  • 第 1 个参数 pool_ptr 是内存块池控制块指针。
  • 第 2 个参数 name 是内存块池名字符串,获取后存储的指针。
  • 第 3 个参数 available_blocks 是可用内存块数,获取后存储的指针。
  • 第 4 个参数 total_blocks 是内存块总数,获取后存储的指针。
  • 第 5 个参数 first_suspended 是等待该内存块池的第一个线程TCB指针,获取后存储的指针。
  • 第 6 个参数 suspended_count 是等待该内存块池的线程数,获取后存储的指针。
  • 第 7 个参数 next_pool 是内存块池列表的下一个内存块池控制块指针,获取后存储的指针。
  • 返回值:
    • TX_SUCCESS(0x00)成功获取内存块池信息。
    • TX_POOL_ERROR:(0x02)无效的内存块池指针。

5.tx_block_pool_prioritize

UINT  tx_block_pool_prioritize(TX_BLOCK_POOL *pool_ptr)

内存块池挂起列表的最高优先级线程置队头:

  • 第 1 个参数 pool_ptr 是内存块池控制块指针。
  • 返回值:
    • TX_SUCCESS(0x00)成功或挂起列表为空。
    • TX_POOL_ERROR:(0x02)无效的内存块池指针。

6.tx_block_release

UINT  tx_block_release(VOID *memory_ptr)

内存块释放:

  • 第 1 个参数 memory_ptr 是要释放内存块首地址。
  • 返回值:
    • TX_SUCCESS(0x00)成功释放。
    • TX_PTR_ERROR(0x03)无效的内存块指针。

tx_block_release将先前分配的内存块释放,挂起列表按顺序开始分配,直至可用内存块不足或挂起列表为空。

ThreadX学习(4)——内存管理相关推荐

  1. 深入学习python内存管理

    深入Python的内存管理 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 语言的内存管理是语言设计的一个重要方面.它是决定语言性 ...

  2. python内存管理可以使用del_Python深入学习之内存管理

    语言的内存管理是语言设计的一个重要方面.它是决定语言性能的重要因素.无论是C语言的手工管理,还是Java的垃圾回收,都成为语言最重要的特征.这里以Python语言为例子,说明一门动态类型的.面向对象的 ...

  3. 11.FreeRTOS学习笔记-内存管理

    几种内存分配算法的比较 heap_1.c 管理方案是 FreeRTOS 提供所有内存管理方案中最简单的一个,它只能申请内存而不能进行内存释放,并且申请内存的时间是一个常量 heap_2.c方案支持释放 ...

  4. Box2d源码学习二内存管理之SOA的实现

    本系列博客是由扭曲45原创,欢迎转载,转载时注明出处,http://blog.csdn.net/cg0206/article/details/8258166 SOA,全称small object al ...

  5. Cocos2d-x学习笔记—内存管理机制

    Cocos2d-x 3.x内存管理机制 1:C++内存管理 1-1:内存分配区域 创建对象需要两个步骤:第一步,为对象分配内存:第二步,调用构造函数初始化内存.在第一步中,可以选择几个不同的分配区域. ...

  6. Nginx学习之内存管理

    Nginx对内存管理有自己的一套机制,具体Nginx源码中在ngx_palloc.c中.主要是分为是对大块内存和小内存分配.大体结构图如下(该图为网络上下载的): 小内存是从pool内存池中分配的:大 ...

  7. C语言学习笔记 —— 内存管理

    一.内存模型 对于一个C语言程序而言,内存空间主要由五个部分组成 代码段(text).数据段(data).未初始化数据段(bss),堆(heap) 和 栈(stack) 组成,其中代码段,数据段和BS ...

  8. 深度学习中的内存管理问题研究综述

    点击上方蓝字关注我们 深度学习中的内存管理问题研究综述 马玮良1,2, 彭轩1,2, 熊倩1,2, 石宣化1,2, 金海1,2 1 华中科技大学计算机科学与技术学院,湖北 武汉 430074 2 华中 ...

  9. 操作系统内存管理、Cache调度策略学习

    原文  http://www.cnblogs.com/LittleHann/p/4012086.html 主题 操作系统 HTML 目录 0. 引言 1. 内存管理的概念 2. 内存覆盖与内存交换 3 ...

  10. 同样学习Linux, 为何差别这么大? - 论打通Linux进程和内存管理任督二脉

    穆赫兰道和内陆帝国 我在多年的工程生涯中发现很多工程师碰到一个共性的问题:Linux工程师很多,甚至有很多有多年工作经验,但是对一些关键概念的理解非常模糊,比如不理解CPU.内存资源等的真正分布,具体 ...

最新文章

  1. 实现费用管理 mysql_移动电费房租管理系统的设计与实现(IDEA,MySQL)
  2. Scrapy结合Mysql爬取天气预报入库
  3. 2个网页跳来跳去_成为搜索产品经理(2):认识网络爬虫
  4. 筒灯智能驱动芯片作用_魅族发布Lipro智能吸顶灯与地脚灯 解决生活照明两大痛点...
  5. [网摘]CSS z-index 属性
  6. Mac cnpm装包时提示Error: EACCES: permission denied解决办法
  7. WindowManager.LayoutParams类
  8. doc自动生成html,java web应用中自动生成文章html页面的实现.doc
  9. VB选择文件夹并取文件夹名
  10. 调用腾讯的API接口
  11. oracle crystall ball,Oracle Crystal Ball下载
  12. Android Studio躲避小球小游戏(一界面布局)
  13. 供应IMX335/IMX386/IMX258/OV4689/OV5640/OV8865/光学防抖摄像头模组
  14. Unity 渲染管线总结
  15. 60个经典的电脑技巧!每一个都超实用!
  16. C++sort函数使用(成绩排名)
  17. linux svn图形工具,linux 下svn图形客户端smartsvn 安装
  18. 小白必读:计算机网络入门
  19. 怎么删除批注mysql_如何去掉 Word 文档修订和批注和不显示已删除内容
  20. 电脑桌面录制直播嵌入网页

热门文章

  1. jmeter聚合报告
  2. ugui 转轮_(搬运工)unity3D的FingerGestures插件
  3. 2018 年,做平凡世界里的超人
  4. PTA L3-031 千手观音 (30 分)
  5. 简单的职工信息管理系统(运用了存储过程,和datagridview,dataset的设置)
  6. Ardunio开发实例-磁簧开关
  7. 基于物联网的智能家居系统设计QY-LYZN
  8. [物理实验]计算不确定度
  9. PHP调用微信消息订阅推送
  10. DeepXDE 科学机器学习库(薛定谔方程)