미소를뿌리는감자의 코딩
[Pintos_project3 (4)] vm_alloc_page_with_initializer 본문
1. 개요
vm_alloc_page_with_initializer는 페이지 type에 따라, UNINIT 페이지를 초기화 하는 함수이다.
Anonymous page 파트에 들어와서, 전체적인 흐름을 한번 정리해 보았다.
vm_alloc_page_with_initializer가 실행이 되면서, swap_in 핸들러와, 초기화 함수(initializerFunc)를 설정해 준다. 이후 spt에 해당 페이지를 추가해 주는 과정을 거친다.
이후, 프로그램 실행 중, 페이지 fault가 발생하게 되면 해당 elem을 찾게되고, UNINIT 상태임을 확인하게 되면, 이전에 초기화 시 설정해 두었던 swap_in 핸들러를 통해 initializerFunc에 저장해두었던 함수를 실행하게 된다.
2. 본문
bool
vm_alloc_page_with_initializer (enum vm_type type, void *upage, bool writable,
vm_initializer *init, void *aux) {
ASSERT (VM_TYPE(type) != VM_UNINIT)
struct supplemental_page_table *spt = &thread_current ()->spt;
/* Check wheter the upage is already occupied or not. */
if (spt_find_page (spt, upage) == NULL) {
/* TODO: Create the page, fetch the initialier according to the VM type,
* TODO: and then create "uninit" page struct by calling uninit_new. You
* TODO: should modify the field after calling the uninit_new. */
/* TODO: Insert the page into the spt. */
/* [Pseudo]
* page 할당 -> malloc 이용 || uninit_new를 통해서 uninit를 상태로 가지는 페이지 만들기
* swap_in handler 설정
* 초기화 함수(vm_initializer) 설정. page type에 따라, anon_initializer or. lazy_load_segment
* spt에 field가 설정된 uninit페이지 추가 */
struct page *page = (struct page *)malloc(sizeof(struct page));
typedef bool (*initializerFunc)(struct page *, enum vm_type, void *);
initializerFunc initializer = NULL;
switch (VM_TYPE(type)) {
case VM_ANON:
initializer = anon_initializer;
break;
case VM_FILE:
initializer = file_backed_initializer;
break;
}
uninit_new(page, upage, init, type, aux, initializer);
page->writable = writable;
return spt_insert_page(spt, page);
}
err:
return false;
}
코드를 참조하기에 앞서, pseudo 코드를 작성해보았다. 예상한 흐름대로 코드가 진행된 것 같다.
bool
vm_alloc_page_with_initializer (enum vm_type type, void *upage, bool writable,
vm_initializer *init, void *aux) {
해당 함수의 인자 중, upage가 어떤 것을 나타내는지 잘 모르겠어서 알아보았다.
upage는 할당할 가상 주소를 의미한다.
ASSERT (VM_TYPE(type) != VM_UNINIT)
페이지 타입의 경우엔, VM_UNINIT은 직접적으로 요청될 수 없기 때문에 이를 확인해 준다. VM_ANON, VM_FILE을 설정하면서, 간접적으로 이용되기 때문이다.
if (spt_find_page (spt, upage) == NULL) {
이걸로, 가상 주소에 해당되는 페이지가 이미 존재하는 지 확인하는 작업을 한다.
존재하지 않는다면 페이지를 동적으로 확인한 후, VM_TYPE에 따라 initializer를 설정해 준다.
마지막으로 페이지 상태를 uninit_new 함수를 이용해서 uninit으로 설정해 준다.
/* DO NOT MODIFY this struct */
static const struct page_operations uninit_ops = {
.swap_in = uninit_initialize,
.swap_out = NULL,
.destroy = uninit_destroy,
.type = VM_UNINIT,
};
/* DO NOT MODIFY this function */
void
uninit_new (struct page *page, void *va, vm_initializer *init,
enum vm_type type, void *aux,
bool (*initializer)(struct page *, enum vm_type, void *)) {
ASSERT (page != NULL);
*page = (struct page) {
.operations = &uninit_ops, // 여기서 .type을 VM_UNINIT으로 설정해 줌.
.va = va,
.frame = NULL, /* no frame for now 아직 PM에 할당이 안됨*/
.uninit = (struct uninit_page) {
.init = init,
.type = type,
.aux = aux,
.page_initializer = initializer,
}
};
}
이후 페이지를 spt에 넣어준다.
3. 결과
아직은 123 of 141 tests failed로 동일하다.
'정글 일지' 카테고리의 다른 글
[Pintos_project3 (6)] load_segment & lazy_load_segment (0) | 2024.11.30 |
---|---|
[Pintos_project3 (5)] anon_initializer (0) | 2024.11.30 |
[Pintos_project3 (3)] spt_insert_page (0) | 2024.11.29 |
[Pintos_project3 (2)] spt_find_page (0) | 2024.11.29 |
[Pintos_project3 (1)] supplemental_page_table_init (0) | 2024.11.28 |