Linux内核链表list_head扩展---klist(四)

2014-11-24 08:54:32 ? 作者: ? 浏览: 11
t_remove_waiters);
183
184static void klist_release(struct kref *kref)
185{
186 struct klist_waiter *waiter, *tmp;
187 struct klist_node *n = container_of(kref, struct klist_node, n_ref);
188
189 WARN_ON(!knode_dead(n));
/* 删除链表中的节点入口 */
190 list_del(&n->n_node);
191 spin_lock(&klist_remove_lock);
/* 内核链表操作宏include/linux/list.h,遍历klist节点移除等待链表 */
192 list_for_each_entry_safe(waiter, tmp, &klist_remove_waiters, list) {
/* 是要删除链表节点的等待器 */
193 if (waiter->node != n)
194 continue;
195
/* 等待者唤醒标志 */
196 waiter->woken = 1;
197 mb();
/* 唤醒等待进程 */
198 wake_up_process(waiter->process);
/* 删除链表入口 */
199 list_del(&waiter->list);
200 }
201 spin_unlock(&klist_remove_lock);
/* 设置节点n指向的klist为空 */
202 knode_set_klist(n, NULL);
203}
204
/* 减引用次数并删除节点 */
205static int klist_dec_and_del(struct klist_node *n)
206{
/* n->nref减引用次数,若引用次数减完不为0,调用klist_release清除节点对象,返回1;为0,则返回0 */
207 return kref_put(&n->n_ref, klist_release);
208}
209
/* 带锁操作的节点删除,不判断是否成功,减引用次数 */
210static void klist_put(struct klist_node *n, bool kill)
211{
/* 获取节点的put方法 */
212 struct klist *k = knode_klist(n);
213 void (*put)(struct klist_node *) = k->put;
214
215 spin_lock(&k->k_lock);
/* “需要杀死节点” = = */
216 if (kill)
217 knode_kill(n);
/* 节点对象引用次数为0了,则不需要调用put方法 */
218 if (!klist_dec_and_del(n))
219 put = NULL;
220 spin_unlock(&k->k_lock);
/* 调用put方法 */
221 if (put)
222 put(n);
223}
224
225/**
226 * klist_del - Decrement the reference count of node and try to remove.
227 * @n: node we're deleting.
228 */
/* 删除节点“杀死死节点 */
229void klist_del(struct klist_node *n)
230{
231 klist_put(n, true);
232}
233EXPORT_SYMBOL_GPL(klist_del);
234
235/**
236 * klist_remove - Decrement the refcount of node and wait for it to go away.
237 * @n: node we're removing.
238 */
239void klist_remove(struct klist_node *n)
240{
/* 定义一个等待者,并加入等待者加入移除等待者链表 */
241 struct klist_waiter waiter;
242
243 waiter.node = n;
244 waiter.process = current;
245 waiter.woken = 0;
246 spin_lock(&klist_remove_lock);
247 list_add(&waiter.list, &klist_remove_waiters);
248 spin_unlock(&klist_remove_lock);
249
/* 清除节点,并设置等待者 */
250 klist_del(n);
251
252 for (;;) {
/* 设置进程状态不可中断,等待 */
253 set_current_state(TASK_UNINTERRUPTIBLE);
/* 节点被删除,进程被唤醒 */
254 if (waiter.woken)
255 break;
/* 内核调度器 */
256 schedule();
257 }
/* 设置当前进程状态为运行 */
258 __set_current_state(TASK_RUNNING);
259}
260EXPORT_SYMBOL_GPL(klist_remove);
261
262/**
263 * klist_node_attached - Say whether a node is bound to a list or not.
264 * @n: Node that we're testing.
265 */
/* 判断节点是不是链表边界 */
266int klist_node_attached(struct klist_node *n)
267{
268 return
-->

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: