在Pintos中切换上下文

时间:2016-09-13 22:52:57

标签: x86 operating-system scheduler pintos

我正在分析Pintos的调度程序(我的意思是 - 本机实现提供的简单调度程序)。

当勾选(我的意思是由计时器引发的刻度)时,它将由以下方式处理:

static void
timer_interrupt (struct intr_frame *args)
{
  ticks++;
  thread_tick ();
}
args指向的

结构包含(以及其他)下一条指令中断线程的IP。因此,记住当前线程让他继续工作至关重要。请注意,该处理程序仅递增ticks并在没有thread_tick()的情况下调用args。现在,有关eip(和段寄存器等)的信息将丢失。

这是否意味着提供的调度程序无法继续执行线程的工作? 在那种情况下,它可能是第一个项目的一部分。

我在问,因为我不确定我是否误解了什么。

我附上一个"入口点"每个中断处理程序:

.func intr_entry
intr_entry:
    /* Save caller's registers. */
    pushl %ds
    pushl %es
    pushl %fs
    pushl %gs
    pushal

    /* Set up kernel environment. */
    cld         /* String instructions go upward. */
    mov $SEL_KDSEG, %eax    /* Initialize segment registers. */
    mov %eax, %ds
    mov %eax, %es
    leal 56(%esp), %ebp /* Set up frame pointer. */

    /* Call interrupt handler. */
    pushl %esp
.globl intr_handler
    call intr_handler
    addl $4, %esp
.endfunc

intr_handler功能:

void intr_handler (struct intr_frame *frame) 
{
  bool external;
  intr_handler_func *handler;

  external = frame->vec_no >= 0x20 && frame->vec_no < 0x30;
  if (external) 
    {
      ASSERT (intr_get_level () == INTR_OFF);
      ASSERT (!intr_context ()); 
      in_external_intr = true;
      yield_on_return = false;
    }

  handler = intr_handlers[frame->vec_no];
  if (handler != NULL)
    handler (frame);
  else if (frame->vec_no == 0x27 || frame->vec_no == 0x2f)
    {
       // ignore
    }
  else
     unexpected_interrupt (frame);


  /* Complete the processing of an external interrupt. */
  if (external) 
    {
      ASSERT (intr_get_level () == INTR_OFF);
      ASSERT (intr_context ());

      in_external_intr = false;
      pic_end_of_interrupt (frame->vec_no); 

      if (yield_on_return) 
        thread_yield (); 
    }
}

因此,正如您所看到的,intr_handler根本没有处理上下文。 基本上,它调用特定的处理程序,如timer_interrupt(见上文)。 timer_interrupt来电thread_tick

void thread_tick (void) 
{
  struct thread *t = thread_current ();

  /* Update statistics. */
  if (t == idle_thread)
    idle_ticks++;
  else
    kernel_ticks++;

  /* Enforce preemption. */
  if (++thread_ticks >= TIME_SLICE)
    intr_yield_on_return ();
}

intr_yield_on_return

intr_yield_on_return (void) 
{
  ASSERT (intr_context ());
  yield_on_return = true;
}

intr_yield_on_return设置标志。 intr_handler有一段代码:

 if (yield_on_return) 
        thread_yield (); 

所以它会调用thread_yield

thread_yield (void) 
{
  struct thread *cur = thread_current ();
  enum intr_level old_level;

  ASSERT (!intr_context ());

  old_level = intr_disable ();
  if (cur != idle_thread) 
    list_push_back (&ready_list, &cur->elem);
  cur->status = THREAD_READY;
  schedule ();
  intr_set_level (old_level);
}

thread_yield也没有记住IP(和其他人)当前的帖子。

0 个答案:

没有答案