Pintos Project1 day 6

John Jean·2024년 8월 28일

pintos

목록 보기
6/7

Pintos

진행 상황

오늘 하루종일 priotity-donate-one으로 삽질하다 팀원이 도와줘서 (사실상 옆에서 떠먹여줘서) 해결함. -> 이거 해결하니 priority-sema도 해결이 되더라.

문제상황은 이렇다.

  • 우선순위가 높은 쓰레드 H, 중간 M 그리고 낮은 L가 있다고 생각해보세요.
  • 만약 L이 락을 갖고있어서 H가 L을 기다려야하고 M이 ready list에 있다면, H는 절대로 CPU를 사용하지 못할 것입니다.
  • 왜냐면 낮은 우선순위의 스레드가 CPU시간을 얻지 못할 것이기 때문입니다.
  • 이 문제에 대한 부분적으로 해결하는 방법은 L이 락을 갖는 동안 H가 L에게 우선순위를 기부(donate)한 다음, L이 잠금을 해제하면 (따라서 H가 획득) 이 기부를 회수하는 것입니다.
  • donate-one 을 해결하려면 고쳐야 할 부분이 몇 군데 있다.

threads 구조체에 필드 추가

//threads.h
	int original_priority;	   /* 기존 우선순위 */
	struct lock *l;			   /* 스레드가 기다리고 있는 락 */

thread_set_priority()

original_priority 도 업테이트 해줘야 함.

void thread_set_priority(int new_priority)
{
	struct thread *curr = thread_current(); // 현재 스레드 가져오기

	curr->priority = new_priority; // 우선순위를 직접 변경
	curr->original_priority = new_priority;
	// 추가
	if (thread_current()->priority < list_entry(list_begin(&ready_list), struct thread, elem)->priority)
	{
		thread_yield();
	}
}

sema_down()

사실 이 부분은 앞서 문제를 다 푼 다른 동기가 고쳐야 할것 이라고 강력하게 주장했지만, 일단 당장 풀고있는 테스트 케이스는 통과됐고, 추후 변경이 필요하면 그 때 변경해보려 함.

// synch.c
void sema_down(struct semaphore *sema)
{
	enum intr_level old_level;

	ASSERT(sema != NULL);
	ASSERT(!intr_context());

	old_level = intr_disable();
	struct lock *lock = thread_current()->l;
	while (sema->value == 0)
	{
		// list_push_back(&sema->waiters, &thread_current()->elem);
		list_insert_ordered(&sema->waiters, &thread_current()->elem, compare_thread, NULL);

		// 대기자의 우선순위가 락의 홀더보다 높으면 기부

		if (lock && thread_current()->priority > lock->holder->priority)
		{
			lock->holder->priority = thread_current()->priority;
		}
		thread_block();
	}
	sema->value--;

	intr_set_level(old_level);
}

sema_up()

// synch.c
void sema_up(struct semaphore *sema)
{
	enum intr_level old_level;

	ASSERT(sema != NULL);
	struct lock *lock = thread_current()->l;

	old_level = intr_disable();
	if (!list_empty(&sema->waiters))
		thread_unblock(list_entry(list_pop_front(&sema->waiters),
								  struct thread, elem));
	sema->value++;
	thread_current()->priority = thread_current()->original_priority;
	if (thread_current()->priority < list_entry(list_begin(&ready_list), struct thread, elem)->priority)
	{
		thread_yield();
	}
	intr_set_level(old_level);
}

생각해볼 과제

  • 현재 구현한 코드는 lock_acquire, lock_release 함수가 아닌 sema_up & down 함수이다.
  • 앞으로 풀어야될 테스트케이스에선 lock함수에 직접 접근해야 할 경우가 있다고함. 가능하다면 lock함수에서 연산을 할 방법도 생각해보장
profile
크래프톤 6기 정글러

0개의 댓글