内核中有些地方的内存分配是不允许失败的。为了确保成功分配内存,建立了内存池。内存池是某种形式的高速后备缓存。试图始终保存空闲的内存,以便在紧急状态下使用。
类型:mempool_t,头文件:<linux/mempool.h>
接口:
创建内存池对象:
mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn, mempol_free_t *free_fn, void *pool_data);
min_nr:内存池始终保持的已分配对象的最少数目
alloc_fn:原型 typedef void *(mempool_alloc_t )(gfp_t gfp_mask, void *pool_data),通常值为mempool_alloc_slab(内核定义的函数)
free_fn:原型 typedef void (mempol_free_t )(void *element, void *pool_data),通常值为mempool_free_slab(内核定义的函数)
pool_data:被传入alloc_fn和free_fn
分配内存对象:
void *mempool_alloc(mempool_t *pool, int gfp_mask);
首先通过分配函数获得内存对象,如果失败,就会返回预先分配的内存对象
释放内存对象:
void mempool_free(void *element, mempool_t *pool);
如果预先分配的对象数目小于要求的最低数目,就会将该内存对象保留在内存池中,否则返回给系统
释放内存池:
void mempool_destroy(mempool_t *pool);
在释放内存池时,必须将所有分配的内存对象返回到内存池中
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/mempool.h>
#define MEM_SIZE 8
#define MIN_NR 8
static mempool_t *pstPool = NULL;
static struct kmem_cache *pKmemCache = NULL;
void constructor(void *args)
{
//printk("constructor. \n");
memset(args, 0x0, MEM_SIZE);
strcpy(args, "hello");
}
static int __init hello_init(void)
{
printk("hello_init. \n");
pKmemCache = kmem_cache_create("test", MEM_SIZE, 0, SLAB_HWCACHE_ALIGN, constructor);
if (!pKmemCache)
{
printk("kmem_cache_create failed. \n");
return -ENOMEM;
}
pstPool = mempool_create(MIN_NR, mempool_alloc_slab, mempool_free_slab, pKmemCache);
if (!pstPool)
{
printk("mempool_create failed. \n");
return -ENOMEM;
}
void *p = mempool_alloc(pstPool, GFP_KERNEL);
if (!p)
{
printk("mempool_alloc failed. \n");
return -ENOMEM;
}
printk("str:%s\n", p);
mempool_free(p, pstPool);
return 0;
}
static void __exit hello_exit(void)
{
printk("hello_exit. \n");
if (NULL != pstPool)
{
mempool_destroy(pstPool);
pstPool = NULL;
}
}
MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);
总结:
内存池会分配一些内存块,空闲且不会得到真正的使用,容易浪费大量内存。尽量少用内存池。