๐Ÿ“€ KAIST:PINTOS | Implementation | Priority Scheduling | Step 1 / 6

์ด์ˆœ๊ฐ„ยท2025๋…„ 5์›” 13์ผ

KAIST:PINTOS

๋ชฉ๋ก ๋ณด๊ธฐ
6/23

์˜ค๋Š˜์€ ์ฒซ ๋ฒˆ์งธ ๋‹จ๊ณ„๋กœ, ์Šค๋ ˆ๋“œ ์šฐ์„ ์ˆœ์œ„ ๊ธฐ๋ฐ˜ ์Šค์ผ€์ค„๋ง์˜ ์ •๋ ฌ ๊ตฌ์กฐ๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ 
priority-fifo, priority-preempt, priority-change ํ…Œ์ŠคํŠธ๋ฅผ ์„ฑ๊ณต์‹œํ‚จ ๊ธฐ๋ก์„ ์ •๋ฆฌํ–ˆ๋‹ค.


๐ŸŽฏ ์ตœ์ข… ๋ชฉํ‘œ ํ…Œ์ŠคํŠธ ๋ชฉ๋ก (์ด 12๊ฐœ)

์นดํ…Œ๊ณ ๋ฆฌํ…Œ์ŠคํŠธ ์ด๋ฆ„
์šฐ์„ ์ˆœ์œ„ ์กฐ์ž‘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 ์™„๋ฃŒ


๐Ÿงฉ ์™œ Step 1์„ ๋จผ์ € ๊ตฌํ˜„ํ•ด์•ผ ํ• ๊นŒ?

priority-fifo์™€ priority-preempt๋Š”
ready_list๊ฐ€ priority ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌ๋˜์–ด ์žˆ๋Š”๊ฐ€?
๊ทธ๋ฆฌ๊ณ  ๋” ๋†’์€ priority์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๋“ฑ์žฅํ–ˆ์„ ๋•Œ ์„ ์ ๋˜๋Š”๊ฐ€?๋ฅผ ํ™•์ธํ•˜๋Š” ํ…Œ์ŠคํŠธ์ด๋‹ค.

์ฆ‰, ์ด ํ…Œ์ŠคํŠธ๋“ค์ด ํ†ต๊ณผํ•˜์ง€ ์•Š์œผ๋ฉด ์ดํ›„ ๋„๋„ค์ด์…˜์„ ๊ตฌํ˜„ํ•ด๋„ ์˜๋ฏธ๊ฐ€ ์—†์Œ.
์™œ๋ƒํ•˜๋ฉด ๊ธฐ๋ถ€๋ฐ›์€ priority๊ฐ€ ์ œ๋Œ€๋กœ ๋ฐ˜์˜๋˜์ง€ ์•Š๊ณ , ์—ฌ์ „ํžˆ ๋‚ฎ์€ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋จผ์ € ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ.


๐Ÿ›  Step 1์—์„œ ๊ตฌํ˜„ํ•œ ๊ฒƒ๋“ค

โœ… 1. 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 ๊ธฐ์ค€์œผ๋กœ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.


โœ… 2. 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);

โœ… 3. 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);
}

์ด ์ฝ”๋“œ๋กœ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์€ ์Šค๋ ˆ๋“œ๊ฐ€ ๋จผ์ € ์‹คํ–‰๋˜๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค.


โœ… 4. 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();       // ์–‘๋ณด ํ•„์š” ์‹œ ์ฒ˜๋ฆฌ
}

โœ… 5. ํ…Œ์ŠคํŠธ ์‹คํ–‰ (make ๋ฐฉ์‹)

์œ„์˜ ๊ตฌํ˜„์ด ์ž˜ ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด, 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


๐Ÿงฑ ๋‹ค์Œ ๋‹จ๊ณ„ (Step 2 / 6)

์šฐ์„ ์ˆœ์œ„ ์ง์ ‘ ๋ณ€๊ฒฝ + ๋„๋„ค์ด์…˜ ๊ตฌํ˜„

๋‹ค์Œ ๋‹จ๊ณ„์—์„œ๋Š” ๋‹ค์Œ ํ…Œ์ŠคํŠธ๋“ค์„ ํ†ต๊ณผ์‹œํ‚ค๊ธฐ ์œ„ํ•œ ๊ธฐ๋Šฅ๋“ค์„ ๊ตฌํ˜„ํ•  ์˜ˆ์ •์ด๋‹ค:

๋ชฉํ‘œ ํ…Œ์ŠคํŠธํ•„์š”ํ•œ ๊ตฌํ˜„
priority-changethread_set_priority()
priority-donate-onedonate_priority()
priority-donate-multiple๋„๋„ค์ด์…˜ ๋ฆฌ์ŠคํŠธ ๊ด€๋ฆฌ
priority-donate-nest, -chain๋„๋„ค์ด์…˜ ์ฒด์ธ ๊ตฌํ˜„
priority-donate-lower, -multiple2donation rollback (remove_with_lock, refresh_priority)

โœจ ๋งˆ๋ฌด๋ฆฌ

  • Step 1: ready_list ์šฐ์„ ์ˆœ์œ„ ์ •๋ ฌ ๊ตฌํ˜„ ์™„๋ฃŒ
  • priority-fifo, priority-preempt, priority-change ํ…Œ์ŠคํŠธ ํ†ต๊ณผ ํ™•์ธ
profile
์„œํˆด์ง€์–ธ์ • ๋Š˜ ํ–‰๋™์ด ๋จผ์ €์ด๊ธฐ๋ฅผ

2๊ฐœ์˜ ๋Œ“๊ธ€

comment-user-thumbnail
2025๋…„ 5์›” 14์ผ

๊ฐœ๋…์€ ์€์ƒ‰ cd์ด๊ณ  ๋งจ๋“ ๊ฑฐ๋Š” ๊ธˆ์ƒ‰ cd์ธ๊ฐ€์š”?

1๊ฐœ์˜ ๋‹ต๊ธ€