-
Pintos project3_Memory Mapped FilesOS/Pintos P.J_3 2022. 1. 22. 19:01
이제 memory-mapped pages에 다루어 보도록 하자
어나니머스 페이지와 달리 memory-mapped pages는 file-backed mappings이다 즉 페이지 안의 데이터는 실제 존재하는 file 데이터를 미러링한 값들이다.
만약 페이지 폴트가 발생하면 물리 frame이 즉시 할당되고 contents들은 파일에서 메모리로 복사된다.
memorry-mapped 페이지들이 unmapped 되거나 swapped out되면 파일에도 이러한 변경사항이 그대로 반영된다.
mmap and munmap System Call
mmap 과 munmap은 memory mapped files를 위한 systemcalls 이다. 현재 우리의 VM system 에서 페이지는 mmap영역에서 lazily load되어야 한다. 그리고 mapped file은 그 자체가 mapping 을 위한 백업 저장소로 사용된다.
위의 두 시스템콜을 구현하기 위해 vm/file.c에 있는 do_mmap과 do_munmap을 구현해야한다.
mmap
/*userprog/syscall.c*/ void *mmap(void *addr, size_t length, int writable, int fd, off_t offset) { if (offset % PGSIZE != 0) { return NULL; } if (pg_round_down(addr) != addr || is_kernel_vaddr(addr) || addr == NULL || (long long)length <= 0) return NULL; if (fd == 0 || fd == 1) exit(-1); // vm_overlap if (spt_find_page(&thread_current()->spt, addr)) return NULL; struct file *target = process_get_file(fd); // struct file *target = find_file_by_fd(fd); if (target == NULL) return NULL; void *ret = do_mmap(addr, length, writable, target, offset); return ret; }
프로세스의 virual address 공간인 addr에 fd로 부터 연 파일을 offset부터 length만큼 매핑한다.
만약 file의 length가 PGSIZE의 배수가 아닌경우 마지막 매핑된 페이지의 몇 bytes는 파일의 끝을 넘어"stickout"될 것이다. page fault가 발생하면 이 바이트를 0으로 set하고 페이지를 디스크에 다시 쓸 때 버린다.
Pintos 에서 virtual page 0 는 매핑되지 않는다고 가정하므로 addr이 0이면 fail이 반드시 난다.
munmap
munmap 함수는 특정 addr에 대해 unamp을 하는 하는 함수로 addr은 아직 매핑이 해제되지 않은 동일 프로세스에서 mmap에 대한 이전 호출에서 반환된 가상주소여야한다.
프로세스가 종료되는 시점(exit)에서 모든 매핑된 메모리는 unmapped되어야 한다.
/*syscall.c*/ void munmap(void *addr) { do_munmap(addr); } /* file.c */ /* Do the mmap */ /* Do the munmap */ void do_munmap (void *addr) { while (true) { struct page *page = spt_find_page(&thread_current()->spt, addr); if (page == NULL) break; struct container *aux = (struct container *)page->uninit.aux; // dirty(사용되었던) bit 체크 if (pml4_is_dirty(thread_current()->pml4, page->va)) { file_write_at(aux->file, addr, aux->page_read_bytes, aux->offset); pml4_set_dirty(thread_current()->pml4, page->va, 0); } pml4_clear_page(thread_current()->pml4, page->va); addr += PGSIZE; } }
만약 두개 이상의 프로세스가 같은 파일을 매핑했다고 두번을 언맵할 필요 없다 UNIX가 알아서 같은 물리 page를 공유하도록 처리하기 떄문이다. 그리고 mmap 시스템콜 또한 페이지가 공유될 것인지 아닌지 여부를 지정할 수있는 인수도 있다.(copy-on-write)
'OS > Pintos P.J_3' 카테고리의 다른 글
Pintos project3_Swap In/Out (0) 2022.01.25 Pintos project3_Stack Growth (0) 2022.01.21 Pintos project3_Anonymous Page (0) 2022.01.21 Pintos project3_Memory management (0) 2022.01.19 [Project 3_Virtual Memory]_Intro (0) 2022.01.11