参考:
http://blog.sina.com.cn/s/blog_5e99b41e0100rxgf.html
http://hi.baidu.com/shiftedmind/blog/item/1a7c8381e6a67fa56d8119da.html
在Linux内核源码中,经常要对链表进行操作,其中一个很重要的宏是list_for_each_entry:
意思大体如下:
假设下面几个结点,则第一个member代表head,list_for_each_entry的作用就是循环遍历每一个pos中的member子项。
list_for_each_entry应用:
它实际上是一个 for 循环,利用传入的 pos 作为循环变量,从表头 head 开始,逐项向后(next 方向)移动 pos,直至又回head(prefetch() 可以不考虑,用于预取以提高遍历速度 )。
在程序中的使用如下:
list_for_each_entry(pos , head,member)
{
………………
addr = pos; //对返回值pos的操作,这样更容易去理解list_for_each_entry,可以把它看作for()循环
………………
}
宏list_for_each_entry的实现:
对程序中for循环的三步分析:
(1),pos =list_entry((head)->next, typeof(*pos), member)
pos相当于循环中返回的循环变量,这里就是返回一个结构体指针。实现过程如下:
函数list_entry():
跟进:container_of这个函数:
这个不做重点分析,这个函数的做用是:它的作用显而易见,那就是根据一个结构体变量中的一个域成员变量的指针来获取指向整个结构体变量的指针。
所以list_entry()的作用为:如上图所示,可以以通过已知的指向member子项的指针,获得整个结构体的指针(地址)
(2),prefetch(pos->member.next),&pos->member!= (head);
prefetch的含义是告诉cpu那些元素有可能马上就要用到,告诉cpu预取一下,这样可以提高速度,用于预取以提高遍历速度;
&pos->member !=(head) ,这个判断循环条件。
(3), pos= list_entry(pos->member.next, typeof(*pos), member))
和第(1)实现相似,用于逐项向后(next 方向)移动 pos。
分享到:
相关推荐
3.11. list_for_each_entry_continue 13 3.11.1. 定义 13 3.11.2. 作用 13 3.11.3. 区别 13 3.12. list_for_each_safe_rcu 14 4. hlist(hash list) 14 4.1. hlist(hash list)结构 14 4.1.1. 简述 14 4.1.2. 定义...
>>> from drgn.helpers.linux import list_for_each_entry >>> for mod in list_for_each_entry( ' struct module ' , ... prog[ ' modules ' ].address_of_(), ... ' list ' ): ... if mod.refcnt.counter > 10 : ....
从初学者的角度深入的分析了内核数据结构的双向循环链表 list_head结构如何构建链表 分析了list_entry LIST_HEAD list_for_each 并最后给出了一个例子以便学习
#define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next) 二.内核链表 内核链表是一种链表,Linux内核中的链表都是用这种形式实现...
#define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next) C语言的双链表,可以增加。插入,删除,修改,销毁等函数接口。
list_for_each (q, &init_task.tasks) { task = list_entry (q, struct task_struct, tasks); printk ("<0>" "%d\t%d\t%s\n", task->pid, task->parent->pid, task->comm); } return 0; }
Handy for text-intensive applications that involve repetitive text entry and/or lots of professiona-specific shorthand and acronyms. The Text Expander also supports "tabbing" between ...
-- Each camcorder profile defines a set of predefined configuration parameters --> <!-- Back Camera --> <!-- Front Camera --> bitRate="9000000" width="1920" height="1080" frameRate="24...
Each entry is divided into senses, with brief definitions and a full list of synonyms for each sense, to ensure that the selected usage is the most appropriate one. All special usages, such as slang ...
Checking for an ID in Each of Two Files 135 Checking for an ID in Each of "n" Files 138 A Macro for ID Checking 140 More Complicated Multi-File Rules 143 Checking That the Dates Are in the Proper ...
Each command list entry contains information necessary to program an SATA device, and a pointer to a descriptor table for transferring data between system memory and the device.
Please see the actual settings later in the document for more details as to why ; we recommend these changes in PHP's behavior. ; display_errors ; Default Value: On ; Development Value: On ; ...
for (Map.Entry, String> m : emails.entrySet()) { logger.info("email-" + m.getKey() + ":" + m.getValue()); } for (Map.Entry, String> m : emails.entrySet()) { logger.info("email-" + m...
a) implicit palette can fail to create palette entry, causing tuning error b) VsSendBinary() fails if 128 chars or more sent (signed char error) Fixes/features added from previous release a) included...
Repeat the above steps for each IDE that is using Raize Components. >> Removing the component files from your hard disk At this point, all IDEs are no longer using Raize Components. To remove the ...
Next, select the "Raize Components 6.0" entry from the list of installed programs, and then click the Remove button. MINIMUM SYSTEM REQUIREMENTS At least one of the following compilers: Embarcadero...
For each port in the list, information about the process that opened the port is also displayed, including the process name, full path of the process, version information of the process (product name...
13)..Added: "User" and "Session" columns to processes list, processes list is also sorted by session first 14)..Added: Support for showing current user processes only 15)..Added: Expanding environment...
For example: If you want to break each time that a message box is going to be displayed, simply put breakpoints on the memory addresses of message-box functions: MessageBoxA, MessageBoxExA, and ...
* This structure is private to each device. It is used to pass * packets in and out, so there is place for a packet */ struct snull_priv { struct net_device_stats stats; int status; struct ...