lazy_load_segment() - sihyun10/pintos-lab-vm GitHub Wiki

lazy_load_segment() ํ•จ์ˆ˜ ๊ตฌํ˜„

static bool lazy_load_segment(struct page *page, void *aux);

์ด ํ•จ์ˆ˜๋Š” ํŽ˜์ด์ง€๊ฐ€ ์ฒ˜์Œ ์ ‘๊ทผ๋  ๋•Œ (page fault ๋ฐœ์ƒ ์‹œ) ํ˜ธ์ถœ๋œ๋‹ค.
vm_alloc_page_with_initializer()์— ๋“ฑ๋กํ•ด๋‘์—ˆ๋˜ ์ดˆ๊ธฐํ™” ํ•จ์ˆ˜์ด๋‹ค.
์ฆ‰, ์‹ค์ œ๋กœ ํŒŒ์ผ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด (๋ฌผ๋ฆฌ) ๋ฉ”๋ชจ๋ฆฌ๋กœ ๋กœ๋”ฉํ•˜๋Š” ๋™์ž‘์€ ์—ฌ๊ธฐ์„œ ๋ฐœ์ƒํ•œ๋‹ค.
aux๋Š” load_segment()์—์„œ ๋„˜๊ฒจ์ค€ load_info ๊ตฌ์กฐ์ฒด ํฌ์ธํ„ฐ์ด๋‹ค.

โ–ถ๏ธŽ ๋™์ž‘ ๊ณผ์ •

  1. aux์— ๋‹ด๊ธด ์ •๋ณด๋ฅผ ๊บผ๋‚ธ๋‹ค. (file, ofs, read_bytes, zero_bytes)
  2. file_read_at()์œผ๋กœ ํ•ด๋‹น ํŒŒ์ผ์—์„œ ํ•„์š”ํ•œ ๋งŒํผ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๋Š”๋‹ค.
  3. ๋‚˜๋จธ์ง€ ๊ณต๊ฐ„์€ memset()์„ ์‚ฌ์šฉํ•ด 0์œผ๋กœ ์ฑ„์šด๋‹ค.
  4. ์„ฑ๊ณต ์—ฌ๋ถ€๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

1. aux๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ๋ฐ›์€ ์ •๋ณด๋ฅผ ๊บผ๋‚ธ๋‹ค.

struct load_info *info = (struct load_info *)aux;

load_segment()์— ๋„˜๊ธด ์ •๋ณด๋ฅผ ๋ฐ›์•„์˜จ๋‹ค.
(file, offset, ์ฝ์„ ๋ฐ”์ดํŠธ, 0์œผ๋กœ ์ฑ„์šธ ๋ฐ”์ดํŠธ)

struct file *file = info->file;
off_t ofs = info->ofs;
size_t page_read_bytes = info->read_bytes;
size_t page_zero_bytes = info->zero_bytes;

๋‹ค์Œ์œผ๋กœ ํ•„์š”ํ•œ ๊ฐ’์„ ๊บผ๋‚ธ๋‹ค.

uint8_t *kva = page->frame->kva;

์ด ํŽ˜์ด์ง€์— ๋งคํ•‘๋œ ๋ฌผ๋ฆฌ ํ”„๋ ˆ์ž„์˜ ์ปค๋„ ๊ฐ€์ƒ ์ฃผ์†Œ๋ฅผ ์–ป๋Š”๋‹ค.
๋ฐ์ดํ„ฐ๋ฅผ ์‹ค์ œ๋กœ ์ด ์ฃผ์†Œ์— ์ฑ„์›Œ ๋„ฃ์„ ๊ฒƒ์ด๋‹ค.

2. ํ•ด๋‹น ํŒŒ์ผ์—์„œ ํ•„์š”ํ•œ ๋งŒํผ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๋Š”๋‹ค.

if (file_read_at(file, kva, page_read_bytes, ofs) != (int)page_read_bytes) {
  free(info);
  return false;
}

file์—์„œ ofs ์œ„์น˜๋ถ€ํ„ฐ page_read_bytes๋งŒํผ ์ฝ์–ด kva๋กœ ๋ณต์‚ฌํ•œ๋‹ค.
ํŒŒ์ผ ์ฝ๊ธฐ์— ์‹คํŒจํ•˜๋ฉด ํ• ๋‹นํ–ˆ๋˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•˜๊ณ  false ๋ฐ˜ํ™˜ํ•œ๋‹ค.

3. ๋‚˜๋จธ์ง€ ๊ณต๊ฐ„์€ memset()์„ ์‚ฌ์šฉํ•ด 0์œผ๋กœ ์ดˆ๊ธฐํ™”

memset(kva + page_read_bytes, 0, page_zero_bytes);  

4. ์„ฑ๊ณต ๋ฐ˜ํ™˜ํ•œ๋‹ค.

return true;

์ด์ œ ๋ชจ๋“  ์ž‘์—…์ด ์ž˜ ์ˆ˜ํ–‰๋˜์—ˆ๊ธฐ์— true๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.


๊ตฌํ˜„ํ•œ ์ฝ”๋“œ

static bool
lazy_load_segment(struct page *page, void *aux)
{
  /* TODO: Load the segment from the file */
  /* TODO: This called when the first page fault occurs on address VA. */
  /* TODO: VA is available when calling this function. */

  struct load_info *info = (struct load_info *)aux;

  struct file *file = info->file;
  off_t ofs = info->ofs;
  size_t page_read_bytes = info->read_bytes;
  size_t page_zero_bytes = info->zero_bytes;

  // ์‹ค์ œ ํ”„๋ ˆ์ž„์˜ ์ปค๋„ ๊ฐ€์ƒ ์ฃผ์†Œ ์–ป๊ธฐ
  uint8_t *kva = page->frame->kva;

  // ํŒŒ์ผ์—์„œ ํ•„์š”ํ•œ ๋งŒํผ ์ฝ๊ธฐ
  if (file_read_at(file, kva, page_read_bytes, ofs) != (int)page_read_bytes)
  {
    free(info);
    return false;
  }

  // ๋‚จ์€ ์˜์—ญ์€ 0์œผ๋กœ ์ฑ„์šฐ๊ธฐ
  memset(kva + page_read_bytes, 0, page_zero_bytes);

  return true;
}
  • load_info ๊ตฌ์กฐ์ฒด์—์„œ ํŒŒ์ผ, ์˜คํ”„์…‹, ์ฝ๊ธฐ/์ œ๋กœ ๋ฐ”์ดํŠธ ์ •๋ณด๋ฅผ ์ถ”์ถœ
  • ํ”„๋ ˆ์ž„์˜ ์ปค๋„ ๊ฐ€์ƒ ์ฃผ์†Œ(kva)๋ฅผ ํ™•๋ณด
  • file_read_at()์œผ๋กœ ํŒŒ์ผ ๋ฐ์ดํ„ฐ๋กœ๋”ฉ, ์‹คํŒจ ์‹œ ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ ํ›„ false ๋ฐ˜ํ™˜
  • ๋‚จ์€ ๊ณต๊ฐ„์€ memset()์œผ๋กœ 0์œผ๋กœ ์ดˆ๊ธฐํ™”
  • true ๋ฐ˜ํ™˜