diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/threads/thread.h | 6 | ||||
| -rw-r--r-- | src/userprog/process.c | 41 | ||||
| -rw-r--r-- | src/userprog/syscall.c | 10 |
3 files changed, 45 insertions, 12 deletions
diff --git a/src/threads/thread.h b/src/threads/thread.h index b822b64..b2a1982 100644 --- a/src/threads/thread.h +++ b/src/threads/thread.h @@ -32,12 +32,12 @@ struct parent_child { struct list_elem elem; // owned by the parent - struct semaphore exit_sema; + // struct semaphore exit_sema; struct lock l; int exit_status; int alive_count; - + tid_t child_tid; }; /* Thread priorities. */ @@ -119,7 +119,7 @@ struct thread uint32_t *pagedir; /* Page directory. */ struct file **fds; /* Pointer to array of file descriptors. */ - struct parent_child parent; // one parent + struct parent_child *parent; // one parent struct list children; // multiple children #endif diff --git a/src/userprog/process.c b/src/userprog/process.c index e99374b..39f063b 100644 --- a/src/userprog/process.c +++ b/src/userprog/process.c @@ -14,6 +14,7 @@ #include "threads/flags.h" #include "threads/init.h" #include "threads/interrupt.h" +#include "threads/malloc.h" #include "threads/palloc.h" #include "threads/synch.h" #include "threads/thread.h" @@ -42,12 +43,8 @@ tid_t process_execute (const char *file_name) { struct start_process_args args; // stack allocated since we know we wait for thread_create to finish reading - struct thread *t; tid_t tid; - t = thread_current (); - printf("%s starting %s\n", t->name, file_name); - sema_init (&args.sema, 0); /* Make a copy of FILE_NAME. @@ -68,7 +65,7 @@ process_execute (const char *file_name) sema_down (&args.sema); if (args.success) { - list_push_back (&t->children, &args.child->elem); + list_push_back (&thread_current ()->children, &args.child->elem); } else { tid = -1; } @@ -98,10 +95,15 @@ start_process (void *args_) args->success = success; if (success) { - sema_init (&t->parent.exit_sema, 0); - lock_init (&t->parent.l); + t->parent = malloc (sizeof (struct parent_child)); + + // sema_init (&t->parent.exit_sema, 0); + lock_init (&t->parent->l); - args->child = &t->parent; + t->parent->child_tid = t->tid; + t->parent->alive_count = 2; + + args->child = t->parent; } sema_up (&args->sema); @@ -135,6 +137,19 @@ process_wait (tid_t child_tid UNUSED) for (;;) {} } +static void +free_pc (struct parent_child *pc) +{ + lock_acquire (&pc->l); + + pc->alive_count--; + if (pc->alive_count == 0) { + free (pc); + } else { + lock_release (&pc->l); + } +} + /* Free the current process's resources. */ void process_exit (void) @@ -142,6 +157,16 @@ process_exit (void) struct thread *cur = thread_current (); uint32_t *pd; + free_pc (cur->parent); + + struct list_elem *e; + struct parent_child *child; + while (!list_empty (&cur->children)) { + e = list_pop_front (&cur->children); + child = list_entry (e, struct parent_child, elem); + free_pc (child); + } + /* Destroy the current process's page directory and switch back to the kernel-only page directory. */ pd = cur->pagedir; diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 0df46f4..177cf02 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -69,7 +69,7 @@ get_fd (struct thread *thread, int fd_i) } static void -exit (int status UNUSED) +exit (int status) { struct thread *thread = thread_current (); @@ -83,6 +83,14 @@ exit (int status UNUSED) } free (thread->fds); } + + lock_acquire (&thread->parent->l); + thread->parent->exit_status = status; + lock_release (&thread->parent->l); + + printf("%s: exit(%d)\n", thread->name, status); + + thread_exit (); } static int |
