读书人

slab分配器 - 范例用法

发布时间: 2012-08-25 10:06:20 作者: rapoo

slab分配器 - 实例用法

slab分配器 - 实例用法
其原理此处不再赘述,请参看:http://www.ibm.com/developerworks/cn/linux/l-linux-slab-allocator/
1. 定义一个 kmem_cache 对象,然后对其进行初始化

static struct kmem_cache *sample_cachep;static void init_sample_cachep( void ){    sample_cachep = kmem_cache_create(        "sample_cachep", /* Name */   32,   /* Object Size */   0,   /* Alignment */   SLAB_HWCACHE_ALIGN, /* Flags */   NULL);   /* Constructor */   return;}

这里是采用的通用slab缓存方式实现,这个特定的缓存包含 32 字节的对象,并且是硬件缓存对齐的(由标志参数 SLAB_HWCACHE_ALIGN 定义)。
如果采用专用slab缓存,那么必须要知道建立缓存对象的大小,比如,我们需要为sample_struct结构体建立一个专用的slab缓存,那么其调用格式如下:

static struct kmem_cache *sample_struct_cachep;static void init_sample_struct_cache( void ){    sample_struct_cachep = kmem_cache_create(        "sample_struct_cachep",  /* Name */   sizeof(struct sample_struct), /* Object Size */   0,     /* Alignment */   SLAB_HWCACHE_ALIGN,  /* Flags */   NULL);  /* Constructor */   return;}

接下来以专用slab缓存为实例
2. 使用所分配的 slab 缓存对象,或释放所分配的 slab 缓存对象

int slab_test( void ){       struct sample_struct *object;       printk( "Cache name is %s/n", kmem_cache_name( sample_struct_cachep ) );       printk( "Cache object size is %d/n", kmem_cache_size( sample_struct_cachep ) );       object = kmem_cache_alloc(sample_struct_cachep, GFP_KERNEL);       if (object) {             kmem_cache_free(sample_struct_cachep, object);       }       return 0;}

3. slab 缓存的销毁。调用者必须确保在执行销毁操作过程中,不要从缓存中分配对象。

static void remove_sample_struct_cache( void ){      if (sample_struct_cachep)              kmem_cache_destroy( sample_struct_cachep );      return;}

4.所在slab缓存使用过程中,可以通过slabtop查看。

5. 实例

/********************************************** * Author: lewiyon@hotmail.com * File name: slabmod.c * Description: slab缓存使用实例  * Date: 2012-07-26 *********************************************/#include <linux/init.h> #include <linux/module.h> #include <linux/module.h> #include <linux/unistd.h>//#include <sys/type.h>#include <linux/slab.h>MODULE_LICENSE("GPL");  #define first   1000     /* 第一次尝试分配1000个对象 */struct sample_struct {    int id;    char name[20];    char address[50];};static struct kmem_cache *sample_struct_cachep;    static struct sample_struct *sample1[first];static int sample_mod_init(void){    int i;    sample_struct_cachep = kmem_cache_create(            "sample_struct_cachep",         /* Name */            sizeof(struct sample_struct),   /* Object Size */            0,                              /* Alignment */            SLAB_HWCACHE_ALIGN,             /* Flags */            NULL);                          /* Constructor */    /* 确保创建成功:有可能失败 */    if (NULL == sample_struct_cachep)        return 1;    printk(KERN_INFO "Cache name is %s\n",             kmem_cache_name(sample_struct_cachep));       /* 首次分配 */    for (i = 0; i < first; i++)    {        sample1[i] = kmem_cache_alloc(sample_struct_cachep, GFP_KERNEL);        if (NULL == sample1[i])        {            int ii;            printk("First alloc ERR: %d/n", i);            for (ii = 0; ii < i; ii++)            {                kmem_cache_free(sample_struct_cachep, sample1[ii]);                sample1[ii] = NULL;            }        }    }    return 0;}static void sample_mod_exit(void){    int i;    if (sample1[0])    {        for (i = 0; i < first; i++)            {                kmem_cache_free(sample_struct_cachep, sample1[i]);                sample1[i] = NULL;            }    }    if (sample_struct_cachep)     {        kmem_cache_destroy( sample_struct_cachep );        printk(KERN_INFO "Destroy sample_struct_cachep!\n");    }    return ;} module_init(sample_mod_init); module_exit(sample_mod_exit);MODULE_AUTHOR("lewiyon@hotmail.com"); MODULE_DESCRIPTION("A Simple slab sample"); 

插入模块、删除模块前后slabtop观察结果

[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
1020 1020 100% 0.12K 34 30 136K sample_struct_cachep
[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
1020 1010 99% 0.12K 34 30 136K sample_struct_cachep
[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
1020 1002 98% 0.12K 34 30 136K sample_struct_cachep
[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
1020 1001 98% 0.12K 34 30 136K sample_struct_cachep
[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
1020 1000 98% 0.12K 34 30 136K sample_struct_cachep
[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
1020 1000 98% 0.12K 34 30 136K sample_struct_cachep
[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
1020 1000 98% 0.12K 34 30 136K sample_struct_cachep
[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
1020 1000 98% 0.12K 34 30 136K sample_struct_cachep
[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
1020 1000 98% 0.12K 34 30 136K sample_struct_cachep
[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
[root@RedHat ~]#
分析:

a. 再没有插入模块时,没有数据

b. 插入模块时,新建slab,这是数据都是active的,此时对象数目为OBJS = SLABS * OBJ/SLAB = 34*30 = 1020;

c. 随着模块稳定下来, 未使用的对象变为inactive,那么active数目就变味了1000;(与程序相对应)

d. 删除模块后,数据消失

读书人网 >移动开发

热点推荐