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
๊ตฌ์กฐ์ฒด ํฌ์ธํฐ์ด๋ค.
โถ๏ธ ๋์ ๊ณผ์
aux
์ ๋ด๊ธด ์ ๋ณด๋ฅผ ๊บผ๋ธ๋ค. (file
,ofs
,read_bytes
,zero_bytes
)file_read_at()
์ผ๋ก ํด๋น ํ์ผ์์ ํ์ํ ๋งํผ ๋ฐ์ดํฐ๋ฅผ ์ฝ๋๋ค.- ๋๋จธ์ง ๊ณต๊ฐ์
memset()
์ ์ฌ์ฉํด 0์ผ๋ก ์ฑ์ด๋ค. - ์ฑ๊ณต ์ฌ๋ถ๋ฅผ ๋ฐํํ๋ค.
aux
๋ฅผ ํตํด ์ ๋ฌ๋ฐ์ ์ ๋ณด๋ฅผ ๊บผ๋ธ๋ค.
1. 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
๋ฐํํ๋ค.
memset()
์ ์ฌ์ฉํด 0์ผ๋ก ์ด๊ธฐํ
3. ๋๋จธ์ง ๊ณต๊ฐ์ 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
๋ฐํ