目录

​摘要​

​1 概念​

​2 实现​

​2.1 定义memory pool​

​2.2 分配一个内存块​

​2.3 释放一个内存块​

​3 参考链接​


本学笔记基于zephyr 工程版本 2.2.99,主机环境为ubuntu18.04,开发平台 nrf52840dk_nrf52840

摘要

memory pool是一个内核对象,允许内存块可以动态的从指定的内存区域分配。内存块在指定的内存中是可变的大小。因此,当应用程序需要为不同大小的数据结构分配存储时,可以减少浪费的内存数量。内存池使用“伙伴内存分配”算法来有效地将较大的块划分为较小的块,从而允许有效地分配和释放不同大小的块,并且限制内存碎片问题。

1 概念

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

memory pool具有以下关键属性:

 minimum block size:单位是字节,它必须至少有4X字节长,其中X大于0。

maximum block size:单位是字节,maximum block size应该是minimum block size 4的幂数倍。也就是说,“maximum block size”必须等于“minimum block size”乘以4^Y,其中Y大于等于0。

number of maximum-szie blocks: 必须大于0。

buffer :为memory slab块提供内存的buffer。它必须至少是“ minimum block size”乘以“number of maximum-szie blocks”字节长。

简单理解一下,了解伙伴算法的童鞋肯定不难理解。就是说有一片内存(buffer),需要被管理。这片内存分“”number of maximum-szie blocks”个大小为"maximum block size"的内存块。然后根据伙伴算法,还可以继续把"maximum block size"的内存块的进行拆分,但是拆分的块最小也得是"minimum block size"大小。

内存池的缓冲区必须与N字节边界对齐,其中N是大于2的2次方(即4、8、16、…)。为了确保缓冲区中的所有内存块都类似地对齐到这个边界,最小块大小也必须是N的倍数。

需要使用内存块的线程只需从memory pool中分配它。成功分配之后,线程提供的块描述符的data字段指示内存块的起始地址。当线程使用完一个内存块时,它必须将该块释放回memory pool,以便可以重用该块。

如果所需指定大小的块不可用,线程可以选择等待其一个可用。任意数量的线程可以同时等待同一个memory pool中;当memory pool中有合适的内存块可用,优先级最高并且等待时间最长的线程会被唤醒,由优先使用这个块。

与堆不同,如果需要,可以定义多个memory pool。例如,不同的应用程序可以使用不同的memory pool;这有助于防止一个应用程序劫持资源来分配所有可用块。简单的说就是和堆对比,所有应用程序都从一个堆去分配内存,那么如果有恶意的程序,一下子把堆都分配走了,那么其他的应用程序就没有内存可用了。

2 实现

2.1 定义memory pool

下面的代码定义并初始化一个内存池,该内存池有3个块,每个块的大小为4096字节,可以将其划分为小至64字节的块,并与一个4字节的边界对齐。(也就是说,内存池支持4096、1024、256和64字节的块大小。)注意,这个宏定义了所有内存池数据结构及其缓冲区。

K_MEM_POOL_DEFINE(my_pool, 64, 4096, 3, 4);

2.2 分配一个内存块

下面的示例代码,分配200个字节,如果不能分配最多等待100毫秒,直到200字节的内存块可用,然后用0填充它。如果没有获得合适的块,用printf打印消息。注意,应用程序将实际接收256字节的内存块,因为这是内存池支持的最接近的匹配大小。

struct k_mem_block block;

if (k_mem_pool_alloc(&my_pool, &block, 200, 100) == 0)) {
memset(block.data, 0, 200);
...
} else {
printf("Memory allocation time-out");
}

2.3 释放一个内存块

下面的代码示例,分配一个75字节的内存块,然后在不再需要它时释放它。(一个256字节的内存块实际上是用来满足请求的。)

struct k_mem_block block;

k_mem_pool_alloc(&my_pool, &block, 75, K_FOREVER);
... /* use memory block */
k_mem_pool_free(&block);

3 参考链接

​https://docs.zephyrproject.org/latest/reference/kernel/memory/pools.html​