-
[SW 정글 70일차] Pintos project 2 - System Calls 구현 2일차기타/SW 사관학교 정글 2021. 10. 12. 02:10
오늘은 지난 번에 system calls halt()와 exit() 구현에 이어 진행해보려고 한다.
/* 구현 완료 */ void halt (void) NO_RETURN; /* 구현 완료 */ void exit (int status) NO_RETURN; pid_t fork (const char *thread_name); int exec (const char *file); int wait (pid_t); bool create (const char *file, unsigned initial_size); bool remove (const char *file); int open (const char *file); int filesize (int fd); int read (int fd, void *buffer, unsigned length); int write (int fd, const void *buffer, unsigned length); void seek (int fd, unsigned position); unsigned tell (int fd); void close (int fd);
1. wait (pid_t)
wait() syscall을 처음 접했을 때 느낀 점은 os에서도 모성애가 느껴진다였다.
wait()는 자식 프로세스 pid를 인자로 받아 해당 자식 프로세스를 기다리면서 자식의 exit status를 기다리는 시스템 콜이다.
자식 프로세스가 exit되지 않은 상태라면 종료될 때까지 기다리고 종료되었을 때의 status를 반환해준다.
만약에 자식 프로세스가 exit() 시스템 콜을 호출하지는 않았지만 커널에 의해 종료되었다면(예를 들어, 예외 상황이 발생한 경우) -1을 반환한다.
wait()가 fail이거나 -1을 반환하는 경우는 2가지가 존재한다.
1) 인자로 받은 pid를 가진 프로세스가 wait()를 호출한 프로세스의 직계 자식이 아닐 때이다.
만약에 A 프로세스가 B 프로세스를 fork하고 B 프로세스가 C 프로세스를 fork했다면 A 프로세스는 B 프로세스가 종료되었을지라도 C 프로세스를 wait할 수 없다는 것이다.
2) 하나의 프로세스는 주어진 자식에 대해 최대 한번만 wait()을 호출할 수 있다.
wait(pid_t) 구현은 process.c에 있는 process_wait()에 구현하면 된다.
일단은 현재 실행 중인 스레드(wait을 호출한 스레드)가 가지고 있는 child_list를 탐색해야한다.
for문을 이용하여 child_list의 처음부터 끝까지 보며 인자로 받은 pid와 같은 자식 프로세스가 존재하면 해당 프로세스를 리턴하고 없다면 null을 반환하는 새로운 함수 get_child_with_pid()를 만들어줬다.
null을 반환하면 해당 자식 프로세스가 없다는 것을 의미하니까 wait()에서 -1을 리턴하고 끝내게 구현했다.
이후에 semaphore가 초기값이 0인 wait_sema을 사용하였고 해당 세마포어를 sema_down해줬다.
이렇게 하면 wait를 호출한 프로세스는 누군가가 sema_up할 때까지 기다려야하고 여기서 누군가는 wait()하고 있는 자식프로세스이다.
기다리고 있던 자식 프로세스가 process_exit()을 통해 exit을 하려했을 때 wait_sema를 sema_up해주고 할당받았던 모든 메모리를 free하기 전에 free_sema(마찬가지로 세마포어가 0으로 초기화)라는 것을 sema_down을 해준다.
이렇게 되면 wait_sema를 sema_up해주기를 기다리던 wait()를 호출한 프로세스가 다시 작업을 수행하게 되면서 자식 프로세스의 exit status를 받아오고 자식 프로세스가 할당받았던 메모리를 회수할 수 있도록 free_sema를 sema_up해주고 자식 프로세스의 exit status를 리턴하는 것으로 마무리 한다.
1. int exec (const char *cmd_line)
현재 실행 중인 프로세스를 인자로 받은 command line을 argument passing하여 얻은 file_name으로 변경하는 역할을 한다.
exec()가 성공적으로 이루어졌다면 아무 것도 반환하지 않고 프로그램이 로드되지 않거나 어떠한 이유로 실행되지 않을 경우에는 -1을 반환하고 프로세스를 종료시킨다.
exec의 코드 구현은 일단은 인자로 받은 file_name이 현재 exec를 호출한 프로세스의 유저영역 메모리에 있는지부터 확인을 해야한다.
유저영역에 있다는 것을 확인하기 위해서 어제 만든 check_address()함수를 쓰고 유저영역에 있다는 것이 확인되면 다음 작업을 진행하고 커널영역에 있다면 프로세스를 종료시킨다.
그 후에 file_name을 저장해줄 페이지를 할당받고 해당 페이지에 file_name을 넣어준다.
그 후에 process_exec()함수를 실행하여 현재 실행 중인 프로세스를 file_name으로 context switching해주는 작업을 진행하면 된다.
[오늘의 나는 어땠을까?]
오늘은 10시 30분에 권영진 교수님의 OS강의를 들었다.
이전에도 들었을 때 짧은 소감을 기록한 적이 있는데 역시나 그 때와의 느낌과 똑같이 다시 대학교를 입학하고 싶다는 생각이 들만큼 좋은 강의이다.
뭔가 나 혼자서 OS를 공부할 떄에는 누군가가 설명한 블로그, 책을 기반으로 공부하면서 그들이 얘기하는 범위 내에서 좁은 시야로 공부했다면 권영진 교수님의 OS강의를 들으면 높은 곳에서 OS라는 것을 본다는 느낌이다.
나도 언젠가 사람들 앞에서 내가 깊게 공부한 나만의 영역을 발표하면서 누군가 나를 지금의 내가 권영진 교수님에게 느끼는 감정을 느끼게 하는 사람이 되고 싶다.
말이 길고 서두가 없어보이지단 간단히 말해서 컴퓨터 사이언스라는 폭 넓은 분야에서 나만의 전문분야가 있고 그 전문분야에 대한 전문성을 인정받고 싶다는 것이다.
정글이 끝나고 이 몰입경험을 유지하여 목표를 이뤄내자.
'기타 > SW 사관학교 정글' 카테고리의 다른 글
[SW 정글 72일차] Pintos project 2 - System Calls 마무으리 (0) 2021.10.14 [SW 정글 71일차] Pintos project 2 - System Calls 구현 3일차 (0) 2021.10.12 [SW 정글 69일차] 오늘은 Concurrency 되짚어 보기 (0) 2021.10.11 [SW 정글 68일차] Pintos project 2 - System Calls 구현 1일차 (0) 2021.10.10 [SW 정글 67일차] Pintos project 2 - Argument Passing 구현 (0) 2021.10.08