크래프톤 정글 일지

[PintOS] Project 1 - Threads - Alarm clock

나한나한나한나 2024. 5. 11. 21:01

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시간 정도 걸린 것 같다

고통스러웠지만

이제야 뭘 해야 하고 뭘 하고 있는 지 조금 알 것 같다

 

자고싶다