static bool
load_segment (struct file *file, off_t ofs, uint8_t *upage,
uint32_t read_bytes, uint32_t zero_bytes, bool writable) {
ASSERT ((read_bytes + zero_bytes) % PGSIZE == 0);
ASSERT (pg_ofs (upage) == 0);
ASSERT (ofs % PGSIZE == 0);
off_t read_ofs = ofs;
while (read_bytes > 0 || zero_bytes > 0) {
/* Do calculate how to fill this page.
* We will read PAGE_READ_BYTES bytes from FILE
* and zero the final PAGE_ZERO_BYTES bytes. */
size_t page_read_bytes = read_bytes < PGSIZE ? read_bytes : PGSIZE;
size_t page_zero_bytes = PGSIZE - page_read_bytes;
/* Set up aux to pass information to the lazy_load_segment. */
struct vmpage_info *aux = malloc(sizeof (struct vmpage_info));
aux->file = file;
aux->ofs = read_ofs;
aux -> page_read_bytes = page_read_bytes;
aux -> page_zero_bytes = page_zero_bytes;
if (!vm_alloc_page_with_initializer (VM_ANON, upage,
writable, lazy_load_segment, aux)){
free(aux);
return false;
}
/* Advance. */
read_bytes -= page_read_bytes;
zero_bytes -= page_zero_bytes;
upage += PGSIZE;
read_ofs += PGSIZE;
}
return true;
}
: load_segment() -> vm_alloc_page_with_initializer() -> lazy_load_segment() 순서로 실행
bool lazy_load_segment (struct page *page, void *aux) {
struct vmpage_info* info = (struct vmpage_info*) aux;
if (page == NULL) return false;
/* load proper info to page */
if (info -> page_read_bytes > 0) {
file_seek (info -> file, info -> ofs);
if (file_read (info -> file, page -> frame ->kva, info -> page_read_bytes) != (off_t) info -> page_read_bytes) {
vm_dealloc_page (page);
return false;
}
}
memset (page -> va + info -> page_read_bytes, 0, info -> page_zero_bytes);
file_close (info -> file);
free (info);
return true;
}