운영체제(OS)/with PintOS

(Project3-Virtual Memory) - Stack Growth

스탠딩 2023. 12. 26. 21:23

스택 성장 기능을 구현하세요. 이를 위해 먼저 `vm/vm.c`의 `vm_try_handle_fault` 함수를 수정하여 스택 성장을 식별하도록 해야 합니다. 스택 성장을 식별한 후에는 `vm/vm.c`에 있는 `vm_stack_growth` 함수를 호출하여 스택을 성장시켜야 합니다. `vm_stack_growth` 함수를 구현하세요.

bool vm_try_handle_fault (struct intr_frame *f, void *addr,
    bool user, bool write, bool not_present);

이 함수는 `userprog/exception.c`의 `page_fault` 함수에서 페이지 부재 예외를 처리하는 동안 호출됩니다. 이 함수에서는 페이지 부재가 스택 성장에 대한 유효한 경우인지 여부를 확인해야 합니다. 부재를 스택 성장으로 처리할 수 있다고 확인되면 해당 주소로 `vm_stack_growth`를 호출하세요.

bool vm_try_handle_fault(struct intr_frame *f, void *addr, bool user, bool write, bool not_present)
{
  struct supplemental_page_table *spt = &thread_current()->spt;
  struct page *page = NULL;
  /* TODO: Validate the fault */
  /* TODO: Your code goes here */
  if (is_kernel_vaddr(addr) && user)
    return false;

  page = spt_find_page(spt, addr);

  if (page == NULL) // 페이지가 없다면
  {
    struct thread *current_thread = thread_current();
    void *stack_bottom = pg_round_down(thread_current()->user_rsp);
    if (write && (addr >= pg_round_down(thread_current()->user_rsp - PGSIZE)) && (addr < USER_STACK))
    {
      vm_stack_growth(addr); // 스택 확장 후 페이지 할당
      return true;
    }
    return false;
  }

  if (vm_do_claim_page(page))
    return true;

  return false;
}

 

 

void vm_stack_growth (void *addr);

스택 크기를 증가시켜서 주소 `addr`이 더 이상 부재 주소가 아니도록 익명 페이지 하나 이상을 할당합니다. 할당 처리 시에는 주소 `addr`을 PGSIZE로 내림하여 처리해야 합니다.

static void vm_stack_growth(void *addr)
{
  void *pg_addr = pg_round_down(addr); // 페이지 시작 주소로 내림
  ASSERT((uintptr_t)USER_STACK - (uintptr_t)pg_addr <= (1 << 20)); // pintos에서는 최대 1MB로 제한

  while (vm_alloc_page(VM_ANON, pg_addr, true)) // 페이지 단위로 할당
  {
    struct page *pg = spt_find_page(&thread_current()->spt, pg_addr);
    vm_claim_page(pg_addr);
    pg_addr += PGSIZE;
  }
}

 

대부분의 운영 체제는 스택 크기에 대한 절대적인 제한을 가지고 있습니다. 일부 운영 체제는 이 제한을 사용자가 조절할 수 있도록 허용하며, 이를 위해 많은 Unix 시스템에서는 ulimit 명령을 사용합니다. 많은 GNU/Linux 시스템에서는 기본 제한이 8MB입니다. 이 프로젝트에서는 스택 크기를 최대 1MB로 제한해야 합니다.

이제 모든 스택 성장 테스트 케이스가 통과되어야 합니다.