<--------- thread 관련 함수 --------->
[pintos/src/threads/thread.c]
static struct list ready_list // Ready 상태의 thread를 관리하는 list, CPU를 기다리는 쓰레드들의 배열
static struct list all_list // 모든 thread를 관리하는 list
void thread_yield(int64_t ticks) // 인터럽트 상태 확인 후, ready_list 가장 마지막에 현재 스레드를 삽입 후 스케줄링(다음 스레드에게 cpu 점유 양보)
<--------- timer 관련 함수 --------->
void timer_sleep(int64_t ticks){
int64_t start = timer_ticks();
while(timer_elapsed(start) < ticks) // 인자로 전달된 ticks이후 몇 tick이 지났는지 반환
thread.yield();
}
// 시간이 ticks를 넘어갈 때까지 thread.yield()를 반복
timer_sleep()에서 while문을 보면 스레드가 계속 잠을 자야 되는데 thread_yield()라는 함수가 잠을 자려는 스레드를 ready_list의 맨 뒤로 삽입하게 하는데, 이렇게 되면 ready_list에 들어가게 된 스레드는 잠을 자도 편히 잘 수가 없게 된다. 정해진 ticks동안 아무것도 하지 않도록 잠을 자야 하는데 잠에서 깨지 이전에 ready_list에서 스케줄링 되어 다시 running상태가 될 수 있기 때문에 완벽하게 자는 상태가 아니게 된다. 그래서 과제를 해결하기 위해서 몇 가지 선언해야 할 것들이 있다.
thread.c
위와 같이 잠자는 스레드를 모아놓는 list와 스레드가 일어날 시각을 나타내는 next_tick_to_awake를 선언해서 cpu 점유 제한 시간을 나타내준다.
선언한 next_tick_to_awake를 getter, setter해주는 메소드를 작성함으로써 점유시간을 불러들이거나 저장할 수 있도록 해준다.
그리고 당연히 thread_init에 위에서 선언해 놓은 sleep_list를 초기화해주는 작업을 추가로 작성한다.
원래 있던 thread_yield()와는 전혀 다른 기능을 해야 하기 때문에, 스레드를 재우는 함수와 스레드를 깨우는 함수를 각각 작성해준다.
thread_sleep(): 현재 스레드를 받아와서, next_tick_to_awake()로 자는 시간을 저장해주고 새롭게 만든 sleep_list에 받아온 스레드를 삽입한 후, block을 시킨다.
thread_awake(): 자고 있는 스레드들 중에 깨어날 시각이 미리 저장되어있던 ticks인 스레드를 깨워준다.