summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/threads/thread.h6
-rw-r--r--src/userprog/process.c41
-rw-r--r--src/userprog/syscall.c10
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