일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 노가다
- 황금 장미
- alarm clock
- 셋업
- 가테
- 글루민
- 일지 시작한 지 얼마나 됐다고
- multi-oom
- 핀토스 프로젝트 2
- Project 1
- 끝
- 아직도 실험 중
- 핀토스 프로젝트 4
- 제발흰박
- 바빠지나?
- botw
- 핀토스 프로젝트 3
- 핀토스 프로젝트 1
- 마일섬
- 글리치
- PINTOS
- 자 이제 시작이야
- 파란 장미
- 내일부터
- 핀토스 프로젝트
- Today
- Total
거북이의 쉼터
(2022.03.08) Memory Mapped Files 가이드라인 (1) 본문
드디어 VM_UNINIT과 VM_ANON의 좁고 편협한 사고에서 벗어나 VM_FILE을 다루게 되는 mmap이다.
보이는 것처럼 나는 아주 "절거워"질 예정이다.
지금 여기까지 해온 사람들에게는 익숙하겠지만 mmap은 파일의 내용을 메모리 상에 올려 입출력을 빠르게 해줄 수 있는 기법이다. 구현할 mmap의 형태는 다음과 같으며,
void *mmap (void *addr, size_t length, int writable, int fd, off_t offset);
addr에 주어진 length 만큼의 공간에 fd에 대응되는 파일의 offset에 해당하는 내용을 매핑한다. 이 때, 매핑된 해당 페이지의 쓰기 권한은 writable을 따른다. 주어진 addr은 반드시 page-aligned 되어 있어야 하며, 만약 매핑된 길이가 PGSIZE의 배수가 아닐 경우, 해당 부분은 0으로 채운뒤, 파일에 내용을 다시 쓸 때 날려버린다. VM_ANON과 마찬가지로, VM_FILE도 lazy loading 되어야 하며, VM_UNINIT을 활용해 spt에 넣어놓은 뒤에 fault가 났을 때 할당하는 방식으로 진행해야 한다.
기타 주의 사항은 열린 파일의 길이가 0일 때, 주어진 addr이 NULL일 때, length가 0일 때, stdin과 stdout에 해당하는 파일을 매핑하려 할 때이다. 기본적으로 해당 경우들에 대해서 mmap은 모두 실패했다는 반환값인 NULL을 반환해야 한다. 단, 열린 파일의 길이가 0일 때는 성공해도 괜찮으나, 해당 주소에 접근해 읽으려 할때는 실패해야 한다는 조건이 붇는다. (그냥 NULL을 반환하는 것이 속편할 것이다.) 그 외에도 매핑하려는 영역이 기존에 있는 영역하고 겹칠 경우 실패해야 한다.
예외 처리와 제약 조건이 참 많은 함수이다. 또한, 매뉴얼 하단에 적힌 내용도 고려해 mmap을 구현할 필요가 있다.
Closing or removing a file does not unmap any of its mappings. Once created, a mapping is valid until munmap is called or the process exits, following the Unix convention. See Removing an Open File for more information. You should use the file_reopen function to obtain a separate and independent reference to the file for each of its mappings.
이에 mmap을 한다는 것은 mmap을 할 때 사용한 fd와 연동된 파일과는 별개로 thread에서 따로 mmap된 파일을 관리해야 한다는 것을 의미한다. file_reopen을 사용하라고 나와 있으니 관리할 file을 만들 때 사용하도록 한다.
mmap이 있으면, 해제하는 것도 있어야 한다. 이를 위해 munmap을 구현하라고 나와있다.
void munmap (void *addr);
인자의 제약 조건은 반드시 같은 프로세스에서 mmap이 된 addr이어야 하며, munmap이 불리지 않은 가상주소여야 한다. exit 등에서 남은 매핑들이 정리될 때 사용될 것이다. 어떤 이유에서든지 해당 함수가 호출된다면, 기존 파일에 변경된 사항들을 적용시켜줄 필요가 있다. 이 때, 반드시 변경된 페이지들만 디스크에 쓰도록 하고 그렇지 않은 페이지는 모두 단순히 날리면 된다. 이러한 구분을 위해 dirty bit을 사용할 것이다.
매뉴얼은 해당 함수들을 구현하기 위해 추가로 건드리면 좋을 함수들을 추천한다.
void vm_file_init (void);
bool file_backed_initializer (struct page *page, enum vm_type type, void *kva);
static void file_backed_destroy (struct page *page);
vm_file_init은 mmap, munmap을 사용하기 위해 필요한 인프라를 구축하는 역할을 위해 필요하다. file_backed_initializer는 VM_UNINIT에서 VM_FILE로 바뀔 때 호출되는 함수이며, file_backed_destroy는 spt를 비울 때, 또는 munmap을 할 때 사용될 것이다. file_backed_destory에서 dirty bit에 유의하라고 나와 있다.
이제 매뉴얼에서 살펴볼 것은 다 본 것 같다. mm 또는 mmap이 붙어있는 테케는 성공해야 할 것 같은데 이제부터는 swapping이 일어나야 하는지 확실하지가 않아서 오리무중이다. 일단 내일부터 mmap 관련 함수를 구현해보도록 하자.
'코딩 삽질 > KAIST PINTOS (CS330)' 카테고리의 다른 글
(2022.03.11) Swap In/Out 가이드라인 (0) | 2022.03.11 |
---|---|
(2022.03.09) Memory Mapped Files 가이드라인 (2) (0) | 2022.03.09 |
(2022.03.08) Stack Growth 구현 (0) | 2022.03.08 |
(2022.03.08) Stack Growth 가이드라인 (0) | 2022.03.08 |
(2022.03.06) Anonymous Page 가이드라인 (2) (0) | 2022.03.06 |