
fork 실패 예외처리fork가 실패하는 경우process_fork 함수는 복제 과정에서 문제가 발생할 시 TID_ERROR을 반환해야 함// [부모] process_fork 함수
tid_t result = thread_create(name, PRI_DEFAULT, __do_fork, fa);
// 자식 쓰레드 생성에 실패하면 TID_ERROR 반환
if (result == TID_ERROR){
free(fa);
return TID_ERROR;
}
(1) thread_create가 자식 쓰레드 생성에 실패한 경우
thread_create는 실패 시 TID_ERROR 반환, 쉽게 예외처리 가능(2) 자식 프로세스의 __do_fork에서 부모의 자원을 복제하는 데 실패한 경우
struct fork_aux {
struct thread *parent;
struct intr_frame *parent_if;
bool success; // 복제의 성공 여부 표시
};
struct thread *curr = thread_current();
// [구현 7-2] 자식에게 부모의 인터럽트 프레임 전달하기.
struct fork_aux *fa = malloc(sizeof(struct fork_aux));
if (fa == NULL){
return TID_ERROR;
}
fa -> parent = thread_current();
fa -> parent_if = if_;
fa -> success = false; // false로 초기화
// 자식 쓰레드 생성 및 __do_fork 호출
tid_t result = thread_create(name, PRI_DEFAULT, __do_fork, fa);
__do_fork에 여러 인자를 넘기기기 위해, 구조체로 묶고 포인터로 전달success 멤버: false로 초기화, 복제에 성공했을 때만 true로 변경// [자식] __do_fork 함수
current->pml4 = pml4_create();
if (current->pml4 == NULL)
goto error;
if (!pml4_for_each(parent->pml4, duplicate_pte, parent))
goto error;
struct file *copy = file_duplicate(parent_file);
if (copy == NULL)
goto error;
// 성공한 경우 success 멤버를 true로 변경
((struct fork_aux *)(aux)) -> success = true;
do_iret (&if_);
// 생략
error:
// 실패한 경우, 바로 error로 이동하므로 success는 false로 유지됨
sema_up(&(parent -> f_sema));
thread_exit (); // 자식 쓰레드 종료
error 레이블로 이동 -> success는 false 유지thread_exit으로 종료시킴true로 변경하고, do_iret으로 사용자모드로 복귀// [부모] process_fork
sema_down(&(thread_current()->f_sema));
// fa는 __do_init에 전달한 구조체
if (!(fa -> success)){
result = TID_ERROR;
}
free(fa);
return result;
success 멤버를 false로 남겨둔 경우, TID_ERROR를 반환해 복제실패 처리