• B_QuRT_User_Guide(30)


    20 内存分配

    QuRT 用户程序被分配了一个默认的全局堆,由标准 C 函数 malloc 和 free 访问(第 2.1 节)。
    线程使用内存分配在用户程序中创建额外的基于堆的存储分配器。

    注意:内存分配不能在线程分配的内存区域之外分配内存(第 2.1 节)。  这是使用 QuRT 内存管理服务完成的(第 21 节)。
    
    • 1

    内存分配支持以下操作:

    • qurt_calloc()
    • qurt_free()
    • qurt_malloc()
    • qurt_realloc()

    20.1 qurt_calloc()

    20.1.1 功能文档

    20.1.1.1 void∗ qurt_calloc ( unsigned int elsize, unsigned int num )

    在 QuRT 系统堆上动态分配指定的数组。 返回值是分配数组的地址。

    注意:分配的内存区域会自动初始化为零。
    
    • 1

    参数

    inelsize每个数组元素的大小(以字节为单位)。
    innum数组元素的数量。

    返回值
    非零 - 指向已分配数组的指针。
    零 - 堆中没有足够的内存来分配数组。

    依赖项
    None.

    20.2 qurt_free()

    20.2.1 功能文档

    20.2.1.1 void qurt_free ( void ∗ ptr )

    从堆中释放分配的内存。

    从 QuRT 系统堆中释放指定的内存。

    参数

    in∗ptr指向要释放的内存地址的指针。

    返回值
    None.

    依赖项
    ptr 值指定的内存项必须先前已使用内存分配函数之一(qurt_calloc、qurt_malloc、qurt_realloc)分配。 否则 QuRT 的行为是不确定的。

    20.3 qurt_malloc()

    20.3.1 功能文档

    20.3.1.1 void∗ qurt_malloc ( unsigned int size )

    在 QuRT 系统堆上动态分配指定的数组。 返回值是分配的内存区域的地址。

    注意:分配的内存区域会自动初始化为零。
    
    • 1

    参数

    insize内存区域的大小(以字节为单位)。

    返回值
    非零 - 指向已分配内存区域的指针。
    0 - 堆中没有足够的内存来分配内存区域。

    依赖项
    None.

    20.4 qurt_realloc()

    20.4.1 功能文档

    20.4.1.1 void∗ qurt_realloc ( void ∗ ptr, int newsize )

    在堆上重新分配内存。

    更改已在 QuRT 系统堆上分配的内存区域的大小。 重新分配内存操作在功能上类似于 realloc。 它接受指向堆上现有内存区域的指针,并将内存区域调整为指定大小,同时保留内存区域的原始内容。

    注意:这个函数可能会改变内存区域的地址。  如果 ptr 的值为 NULL,则此函数等效于 qurt_malloc()。  如果 new_size 的值为 0,则相当于 qurt_free()。  如果内存区域被扩展,添加的内存不会被初始化。
    
    • 1

    参数

    in∗ptr指向内存区域地址的指针。
    innewsize重新分配的内存区域的大小(以字节为单位)。

    返回值
    非零 - 指向重新分配的内存区域的指针。
    0 - 堆中没有足够的内存来重新分配内存区域。

    依赖项
    None.

    21 内存管理

    线程使用内存管理来动态分配用户程序内存,与其他用户程序共享内存,以及管理虚拟内存。

    为了在其分配的内存区域之外动态分配内存(第 2.1 节),线程通过将内存池附加到预定义的池来初始化内存池。 然后,它创建一个或多个内存区域,并将池指定为区域属性之一。 线程可以访问新分配的内存区域中的内存。

    注意:一个用户程序不能与另一个用户程序共享其原始分配的内存——它只能共享动态分配的内存区域。
    
    • 1

    内存池将内存区域分配给不同类型的物理(非虚拟)内存。 比如Hexagon处理器可以访问SMI、TCM、EBI内存; 要在每个内存中分配区域,请为每个内存单元定义一个单独的内存池(例如,SMI 池或 TCM 池)。 创建内存区域的请求总是将内存池对象指定为区域属性。

    内存池在系统配置文件(第 2.2 节)中预定义,并由它们在内存池附加操作中分配的池名称指定。 QuRT 用户程序系统中的所有用户程序都可以访问内存池。

    qurt_mem_pool_create() 可以在运行时创建内存池。

    QuRT 预定义了内存池对象 qurt_mem_default_pool,该对象预附加到系统配置文件中的默认内存池。 它被定义为在 SMI 内存中分配内存区域。

    添加页面和删除页面操作用于直接操作内存池。

    内存区域用于定义具有一组固定属性的内存区域,这些属性指定区域的虚拟内存映射和缓存类型。 在系统配置文件(第 2.2 节)中预定义了一组核心区域,并在运行时创建或删除其他区域以支持动态内存管理。

    内存区域具有以下属性:

    • Size – 内存区域大小(以字节为单位)。
    • Pool – 区域所属的内存池; 每个区域必须有一个对应的池。
    • 映射——内存映射表示内存区域在虚拟内存中的映射方式:
      • 虚拟映射区域将其虚拟地址范围映射到物理内存的可用连续区域。 这可以最有效地使用虚拟内存,并且适用于大多数内存用例。
      • 物理连续映射区域将其虚拟地址范围映射到物理内存的特定连续区域。 当内存区域被绕过 Hexagon 虚拟内存寻址的外部设备访问时,这是必要的。
    • 物理地址——内存区域的物理基地址; 仅在使用物理连续映射内存区域时设置。
    • 虚拟地址——内存区域虚拟地址; 返回内存区域基地址的只读属性。
    • 高速缓存模式——高速缓存类型,指示内存区域是使用指令高速缓存还是数据高速缓存。
    • 总线——总线属性指示(A1,A0)总线属性位。
    • 类型——内存区域类型(本地/共享); 指示内存区域对于用户程序是本地的还是在用户程序之间共享。
    注意:内存区域大小和池属性直接设置为内存区域创建操作中的参数。
    
    • 1

    在创建区域之前(使用 qurt_mem_region_attr_init() 和 qurt_mem_region_attr_set 函数)和创建区域时(通过直接将属性作为参数传递给 qurt_mem_region_create())设置内存区域属性。

    内存区域大小和内存区域池在创建区域时设置——其他内存区域属性在创建操作之前设置。

    可以使用 qurt_mem_region_attr_get() 和其他 qurt_mem_region_attr_get 函数从创建的内存区域中检索内存区域属性。

    唯一不能从内存区域检索的属性是内存池。

    内存映射指定 Hexagon 处理器中虚拟内存和物理内存之间的映射。

    创建映射和删除映射操作直接操作内存映射。

    内存映射静态查询操作指示内存页是否被静态映射。 如果指定页面是静态映射的,则操作返回页面的虚拟地址。 如果页面不是静态映射的(或者如果它不存在),则操作返回 -1 作为虚拟地址值。

    查找物理地址操作执行虚拟到物理地址的转换。 它返回指定虚拟地址的物理内存地址。

    注意:内存映射直接在页表上操作——因此,更改映射会影响为受影响的内存区域定义的任何内存区域。
    
    • 1

    内存排序
    某些设备在访问时需要同步存储和加载。 这种同步可以通过 qurt_mem_barrier() 和 qurt_mem_syncht() 完成。

    屏障操作确保所有先前的内存事务都是全局可观察的,然后任何未来的内存事务都是全局可观察的。

    直到源自当前线程的所有先前的内存事务(例如缓存和未缓存的加载和存储)都完成并且全局可观察时,同步操作才会返回。

    使用以下 QuRT 功能访问内存管理服务:
    (条目较多,详情见后续各小节)

    21.1 qurt_lookup_physaddr()

    21.1.1 功能文档

    21.1.1.1 qurt_paddr_t qurt_lookup_physaddr ( qurt_addr_t vaddr )

    将虚拟内存地址转换为映射到的物理内存地址。

    查找发生在调用者的过程中。 使用 qurt_lookup_physaddr2() 查找另一个进程的物理地址。

    相关数据类型
    qurt_addr_t
    qurt_paddr_t

    参数

    invaddr虚拟地址。

    返回值
    非零 - 虚拟地址映射到的物理地址。
    0 – 未映射虚拟地址。

    依赖项
    None.

    21.2 qurt_lookup_physaddr2()

    21.2.1 功能文档

    21.2.1.1 qurt_paddr_64_t qurt_lookup_physaddr2 ( qurt_addr_t vaddr, unsigned int pid )

    将指定进程的虚拟内存地址转换为它所映射到的 64 位物理内存地址。

    相关数据类型
    qurt_addr_t
    qurt_paddr_64_t

    参数

    invaddr虚拟地址。
    inpidPID.

    返回值
    非零 – 虚拟地址映射到的 64 位物理地址。
    0 – 未映射虚拟地址。

    依赖项
    None.

    21.3 qurt_lookup_physaddr_64()

    21.3.1 功能文档

    21.3.1.1 qurt_paddr_64_t qurt_lookup_physaddr_64 ( qurt_addr_t vaddr )

    将虚拟内存地址转换为映射到的 64 位物理内存地址。

    查找发生在调用者的过程中。 使用 qurt_lookup_physaddr2() 查找另一个进程的物理地址。

    相关数据类型
    qurt_paddr_64_t
    qurt_addr_t

    参数

    invaddr虚拟地址。

    返回值
    非零 – 虚拟地址映射到的 64 位物理地址。
    0 – 未映射虚拟地址。

    依赖项
    None.

  • 相关阅读:
    21天学习挑战赛-Java进阶
    Java:缓存行和伪共享
    极狐(GitLab) 马景贺:DevSecOps落地实践的挑战与应对之道
    NP管理器 NPManager v3.0.49 安卓APK逆向反编译工具
    鞋子,靴子,拖鞋傻傻分不清楚 pytorch实现分类 入门小案例
    Java 通过反射修改字符串 String 类型变量的取值而不改变字符串变量的指向
    2019中原银行java实习面试
    vue2以ElementUI为例构建notify便捷精美提示
    泛型中<>和()中的类型
    Linux 高级网络设置
  • 原文地址:https://blog.csdn.net/weixin_38498942/article/details/125424109