void fastcall __tasklet_schedule(struct tasklet_struct *t) { unsigned long flags; local_irq_save(flags); t->next = __get_cpu_var(tasklet_vec).list; __get_cpu_var(tasklet_vec).list= t; /* 只是当前CPU ? */ raise_softirq_irqoff(TASKLET_SOFTIRQ); local_irq_restore(flags); } static inline void tasklet_schedule(struct tasklet_struct *t) { if(!test_and_set_bit(TASKLET_STATE_SCHED,&t->state)) /*判断是否被SCHED,如果是,则什么也不做,这不是只调度一次吗? */ __tasklet_schedule(t); } |
static void tasklet_action(struct softirq_action *a) { struct tasklet_struct *list; local_irq_disable(); list = __get_cpu_var(tasklet_vec).list; __get_cpu_var(tasklet_vec).list = NULL; local_irq_enable(); while (list) { struct tasklet_struct *t = list; list = list->next; if (tasklet_trylock(t)) { /*判断是否在其他CPU上执行 */ if (!atomic_read(&t->count)) { if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) BUG(); t->func(t->data); tasklet_unlock(t); continue; } tasklet_unlock(t); } /*已经在其他CPU上执行了,为什么还要再次加入当前的CPU队列? */ local_irq_disable(); t->next = __get_cpu_var(tasklet_vec).list; __get_cpu_var(tasklet_vec).list = t; __raise_softirq_irqoff(TASKLET_SOFTIRQ); local_irq_enable(); } } |
欢迎光临 Chinaunix (http://bbs.chinaunix.net/) | Powered by Discuz! X3.2 |