Alarm Clock
๐ devices/timer.c ์ ์๋ timer_sleep()์ ๋ค์ ๊ตฌํํด๋ด ์๋ค.
๐ํ์ฌ ํํ ์ค์ ๊ตฌํ๋์ด์๋ timer_sleep()
- ํ์ฌ ํ๋ก์ธ์ค๋ ์๋์ ์ธ๋ ค์ค์ผ ํ๋ ์๊ฐ์ด ๋๋์ง ์ฌ๋ถ๋ฅผ ํ์ธํ๊ธฐ ์ํด, ready ์ํ์ running ์ํํ๋ฅผ ์๋ค๊ฐ๋ค ํ๊ฒ ๋๋ค. ๊ทธ ๊ฒฐ๊ณผ, ๋ ์ํ ์ฌ์์์ ์๋ค๊ฐ๋ค ํ๋ฉด์ ์๋ชจ์ ์ธ cpu cycle์ ๋ฐ๋ณตํ๊ฒ ๋๋ค. ์ฐ๋ ๋๊ฐ running ์ํ์ผ ๋, alarm์ ํธ์ถํ๋ฉด, ์ค๋น๋ฆฌ์คํธ์ ๊ฐ์ฅ ๋งจ ๋ง์ง๋ง์ผ๋ก ๋ค์ ๋ค์ด๊ฐ๊ณ , ๊ฒฐ๊ตญ ๋ค์ ์คํ๋๋ค. ๋ฐ๋ผ์, ํ์ฌ ๊ตฌํ๋ ๋ฐฉ์์ผ๋ก ์ค๋น ๋ฆฌ์คํธ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ ๋ฃจํ๋ฅผ ๊ณ์ ๋๊ฒ ๋๋ ๊ฒ์ด๋ค. ready_list -> running -> yield -> ready_list
๐ก๊ตฌํ ์์ด๋์ด
๐๐ปblocked ํ์ฉํ๊ธฐ
- blocked ๋ผ๋ ๊ฐ๋ ์ ํ์ฉํด timer_sleep()์ ๊ตฌํํ๋ค.
- timer_sleep()์ ํธ์ถํ๋ฉด, os๊ฐ ์คํ์ค์ด์๋ running thread๋ฅผ blocked ์ํ๋ก ๋ง๋ค์ด ์ค๋ค. os๋ ์ฃผ๊ธฐ์ ์ผ๋ก ์๊ฐ์ ์ฒดํฌํด์ ,blocked ์ํ์ ์๋ ์ฐ๋ ๋๋ฅผ ๊นจ์์ฃผ๊ฒ ๋๋ค. ์ด๋ฌํ ์ ๊ทผ๋ฐฉ๋ฒ์ผ๋ก cpu์ธ์ดํด๊ณผ ์ ๋ ฅ์๋ชจ๋ฅผ ์ ์ฝํ ์ ์๊ฒ๋จ
- ํ์ฌ์ ํํ ์ค์๋ all_list , ready_list ๋ ๊ฐ์ ๋ฆฌ์คํธ๋ง ์๋ ์ํ์ด๋ค. ์๋ก์ด ๋ฆฌ์คํธ sleep_list๋ฅผ ๊ตฌํํด์ผํ๋ค. ์ด ๋ฆฌ์คํธ๋ blocked ์ํ์ธ ์ค๋ ๋๋ค๋ก ๊ตฌ์ฑ๋์ด ์๋ค. ํ๋ก์ธ์ค๊ฐ timer_sleep()์ ํธ์ถํ๋ฉด, os๋ ์ค๋ ๋๋ฅผ ์ผ๋จ sleep_list์ ๋ฃ๊ณ os๋ ํ์ด๋จธ๋ฅผ ๊ณ์ ์ฒดํฌํ๋ค๊ฐ, ์๊ฐ์ด ๋ค ๋๋ฉด, ๊ทธ ์ฐ๋ ๋๋ฅผ ๊นจ์์ค๋ค.
alarm clock - ๊ตฌํ
โ๏ธthread.h
int64_t thread_tick_count;
- thread ๊ตฌ์กฐ์ฒด์ ์ถ๊ฐ
โ๏ธthread.c
void make_thread_sleep(int64_t ticks)
{
enum intr_level old_level;
old_level = intr_disable();
ASSERT(!intr_context());
ASSERT(intr_get_level() == INTR_OFF);
// printf("in thread sleep\n");
struct thread *t = thread_current();
// ticks๋ฅผ ์ด๋๋ค ์ธ๊น
// ๋ฃ์๋ ์ ๋ ฌํด์ ๋ฃ๊ธฐ
// list_push_back(&blocked_list, &thread_current() -> elem);
// list, ํ์ฌ ๋ฆฌ์คํธ์ ์ฝ์
ํ๋ ค๋ thread, list์ ์๋ ์ค๋ ๋
t->thread_tick_count = ticks;
t->status = THREAD_BLOCKED;
list_insert_ordered(&blocked_list, &(t->elem), tick_less, NULL);
schedule();
intr_set_level(old_level);
}
void make_thread_wakeup(int64_t ticks)
{
// ์ด๋ ๊ฒ ๊ตฌํํ๋ ค๋ฉด ์์๋๋ก ์ ๋ ฌํด์ ๋ฃ์ด์ค์ผํ
while (!list_empty(&blocked_list) && list_entry(list_front(&blocked_list), struct thread, elem) -> thread_tick_count <= ticks)
{
struct thread * t = list_entry(list_pop_front(&blocked_list), struct thread, elem);
// list_pop_front(&blocked_list);
thread_unblock(t);
}
}
static bool
tick_less(const struct list_elem *a_, const struct list_elem *b_,
void *aux UNUSED)
{
const struct thread *a = list_entry(a_, struct thread, elem);
const struct thread *b = list_entry(b_, struct thread, elem);
return a->thread_tick_count < b->thread_tick_count;
}
โ๏ธtimer.c
/* timer ์ธํฐ๋ฝํธ๋ ๋งค tick ๋ง๋ค ticks ๋ผ๋ ๋ณ์๋ฅผ ์ฆ๊ฐ์ํด์ผ๋ก์ ์๊ฐ์ ์ฐ๋ค.
์ด๋ ๊ฒ ์ฆ๊ฐํ ticks ๊ฐ TIME_SLICE ๋ณด๋ค ์ปค์ง๋ ์๊ฐ์ intr_yield_on_return() ์ด๋ผ๋ ์ธํฐ๋ฝํธ๊ฐ ์คํ๋๋๋ฐ,
์ด ์ธํฐ๋ฝํธ๋ ๊ฒฐ๊ณผ์ ์ผ๋ก thread_yield() ๋ฅผ ์คํ์ํจ๋ค.
์ฆ ์์ scheduling ํจ์๋ค์ด ํธ์ถ๋์ง ์๋๋ผ๋ ์ผ์ ์๊ฐ๋ง๋ค ์๋์ผ๋ก scheduling ์ด ๋ฐ์ํ๋ค. */
static void
timer_interrupt (struct intr_frame *args UNUSED) {
ticks++;
thread_tick ();
make_thread_wakeup(ticks);
}
/* Suspends execution for approximately TICKS timer ticks. */
// void // timer_sleep() ํจ์๊ฐ ํธ์ถ๋๋ฉด, ํด๋น ์ค๋ ๋๋ ready์ํ๊ฐ ์๋ blocked์ํ๋ก ์ ํ๋๋ค. blocked๋ ์ค๋ ๋๋ค์ ์ผ์ด๋ ์๊ฐ์ด ๋๋ฉด ์ผ์ด๋์ผ ํ๋ค.
// timer_sleep (int64_t ticks) { // system timer : ์ด๋น 100ํ์ ticks ๋ฐ์. (1 tick = 10ms)
// /* Busy waiting : Thread๊ฐ CPU๋ฅผ ์ ์ ํ๋ฉด์ ๋๊ธฐํ๊ณ ์๋ ์ํ. CPU ์์์ด ๋ญ๋น ๋๊ณ , ์๋ชจ ์ ๋ ฅ์ด ๋ถํ์ํ๊ฒ ๋ญ๋น๋ ์ ์๋ค. */
void
timer_sleep (int64_t ticks) {
// int64_t start = timer_ticks (); //ํ์ฌ tic์ start์ ๋ฃ์ด์
ASSERT (intr_get_level () == INTR_ON); //interrupt ์ํ์ธ์ง ํ์ธ
// printf("<1>\n");
// while (timer_elapsed (start) < ticks) //start๋ก ๋ถํฐ ์๊ฐ์ด ์ผ๋ง๋ ์ง๋ฌ๋์ง
// thread_yield ();
// printf("Switch : %d\n", swch);
// printf("in 'while' ... running\n");
make_thread_sleep(timer_ticks () + ticks); //ํ์ฌ ์๊ฐ๋ถํฐ ์ฌ์์ผํ tick์ ๋ํด์ฃผ์ด์ผํจ
// printf("timer_sleep finish\n");
// thread_print_stats();
}
'pintos' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[WIL] Copy On Write (1) | 2023.10.24 |
---|---|
[WIL]Project3: Virtual Memory (1) | 2023.10.11 |
[PROJECT 1 : THREADS]๊ณผ์ ์ค๋ช (0) | 2023.09.21 |