PintOS에서 process_wait 올바르게 구현하기
0. 서론
2주차에서 구현한 코드 중 process_wait
및 process_exit
가 심각한 오류를 내포하고 있음을 발제를 통해 확인할 수 있었다. 이를 해소하기 위한 방법을 알아보자.
1. 기존 코드의 문제점
기존 process_wait()
과 process_exit()
은 아래와 같이 구현되어 있었다.
여기서 문제가 되는 코드는 process_exit()
의
이다.
위 코드에 의해 exit되는 process들은 전부 세마포의 값을 내리고 스스로 block상태가 되게 되는데, 만약 해당 프로세스의 부모 프로세스가 wait()
시스템 콜을 호출하지 않는다면 이들은 영원히 깨어나지 못하게 된다.
즉, sema_down()
은 항상 호출되는데 sema_up()
은 조건부로 호출되므로 문제가 발생한다.
따라서 이를 위해선 문제가 되는 sema_down()
과 sema_up()
을 호출하지 않아야 하므로 아래와 같은 코드가 되어야 한다.
그런데 이렇게 두 번째 세마포를 사용하지 않으면 발생하는 또 다른 문제가 있다(사실 이 문제 때문에 두 번째 세마포sema_for_free
를 사용했다).
바로 child thread가 process_exit()
이후 제거되게 되면 list_remove(&child->child_elem)
의 child 포인터가 댕글링 포인터가 된다는 점이다.
2. 해결 방안
따라서 이를 해소하기 위해서 댕글링 포인터가 발생할 가능성을 완전히 배제하기 위해 부모가 child pointer를 관리하지 않도록 수정했고, 대신 child의 tid와 exit_status를 리스트 형태로 가지도록 하였다.
또, sync_read
나 sync_write
등의 테스트를 통과하기 위해 각 자식 정보마다 고유의 sema_for_wait
을 가지도록 했다.
그리고 해당 구조체를 위한 인터페이스들을 정의해 주었다.
이후 process_wait()
과 process_exit()
을 아래와 같이 수정해준다.
이외에도 syscall.c
등에서 시스템 콜 함수들을 조금씩 바꾸어야 하는데, 그 부분은 간단하므로 생략한다.