[Pintos] Project 3 - (3) Stack growth

해롱그·2023년 10월 18일
1

OS

목록 보기
11/12

# thread.h

void* stack_bottom;		// stack의 최하위 주소 저장할 변수
void* rsp_stack;		// stack 늘리기 위해 rsp 저장할 변수
#process.c

/* Create a PAGE of stack at the USER_STACK. Return true on success.
 * USER_STACK 설정하는 역할로 유저 스택 페이지를 할당하고 초기화 한다. */
static bool setup_stack(struct intr_frame *if_) {
    bool success = false;
    // stack_bottom: 스택 페이지의 가장 아래 부분을 가리키는 포인터
    // USER_STACK은 사용자 스택의 최상위 주소이며 여기에 PGSIZE만큼 뺴줌으로써 스택의 맨 아래 주소를 계산한다.
    // 주의) 일반적으로 stack의 bottom은 스택의 최상위 주소이지만 코드상에서의 stack bottom은 가장 낮은 주소를 나타냄
    void *stack_bottom = (void *)(((uint8_t *)USER_STACK) - PGSIZE);    // 0x4747F000
    // anon 타입의 사용자 스택 페이지 할당 (쓰기 가능)
    if (vm_alloc_page(VM_ANON, stack_bottom, true)) {
        if (vm_claim_page(stack_bottom)) {  // 페이지를 물리 메모리에 연결
                if_->rsp = USER_STACK;      // 성공적으로 연결되면 rsp를 USER_STACK(최상위 주소)으로 설정 -> 스택은 높은 주소부터 쌓이니까!
                thread_current()->stack_bottom = stack_bottom;  // 스택의 끝 부분 저장
                success = true;
            }
        }
    return success;
}
# vm.c

bool
vm_try_handle_fault (struct intr_frame *f UNUSED, void *addr UNUSED,
		bool user UNUSED, bool write UNUSED, bool not_present UNUSED) {
	struct thread *curr = thread_current();
	struct supplemental_page_table *spt UNUSED = &thread_current()->spt;
	
	// 페이지 폴트가 발생한 가상 주소 및 인자들이 유효한지 체크
	if (!is_user_vaddr(addr))
		return false;
	
	// 스택 증가로 page fault 예외를 처리할 수 있는지 확인 후 vm_stack_growth 호출
	// rsp가 유효하면 스택그로우 호출
	if (USER_STACK - (1<<20) <= addr && curr->rsp_stack-8 <= addr && addr <= curr->stack_bottom)
		vm_stack_growth(addr);

	// 접근한 메모리가 물리 페이지와 매핑 되지 않은 경우
	if (not_present) {
		struct page *page = spt_find_page(spt, addr);
		if (!page)
			return false;
			
		// read only page에 write 하려는 상황인지 확인
		if (write && !page->writable)
			return false;

		return vm_do_claim_page (page);
	}
	return false;
}

static void
vm_stack_growth (void *addr UNUSED) {
	// 하나 이상의 anon 페이지를 할당하여 스택 크기를 늘림
	// addr은 faulted 주소에서 유효한 주소
	addr = pg_round_down(addr);
	if (vm_alloc_page(VM_ANON, addr, true))
		thread_current()->stack_bottom -= PGSIZE;	// stack_bottom 갱신해줌
}

주석으로 정리..

profile
사랑아 컴퓨터해 ~

0개의 댓글