
2025.05.13
오늘한 내용 : PintOS - Project1: Threads - 기본 Priority Scheduling 구현 / 개념 - thread init, thread lifecycle, 우선순위 기부 양보 차이
WEEK 09 : 정글 끝까지(PintOS) - Threads
| 항목 | 작성 예시 |
|---|---|
| Ready 리스트 정렬은 어떻게 하나요? | list_insert_ordered()로 Ready 리스트 정렬 |
| 우선순위 변경 시 재정렬 필요 여부 | thread_set_priority() 호출 시 yield() 필요 |
| 새 스레드가 Ready 상태가 될 때 어떻게 하나요? | thread_unblock()에서 정렬 삽입 |
| 어디서 수정해야 하나요? | thread_unblock(), thread_yield(), schedule() |
| 주의할 점은? | 같은 priority라면 round-robin 유지해야 함 |
thread->priority 필드 사용list_insert_ordered()로 정렬 삽입thread_yield()에서 ready list의 가장 높은 priority 비교thread_create()thread_unblock()thread_yield()schedule(), next_thread_to_run()| 테스트 이름 | 의미 |
|---|---|
priority-change | 우선순위가 바뀔 때 스케줄러가 적절히 반응하는지 |
priority-preempt | 더 높은 우선순위 스레드가 나타나면 선점되는지 확인 |
priority-fifo | 같은 priority이면 FIFO 순서로 동작하는지 |
부트스트랩 ── thread_init() ──┐
↓
초기 스레드 (BOOT) ─ thread_start() ─┐
↓
idle 스레드 생성
↓
인터럽트 활성화 → 타이머 IRQ 발생
↓
schedule()
├─ Ready 큐 비어 있으면 idle 실행 (hlt 루프)
└─ Ready 큐에 스레드 있으면 해당 스레드 실행
↓
thread_launch() → 실행
thread_init() 단계
initial_thread 구조체로 Bootstrap(메인) 스레드 생성, 기본 상태 THREAD_RUNNING 설정thread_start() 단계
struct semaphore idle_started; 선언 및 sema_init(&idle_started, 0); 호출thread_create("idle", PRI_MIN, idle, &idle_started);idle() 함수와 &idle_started가 스레드에 전달됨intr_enable() 호출 → 타이머 인터럽트 수신 시작sema_down(&idle_started) 호출idle() 스레드가 처음 실행되면 내부에서 sema_up(&idle_started)를 호출해 Bootstrap 스레드를 깨움intr_enable() 호출 → 타이머 인터럽트 수신 시작
sema_down(&idle_started); 호출 → idle 스레드가 sema_up()을 호출할 때까지 Bootstrap 스레드 블록idle 스레드 초기 실행
static void idle(void *idle_started_) {
sema_up(idle_started_); // Bootstrap 깨우기
for (;;) {
intr_disable();
asm volatile ("hlt"); // CPU 절전 모드 진입
intr_enable();
}
}
sema_up()으로 Bootstrap 스레드 READY 복귀hlt 루프 실행스케줄러 흐름 (schedule())
thread_launch()로 컨텍스트 전환Bootstrap vs Idle 실행 조건
yield()는 BLOCKED가 아니라 READY 상태로 돌아가기 때문에, bootstrap이 다시 선택되고 idle은 여전히 대기 상태.thread_start() 안의 sema_down(&idle_started)sema_down(), lock_acquire(), cond_wait() 같은 함수 호출 시 블록.thread_block() 호출핵심 포인트
양보는 실행중이더라도 우선순위가 높은 새로운 쓰레드가 생기면(언블럭이 되든, 새로운 쓰레드가 들어오든) 멈춰서 양보해준다?
기부는 임계영역에서 똑같은 자원을 사용해야되는데 우선순위 낮은애가 그거 락하고 있으면 먼저 락한 낮은 우선순위의 스레드가 그걸 다써야 풀어주는데 우선순위 높은 애가 빨리 쓰게하려고 낮은 애한테 우선순위 빌려줘서 락 빨리 풀게 하고 H를 쓰게 해준다?
thread_unblock()로 깨워진 스레드의 우선순위가 현재 실행 중인 스레드보다 높을 때thread_set_priority()로 우선순위를 낮춰서 READY 큐 맨 앞 스레드보다 낮아졌을 때threads/thread.c 및 threads/thread.hthread.hstruct thread에 int priority, int base_priority, struct list donations, struct lock *waiting_lock 필드 추가thread_unblock() / thread_yield() / thread_create() 등에서list_insert_ordered(&ready_list, &t->elem, cmp_priority, NULL) 사용next_thread_to_run()ready_list.front에서 우선순위 높은 스레드 반환thread_create() → thread_unblock() 호출thread_unblock() → list_insert_ordered() + 양보 검사thread_yield() → list_insert_ordered() + schedule()schedule() → next_thread_to_run() → thread_launch()* thread.c
thread_unblock() - ready_list 삽입 시 ordered로 변환
thread_unblock() - 끝부분 현재스레드와 삽입스레드 우선순위 비교
/ 현재스레드가 idle이 아닐때 yield 진행
thread_yield() - ready_list 삽입 시 ordered로 변환
thread_piroity_greater() 구현 - 내림차순
list_insert_ordered(&ready_list, &t->elem, thread_priority_greater, NULL);
if (thread_current() != idle_thread && t->priority > thread_get_priority())
{
if (intr_context())
intr_yield_on_return();
else
thread_yield();
}