linux内核源码里的链表

linux源代码里的链表结构可能与教课书里的不太一样,如下:

struct list_head {
	struct list_head *next, *prev;
};

可以看到,里面没有数据域,那么这个结构在linux源码里怎么应用呢,看一个例子:

struct vblk {				/* Generalised VBLK */
	u8	name[64];
	u64	obj_id;
	u32	sequence;
	u8	flags;
	u8	type;
	union {
		struct vblk_comp comp;
		struct vblk_dgrp dgrp;
		struct vblk_disk disk;
		struct vblk_part part;
		struct vblk_volu volu;
	} vblk;
	struct list_head list;
};

很明显,跟我们平常用的相反,它将list_head结构挂在了数据里面,为了能访问到数据域的地址,linux源码里提供了一个叫list_entry的:

#define list_entry(ptr, type, member) \
	container_of(ptr, type, member)

#define container_of(ptr, type, member) ({			\
        const typeof( ((type *)0)->member ) *__mptr = (ptr);	\
        (type *)( (char *)__mptr - offsetof(type,member) );})

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

其中,list_entry的三个入参分别是,指针的地址,数据域的结构类型和指针成员,实例如:定义一个,
struct vblk   sample;

struct list_head *ptr;
我们就这样用list_entry:

list_entry(ptr, struct vblk, list);
list_entry返回的就是包含ptr地址的vblk结构的首地址,这样我们就可以任意访问这个结构里的数据字段了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值