龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 操作系统 > LINUX系统 >

pdflush内核线程池及其中隐含的竞争(5)

时间:2014-06-01 02:11来源:网络整理 作者:网络 点击:
分享到:
91 static int __pdflush(struct pdflush_work *my_work) 92 { 93 current-flags |= PF_FLUSHER; 94 my_work-fn = NULL; 95 my_work-who = current; 96 INIT_LIST_HEAD(my_work-list); 做些初始化动作。 97


 

 91 static int __pdflush(struct pdflush_work *my_work)
 92 {
 93         current->flags |= PF_FLUSHER;
 94         my_work->fn = NULL;
 95         my_work->who = current;
 96         INIT_LIST_HEAD(&my_work->list);
做些初始化动作。
 97
 98         spin_lock_irq(&pdflush_lock);
因为要对nr_pdflush_threads和pdflush_list操作,所以需要加互斥锁,为了避免意外(pdflush任务的添加可能在硬中断上下文),故同时关闭硬中断。
 99         nr_pdflush_threads++;
将nr_pdflush_threads的计数加1,因为多了一个pdflush内核线程实例。
100         for ( ; ; ) {
101                 struct pdflush_work *pdf;
102
103                 set_current_state(TASK_INTERRUPTIBLE);
104                 list_move(&my_work->list, &pdflush_list);
105                 my_work->when_i_went_to_sleep = jiffies;
106                 spin_unlock_irq(&pdflush_lock);
107
108                 schedule();
将自己加入空闲线程列表pdflush_list,然后让出cpu,等待被调度。
109                 if (try_to_freeze()) {
110                         spin_lock_irq(&pdflush_lock);
111                         continue;
112                 }
如果正在冻结当前进程,继续循环。
113
114                 spin_lock_irq(&pdflush_lock);
115                 if (!list_empty(&my_work->list)) {
116                         printk("pdflush: bogus wakeup!\n");
117                         my_work->fn = NULL;
118                         continue;
119                 }
120                 if (my_work->fn == NULL) {
121                         printk("pdflush: NULL work function\n");
122                         continue;
123                 }
124                 spin_unlock_irq(&pdflush_lock);
上面是对被意外唤醒情况的处理。
125
126                 (*my_work->fn)(my_work->arg0);
127
带参数arg0执行任务函数。
128                 /*
129                  * Thread creation: For how long have there been zero
130                  * available threads?
131                  */
132                 if (jiffies - last_empty_jifs > 1 * HZ) {
133                         /* unlocked list_empty() test is OK here */
134                         if (list_empty(&pdflush_list)) {
135                                 /* unlocked test is OK here */
136                                 if (nr_pdflush_threads < MAX_PDFLUSH_THREADS)
137                                         start_one_pdflush_thread();
138                         }
139                 }
如果pdflush_list为空超过1妙,并且线程数量还有可以增长的余地,则重新启动一个新的pdflush线程实例。
140
141                 spin_lock_irq(&pdflush_lock);
142                 my_work->fn = NULL;
143
144                 /*
145                  * Thread destruction: For how long has the sleepiest
146                  * thread slept?
147                  */
148                 if (list_empty(&pdflush_list))
149                         continue;
如果pdflush_list依然为空,继续循环。
150                 if (nr_pdflush_threads <= MIN_PDFLUSH_THREADS)
151                         continue;
如果线程数量不大于最小线程数,继续循环。
152                 pdf = list_entry(pdflush_list.prev, struct pdflush_work, list);
153                 if (jiffies - pdf->when_i_went_to_sleep > 1 * HZ) {
154                         /* Limit exit rate */
155                         pdf->when_i_went_to_sleep = jiffies;
156                         break;                                  /* exeunt */
157                 }
如果pdflush_list的最后一个内核线程睡眠超过1秒,可能系统变得较为轻闲,结束本线程。为什么是最后一个?因为这个list是作为栈来使用的,所以栈底的元素也肯定就是最老的元素。
158         }
159         nr_pdflush_threads--;
160         spin_unlock_irq(&pdflush_lock);
161         return 0;
nr_pdflush_threads减1,退出本线程。
162 }
163
 
精彩图集

赞助商链接