728x90
반응형
fork
더보기
모든 케이스를 통과한게 아니라 중간에 틀린 내용이 있을 것으로 예상..
fork()
자식 프로세스(쓰레드)를 생성하고 부모 프로세스(쓰레드)의 내용을 자식에게 복사함
tid_t fork(const char *file_name, struct intr_frame *f)
{
return process_fork(file_name, f);
}
process_fork()
커널의 인터럽트 프레임을 부모 구조체 내부의 parent_tf에 복사함(자식에게 복사해주기 위함)
tid_t process_fork(const char *name, struct intr_frame *if_ UNUSED)
{
struct thread *parent = thread_current(); // 부모 쓰레드
memcpy(&parent->parent_tf, if_, sizeof(struct intr_frame));
tid_t tid = thread_create(name, PRI_DEFAULT, __do_fork, parent);
if (tid == TID_ERROR)
return TID_ERROR;
struct thread *child = get_child_process(tid);
if (child->exit_status == TID_ERROR)
return TID_ERROR;
sema_down(&child->load_sema);
return tid;
}
__do_fork()
부모의 내용을 자식에게 복사하는 함수(인터럽트 프레임, 파일 디스크립터 테이블 등)
static void
__do_fork(void *aux)
{
struct intr_frame if_;
struct thread *parent = (struct thread *)aux;
struct thread *current = thread_current();
struct intr_frame *parent_tf = &parent->parent_tf;
bool succ = true;
memcpy(&if_, parent_tf, sizeof(struct intr_frame));
current->pml4 = pml4_create();
if (current->pml4 == NULL)
goto error;
process_activate(current);
#ifdef VM
supplemental_page_table_init(¤t->spt);
if (!supplemental_page_table_copy(¤t->spt, &parent->spt))
goto error;
#else
if (!pml4_for_each(parent->pml4, duplicate_pte, parent))
goto error;
#endif
current->fdt[0] = parent->fdt[0];
current->fdt[1] = parent->fdt[1];
current->next_fd = parent->next_fd;
for (int i = 2; i < 64; i++)
{
if (parent->fdt[i] != NULL)
{
current->fdt[i] = file_duplicate(parent->fdt[i]);
}
}
sema_up(¤t->load_sema);
process_init();
if_.R.rax = 0;
if (succ)
do_iret(&if_);
error:
sema_up(¤t->load_sema);
exit(TID_ERROR);
}
duplicate_pte
부모의 페이지 테이블을 자식에게 복제하는 함수
static bool
duplicate_pte(uint64_t *pte, void *va, void *aux)
{
struct thread *current = thread_current();
struct thread *parent = (struct thread *)aux;
void *parent_page;
void *newpage;
bool writable;
/* 1. TODO: 부모 페이지가 커널 페이지인 경우, 즉시 반환합니다. */
if (is_kernel_vaddr(va))
return true;
/* 2. 부모의 페이지 맵 레벨 4에서 VA를 해결합니다. */
parent_page = pml4_get_page(parent->pml4, va);
if (!parent_page)
return false;
/* 3. TODO: 자식에게 새로운 PAL_USER 페이지를 할당하고 결과를
* TODO: NEWPAGE에 설정합니다. */
newpage = palloc_get_page(PAL_USER | PAL_ZERO);
if (newpage == NULL)
return false;
/* 4. TODO: 부모의 페이지를 새로운 페이지에 복제하고
* TODO: 부모의 페이지가 쓰기 가능한지 확인합니다 (결과에 따라 WRITABLE을 설정). */
memcpy(newpage, parent_page, PGSIZE);
writable = is_writable(pte);
/* 5. 자식의 페이지 테이블에 주소 VA로 새로운 페이지를 WRITABLE 권한으로 추가합니다. */
if (!pml4_set_page(current->pml4, va, newpage, writable))
return false;
return true;
}
728x90
반응형
'크래프톤 정글 - TIL' 카테고리의 다른 글
크래프톤 정글 5기 TIL - Day 84 ~ 95(실력 다지기) (0) | 2024.06.14 |
---|---|
크래프톤 정글 5기 TIL - Day 71 ~83(Virtual Memory) (0) | 2024.06.03 |
크래프톤 정글 5기 TIL - Day 67~69(Pintos Project 2) (0) | 2024.05.28 |
크래프톤 정글 5기 TIL - Day 64~66(Pintos Project 2) (1) | 2024.05.24 |
크래프톤 정글 5기 TIL - Day 60 ~ 64(PintOS Project 2) (0) | 2024.05.20 |