과제 목표
thread_create( ) : 스레드를 생성할 때, 실행 중인 스레드와 비교하여 새로 생성한 스레드가 우선순위가 높다면 스케줄링을 해준다.
unblock과 yield를 수정한다는 것은 ready_list의 변화가 생겼을 때, 우선순위 순으로 정렬하라는 것이다. 정렬은 pintos에 구현되어 있는 list_inster_ordered( )를 사용해서 정렬하면 된다.
구현
/* 현재 수행중인 스레드와 가장 높은 우선순위의 스레드의 우선순위를 비교하여 스케줄링 */
void test_max_priority(void);
/* 인자로 주어진 스레드들의 우선순위를 비교 */
bool cmp_priority(const struct list_elem *a, const struct list_elem *b, void *aux UNUSED);
test_max_priority( )
함수이다. create에 함수를 추가해준다.tid_t thread_create(const char *name, int priority,
thread_func *function, void *aux)
{
…
thread_unblock(t);
/* 생성된 스레드의 우선순위가 현재 실행중인 스레드의 우선순위보다 높다면, CPU를 양보한다. */
test_max_priority();
return tid;
}
void test_max_priority(void) {
/* ready_list에서 우선순위가 가장 높은 스레드와
현재 스레드의 우선순위를 비교하여 스케줄링 */
if (!list_empty(&ready_list)) {
struct thread *top_pri = list_begin(&ready_list);
if (cmp_priority(top_pri, &thread_current()->elem, NULL))
{
thread_yield();
}
}
}
cmp_priority()
함수는 밑에서 자세히 설명하겠지만 간단히 두 인자를 비교해 매개변수에서 첫번째 인자가 크다면 TRUE를 반환 아니라면 FALSE를 반환해주는 함수이다. 즉, 실행중인 스레드보다 ready_list에 스레드가 priority가 더 크다면 스케줄링을 해준다. bool cmp_priority(const struct list_elem *a_, const struct list_elem *b_, void *aux UNUSED) {
struct thread *a = list_entry(a_, struct thread, elem)->priority;
struct thread *b = list_entry(b_, struct thread, elem)->priority;
return a > b;
}
list_entry()
함수는 처음에 이해하기 힘들었지만 위에 사진을 보면 이해하기 훨씬 쉬워질것이다. ready_list에 줄 서있는 애들은 엄밀히 말하면 스레드가 아닌 스레드 내 멤버인 list_elem이다. 따라서 list_elem만 가져온다고 해당 스레드 전체를 비교할 수는 없다.(우리가 알아야 할 건 스레드 내에 속한 다른 멤버인 priority인데 이거랑 list_elem과는 연관이 없음) 하지만 우리는 list_entry를 통해서 ready_list에 줄 서있는 해당 스레드 전체를 들고 올 수 있고 그러면 그 안에 속한 priority까지 함께 들고 올 수 있게 되는 것이다.void thread_unblock(struct thread *t)
{
…
/* 스레드가 unblock될 때, 우선순위 순으로 정렬되어 ready_list에 삽입 */
list_insert_ordered(&ready_list, &t->elem, cmp_priority, NULL);
…
}
void thread_yield(void)
{
…
/* 현재 thread가 CPU를 양보하여 ready_list에 삽입될 때, 우선순위 순서로 정렬하여 삽입 */
list_insert_ordered(&ready_list, &curr->elem, cmp_priority, NULL);
…
}
void thread_set_priority(int new_priority)
{
thread_current()->priority = new_priority;
/* 스레드의 우선순위가 변경되었을때 우선순위에 따라
선점이 발생하도록 한다. */
test_max_priority();
}
결과
요약
PintOS Project1 GIthub 주소 PintOS