zephyr笔记 2.3.1 Memmory Slabs

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字节的边界。

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 和它的缓冲区。

K_MEM_SLAB_DEFINE(my_slab, 400, 6, 4);

3.2 分配内存块

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

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

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() 来释放内存块。

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

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 中提供了:

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值