list_for_each_entry


內核里面用list_for_each_entry實在太多了,定義在linux-3.10/include/linux/list.h:

 1 /**
 2  * list_for_each_entry    -    iterate over list of given type
 3  * @pos:    the type * to use as a loop cursor.
 4  * @head:    the head for your list.
 5  * @member:    the name of the list_struct within the struct.
 6  */
 7 #define list_for_each_entry(pos, head, member)                \
 8     for (pos = list_entry((head)->next, typeof(*pos), member);    \
 9          &pos->member != (head);     \
10          pos = list_entry(pos->member.next, typeof(*pos), member))
11 
12 /**
13  * list_entry - get the struct for this entry
14  * @ptr:    the &struct list_head pointer.
15  * @type:    the type of the struct this is embedded in.
16  * @member:    the name of the list_struct within the struct.
17  */
18 #define list_entry(ptr, type, member) \
19     container_of(ptr, type, member)

 

要分析list_entry就得分析container_of,linux-3.10/include/linux/kernel.h:

 1 /**
 2  * container_of - cast a member of a structure out to the containing structure
 3  * @ptr:    the pointer to the member.
 4  * @type:    the type of the container struct this is embedded in.
 5  * @member:    the name of the member within the struct.
 6  *
 7  */
 8 #define container_of(ptr, type, member) ({            \
 9     const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
10     (type *)( (char *)__mptr - offsetof(type,member) );})

宏定義的第一行:typeof(x)是gcc預處理,獲取x的類型,這里((type *)0)->member利用p=0的指針指向相應結構體(type)的成員,typeof獲取該成員的類型並定義__mptr。

第二行:#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER),跟第一行的((type *)0)->member一個樣子,獲取結構體(type)的偏移量,最后__mptr轉換成(char *)減去自己在結構體(type)的偏移量得到結構體(type)的指針。

可以看出第一行在功能上是沒有什么卵用,其實只是作為類型檢測,實現一個給定成員類型(member)的指針(ptr)找到這個成員的結構體(type)功能的只在第二行。

 

返回看list_entry(ptr, type, member)其實就是通過ptr找到type。

再回到list_for_each_entry(pos, head, member)的實現可以知道,用list_head通過list_entry找到包含next list_head的結構體(pos)作為變量進行循環。可得要使用list_for_each_entry,struct pos里面的成員必須包含list_head。所以在linux里面的struct經常看到list_head這個成員就是這個道理


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM