【问题标题】:Why xv6 scheduler calls sti() in the begining of every loop?为什么 xv6 调度程序在每个循环开始时调用 sti()?
【发布时间】:2015-05-07 12:24:22
【问题描述】:

配套书说

在空闲的 CPU 上定期启用中断的原因是 可能没有 RUNNABLE 进程,因为进程(例如,shell) 正在等待 I/O;如果调度程序让中断禁用所有 时间,I/O 永远不会到达。

但我认为我们只需要在外部 for 循环之前调用 sti() 一次,因为每次我们释放 ptable.lock 时,都会再次启用中断。

【问题讨论】:

  • 也许您应该尝试删除重复的sti 并查看调度程序是否挂起或正常继续。

标签: operating-system kernel xv6


【解决方案1】:

schedule() 可能在中断被禁用的情况下被调用,在这种情况下释放 ptable 自旋锁不会重新启用它们。

【讨论】:

  • 是的,没错。但我认为我们只需要在 scheduler() 开始时启用中断。为什么我们需要反复这样做?你能在需要的时候给我一个场景吗?非常感谢。
【解决方案2】:

如果您查看releasing a lock 的代码,您会发现它没有明确启用中断。相反,它使用函数popcli

void release ( struct spinlock* lk )
{
    ...
    popcli();  // enable interrupts
}

函数popcli 并不总是启用中断。它与pushcli 一起使用以跟踪嵌套级别。 “Pushcli/popcli 与 cli/sti 类似,只是它们是匹配的:需要两个 popcli 才能撤消两个 pushcli”。 1

void popcli ( void )
{
    // If interrupts are enabled, panic...
    if ( readeflags() & FL_IF )
    {
        panic( "popcli: interruptible" );
    }

    // Track depth of cli nesting
    mycpu()->ncli -= 1;

    // Popped more than were pushed...
    if ( mycpu()->ncli < 0 )
    {
        panic( "popcli" );
    }

    // Reached outermost, so restore interrupt state
    if ( mycpu()->ncli == 0 && mycpu()->intena )
    {
        sti();  // enable interrupts
    }
}

popcli有时启用中断,pushcli总是禁用中断。

void pushcli ( void )
{
    int eflags;

    eflags = readeflags();

    // Disable interrupts
    cli();

    // Save interrupt state at start of outermost
    if ( mycpu()->ncli == 0 )
    {
        mycpu()->intena = eflags & FL_IF;
    }

    // Track depth of cli nesting
    mycpu()->ncli += 1;
}

通过显式调用sti,调度程序会覆盖当前的 push/popcli 状态。我认为这提供了允许 IO 中断发生所需的简短窗口。 IE。调用sti 和调用cli 之间的时间段(通过acquire -> pushcli -> cli)。

void scheduler ( void )
{
    ...
    for ( ;; )
    {
        // Enable interrupts on this processor.
        sti();

        // Acquire process table lock
        acquire( &ptable.lock );

        // Loop over process table looking for process to run.
        for ( p = ptable.proc; p < &ptable.proc[ NPROC ]; p += 1 )
        {
            ...
        }

        // Release process table lock
        release( &ptable.lock );
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 2020-11-23
    • 1970-01-01
    相关资源
    最近更新 更多