前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >zephyr笔记 2.3.1 Memmory Slabs

zephyr笔记 2.3.1 Memmory Slabs

作者头像
twowinter
发布2020-04-17 11:17:49
5830
发布2020-04-17 11:17:49
举报
文章被收录于专栏:twowintertwowinter

1 前言

memory slab 是一个内核对象,它允许从指定的内存区域动态分配内存块。 memory slab 中的所有内存块都有一个固定大小,可以高效地分配和释放它们,避免出现内存碎片问题。

我正在学习 Zephyr,一个很可能会用到很多物联网设备上的操作系统,如果你也感兴趣,可点此查看帖子zephyr学习笔记汇总

2 概念

可以定义任意数量的 memory slab。每个 memory slab 都由其内存地址引用。

memory slab 具有以下关键属性:

  • 每个块的块大小,以字节为单位。它必须至少有4N个字节长,其中N大于0。
  • 可用于分配的块数。它必须大于零。
  • 为 memory slab 的块提供内存的缓冲区。它必须至少“块大小”乘以“块数”字节。

memory slab 的缓冲区必须与N字节边界对齐,其中N是大于2的幂(即4,8,16,…)。为确保缓冲区中的所有内存块与此边界相似,块大小必须也是N的倍数。

内存板必须初始化才能使用。这将其所有块都标记为未使用。

需要使用内存块的线程只需向 memory slab 申请分配。当线程完成一个内存块时,它必须将块释放回 memory slab ,以便块可以重用。

如果所有块都在使用中,线程可以选择等待一个可用的块。可能会有任何数量的线程同时在空的 memory slab 上等待; 当内存块变得可用时,它被赋予等待时间最长的最高优先级线程。

与堆不同,如果需要,可以定义多个内存块。可定义一个由较小内存块组成的 memory slab,同时再定义其他较大内存块组成的 memory slab。或者,可以使用内存池对象。

2.1 内部操作

memory slab 的缓冲区是一个固定大小的块的数组,块之间没有浪费的空间。

memory slab 使用链接链表跟踪未分配的块; 每个未使用块的前4个字节提供必要的链接。

3 操作

3.1 定义一块 memory slab

memory slab 是使用 struct k_mem_slab 类型的变量定义的。 它必须通过调用 k_mem_slab_init() 来初始化。

以下代码定义并初始化一个 memory slab ,该 slab 有6个长度为400个字节的块,每个块都对齐到一个4字节的边界。

代码语言:javascript
复制
struct k_mem_slab my_slab;
char __aligned(4) my_slab_buffer[6 * 400];

k_mem_slab_init(&my_slab, my_slab_buffer, 400, 6);

或者,可以在编译时通过调用 K_MEM_SLAB_DEFINE 来定义和初始化 memory slab。

以下代码与上面的代码段具有相同的效果。 观察宏定义了 memory slab 和它的缓冲区。

代码语言:javascript
复制
K_MEM_SLAB_DEFINE(my_slab, 400, 6, 4);

3.2 分配内存块

内存块通过调用 k_mem_slab_alloc() 来分配。

以下代码构建在上面的示例上,并等待100毫秒以使内存块变为可用,然后用零填充它。 如果没有获得合适的块,则会打印警告。

代码语言:javascript
复制
char *block_ptr;

if (k_mem_slab_alloc(&my_slab, &block_ptr, 100) == 0)) {
    memset(block_ptr, 0, 400);
    ...
} else {
    printf("Memory allocation time-out");
}

3.3 释放内存块

通过调用 k_mem_slab_free() 来释放内存块。

以下代码构建在上面的示例上,并分配一个内存块,然后在不再需要时释放它。

代码语言:javascript
复制
char *block_ptr;

k_mem_slab_alloc(&my_slab, &block_ptr, K_FOREVER);
... /* use memory block pointed at by block_ptr */
k_mem_slab_free(&my_slab, &block_ptr);

4 建议用法

使用 memory slab 来分配和释放固定大小块中的内存。

从一个线程向另一个线程发送大量数据时使用 memory slab 的块,以避免不必要的数据复制。

5 配置选项

6 APIs

下列 memory slab API,都在 kernel.h 中提供了:

代码语言:javascript
复制
K_MEM_SLAB_DEFINE
k_mem_slab_init()
k_mem_slab_alloc()
k_mem_slab_free()
k_mem_slab_num_used_get()
k_mem_slab_num_free_get()

End

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 前言
  • 2 概念
    • 2.1 内部操作
    • 3 操作
      • 3.1 定义一块 memory slab
        • 3.2 分配内存块
          • 3.3 释放内存块
          • 4 建议用法
          • 5 配置选项
          • 6 APIs
          • End
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档