Chinaunix首页 | 论坛 | 博客
  • 博客访问: 380643
  • 博文数量: 62
  • 博客积分: 5015
  • 博客等级: 大校
  • 技术积分: 915
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-08 02:00
文章分类

全部博文(62)

文章存档

2009年(45)

2008年(17)

我的朋友

分类: LINUX

2008-12-29 15:23:17

fastcall unsigned int do_IRQ(struct pt_regs *regs){
  irq_enter();//increase hardware irq preemptcount
 
  __do_IRQ(irq, regs){
  handle_IRQ_event(irq, regs, action){
   if (!(action->flags & SA_INTERRUPT)){
    local_irq_enable();
   }
   do {
    ret = action->handler(irq, action->dev_id, regs);
   } while (action); 
   local_irq_disable();
  
  }//end handle_IRQ_event
 
  }//end __do_IRQ
 irq_exit(){
  sub_preempt_count(IRQ_EXIT_OFFSET);//decrease hardware irq preemptcount
  do_softirq(){
   if (in_interrupt()){// softirq should be serilaized for one cpu
    return;
   }
   
    local_irq_save(flags);//save flags reg and disable local irq
   
    __do_softirq(){
      local_bh_disable();//increase the softirq counter to serilaize the softirq (checked by in_interrupt()).
               //this means for one cpu, only one softirq should be execute at one time.
               //No other softirq could be executed while there is one softirq in processing on the specified cpu.
               //no two softirqs can be executed at the same time. even they are different ones.
      local_irq_enable();
     
      do {
     if (pending & 1) {
      h->action(h);
     }
     h++;
     pending >>= 1;
    } while (pending);
    local_irq_disable();
    pending = local_softirq_pending();
    
    if (pending)
     wakeup_softirqd();//handle the left pending softirq in kernel thread (now is in the irq context). this gives running changes to user thread
   
    __local_bh_enable();//decrease the softirq counter
   
    }//end __do_softirq
   
    local_irq_restore(flags);//restore flags reg and local irq
  }//end do_softirq
 
 }//end irq_exit
 
}// end do_IRQ
阅读(584) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~