linux驱动 内存池的机制和使用

内存池(memory pool)是Linux 2.6的一个新特性。内核中有些地方的内存分配是不允许失败的。为了确保这种情况下的成功分配,内核开发者建立了一种称为内存池的抽象。内存池其实就是某种形式的后备高速缓存,它试图始终保存空闲的内存,以便在紧急状态下使用。下边是内存池对象的类型:

    typedef struct mempool_s {  
        spinlock_t lock;        /*用来保护对象字段的自旋锁*/  
        int min_nr;     /*内存池中元素的最大个数*/  
        int curr_nr;        /*当前内存池中元素的个数*/  
        void **elements;        /*指向一个数组的指针,该数组由指向保留元素的指针组成*/  
      
      
        void *pool_data;        /*池的拥有者可获得的私有数据*/  
        mempool_alloc_t *alloc; /*分配一个元素的方法*/  
        mempool_free_t *free;   /*释放一个元素的方法*/  
        wait_queue_head_t wait; /*当内存池为空时使用的等待队列*/  
    } mempool_t;  

下面介绍一些API,这些API的内核源码不过二百多行:

创建内存池对象,mempool_create():

    mempool_t * mempool_create(int min_nr, mempool_alloc_t *alloc_fn, mempool_free_t *free_fn, void *pool_data);  


min_nr参数表示的是内存池应始终保持的已分配对象的最少数目,对象的实际分配和释放由alloc_fn和free_fn函数处理,其原型如下:

    typedef void *(mempool_alloc_t)(int gfp_mask, void *pool_data);  
    typedef void mempool_free_t(void *element, void *pool_data);  
mempool_create的最后一个参数,即pool_data,被传入alloc_fn和free_fn。

在建立内存池之后,可如下所示分配和释放对象:

 void *mempool_alloc(mempool_t *pool, int gfp_mask);  
void mempool_free(void *element, mempool_t *pool); 

在创建mempool时,就会多次调用分配函数为预先分配的对象创建内存池,创建的对象个数为min_nr的大小。之后,对mempool_alloc()的调用将首先通过分配函数获得该对象;如果该分配失败,就会返回预先分配的对象(如果存在的话)。如果使用mempool_free释放一个对象,则如果预先分配的对象数目小于要求的最低数目,就会将该对象保留在内存池中;否则,该对象会返回给系统。

可以调用下面的函数来调整mempool的大小:

    int mempool_resize(mempool_t *pool, int new_min_nr, int gfp_mask);  
可以使用下面的函数将内存池返回给系统

  1. void mempool_destroy(mempool_t *pool); 
在销毁mempool之前,必须将所有已分配的对象返回到内存池中,否则会导致内核oops。
    #include <linux/init.h>  
    #include <linux/module.h>  
    #include <linux/kernel.h>  
    #include <linux/slab.h>  
    #include <linux/errno.h>  
    #include <linux/mempool.h>  
    #include <linux/gfp.h>  
    #include <linux/delay.h>  
      
    struct my_mempool{  
        int val;  
    };  
    #define MY_MIN_MEMPOOL 20  
      
    struct kmem_cache * mempool_cachep = NULL;  
    mempool_t * my_pool = NULL;  
    struct my_mempool * mempool_object = NULL;  
      
    static int __init mempool_init(void){  
        printk("memory pool test module init!\n");  
        mempool_cachep = kmem_cache_create("mempool_cachep", sizeof(struct my_mempool), 0, 0, NULL);  
        if(!mempool_cachep)  
            return -ENOMEM;  
        my_pool = mempool_create(MY_MIN_MEMPOOL, mempool_alloc_slab, mempool_free_slab, mempool_cachep);  
        if(!my_pool)  
            return -ENOMEM;  
        mempool_object = (struct my_mempool *)mempool_alloc(my_pool, GFP_KERNEL);  
        if(mempool_object)  
            printk("one object has been allocated!\n");  
        else  
            goto fail;  
        printk("memory pool curr_nr is %d, min_nr is %d\n", my_pool->curr_nr, my_pool->min_nr);  
        mempool_free(mempool_object, my_pool);  
        return 0;  
    fail:  
        mempool_destroy(my_pool);  
        kmem_cache_destroy(mempool_cachep);  
        return -1;  
    }  
      
    static void __exit mempool_exit(void){  
        printk("memory pool test module exit!\n");  
        if(my_pool){  
            mempool_destroy(my_pool);  
            printk("mempool has been destroy!\n");  
        }  
      
        if(mempool_cachep){  
            kmem_cache_destroy(mempool_cachep);  
            printk("cache has been destroy!\n");  
        }  
    }  
      
    module_init(mempool_init);  
    module_exit(mempool_exit);  
    MODULE_AUTHOR("embeddedlwp@163.com");  
    MODULE_LICENSE("GPL");  



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值