现在的位置: 首页 > 综合 > 正文

Slob中kmalloc的实现

2018年05月19日 ⁄ 综合 ⁄ 共 2067字 ⁄ 字号 评论关闭

Slob是一种Linux内存分配器,管理了堆的分配算法

在内核态或用户态的mallockmallc都要用到slob

废话少说,看代码

static inline void *kmalloc(size_t size, int flags)

{

return __kmalloc(size, flags);//调用__kmalloc

}

void *__kmalloc(size_t size, gfp_t gfp)

{

slob_t *m;

bigblock_t *bb;

unsigned long flags;

if (size < PAGE_SIZE - SLOB_UNIT) { //判断申请的内存是否小于一个page的大小,SLOB_UNIT slob单链表结构

m = slob_alloc(size + SLOB_UNIT, gfp, 0);//分配slab

return m ? (void *)(m + 1) : 0;

}

 

bb = slob_alloc(sizeof(bigblock_t), gfp, 0);// 大于一个page的内存申请

if (!bb)

return 0;

bb->order = get_order(size);

bb->pages = (void *)__get_free_pages(gfp, bb->order);

if (bb->pages) {

spin_lock_irqsave(&block_lock, flags);

bb->next = bigblocks;

bigblocks = bb;

spin_unlock_irqrestore(&block_lock, flags);

return bb->pages;

}

slob_free(bb, sizeof(bigblock_t));

return 0;

}

关于slob_alloc的定义在:

static void *slob_alloc(size_t size, gfp_t gfp, int align)

{

slob_t *prev, *cur, *aligned = 0;

int delta = 0, units = SLOB_UNITS(size);

unsigned long flags;

spin_lock_irqsave(&slob_lock, flags);

prev = slobfree;

for (cur = prev->next; ; prev = cur, cur = cur->next) {//遍历链表找到合适的slob

if (align) { //SLOB我们传入的都是0

aligned = (slob_t *)ALIGN((unsigned long)cur, align);

delta = aligned - cur;

}

if (cur->units >= units + delta) { /* room enough? */ //略过

if (delta) { /* need to fragment head to align? */

aligned->units = cur->units - delta;

aligned->next = cur->next;

cur->next = aligned;

cur->units = delta;

prev = cur;

cur = aligned;

}

if (cur->units == units) /* exact fit? */ //请求的和当前的正好相等

prev->next = cur->next; /* unlink *//把匹配的这块从链表中取出来

else { /* fragment */ //没有正好匹配的情况?(大多数情况下>的)

prev->next = cur + units;

prev->next->units = cur->units - units;

prev->next->next = cur->next;

cur->units = units; //同理在当前的链表减个出来

}

slobfree = prev;

spin_unlock_irqrestore(&slob_lock, flags);

return cur;

}

if (cur == slobfree) {

spin_unlock_irqrestore(&slob_lock, flags);

if (size == PAGE_SIZE) /* trying to shrink arena? */

return 0;

cur = (slob_t *)__get_free_page(gfp);

if (!cur)

return 0;

slob_free(cur, PAGE_SIZE);

spin_lock_irqsave(&slob_lock, flags);

cur = slobfree;

}

}

}

Slob内存分配比较简单,只有两条链表来分配可用的内存,没有涉及到复杂的优先级排队,调度的策略,适合小系统使用 slab是更复杂的分配。

抱歉!评论已关闭.