td_intr_nesting_level--; } 中斷線程調度函數(shù)ithread_schedule()處理有關中斷線程調度的工作 。 代碼: int ithread_schedule(struct ithd *ithread, int do_switch) { struct int_en。FreeBSD 5 內核源代碼分析之中斷處理( 六 )。" />

日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

FreeBSD 5 內核源代碼分析之中斷處理( 六 )


}
td->td_intr_nesting_level--;
}

中斷線程調度函數(shù)ithread_schedule()處理有關中斷線程調度的工作 。
代碼:
int
ithread_schedule(struct ithd *ithread, int do_switch)
{
struct int_entropy entropy;
struct thread *td;
struct thread *ctd;
struct proc *p;

/*
* If no ithread or no handlers, then we have a stray interrupt.
*/
if ((ithread == NULL) || TAILQ_EMPTY(&ithread->it_handlers))
return (EINVAL);

ctd = curthread;
/*
* If any of the handlers for this ithread claim to be good
* sources of entropy, then gather some.
*/
if (harvest.interrupt && ithread->it_flags & IT_ENTROPY) {
entropy.vector = ithread->it_vector;
entropy.proc = ctd->td_proc;
random_harvest(&entropy, sizeof(entropy), 2, 0,
RANDOM_INTERRUPT);
}

如果該中斷線程有IT_ENTROPY標志,說明可以當作隨機數(shù)的來源 。
代碼:
td = ithread->it_td;
p = td->td_proc;
KASSERT(p != NULL, ("ithread %s has no process", ithread->it_name));
CTR4(KTR_INTR, "%s: pid %d: (%s) need = %d",
__func__, p->p_pid, p->p_comm, ithread->it_need);

/*
* Set it_need to tell the thread to keep running if it is already
* running. Then, grab sched_lock and see if we actually need to
* put this thread on the runqueue. If so and the do_switch flag is
* true and it is safe to switch, then switch to the ithread
* immediately. Otherwise, set the needresched flag to guarantee
* that this ithread will run before any userland processes.
*/
ithread->it_need = 1;

設置it_need,可以保證中斷線程不會在還有中斷的情況下,錯過中斷而去睡眠,見ithread_loop() 。
代碼:
mtx_lock_spin(&sched_lock);
if (TD_AWAITING_INTR(td)) {
CTR2(KTR_INTR, "%s: setrunqueue %d", __func__, p->p_pid);
TD_CLR_IWAIT(td);
setrunqueue(td);
if (do_switch &&
(ctd->td_critnest == 1) ) {
KASSERT((TD_IS_RUNNING(ctd)),
("ithread_schedule: Bad state for curthread."));
ctd->td_proc->p_stats->p_ru.ru_nivcsw;
if (ctd->td_flags & TDF_IDLETD)
ctd->td_state = TDS_CAN_RUN; /* XXXKSE */
mi_switch();
} else {
curthread->td_flags |= TDF_NEEDRESCHED;
}

如果中斷線程正在睡眠,也就是說中斷線程正在等待中斷的到來,則將它放入runqueue,馬上運行 。
如果參數(shù)指示可以調度,并且當前線程的嵌套調度深度為1,即第一次試圖調度中斷線程,則進行
上下文切換,否則,將不立即調度運行中斷線程,而要等到正常調度時再運行 。

這里需要指出的是,如果決定mi_switch(),由于中斷線程優(yōu)先級很高,中斷線程將會立即執(zhí)行,
中斷處理函數(shù)完成后也許將回到這里,也可能有變數(shù),不會馬上回到這里(FIXME),因此前面
intr_execute_handlers()中先應答中斷控制器,將中斷處理必須做的先做完 。

調度回來后,繼續(xù)運行,完成整個中斷的處理 。
代碼:
} else {
CTR4(KTR_INTR, "%s: pid %d: it_need %d, state %d",
__func__, p->p_pid, ithread->it_need, td->td_state);
}

否則,由于已經設置了it_need=1,已經在運行的中斷線程將負責處理之 。
代碼:
mtx_unlock_spin(&sched_lock);

return (0);
}

我們再來看看中斷線程本身,該函數(shù)較為簡單,兩個嵌套的循環(huán)保證不會遺漏中斷,
如果中斷服務完成,則睡眠,調用mi_switch()
代碼:
/*
* This is the main code for interrupt threads.
*/
static void
ithread_loop(void *arg)
{
struct ithd *ithd; /* our thread context */
struct intrhand *ih; /* and our interrupt handler chain */
struct thread *td;
struct proc *p;

td = curthread;
p = td->td_proc;
ithd = (struct ithd *)arg; /* point to myself */
KASSERT(ithd->it_td == td && td->td_ithd == ithd,
("%s: ithread and proc linkage out of sync", __func__));

/*
* As long as we have interrupts outstanding, go through the

推薦閱讀