linux 2.6中断提高进程实时性,Linux 2.6如何使用时间中断来完成进程调度

进程调度:

Linux里的进程管理调度,如何调度使用不同的进程占用不同的时间片段,主要在核心函数 scheduler_tick (kernel/sched.c)

硬中断触发:

对操作系统来说,中断是一种电信号,由硬件设备产生,并直接送入中断控制器(如8259A)的输入引脚上,然后再由中断控制器向处理器发送相应的信号。处理器一经检测到

该信号,便中断自己当前正在处理的工作,转而去处理中断。此后,处理器会通知 OS 已经产生中断。这样,OS 就可以对这个中断进行适当的处理了。不同的设备对应的中断不同,而每个中断都通过一个唯一的数字标识。这些中断值通常被称为中断请求线,这里所说的中断就是硬中断,也是我们常说的中断的上半部分。

硬中断的执行:

不同的架构在linux上是不同的执行,在x86架构中,源码程序在/arch/x86_64/kernel/irq.c

asmlinkage unsigned int do_IRQ(struct pt_regs *regs)

{

/* high bit used in ret_from_ code */

unsigned irq = ~regs->orig_rax;

if (unlikely(irq >= NR_IRQS)) {

printk(KERN_EMERG "%s: cannot handle IRQ %d\n",

__FUNCTION__, irq);

BUG();

}

exit_idle();

irq_enter();

#ifdef CONFIG_DEBUG_STACKOVERFLOW

stack_overflow_check(regs);

#endif

__do_IRQ(irq, regs);

irq_exit();

return 1;

}其中  __do_IRQ() 是处理不同的中断信号的函数, 而在irq_exit()里所处理的是中断的下半部分,也就是我们常说的软中断。

在__do_IRQ()的处理函数中,handle_IRQ_event (irq/handle.c)主要负责调用不同的中断信号所注册的函数。

/**

* handle_IRQ_event - irq action chain handler

* @irq:the interrupt number

* @regs:pointer to a register structure

* @action:the interrupt action chain for this irq

*

* Handles the action chain of an irq event

*/

irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs,

struct irqaction *action)

{

irqreturn_t ret, retval = IRQ_NONE;

unsigned int status = 0;

handle_dynamic_tick(action);

if (!(action->flags & IRQF_DISABLED))

local_irq_enable_in_hardirq();

do {

ret = action->handler(irq, action->dev_id, regs);

if (ret == IRQ_HANDLED)

status |= action->flags;

retval |= ret;

action = action->next;

} while (action);

if (status & IRQF_SAMPLE_RANDOM)

add_interrupt_randomness(irq);

local_irq_disable();

return retval;

}

其中struct irqaction 是就是每个不同的硬件中断所注册的处理函数

我们在来看看时间中断里所注册的处理函数,x86_64/kernel/time.c

static struct irqaction irq0 = {

timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL

};

timer_interrupt 函数

static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)

{

if (apic_runs_main_timer > 1)

return IRQ_HANDLED;

main_timer_handler(regs);

#ifdef CONFIG_X86_LOCAL_APIC

if (using_apic_timer)

smp_send_timer_broadcast_ipi();

#endif

return IRQ_HANDLED;

}

在 main_timer_handler 函数里,我们可以清楚的看到

#ifndef CONFIG_SMP

update_process_times(user_mode(regs));

#endif

函数update_process_times 里显示的调用了 scheduler_tick

/*

* Called from the timer interrupt handler to charge one tick to the current

* process. user_tick is 1 if the tick is user time, 0 for system.

*/

void update_process_times(int user_tick)

{

struct task_struct *p = current;

int cpu = smp_processor_id();

/* Note: this timer irq context must be accounted for as well. */

if (user_tick)

account_user_time(p, jiffies_to_cputime(1));

else

account_system_time(p, HARDIRQ_OFFSET, jiffies_to_cputime(1));

run_local_timers();

if (rcu_pending(cpu))

rcu_check_callbacks(cpu, user_tick);

scheduler_tick();

run_posix_cpu_timers(p);

} 我们可以看到在时间中断里会调用进程调度,并且在中断的上半部分,也就是不可被打断。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值