Chinaunix首页 | 论坛 | 博客
  • 博客访问: 110877
  • 博文数量: 40
  • 博客积分: 1650
  • 博客等级: 上尉
  • 技术积分: 420
  • 用 户 组: 普通用户
  • 注册时间: 2007-07-20 13:05
文章分类
文章存档

2011年(1)

2009年(1)

2008年(1)

2007年(37)

我的朋友

分类: LINUX

2007-07-24 14:07:51

     slab分配器的内存组织结构中处在最高层的是 cache_chain,这是一个 slab 缓存的链接列表。通过该列表可以查找到最适合所需分配大小的缓存(遍历列表)。cache_chain 的每个元素都是一个 kmem_cache 结构的引用(称为一个 cache)。它定义了一个要管理的给定大小的对象池。

struct kmem_cache_s {
/* 1) each alloc & free */
    /* full, partial first, then free */
    struct list_head    slabs_full;
    struct list_head    slabs_partial;
    struct list_head    slabs_free;
    unsigned int objsize;
    unsigned int flags;    /* constant flags */
    unsigned int num;    /* # of objs per slab */
    spinlock_t        spinlock;
#ifdef CONFIG_SMP
    unsigned int batchcount;
#endif

/* 2) slab additions /removals */
    /* order of pgs per slab (2^n) */
    unsigned int        gfporder;

    /* force GFP flags, e.g. GFP_DMA */
    unsigned int        gfpflags;

    size_t colour;        /* cache colouring range */
    unsigned int colour_off;    /* colour offset */
    unsigned int colour_next;    /* cache colouring */
    kmem_cache_t *slabp_cache;
    unsigned int growing;
    unsigned int dflags;        /* dynamic flags */

    /* constructor func */
    void (*ctor)(void *, kmem_cache_t *, unsigned long);

    /* de-constructor func */
    void (*dtor)(void *, kmem_cache_t *, unsigned long);

    unsigned long        failures;

/* 3) cache creation/removal */
    char name[CACHE_NAMELEN];
    struct list_head next;
#ifdef CONFIG_SMP
/* 4) per-cpu data */
    cpucache_t *cpudata[NR_CPUS];
#endif
};

    每个缓存都包含了一个 slabs 列表,这是一段连续的内存块(通常都是以页面最小单位)。存在 3 种 slab:
slabs_full
    完全分配的 slab
slabs_partial
    部分分配的 slab
slabs_empty
    空 slab,或者没有对象被分配

    注意 slabs_empty 列表中的 slab 是进行回收(reaping)的主要备选对象。正是通过此过程,slab 所使用的内存被返回给操作系统供其他用户使用。


    slab 列表中的每个 slab 都是一个连续的内存块(一个或多个连续页),它们被划分成一个个对象。这些对象是从特定缓存中进行分配和释放的基本元素。注意 slab 是 slab 分配器进行操作的最小分配单位,因此如果需要对 slab 进行扩展,这也就是所扩展的最小值。通常来说,每个 slab 被分配为多个对象。

typedef struct slab_s
{
    struct list_head list;
    unsigned long colouroff;
    void *s_mem;        /* including colour offset */
    unsigned int inuse;        /* num of objs active in slab */
    kmem_bufctl_t free;
} slab_t;


    由于对象是从 slab 中进行分配和释放的,因此单个 slab 可以在 slab 列表之间进行移动。例如,当一个 slab 中的所有对象都被使用完时,就从 slabs_partial 列表中移动到 slabs_full 列表中。当一个 slab 完全被分配并且有对象被释放后,就从 slabs_full 列表中移动到 slabs_partial 列表中。当所有对象都被释放之后,就从 slabs_partial 列表移动到 slabs_empty 列表中。
阅读(1037) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~