现在的位置: 首页 >> 操作系统 >> FreeBSD >> FreeBSD 5 内核源代码分析之中断处理
添加时间:2005-8-21 来源:网教中国 作者:
FreeBSD 5 内核源代码分析之中断处理

id, ithread->it_need, td->td_state);
}

否则,由于已经设置了it_need=1,已经在运行的中断线程将负责处理之。
代码:

mtx_unlock_spin(&sched_lock);

return (0);
}

我们再来看看中断线程本身,该函数较为简单,两个嵌套的循环保证不会遗漏中断,
如果中断服务完成,则睡眠,调用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
* list of handlers, giving each one a go at it.
*/
for (;;) {
/*
* If we are an orphaned thread, then just die.
*/
if (ithd->it_flags & IT_DEAD) {
CTR3(KTR_INTR, "%s: pid %d: (%s) exiting", __func__,
p->p_pid, p->p_comm);
td->td_ithd = NULL;
mtx_destroy(&ithd->it_lock);
mtx_lock(&Giant);
free(ithd, M_ITHREAD);
kthread_exit(0);
}

如果已经删除当前IRQ的中断处理程序,则需要退出中断线程。
代码:

CTR4(KTR_INTR, "%s: pid %d: (%s) need=%d", __func__,
p->p_pid, p->p_comm, ithd->it_need);
while (ithd->it_need) {
/*
* Service interrupts. If another interrupt
* arrives while we are running, they will set
* it_need to denote that we should make
* another pass.
*/
atomic_store_rel_int(&ithd->it_need, 0);

清除it_need标志,当清除后又有中断发生时,it_need将变成1,从而循环继续。
代码:

restart:
TAILQ_FOREACH(ih, &ithd->it_handlers, ih_next) {
if (ithd->it_flags & IT_SOFT && !ih->ih_need)
continue;
atomic_store_rel_int(&ih->ih_need, 0);
CTR6(KTR_INTR,
"%s: pid %d ih=%p: %p(%p) flg=%x", __func__,
p->p_pid, (void *)ih,
(void *)ih->ih_handler, ih->ih_argument,
ih->ih_flags);

if ((ih->ih_flags & IH_DEAD) != 0) {
mtx_lock(&ithd->it_lock);
TAILQ_REMOVE(&ithd->it_handlers, ih,
ih_next);
wakeup(ih);
mtx_unlock(&ithd->it_lock);
goto restart;
}
if ((ih->ih_flags & IH_MPSAFE) == 0)
mtx_lock(&Giant);
ih->ih_handler(ih->ih_argument);

调用设备驱动的中断服务函数。所有注册到该IRQ的函数都将被调用,各个设备的函数将检查
自己设备的状态以确定是否是自己的设备产生的中断。
代码:

if ((ih->ih_flags & IH_MPSAFE) == 0)
mtx_unlock(&Giant);
}
}

/*
* Processed all our interrupts. Now get the sched
* lock. This may take a while and it_need may get
* set again, so we have to check it again.
*/
WITNESS_WARN(WARN_PANIC, NULL, "suspending ithread");
mtx_assert(&Giant, MA_NOTOWNED);
mtx_lock_spin(&sched_lock);
if (!ithd->it_need) {
/*
* Should we call this earlier in the loop above?
*/
if (ithd->it_enable != NULL)
ithd->it_enable(ithd->it_vector);
TD_SET_IWAIT(td); /* we're idle */
p->p_stats->p_ru.ru_nvcsw++;
CTR2(KTR_INTR, "%s: pid %d: done", __func__, p->p_pid);
mi_switch();
CTR2(KTR_INTR, "%s: pid %d: resumed", __func__, p->p_pid);
}

如果此时it_need==1,则说明新来了中断,继续for循环为该中断服务,
否则挂起调度。
代码

上一页 [1] [2] [3] [4] [5] [6] [7]  下一页


上一篇:FreeBSD 5内核源代码分析之系统调用过程 下一篇:不直接替换系统调用的kld
大部分文章摘自网上,如有侵犯您的权益请与我们联系,我们会第一时间进行处理,谢谢! [ 打印文章 ] [ 关闭窗口 ]
推荐文章
·FreeBSD handbook中文版 9 配制F
·FreeBSD 升级系统
·Ports & Package
·FreeBSD kernel 编译大法(二)ker
·FreeBSD 上使用Kerberos 5认证
·FreeBSD 5.x 中 gbfs 的修正,及
·FreeBSD 安装Linuxigd
·FreeBSD 使用cvsd创建安全的cvs
·FreeBSD trafcount命令介绍
·FreeBSD入门安装及汉化
相关文章
 
最新文章
·FreeBSD连载(94):基于NAT的负载
·FreeBSD连载(93):反向代理负载
·FreeBSD连载(92):基于DNS的负载
·FreeBSD连载(91):提升静态网页
·FreeBSD连载(90):单服务器性能
·FreeBSD连载(89):CGI和SSI的安
·FreeBSD连载(88):安全连接方式S
·FreeBSD连载(87):基于用户的访
·FreeBSD连载(86):对IP地址和域
·FreeBSD连载(85):配置Apache服(
Google