์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- c#
- ์ ๋ํฐ
- ํํ ์ค
- 4๊ธฐ
- ๋ค์ต์คํธ๋ผ
- ํฌ๋ํํค ์ ๊ธ 4๊ธฐ
- BFS
- TiL
- KRAFTON JUNGLE
- User Stack
- pintos
- ํ์ด์ฌ
- project3
- ํฐ์คํ ๋ฆฌ์ฑ๋ฆฐ์ง
- ์ด๋ฒคํธ ํจ์ ์คํ ์์
- kraftonjungle
- ํฌ๋ํํค์ ๊ธ4๊ธฐ
- ํฌ๋ํํค์ ๊ธ
- ํฌ๋ํํค ์ ๊ธ
- C
- ์ ์-์ ํฌ
- ์ฐ๊ฒฐ๋ฆฌ์คํธ
- Unity
- ์ถ์ํด๋์ค์์ธํฐํ์ด์ค
- ์๊ณ ๋ฆฌ์ฆ
- ๋คํธ์ํฌ
- ์ค๋ธ์
- anonymous page
- ๋ฐฑ์ค
- ์๊ณ ๋ฆฌ์ฆ์์ -๋๋น์ฐ์ ํ์2
- Today
- Total
๋ง๊ฐ๋ก๊ทธ
ํฌ๋ํํค ์ ๊ธ WEEK11 DAY 86 - PintOS Project3 - Stack Growth ์์ฑ ๋ณธ๋ฌธ
ํฌ๋ํํค ์ ๊ธ WEEK11 DAY 86 - PintOS Project3 - Stack Growth ์์ฑ
habbn 2024. 4. 1. 22:46๐2024.4.1
1. Stack Growth ์์ฑ
2. ๋ฐฑ์ค - ์จ๋ฐ๊ผญ์ง
Stack Growth ์กฐ๊ฑด
1. addr์ด rsp๋ณด๋ค ๋์ ์ฃผ์๋ฅผ ๊ฐ๋ฆฌ์ผ์ผ ํ๋ค.
2. rsp - 8์ ์ ๊ทผํ ๊ฒฝ์ฐ์๋ stack growth๋ก ํด๊ฒฐํ๋ค.
3. USER_STACK ์๋์ ์์ด์ผ ํ๊ณ , USER_STACK - (1MB) ์์ ์์ด์ผ ํ๋ค. -> USER_STACK ์์ญ ๋ด์ ์์ด์ผ ํ๋ค.
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;
struct page *page = NULL;
if (addr == NULL)
return false;
if (is_kernel_vaddr(addr))
return false;
// true: addr์ ๋งคํ๋ physical page๊ฐ ์กด์ฌํ์ง ์๋ ๊ฒฝ์ฐ์ ํด๋นํ๋ค.
// false: read only page์ writing ์์
์ ํ๋ ค๋ ์๋์ ํด๋นํ๋ค.
if (not_present) // ์ ๊ทผํ ๋ฉ๋ชจ๋ฆฌ์ physical page๊ฐ ์กด์ฌํ์ง ์์ ๊ฒฝ์ฐ
{
/* TODO: Validate the fault */
// ํ์ด์ง ํดํธ๊ฐ ์คํ ํ์ฅ์ ๋ํ ์ ํจํ ๊ฒฝ์ฐ์ธ์ง๋ฅผ ํ์ธํ๋ค.
void *rsp = f->rsp; // user access์ธ ๊ฒฝ์ฐ rsp๋ ์ ์ stack์ ๊ฐ๋ฆฌํจ๋ค.
if (!user) // kernel access์ธ ๊ฒฝ์ฐ thread์์ rsp๋ฅผ ๊ฐ์ ธ์์ผ ํ๋ค.
rsp = thread_current()->stack_rsp;
// ์คํ ํ์ฅ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ ํดํธ์ธ ๊ฒฝ์ฐ, vm_stack_growth๋ฅผ ํธ์ถํ๋ค.
if (USER_STACK - (1 << 20) <= rsp - 8 && rsp - 8 <= addr && addr <= USER_STACK)
vm_stack_growth(addr);
page = spt_find_page(spt, addr);
if (page == NULL)
return false;
if (write == 1 && page->writable == 0) // write ๋ถ๊ฐ๋ฅํ ํ์ด์ง์ write ์์ฒญํ ๊ฒฝ์ฐ
return false;
return vm_do_claim_page(page);
}
return false;
}
stack_bottom์ ์ด์ฉํด์ ๊ตฌํํ๋ ค ํ์ง๋ง ์ด๋ ค์์ ๊ฒช๊ณ ํ ์คํธ๊ฐ ์ ์๋๋๊ฑฐ์ผ!!..
static void
vm_stack_growth (void *addr UNUSED) {
vm_alloc_page(VM_ANON|VM_MARKER_0, pg_round_down(addr), true);
}
1. tests/vm/pt-write-code / tests/vm/pt-write-code2
์ด ํ ์คํธ๋ฅผ ํต๊ณผํ๋ ค๋ฉด ์์คํ ์ฝ read ํจ์๋ฅผ ์์ ํด์ผ ํ๋ค.
๊ณ์ํด์ ์ ํ ์คํธ ๋ถ๋ถ์์ fail์ด ๋ ์ ๊ณฐ๊ณฐํ ์๊ฐํด๋ณด๋ค ์์คํ ์ฝ ์ชฝ ๋ฌธ์ ์ผ ๊ฒ ๊ฐ๋ค๋ ์๊ฐ์ด ๋ค์๊ณ ๋์ ์๊ฐ์ด ๋ง์๋ค๋ ์ ์ด ๊ธฐ๋ปค๋ค!
์ผ๋จ ํ์ฌ ์ธ์๋ก ์ฃผ์ด์ง ๋ฒํผ๊ฐ spt์ ์๋์ง ํ์ธ ํ page๋ฅผ ๋ฐ์์ ํด๋น page์ ์ฐ๊ธฐ ๊ฐ๋ฅ ์ฌ๋ถ๋ฅผ ํ์ธํ๊ณ ์๋๋ผ๋ฉด exit(-1)์ ํ์ด์ผ ํ๋ค.
๊ทธ๋ฌ๋ ๋์ ์ต๊ด์ ์ธ ์ค์๋ก page๊ฐ ์๋๋ฐ ์ด ํด๋น page๊ฐ ์ฐ๊ธฐ๊ฐ ๋ถ๊ฐ๋ฅํด! ๊ทธ๋ฌ๋ฉด ๋๊ฐ! ๋ผ๊ณ ํ์ด์ผ ํ๋ค๊ฑธ !page &&!page->writable ๋ก ๊ฑธ์ด๋ฌ์ ์๊พธ fail์ด ๋ด์๋.. ๋ฌธ์ ๊ฐ ์์๋ค
๋๋ฃ ๋ถ์ด๋ ์๊ธฐํ๋ค ๋ญ๊ฐ ์๋ชป๋ ์ ์ ๊นจ๋ซ๊ณ ๋ฐ๋ก ์์ ํด์ฃผ์๋ค.
๐ค์๋ฌธ์ด์๋ ์
์ฒ์์ ์ read()์์ ํ์ฌ ํ์ด์ง๊ฐ ์ฐ๊ธฐ ๊ฐ๋ฅํ์ง ์ฌ๋ถ๋ฅผ ์ฒดํฌํ์ง? write๊ฐ ์๋๋ผ ์ read์์? ๋ผ๋ ์๊ฐ์ด ๋ค์์๋ค.
read๋ ํ์ผ์์ buffer๋ก๋ถํฐ ์ฝ๋๊ฒ(์จ์ฃผ๋ ๊ฒ) ์ด๊ณ , read , write ๋ชจ๋ ์ฐ๊ธฐํ ํ์ด์ง์ฌ์ผ ํ๋ค๊ณ ํ๋ค.
๊ทธ๋์ ์ฐ๊ธฐ ๊ฐ๋ฅํด์ผ buffer์ ์ธ ์ ์์ผ๋๊น read์์ ์ฒดํฌ๋ฅผ ํ๋ ๊ฒ!
๋ ๋ค ํด์ค๋ ์๊ด ์๋ค๊ณ ํ๋ค.
int read(int fd, void *buffer, unsigned size) {
check_address(buffer);
int byte = 0;
char *_buffer;
if (fd == STDIN_FILENO) {
_buffer = buffer;
while (byte < size) {
_buffer[byte++] = input_getc();
}
}
else{
struct file *_file = get_file_from_fd(fd);
if (_file == NULL) {
return -1;
}
struct page * _page = spt_find_page(&thread_current()->spt, buffer);
if(_page && !_page->writable){
exit(-1);
}
lock_acquire(&filesys_lock);
byte = file_read(_file, buffer, size);
lock_release(&filesys_lock);
}
return byte;
}
2. tests/vm/pt-grow-stk-sc
์ด ํ ์คํธ๋ ๋์ ๋ณ์๊ฐ ์๋ ์ ์ ๋ณ์๋ฅผ ๋ง๋ค์ด์ ๋ ๊ฐ์ ๋ฐ์ดํฐ๊ฐ ๊ฐ์์ง ์ผ๊ด์ฑ์ ํ์ธํ๋ ํ ์คํธ์๋ค.
๋ค๋ฅธ ํ ์คํธ๋ ๋ค ํต๊ณผํ๋๋ฐ ์ด ํ ์คํธ๋ง ํต๊ณผ๊ฐ ์๋ผ์ printf ๋ฌธ์ ํ๋์ฉ ์ฐ์ผ๋ฉด์ ํ์ธํด๋ณด๋ check_address()์์ ๊ฑธ๋ฆฐ๋ค๋ ์ ์ ํ์ธํ๋ค!
์ ์ ๋ณ์๋ ๋์ ๋ณ์๊ฐ ์๋๊ธฐ ๋๋ฌธ์ page๊ฐ ์์ผ๋๊น ๋น์ฐํ spt_find_page() ์์ธ์ฒ๋ฆฌ๋ฌธ์์ ๊ฑธ๋ ค ์ข ๋ฃ๋์๋ ๋ฌธ์ ์๋ค.
๊ทธ๋์ ์ด ์์ธ์ฒ๋ฆฌ๋ฅผ ์ฃผ์ ์ฒ๋ฆฌํด์ฃผ๋ ์ฑ๊ณต!!
// if(spt_find_page(&thread_current()->spt, (void *)addr) == NULL) {
// exit(-1);
// }
stack growth ์ ์ฒด ํต๊ณผ๋ก ์ด์ 33 failed!
stack growth ์๊ฐ๋ณด๋ค ๊ฐ๋จํ๊ณ ์ฝ๋๋ ๋ง์ด ์ถ๊ฐ ์ํ๋๋ฐ ์์ด๋ฆฌ ์๊ฐ์ ์ค๋ ๋ณด๋๋์ง...ใ ใ ๊ทธ๋๋ ์ดํดํ๊ณ ๋์ด๊ฐ์ผ๋ ๋คํ์ด๋ผ๊ณ ์๊ฐํ๋ค.
๋ฐฑ์ค ์จ๋ฐ๊ผญ์ง
x - 1, x + 1, x*2 ์ธ ๊ฐ์ง์ ์กฐ๊ฑด์ ํ์ธํ๋ ๊ฒ ์ด๋ ค์ ๋ค.
import sys
from collections import deque
input = sys.stdin.readline
def bfs(n):
q = deque()
q.append(n)
while q:
x = q.popleft()
if x == K:
print(dist[x])
break
for nx in (x-1, x+1, x*2):
if 0 <= nx <= MAX and not dist[nx]:
dist[nx] = dist[x] + 1
q.append(nx)
N, K = map(int,input().split())
MAX = 10**5
dist = [0] * (MAX+1)
bfs(N)