Linux内核链表listhead扩展klistWord文档下载推荐.docx

上传人:b****6 文档编号:20179621 上传时间:2023-01-17 格式:DOCX 页数:27 大小:31.69KB
下载 相关 举报
Linux内核链表listhead扩展klistWord文档下载推荐.docx_第1页
第1页 / 共27页
Linux内核链表listhead扩展klistWord文档下载推荐.docx_第2页
第2页 / 共27页
Linux内核链表listhead扩展klistWord文档下载推荐.docx_第3页
第3页 / 共27页
Linux内核链表listhead扩展klistWord文档下载推荐.docx_第4页
第4页 / 共27页
Linux内核链表listhead扩展klistWord文档下载推荐.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

Linux内核链表listhead扩展klistWord文档下载推荐.docx

《Linux内核链表listhead扩展klistWord文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Linux内核链表listhead扩展klistWord文档下载推荐.docx(27页珍藏版)》请在冰豆网上搜索。

Linux内核链表listhead扩展klistWord文档下载推荐.docx

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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > IT计算机 > 计算机硬件及网络

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1