[PintOS] PROJECT4: VIRTUAL MEMORY(Stack Growth, Memory Mapped Files, Swap In/Out) - 4주차 WIL (3) - fork()시에 부모의 swap-out된 페이지까지도 모두 자식에서는 물리메모리에 올리는 전략을 선택하게 된 이유

bongf·2022년 6월 21일
0

정글

목록 보기
19/20

Swap-disk

  • 스왑공간이 추가되면 각 프로세스는 마치 큰 가상 큰 메모리가 있는 환상을 줄 수 있다. (인용, 책, 운영체제 아주 쉬운 세가지 이야기)
  • 스왑공간에 필요 없는 데이터를 올리고 필요할 때 스왑공간으로부터 데이터를 읽어오면서 큰 메모리를 제공해주는 것 같은 효과를 낼 수 있다.
  • 그러나 이 스왑 디스크 때문에 fork(), exit()시 등에서 매핑 관리가 까다로웠다

fork()시에 부모의 swap-out된 페이지까지도 모두 자식에서는 물리메모리에 올리는 전략을 선택하게 된 이유

겪었던 문제 - 부모의 swap-out된 페이지를 자식에 복사할 때 똑같이 swap-out 된 페이지로 만들자

  • 부모가 swap-out 된 페이지를 갖고 있다고 할 때, 이를 자식에 복사할 때 어떻게 데이터를 복사할 것인가에 대한 고민을 했다.
  • 처음에는 부모의 swap-out 된 페이지를 복사할 때 의 swap-disk로 부터 데이터를 읽어올 entry 지점을 복사하고, 자식에게도 swap-out 된 페이지로 만들었다 (자식도 필요할 때 swap-in 시키라는 목적으로)
  • 그렇게 되면 자식이 swap-disk에서 데이터를 읽으면 부모가 읽지 못하는 문제가 생기지 않을까? 생각했다.
    • 우리는 디스크의 상태를 bitmap으로 관리하면서 해당 disk의 섹터에 데이터가 있는지 없는지를 true, false로 관리하는 것으로 구현했다. (false라면 해당 섹터에 데이터를 쓸 수 있다)
  • 그런데 자식이 먼저 해당 데이터를 읽어버린다면? 해당 비트는 false가 되고, 부모는 이를 읽을 수 없을 것이다(false로 변경된 비트맵이 가리키는 디스크 섹터에 다른 swap-out 된 페이지가 자신의 데이터를 입력할 수 있다)

해결책 시도1 : 자식에게 is_child라는 flag를 주었다.

  • 그렇게해서 자식이 데이터를 읽는다면 해당 부분의 비트맵 값은 true로 유지되고 다른 페이지가 데이터를 변경할 수 없어 부모는 자신이 저장한 데이터를 읽을 수 있을 것ㅅ이라 생각했다.
  • 그러나 이렇게 구현했음에도 계속 테스트가 통과되지 못했고 어디서 에러가 났는지 알 수는 없었다.
  • 고민을 계속하다 어디가 문제인지 알아낼 수 있었다.

다시 문제 : 그렇게 되면 부모가 swap-disk로부터 데이터를 먼저 읽으면 자식이 읽을 데이터가 없다.

  • 그러나 테스트는 실패했는데 왜 실패했을까를 고민해보고 아래와 같이 작성했다.
  • 부모든 자식이든 해당 부분이 참조되면 page_fault가 나서 swap_in을 수행할텐데 먼저 접근하는 것이 자식이라는 보장이 없다.
  • 만약 부모가 해당 부분을 먼저 읽어버리면 자식은 접근했을 때 이상한 값을 읽을 가능성이 있다(부모는 데이터를 읽고 비트를 false로 만들고 다른 페이지가 false를 확인하고 해당 부분에 데이터를 작성한 경우)

해결 시도 2 : page 복사시에 자식에게는 부모의 데이터가 swap-in/out에 상관 없이 모두 물리메모리에 올린다.

  • 그렇기 때문에 page를 복사할 때 아예 자식은 물리메모리에 전부 올려버렸다. 그렇게 되면 fork() 할 동안은 부모는 잠들게 되므로 항상 자식이 먼저 해당 디스크에서 값을 것이 보장된다.
  • 다음과 같이 구현했다. 부모의 데이터가 물리 메모리에 없는 경우, swap-out 되었는지 확인하고 물리 메모리를 할당 받는다.. 그리고 나서 'annon_child_swap_in()'으로 부모가 swap_out 한 데이터를 읽어서 실제 물리 메모리에 올려버린다.
  • 이 때 부모가 사용한 swap_in() 함수가 아니라 'annon_child_swap_in()'를 사용한다. 거의 비슷한 기능임에도 함수를 구분한 이유는swap-disk를 관리하는 비트맵을 수정하지 않게 하기 위함이다 (비트값은 true로 값이 유지되어 부모는 다음 참조 때 디스크에서 값을 읽을 수 있다
  • 물론 부모의 swap-out 된 것까지 자식이 모두 물리메모리에 올리게 되므로 물리 메모리는 부족할 터인데 이는 자식이 따로 swap-disk에 쓰도록 해야 한다.
  • 그렇기 떄문에 fork()시에 자식은 부모의 모든 데이터를 물리 메모리에 올리게 하도록 구현하는 전략을 선택하게 되었다.
profile
spring, java학습

0개의 댓글