内存管理之slab分配器

内存区管理中slab分配器的分配slab对象的函数kmem_cache_alloc():

void * kmem_cache_alloc (kmem_cache_t *cachep, int flags)
{
	return __cache_alloc(cachep, flags);
}
__cache_alloc()函数实现对slab对象的分配:

static inline void * __cache_alloc (kmem_cache_t *cachep, int flags)
{
	unsigned long save_flags;
	void* objp;
	struct array_cache *ac;

	cache_alloc_debugcheck_before(cachep, flags);

	local_irq_save(save_flags);
	ac = ac_data(cachep);
	if (likely(ac->avail)) {
		STATS_INC_ALLOCHIT(cachep);
		ac->touched = 1;
		objp = ac_entry(ac)[--ac->avail];
	} else {
		STATS_INC_ALLOCMISS(cachep);
		objp = cache_alloc_refill(cachep, flags);
	}
	local_irq_restore(save_flags);
	objp = cache_alloc_debugcheck_after(cachep, flags, objp, __builtin_return_address(0));
	return objp;
}
其中的语句objp = ac_entry(ac)[--ac->avail];等价于objp = ((void **)(ac+1))[--ac->avail];刚开始对于这个语句很不理解,后来查看了牛人对于slab相关数据结构的讲解,才恍然大悟。下图为slab相关的数据结构的图解:

要理解上述的那条语句需要注意以下3点:

(1)array_cache数据结构是空闲对象的本地高速缓存的一个描述符;

(2)而本地高速缓存数组是由一个指向被释放对象的小指针数组组成;

(3)本地高速缓存正好存放在array_cache描述符的后面。

所以((void **)(ac+1))[--ac->avail] 语句首先是通过ac+1来获取本地高速缓存的地址,由于本地高速缓存是一个包含指针的数组,所以要通过强制类型转换将ac类型转换为指向指针类型的指针。最后还要注意一点array_cache数据结构的 avail 域既表示本地高速缓存中可使用对象的指针的个数,也表示高速缓存中第一个空槽的下标。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值