Main goal
we gonna modify the system call 'timer_alarm'
and we gonna modify pintos to use sleep/wakeup/die for alarm
current system
running thread에 alarm이 울리면 ready list의 tail로 돌아간다
timer_ticks()로 current time을 기록(start)
it keeps executing the thread_yield() -> it release cpu and check the running time(?)
thread_yield()
first, it gets pointer of the current thread structure
then it disable interrupt
그리고 cur->elem을 ready list에 넣는다
cur->status 를 THREAD_READY로 변경
schedule()이 context switch를 수행
after finish context switch, 인터럽트 레벨을 원래대로 돌림(old_level)
functions in thread_yield()
- thread_current()
- intr_disable()
- intr_set_level(old_level)
- list_push_back(&ready_list, &cur->elem)
- schedule()
timer_sleep()을 더 효율적?효과적?으로 만드는 것이 이 프로젝트의 목적
blocked state를 가정(sleep)
timer_sleep()으로 쓰레드를 blocked state로 만들고,
OS는 timer_interrupt를 frequently 확인해서 wakeup 시켜야 함
디자인
코드 시작 - list가 두 개 있음 (all_list, ready_list)
ready_list는 cpu에 의해 실행되길 기다리는 프로세스들의 집합
new data structure - the list of blocked threads - sleep_list
프로세스가 timer_sleep()을 call 할때, OS는 쓰레드를 sleep_list에 넣는다
그리고 os는 계속 the timer를 확인한다
timer is up 할때, os는 그것을 wakes up 해서 sleep_list에서 ready_list로 이동시킨다
그것이 wakeup()함수의 존재 이유
이것이 timer_sleep 알고리즘의 디자인
Implementation of Alarm Clock
- Define Sleep Queue
- static struct list sleep_list;
- and initialize it
- list_init (&sleep_list);
- Point to think:
- where do we put the declaration statement and when are we going to initialize it
글로벌 틱과 로컬 틱
timer interrupt handler는 어떤 쓰레드를 깨워야 할 지 체크해야 한다
각 쓰레드는 time to wakeup을 가져야 한다
기본 쓰레드는 this field(time to wakeup)가 없으므로, 우리가 the threads structure를 수정해서 박아야 함
efficiency도 고려해야 하기 때문에 글로벌 틱이라는 전역변수를 생성
로컬 틱 중 minimum을 글로벌 틱에 저장
timer interrupt handler가 실행될 때마다 체크
만약 current time 이 글로벌 틱보다 크거나 같으면, 이 쓰레드를 깨워야 한다는 의미(sleep_list에서 ready_list로)
모든 blocked threads를 스캔해야 하는 것은 아님
글로벌 틱을 선언해야 하는 이유는 sleep_list를 스캔하는 시간을 줄이기 위함
Modify thread structure
thread struct에 필드를 추가해야 함 - 그것은 alarm time to wake up
Implementation of Alarm Clock
timer_sleep()이 호출됐을 때, 틱(현재시각)을 체크
wakeup까지 필요한 틱이 현재 틱 보다 작으면
(나는 이 부분이 이해하기가 어려웠는데, 틱을 '시간'(during)으로 생각해서 그랬다. 틱은 '시각'이다.(at))
당 쓰레드를 ready_list에서 제거하고 sleep_list로 삽입, 현재 틱에 ticks(인자로 받은 값)를 더해서.
기존 코드(파란 색)는 무지성 양보
thread_sleep()
current thread가 idle thread가 아니라면,
쓰레드의 상태를 BLOCKED로 바꾸고
로컬 틱을 저장
글로벌 틱을 업데이트(그것이 로컬 틱 중에 minimum이라면)
schedule() 호출(컨텍스트 스위치)
잊지 말 것 - 쓰레드 리스트에 쓰레드 스트럭처를 삽입할 때, disable interrupt 하는 것을 잊지 말 것
Implementation of Alarm Clock
timer interrupt는 모든 것의 심장이다(!)
timer interrupt가 occur할때 결정한다 어떤 쓰레드가 wake up 할건지
쓰레드를 wake up 하기 위해서, 그것을 sleep 큐에서 삭제하고 ready_list에 삽입해야 한다
쓰레드의 상태를 sleep(blocked)에서 ready로 바꾸는 것을 잊지 말 것!!!!!
timer_interrupt()
have to add this part(파란 부분)
sleep list와 global tick을 체크
wakeup 할 쓰레드를 찾고
ready list로 move
글로벌 틱 업데이트(필요하다면)
결론(드디어)
몇 개의 함수를 수정(위에 있는 3개)
몇 개의 함수를 추가(following the design suggestion for modularization)
아마도 네 개일 것임
첫째는 쓰레드 상태를 blocked로 변경하고 sleep queue에 넣는 함수
둘째는 sleep queue에서 깨울 놈을 찾고 그놈을 깨우는 함수(sleep queue에서 ready list로 이동)
셋째는 minimum value of tick을 가진 쓰레드를 저장하는 함수
넷째는 minimum value of tick을 리턴하는 함수
씨발 끝났다!!
영상 길이는 13분인데 정리하는 데 5시간 정도 걸린 것 같다
고통스러웠지만
이제야 뭘 해야 하고 뭘 하고 있는 지 조금 알 것 같다
자고싶다
'크래프톤 정글 일지' 카테고리의 다른 글
[PintOS] Priority Scheduling (0) | 2024.05.13 |
---|---|
[PintOS] 이 OS, 핀토스는 어디가 시작점인가 (0) | 2024.05.13 |
[PintOS] 카이스트 전산학과 권영진 교수님 OS 특강 (0) | 2024.05.11 |
크래프톤 정글 PINTOS Project 0: PintOS 키워드 정리 (0) | 2024.05.11 |
ubuntu 18.04 환경 세팅하기 (0) | 2024.05.10 |