Pintos P2 - ์‚ฌ์ „ ์ž‘์—….

12 minute read

3๋…„๊ฐ„ ์‚ฐ์—…๊ธฐ๋Šฅ์š”์›์œผ๋กœ ๋ณต๋ฌด ํ•˜๊ณ , ๋ณตํ•™ํ•ด ์ปด๊ณต๊ณผ ์ˆ˜์—…์„ ๋“ฃ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋™์•ˆ ๋งŽ์ด ๋ฐฐ์› ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋Š”๋ฐ, ์—ฌ์ „ํžˆ ๋ถ€์กฑํ•œ ๋ถ€๋ถ„์ด ๋งŽ๋„ค์š” ^^;; ์—ญ์‹œ ์„ธ์ƒ๋„ ๋„“๊ณ  ๊ณต๋ถ€์˜ ๊ธธ๋„ ๋„“์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ด ๊ธ€์€ ์ œ๊ฐ€ Pintos P2๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด Pintos ์ฝ”๋“œ์™€ ๊ฐ์ข… ์ž๋ฃŒ๋ฅผ ์ฐพ์•„๋ณด๋ฉฐ, ์ •๋ฆฌํ•œ ์‚ฌ์ „ ์ž๋ฃŒ ์ž…๋‹ˆ๋‹ค. Pintos P2 ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•œ ํ”์ ์ด๋ผ๊ณ  ๋ณด์‹œ๋ฉด ๋  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Virtual Memory

์‚ฌ์‹ค Virtual Memory๋Š” Pintos P3์—์„œ ๊ตฌํ˜„ํ•˜๋Š” ์ฃผ์ œ์ด๋‹ค. ๊ทธ๋Ÿฐ๋ฐ, ์ค‘๊ฐ„๊ณ ์‚ฌ ์ค€๋น„ํ•  ๋•Œ๋ถ€ํ„ฐ ์šฉ์–ด๊ฐ€ ํŠ€์–ด ๋‚˜์™€์„œ ์–ด์ฉ” ์ˆ˜ ์—†์ด ๋ฏธ๋ฆฌ ๊ณต๋ถ€ ํ–ˆ๋‹ค.

ํ•œ๋น›๋ฏธ๋””์–ด์—์„œ ์ด ์ฃผ์ œ์— ๋Œ€ํ•ด ์ž˜ ์ •๋ฆฌํ•œ ์˜์ƒ์ด ์˜ฌ๋ผ์™€ ์žˆ์œผ๋‹ˆ ์ฐธ๊ณ ํ•˜๋„๋ก ํ•œ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ์š”์•ฝ๋งŒ ์ ์–ด๋‘”๋‹ค.

What is Virtual Memory

์ผ๋‹จ โ€œ๊ฐ€์ƒ ๋ฉ”๋ชจ๋ฆฌโ€๋ผ๋Š” ๊ธฐ์ˆ ์€ ์‹ค์ œ ๋ฌผ๋ฆฌ ๋ฉ”๋ชจ๋ฆฌ๋ณด๋‹ค ํฐ ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ๊ธฐ์ˆ ์ด๋‹ค.

Virtual memory.svg
By Ehamberg - Own work, CC BY-SA 3.0, Link

๊ตฌํ˜„์˜ ์ปจ์…‰์€ ๊ฐ„๋‹จํ•œ๋ฐ, ์‹คํ–‰ํ•˜๊ณ ์ž ํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์˜ โ€œ์ผ๋ถ€โ€๋งŒ ๋ฉ”๋ชจ๋ฆฌ์— ์ ์žฌํ•˜๊ณ , ์‹คํ–‰ํ•œ๋‹ค. ์ด๊ฒƒ์€ ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•  ๋•Œ, ํ”„๋กœ๊ทธ๋žจ์ด ์‚ฌ์šฉํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„ ์ „์ฒด๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ ค๋‘˜ ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์ดํ„ฐ๋Š” ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ ค๋‘๊ณ  ์‚ฌ์šฉํ•˜๋ฉฐ, ์ž์ฃผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ๋Š” Disk๋กœ ๋‚ด๋ ค์„œ(swap-out) ์ž ์‹œ ๋ณด๊ด€ ํ–ˆ๋‹ค๊ฐ€ ์‚ฌ์šฉํ•  ํƒ€์ด๋ฐ์ด ์˜ค๋ฉด ๊บผ๋‚ด์„œ(swap-in) ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

๊ฐ€์ƒ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ 2๊ฐ€์ง€๊ฐ€ ์žˆ๋Š”๋ฐ, Paging๊ณผ Segmentation์ด๋‹ค.

Paging

ํ”„๋กœ์„ธ์Šค์˜ ๋…ผ๋ฆฌ ์ฃผ์†Œ ๊ณต๊ฐ„์„ โ€œํŽ˜์ด์ง€(page)โ€œ๋ผ๋Š” ๋‹จ์œ„๋กœ ์ž๋ฅธ๋‹ค. ์ด๋•Œ, ๊ฐ ํŽ˜์ด์ง€์˜ ํฌ๊ธฐ๋Š” ๋ชจ๋‘ ๋™์ผํ•˜๋‹ค(ex. 4 kb). ๊ทธ๋ฆฌ๊ณ  ๋ฌผ๋ฆฌ์  ๋ฉ”๋ชจ๋ฆฌ์˜ ์ฃผ์†Œ ๊ณต๊ฐ„์„ โ€œํ”„๋ ˆ์ž„(frame)โ€œ๋ผ๋Š” ๋‹จ์œ„๋กœ ์ž๋ฅธ๋‹ค. ํ”„๋ ˆ์ž„์€ ํŽ˜์ด์ง€์™€ ๋™์ผํ•œ ํฌ๊ธฐ๋ฅผ ๊ฐ–๋Š”๋‹ค.

ํ”„๋กœ์„ธ์„œ์˜ ๊ฐ ํŽ˜์ด์ง€๋Š” ํ”„๋กœ์„ธ์Šค ๊ด€์ ์—์„œ ๋ณด๋ฉด, ์—ฐ์†ํ•œ ์ฃผ์†Œ ๊ณต๊ฐ„์— ์žˆ๋”๋ผ๋„, ๋ฌผ๋ฆฌ ๋ฉ”๋ชจ๋ฆฌ์ธ ํ”„๋ ˆ์ž„ ๊ด€์ ์—์„œ ๋ณด๋ฉด ๋ถˆ์—ฐ์†์ ์œผ๋กœ ๋ฐฐ์น˜ ๋œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ด ํŽ˜์ด์ง€์™€ ํ”„๋ ˆ์ž„์˜ ๋งคํ•‘ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ์ด โ€œํŽ˜์ด์ง€ ํ…Œ์ด๋ธ”(Page Table)โ€œ์ด๋‹ค.

์ด ํŽ˜์ด์ง€ ํ…Œ์ด๋ธ”์€ ๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผ์ด ๋ฐœ์ƒํ•  ๋•Œ๋งˆ๋‹ค ์ ‘๊ทผํ•ด์•ผ ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋กœ, ์ ‘๊ทผ์ด ๋งค์šฐ ๋นˆ๋ฒˆํ•˜๋‹ค. ๊ทธ๋ž˜์„œ CPU์— ๊ฐ€๊นŒ์šด ์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ ํ•ด๋‘๋Š”๋ฐ, ์ด ์บ์‹œ ๋ฉ”๋ชจ๋ฆฌ์˜ ์ž๋ฃŒ ๊ตฌ์กฐ๋ฅผ โ€œTLB(Translation Lookaside Buffer)โ€œ๋ผ๊ณ  ํ•œ๋‹ค. ๋ฌผ๋ก , TLB์— Page Table์˜ ๋‚ด์šฉ ์ „์ฒด๋ฅผ ๋‘๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ๊ณ , ์ด๋Ÿฐ ๊ฒฝ์šฐ โ€œTLB missedโ€๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

Segmentation

์„ธ๊ทธ๋จผํŠธ(Segment)๋Š” ๋ฉ”๋ชจ๋ฆฌ์˜ ํŠน์ • ๊ตฌ์—ญ์„ ๋‚˜ํƒ€๋‚ธ๋‹ค. ๊ตฌ์—ญ์ด๋ผ๊ณ  ํ•˜๋ฉด, Code, Data, Stack ๊ตฌ์—ญ์„ ๋งํ•˜๋ฉฐ ๊ฐ๊ฐ

  • Code Segment (CS)
  • Data Segment (DS)
  • Stack Segment (SS)

๋ผ๊ณ  ํ•œ๋‹ค. ๊ฐ ์„ธ๊ทธ๋จผํŠธ๋งˆ๋‹ค ๋‹ค๋ฅธ ์ ‘๊ทผ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋Š”๋ฐ, ์ฝ”๋“œ ์˜์—ญ์€ RX๋งŒ ๊ฐ€๋Šฅํ•˜๊ณ , Write๋ฅผ ๋ถˆ๊ฐ€ํ•˜๋‹ค.

๊ทธ๋ฆฌ๊ณ  ํ•œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค์˜ ๋ฉ”๋ชจ๋ฆฌ ์„ธ๊ทธ๋จผํŠธ์— ์ ‘๊ทผํ•˜์ง€ ๋ชป ํ•˜๋„๋ก ํ•ด์•ผ ํ•œ๋‹ค.


์„ธ๊ทธ๋จผํŠธ์™€ ํŽ˜์ด์ง• ๊ธฐ๋ฒ•์„ ๋น„๊ตํ•˜๋ฉด, ์„ธ๊ทธ๋จผํŠธ์˜ ๊ธฐ๋ณธ ๋‹จ์œ„์ธ โ€œ์„ธ๊ทธ๋จผํŠธโ€๋Š” ๊ทธ ํฌ๊ธฐ๊ฐ€ ์ •ํ•ด์ง€์ง€ ์•Š๊ณ  ๊ฐ€๋ณ€์ ์ด๋‹ค. ๊ทธ๋ž˜์„œ ํ•œ ํ”„๋กœ์„ธ์Šค์˜ Program Code๋Š” ๋ฌผ๋ฆฌ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„ ์ƒ์— ํ•˜๋‚˜์˜ ์„ธ๊ทธ๋จผํŠธ์— ๋ชจ๋‘ ๋“ค์–ด์žˆ์œผ๋ฉฐ ์—ฐ์†๋œ ๊ณต๊ฐ„์— ๋ฐฐ์น˜๋œ๋‹ค.

๋ฐ˜๋ฉด์—, ํŽ˜์ด์ง•์—์„œ๋Š” ์ฝ”๋“œ ์˜์—ญ์€ ์—ฌ๋Ÿฌ ํŽ˜์ด์ง€๋กœ ๋‚˜๋ˆ„์—ˆ๊ณ , ๋ฌผ๋ฆฌ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๊ฐ ์ฝ”๋“œ ํ”„๋ ˆ์ž„์ด ์—ฐ์†์ ์œผ๋กœ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค.

Kernel Memory vs. User Memory

๋ฌผ๋ฆฌ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์€ ํฌ๊ฒŒ, ์ปค๋„ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„๊ณผ ์œ ์ € ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์œผ๋กœ ๋‚˜๋‰œ๋‹ค. ๋‘ ๊ณต๊ฐ„์€ ์„œ๋กœ ์นจ๋ฒ”ํ•  ์ˆ˜ ์—†๋Š” ๊ณต๊ฐ„์ด๋‹ค. ์ปค๋„ ๊ณต๊ฐ„์—๋Š” ์ปค๋„ ๋™์ž‘์— ํ•„์š”ํ•œ code, data, stack, heap ์„น์…˜์ด ์กด์žฌํ•œ๋‹ค. ์œ ์ € ๊ณต๊ฐ„์—๋Š” ์œ ์ € ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰ํ•˜๋Š” code, data, stack, heap์ด ์ €์žฅ๋œ๋‹ค. ์œ ์ € ๊ณต๊ฐ„์—๋Š” ์—ฌ๋Ÿฌ ํ”„๋กœ๊ทธ๋žจ์ด ๊ณต๊ฐ„์„ ์ ์œ ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ ๋ณธ์ธ์€ ์ง์ ‘ ํ™•์ธํ•˜์ง€ ์•Š์œผ๋ฉด ์ฐ์ฐํ•˜๋‹ˆโ€ฆ ๊ณผ์—ฐ์ด ์ด ๋ง์ด ์ง„์งœ์ธ์ง€ ๊ถ๊ธˆํ•ด์กŒ๋‹ค ใ…‹ใ…‹ใ…‹ ์ฐพ์•„๋ณด๋‹ˆ vm_stats๋ผ๋Š” ๋ช…๋ น์–ด๋ฅผ ์“ฐ๋ฉด ์ปค๋„ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์œผ๋กœ ์–ผ๋งŒํผ์ด ์žกํ˜€ ์žˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ,

$ vm_stats
Mach Virtual Memory Statistics: (page size of 16384 bytes)
Pages free:                               18228.
Pages active:                            952019.
Pages inactive:                          948651.
Pages speculative:                         2472.
Pages throttled:                              0.
Pages wired down:                        212664.
Pages purgeable:                          57595.
...

๋‚ด๊ฐ€ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” M3 ๋งฅ๋ถ ๊ธฐ์ค€์œผ๋กœ๋Š” 212664 * 16384 bytes = 3.48 Gb ์ •๋„๊ฐ€ wired memory, ๊ณ ์ •๋œ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์œผ๋กœ ์žกํ˜€ ์žˆ๋‹ค. ์ฐธ๊ณ ๋กœ ํ˜„์žฌ ๋งฅ๋ถ์˜ ์ „์ฒด ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์ด์ฆˆ๋Š” 36 Gb์ด๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค ํšŒ์‚ฌ๋‹˜ ๐Ÿฅฏ ๋Œ€์ถฉ 10% ์ •๋„๊ฐ€ ์ปค๋„ ๊ณต๊ฐ„์œผ๋กœ ์žกํ˜€ ์žˆ๋Š” ์…ˆ์ด๋‹ค.

Interrupt Frame

์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒ ํ–ˆ์„ ๋•Œ, ํ˜„์žฌ ์ž‘์—…์„ ๋ฉˆ์ถ”๊ณ  ์ธํ„ฐ๋ŸฝํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋™์•ˆ CPU์˜ ์ƒํƒœ๋ฅผ ์ €์žฅํ•ด๋‘๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•จ.

์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด, CPU๋Š” ํ˜„์žฌ ๋ ˆ์ง€์Šคํ„ฐ์˜ ์ƒํƒœ, PC, EFLAS๋ฅผ ๋ชจ๋‘ ์Šคํƒ์— ์ €์žฅํ•œ๋‹ค. ์Šคํƒ์— ์ €์žฅํ•  ๋•Œ, ๊ทธ๋ƒฅ ์ €์žฅํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ Interrupt Frame๋ผ๋Š” ๊ฑฐ์— ๋‹ด์•„์„œ ์ €์žฅํ•œ๋‹ค.


Stack Frame์— ๋Œ€ํ•ด์„œ๋Š” ์ค‘๊ฐ„๊ณ ์‚ฌ ๊ณต๋ถ€ํ•˜๋ฉด์„œ ๋”ฐ๋กœ ์ •๋ฆฌ๋ฅผ ํ•ด๋’€๋Š”๋ฐ, Interrupt Frame์„ ๊ณต๋ถ€ํ•˜๊ณ  ๋‚˜๋‹ˆ ๋‘˜๋‹ค ํ”„๋ ˆ์ž„์ธ๋ฐ, ์–ด๋–ค๊ฒŒ ๋‹ค๋ฅธ์ง€ ๊ถ๊ธˆํ•ด์กŒ๋‹ค.

inline assembly

Pintos P2๋ถ€ํ„ฐ๋Š” C์ฝ”๋“œ์—์„œ ์–ด์…ˆ๋ธ”๋ฆฌ ์ฝ”๋“œ๋„ ๋“ฑ์žฅํ•œ๋‹ค ใ…Žใ„ทใ„ท;; ์•„๋ž˜์™€ ๊ฐ™์ด ๋‚˜์˜ค๋Š”๋ฐ, ์ด๋ฒˆ์— ์ฒ˜์Œ๋ณด๋Š” ์ฝ”๋“œ๋ผ ํ•œ๋ฒˆ ์ •๋ฆฌํ•ด๋ณธ๋‹ค.

asm volatile ("movl %0, %%esp; jmp intr_exit" : : "g" (&if_) : "memory");

์ผ๋‹จ asm์€ inline assembly๋ฅผ ์“ฐ๊ธฐ ์œ„ํ•œ ํ‚ค์›Œ๋“œ์ด๋‹ค. asm ("INLINE ASM")์œผ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

volatile์€ C์–ธ์˜ ์ตœ์ ํ™” ๊ด€๋ จ ํ‚ค์›Œ๋“œ์ด๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ด ์ฝ”๋“œ ๋ผ์ธ์„ ์ตœ์ ํ™” ํ•˜์ง€ ์•Š๋„๋ก ๊ฐ•์ œํ•œ๋‹ค. ASM ์ฝ”๋“œ๋ฅผ ์“ฐ๋Š” ๊ฒฝ์šฐ, ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ตœ์ ํ™”๋ฅผ ํ†ตํ•ด ASM ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด ๊ฒฝ์šฐ ์˜๋„์™€ ๋‹ค๋ฅธ ๋™์ž‘์„ ํ•˜๋„๋ก ์ˆ˜์ •๋  ์šฐ๋ ค๊ฐ€ ์žˆ๋‹ค. ์ด๋Ÿฐ ์ปดํŒŒ์ผ๋Ÿฌ ์ตœ์ ํ™”๋ฅผ ๋น„ํ™œ์„ฑํ™” ํ•ด์ฃผ๋Š”๊ฒŒ volatile ํ‚ค์›Œ๋“œ๋ผ๊ณ  ํ•œ๋‹ค. volatile ํ‚ค์›Œ๋“œ๋Š” ๊ผญ ASM ์ฝ”๋“œ๋ž‘ ๊ฐ™์ด ์จ์•ผ ํ•˜๋Š” ๊ฑด ์•„๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์ธ C ์ฝ”๋“œ์—์„œ๋„ ์“ธ ์ˆ˜ ์žˆ๋‹ค.

strtok_r()

/* Breaks a string into tokens separated by DELIMITERS.  The
   first time this function is called, S should be the string to
   tokenize, and in subsequent calls it must be a null pointer.
   SAVE_PTR is the address of a `char *' variable used to keep
   track of the tokenizer's position.  The return value each time
   is the next token in the string, or a null pointer if no
   tokens remain.

   This function treats multiple adjacent delimiters as a single
   delimiter.  The returned tokens will never be length 0.
   DELIMITERS may change from one call to the next within a
   single string.

   strtok_r() modifies the string S, changing delimiters to null
   bytes.  Thus, S must be a modifiable string.  String literals,
   in particular, are *not* modifiable in C, even though for
   backward compatibility they are not `const'.

   Example usage:

   char s[] = "  String to  tokenize. ";
   char *token, *save_ptr;

   for (token = strtok_r (s, " ", &save_ptr); token != NULL;
        token = strtok_r (NULL, " ", &save_ptr))
     printf ("'%s'\n", token);

   outputs:

     'String'
     'to'
     'tokenize.'
*/
char *
strtok_r (char *s, const char *delimiters, char **save_ptr) 
{
  char *token;
  
  ASSERT (delimiters != NULL);
  ASSERT (save_ptr != NULL);

  /* If S is nonnull, start from it.
     If S is null, start from saved position. */
  if (s == NULL)
    s = *save_ptr;
  ASSERT (s != NULL);

  /* Skip any DELIMITERS at our current position. */
  while (strchr (delimiters, *s) != NULL) 
    {
      /* strchr() will always return nonnull if we're searching
         for a null byte, because every string contains a null
         byte (at the end). */
      if (*s == '\0')
        {
          *save_ptr = s;
          return NULL;
        }

      s++;
    }

  /* Skip any non-DELIMITERS up to the end of the string. */
  token = s;
  while (strchr (delimiters, *s) == NULL)
    s++;
  if (*s != '\0') 
    {
      *s = '\0';
      *save_ptr = s + 1;
    }
  else 
    *save_ptr = s;
  return token;
}

์‹ค์ œ ์ฝ”๋“œ์—์„œ ์‚ดํŽด๋ณด์ž๋ฉด

tid_t
process_execute (const char *file_name) // ์—ฌ๊ธฐ
{
  char *fn_copy;
  /* Make a copy of FILE_NAME.
     Otherwise there's a race between the caller and load(). */
  fn_copy = palloc_get_page (0);
  if (fn_copy == NULL)
    return TID_ERROR;
  strlcpy (fn_copy, file_name, PGSIZE);
  ...
}

palloc

โ€˜Page allocatorโ€™์˜ ์•ฝ์ž๋กœ ํ•ด๋‹น ๊ตฌํ˜„์€ src/threads/palloc.c ํŒŒ์ผ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์•„๋ž˜ ๋‚ด์šฉ์€ ํ•ด๋‹น ํŒŒ์ผ์— ์žˆ๋Š” ์ฃผ์„์˜ ๋‚ด์šฉ์˜ ํ•ด์„.

Page allocator. Hands out memory in page-size (or page-multiple) chunks. See malloc.h for an allocator that hands out smaller chunks.

๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํŽ˜์ด์ง€ ํฌ๊ธฐ(๋ณดํ†ต 4kb) ๋˜๋Š” ๊ทธ๊ฒƒ์˜ ์ •์ˆ˜๋ฐฐ๋กœ ํ• ๋‹นํ•˜๋Š” ๋…€์„์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ, ๊ทธ๊ฒƒ๋ณด๋‹ค ์ ์€ ์ฒญํฌ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•ด์•ผ ํ•œ๋‹ค๋ฉด, malloc()์„ ์“ฐ๋ผ๊ณ  ํ•˜๋„ค์š”.

System memory is divided into two โ€œpoolsโ€ called the kernel and user pools. The user pool is for user (virtual) memory pages, the kernel pool for everything else.

์‹œ์Šคํ…œ์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ปค๋„ ํ’€๊ณผ ์œ ์ € ํ’€๋กœ ๋‚˜๋ˆˆ๋‹ค๊ณ  ํ•œ๋‹ค. ์œ ์ € ํ’€์€ ์œ ์ € ํ”„๋กœ์„ธ์Šค๊ฐ€ ์“ฐ๋Š” ์šฉ๋„์ด๊ณ , ์ปค๋„ ํ’€์€ ์ปค๋„์ด ์“ฐ๊ธฐ ์œ„ํ•œ ๊ณต๊ฐ„์ด๋‹ค.

The idea here is that the kernel needs to have memory for its own operations even if user processes are swapping like mad.

๋ฉ”๋ชจ๋ฆฌ ์Šค์™‘(swap)์€ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋ถ€์กฑํ•œ ์ƒํ™ฉ์—์„œ ๋ฐœ์ƒํ•œ๋‹ค. ๋งŒ์•ฝ ์œ ์ € ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ์œผ๋กœ ๋ฏธ์นœ๋“ฏ์ด(like mad) ์Šค์™‘๋˜๋Š” ์ƒํ™ฉ์ด๋”๋ผ๋„, ์ปค๋„์ด ํ•„์š”๋กœ ํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ๋Š” ์ปค๋„ ํ’€์—์„œ ํ•ญ์ƒ ํ™•๋ณด๋˜๋„๋ก ํ•œ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.

By default, half of system RAM is given to the kernel pool and half to the user pool. That should be huge overkill for the kernel pool, but thatโ€™s just fine for demonstration purposes.

์‹œ์Šคํ…œ ๋ฉ”๋ชจ๋ฆฌ์˜ ์ ˆ๋ฐ˜์€ ์ปค๋„ ํ’€, ๋‚˜๋จธ์ง€ ์ ˆ๋ฐ˜์€ ์œ ์ € ํ’€๋กœ ๋‚˜๋ˆˆ๋‹ค๋Š” ๋ง. ๋ฐ๋ชจ ์šฉ๋„๋กœ๋Š” ์ด ์ •๋„๋กœ ์„ค์ •ํ•ด๋„ ์ถฉ๋ถ„ํ•˜๋‹ค๊ณ  ํ•œ๋‹ค ใ…Žใ…Ž

TODO: ์ด๊ฒŒ ๋ญ”์ง€

palloc_get_page()

palloc_free_page()

palloc_get_page()๋กœ ํ• ๋‹น ๋ฐ›์€ ํŽ˜์ด์ง€๋ฅผ ํ•ด์ œํ•ด์ฃผ๋Š” ๋ช…๋ น์–ด.

๊ผญ, ํ•ด์ œ ํ•ด์ค˜ํ•จ!!

TDBโ€ฆ