์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
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 |
- pintos
- ์ถ์ํด๋์ค์์ธํฐํ์ด์ค
- ํ์ด์ฌ
- User Stack
- BFS
- 4๊ธฐ
- kraftonjungle
- TiL
- ๋คํธ์ํฌ
- ์ค๋ธ์
- ํฌ๋ํํค ์ ๊ธ
- Unity
- ์๊ณ ๋ฆฌ์ฆ
- ํฌ๋ํํค ์ ๊ธ 4๊ธฐ
- ์ ์-์ ํฌ
- KRAFTON JUNGLE
- project3
- ์ ๋ํฐ
- ํํ ์ค
- ๋ค์ต์คํธ๋ผ
- ํฌ๋ํํค์ ๊ธ4๊ธฐ
- ํฌ๋ํํค์ ๊ธ
- anonymous page
- c#
- ํฐ์คํ ๋ฆฌ์ฑ๋ฆฐ์ง
- ์ฐ๊ฒฐ๋ฆฌ์คํธ
- ๋ฐฑ์ค
- C
- ์๊ณ ๋ฆฌ์ฆ์์ -๋๋น์ฐ์ ํ์2
- ์ด๋ฒคํธ ํจ์ ์คํ ์์
- Today
- Total
๋ง๊ฐ๋ก๊ทธ
ํฌ๋ํํค ์ ๊ธ WEEK08 DAY68 - PintOS Project2 argument passing ๋ณธ๋ฌธ
ํฌ๋ํํค ์ ๊ธ WEEK08 DAY68 - PintOS Project2 argument passing
habbn 2024. 3. 15. 22:31๐2024.3.15
1. argument passing ๊ตฌํ
2. ๋ฐฑ์ค
argument passing ์ธ์ ์ ๋ฌ
userํ๋ก๊ทธ๋จ์ด ์คํ๋๊ธฐ ์ ์ ํ๋ก๊ทธ๋จ์ ๋ํ ์ธ์๋ฅผ ์ค์ ํด์ผ ํ๋ค.
1. process_create_initd()
๐๐ป command line์ parsing ํด์ file_name์ ์ฐพ๋๋ค.
- ์ธ์๋ก ๋ค์ด์ค๋ file_name์ด ์คํ ์ ์ ๋ ฅ๋ command line์ด๋ค.
- ์ด command line์ parsingํด์ ํ์ผ ์ด๋ฆ์ ์ฐพ๋๋ค.
- parsingํด์ ์ป์ด๋ธ ํ์ผ ์ด๋ฆ์ด thread_create ํจ์์ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ๋ค์ด๊ฐ์ผ ํ๋ค.
tid_t
process_create_initd (const char *file_name) {
char *fn_copy;
tid_t tid;
/* Make a copy of FILE_NAME.
* Otherwise there's a race between the caller and load(). */
fn_copy = palloc_get_page (0); //file_name์ ๋ณต์ฌ๋ณธ
if (fn_copy == NULL)
return TID_ERROR;
strlcpy (fn_copy, file_name, PGSIZE);
//Argument Pasing
//command_line์ parsingํด์ file_name ์ฐพ๋๋ค.
char *save_ptr;
strtok_r (file_name, " ", &save_ptr);
//~Argument Pasing
/* Create a new thread to execute FILE_NAME. */
tid = thread_create (file_name, PRI_DEFAULT, initd, fn_copy);
if (tid == TID_ERROR)
palloc_free_page (fn_copy);
return tid;
}
2. process_exec()
๐๐ป ์ธ์๋ก ๋ค์ด์ค๋ f_name์ parsing ํ๊ณ user_stack์ ๋งค๊ฐ๋ณ์๋ค์ push ํ๋ค.
- parsing ํ ์ธ์๋ค์ ๋ด์ parse ๋ฐฐ์ด์ ๊ธธ์ด๋ 64๋ก ์ง์ ํ๋ค.
- strtok_r ํจ์๋ฅผ ํ์ฉํด parsing ํ ๊ฒฐ๊ณผ๋ฅผ count์ parse์ ๋ด์๋๊ณ , ์๋์์ ์๋ก ์ ์ธํ argument_stack ํจ์๋ฅผ ํธ์ถํ ๋ ์ ๋ฌํ๋ค.
- hex_dump() ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ๋ค. (๋ฉ๋ชจ๋ฆฌ์ ๋ด์ฉ์ 16์ง์ ํ์์ผ๋ก ์ถ๋ ฅํด ์ค์ ์คํ์ ์ ์ฅ๋ ๊ฐ๋ค์ ํ์ธํ ์ ์๋ค.)
int
process_exec (void *f_name) {
char *file_name = f_name;
bool success;
/* We cannot use the intr_frame in the thread structure.
* This is because when current thread rescheduled,
* it stores the execution information to the member. */
struct intr_frame _if;
_if.ds = _if.es = _if.ss = SEL_UDSEG;
_if.cs = SEL_UCSEG;
_if.eflags = FLAG_IF | FLAG_MBS;
/* We first kill the current context */
process_cleanup ();
// Argument Passing ~
int argc = 0;
char *argv[64]; //parssingํ ์ธ์๋ฅผ ๋ด์ ๋ฐฐ์ด
char *token, *save_ptr;
for (token = strtok_r(file_name, " ", &save_ptr); token != NULL; token = strtok_r(NULL, " ", &save_ptr))
{
argv[argc++] = token;
}
// ~ Argument Passing
/* And then load the binary */
success = load (file_name, &_if);
// Argument Passing ~
argument_stack(argv, argc, &_if); // ํจ์ ๋ด๋ถ์์ argv์ rsp์ ๊ฐ์ ์ง์ ๋ณ๊ฒฝํ๊ธฐ ์ํด ์ฃผ์ ์ ๋ฌ
hex_dump(_if.rsp, _if.rsp, USER_STACK - (uint64_t)_if.rsp, true); // user stack์ 16์ง์๋ก ํ๋ฆฐํธ
// ~ Argument Passing
/* If load failed, quit. */
palloc_free_page (file_name);
if (!success)
return -1;
/* Start switched process. */
do_iret (&_if);
NOT_REACHED ();
}
3. argument_stack()
๐๐ป process_exec() ํจ์์์ parsing ํ ํ๋ก๊ทธ๋จ ๋ฆ๊ณผ ์ธ์๋ฅผ ์คํ์ ์ ์ฅํ๊ธฐ ์ํด ์ฌ์ฉํ ํจ์๋ฅผ ์๋ก ์ ์ธํ๋ค.
1. ํ๋ก๊ทธ๋จ ์ด๋ฆ, ์ธ์ ๋ฌธ์์ด push
์คํ์ ์๋ ๋ฐฉํฅ์ผ๋ก ์ปค์ง๋ฏ๋ก ์คํ์ ์ธ์๋ฅผ ์ถ๊ฐํ ๋ ์ค๋ฅธ์ชฝ-> ์ผ์ชฝ ๋ฐฉํฅ์ผ๋ก push
2. word-align(8์ ๋ฐฐ์)๋ก ๋ง์ถฐ์ฃผ๊ธฐ
๊ฐ ๋ฌธ์์ด์ push ํ๊ณ ๋์ 8byte ๋จ์๋ก ์ ๋ ฌํ๊ธฐ ์ํด padding์ ์ถ๊ฐํ๋ค.
3. ์ธ์ ๋ฌธ์์ด ์ข ๋ฃ๋ฅผ ๋ํ๋ด๋ 0 push
์ ๋ ฌํ๊ณ ๋์ 0์ push ํ๋ค. (์ธ์ ๋ฌธ์์ด๋ค์ ์ข ๋ฃ๋ฅผ ์๋ฏธํ๋ค)
4. ๊ฐ ์ธ์ ๋ฌธ์์ด์ ์ฃผ์ push
์ธ์ ๋ฌธ์์ด push ํ๋ฉด์ argv์ ๋ด์๋ ๊ฐ ๋ฌธ์์ด์ ์ฃผ์๋ฅผ push ํ๋ค.
5. fake return address
๋ค์ ์ธ์คํธ๋ญ์ ์ ์ฃผ์๋ฅผ push ํด์ผ ํ๋๋ฐ, ์ง๊ธ์ ํ๋ก์ธ์ค๋ฅผ ์์ฑํ๋ ๊ฑฐ๋ผ์ ๋ฐํ ์ฃผ์๊ฐ ์๋ค. ๊ทธ๋์ fake return address๋ก 0์ ์ถ๊ฐํ๋ค.
void argument_stack(char **argv, int argc, struct intr_frame *if_)
{
char *arg_address[128];
// ํ๋ก๊ทธ๋จ ์ด๋ฆ, ์ธ์ ๋ฌธ์์ด push
for(int i = argc - 1; i >= 0; i--)
{
int arg_i_len = strlen(argv[i]) +1; //sential(\0) ํฌํจ
if_->rsp -= arg_i_len; //์ธ์ ํฌ๊ธฐ๋งํผ ์คํ์ ๋๋ ค์ค
memcpy(if_->rsp, argv[i], arg_i_len); //๋๋ ค์ค ๊ณต๊ฐ์ ํด๋น ์ธ์๋ฅผ ๋ณต์ฌ
arg_address[i] = (char *)if_->rsp; //arg_address์ ์ ์ธ์๋ฅผ ๋ณต์ฌํด์ค ์ฃผ์๊ฐ์ ์ ์ฅ
}
// word-align(8์ ๋ฐฐ์)๋ก ๋ง์ถฐ์ฃผ๊ธฐ
if(if_->rsp % 8 != 0)
{
int padding = if_->rsp % 8;
if_->rsp -= padding;
memset(if_->rsp, 0, padding);
}
// ์ธ์ ๋ฌธ์์ด ์ข
๋ฃ๋ฅผ ๋ํ๋ด๋ 0 push
if_->rsp -= 8;
memset(if_->rsp, 0, 8);
// ๊ฐ ์ธ์ ๋ฌธ์์ด์ ์ฃผ์ push
for(int i = argc-1; i >= 0; i--)
{
if_->rsp -= 8;
memcpy(if_->rsp, &arg_address[i], 8);
}
// fake return address
if_->rsp -= 8;
memset(if_->rsp, 0, 8);
//rdi ์๋ ์ธ์์ ๊ฐ์, rsi์๋ argv ์ฒซ ์ธ์์ ์์ ์ฃผ์ ์ ์ฅ
if_->R.rdi = argc;
if_->R.rsi = if_->rsp + 8; //fake return address + 8
}
4. process_wait
argument passing ํ ์คํธ๋ฅผ ํ๋ ค๋ฉด ์ผ๋จ wait๋ฅผ ํ๋ด๋ผ๋ ๋ด์ผ ํด์ ์์๋ฐฉํธ์ผ๋ก ๋ฐ๋ณต๋ฌธ์ ์ถ๊ฐํ๋ค.
10์ต์ผ๋ก ํ๋ฉด ๋๋ฌด ๋นจ๋ฆฌ ๋๋๋ฒ๋ฆฌ๊ณ 100์ต์ผ๋ก ํ๋ฉด time out์ด ๋ ์ ์ ๋ค์ด๊ฒ์ํ ๊ฒฐ๊ณผ 30์ต์ผ๋ก ํ๋ ์๋์๋ค.
int
process_wait (tid_t child_tid UNUSED) {
/* XXX: Hint) The pintos exit if process_wait (initd), we recommend you
* XXX: to add infinite loop here before
* XXX: implementing the process_wait. */
for(int i = 0; i < 3000000000; i++);
return -1;
}
Test ๊ฒฐ๊ณผ
๋ฐฑ์ค 11723 ์งํฉ
์ญ์ ํ๊ณ ์ง์ฐ๋ ๋ถ๋ถ์ ๋น์ฐํ๊ฒ append์ remove๋ก ํ์๋.... +empty
์งํฉ์์๋ add์ discard ๊ทธ๋ฆฌ๊ณ clear ๋ผ๋ ์ ์ ๋ฐฐ์ฐ๊ฒ ๋์๋ค.
# 11723 ์งํฉ
# add x : S์ x ์ถ๊ฐ,
import sys
input = sys.stdin.readline
M = int(input())
S = set()
for i in range(M):
comment = input().split()
if comment[0] == "add":
if int(comment[1]) not in S:
S.add(int(comment[1]))
elif comment[0] == "remove":
if int(comment[1]) in S:
S.discard(int(comment[1]))
elif comment[0] == "check":
if int(comment[1]) in S:
print(1)
else:
print(0)
elif comment[0] == "toggle":
if int(comment[1]) in S:
S.discard(int(comment[1]))
else:
S.add(int(comment[1]))
elif comment[0] == "all":
S = set(range(1, 21))
elif comment[0] == "empty":
S.clear()