문제상황
priority-sema는 pass하는데 priority-condvar는 실패했다.
테스트 결과를 보니까 정렬이 안되고 있는 점을 발견할 수 있었다.
수 시간의 삽질과 팀원들의 수고 덕분에 왜 정렬이 되지 않았었는지 확인할 수 있었다.
문제의 우선순위 정렬 함수
bool
cmp_sema_elem_priority (const struct list_elem *a, const struct list_elem *b, void *aux) {
struct semaphore_elem *semaElem_a = list_entry(a, struct semaphore_elem, elem);
struct semaphore_elem *semaElem_b = list_entry(b, struct semaphore_elem, elem);
struct semaphore sema_a = semaElem_a->semaphore;
struct semaphore sema_b = semaElem_b->semaphore;
struct list *waiters_a = &sema_a.waiters;
struct list *waiters_b = &sema_b.waiters;
if(list_empty(waiters_a) == true)
return false;
if(list_empty(waiters_b) == true)
return true;
struct thread* t_a = list_entry(list_begin(waiters_a), struct thread, elem);
struct thread* t_b = list_entry(list_begin(waiters_b), struct thread, elem);
return t_a->priority > t_b->priority;
}
틀렸던 세가지 부분
struct semaphore_elem *semaElem_a = list_entry(a, struct semaphore_elem, elem);
이 부분을
struct semaphore_elem *semaElem_a = list_entry(a, struct thread, elem);
로 되어있었다.
그러니까, list_entry함수에서 두번째 매개변수로 구조체를 넣어줘야 하는데 이 구조체를 저장하고자 하는 변수의 타입과 같게 맞춰줘야 했는데 thread 구조체로 잘못 넣어주고 있었다.
마지막에 waiters 리스트의 맨 앞부분을 list_begin으로 꺼내서 thread 구조체에 넣는 부분이다.
struct thread* t_a = list_entry(list_begin(waiters_a), struct thread, elem);
이 부분을
struct thread* t_a = list_begin(waiters_a);
이렇게 쓰고 실행했다.
여기서 생기는 문제는 list_begin은 list_elem 타입을 반환하는데 thread 구조체로 받고 있었다. 따라서 list_entry로 감싸줘서 thread를 반환할 수 있게 하였다.
list_begin(waiters_a)
가 list_begin(&waiters_a)
로 되어있었다. 이건 원래 내가 처음 짰던 코드에서는 앤퍼센트가 없었는데 이것저것 테스트 해보다가 지우질 않고 계속 돌리고 있었다. list_begin()의 정의를 보면 인자로 struct list *
를 받게 되어있기 때문에 &waiters_a로 하게되면 더블포인터가 되버린다.