쓸만한 함수들
struct thread *curr = running_thread();
- 아마 현재 CPU에서 작업중인 쓰레드 아닐까?
struct thread *next = next_thread_to_run();
static struct thread *
next_thread_to_run(void)
{
if (list_empty(&ready_list))
return idle_thread;
else
return list_entry(list_pop_front(&ready_list), struct thread, elem);
}
- 레디 리스트 가장 앞에 있는 쓰레드를 가져옴!! → FIFO이니까 그냥 레디 리스트에 삽입할 때 우선순위 순으로 삽입하면 될 것 같은데??
작업한 코드
thread_yield
/* CPU를 양보합니다. 현재 스레드는 휴면 상태가 되지 않으며,
스케줄러의 판단에 따라 즉시 다시 스케줄될 수 있습니다. */
void thread_yield(void)
{
struct thread *curr = thread_current();
enum intr_level old_level;
ASSERT(!intr_context());
old_level = intr_disable();
if (curr != idle_thread)
// list_push_back(&ready_list, &curr->elem);
list_insert_ordered(&ready_list, &curr->elem, compare_priority, NULL);
do_schedule(THREAD_READY);
intr_set_level(old_level);
}
/* Yields the CPU. The current thread is not put to sleep and
may be scheduled again immediately at the scheduler's whim. */
void
thread_yield (void) {
struct thread *curr = thread_current ();
enum intr_level old_level;
ASSERT (!intr_context ());
old_level = intr_disable ();
if (curr != idle_thread)
list_push_back (&ready_list, &curr->elem);
do_schedule (THREAD_READY);
intr_set_level (old_level);
}
compare_priority
static bool compare_priority(const struct list_elem *a, const struct list_elem *b, void *aux)
{
struct thread *t1 = list_entry(a, struct thread, elem);
struct thread *t2 = list_entry(b, struct thread, elem);
return t1->priority > t2->priority;
}
thread_unblock
/* 차단된 스레드 T를 실행 준비 상태로 전환합니다.
T가 차단되지 않은 경우 이는 오류입니다. (실행 중인 스레드를 준비 상태로 만들려면 thread_yield()를 사용하세요.)
이 함수는 실행 중인 스레드를 선점하지 않습니다. 이는 중요할 수 있습니다: 호출자가 인터럽트를 직접 비활성화한 경우,
스레드를 원자적으로 차단 해제하고 다른 데이터를 업데이트할 수 있다고 기대할 수 있습니다. */
void thread_unblock(struct thread *t)
{
enum intr_level old_level;
struct thread *cur = thread_current(); // 현재 실행중인 쓰레드
ASSERT(is_thread(t));
old_level = intr_disable(); // 인터럽트 끄기 -> 레이스 컨디션 방지
ASSERT(t->status == THREAD_BLOCKED);
list_insert_ordered(&ready_list, &t->elem, compare_priority, NULL); // 우선순위 순으로 레디 큐에 저장
if (thread_get_priority() < t->priority) // 레디 큐에 넣을 쓰레드의 우선순위가 더 높은 경우
{
thread_yield(); // 현재 쓰레드는 CPU 양보
}
// list_push_back(&ready_list, &t->elem);
t->status = THREAD_READY;
intr_set_level(old_level); // 인터럽트 다시 켜기
}
- 새 쓰레드를 레디 큐에 우선순위 순으로 집어넣고, 만약 현재 실행 중인 쓰레드의 우선순위가 새 쓰레드보다 우선순위가 낮다면 CPU를 양보하도록 함
- 그런데 이렇게 고치니까 갑자기 쓰레드 자체가 레디 큐에 안 들어가는것 같음.. 이유가 뭘까>??
- 아마 맨 처음에 idle 쓰레드가 있었는데 이 쓰레드는 thread_yield를 사용해도 양보를 하지 못하기 때문에 그런것 같다..
void
thread_unblock (struct thread *t) {
enum intr_level old_level;
ASSERT (is_thread (t));
old_level = intr_disable ();
ASSERT (t->status == THREAD_BLOCKED);
list_push_back (&ready_list, &t->elem);
t->status = THREAD_READY;
intr_set_level (old_level);
}