첫 과제인 Alarm Clock
을 성공적으로 처리하고, 본격적으로 PintOS
의 스케줄링에 딥다이브할 시간이 왔다. 기존의 바보같던 스케줄러를 뚝딱뚝딱 고쳐 똑똑하게 만드는 과정은 너무나 어려웠고, 또 즐거웠다! PintOS
주차가 지옥주라고 불림과 동시에, 정글의 꽃으로 불리는 이유를 알 수 있었다. 정글 끝까지
라는 캐치프레이즈에 걸맞게, 긴 준비를 마쳐 정글의 최종보스를 마주하고 있는 느낌이랄까? 각설하고, 첫 프로젝트의 두 번째 과제에선 어떤 문제들을 해결하고, 어떻게 내가 성장할 수 있었는 지 알아보자.
아주아주아주~ 멍청했던 Busy-wait
방식을 Sleep
방식으로 개선한 후, 다음 과제는 바로 Priority Scheduling
! 세상만사 모든 일에는 우선순위가 있기 마련이다. 당연히 유튜브 보고 누워있기 보단 밥먹기 와 잠자기 가 우선일 것, 이는 컴퓨터도 동일할 것이다. 어떠한 스레드는 다른 스레드보다 급하게 처리되어야 할 수 있고, 반면에 느리게 처리되어도 상관없는 스레드가 있을 터, 또한 이러한 우선순위는 시시각각 변동될 수도 있다. 사용자가 잠시 사용을 멈추고 백그라운드로 밀어놓은 프로그램은 우선순위가 낮아지겠지? 이와 같이 똑똑한 스케줄링을 위해 우선순위에 맞게 작업 순서를 정하는 것은 상당히! 매우! 우아하고 필수적인 과정이라고 할 수 있겠다.
우리에게 주어진 첫 과제는 스레드가 본인의 작업을 처리하기 위해 CPU
점유를 기다리는 리스트인 ready_list
에 진입할 때, 무작정 리스트의 엉덩이에 붙는 것이 아닌 thread
구조체가 가지는 priority
에 알맞는 자리를 찾아 삽입되도록 하는 것. 이렇게 바꿔줌으로써 ready_list
의 스레드는 본인의 우선순위에 맞게 착착~ 이쁘게 서있는 형태가 되겠지? 이 과정은 크게 복잡하지 않았다.
저렇게 ready_list
에 본인 순위에 맞게 딱딱 줄 서서 들어간다면 Priority Scheduling
은 끝 아니야? 싶겠지만, OS
의 세계는 그렇게 녹록치 않다. 여기서 Lock
이라는 개념이 추가되는데, 이는 간단하게 공유 자원이라고 생각하면 된다. 정확히 말하면 동시성 프로그램에서 생기는 공유 자원 충돌을 막기 위한 방법 중 하나인데, 일단은 공유 자원이라고 생각하고 넘어가자. 이런거 하나하나 적어놓을 시간은 없어서.. 다른 잘 적어놓은 블로그를 참조하시길!
결론을 말하자면 공유 자원이라는 개념이 도입되면서, 우선 순위가 높은 스레드들이 우선 순위가 낮은 스레드들의 작업에게 우선순위가 밀리는, 그야말로 억울함 그 자체인 상황이 발생할 수 있다는 것이다. 이를 해결할 수 있는 방법이 Priority Donation
되시겠다. 이러한 도네이션 개념을 계속 확장해나가면서 스레드들의 다양한 상황에서의 억울함을 해소해 주는 것이 이번 챕터의 핵심 개념이었다.
이번 과제에서 가장 크게 통감했던 부분은 코드에서 사용하는 데이터의 구조에 대한 이해가 정말정말 중요하다는 것이다. 비효율적이고 복잡하게 짜여있다고 생각이 들어 데이터 구조를 추상화해서 넘겨버리면, 어김없이 피를 보더라고 😂 다행히 우리 조는 코드를 깊이 뜯어보는 걸 우선으로 생각했기에 수월하게 구조를 이해했고, 다른 조원들에게 이해한 내용을 설명할 기회도 있었다! 참으로 영광스러운 경험...
도저히 맥락을 짚을 수 없어 함수의 동작을 배제하고 코드를 짜내려간 적이 있었다. 바로 lock_acquire
함수 내의 sema_down
이 그녀석인데, 락을 점유 요청하는 함수에서 이 녀석이 대체 왜 필요한지 알 수 없었던 것. 이 녀석을 배제한다면 해당 함수의 흐름이 도저히 이해가 되질 않는다. 이 부분은 다른 팀원분의 도움을 받아 이해했는데, 우리가 배제했던 부분이 해당 락 대기줄에 세워놓고 Blocked 상태로 만들어 락을 점유하기까지 대기시키는 부분 이었던 것이었다. 이런 중요한 부분을 떼놓고 보니 흐름이 이해가 될리가.. 잡설이 길었지만 결국
을 절절하게 느꼈다는 것.
한 프로젝트에 몰두하는 기간이 길어지고, PintOS
특성상 한 화면을 보고 같이 코딩하는 시간이 많다 보니, 주석과 깃 커밋 메세지의 중요성을 깨닫을 수 있었다. 전날 이해했던 부분을 동료에게 설명하려 했는데, 기억이 완벽하게 나지 않는다거나 하는 상황에 큰 도움이 됐다. 비록 작은 단위의 협업이지만, 역시나 기록의 중요성은 두말하면 입아픈 듯.
기존 정글에서의 나는, 굳이 무언가를 나서서 설명하지는 않았다. 나보다 잘하는 사람들이 분명히 많이 존재하기에 굳이? 싶었던 것도 있고, 내 꺼 하기도 바쁘기도 했고. 하지만 이번에 PintOS
주차에 진입하고 나서부턴 적극적으로 이해한 부분을 설명하려 했다. 물론 정말 확실히 이해한 개념만! 오개념을 설파하여 동료들에게 민폐끼치는건 싫었기에.. ㅋㅋ 코치님들이 설명하면서 배우는 것도 많을 거라고 꾸준히 얘기하셨었는데, 정말 그런 것 같다. 동료들이 이해할 수 있도록 정보를 가공하고, 말로 표현하며 설명하는 과정에서 빈 부분들이 메꿔지는 느낌이랄까?
바퀴를 다시 발명하지 마라 라는 유명한 프로그래밍 격언이 있다. 정글 입소 이후 코치님들이 언급하셔서 접한 말인데, 가슴에 두고두고 새겨야 할 말 같다. 이번 PintOS
프로젝트의 기본 뼈대에는 편의를 위한 다양한 메소드들이 존재하는데, 단순히 이 녀석들을 사용하면 편하게 코드를 짤 수 있다!를 넘어 다양한 장점들이 있었다. 첫째로 일반적으로 가독성을 개선해 줄 여지가 있다는 것! 특히나 코드가 난잡해지기 쉬운 C언어에서는 더욱이 돋보이는 기능이었다. 포인터를 가리키고, 참조하고, 또 가리키고... 이러한 부분을 작성되어있는 함수를 이용해 보다 읽기 편하게 개선할 수 있었다. 둘째로는 디버깅에서의 이점인데, PintOS
가 교육용 OS라 그런 것도 있겠지만, 작성되어 있는 함수들이 각 기능이 정상적으로 동작하는 지 검사할 수 있는 ASSERT
함수를 포함하고 있었기에 디버깅시 매우 편했다! 진작 쓸걸 하는 말이 바로 튀어나올 정도로 😂
우당탕탕 진행됐던 PintOS
의 첫 프로젝트가 종료되었다. 적어도 지금은 PintOS
의 첫 산맥을 성공적으로 등반했다는 데에 조금은 한 숨 돌릴 수 있겠다. 하지만 아직도 남은 거대한 산이 세개나 더 있다. 남은 주차도 화이팅!
오늘도 잘 봤습니다.
비유를 들어가서 설명해주셔서 덕분에 재밌게 읽었네요. 😀
앞으로도 힘내셔서 열심히 하셨으면 좋겠습니다!🫡