์ค๋์ ์ฒซ ๋ฒ์งธ ๋จ๊ณ๋ก, ์ค๋ ๋ ์ฐ์ ์์ ๊ธฐ๋ฐ ์ค์ผ์ค๋ง์ ์ ๋ ฌ ๊ตฌ์กฐ๋ฅผ ๊ตฌํํ๊ณ
priority-fifo, priority-preempt, priority-change ํ
์คํธ๋ฅผ ์ฑ๊ณต์ํจ ๊ธฐ๋ก์ ์ ๋ฆฌํ๋ค.
| ์นดํ ๊ณ ๋ฆฌ | ํ ์คํธ ์ด๋ฆ |
|---|---|
| ์ฐ์ ์์ ์กฐ์ | priority-change |
| ๊ธฐ๋ณธ ๋๋ค์ด์ | priority-donate-one, priority-donate-multiple, priority-donate-multiple2 |
| ๋๋ค์ด์ ์ฒด์ธ | priority-donate-nest, priority-donate-chain |
| ๋ฝ/์ธ๋งํฌ์ด ๊ธฐ๋ฐ ๋๋ค์ด์ | priority-donate-sema, priority-donate-lower |
| ์ฐ์ ์์ ๊ธฐ๋ฐ ์ค์ผ์ค๋ง | priority-fifo, priority-preempt |
| ๋๊ธฐํ ๊ธฐ๋ฐ ์ฐ์ ์์ | priority-sema, priority-condvar |
โ
ํ์ฌ ํต๊ณผํ ํ
์คํธ:
priority-fifo, priority-preempt, priority-change
โ Step 1 / 6 ์๋ฃ
priority-fifo์ priority-preempt๋
ready_list๊ฐ priority ๊ธฐ์ค์ผ๋ก ์ ๋ ฌ๋์ด ์๋๊ฐ?
๊ทธ๋ฆฌ๊ณ ๋ ๋์ priority์ ์ค๋ ๋๊ฐ ๋ฑ์ฅํ์ ๋ ์ ์ ๋๋๊ฐ?๋ฅผ ํ์ธํ๋ ํ
์คํธ์ด๋ค.
์ฆ, ์ด ํ
์คํธ๋ค์ด ํต๊ณผํ์ง ์์ผ๋ฉด ์ดํ ๋๋ค์ด์
์ ๊ตฌํํด๋ ์๋ฏธ๊ฐ ์์.
์๋ํ๋ฉด ๊ธฐ๋ถ๋ฐ์ priority๊ฐ ์ ๋๋ก ๋ฐ์๋์ง ์๊ณ , ์ฌ์ ํ ๋ฎ์ ์ฐ์ ์์๊ฐ ๋จผ์ ์คํ๋๊ธฐ ๋๋ฌธ.
priority_cmp() ํจ์ ๊ตฌํready_list์ ์ ๋ ฌ์ ์ฐ์ ์์ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌํ๊ธฐ ์ํด priority_cmp() ํจ์๋ฅผ ๊ตฌํํ๋ค.
์ด ํจ์๋ list_insert_ordered()์ ํจ๊ป ์ฌ์ฉ๋์ด ready_list๊ฐ ํญ์ ์ฐ์ ์์๊ฐ ๋์ ์ค๋ ๋๊ฐ ๋จผ์ ์คํ๋๋๋ก ์ ์งํ๊ฒ ํจ.
๐ threads/thread.c:
bool priority_cmp(const struct list_elem *a, const struct list_elem *b, void *aux UNUSED) {
struct thread *a_thread = list_entry(a, struct thread, elem);
struct thread *b_thread = list_entry(b, struct thread, elem);
return a_thread->priority > b_thread->priority;
}
๐ threads/thread.h:
bool priority_cmp(const struct list_elem *a, const struct list_elem *b, void *aux);
์ด ํจ์๋ ready_list๋ฅผ priority ๊ธฐ์ค์ผ๋ก ์ค๋ฆ์ฐจ์ ์ ๋ ฌํ๋ ๋ฐ ์ฌ์ฉ๋๋ค.
thread_unblock()์์ priority_cmp() ์ฌ์ฉํ์ฌ ready_list์ ์ฝ์
๊ธฐ์กด์ list_push_back()์ ์ฌ์ฉํ๋ ๋ถ๋ถ์ list_insert_ordered()๋ก ๋ฐ๊พธ์ด,
ready_list๊ฐ FIFO๊ฐ ์๋ priority ์์ผ๋ก ์ ์ง๋๊ฒ ํ๋ค.
์ด์ priority_cmp() ํจ์์ ์ํด ์ฐ์ ์์๊ฐ ๋์ ์ค๋ ๋๊ฐ ๋จผ์ ์คํ๋๋๋ก ๋ณด์ฅํ ์ ์๋ฐ.
๐ threads/thread.c:
๊ธฐ์กด ์ฝ๋:
list_push_back(&ready_list, &t->elem);
์์ ํ:
list_insert_ordered(&ready_list, &t->elem, priority_cmp, NULL);
thread_yield()์์ ready_list ์ฐ์ ์์ ์ ๋ ฌ ์ฝ์
์ค๋ ๋๊ฐ ์๋ณดํ ๋์๋ ์ฐ์ ์์๊ฐ ๋์ ์ค๋ ๋๊ฐ ๋จผ์ ์คํ๋๋๋ก ํ๊ธฐ ์ํด,
thread_yield()์์ ready_list์ ์ ๋ ฌ๋ ์์๋ก ์ฝ์
ํ ์ ์๋๋ก ํ๊ณ
๐ threads/thread.c:
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_insert_ordered(&ready_list, &curr->elem, priority_cmp, NULL); // โ
์ ๋ ฌ ๊ธฐ๋ฐ ์ฝ์
do_schedule(THREAD_READY);
intr_set_level(old_level);
}
์ด ์ฝ๋๋ก ์ฐ์ ์์๊ฐ ๋์ ์ค๋ ๋๊ฐ ๋จผ์ ์คํ๋๋๋ก ํ ์ ์๋ค.
thread_set_priority()์ priority ๊ด๋ฆฌthread_set_priority() ํจ์๋ฅผ ๊ตฌํํ์ฌ ์ค๋ ๋์ ์ฐ์ ์์๋ฅผ ๋ณ๊ฒฝํ๊ณ ,
์ด๋ ๊ธฐ์กด priority๊ฐ ๋ณต์๋๊ฑฐ๋ ๊ธฐ๋ถ๋ฐ์ ์ฐ์ ์์๋ก ๋ณ๊ฒฝ๋๋๋ก ํ์๋ค.
void thread_set_priority(int new_priority) {
struct thread *cur = thread_current();
cur->original_priority = new_priority;
refresh_priority(); // ๊ธฐ๋ถ ๊ณ ๋ คํด์ priority ๋ฐ์
thread_yield(); // ์๋ณด ํ์ ์ ์ฒ๋ฆฌ
}
์์ ๊ตฌํ์ด ์ ๋์๋์ง ํ์ธํ๊ธฐ ์ํด, priority-fifo์ priority-preempt ํ
์คํธ๋ฅผ ์คํํด๋ณด๋ฉด
make clean && make check
๋๋ ๊ฐ๋ณ ํ ์คํธ๋ง ์คํํ ๋:
cd build
make tests/threads/priority-fifo.result
make tests/threads/priority-preempt.result
๋๋ pintos ์๋ ์คํ:
pintos -v -k -T 60 -m 20 -- -q run priority-fifo
pintos -v -k -T 60 -m 20 -- -q run priority-preempt
(priority-fifo) 16 threads will iterate 16 times in the same order each time.
(priority-fifo) end
(priority-preempt) The high-priority thread should have already completed.
โ ๋ ๋ค ์ ์ ์ข ๋ฃ๋๋ฉด PASS
์ฐ์ ์์ ์ง์ ๋ณ๊ฒฝ + ๋๋ค์ด์ ๊ตฌํ
๋ค์ ๋จ๊ณ์์๋ ๋ค์ ํ ์คํธ๋ค์ ํต๊ณผ์ํค๊ธฐ ์ํ ๊ธฐ๋ฅ๋ค์ ๊ตฌํํ ์์ ์ด๋ค:
| ๋ชฉํ ํ ์คํธ | ํ์ํ ๊ตฌํ |
|---|---|
priority-change | thread_set_priority() |
priority-donate-one | donate_priority() |
priority-donate-multiple | ๋๋ค์ด์ ๋ฆฌ์คํธ ๊ด๋ฆฌ |
priority-donate-nest, -chain | ๋๋ค์ด์ ์ฒด์ธ ๊ตฌํ |
priority-donate-lower, -multiple2 | donation rollback (remove_with_lock, refresh_priority) |
priority-fifo, priority-preempt, priority-change ํ
์คํธ ํต๊ณผ ํ์ธ
๊ฐ๋ ์ ์์ cd์ด๊ณ ๋งจ๋ ๊ฑฐ๋ ๊ธ์ cd์ธ๊ฐ์?