OS Project1: THREADS(2)

wu2eeยท2021๋…„ 2์›” 3์ผ
0

OS PROJECT

๋ชฉ๋ก ๋ณด๊ธฐ
5/10

1. Alarm System Call

๋ชฉํ‘œ

  • Alarm : ํ˜ธ์ถœํ•œ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ •ํ•ด์ง„ ์‹œ๊ฐ„ ํ›„์— ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๋Š” ์ปค๋„ ๋‚ด๋ถ€ ํ•จ์ˆ˜
  • Pintos์—์„œ๋Š” ์•Œ๋žŒ ๊ธฐ๋Šฅ์ด Busy waiting์„ ์ด์šฉํ•˜์—ฌ ๊ตฌํ˜„๋˜์–ด ์žˆ์Œ
  • ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„œ ์•Œ๋žŒ ๊ธฐ๋Šฅ์„ sleep/wake up์„ ์ด์šฉํ•˜์—ฌ ๋‹ค์‹œ ๊ตฌํ˜„ ํ•œ๋‹ค.

Busy waiting ์ด๋ž€?

  • Thread๊ฐ€ CPU๋ฅผ ์ ์œ ํ•˜๋ฉด์„œ ๋Œ€๊ธฐํ•˜๊ณ  ์žˆ๋Š” ์ƒํƒœ
  • CPU ์ž์›์ด ๋‚ญ๋น„ ๋˜๊ณ , ์†Œ๋ชจ ์ „๋ ฅ์ด ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋‚ญ๋น„๋  ์ˆ˜ ์žˆ๋‹ค.
/* Suspends execution for approximately TICKS timer ticks. */
void timer_sleep (int64_t ticks) {
	int64_t start = timer_ticks ();
	ASSERT(intr_get_level() == INTR_ON);

	while (timer_elapsed (start) < ticks)
		thread_yield ();
}

ํ˜„์žฌ while๋ฌธ ์•ˆ์—์„œ ์ธ์ž๋กœ ๋ฐ›์€ ticks ๋งŒํผ ๊ณ„์†ํ•ด์„œ ํ˜„์žฌ CPU ์ ์œ ๋ฅผ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—๊ฒŒ ์–‘๋ณดํ•˜๊ณ  ready_list์˜ ์ œ์ผ ๋’ค๋กœ ๋„ฃ์–ด์ฃผ๊ณ  ์žˆ๋‹ค.

์ฆ‰, ๊ณ„์†ํ•ด์„œ ๋ฌดํ•œ ๋ฃจํ”„๋ฅผ ๋Œ๋ฉด์„œ ์ฒดํฌ๋ฅผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— CPU ์ž์›์„ ๋‚ญ๋น„ํ•˜๊ฒŒ ๋œ๋‹ค.

๐Ÿ‘€ ์ฐธ๊ณ  ์‚ฌํ•ญ
๊ธฐ๋ณธ์ ์œผ๋กœ system timer๋Š” ์ดˆ๋‹น 100ํšŒ์˜ ticks์„ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค (์ฆ‰, 1 tick = 10ms )

ํ•€ํ† ์Šค์˜ Thread Lifecycle

ํ•€ํ† ์Šค์˜ list ์ž๋ฃŒ ๊ตฌ์กฐ

๐Ÿ’ป ๊ตฌํ˜„ํ•˜๊ธฐ

1. thread ๊ตฌ์กฐ์ฒด ์ˆ˜์ •

  • ๊นจ์–ด๋‚˜์•ผ ํ•  tick์„ ์ €์žฅ (wakeup_tick)

2. ์ „์—ญ๋ณ€์ˆ˜ ์ถ”๊ฐ€

  • Sleep queue ์ž๋ฃŒ๊ตฌ์กฐ ์ถ”๊ฐ€
  • next_tick_to_awake ์ „์—ญ ๋ณ€์ˆ˜ ์ถ”๊ฐ€
  • sleep_list์—์„œ ๋Œ€๊ธฐ์ค‘์ธ ์Šค๋ ˆ๋“œ ๋“ค์˜ wakeup_tick ๊ฐ’ ์ค‘ ์ตœ์†Œ๊ฐ’์„ ์ €์žฅ

3. ๊ตฌํ˜„ํ•  ํ•จ์ˆ˜ ์„ ์–ธ

4. thread_init() ํ•จ์ˆ˜ ์ˆ˜์ •

  • Sleep queue ์ž๋ฃŒ๊ตฌ์กฐ ์ดˆ๊ธฐํ™” ์ฝ”๋“œ ์ถ”๊ฐ€

5. timer_sleep() ํ•จ์ˆ˜ ์ˆ˜์ •

  • Sleep queue๋ฅผ ์ด์šฉํ•˜๋„๋ก ํ•จ์ˆ˜ ์ˆ˜์ •

6. thread_sleep() ํ•จ์ˆ˜ ๊ตฌํ˜„

  • Thread๋ฅผ blocked ์ƒํƒœ๋กœ ๋งŒ๋“ค๊ณ  sleep queue์— ์‚ฝ์ž…ํ•˜์—ฌ ๋Œ€๊ธฐ
  • timer_sleep() ํ•จ์ˆ˜์— ์˜ํ•ด ํ˜ธ์ถœ

์—ฌ๊ธฐ์„œ ํ˜„์žฌ ์Šค๋ ˆ๋“œ๊ฐ€ idle thread ์ด๋ฉด sleep ๋˜์ง€ ์•Š๋„๋ก ํ•ด์•ผํ•œ๋‹ค. idle ์Šค๋ ˆ๋“œ๋Š” ์šด์˜์ฒด์ œ๊ฐ€ ์ดˆ๊ธฐํ™”๋˜๊ณ  ready_list๊ฐ€ ์ƒ์„ฑ๋ ๋•Œ ์ฒซ๋ฒˆ์งธ๋กœ ์ถ”๊ฐ€๋˜๋Š” ์Šค๋ ˆ๋“œ์ด๋‹ค. ๊ตณ์ด ์ด ์Šค๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค์–ด์ค€ ์ด์œ ๋Š” CPU๋ฅผ ์‹คํ–‰์ƒํƒœ๋กœ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•จ์ด๋‹ค.

CPU๊ฐ€ ํ• ์ผ์ด ์—†์œผ๋ฉด ์•„์˜ˆ ๊บผ์ ธ๋ฒ„๋ฆฌ๊ณ , ํ•  ์ผ์ด ์ƒ๊ธฐ๋ฉด ๋‹ค์‹œ ์ผœ์ง€๋Š” ๋ฐฉ์‹์ด๋ฏ€๋กœ ์†Œ๋ชจ๋˜๋Š” ์ „๋ ฅ๋ณด๋‹ค ๋ฌด์˜๋ฏธํ•œ ์ผ์ด๋ผ๋„ ๊ทธ๋ƒฅ ๊ณ„์† ํ•˜๊ณ  ์žˆ๋Š”๊ฒŒ ๋” ์ ์€ ์ „๋ ฅ์„ ์†Œ๋ชจํ•œ๋‹ค.

7. timer_interrupt() ํ•จ์ˆ˜ ์ˆ˜์ •

8. thread_awake() ํ•จ์ˆ˜ ๊ตฌํ˜„

  • wakeup_tick๊ฐ’์ด ticks๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€ ์Šค๋ ˆ๋“œ๋ฅผ ๊นจ์›€
  • ํ˜„์žฌ ๋Œ€๊ธฐ์ค‘์ธ ์Šค๋ ˆ๋“œ๋“ค์˜ wakeup_tick๋ณ€์ˆ˜ ์ค‘ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’์„ next_tick_to_awake ์ „์—ญ ๋ณ€์ˆ˜์— ์ €์žฅ

9. update_next_tick_to_awake() ํ•จ์ˆ˜ ์ถ”๊ฐ€

  • next_tick_to_awake ๋ณ€์ˆ˜๋ฅผ ์—…๋ฐ์ดํŠธ

10. get_next_tick_to_awake() ํ•จ์ˆ˜ ์ถ”๊ฐ€

๊ฒฐ๊ณผ


busy waiting์„ ์ œ๊ฑฐํ•œ ํ›„์—๋Š” sleep ์ƒํƒœ์—์„œ CPU๋ฅผ ์ ์œ ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— idel tick์ด ์ฆ๊ฐ€ํ•จ.

Question

Q : timer_interrupt๋ฅผ ํ•˜๋Š” ๊ฒƒ์€ ํ•˜๋“œ์›จ์–ด์—์„œ ์ผ์–ด๋‚˜๋Š” ๋…๋ฆฝ์ ์ธ main ๋ฌธ์œผ๋กœ ๋ณด์•„๋„ ๋˜๋Š”๊ฐ€? ์˜ˆ๋ฅผ ๋“ค๋ฉด timer_sleep ํ•จ์ˆ˜์—์„œ busy waiting ์‹œ์— while๋ฌธ ์•ˆ์— ์žˆ์Œ์—๋„ timer tick์ด ๊ณ„์† ์ฆ๊ฐ€ํ•˜๋Š” ์ .

A : ๋น„์Šทํ•œ ๋Š๋‚Œ์œผ๋กœ ์ƒ๊ฐ ํ•˜๋ฉด ๋œ๋‹ค. Interrupt๊ฐ€ enable ๋˜์–ด์žˆ๋‹ค๋ฉด kenel code์˜ ์–ด๋Š ๋ถ€๋ถ„์„ ์‹คํ–‰ ์ค‘์ด๋“  timer_interrupt๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ๋ฅผ๋“ค์–ด

1 int main () {
2   int i = 0;
3   i += 1;
4   i -= 10;
5   return 0;
6 }

์ด๋Ÿฐ ์ฝ”๋“œ๊ฐ€ ์žˆ๊ณ , timer interrupt handler๊ฐ€

7 void timer_intr_handler () {
8   timer_ticks ++;
9 }

์ด๋Ÿฐ ์‹์œผ๋กœ ์ƒ๊ฒผ๋‹ค๋ฉด, main ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰์ค‘์ผ ๋•Œ 1~2๋ฒˆ ์ค„ ์‚ฌ์ด, 2~3๋ฒˆ ์ค„ ์‚ฌ์ด ๋“ฑ ์–ด๋Š ์œ„์น˜์—์„œ๋“  interrupt๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ 2~3๋ฒˆ ์ค„ ์‚ฌ์ด์—์„œ timer iinterrupt๊ฐ€ ๋ฐœ์ƒ๋˜์—ˆ๋‹ค๋ฉด, ์‹ค์ œ๋กœ ์ฝ”๋“œ๋Š” 1 -> 2 -> 7 -> 8 -> 9 -> 3 -> 4 -> 5 -> 6 ์ˆœ์œผ๋กœ ์‹คํ–‰๋œ๋‹ค.

profile
์ฆ๊ฒ๊ฒŒ ์ฝ”๋”ฉํ•ฉ์‹œ๋‹ค

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