[TIL/크래프톤 정글] DAY 89

배재준·2025년 6월 7일

크래프톤 정글 - TIL

목록 보기
81/93
post-thumbnail

2025.06.06

TIL(TODAY I LEARN)


  • 오늘한 내용 : PintOS - Project3: Virtual Memory - spt copy, kill 구현

  • WEEK 13 : 정글 끝까지(PintOS) - Virtual Memory


  • supplemental_page_table_copy() 구현
    • 아직 파일 관련은 구현되지 않은 상태
/* Copy supplemental page table from src to dst */
bool supplemental_page_table_copy(struct supplemental_page_table *dst,
								  struct supplemental_page_table *src)
{
	struct hash_iterator i;

	hash_first(&i, &src->spt_hash);
	while (hash_next(&i))
	{
		struct page *src_page = hash_entry(hash_cur(&i), struct page, hash_elem);
		enum vm_type type = src_page->operations->type;
		void *va = src_page->va;
		bool writable = src_page->writable;

		/* uninit 상태일 때 */
		if (type == VM_UNINIT)
		{
			vm_initializer *init = src_page->uninit.init;
			void *aux = src_page->uninit.aux;
			/* vm_alloc_page_with_initializer(type, ...) 여기서 type은 최종 타입을 보내줘야함 */
			if (!vm_alloc_page_with_initializer(src_page->uninit.type, va, writable,
												init, aux))
				return false;
		}
		else
		{
			/* VM_ANON or VM_FILE 일때 메모리 할당 -> 페이지 요청 -> 메모리 복사 */
			if (!vm_alloc_page(type, va, writable))
				return false;

			/* 물리 프레임 연결 */
			if (!vm_claim_page(va))
				return false;

			/* 실제 물리 프레임 할당을 위해 자식 page 구조체를 찾는다 */
			struct page *dst_page = spt_find_page(dst, va);

			/* 부모 프레임에서 자식 프레임으로 내용 복사 */
			memcpy(dst_page->frame->kva, src_page->frame->kva, PGSIZE);
		}
	}
	return true;
}
  • supplemental_page_table_kill() 구현
    • hash_destroy / hash_clear의 차이가 뭘까
    • 43 실패 / 41 실패
    • wait-killed, exec-missing 차이
/* spt_kill()을 위한 함수 추가*/
void hash_page_destroy(struct hash_elem *e, void *aux)
{
	struct page *p = hash_entry(e, struct page, hash_elem);
	destroy(p);
	free(p);
}

/* Free the resource hold by the supplemental page table */
void supplemental_page_table_kill(struct supplemental_page_table *spt)
{
	/* TODO: Destroy all the supplemental_page_table hold by thread and
	 * TODO: writeback all the modified contents to the storage. */

	// 버킷 배열 메모리 자체를 해제
	hash_destroy(&spt->spt_hash, hash_page_destroy);
}
  • process_exec() 에서 cleanup() 시 spt_kill() 호출해서 초기화함
    • 이 때, hash_table 구조체 마저도 삭제를 해버리니까 다시 init을 해서 다시 초기형태를 만들어준다.
    • hash_destroy()일 경우 여기서 추가해줘야함
    • hash_clear()일 경우 없어도 된다.
process.c
-----------
int process_exec(void *f_name)
{
	...
	/* We first kill the current context */
	process_cleanup();
	
	// 추가 한 부분
#ifdef VM
	/* project 3) 새 프로그램 로드를 위해 빈 SPT로 다시 초기화 추가*/
	supplemental_page_table_init(&thread_current()->spt);
#endif
  ...
  }
  • check_user_address() 수정 → read_boundary test 통과
/*  check_user_address(const void *uaddr){}
	널 포인터 차단 : !uaddr → NULL 이면 즉시 프로세스 종료
	유저 영역 검사 : !is_user_vaddr(uaddr) → 주소가 `PHYS_BASE` 이상(커널 영역)에 있으면 종료
	매핑 여부 검사 : pml4_get_page(..., uaddr) == NULL => 가상 → 물리 매핑이 안 돼 있으면 종료
*/
void check_user_address(const void *uaddr)
{
#ifndef VM
	// project 2
	if (!uaddr || !is_user_vaddr(uaddr) || pml4_get_page(thread_current()->pml4, uaddr) == NULL)
	{
		sys_exit(-1);
	}
#else
	// project 3
	// spt 매핑 여부 검사 : spt_find_page() == NULL -> exit()
	if (!uaddr || !is_user_vaddr(uaddr) || spt_find_page(&thread_current()->spt, uaddr) == NULL)
	{
		sys_exit(-1);
	}
#endif
}

잘하고 있는 거겠지? 화이팅!

0개의 댓글