1. 程式人生 > >linux核心分析———SLAB原理及實現

linux核心分析———SLAB原理及實現

//填充CPU快取記憶體

static void *cache_alloc_refill(structkmem_cache *cachep, gfp_t flags)

{

int batchcount;

struct kmem_list3 *l3;

struct array_cache *ac;

int node;

ac = cpu_cache_get(cachep);//獲得高所快取所在本地CPU快取

retry:

batchcount = ac->batchcount;

if (!ac->touched && batchcount > BATCHREFILL_LIMIT){

/*如果不經常活動,則部分填充*/

batchcount = BATCHREFILL_LIMIT;//16

}

l3 = cachep->nodelists[node];//獲得相應的kmem_list3結構體

...

/* 先考慮從共享本地CPU快取記憶體*/

if (l3->shared && transfer_objects(ac, l3->shared,batchcount))

goto alloc_done;

while (batchcount > 0) {//老老實實的從本快取記憶體分配

struct list_head *entry;

struct slab *slabp;

/* Get slab alloc is to come from. */

entry = l3->slabs_partial.next;//半滿的連結串列

if (entry == &l3->slabs_partial) {//如果半空的都沒了,找全空的

l3->free_touched = 1;

entry = l3->slabs_free.next;

if (entry == &l3->slabs_free)//全空的也沒了,必須擴充了

cache_grow(cachep, flags | GFP_THISNODE, node, NULL);

}

//此時,已經找到了一個連結串列(半空或者全空)

slabp = list_entry(entry, struct slab, list);//找到一個slab

check_slabp(cachep, slabp);

check_spinlock_acquired(cachep);

while (slabp->inuse < cachep->num &&batchcount--)

{//迴圈從slab中分配物件

ac->entry[ac->avail++] =slab_get_obj(cachep, slabp,node);

}

check_slabp(cachep, slabp);

/*slab放到合適的鏈中:*/

list_del(&slabp->list);

if (slabp->free == BUFCTL_END)//如果已經沒有空閒物件了,則放到滿連結串列中

list_add(&slabp->list, &l3->slabs_full);

else//否則放在半滿連結串列

list_add(&slabp->list, &l3->slabs_partial);

}

...

ac->touched = 1;

return ac->entry[--ac->avail];

}