pdflush内核线程池及其中隐含的竞争(5)
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 |
- 上一篇:Linux日志文件系统及性能分析
- 下一篇:linux学习日记五 磁盘与文件系统管理
精彩图集
精彩文章