핀토스는 os 학습을 위해 개발되어 있는 작은 os로 각종 os를 구성하는 핵심 요소들이
누락이 되거나 미완성 상태로 배포가 되어 있으며 이을 채워나가며 학습을 하게된다.
핀토스 프로젝트를 시작하고 첫번째로 만나게 되는것은 바로 알람과 관련된 테스트
즉 os에서의 쓰레드를 sleep 시키는 매커니즘에 대한 테스트이다.
쓰레드를 일정시간 대기시키는 thread_sleep 함수가 pintos에 구현이 되어 있기는 하다.
하지만 개선 전의 thread_sleep 함수명의 sleep과 다르게 쓰레드가 대기상태가 되지않는다.
계속 작동하면서 일정 시간동안 자신이 작동할 차레가 되면 타이머 인터럽트로 인해 증가하는
tick의 값을 확인하고 while문 밖을 빠져나갈지 아니면 즉시 자신의 차레를 다음 쓰레드로
넘길지 결정하는 방식으로 구현되어 있다.
따라서 쓰레드가 실제로 sleep을 하는 것이 아닌 무한 루프를 돌고있는 busy_wait 상태라
고 볼 수 있다.
이러한 busy_wait 방식을 개선하기 위해 주목한 부분이 바로 타이머 인터럽트이다.
타이머 인터럽트는 하드웨어 수준에서의 os 서포팅으로 소프트웨어를 통한 동작이 아닌
하드웨어가 특정 주기마다 발생시키는 특별한 신호를 통해 발생하는 이벤트이다.
이러한 외부 인터럽트의 한 종류인 타이머 인터럽트 이벤트는 인터럽트 플레그가 꺼져 있는
상태가 아니라면 어떠한 상황에서도 발생하므로 타이머 인터럽트와 연계하여
thread_sleep을 구현하면 쓰레드가 실행대기 상태가 아니라 완전히 정지 상태가
되어있어도 접근하여 깨울 수 있을것이라 판단했다.
첫번째로 thread 구조체 내부에 wake_tick 변수를 추가하여 만약 쓰레드가 sleep 상태라면
언제 쓰레드를 깨울지 기록하도록 했다.
두번째로 thread_sleep 함수가 호출되면 실행대기중인 쓰레드들이 연결되는
ready_list에서 완전히 쓰레드를 제거하고 관리하기 위해 sleep_list를
새로 생성했다. thread_sleep이 호출되면 sleep_list에 해당 함수를 호출한
쓰레드가 추가되는데 이때 wake_tick 기준으로 sort하여 삽입 함으로써
리스트의 첫번째 요소는 항상 가장 빠르게 일어냐야할 쓰레드가 오도록
구현했다.
다음으로 구현한것은 thread_wake 함수이다.
thread_wake함수는 타이머 인터럽트가 발생하면 호출되는 이벤트 함수는
타이머 인터럽트 함수가 호출하게 함으로써 타이머 인터럽트가 발생하는 매
tick 마다 호출되게 된다.
thread_wake 함수는 sleep_list를 처음부터 순회하게 되며 현재의 tick
과 쓰레드에 적혀있는 wake_tick을 비교하여 깨울 시간에 도달한 쓰레드
들을 sleep_list에서 뽑아내어 ready_list로 옮김으로써 쓰레드를 sleep
상태에서 ready 상태로 변경하게 된다.