그 외 알게 된 내용에 대해서는 아래에 정리했다.
구현하면서 돌아가는데 왜 되는지 몰랐던 것들
우리조가 구현한 pintOS에는 파일을 페이지에 매핑한 페이지(Memory Mapped Files)에 대해서는 전역변수로 frame-list를 선언하고, 이로 관리했다.
이를 삭제해주는 위치 때문에 문제가 발생했다.
처음에는 프로세스가 종료될 때 호출되는 process_exit()
함수에서 process_cleanup()
을 호출하고 이 process_cleanup()
에서 해당 매핑을 해제하고, 매핑 테이블(frme table)을 삭제했다.
그렇지만, TEST에서 자식을 종료후 부모가 동일 파일을 확인했을 때 부모가 변경된 내용을 읽지 못하는 일이 발생했다. 왜 그런지 이런 저런 시도를 해보다가 매핑을 해제하는 (변경이 있으면 파일에 써주는 작업을 해주는) 함수를 더 일찍 선언했더니 통과되었다.
일단 돌아가게 하고 왜 그러는지 이해해했다.
핵심은 저기에 작성된 sema_up(&curr->load_sema);
이었다. 지금 프로세스 종료 흐름은 자식을 fork()한 후 wait()하면 부모는 자식이 종료될 때까지 자식의 load_sema에 잠든다. 자식은 프로세스가 끝날 때 자신의 load_sema에 잠든 부모를 깨우는데 sema_up(&curr->load_sema);
이 때 일어난 부모가 파일을 확인하면 이전 버전에서는 아직 부모는 변경 전 파일을 읽고 있기 때문에 테스트가 실패했던 것.
이를 위로 올려주면 부모는 변경 후의 파일을 확인하게 되므로 문제가 해결된 것이다.
이를 어디에 두면 될까에 대해서 생각했을 때는 부모를 깨우기 전인 load_sema up 할 때까지만 하면 된다고 생각했다.
프로그램 파일은 변경되면 안되는 파일이기 때문
이다. linux에서는 bss와 같은 수정이 일어나는 segment는 anonymous page로 관리하고, 다른 부분은 file-backed page
로 관리한다고 한다.