
작업 종료 - 작업 도착)과 반환 시간(작업 첫 스케줄링 - 작업 도착)에 대해서 배웠음.ready_list도 여러 개로 만들어야 할 수도 있을듯??멀티레벨 피드백 큐는 우선순위를 사용
우선순위에 따른 스케줄링 규칙
cf. 큐를 1개 사용하는 기본 핀토스도 위와 같은 방식으로 스케줄링이 이루어짐.




[구현 3-1] struct thread 구조체에 추가할 멤버들
int saved_priority: priority donation이 이루어진 경우, donation 이전 priority를 저장.priority의 경우 업데이트를 갱신하려고 함.struct lock *wait_on_lock: 현재 쓰레드가 대기 중인 lock.struct list *donations: 현재 쓰레드에게 priority를 기부할 수 있는 쓰레드들을 리스트로 관리.struct list_elem d_elem: list에 넣는 용도.[구현 3-2] init_thread: priority donation 관련 멤버도 초기화해야 함.
saved_priority 멤버도, priority 매개변수로 초기화해 줘야겠지?wait_on_lock을 NULL로 해 줘야겠지?init_list로 donations 멤버 자리에 리스트를 만들어 두어야겠지?[구현 3-3] lock_acquire
lock -> holder != NULL)wait_on_lock을, 현재 acquire하려는 lock으로 갱신한다.donations 리스트에 현재 쓰레드를 넣어 준다.priority의 내림차순으로 넣어야 할 것임. 제일 높은 priority 기준이니까? (list_insert_ordered)priority를, donations 맨 앞에 위치한 노드의 priority로 갱신한다. (thread_set_priority). 단, 갱신할 priority가 높은 경우에만 갱신한다donate() 함수 따로 만듦. 입력받은 쓰레드의 priority랑 donations 리스트 맨 앞priority 비교해서, 기부가 필요하면 기부하는 식.// 입력받은 쓰레드의 priority와, donations 리스트 맨 앞의 priority를 비교 후, 기부가 필요하면 기부.
void donate(struct thread *c_thread){
struct list *c_donations = &(c_thread -> donations);
int front_priority = list_entry(list_begin(c_donations), struct thread, d_elem) -> priority;
// 현재 lock을 가진 쓰레드의 priority를, donations 맨 앞 위치한 노드의 priority로 갱신
// 단, 갱신할 priority가 높은 경우만
if ((c_thread -> priority) < front_priority){
c_thread -> priority = front_priority;
}
// [구현 3-7] Nested Donation 구현
if (c_thread -> wait_on_lock != NULL){
donate(c_thread -> wait_on_lock -> holder);
}
}
[구현 3-4] lock_release
(1) lock->holder(lock을 갖고 있던 쓰레드)의 donations를 순회한다.
wait_on_lock 멤버가 lock과 일치하면, 해당 노드를 없앤다.wait_on_lock도 NULL로 바꿔 주자.(2) thread의 priority를 남은 donations 리스트의 최댓값 priority로 재설정한다.
saved_priority로 재설정한다. (thread_set_priority)[구현 3-5] thread_set_priority
saved_priority, priority를 설정한 값으로 바꾼다.donations 리스트를 재정렬해 준다.donate 함수 잘 써먹음[구현 3-6] thread_get_priority
priority에 갱신된 priority를 두고 saved_priority에 원래 priority를 두므로, 변경할 게 없음.[구현 3-7] nested donation
donate 함수를 재귀 처리. 입력받은 쓰레드의 priority와 donations 리스트 맨 앞의 priority를 비교해서 기부 처리하는 함수인데, 매개변수를 donate당한 애로 넣어주면 될듯?이렇게 하면 priority-donate-sema 빼고 다 됐는데
sema_up에서 세마포어 기다리는 쓰레드들을 확인할 때, donation이 이루어져도 정렬되지 않았던 게 문제였음sema_up에서 thread_unblock 하기 전에 &sema->waiters를 정렬시켜야 했다void
sema_up (struct semaphore *sema) {
// [구현 2-5] 깨운 쓰레드의 priority가 더 높은 경우, CPU는 yield해줘야 함
enum intr_level old_level;
ASSERT (sema != NULL);
old_level = intr_disable ();
if (!list_empty (&sema->waiters)){
list_sort(&sema -> waiters, dsc_priority, NULL);
thread_unblock (list_entry (list_pop_front (&sema->waiters),
struct thread, elem));
}
sema->value++;
// 깨운 쓰레드의 priority가 더 높은 경우 yield
check_front_yield();
intr_set_level (old_level);
}