운영체제에는 일정 시간에 프로세스를 깨우는 타이머 알람 기능 시스템 콜인 alarm clock 기능이 있다.
현재 pintos에 구현되어 있는 alarm clock은 busy waiting 방식으로 구현되어 있다.
프로세스의 상태가 running과 ready 사이에서 계속 왔다갔다 하면서 일어나야되는 시간인지를 확인하는 방식으로 wait하는데 바빠서 busy waiting 방식! running이라는건 cpu가 실행하고 있다는 상태이고 ready는 cpu가 실행하고 있지 않은 상태인데 이 상태들을 반복해서 왔다갔다 한다는건 context switching을 계속 한다는 것이기 때문에 매우 비효율적이다.
이 방식을 sleep/awake 방식으로 바꿔주기에 앞서 기존 코드를 분석했다.
전체적인 흐름은 main thread가 있고, idle thread가 있고, 일어나야하는 thread들이 있다.
tick은 프로그램 내부에서 시간을 나타내기 위한 단위이고 부팅이후에 일정한 시간마다 1씩 올라간다.
idle thread는 ready list가 비었을 때 실행되는 thread로 busy waiting 방식에서는 ready list가 항상 차있기 때문에 처음을 제외하고는 실행되지 않을거다.
프로그램의 처음 시작은 thread/init.c의 main으로부터 시작된다.
이곳에서 각종 초기화를 하고 thread_start() 함수에서 idle thread를 만든다.
idle_started 세마포어를 이용해서 idle thread가 만들어지고 초기화되기까지 기다렸다가 다음 기능들을 수행한다.
thread_create() 함수를 실행하면 페이지를 할당받고, thread를 초기화하고(상태는 blocked으로 초기화), tid를 할당받는다.
해당 thread가 수행해야하는 주소(t->tf.rip)에 kernel_thread 함수 주소값을 넣고, kernel_thread 함수의 인자값들을 t->tf.R.rdi와 t->tf.R.rsi에 넣는다.
그리고 thread_unblock() 함수를 실행해서 상태를 ready로 바꿔주고 ready_list 마지막에 넣는다.
kernel_thread() 함수는 함수주소값과 매개변수를 받아서 해당 함수를 실행한다.
그래서 스케줄에 의해 해당 thread가 일을 해야할 때가 오면, t->tf.rip 에 저장된 kernel_thread 함수가 실행될거고 그 인자값들은 t->tf.R.rdi와 t->tf.R.rsi에 저장되어 있을거고 해당 값들로 함수를 실행할거다. ex) idle_thread는 idle함수가 실행
idle_thread가 수행하는 idle 함수는 계속 for문을 돌고있다.
thread_block() 함수가 수행되면서 thread의 상태를 block으로 바꾸고 스케줄에 의해 다음 thread가 실행될거다.
처음 create_thread()로 idle_thread가 만들어지면 ready_list에 넣을건데 그후 thread_block()의 schedule()에 의해 리스트에서 꺼내질거고, 그 후 다시 ready_list에 들어가지 않고 밖에서 block상태로 있을거다. 만약 ready_list가 비었다면 idle_thread가 running상태가 되고 idle_thread tick이 올라갈거다.
'정글' 카테고리의 다른 글
정글 [week11] Pintos-KAIST Project 3 :: VIRTUAL MEMORY - 2 (1) | 2024.05.27 |
---|---|
정글 [week10] Pintos-KAIST Project 3 :: VIRTUAL MEMORY (0) | 2024.05.21 |
정글 [week08] Pintos-KAIST Project 2 :: USER PROGRAMS (0) | 2024.05.14 |
[정글 WEEK00] 개발일지 - 정글러 동선 (2) | 2024.03.17 |