KAIST Jungle 7์ฃผ์ฐจ, OS ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉฐ ํ์ตํ ๋ด์ฉ์ ์ ๋ฆฌํ ๊ธ์ ๋๋ค.
๋ค์ด๊ฐ๊ธฐ ์ ์
ํ๋ก์ธ์ค๋ ๋ญ๊ณ ์ค๋ ๋๋ ๋ญ๊ฐ์? [์ ํ๋ธ ์์ ๊ฐ์]
- CPU์ ๋์์ฑ์ ์ฌ๋ฌ ์์
์ ์ผ๋ถ๋ถ์ฉ context switching ํ๋ฉด์ ์งํ๋จ
- A, B, C ์์ ๋์ ์ฒ๋ฆฌ ์ ์์๋๋ก A(5% ์ํ)โถ๏ธ B(5% ์ํ) โถ๏ธ C(5% ์ํ) โถ๏ธ A(10% ์ํ)โถ๏ธ B(10% ์ํ) โถ๏ธ C(10% ์ํ) ... (๋ฐ๋ณต) โถ๏ธ A(100% ์ํ)โถ๏ธ B(100% ์ํ) โถ๏ธC(100% ์ํ)
- ๋ณ๋ ฌ์ฑ์ ํ๋ก์ธ์ค ํ๋์ ์ฝ์ด ์ฌ๋ฌ ๊ฐ๊ฐ ๋ฌ๋ ค์ ๊ฐ๊ฐ์ด ์์
์ ๋์์ ์งํํ๋ ๊ฒ(์์
๋ถ๋ด)
- ์ฒซ ๋ฒ์งธ ์ฝ์ด์์ A์์ , ๋ ๋ฒ์งธ ์ฝ์ด์์ B์์ , ์ธ ๋ฒ์งธ ์ฝ์ด์์ C์์ ์ ๊ฐ์ ์์ ์ ์์ ํจ
- ํ ํ๋ก์ธ์ค(ex. ํฌ๋กฌ) ๋ด์์ ๋ค์ํ ์์
์ด ์งํ๋์ด์ผ ํ ๋ ๐ก Thread
- Thread๋ ํ๋ก์ธ์ค๋ง๋ค ์ฃผ์ด์ง ์ ์ฒด ์์์ ํจ๊ป ์ฌ์ฉํ๋ ๊ฒ
- ์ฅ์ : ์๋, ํจ์จ โฌ๏ธ
- ๋จ์ : Thread๊ฐ ๋์์ ์์์ ์ฌ์ฉํ๊ฒ ๋๋ ๊ฒฝ์ฐ, ์ด๋ก ์ธํ error๊ฐ ๋ฐ์ํ๊ธฐ ์ฝ๋ค๋ ๋จ์ ์ด ์์
- ์ฑํฌ๋ก๋์ด์ฆ(synchronize) : ๋ ์ด์์ ์ค๋ ๋๊ฐ ๋์์ ์์์ ์ฌ์ฉํ์ง ๋ชป ํ๋๋ก ํจ
- Thread๋ ํ๋ก์ธ์ค๋ง๋ค ์ฃผ์ด์ง ์ ์ฒด ์์์ ํจ๊ป ์ฌ์ฉํ๋ ๊ฒ
์ปค๋ ์ค๋ ๋(Kernel Treads)
- ์ปค๋ ์ค๋ ๋๋ ์ด์ ์ฒด์ ์ ํต์ฌ ๋ถ๋ถ์์ ์คํ๋๋ Thread
- ์ด๋ค์ ํ๋์จ์ด์ ์ง์ ์ํธ ์์ฉํ๊ณ , ์์คํ ์์์ ๊ด๋ฆฌํ๋ฉฐ, ์ฌ์ฉ์ ์์ค์ ์ค๋ ๋ ๋ฐ ํ๋ก์ธ์ค์ ์๋น์ค๋ฅผ ์ ๊ณตํจ
- PintOS ๊ตฌํ์ ํ์์ ์ธ ์ฌํญ: Thread ์ค์ผ์ค๋ง, Thread ์์ฑ ๋ฐ ์ข ๋ฃ,Thread ๊ฐ ๋๊ธฐํ(์: ์ธ๋งํฌ์ด, ๋ฝ), ์ฐ์ ์์ ์ค์ผ์ค๋ง์ ์ง์ โก๏ธ ์ด๋ฅผ ํตํด ์ด์ ์ฒด์ ๊ฐ ๋ค์ํ ์์ ์ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์์
์ฑํฌ๋ก๋์ด์ฆ(synchronization) - ๊ณผ์ ์ค๋ช ์ ๊ธฐ๋ฐ ์ ๋ฆฌ
ํนํ๋ OS kernel์ Thread ๊ฐ ์์์ ๊ณต์ ํ ๋ ํต์ ๋ ํ์(controlled fashion)์ ์งํค์ง ์๋๋ค๋ฉด big messํ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ์ ์๋ค. PintOS์์๋ ์ด๋ฅผ ๋ง๊ธฐ ์ํด ๋ค์ํ ๋ค์ํ synchronization ํจ์(primitives)๋ฅผ ์ ๊ณตํ๋ค.
- Disabling Interrupts
- Synchronization์ ํ๋ ๊ฐ์ฅ ๋จ์ํ ๋ฐฉ๋ฒ์ interrupts๋ฅผ ๋ถ๊ฐ๋ฅํ๊ฒ ํ๋ ๊ฒ
- interrupts๊ฐ ์ผ์ ธ ์์ผ๋ฉด, ์งํ ์ค์ธ Thread๊ฐ ์ธ์ ๋ ๋ค๋ฅธ Thread์ ์ํด ์ ์ (preempt)๋ ์ ์์(error ๋ฐ์ ๊ฐ๋ฅ)
- interrupts๋ฅผ ๋๋ฉด, ์งํ์ค์ธ Thread ์ ์ ์ด ๋ถ๊ฐ๋ฅํจ
- Thread ์ ์ ์ time interrupts(์์คํ ํ์ด๋จธ๋ก๋ถํฐ ์ ํด์ง ์๊ฐ ๊ฐ๊ฒฉ์ ๋ฐ๋ผ interrupts ๋ฐ์)์ ์ํด ์ด๋ค์ง๊ธฐ ๋๋ฌธ
- ๋ค๋งInterrupts ๋นํ์ฑํ ๋์ด ์๋ค๋ฉด OS๋ ์์คํ ์ ์ ์ด๊ถ์ ๋ค์ ์ป์ ์ ์์(์ ์์ ํ๋ก๊ทธ๋จ์ด ํ๋ก์ธ์ค ๋ ์ ์ ๊ฐ๋ฅํ๊ฒ ํจ)
- ์ผ๋ฐ์ ์ธ Unix ์์คํ
์ '์ ์ ๋ถ๊ฐ๋ฅ(nonpreemptible)'์ด์ง๋ง, PintOS๋ '์ ์ ๊ฐ๋ฅํ(preemptible)' Kernel์
- '์ ์ ๊ฐ๋ฅํ' Kernel์ ๊ฒฝ์ฐ ๋ช ์์ ์ธ synchronization์ด ๋์ฑ ํ์ํจ
- ์ธ๋ถ interrupts handler์ kernel thread๋ฅผ ๋๊ธฐํ์ํค๊ธฐ ์ํจ
- ์ธ๋ถ interrupts handler๋ ์ ๋ค๊ฒ ํ ์ ์๊ธฐ์ ๋นํ์ฑํ ์ํค์ง ์๊ณ ๋ ๋๊ธฐํ๊ฐ ๊ฑฐ์ ๋ถ๊ฐ๋ฅ ํจ
(์ฐธ๊ณ ) ์์ ํด์ผ ํ ์ ์ฒด ์ฝ๋ ๋ผ์ธ ์
Alarm Clock(OS, "Thread ์ผ์ ์๊ฐ ์ดํ์ ์ผ์ด๋")
Alarm Clock ๊ณผ์ ๋ timer_sleep() ํจ์๋ฅผ ์ฌ๊ตฌํํ๋ ๊ณผ์ ์ด๋ค. ๊ธฐ์กด์ ๊ตฌํ๋์ด ์๋ ๋ฐฉ์์ busy-waiting ๋ฐฉ์์ผ๋ก 'OS์์ Thread๋ฅผ ์ฌ์ ๋ค๊ฐ ๊ณง๋ฐ๋ก ์๊ฐ์ ํ์ธํ๊ณ ์์ง ์ผ์ด๋ ์๊ฐ์ด ์๋๋ผ๋ฉด ๋ค์ ์ฌ์ฐ๊ณ ๋, ๊ณง๋ฐ๋ก ์๊ฐ์ ํ์ธํ๋ ๊ณผ์ ์ ๋ฐ๋ณตํ๋ ๊ฒ'์ด๋ค. ์ด๋ Thread์ ์ํ๊ฐ Running ↔๏ธ Ready๋ฅผ ๋ฐ๋ณตํ๋ค.
์กฐ๊ธ ๋ ํ์ด์ ๊ณผ์ ์ ๋ณด๋ฉด, Running ์ํ์์ sleep ๋ช ๋ น์ ๋ฐ์ Thread๋ Ready ์ํ๊ฐ ๋๊ณ ready queue์ ์ถ๊ฐ ๋๋ค. Ready queue์ ์๋ Threads๋ ์ผ์ด๋ ์๊ฐ์ด ์๋์๋ ์๊ด์์ด ๊นจ์์ ธ์ Running ์ํ๊ฐ ๋๋ค. ์ผ์ด๋ ์๊ฐ์ด ์๋์๊ธฐ์ ๋ค์ Ready ์ํ๊ฐ ๋๊ณ , ready queue์ ์ถ๊ฐ๋๋ค.
Sleep/Wake up ๊ธฐ๋ฐ์ Alarm Clock ๊ตฌํ
๊ธฐ์กด ๋ฐฉ์์์ Running ↔๏ธ Ready ์ํ๊ฐ ๋ฐ๋ณต์ ์ผ๋ก(while๋ฌธ ์์์) ๊นจ์ด๋ ์๊ฐ๊น์ง ์คํ๋๋ ๋นํจ์จ์ ํด๊ฒฐํ๊ธฐ ์ํด Ready ์ํ๋ก ์ ํํ๋ ๊ฒ์ด ์๋ Block ์ํ๋ก ์ ํํด Block ์ํ์ธ ๊ฒ์ ๊นจ์ด๋ ์๊ฐ์ด ๋๊ธฐ ์ ์ ์ค์ผ์ฅด๋ง์ ํฌํจ๋์ง ์๋๋ก ์์ ํ๋ค. ๊นจ์ด๋ ์๊ฐ์ด ๋์์ ๋, Block ์ํ๋ฅผ โก๏ธ Ready ์ํ๋ก ๋ฐ๊พธ์ด์ค๋ค.
Sleep queue ์๋ฃ ๊ตฌ์กฐ ์ถ๊ฐ
/* List of processes in THREAD_READY state, that is, processes
that are ready to run but not actually running. */
static struct list ready_list;
static struct list sleep_list;
...
void thread_init(void) {
...
/* Init the globla thread context */
lock_init(&tid_lock);
list_init(&ready_list);
list_init(&sleep_list);
list_init(&destruction_req);
...
}
Sleep ๋์ด ์๋ Threads๋ฅผ ์ ์ฅํ queue ๊ตฌ์กฐ์ฒด๋ฅผ ์ ์ธํ๋ค. ์ดํ Thread ์ด๊ธฐํ ์ sleep_list๋ฅผ ํจ๊ป ์ด๊ธฐํ๋๋๋ก ํ๋ค. ์ด sleep_list๋ Block ์ํ์ Threads๊ฐ ์ ์ฅ๋์ด ๊นจ์ด๋ ์๊ฐ์ด ๋๊ธฐ ์ ๊น์ง ๋จธ๋ฌด๋ฅด๋ ๊ณณ์ด๋ค.
Thread_sleep() ํจ์ ๊ตฌํ
void thread_sleep(int64_t ticks) {
struct thread *curr = thread_current();
enum intr_level old_level;
ASSERT(!intr_context());
old_level = intr_disable(); // Disabling Interrupts
if (curr != idle_thread) { // idle thread๋ sleep ๋์ง ์์์ผ ํจ
curr->wakeup_tick = ticks; // ํ์ฌ thread์ ์ผ์ด๋์ผ ํ๋ ์๊ฐ ์ ์ฅ
list_push_back(&sleep_list, &curr->elem); // sleep queue์ push back
thread_block(); // thread block ์ํ๋ก ์ ํ
}
intr_set_level(old_level); // Anabling Interrupts
}
Thread๋ฅผ sleep queue์ ์ฝ์ (list_push_back())ํ๊ณ , blocked ์ํ๋ก ๋ง๋ค์ด์ ๋๊ธฐํ๋ค. ์ด๋, Disabling Interrupts๋ฅผ ํตํด ๊ณผ์ ์ค Interrupts๋ฅผ ๋ฐ์๋ค์ด์ง ์๊ณ , thread๋ฅผ Block ์ํ๋ก์ ์ ํ ํ์ Interrupts๋ฅผ ๋ฐ์๋ค์ธ๋ค(Anabling Interrupts).
timer_sleep() ํจ์ ์์
void timer_sleep(int64_t ticks) {
int64_t start = timer_ticks();
ASSERT(intr_get_level() == INTR_ON);
thread_sleep(start + ticks); // ํ์ฌ tick + ์์ผํ๋ tick = ๊นจ์ด๋์ผํ ์๊ฐ
}
Interrupts๋ฅผ ๋ฐ์๋ค์ด๊ณ ์์ ๋(Interrupts ON), ํ์ฌ OS์ tick(์๊ฐ)์ ์์ผํ๋ ์๊ฐ tick์ ๋ํด์ ๊นจ์ด๋์ผํ '์๊ฐ'์ ๊ตฌํ์ฌ thread_sleep() ํจ์์ ์ธ์๋ก ์ฌ์ฉํ๋ค. ๐ก ์ฆ, ํ์ฌ threads๋ OS์ tick์ด 'start + tick'์ผ ๋ wake up ํ๊ฒ ๋๋ค.
timer_interrupt() ํจ์
static void timer_interrupt(struct intr_frame *args UNUSED) {
ticks++;
thread_tick();
thread_awake(ticks);
}
timer_interrup() ํจ์์ thread_awake(ticks)๋ฅผ ์ถ๊ฐํ์ฌ์ ticks๊ฐ ์ฆ๊ฐํ ๋๋ง๋ค wake upํ ์ ์๋ Thread๊ฐ ์๋์ง ์ฐพ๊ณ , Ready ์ํ๋ก ์ ํ์์ผ ์ค๋ค. ์ด๋ก์จ Sleep/Wake up ๋ฐฉ์์ผ๋ก ๊ตฌํ์ด ๊ฐ๋ฅํ๋ค.
๐ ๋ฐ์ํ Bug
thread_sleep() ํจ์ ๊ตฌํ ์ค ๋ฐ์ํ๋ 'Keral PANIC' error์ด๋ค. ๊ตฌํ ๊ฒฐ๊ณผ๋ฅผ ์ดํด๋ณด๋ฉด, ์๋์ ๊ฐ๋ค.
Timer: 27 ticks
Thread: 1 idle ticks, 26 kernel ticks, 0 user ticks
26 kernel ticks์ 1 idle ticks ํ, Kernel PANIC์ผ๋ก test๊ฐ failed ํ๋ค.
Kernel PANIC
์ด๋ "LINUX ์์คํ ์ ์ฌ๊ฐํ ์ค๋ฅ๊ฐ ์๊ฒจ ์์คํ ์ ๋ค์ด์ํค๋ ๋์"์ด๋ผ๊ณ ํ๋ค. Thread ๊ตฌํ ์ค ํด๋น ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์๋ ๊ฒฝ์ฐ๋ก '์์์ ๊ณ ๊ฐ', '์์คํ ์ ๋ถ์์ ์ฑ', '์ค๋ฅ ์ฒ๋ฆฌ์ ์คํจ', '๋๋ฒ๊น ๋ฐ ์ค๋ฅ ๋ณด๊ณ ๋งค์ปค๋์ฆ'์ ๋ค ์ ์๋ค(by Chat GPT). ์์คํ ์ ์ถฉ๋ถํ ์์์ด ์๊ฒ ๋์์ ๊ฒฝ์ฐ๊ฐ ์์์ ์ ์ ์์๋ค.
๋ฌธ์ ๋ sleep_list์ push back ํ๋ current thread์ ticks๊ฐ ํ ๋น๋์ง ์์๊ธฐ์ ๋ฐ์ํ๊ณ , ์ด๋ก์ธํด Kernel์์ ์ด Thread๋ค์ ๋ค์ Wake up ์ํค์ง ๋ชปํ๊ธฐ์ ๋ฐ์ํ ์ค๋ฅ์๋ค. ๊ทธ๋์ 26 ticks์ kernel๊ณผ 1 ticks์ idle ํ์ ์ฌ์ฉํ ์ ์๋ ์์์ด ์์ด Kernel Panic์ด ๋ฐ์ํ ๊ฒ์ด๋ค.
'๐งญ KAIST JUNGLE > Pintos' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[PintOS] User Program - System Call2 (Project 2, TIL) (0) | 2024.05.14 |
---|---|
[PintOS] User Program - System Call (Project 2, TIL) (2) | 2024.05.08 |
[PintOS] User Program - Arguments parsing (Project 2, TIL) (0) | 2024.05.06 |
[PintOS] User Program - ๋ฐฐ๊ฒฝ์ง์(Project 2, TIL) (1) | 2024.05.04 |
[PintOS] Thread - Priority Scheduling (Project 1, WIL) (0) | 2024.05.02 |