KAIST 핀토스를 기반으로 만든 코드는 재배포가 불가능하다고 프로젝트 가이드라인의 legal issue에 명시되어있다.
라이센스를 찾아봤는데 프로젝트에 따라 자기가 작성한 부분도 배포가 불가능하다고 한다.
따라서 코드는 블로그에 첨부하지 않는다.
이걸 코드없이 정리하려니 답이 없어서 내가 구현을 진행한 부분들을 순서대로 기록해봤다.
sleep and awake
기존 timer는 busy waits이 발생하는 구조를 갖고 있었다. 알람 시각에 도달하기를 그저 기다리는 스레드들이 계속 서로에게 CPU 사용 권한을 넘겨주고, 알람 시각이 아니라면 다시 다른 스레드에게 CPU 사용 권한을 넘기는, 이러한 무의미한 토스를 반복하며 CPU의 사용 권한이라는 공유자원에 낭비가 일어나는 것이다.
각 스레드들이 기상시각이 될때까지 ready_list에 포함되지 않게 하고, 기상시각이 되면 ready_list에 들어가 일을 수행하게 하는 구조로 바꾼다면 위의 문제를 개선할 수 있을 것이고, 이것이 이번 소주제의 목적이다.
이를 구현하기 위해 가장 먼저 timer.c를 손봤다.
순서 1 ~ 3
스레드가 자신이 알람을 출력할 시각이 아니면 다시 ready_list로 돌아가던 기존의 구조에서, 알람을 출력할 시각까지 threads_sleep()하는 것으로 바꾸어, 무의미한 줄세우기를 스킵한다.
이렇게 바꾸면 대부분의 시간 동안 CPU의 사용 권한은 idle이 갖고 있게 된다. 그렇다면 idle은 자고 있는 스레드를 언제 깨워야 할지 그 기상시각을 알 필요가 있다. 이를 해결하기 위해 기상시각을 호출하는 함수 threads_awaketime()를 사용하고, 현재 시각이 기상시각에 도달했을 때 스레드를 깨우는 함수 threads_awake()를 실행하도록 한다.
timer의 구조를 위와 같이 바꾸었을 때, timer는 busy waits을 개선하게 된다. 이제 timer에서 구현 없이 미리 사용했던 함수와 변수들을 thread.*에서 구현하면 된다.
순서 4 ~ 9
thread_sleep(), threads_awake()은 각각 두 개의 기능을 가진다.
thread_sleep()
기능 1 : sleep_list를 탐색해서 curr_tick에 일어나야 할 모든 스레드를 unblock
기능 2 : next_awaketick를 sleep_list의 스레드들의 awaketick 중 최솟값으로 갱신
threads_awake()
기능 1 : sleep_list를 탐색해서 curr_tick에 일어나야 할 모든 스레드를 unblock
기능 2 : next_awaketick를 sleep_list의 스레드들의 awaketick 중 최솟값으로 갱신
위 기능을 만족하도록 필요한 변수들을 선언하고 구현했다.
순서 10 ~ 11
마지막으로 threads.c의 수정에 따라 필요한 구문들을 threads.h에 추가해주는 것으로 busy waits을 개선한 구조가 완성되었다.
'Week 08 ~ 13 : KAIST PintOS' 카테고리의 다른 글
[KAIST PintOS Project] PRJ 3를 마치며 (0) | 2022.01.25 |
---|---|
[KAIST PintOS Project] PRJ 2를 마치며 (0) | 2022.01.11 |
[KAIST PintOS Project] PRJ 1을 마치며 (0) | 2021.12.30 |
[KAIST PintOS Project 1] 3. synchronization (0) | 2021.12.30 |
[KAIST PintOS Project 1] 2. priority scheduling (0) | 2021.12.29 |