
// 가정: 함수 초기에 struct thread *curr = thread_current(); 선언됨
/*
if (list_empty(&curr->donations))
{
curr->priority = curr->origin_priority;
}
else // donations 리스트가 존재할 경우
{
list_sort(&curr->donations, cmp_donate_priority, NULL);
struct thread *first_one = list_entry(list_front(&curr->donations), struct thread, d_elem);
// 문제 지점: curr->priority가 origin_priority가 아닌, 이전의 유효 우선순위일 수 있음
if (first_one->priority > curr->priority)
{
curr->priority = first_one->priority;
}
}
*/
위 코드의 else 블록 (즉, donations 리스트가 비어있지 않을 때)에서 새로운 우선순위를 계산할 때, 비교 대상이 되는 curr->priority는 스레드의 원래 우선순위(origin_priority)가 아닌, 이전에 설정되었던 유효 우선순위 값임.
이로 인해, 만약 스레드가 이전에 다른 높은 우선순위를 기증받아 curr->priority가 이미 높아져 있는 상태였다고 가정.
이후, 기증 상황이 변경되어 현재 donations 리스트에 있는 최고 기증자(first_one)의 우선순위가 origin_priority보다는 높지만 이전의 높은 curr->priority보다는 낮다면, if (first_one->priority > curr->priority) 조건이 거짓.
결과적으로 curr->priority는 갱신되지 않고, 스레드는 필요 이상으로 높은 (또는 현재 상황에 맞지 않는) 우선순위를 유지 가능성 존재. 즉, 우선순위 계산의 기준점이 매번 달라져 일관성 저하.
struct thread *curr = thread_current();
int new_calculated_priority = curr->origin_priority; // 항상 origin_priority에서 계산 시작
if (!list_empty(&curr->donations))
{
list_sort(&curr->donations, cmp_donate_priority, NULL);
struct thread *highest_donor = list_entry(list_front(&curr->donations), struct thread, d_elem);
if (highest_donor->priority > new_calculated_priority)
{
new_calculated_priority = highest_donor->priority;
}
}
curr->priority = new_calculated_priority; // 최종 계산된 우선순위를 반영
일관된 기준점 사용: new_calculated_priority 변수를 항상 스레드의 origin_priority로 초기화. 이것이 우선순위 계산의 변하지 않는 시작점.
정확한 비교 및 업데이트: donations 리스트가 존재할 경우, 가장 높은 우선순위를 가진 기증자(highest_donor)의 우선순위를 이 new_calculated_priority (즉, origin_priority 또는 그보다 높은 기증자의 우선순위로 이미 업데이트된 값)와 비교. 이를 통해 max(origin_priority, 현재_최고_기증자_우선순위) 로직 효과적 구현.
일관된 결과: donations 리스트가 비어있으면 curr->priority는 origin_priority가 되고, 기증자가 있으면 origin_priority와 최고 기증자의 우선순위 중 더 높은 값으로 설정. 따라서 스레드의 우선순위는 항상 원래 우선순위를 기준으로 현재의 기증 상황을 정확히 반영. 이전의 유효 우선순위 상태에 부적절하게 영향을 받지 않아 더 안정적이고 예측 가능한 동작 보장.
10시간 동안 똑같은 테스트 코드만 해결했어요.... 헤헤헤헤ㅔ헤헤헿