[pintOS] Project1-1. Alarm clock

μ˜ˆλ‹ˆΒ·2021λ…„ 2μ›” 3일
0

pintOSν”„λ‘œμ νŠΈ

λͺ©λ‘ 보기
1/6

πŸ“… κΈ°κ°„ : 2021.01.28(수) ~ 2021.01.29(금)


1. 과제 λͺ©ν‘œ

ν˜ΈμΆœν•œ ν”„λ‘œμ„ΈμŠ€λ₯Ό 정해진 μ‹œκ°„ 후에 λ‹€μ‹œ μ‹œμž‘ν•˜λŠ” 컀널 λ‚΄λΆ€ ν•¨μˆ˜λ₯Ό Alarm이라 ν•œλ‹€.
ν˜„μž¬ ν•€ν† μŠ€μ—λŠ” Busy waiting을 μ΄μš©ν•˜μ—¬ κ΅¬ν˜„λ˜μ–΄ μžˆλ‹€.
λ³Έ ν”„λ‘œμ νŠΈμ—μ„œλŠ” μ•ŒλžŒ κΈ°λŠ₯을 sleep/wake up을 μ΄μš©ν•˜μ—¬ λ‹€μ‹œ κ΅¬ν˜„ν•œλ‹€.

* 배경지식

πŸ’‘ Busy waiting?

Threadκ°€ CPUλ₯Ό μ μœ ν•˜λ©΄μ„œ λŒ€κΈ°ν•˜κ³  μžˆλŠ” μƒνƒœ
CPU μžμ›μ΄ λ‚­λΉ„ 되고, μ†Œλͺ¨ μ „λ ₯이 λΆˆν•„μš”ν•˜κ²Œ 낭비될 수 있음
9μ‹œμ— μΌμ–΄λ‚˜λ €κ³  μ•ŒλžŒμ„ λ§žμΆ°λ†¨λŠ”λ° 1λΆ„λ§ˆλ‹€ κΉ¨μ„œ μ‹œκ°„μ„ ν™•μΈν•˜λŠ” 거라고 μƒκ°ν•˜λ©΄ μ΄ν•΄ν•˜κΈ° 쉽닀.
이런 νž˜λ“  μƒνƒœμΈ Busy waiting을 κΉ° μ‹œκ°„κΉŒμ§€ ν‘Ή 재우고, κΉ° μ‹œκ°„μ— κΉ¨μš°λŠ” 방식이 sleep/wake up 방식이닀.

πŸ’‘ ν”„λ‘œμ„ΈμŠ€μ˜ μƒνƒœ

ν”„λ‘œμ„ΈμŠ€λŠ” μ•„λž˜ ν‘œμ™€ 같이 5κ°€μ§€μ˜ μƒνƒœλ₯Ό κ°€μ§ˆ 수 μžˆλ‹€.

πŸ’‘ ν•€ν† μŠ€μ—μ„œμ˜ μŠ€λ ˆλ“œ, ν”„λ‘œμ„ΈμŠ€

ν•€ν† μŠ€μ—μ„œλŠ” ν”„λ‘œμ„ΈμŠ€μ™€ μŠ€λ ˆλ“œλ₯Ό λ™μΌμ‹œν•˜κ³  μžˆλ‹€. κ·Έλž˜μ„œ μœ„μ˜ ν”„λ‘œμ„ΈμŠ€ μƒνƒœλ₯Ό μŠ€λ ˆλ“œλ„ λ˜‘κ°™μ΄ κ°–λŠ”λ‹€.
μ΅œμ‹  μš΄μ˜μ²΄μ œμ—μ„œλŠ” λ‹Ήμ—°νžˆ λ©€ν‹°μŠ€λ ˆλ”©μ„ μ§€μ›ν•˜μ§€λ§Œ,
ꡐ윑용 OS인 ν•€ν† μŠ€λŠ” ν”„λ‘œμ„ΈμŠ€λ‹Ή ν•˜λ‚˜μ˜ μŠ€λ ˆλ“œλ‘œ κ΅¬μ„±λ˜μ–΄μžˆλ‹€!
κ·Έλž˜μ„œ ν”„λ‘œμ„ΈμŠ€μ™€ μŠ€λ ˆλ“œλ₯Ό λ™μΌν•˜κ²Œ μ—¬κΈ°κ³  κ΅¬ν˜„ν•˜λŠ” 것이닀.


2. Busy waiting μ½”λ“œ

void timer_sleep(int64_t ticks)
{
	int64_t start = timer_ticks();

	ASSERT(intr_get_level() == INTR_ON);

	// busy waiting 유발 μ½”λ“œ 
	while (timer_elapsed (start) < ticks)
		thread_yield ();

}

ν˜„μž¬λŠ” μœ„ μ½”λ“œμ™€ 같이, 계속 ν™•μΈν•˜κ³  ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜λŠ” busy waiting λ°©μ‹μœΌλ‘œ κ΅¬ν˜„λ˜μ–΄ μžˆλ‹€.
while문을 μ‹€ν–‰ν•˜λ©΄μ„œ thread_yield()λ₯Ό ν˜ΈμΆœν•˜μ—¬ ready list 에 μžˆλŠ” λ‹€λ₯Έ μŠ€λ ˆλ“œλ₯Ό μœ„ν•΄ CPU 점유λ₯Ό λ°˜ν™˜ν•˜κ³  ready list κ°€μž₯ λ’€λ‘œ μ΄λ™ν•œλ‹€. 이 과정은 ticks λ™μ•ˆ λ°˜λ³΅λœλ‹€.


3. Sleep/wake up κ΅¬ν˜„

ν‘Ή 쉬지 λͺ»ν•˜λŠ” μŠ€λ ˆλ“œλ₯Ό μ‰¬κ²Œ ν•΄μ£Όκ³  μ‹Άλ‹€.

μžμ•Όν•  애듀은 본인이 block(sleep) μƒνƒœλ‘œ λ§Œλ“€μ–΄ sleep_list에 λ„£μ–΄λ‘”λ‹€. -> κΉ° μ‹œκ°„μ΄ 되면 μ°Ύμ•„κ°€μ„œ λ‹€μ‹œ Ready μƒνƒœλ‘œ λ°”κΏ”μ€€λ‹€.

  • thread ꡬ쑰체에 본인이 κΉ¨μ–΄λ‚  μ‹œκ°„μ„ μ €μž₯ν•˜λŠ” wakeup_ticks λ³€μˆ˜λ₯Ό μ„ μ–Έν•œλ‹€.
  • sleep ν•˜λŠ” 애듀을 담을 sleep_list λ₯Ό μ •μ˜ν•œλ‹€.
    (λ°˜λ“œμ‹œ thread_initν•¨μˆ˜μ—μ„œ sleep_listλ₯Ό μ΄ˆκΈ°ν™”ν•΄μ•Όν•œλ‹€.)
  • μ§€κΈˆ 깨울 애듀이 μ—†λŠ”λ° 깨우러 λ‹€λ‹ˆλŠ” λ‚­λΉ„λ₯Ό 막기 μœ„ν•΄ μž μžλŠ” 애듀쀑에 κ°€μž₯ λ¨Όμ € 일어날 μ• κ°€ 일어날 μ‹œκ°μ„ μ €μž₯ν•˜λŠ” next_tick_to_awake λ³€μˆ˜λ₯Ό μΆ”κ°€ν•œλ‹€.
  • next_tick_to_awake에 λŒ€ν•œ getter와 setter 역할을 ν•˜λŠ” update_next_tick_to_awake, get_next_tick_to_awake ν•¨μˆ˜λ₯Ό μΆ”κ°€ν•œλ‹€.
  • μŠ€λ ˆλ“œλ₯Ό 재우고, κΉ¨μš°λŠ” thread_sleep, thread_awake ν•¨μˆ˜λ₯Ό μΆ”κ°€ν•œλ‹€.

thread_sleep
재울 애듀은 sleep_list에 μΆ”κ°€ν•˜κ³  blockμƒνƒœλ‘œ λ§Œλ“ λ‹€.
이 κ³Όμ •μ—μ„œ μΈν„°λŸ½νŠΈμ˜ λ°©ν•΄λ₯Ό λ¬΄μ‹œν•˜κ³  μ˜¨μ „νžˆ ν•¨μˆ˜ λ‚΄λΆ€λ₯Ό μ‹€ν–‰ν•  수 μžˆμ–΄μ•Όν•˜κΈ° λ•Œλ¬Έμ— μ²˜μŒμ— intr_disable()ν•¨μˆ˜λ₯Ό 톡해 μΈν„°λŸ½νŠΈλ₯Ό 받아듀이지 μ•Šλ„λ‘ ν•˜κ³  λ‚΄λΆ€κ°€ λ‹€ μ‹€ν–‰λ˜κ³  λ§ˆμ§€λ§‰ 뢀뢄에 λ‹€μ‹œ intr_set_level(old_level) ν•¨μˆ˜λ₯Ό 톡해 μΈν„°λŸ½νŠΈλ₯Ό 받아듀이도둝 ν•œλ‹€.

thread_awake
sleep list의 λͺ¨λ“  entryλ₯Ό μˆœνšŒν•˜λ©΄μ„œ ν˜„μž¬ tick이 κΉ¨μ›Œμ•Ό ν•  tick 보닀
μž‘λ‹€λ©΄ 슬립 νμ—μ„œ μ œκ±°ν•˜κ³  unblockν•œλ‹€.
크닀면 next_tick_to_awakeλ³€μˆ˜λ₯Ό κ°±μ‹ ν•˜κΈ° μœ„ν•΄ update_next_tick_to_awake()λ₯Ό ν˜ΈμΆœν•œλ‹€.


4. κ²°κ³Ό

Thread : 0 idle ticks ... -> Thread : 550 idle ticks ...

idle μŠ€λ ˆλ“œλŠ” CPU κ°€ 아무 할일도 없을 λ•Œ μ‹€ν–‰λ˜λŠ” μŠ€λ ˆλ“œλ‘œ idle tickλŠ” idle μŠ€λ ˆλ“œκ°€ μ‹€ν–‰λœ tick수, μ‹œκ°„μ„ μ˜λ―Έν•œλ‹€.
Busy-Waiting λ°©μ‹μ—μ„œλŠ” 계속 CPUκ°€ 점유되고 μžˆμ–΄ idle μŠ€λ ˆλ“œκ°€ 싀행될 일이 μ—†μ—ˆμ§€λ§Œ, Sleep / Wake up λ°©μ‹μœΌλ‘œ λ³€κ²½ν•œ ν›„μ—λŠ” CPUκ°€ μž μžλŠ” μŠ€λ ˆλ“œλ₯Ό μ μœ ν•˜μ§€ μ•Šκ³  idle μŠ€λ ˆλ“œκ°€ μ μœ ν–ˆμŒμ„ μ•Œ 수 μžˆλ‹€.

이것은 μŠ€λ ˆλ“œκ°€ μž μžλŠ” λ™μ•ˆ μ‹œμŠ€ν…œ μžμ›μ„ λ‚­λΉ„ν•˜μ§€ μ•Šλ„λ‘ ν•œ 것이닀.


πŸ€” 회고

와.. 쉽지 μ•Šλ‹€...
정글에 μ˜€κ³ λ‚˜μ„œ 맀일맀일이 μƒˆλ‘­μ§€λ§Œ, OS의 μ•…λͺ…은 많이 λ“€μ—ˆμ§€λ§Œ, μ΄λ ‡κ²ŒκΉŒμ§€ μƒˆλ‘œμšΈ 쀄은 λͺ°λžλ‹€. OS μ‹œμž‘ μ „, 3μ£Όλ™μ•ˆ B+트리, malloc lab, μ›Ήμ„œλ²„ κ΅¬ν˜„μ„ ν•˜λ©΄μ„œ λ‚˜λ¦„ μƒμ†Œν•œ κ°œλ…μ„ λ§ˆμ£Όν•˜λŠ” 데에 μ΅μˆ™ν•΄μ‘Œλ‹€κ³  μƒκ°ν–ˆλŠ”λ° μ „ν˜€ μ•„λ‹ˆμ—ˆλ‹€. λ‹Ήμž₯ ν”„λ‘œμ„ΈμŠ€, μŠ€λ ˆλ“œκ°€ ꡬ뢄도 μ•ˆκ°€λŠ” μƒνƒœμ—μ„œ OSλ₯Ό κ΅¬ν˜„ν•˜λΌλ‹ˆμš”.. μ—„μ²­ λ§‰λ§‰ν–ˆμ§€λ§Œ μ—­μ‹œλ‚˜ 삽을 λ“€κ³  νŒŒλ‹€λ³΄λ©΄ μ–΄λ–»κ²Œλ“  λœλ‹€. μ²˜μŒμ— ν•€ν† μŠ€ git clone을 λ°›κ³  μ–΄λ””λΆ€ν„° λ΄μ•Όν•˜λŠ”μ§€λ„ λͺ°λžλŠ”데, 일주일이 μ§€λ‚œ μ§€κΈˆμ€ project1을 μ™„λ£Œν•˜κ³  project2 μ‹œμž‘μ„ μ•žλ‘κ³  μžˆλ‹€. ν•€ν† μŠ€ μ‹œμž‘ν•˜κ³  평균 μˆ˜λ©΄μ‹œκ°„μ΄ ν™• μ€„μ—ˆλ‹€. μ•„μ΄λŸ¬λ‹ˆν•œ 것은 정말 νž˜λ“€μ§€λ§Œ μž¬λ°Œλ‹€λŠ” 점.
μ—΄μ‹¬νžˆ κ³΅λΆ€ν•΄μ„œ project4κΉŒμ§€ 재밌게, λ¬΄μ‚¬νžˆ 마쳀으면!

1개의 λŒ“κΈ€

comment-user-thumbnail
2021λ…„ 2μ›” 5일

쉽지 μ•Šλ‹€... ν™”μ΄νŒ…

λ‹΅κΈ€ 달기