
PintOS Project3(1)
이제 PintOS Project3의 구현을 시작했습니다
Gitbook을 참고하여 진행하였고 아직 코드가 정확한지는 확인할 수 없는 단계라 make가 가능한지만 확인하면서 진행해 틀린 부분이 있을 수 있습니다
supplemental_page_table_init
추가 페이지 테이블을 초기화하고, 추가 페이지 테이블에 사용할 데이터 구조를 선택할 수 있습니다. 이 함수는 새 프로세스가 시작될 때(in initd of userprog/process.c) 프로세스가 분기될 때(in __do_forkof userprog/process.c) 호출됩니다
void
supplemental_page_table_init (struct supplemental_page_table *spt UNUSED) {
hash_init (&spt->spt_hash, page_hash, page_less, NULL);
}
위의 코드는 Pintos 프로젝트의 보충 페이지 테이블을 초기화하는 함수인 supplemental_page_table_init입니다.
1. 함수 시그니처:
- struct supplemental_page_table *spt: 초기화할 보충 페이지 테이블을 가리키는 포인터입니다. (UNUSED 키워드로 사용하지 않을 변수임을 명시합니다.)
2. 함수 동작:
- hash_init 함수를 사용하여 보충 페이지 테이블(spt)의 해시 테이블을 초기화합니다.
- hash_init 함수는 해시 테이블을 초기화하고, 해시 함수(page_hash)와 비교 함수(page_less)를 설정합니다.
- &spt->spt_hash는 초기화할 해시 테이블을 가리키는 포인터입니다.
- page_hash 함수는 주어진 해시 엘리먼트를 해시 테이블에서 찾기 위한 해시 값을 반환합니다.
- page_less 함수는 주어진 두 해시 엘리먼트를 비교하여 정렬 순서를 결정합니다. 이 함수를 통해 해시 테이블에서 엘리먼트를 정렬된 상태로 유지할 수 있습니다.
- 마지막 매개변수 NULL은 사용자 지정 매개변수로, 일반적으로 비어있는 상태입니다.
이 함수는 보충 페이지 테이블을 초기화하여 사용할 준비를 합니다. 해시 테이블을 초기화하고, 해시 함수와 비교 함수를 설정하여 보충 페이지 테이블을 올바르게 동작하도록 준비합니다.
page_hash, page_less
unsigned
page_hash (const struct hash_elem *p_, void *aux UNUSED) {
const struct page *p = hash_entry (p_, struct page, hash_elem);
return hash_bytes (&p->va, sizeof p->va);
}
bool
page_less (const struct hash_elem *a_, const struct hash_elem *b_, void *aux UNUSED) {
const struct page *a = hash_entry (a_, struct page, hash_elem);
const struct page *b = hash_entry (b_, struct page, hash_elem);
return a->va < b->va;
}
1. page_hash 함수
- 입력으로 주어진 해시 엘리먼트(struct hash_elem)를 해시 테이블에서 사용할 키로 변환합니다.
- p_ 매개변수를 struct hash_elem 형태로 캐스팅하여 struct page 포인터로 변환한 뒤 p 변수에 저장합니다.
- p->va는 struct page의 멤버 변수로, 가상 주소(Virtual Address)를 나타냅니다.
- hash_bytes 함수를 사용하여 p->va의 바이트 표현을 해시 키로 변환한 값을 반환합니다.
- sizeof p->va를 통해 p->va의 크기를 해시 키로 사용합니다.
2. page_less 함수:
- 입력으로 주어진 두 해시 엘리먼트(struct hash_elem)를 비교하여 정렬 순서를 판단합니다.
- a와 b 매개변수를 각각 struct hash_elem 형태로 캐스팅하여 struct page 포인터로 변환한 뒤 a와 b 변수에 저장합니다.
- a->va와 b->va는 각각 struct page의 멤버 변수로, 가상 주소(Virtual Address)를 나타냅니다.
- a->va와 b->va를 비교하여 a->va가 b->va보다 작으면 true를 반환하고, 그렇지 않으면 false를 반환합니다.
- page_less 함수는 주로 해시 테이블에서 페이지를 정렬하기 위해 사용됩니다. 가상 주소를 기준으로 페이지를 정렬하고 비교할 때 사용되는 함수입니다.
이러한 해시 함수와 비교 함수는 Pintos 프로젝트에서 페이지 관리 및 가상 메모리 시스템의 핵심 부분에서 사용되며, 페이지 테이블 등에서 페이지를 저장하고 탐색하는 데에 활용됩니다.
spt_find_page
struct page *
spt_find_page (struct supplemental_page_table *spt UNUSED, void *va UNUSED) {
struct page *page = NULL;
/* TODO: Fill this function. */
page = (struct page *)malloc(sizeof(struct page));
struct hash_elem *e;
// va에 해당하는 hash_elem 찾기
page->va = pg_round_down(va); // page의 시작 주소 할당
e = hash_find(&spt->spt_hash, &page->hash_elem);
free(page);
return e != NULL ? hash_entry(e, struct page, hash_elem) : NULL;
}
위의 코드는 Pintos 프로젝트의 보충 페이지 테이블에서 주어진 가상 주소(va)에 해당하는 페이지를 찾는 함수인 spt_find_page입니다.
1. 함수 시그니처:
- struct supplemental_page_table *spt: 보충 페이지 테이블을 가리키는 포인터입니다. (UNUSED 키워드로 사용하지 않을 변수임을 명시합니다.)
- void *va: 찾고자 하는 가상 주소입니다. (UNUSED 키워드로 사용하지 않을 변수임을 명시합니다.)
- 반환값: 가상 주소에 해당하는 페이지를 가리키는 struct page 포인터입니다.
2. 함수 동작:
- struct page *page 변수를 NULL로 초기화합니다. 이 변수는 가상 주소에 해당하는 페이지를 가리키기 위한 용도로 사용됩니다.
- malloc 함수를 사용하여 struct page의 메모리를 동적으로 할당합니다. 이렇게 할당한 메모리는 나중에 해제될 것입니다.
- struct hash_elem *e 변수를 선언합니다. 이 변수는 해시 테이블에서 찾은 엘리먼트를 가리키기 위해 사용됩니다.
- pg_round_down 함수를 사용하여 주어진 가상 주소(va)를 페이지의 시작 주소로 내림(round down)합니다. 이렇게 얻은 시작 주소를 page->va에 할당합니다.
- hash_find 함수를 사용하여 보충 페이지 테이블(spt)의 해시 테이블에서 page->hash_elem에 해당하는 엘리먼트를 찾습니다.
- free 함수를 사용하여 page가 가리키는 동적으로 할당한 메모리를 해제합니다.
- 찾은 엘리먼트(e)가 NULL이 아니라면, 해당 엘리먼트가 가리키는 페이지를 hash_entry 매크로를 사용하여 가져옵니다. 가져온 페이지를 반환합니다. 그렇지 않으면 NULL을 반환합니다.
이 함수는 주어진 가상 주소에 해당하는 페이지를 보충 페이지 테이블에서 검색하여 반환하는 역할을 수행합니다. 이를 위해 주어진 가상 주소를 페이지의 시작 주소로 변환하고, 해시 테이블에서 해당 엘리먼트를 찾아 페이지를 반환합니다.
spt_insert_page
bool
spt_insert_page (struct supplemental_page_table *spt UNUSED,
struct page *page UNUSED) {
int succ = false;
/* TODO: Fill this function. */
return hash_insert(&spt->spt_hash, &page->hash_elem) == NULL ? true : false;
}
위의 코드는 Pintos 프로젝트의 보충 페이지 테이블에 페이지를 삽입하는 함수인 spt_insert_page입니다.
1. 함수 시그니처:
- struct supplemental_page_table *spt: 보충 페이지 테이블을 가리키는 포인터입니다. (UNUSED 키워드로 사용하지 않을 변수임을 명시합니다.)
- struct page *page: 삽입할 페이지를 가리키는 struct page 포인터입니다. (UNUSED 키워드로 사용하지 않을 변수임을 명시합니다.)
- 반환값: 페이지 삽입이 성공했을 경우 true, 실패했을 경우 false를 반환합니다.
2. 함수 동작:
- int succ 변수를 false로 초기화합니다. 이 변수는 페이지 삽입 성공 여부를 나타내는 용도로 사용됩니다.
- hash_insert 함수를 사용하여 보충 페이지 테이블(spt)의 해시 테이블에 page->hash_elem을 삽입합니다.
- hash_insert 함수는 해시 테이블에 새로운 엘리먼트를 삽입하고, 삽입이 성공하면 NULL을 반환합니다.
- 따라서 hash_insert 함수의 반환값이 NULL인 경우에는 페이지 삽입이 성공한 것이므로 succ 변수를 true로 설정합니다.
- 그렇지 않으면 페이지 삽입이 실패한 것이므로 succ 변수는 그대로 false로 유지됩니다.
- succ 변수의 값을 반환하여 페이지 삽입 성공 여부를 알려줍니다.
이 함수는 주어진 페이지를 보충 페이지 테이블에 삽입하는 역할을 수행합니다. 이를 위해 hash_insert 함수를 사용하여 페이지의 hash_elem을 보충 페이지 테이블의 해시 테이블에 삽입합니다. 삽입이 성공하면 true를 반환하고, 실패하면 false를 반환합니다.