Linux内核链表listhead扩展klistWord文档下载推荐.docx
《Linux内核链表listhead扩展klistWord文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Linux内核链表listhead扩展klistWord文档下载推荐.docx(27页珍藏版)》请在冰豆网上搜索。
linux/list.h>
18
/*先声明klist_node节点,在后面定义*/
19structklist_node;
/*klist结构体定义*/
20structklist{
/*klist操作自旋锁*/
21spinlock_tk_lock;
/*内核链表*/
22structlist_headk_list;
/*获取klist_node节点方法*/
23void(*get)(structklist_node*);
/*添加klist_node节点方法*/
24void(*put)(structklist_node*);
25}__attribute__((aligned(sizeof(void*))));
/*按指针大小对齐*/
26
/*定义klist链表初始化宏
*名字初始化锁、链表、get、put方法
27#defineKLIST_INIT(_name,_get,_put)\
/*初始化为解锁状态*/
28{.k_lock=__SPIN_LOCK_UNLOCKED(_name.k_lock),\
/*初始化链表*/
29.k_list=LIST_HEAD_INIT(_name.k_list),\
/*get方法*/
30.get=_get,\
/*put方法*/
31.put=_put,}
32
/*定义并初始化链表*/
33#defineDEFINE_KLIST(_name,_get,_put)\
34structklist_name=KLIST_INIT(_name,_get,_put)
35
/*klist初始化接口,在klist.c里具体分析*/
36externvoidklist_init(structklist*k,void(*get)(structklist_node*),
37void(*put)(structklist_node*));
38
/*节点结构体*/
39structklist_node{
40void*n_klist;
/*neveraccessdirectly*/
/*节点链表入口*/
41structlist_headn_node;
/*引用次数的一个原子变量*/
42structkrefn_ref;
43};
44
/*下面是链表操作方法声明,在klist.c具体分析*/
45externvoidklist_add_tail(structklist_node*n,structklist*k);
46externvoidklist_add_head(structklist_node*n,structklist*k);
47externvoidklist_add_after(structklist_node*n,structklist_node*pos);
48externvoidklist_add_before(structklist_node*n,structklist_node*pos);
49
50externvoidklist_del(structklist_node*n);
51externvoidklist_remove(structklist_node*n);
52
53externintklist_node_attached(structklist_node*n);
54
55
/*klist迭代器和操作方法,关于迭代器比较难理解,先看klist.c再说*/
56structklist_iter{
57structklist*i_klist;
58structklist_node*i_cur;
59};
60
61
62externvoidklist_iter_init(structklist*k,structklist_iter*i);
63externvoidklist_iter_init_node(structklist*k,structklist_iter*i,
64structklist_node*n);
65externvoidklist_iter_exit(structklist_iter*i);
66externstructklist_node*klist_next(structklist_iter*i);
67
68#endif
69----------------------
klist实现代码1/*
2*klist.c-Routinesformanipulatingklists.
4*Copyright(C)2005PatrickMochel
6*ThisfileisreleasedundertheGPLv2.
7*
8*Thisklistinterfaceprovidesacoupleofstructuresthatwraparound
9*structlist_headtoprovideexplicitlist"
head"
(structklist)andlist
10*"
node"
(structklist_node)objects.Forstructklist,aspinlockis
11*includedthatprotectsaccesstotheactuallistitself.struct
12*klist_nodeprovidesapointertotheklistthatownsitandakref
13*referencecountthatindicatesthenumberofcurrentusersofthatnode
14*inthelist.
15*
16*Theentirepointistoprovideaninterfaceforiteratingoveralist
17*thatissafeandallowsformodificationofthelistduringthe
18*iteration(e.g.insertionandremoval),includingmodificationofthe
19*currentnodeonthelist.
20*
21*Itworksusinga3rdobjecttype-structklist_iter-thatisdeclared
22*andinitializedbeforeaniteration.klist_next()isusedtoacquirethe
23*nextelementinthelist.ItreturnsNULLiftherearenomoreitems.
24*Internally,thatroutinetakestheklist'
slock,decrementsthe
25*referencecountofthepreviousklist_nodeandincrementsthecountof
26*thenextklist_node.Itthendropsthelockandreturns.
27*
28*Thereareprimitivesforaddingandremovingnodesto/fromaklist.
29*Whendeleting,klist_del()willsimplydecrementthereferencecount.
30*Onlywhenthecountgoesto0isthenoderemovedfromthelist.
31*klist_remove()willtrytodeletethenodefromthelistandblockuntil
32*itisactuallyremoved.Thisisusefulforobjects(likedevices)that
33*havebeenremovedfromthesystemandmustbefreed(butmustwaituntil
34*allaccessorshavefinished).
35*/
36
37#include<
linux/klist.h>
38#include<
linux/module.h>
39#include<
linux/sched.h>
40
/*下面定义一些节点操作方法,先看下去,再来理解这些操作真正作用*/
41/*
42*Usethelowestbitofn_klisttomarkdeletednodesandexclude
43*deadonesfromiteration.
44*/
45#defineKNODE_DEAD1LU
46#defineKNODE_KLIST_MASK~KNODE_DEAD
47
/*由节点获取链表头*/
48staticstructklist*knode_klist(structklist_node*knode)
49{
50return(structklist*)
51((unsignedlong)knode->
n_klist&
KNODE_KLIST_MASK);
52}
53
/*判断节点“死了”*/
54staticboolknode_dead(structklist_node*knode)
55{
56return(unsignedlong)knode->
KNODE_DEAD;
57}
58
/*设置节点的链表*/
59staticvoidknode_set_klist(structklist_node*knode,structklist*klist)
60{
61knode->
n_klist=klist;
62/*noknodedeservestostartitslifedead*/
/*没有节点刚开始就是“死的”*/
63WARN_ON(knode_dead(knode));
64}
65
/*“杀死”节点*/
66staticvoidknode_kill(structklist_node*knode)
67{
68/*andnoknodeshoulddietwiceevereither,seewe'
reveryhumane*/
/*没有节点能“死”两次,瞧我们多人性化*/
69WARN_ON(knode_dead(knode));
70*(unsignedlong*)&
knode->
n_klist|=KNODE_DEAD;
71}
72
73/**
74*klist_init-Initializeakliststructure.
75*@k:
Theklistwe'
reinitializing.
76*@get:
Thegetfunctionfortheembeddingobject(NULLifnone)
77*@put:
Theputfunctionfortheembeddingobject(NULLifnone)
78*
79*Initialisesthekliststructure.Iftheklist_nodestructuresare
80*goingtobeembeddedinrefcountedobjects(necessaryforsafe
81*deletion)thentheget/putargumentsareusedtoinitialise
82*functionsthattakeandreleasereferencesontheembedding
83*objects.
84*/
/*klist初始化接口
*get/put方法用来操作klist_node
85voidklist_init(structklist*k,void(*get)(structklist_node*),
86void(*put)(structklist_node*))
87{
88INIT_LIST_HEAD(&
k->
k_list);
89spin_lock_init(&
k_lock);
90k->
get=get;
91k->
put=put;
92}
93EXPORT_SYMBOL_GPL(klist_init);
94
/*将节点加入到链表头*/
95staticvoidadd_head(structklist*k,structklist_node*n)
96{
97spin_lock(&
98list_add(&
n->
n_node,&
99spin_unlock(&
100}
101
/*将节点加入到链表尾*/
102staticvoidadd_tail(structklist*k,structklist_node*n)
103{
104spin_lock(&
105list_add_tail(&
106spin_unlock(&
107}
108
/*节点初始化
*包括初始化链表、引用计数、设置指向klist
109staticvoidklist_node_init(structklist*k,structklist_node*n)
110{
111INIT_LIST_HEAD(&
n_node);
112kref_init(&
n_ref);
113knode_set_klist(n,k);
/*如果klist的get方法存在,则调用获取节点*/
114if(k->
get)
115k->
get(n);
116}
117
118/**
119*klist_add_head-Initializeaklist_nodeandaddittofront.
120*@n:
nodewe'
readding.
121*@k:
klistit'
sgoingon.
122*/
/*将节点n初始化并加入到klist的头*/
123voidklist_add_head(structklist_node*n,structklist*k)
124{
125klist_node_init(k,n);
126add_head(k,n);
127}
128EXPORT_SYMBOL_GPL(klist_add_head);
129
130/**
131*klist_add_tail-Initializeaklist_nodeandaddittoback.
132*@n:
133*@k:
134*/
/*将节点n初始化并加入到klist的尾*/
135voidklist_add_tail(structklist_node*n,structklist*k)
136{
137klist_node_init(k,n);
138add_tail(k,n);
139}
140EXPORT_SYMBOL_GPL(klist_add_tail);
141
142/**
143*klist_add_after-Initaklist_nodeandadditafteranexistingnode
144*@n:
145*@pos:
nodetoput@nafter
146*/
/*在节点pos后面插入节点n*/
147voidklist_add_after(structklist_node*n,structklist_node*pos)
148{
149structklist*k=knode_klist(pos);
150
151klist_node_init(k,n);
152spin_lock(&
153list_add(&
pos->
154spin_unlock(&
155}
156EXPORT_SYMBOL_GPL(klist_add_after);
157
158/**
159*klist_add_before-Initaklist_nodeandadditbeforeanexistingnode
160*@n:
161*@pos:
162*/
/*在节点pos前面插入节点n*/
163voidklist_add_before(structklist_node*n,structklist_node*pos)
164{
165structklist*k=knode_klist(pos);
166
167klist_node_init(k,n);
168spin_lock(&
169list_add_tail(&
170spin_unlock(&
171}
172EXPORT_SYMBOL_GPL(klist_add_before);
173
/*等待者结构体,用于删除节点,删除完成唤醒进程*/
174structklist_waiter{
175structlist_headlist;
176structklist_node*node;
177structtask_struct*process;
178intwoken;
179};
180
/*定义并初始化klist节点移除自旋锁*/
181staticDEFINE_SPINLOCK(klist_remove_lock);
/*定义一个等待器的链表*/
182staticLIST_HEAD(klist_remove_waiters);
183
184staticvoidklist_release(structkref*kref)
185{
186structklist_waiter*waiter,*tmp;
187structklist_node*n=container_of(kref,structklist_node,n_ref);
188
189WARN_ON(!
knode_dead(n));
/*删除链表中的节点入口*/
190list_del(&
191spin_lock(&
klist_remove_lock);
/*内核链表操作宏include/linux/list.h,遍历klist节点移除等待链表*/
192list_for_each