From 51bb095185b040b5fcaf3c21e39bc41e81ae95cf Mon Sep 17 00:00:00 2001 From: Hang Park Date: Thu, 13 Apr 2017 03:10:38 +0900 Subject: [PATCH 1/2] [#71] Return saved pid of child process --- src/userprog/syscall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index e277197..4269899 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -210,7 +210,7 @@ syscall_exec (const char *cmd_line) /* Return PID. */ if (p->status & PROCESS_FAIL) return PID_ERROR; - return p->pid; + return pid; } /* Waits for a child process pid and retrieves the child's exit status. */ From a246cc8ee5bc927f3f3b66e44118e6a7b1d5cf2e Mon Sep 17 00:00:00 2001 From: Hang Park Date: Thu, 13 Apr 2017 04:02:51 +0900 Subject: [PATCH 2/2] [#71] Separte child infos into a new structure --- src/threads/thread.c | 19 ++++++++++++++----- src/userprog/process.c | 22 ++++++++++++---------- src/userprog/process.h | 13 ++++++++++--- src/userprog/syscall.c | 10 +++++----- 4 files changed, 41 insertions(+), 23 deletions(-) diff --git a/src/threads/thread.c b/src/threads/thread.c index 8fb0424..09bb282 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -189,14 +189,23 @@ thread_create (const char *name, int priority, #ifdef USERPROG struct process *curr_proc = process_current (); struct process *new_proc = &t->process; + struct process_info *new_proc_info; /* Initialize process. */ - new_proc->pid = t->tid; + new_proc->pid = (pid_t) t->tid; new_proc->parent = curr_proc; - new_proc->status = PROCESS_LOADING; - new_proc->exit_code = -1; - new_proc->is_waiting = false; - list_push_back (&curr_proc->child_list, &new_proc->elem); + + new_proc_info = (struct process_info *) malloc (sizeof (struct process_info)); + if (new_proc_info == NULL) + return TID_ERROR; + + new_proc->info = new_proc_info; + new_proc_info->pid = (pid_t) t->tid; + new_proc_info->process = new_proc; + new_proc_info->status = PROCESS_LOADING; + new_proc_info->exit_code = -1; + new_proc_info->is_waiting = false; + list_push_back (&curr_proc->child_list, &new_proc_info->elem); #endif /* Stack frame for kernel_thread(). */ diff --git a/src/userprog/process.c b/src/userprog/process.c index 6af78e2..c4be183 100644 --- a/src/userprog/process.c +++ b/src/userprog/process.c @@ -103,9 +103,9 @@ start_process (void *arguments) /* Save load result. */ struct process *curr = process_current (); if (success) - curr->status |= PROCESS_RUNNING; + curr->info->status |= PROCESS_RUNNING; else - curr->status |= PROCESS_FAIL; + curr->info->status |= PROCESS_FAIL; curr->exec_file = exec_file; curr->fd_next = FD_MIN; list_init (&curr->file_list); @@ -138,7 +138,7 @@ int process_wait (tid_t child_tid UNUSED) { struct process *curr = process_current (); - struct process *child = process_find_child (curr, child_tid); + struct process_info *child = process_find_child (curr, child_tid); if (child == NULL || child->is_waiting) return -1; @@ -146,7 +146,10 @@ process_wait (tid_t child_tid UNUSED) while (!(child->status & PROCESS_EXIT)) thread_yield (); - return child->exit_code; + int exit_code = child->exit_code; + list_remove (&child->elem); + free (child); + return exit_code; } /* Frees the current process's resources. */ @@ -160,14 +163,13 @@ process_exit (void) for (e = list_begin (&proc->child_list); e != list_end (&proc->child_list); e = list_next (e)) { - struct process *child = list_entry (e, struct process, elem); + struct process_info *child = list_entry (e, struct process_info, elem); if (!(child->status & PROCESS_EXIT)) - child->parent = NULL; + child->process->parent = NULL; } /* Update the process status and free resources. */ - proc->status |= PROCESS_EXIT; - list_remove (&proc->elem); + proc->info->status |= PROCESS_EXIT; file_close (proc->exec_file); for (e = list_begin (&proc->file_list); e != list_end (&proc->file_list);) { @@ -222,14 +224,14 @@ process_current (void) } /* Returns the child process of the given process with the given pid value. */ -struct process * +struct process_info * process_find_child (struct process *proc, pid_t pid) { struct list_elem *e; for (e = list_begin (&proc->child_list); e != list_end (&proc->child_list); e = list_next (e)) { - struct process *child = list_entry (e, struct process, elem); + struct process_info *child = list_entry (e, struct process_info, elem); if (child->pid == pid) return child; } diff --git a/src/userprog/process.h b/src/userprog/process.h index 56b17d8..d38a8cb 100644 --- a/src/userprog/process.h +++ b/src/userprog/process.h @@ -21,12 +21,19 @@ struct process struct file *exec_file; /* Process executable file. */ struct list child_list; /* List of child processes. */ struct list file_list; /* List of files in use. */ - struct list_elem elem; /* List element. */ + struct process_info *info; /* Process information for its parent. */ + int fd_next; /* File descriptor tracker. */ + }; +/* An user process information for its parent process. */ +struct process_info + { + pid_t pid; /* Process identifier. */ + struct process *process; /* Process. */ int status; /* Process status. */ int exit_code; /* Exit code. */ bool is_waiting; /* Whether parent is waiting or not. */ - int fd_next; /* File descriptor tracker. */ + struct list_elem elem; /* List element. */ }; /* A file held by some process. */ @@ -42,7 +49,7 @@ int process_wait (tid_t); void process_exit (void); void process_activate (void); struct process *process_current (void); -struct process *process_find_child (struct process *proc, pid_t pid); +struct process_info *process_find_child (struct process *proc, pid_t pid); struct file *process_get_file (int fd); int process_set_file (struct file * file); diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 4269899..9cba93b 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -174,7 +174,7 @@ void syscall_exit (int status) { /* Set exit code. */ - process_current ()->exit_code = status; + process_current ()->info->exit_code = status; /* Print the termination message. */ printf ("%s: exit(%d)\n", thread_current ()->name, status); @@ -199,16 +199,16 @@ syscall_exec (const char *cmd_line) return pid; /* Obtain the new process. */ - struct process *p = process_find_child (process_current (), pid); - if (p == NULL) + struct process_info *child = process_find_child (process_current (), pid); + if (child == NULL) return PID_ERROR; /* Wait until the new process is successfully loaded. */ - while (p->status == PROCESS_LOADING) + while (child->status == PROCESS_LOADING) thread_yield (); /* Return PID. */ - if (p->status & PROCESS_FAIL) + if (child->status & PROCESS_FAIL) return PID_ERROR; return pid; }