Linux通用内存分配器genalloc

内核的genalloc是给一些需要自己维护内存分配的内核模块使用的,如SRAM, TCM, Shared-memory,ION等,内存可以通过预留,或者从伙伴系统分配,然后添加到memory pool。

它提供了最先适配 fist-fit和最佳匹配 best-fit两种分配算法。
irst-fit 和 best-fit
这两种都是通过Bitmap来标记内存中每个分配单元的状态,空闲或已分配。 最先分配是将第一个可容纳请求大小的的连续空闲空间分配出去。 最佳分配是将可容纳请求大小的的最小连续空闲空间分配出去。 假设某片内存被划分为10个最小单 元.

这两种方法都会产生内存碎片,特别是first-fit,但是分配和释放都非常高效,实现也简单,没有buddy system那么复杂,不用考虑内存的回收,规整等等.

1、基础数据结构

首先看下分配器用到的几个数据结构,struct gen_pool 用来描述一个内存池:

struct gen_pool {
    rwlock_t lock;             /* 链表读写锁 */
    struct list_head chunks;   /* 内存池中内存块的链表 */
    int min_alloc_order;       /* 内存池最小分配单元的阶数,大小为 2^min_alloc_order */
};

在使用的时候需要向内存池中加入内存块,一个内存块即一大块连续的物理内存,用 struct gen_pool_chunk 来描述:

struct gen_pool_chunk {
    spinlock_t lock;              /* 操作内存块时用到的自旋锁 */
    struct list_head next_chunk;  /* 加入内存池的节点 */
    unsigned long start_addr;     /* 内存块的起始地址 */
    unsigned long end_addr;       /* 内存块的结束地址 */
    unsigned long bits[0];        /* 内存块的位图 */
};

2、函数接口及调用方法

genalloc 用到的函数接口有下面几个:

/* 创建一个内存池,主要工作是完成 struct gen_pool 的初始化 */
struct gen_pool *gen_pool_create(int min_alloc_order, int nid);
/* 向内存池中加入内存块,addr 为起始地址,size 为大小 */
int gen_pool_add(struct gen_pool *pool, unsigned long addr, size_t size, int nid);
/* 销毁一个内存池 */
void gen_pool_destroy(struct gen_pool *pool);
/* 内存池分配内存的函数 */
unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size);
/* 内存池释放内存的函数 */
void gen_pool_free(struct gen_pool *pool, unsigned long addr, size_t size);

3.使用方法

 1. 创建内存池

//min_alloc_order最小分配单位

   struct gen_pool *gen_pool_create(int min_alloc_order, int nid)

2. 添加内存到内存池

//内存来源可以是预留,也可以从伙伴系统分配.

int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phys,
         size_t size, int nid)

3. 分配/释放内存

unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)

void gen_pool_free(struct gen_pool *pool, unsigned long addr, size_t size)

4.销毁内存池

void gen_pool_destroy(struct gen_pool *pool)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值