[PintOS] 1-1 Alarm Clock
2024. 5. 16. 00:40ㆍ크래프톤 정글 5기/공부
GIT
[thread.c, thread.h, timer.c, timer.h]
이론 영상 출처 : https://www.youtube.com/watch?v=myO2bs5LMak
# Todo
- Pintos uses busy waiting for alarm
- Modify pintOS to use sleep/wake for alarm
# Files to Modify
- threds/thread
- devices/timer
# todo
1. create sleep_list
2. create wake_up()
3. create sleep()
4. modify timer_sleep()
5. modify timer_interrupt()
6. modify thread_init()
7. Function : 쓰레드 상태를 blocked로 만들고, sleep queue에 삽입한 뒤 대기하는 동작
8. Function : sleep queue에서 wake up 시킬 쓰레드를 찾는 동작 + wake up 시키는 동작
9. Function : 쓰레드가 가지고 있는 tick 최소값을 저장하는 동작
10. Function : 최소 tick 값을 반환하는 동작
1. timer_sleep (int64_t ticks)
현재 실행 중인 쓰레드를 지정된 tick 수만큼 슬립 상태로 만드는 함수
2. int64_t start = timer_ticks ()
현재 tick 값을 가져옴
3. while (timer_elapsed (start) < ticks)
지정된 tick 수만큼 시간이 경과할 때까지 쓰레드를 슬립 상태로 유지
4. thread_yield()
현재 CPU 사용 중인 쓰레드를 양보하고 다른 쓰레드에게 CPU 양보
thread_yield() :
실행 중인 쓰레드를 양보하고 ready_list에 삽입하는 함수
timer_ticks() :
현재까지 발생한 tick 수 반환하는 함수
타이머 인터럽트가 발생할 때마다 tick 값이 증가
timer_elapsed () :
주어진 시작 tick 값부터 현재까지 경과한 tick 수 반환하는 함수
현재 tick 값에서 시작 tick 값을 빼서 경과한 tick 수 계산
1. thread_yield ()
쓰레드의 우선순위를 조정하고 스케줄링을 수행하는 함수
2. struct thread *cur = thread_current()
현재 실행 중인 쓰레드의 포인터 저장
3. enum intr_level old_level
인터럽트 상태를 저장할 변수 선언
4. old_level = intr_disable()
변수에 인터럽트 비활성화 상태 저장
5. if (cur != idle_thread)
현재 쓰레드가 유휴 쓰레드가 아닌 경우에
6. list_push_back(&ready_list, &cur -> elem)
현재 쓰레드를 ready_list의 맨 뒤에 추가 (= 현재 쓰레드를 준비 상태로 전환)
7. cur -> status = THREAD_READY
현재 쓰레드의 상태를 THREAD_READY 상태로 변경
8. schedule()
다음에 실행할 쓰레드를 선택하고 Context Switching 수행하는 함수
9. intr_set_level (old_level)
이전 인터럽트 상태를 복원
if (cur != idle_thread)
유휴 쓰레드인 경우에는 yield 하지 않음
* 유휴 쓰레드 : 시스템에서 다른 쓰레드가 실행 가능한 상태가 아닐 때 실행되는 특별한 쓰레드
intr_disable()
인터럽트를 비활성화하고, 이전 인터럽트 상태를 반환
=> 인터럽트로 인한 race condition 방지
1. Define Sleep Queue
static struct list sleep_list
** 초기화 하는 것 잊지 말기
*** 어디서 선언할 것인지, 언제 초기화 할 것인지 고민하기
2. Global tick / Local tick
global tick, local tick 두개 만들어야 함
1) Global tick
시스템 전체에서 공유되는 tick값
타이머 인터럽트 발생 시 값이 증가
시스템의 절대 시간을 나타냄, 모든 쓰레드에서 공유하고 접근 가능
timer_ticks() 함수 호출 시 global tick 값 반환
시스템 전체의 시간을 측정하고 관리하는 데 사용
2) Local tick
개별 쓰레드에서 사용되는 tick값 (공유 X)
각 쓰레드는 자신만의 tick값 가지며, 쓰레드 별로 독립적인 시간 측정 가능
쓰레드가 생성된 시점 ~ 쓰레드가 실행된 시간 측정하는 데 사용
쓰레드가 실행될 때마다 값이 증가
쓰레드가 block, yield 되면 local tick은 그대로 정지
쓰레드 구조체 내에 local tick 저장 필드가 존재
쓰레드 생성 시 초기화 / 쓰레드 실행 중 업데이트
1. timer_sleep()
현재 실행 중인 쓰레드를 지정된 tick 수만큼 슬립 상태로 만드는 함수
2. start = timer_ticks()
현재 tick 값을 저장
3. if (timer_elapsed (start) < ticks)
현재 쓰레드의 경과한 시간이 지정된 tick 값보다 작을 경우
4. thread_sleep(start + ticks)
현재 쓰레드를 슬립 상태로 만들고, 슬립 큐에 삽입
wakeup을 위해 start + ticks로 시간 정해줌
start = timer_ticks() 변수를, thread_sleep(start + kicks)로 사용하지 못한다 ?
→ start는 지역변수여서, timer_sleep() 종료 시 더이상 사용 X ⇒ 다른 함수에 start 변수는 넣지 못함
1. sleep_list, ready_list에 쓰레드를 넣고 뺄 때 disable interrupt 중요함
2. sleep_list에서 정렬하는 게 편함
wake time이 빠른 순서대로 앞에 위치
첫 번째 쓰레드의 wake up 소요 시간까지의 쓰레드만 검색하면 됨
수정해야 하는 함수
1. thread_init()
sleep queue data structure 초기화하는 코드 추가해야 함
2. timer_sleep()
sleep queue에 쓰레드를 넣는 동작 추가해야 함
3. timer_interrupt()
모든 틱마다, sleep queue에 있는 쓰레드가 wake up 하는 걸 체크할 것
wake up 동작 추가해야 함
추가해야 하는 함수
1. 쓰레드 상태를 blocked로 만들고, sleep queue에 삽입한 뒤 대기하는 동작
2. sleep queue에서 wake up 시킬 쓰레드를 찾는 동작 + wake up 시키는 동작
3. 쓰레드가 가지고 있는 tick 최소값을 저장하는 동작
4. 쓰레드가 가지고 있는 tick 최소값을 반환하는 동작
함수 수정/추가 할때마다 기록을 하면서 해야했는데, 이거 고치고 저거 고치고 하다보니까 before&after 비교가 힘들어졌다.
'크래프톤 정글 5기 > 공부' 카테고리의 다른 글
[PintOS] 1-3 Advanced Scheduler (0) | 2024.05.18 |
---|---|
[PintOS] 1-2 Priority Scheduler, Priority Donation (0) | 2024.05.18 |
[PintOS] Project 1 키워드 정리 (Race Condition, Context Switching, PCB, Process State) (0) | 2024.05.10 |
CSAPP: Network Programming (1) | 2024.05.07 |
[Webproxy-lab] Tiny Web Server (0) | 2024.05.06 |