본문 바로가기
개발자 도전기/[OS] pintOS

pintOS | Project 3 | Stack Growth

by 답수 2021. 10. 20.
728x90
SMALL

 

 

프로젝트 3을 정리하면서 계속 말했던 부분은 메모리를 할당할 때, 필요로 하는 페이지를 요청할 때 필요한 만큼 페이지를 할당해준다는 것이다.

 

여기서는 전 포스팅에서 다뤘던 vm_try_handle_fault() 함수에 대해서 더 자세하게 다룰 것이다.

pintOS | Project 3 | Anonymouse Page

 

pintOS | Project 3 | Anonymouse Page

pintOS | Project 3 | Memory Management Anonymous page 파트에서는 anonymous page라고 불리는 비디스크 기반(non-disk based) 이미지를 구현할 것이다. 라고 깃북에 적혀 있다. anonymous 매핑은 백업 파일이나..

dapsu-startup.tistory.com

 

 

vm_try_handle_fault() 함수는 page fault를 예외 처리하는 동안 userprog/exception.c 파일 내에 있는 page_fault() 함수에서 호출된다. 이 함수는 page fault가 스택에 쌓을 수 있는 유요한 경우인지 아닌지를 검사하기 위해 필요하다.

/*
 * 대부분의 OS는 스택 크기에 절대적인 제한이 있음(유닉스 시스템에선 ulimit command 사용으로 사용자의 조정 제한)
 * pintos 경우 스택 사이즈 1MB로 제한
 */
/* Return true on success */
bool vm_try_handle_fault (struct intr_frame *f UNUSED, void *addr UNUSED,
		bool user UNUSED, bool write UNUSED, bool not_present UNUSED) {
	struct supplemental_page_table *spt UNUSED = &thread_current ()->spt;
	// struct page *page = NULL;
	/* TODO: Validate the fault */
	/* TODO: Your code goes here */
	if (is_kernel_vaddr(addr)) {
        return false;
	}

    void *rsp_stack = is_kernel_vaddr(f->rsp) ? thread_current()->rsp_stack : f->rsp;
    if (not_present){
        if (!vm_claim_page(addr)) {
            if (rsp_stack - 8 <= addr && USER_STACK - 0x100000 <= addr && addr <= USER_STACK) {
                vm_stack_growth(thread_current()->stack_bottom - PGSIZE);
                return true;
            }
            return false;
        }
        else
            return true;
    }
    return false;
}

 

만약 page fault가 stack growth로 다룰 수 있다면, vm_stack_growth() 함수를 호출한다.

/* Growing the stack. */
static void vm_stack_growth (void *addr UNUSED) {
    if(vm_alloc_page(VM_ANON | VM_MARKER_0, addr, 1))
    {
        vm_claim_page(addr);
        thread_current()->stack_bottom -= PGSIZE;   // 스택은 위에서부터 쌓기 때문에 주소값 위치를 페이지 사이즈씩 마이너스함
    }
}

 

 

 

728x90
LIST

댓글