[Linux内存]slab分配器学习笔记(三)--实现

来源:互联网 发布:google play 知乎 编辑:程序博客网 时间:2024/06/04 17:49

1,分配对象


cache_grow用于缓存的增长,它会从伙伴系统获取内存。其流程如图所示:




2,释放对象:



kmem_cache_free ---> __cache_free 
释放的过程正好与分配的过程相反,先将object释放到cpu local slab中,如果cpu local slab满了,就将cpu local slab中的free object释放到share local slab中,如果share local slab也满了,就把share local slab的部分free object释放到slab lists中,然后再将cpu local slab中batcount个free object释放到share local slab中。注意这里释放只是指针接管,cpu local slab与share local slab存放的是指向空闲对象的指针而不是空闲对象本身。limit表示的是cache中最多空闲的obj个数,如果cache中avail的数目小于 limit,那么表示可以将obj直接放入到缓存中,等待新的分配到来。如果cache中空闲的obj太多了,那么,需要将obj放入到slab中。当然这个返回并不是返回一个,而是将batchount个obj返回给slab。这个工作是cache_flusharray来做的

void kmem_cache_free (kmem_cache_t *cachep, void *objp){unsigned long flags;local_irq_save(flags);__cache_free(cachep, objp);local_irq_restore(flags);}static inline void __cache_free (kmem_cache_t *cachep, void* objp){/*获得cpu local slab*/struct array_cache *ac = ac_data(cachep);check_irq_off();objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));/*如果cpu local slab的空闲对象数量 小于 cpu local slab的空闲对象数量上限*/if (likely(ac->avail < ac->limit)) {STATS_INC_FREEHIT(cachep);/*把object 放到cpu local slab中,上移avail指针*/ac_entry(ac)[ac->avail++] = objp;return;} else {STATS_INC_FREEMISS(cachep);cache_flusharray(cachep, ac);/*将对象释放到cpu local slab中*/ac_entry(ac)[ac->avail++] = objp;}}static void cache_flusharray (kmem_cache_t* cachep, struct array_cache *ac){int batchcount;batchcount = ac->batchcount;#if DEBUGBUG_ON(!batchcount || batchcount > ac->avail);#endifcheck_irq_off();spin_lock(&cachep->spinlock);/*如果存在 share local cpu*/if (cachep->lists.shared) {struct array_cache *shared_array = cachep->lists.shared;int max = shared_array->limit-shared_array->avail;、/*如果share local slab还能放下空闲对象*/if (max) {if (batchcount > max)batchcount = max;/*让share local slab来接管 cpu local slab的指针*/memcpy(&ac_entry(shared_array)[shared_array->avail],&ac_entry(ac)[0],sizeof(void*)*batchcount);/*上移avail*/shared_array->avail += batchcount;goto free_done;}}/*如果执行到这里说明share local slab中没有地方了,将cpu local slab中的对象全部赋给slab list3*/free_block(cachep, &ac_entry(ac)[0], batchcount);free_done:spin_unlock(&cachep->spinlock);        /*cpu local slab的avail指针下移batchount*/ac->avail -= batchcount;/*前边空出了batchcount个,将后边的移到前边*/memmove(&ac_entry(ac)[0], &ac_entry(ac)[batchcount],sizeof(void*)*ac->avail);


0 0