mmap과 munmap구현이 끝나고 해야될 건 swap in/out 구현과 copy-on-write 구현이었다.
swap in/out 은 file_backed_page 일 때와 anonymous_page 일 때로 나뉘어 지는데, 각 page마다 구현방법이 다르다.
file_backed_page는 disk에 실제 파일이 있기 때문에, swap_out 할 때 page의 내용이 변경되었으면(dirty bit로 판별가능) disk의 파일에 내용을 덮어씌우고 frame을 비워주면 된다. swap_in 할 때는 그냥 disk의 file을 가지고 오면 된다. anonymous_page는 disk에 파일이 없기 때문에 disk의 swap영역에 따로 저장해두고 꺼낼 때도 그곳에서 꺼내야 한다. swap_out 할 때 swap 영역에서 비어있는 sec_no를 찾고 그곳에 내용을 저장해두고 frame을 비워준다. swap_int 할 때는 저장해둔 sec_no에서 내용을 가지고 온다. 이 내용대로 구현을 하면 swap in/out을 완성할 수 있다.
다음은 copy-on-write 구현이었는데, 중간발표에서 이미 cow를 하신 분이 답지를 뿌리셔서 비교적 쉽게 구현할 수 있었다.
지금의 fork에선 자식 프로세스는 새로운 프레임을 만들어서 부모의 프레임을 복제한다. 부모의 프레임수 대로 자식의 프레임이 만들어진다는 것이다. 그런데 이것은 바로 닥쳤을 때 해주는(?) 운영체제의 디자인에 부합하지 않는다. copy-on-write란 fork 했을 때 자식은 부모의 프레임을 같이 읽고 write를 하려고 할 때 새로운 프레임을 만들어서 복제하고 작업을 하는 것을 말한다.
구현은 기존 supplemental_page_table_copy 에서 page와 frame까지 만들던 것을 page까지만 만들고 부모의 프레임과 연결시켜놓는다. 그리고 page_fault가 났을 때 cow인 경우인지를 체크해서 새로운 프레임을 할당받고 부모의 내용을 복사해주면 된다. 그리고 또 생각해야할 문제는 frame을 destroy할 때인데, 자식이나 부모가 종료될 때 frame을 지우게 되는데 그 프레임을 보고있는 다른 프로세스가 있을 수 있기 때문에 참조하는 녀석들이 있으면 지우지 말아야 한다. 이 부분은 frame 구조체에 indegree_cnt를 추가하고 copy 될때 개수를 늘리고, fault가 나서 프레임을 새로 만들때와 destroy 할때 개수를 줄여서 참조하는 녀석이 아무도 없는 경우에만 frame을 지우도록 처리했다. (cow를 분명 다 구현한 것 같은데 자꾸 안돼서 팀원들과 새벽 5시까지 디버깅을 하다가 결국 오류를 다 잡아내고 퇴근한 그날 너무 행복했다..)
이번주 우리조의 발표주제는 swap out을 시킬 때 어떤 frame을 고를지 정하는 victim policy에 대한 주제였다. gpt에 따르면 가장 효율적인 알고리즘은 LRU(Least Recently Used)라고 한다. 상식적으로 생각했을 때 최근에 사용된 애가 아닌 가장 늦게 사용된 녀석을 고르는게 효율적인 것은 당연하다고 생각한다. 그런데 이 방법은 frame에 접근한 모든 순간에 타임스탬프를 업데이트하거나 리스트의 맨 뒤로 보내는 등의 처리를 해줘야 하기 때문에 구현하기가 복잡하고 오버헤드가 크다. 그래서 실제로 채택한 방법은 Second Chance 방법이다. 구현하기도 쉬운데 나름 효율적이라고 한다. 이건 말 그대로 두번째 기회를 주는 방식으로 pml4에 저장되어 있는 access bit를 이용해서 접근한 적이 있는 지를 체크하고, 접근한 적이 있다면 bit를 0으로 만들어주고 다음 녀석을 살펴본다. 이렇게 계속 검색해 나가다가 access된 적 없는 녀석을 뽑거나 아무도 없다면 그냥 첫번째꺼 뽑는 방법이다.
이번 과제를 하면서 특히 신경 쓴 것중의 하나는 lock을 거는 것 이었다. 우리가 사용한 lock은 총 세가지로, file_lock은 지난 프로젝트때부터 file 관련 함수에 쓰던 lock이고, 이번에 frame_list와 swap_table은 전역으로 모든 프로세스가 사용하는 것이기 때문에 frame_lock과 swap_lock을 만들어 사용하는 모든 곳에 꼼꼼하게 걸어주었다. lock을 걸어서 그런지 동작하는 속도가 느려지긴 했지만 자주 터지던 것들이 안터지는 모습을 보며 행복했다.
정말 길고도 길었던 핀토스가 드디어 끝났다. 지금 되돌아보면 다 할만한 것 같은데 핀토스의 모든 주차는 처음에 너무 막막했다. 그리고 흐름을 파악하는게 너무 어려웠다. 사실 초반엔 나 혼자서는 흐름을 거의 못 파악했고 주변 친구들의 설명으로 알아갔다고 본다. 도움을 준 친구들이 너무 고마웠다! 이제는 2주간의 재정비 시간과 정글의 마지막 관문인 나만무만을 남겨두고 있는데, 정글이 끝나가는 것 같아 벌써 서운해지려고 한다. 여기 와서 정말 다양한 사람들을 만났다. OO님 어디까지 들어가는거예요.. 분들과 코딩 몬스터분들이나 똑똑하고 배울 게 많은 분들 등등 귀한 인연을 많이 만나서 좋았다. 남은 기간동안 아쉽지 않게 열심히 해야지!
'정글' 카테고리의 다른 글
정글 [week10] Pintos-KAIST Project 3 :: VIRTUAL MEMORY (0) | 2024.05.21 |
---|---|
정글 [week08] Pintos-KAIST Project 2 :: USER PROGRAMS (0) | 2024.05.14 |
정글 [week07] Pintos-KAIST Project 1 :: Alarm Clock (0) | 2024.04.27 |
[정글 WEEK00] 개발일지 - 정글러 동선 (2) | 2024.03.17 |