zoukankan      html  css  js  c++  java
  • 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. 删除模块后,数据消失

  • 相关阅读:
    [bzoj3694]最短路
    [bzoj3172][Tjoi2013]单词
    [bzoj2243][SDOI2011]染色
    [bzoj1036][ZJOI2008]树的统计Count
    [学习笔记]树链剖分
    [bzoj4552][Tjoi2016][Heoi2016]排序
    [51nod1515]明辨是非
    [51nod1685]第k大区间
    [日常训练]training
    BZOJ3811: 玛里苟斯
  • 原文地址:https://www.cnblogs.com/youngerchina/p/5624612.html
Copyright © 2011-2022 走看看