
priority-condvar
ํ
์คํธ๊ฐ ๋จ์๋ค
์ด๋ฒ ํฌ์คํธ์์๋ Pintos์ ์ฐ์ ์์ ์ค์ผ์ค๋ง ๊ตฌํ์ ๋ง์ง๋ง ๋จ๊ณ์ธ priority-condvar
๋ฐ ๊ด๋ จ ๊ฐ๋
์ ๋ค๋ฃน๋๋ค.
๋ค์ด๊ฐ๊ธฐ์ ์์ mutex์ semaphore, condition variable์ ๋ํ ํฌ์คํธ๋ฅผ ์ฝ๊ณ ์์ฃผ์๊ธฐ๋ฅผ ๊ถํด ๋๋ฆฝ๋๋ค.
์ ๊น, Priority Scheduling์์ Condition Variable์?
๋๋ต์ ์ธ ๊ตฌ์กฐ๋ ์์ ๊ฐ์ผ๋ฉฐ, ์๋๊ฐ ๋ฐ๋ก synch.h์ ์์นํ ์ปจ๋์ ๋ณ์์ ๋๋ค.
๋ฌธ์ ์ํฉ
Pintos๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋น์ ์ ํ FIFO ์ ์ฑ
์ผ๋ก ์ค๋ ๋๋ฅผ ์ฒ๋ฆฌํ๋๋ก ๋์ด ์์๊ณ , ์ง๊ธ๊น์ง ์ ํฌ๋ ์ด๋ฅผ ์ ์ ํ ์ฐ์ ์์ ์ค์ผ์ค๋ง์ผ๋ก ๊ณ ์น๊ณ ์์์ต๋๋ค. ๋ค๋ง synch.c/h์ ํจ์๋ค์ ์์ ํ์ง ์์ ์ฑ ๋ด๋ฒ๋ ค๋๊ณ ์์์ง์. synch.h์ cond_init, cond_wait, cond_signal, cond_broadcast ๊ฐ์ ๊ฒ๋ค์ ๋ชจ๋ ๋๊ธฐํ๊ฐ ํ์ํ ๋ ์ฌ์ฉํ๊ธฐ ์ํ API์๋ ๊ฐ์ ๊ฒ๋ค์ธ๋ฐ, ์ด์ชฝ์ ๋ด๋ฒ๋ ค๋๊ณ ์์์ผ๋ ๋์ด ์๋ก ๋ค๋ฅธ ์ ์ฑ
์ ๊ฐ์ง๋ ๊ฒ์
๋๋ค. ์ด๋ฅผ ํด๊ฒฐํ์ง ์์ผ๋ฉด priority-condvar
ํ
์คํธ๋ ํต๊ณผ๊ฐ ์ด๋ ต์ต๋๋ค.
์ด๋ฅผ ์ฌ์ฉํ๋ ์์๋ ์๋์ ๊ฐ์ต๋๋ค. ์ด ํฌ์คํธ์์ ์๊ฐํด๋๋ฆฐ ์์ฐ์-์๋น์ ํจํด์ Pintos ๋ฒ์ ์ ๋๋ค.
#include "threads/thread.h"
#include "threads/synch.h"
#include <stdio.h>
static int buffer = 0; // ๊ณต์ ์์
static int data_ready = 0;
/* Pintos ๋๊ธฐํ ํด */
static struct lock buffer_lock;
static struct condition cond;
void producer(void *aux UNUSED) {
timer_sleep(100); // ์์ฐ์ด ๋ฆ๊ฒ ์ผ์ด๋๋ ์ํฉ ์๋ฎฌ๋ ์ด์
(tick ๋จ์)
lock_acquire(&buffer_lock);
buffer = 42;
data_ready = 1;
printf("Producer: ๋ฐ์ดํฐ ์์ฑ ์๋ฃ!\n");
cond_signal(&cond, &buffer_lock); // ์๋น์ ๊นจ์
lock_release(&buffer_lock);
}
void consumer(void *aux UNUSED) {
lock_acquire(&buffer_lock);
while (data_ready == 0) {
printf("Consumer: ๋ฐ์ดํฐ ์์ฑ์ ๊ธฐ๋ค๋ฆฌ๋ ์ค...\n");
cond_wait(&cond, &buffer_lock); // ์กฐ๊ฑด ๋ง์กฑ๊น์ง ๋๊ธฐ
}
printf("Consumer: ๋ฐ์ดํฐ ํ๋! %d\n", buffer);
lock_release(&buffer_lock);
}
void main(void) {
lock_init(&buffer_lock);
cond_init(&cond);
thread_create("consumer", PRI_DEFAULT, consumer, NULL);
thread_create("producer", PRI_DEFAULT, producer, NULL);
}
์์ปจ๋,
- timer.c/h, thread.c/h → ์ค์ผ์ค๋ฌ ์์ฒด
- synch.c/h → ๊ทธ ์ค์ผ์ค๋ฌ ์์์ ๋๊ธฐํ ํด์ ์ ๊ณตํ๋ API ๋ ์ด์ด ๋ด์ง๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
...๋ก ์ดํดํ ์ ์์ต๋๋ค.
ํด๊ฒฐํ๊ธฐ
threads/synch.c ๋ฐ .h๋ฅผ ํ์ธํ์ฌ ์๋์ ๊ฐ์ด ๋ฐ์ํฉ๋๋ค.
- ๊ตฌ์กฐ์ฒด ๊ตฌ์ฑ ํ์ธ
- ๊ธฐ๋ณธ์ผ๋ก ์ ๊ณต๋ ๊ตฌ์กฐ์ฒด๊ฐ ์๋์ ๊ฐ์์ง ํ์ธํด์ฃผ์ธ์. ์ 3๊ฐ๋ .h์, ์๋ 1๊ฐ๋ .c์ ์์ต๋๋ค.
/* A counting semaphore. */
struct semaphore {
unsigned value; /* Current value. */
// ์ด waiters์๋ ์ด semaphore์ ๊ด๋ จํ์ฌ ์ ์๊ณ ์๋ ์ค๋ ๋ (struct thread์ elem ๋ฉค๋ฒ)์ด ์ ์ฅ๋จ.
struct list waiters; /* List of waiting threads. */
};
/* Lock. */
struct lock {
struct thread *holder; /* Thread holding lock (for debugging). */
struct semaphore semaphore; /* Binary semaphore controlling access. */
};
/* Condition variable. */
// ๊ฐ ๊ณต์ ์์๋ง๋ค ํ๋์ฉ ๊ฐ์ง. ๊ณต์ ์์๋ณ๋ก ๋ฐ๋ก๋ฐ๋ก ํ๋์ฉ ๊ฐ๊ณ ์์ด์ผ ํจ.
struct condition {
// ์ด waiters์๋ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋ ์ธ๋งํฌ์ด๋ค์ด ์ ์ฅ๋จ.
struct list waiters; /* List of waiting threads. */
};
/* One semaphore in a list. */
// ํ์ฌ ์ค๋ ๋๊ฐ ์ฌ์ฉํ "์๊ธฐ ์ ์ฉ ์ด์ง ์ธ๋งํฌ์ด".
struct semaphore_elem {
struct list_elem elem; /* List element. */
struct semaphore semaphore; /* This semaphore. */
};
- ๋น๊ต ํจ์ ์ถ๊ฐ
- ์๋ sema_priority_cmp() ๋ฐ donation_priority_cmp()๋ฅผ ์ถ๊ฐํฉ๋๋ค.
// ๋ sema์ 'waiters list๋ด ์ค๋ ๋ ์ค ์ ์ผ ๋์ priority'๋ฅผ ๋น๊ต
// a๊ฐ ๋์ผ๋ฉด true, b๊ฐ ๋์ผ๋ฉด false.
bool sema_priority_cmp(const struct list_elem *a, const struct list_elem *b, void *aux UNUSED){
struct semaphore_elem *sema_a = list_entry(a, struct semaphore_elem, elem);
struct semaphore_elem *sema_b = list_entry(b, struct semaphore_elem, elem);
struct list *waiters_a = &(sema_a->semaphore.waiters);
struct list *waiters_b = &(sema_b->semaphore.waiters);
struct thread *root_a = list_entry(list_begin(waiters_a), struct thread, elem);
struct thread *root_b = list_entry(list_begin(waiters_b), struct thread, elem);
return root_a->priority > root_b->priority;
}
// donation_elem์ priority๋ฅผ ๊ธฐ์ค์ผ๋ก ๋น๊ต
// a๊ฐ ๋์ผ๋ฉด true, b๊ฐ ๋์ผ๋ฉด false.
bool donation_priority_cmp(const struct list_elem *a,
const struct list_elem *b, void *aux UNUSED){
struct thread *st_a = list_entry(a, struct thread, donation_elem);
struct thread *st_b = list_entry(b, struct thread, donation_elem);
return st_a->priority > st_b->priority;
}
- cond_wait() ์์
- ์ค๋ ๋๊ฐ ์ปจ๋์ ๋ณ์๋ฅผ ๊ธฐ๋ค๋ฆด ๋, ์ฐ์ ์์๋ก ์ ๋ ฌํ์ฌ ์ฝ์ ํฉ๋๋ค.
void cond_signal (struct condition *cond, struct lock *lock UNUSED) {
ASSERT (cond != NULL);
ASSERT (lock != NULL);
ASSERT (!intr_context ());
ASSERT (lock_held_by_current_thread (lock));
if (!list_empty (&cond->waiters)){
list_sort(&cond->waiters, sema_priority_cmp, NULL); // priority condvar ๊ตฌํ
sema_up (&list_entry (list_pop_front (&cond->waiters),
struct semaphore_elem, elem)->semaphore);
}
}
- cond_signal() ์์
- ์ค๋ ๋๋ฅผ ๊นจ์ธ ๋ ์ฐ์ ์์๋ฅผ ๊ณ ๋ คํ์ฌ ๊ฐ์ฅ ๋์ ์ฐ์ ์์ ์ค๋ ๋๋ฅผ ๋จผ์ ๊นจ์๋๋ค.
void cond_signal(struct condition *cond, struct lock *lock UNUSED) {
if (!list_empty(&cond->waiters)) {
list_sort(&cond->waiters, sema_priority_cmp, NULL);
sema_up(&list_entry(list_pop_front(&cond->waiters), struct semaphore_elem, elem)->semaphore);
}
}
- lock_acquire() ์์
- ๋ฝ์ ์ฒด๊ฒฐํ๋ ๊ณผ์ ์์ donation priority ์์๋๋ก ์ ๋ ฌ ์ฝ์ ํ๋๋ก ๊ตฌ์ฑํฉ๋๋ค.
void
lock_acquire (struct lock *lock) {
ASSERT (lock != NULL);
ASSERT (!intr_context ());
ASSERT (!lock_held_by_current_thread (lock));
/*-- Priority donation ๊ณผ์ --*/
struct thread *t = thread_current();
if (lock->holder != NULL) {
t->wait_lock = lock;
/*-- Priority condvar ๊ณผ์ --*/
list_insert_ordered(&lock->holder->donations, &t->donation_elem, donation_priority_cmp, NULL);
/*-- Priority condvar ๊ณผ์ --*/
donate_priority();
}
sema_down (&lock->semaphore);
// lock->holder = thread_current ();
t->wait_lock = NULL;
lock->holder = thread_current();
/*-- Priority donation ๊ณผ์ --*/
}
ํ ์คํธ ๋ฐ ๊ฒ์ฆ
priority-condvar
๊น์ง์ ๋ชจ๋ ํ
์คํธ๋ค์ด ํต๊ณผ๋๋์ง ํ์ธํ๋ฉด ์ฑ๊ณต์
๋๋ค. Advanced scheduler (MLFQS)๋ฅผ ์ ์ธํ ๋ชจ๋ ํญ๋ชฉ๋ค์ ํต๊ณผ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
'IT > ์ปดํจํ ์ ์ฌ๊ณ ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Pintos Part 1-3. Priority Scheduling w/ Priority Donation (0) | 2025.05.13 |
---|---|
Pintos Part 1-2. Priority Scheduling (0) | 2025.05.12 |
Pintos Part 1-1. Busy Waiting vs. Sleep/Wakeup (0) | 2025.05.12 |
๋ ๋-๋ธ๋ ํธ๋ฆฌ (Red-Black Tree) (1) | 2025.04.18 |
C์ธ์ด์ ํฌ์ธํฐ (๊ธฐ์ด) (0) | 2025.04.17 |
C์ธ์ด์ ๋ฐฐ์ด๊ณผ ํฌ์ธํฐ (0) | 2025.04.17 |
C์ธ์ด์ ํฌ์ธํฐ ์ดํด: ์๋ฃํ์ผ๋ก์์ *์ ์ญ์ฐธ์กฐ ์ฐ์ฐ์๋ก์์ * (2) | 2025.04.14 |
์๋ ํ์ธ์.
ํฌ์คํ ์ด ์ข์๋ค๋ฉด "์ข์์โค๏ธ" ๋๋ "๊ตฌ๋ ๐๐ป" ํด์ฃผ์ธ์!