๐ฉ๐ปโ๐ป GITHUB ๋ ํฌ์งํ ๋ฆฌ
๐ฉ๐ปโ๐ป GITHUB Stack Growth ์ด์
ํ์ํ ๋๋ง๋ค 1 ํ์ด์ง์ฉ ์๋ผ๋๋ ์คํ์ ๋ง๋ค์ด์ค ๊ฒ์ด๋ค. ์ฆ,
๐ก Page Fault์ ์ํด ๋์ ์ผ๋ก ์๋ผ๋๋ ์คํ์ ๊ตฌํํด์ผํ๋ค.
ํ์ด์ง ํดํธ๊ฐ ๋ฐ์ํ์์ ๋, ์ด ํ์ด์ง ํดํธ๊ฐ stack growth์ ๋ํ ํ์ด์ง ํดํธ์ผ ๋ ์คํ์ ํค์ด๋ค.
์ฐ์ ์คํ์์ญ์ ํ์ฅ ์ํค๊ธฐ ์ํด์๋ ํ์ฌ ์คํ ํฌ์ธํฐ ์์น๋ฅผ ์์์ผ ํ๋ค.
๋ฐ๋ผ์ ์ค๋ ๋ ๊ตฌ์กฐ์ฒด ์์ ์คํ ํฌ์ธํฐ์ ์คํ ๋ฐํ
์ ์ ์ฅํด ๋๋ค.
์คํ์ ๋๋ฆฌ๋ ๊ฒ์ ํ์ด์ง ํดํธ๊ฐ ๋ฐ์ํ์ ๋ ์ด๋ฏ๋ก ํ์ด์ง ํดํธ ํธ๋ค๋ฌ์ ์คํ ํ์ฅ์ ์ถ๊ฐํด ์ฃผ๋ฉด ๋๋ค.
1๏ธโฃ ์ ํจํ ์ฃผ์๊ฐ ์๋ ๊ฒฝ์ฐ
2๏ธโฃ ์ค์ ํ ๋นํ๋ ค๋ ํ์ด์ง๊ฐ ์๋ ๊ฒฝ์ฐ
3๏ธโฃ ์คํ ๊ณต๊ฐ์ด ๋ถ์กฑํ ๊ฒฝ์ฐ โ ํ์ฌ ๊ตฌํํ๋ ค๋ ์ํฉ โ
/** Project 3-Stack Growth*/
#define STACK_LIMIT (USER_STACK - (1 << 20))
userprog/exception.c
์์ page_fault()
๋ก ํธ์ถ๋๋ค.vm_stack_growth
๋ฅผ ํธ์ถํ๋ค.!vm_claim_page(addr)
โ ๊ฐ์ ์ฃผ์ addr์ ๋ํด์ ํ์ด์ง๋ฅผ ํ ๋นํ ์ ์๋ ๊ฒฝ์ฐbool
vm_try_handle_fault (struct intr_frame *f UNUSED, void *addr UNUSED,
bool user UNUSED, bool write UNUSED, bool not_present UNUSED) {
struct supplemental_page_table *spt UNUSED = &thread_current ()->spt;
/** Project 3-Anonymous Page */
struct page *page = NULL;
if (addr == NULL || is_kernel_vaddr(addr))
return false;
if (not_present)
{
/** Project 3-Stack Growth*/
void *rsp = user ? f->rsp : thread_current()->stack_pointer;
if (STACK_LIMIT <= rsp - 8 && rsp - 8 == addr && addr <= USER_STACK){
vm_stack_growth(addr);
return true;
}
else if (STACK_LIMIT <= rsp && rsp <= addr && addr <= USER_STACK){
vm_stack_growth(addr);
return true;
}
page = spt_find_page(spt, addr);
if (!page || (write && !page->writable))
return false;
return vm_do_claim_page(page);
}
return false;
}
static void
vm_stack_growth (void *addr UNUSED) {
/** Project 3-Stack Growth*/
bool success = false;
addr = pg_round_down(addr);
if (vm_alloc_page(VM_ANON | VM_MARKER_0, addr, true)) {
success = vm_claim_page(addr);
if (success) {
thread_current()->stack_bottom -= PGSIZE;
}
}
}
/** #project3-Stack Growth */
#ifdef VM
if (vm_try_handle_fault(f, fault_addr, user, write, not_present))
{
return;
}
else
{
page_fault_cnt++;
exit(-1);
}
#endif
/** #project3-Stack Growth */
#ifdef VM
struct page *page = spt_find_page(&thread_current()->spt, buffer);
if (page && !page->writable)
exit(-1);
#endif
์ถ๊ฐํด์ค๋ค.
/** Project 2-Extend File Descriptor */
int
read(int fd, void *buffer, unsigned length)
{
struct thread *curr = thread_current();
check_address(buffer);
/** #project3-Stack Growth */
#ifdef VM
struct page *page = spt_find_page(&thread_current()->spt, buffer);
if (page && !page->writable)
exit(-1);
#endif
struct file *file = process_get_file(fd);
if (file == STDIN) {
int i = 0;
char c;
unsigned char *buf = buffer;
for (; i < length; i++) {
c = input_getc();
*buf++ = c;
if (c == '\0')
break;
}
return i;
}
if (file == NULL || file == STDOUT || file == STDERR) // ๋น ํ์ผ, stdout, stderr๋ฅผ ์ฝ์ผ๋ ค๊ณ ํ ๊ฒฝ์ฐ
return -1;
off_t bytes = -1;
lock_acquire(&filesys_lock);
bytes = file_read(file, buffer, length);
lock_release(&filesys_lock);
return bytes;
}
#ifdef VM
thread_current()->stack_pointer = f->rsp;
#endif