linux通用链表结构,可嵌入到任何数据结构中,参照《linux内核源代码情景分析》。学习下。。。
//定义
struct list_head{
struct list_head *next,*prev;
};
//初始化
#define INIT_LIST_HEAD(ptr) do{\
(ptr)->next=(ptr):(ptr)->prev=(ptr);\
}while(0)
//插入队列
static __inline__ void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev=new;
new->next=next;
new->prev=prev;
prev->next=new;
}
//从队列中删除
static __inline__ void __list_del(struct list_head *prev,
struct list_head *next)
{
next->prev=prev;
prev->next=next;
}
/*得到当前list_head所嵌入的结构体的首地址
*list_entry-get the struct for this entry
*@ptr: the &struct list_head pointer.
*@type: the type of the struct this is embedded in.
*@member: the name of the list_struct within the struct
*/
#define list_entry(ptr,type,member)\
((type*) ((char*) (ptr)-(unsigned long)(&((type*)0)->member)))
此书上的例子为:
page=memlist_entry(curr,struct page,list);
其中:
#define memlist_entry list_entry
故展开后为:
page=((struct page*)((char*)(curr)-(unsigned long)(&((struct page *)0)->list));
其
中curr是一个page结构内部的成分list的地址,list_entry这个宏的目的是为了得到page结构自身的首地址,其中&
(struct
page*)0)->list则以0地址为依托,恰好从数字上计算出了当前的list,即curr在page中的位移,因此用curr当前的实际地
址减去其在page结构体中的位移则得到page结构体自身的起始地址
阅读(581) | 评论(0) | 转发(1) |