summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/userprog/process.c53
1 files changed, 38 insertions, 15 deletions
diff --git a/src/userprog/process.c b/src/userprog/process.c
index 45aaaa4..c0a770b 100644
--- a/src/userprog/process.c
+++ b/src/userprog/process.c
@@ -18,6 +18,11 @@
#include "threads/thread.h"
#include "threads/vaddr.h"
+struct start_process_args
+ {
+ char *file_name;
+ };
+
static thread_func start_process NO_RETURN;
static bool load (const char *cmdline, void (**eip) (void), void **esp);
@@ -28,29 +33,43 @@ static bool load (const char *cmdline, void (**eip) (void), void **esp);
tid_t
process_execute (const char *file_name)
{
- char *fn_copy;
+ struct start_process_args args; // stack allocated since we know we wait for thread_create to finish reading
tid_t tid;
+ printf("%s starting %s\n", thread_current ()->name, file_name);
+
+ sema_init (&args.sema);
+
/* Make a copy of FILE_NAME.
Otherwise there's a race between the caller and load(). */
- fn_copy = palloc_get_page (0);
- if (fn_copy == NULL)
+ args.file_name = palloc_get_page (0);
+ if (args.file_name == NULL)
return TID_ERROR;
- strlcpy (fn_copy, file_name, PGSIZE);
-
- /* Create a new thread to execute FILE_NAME. */
- tid = thread_create (file_name, PRI_DEFAULT, start_process, fn_copy);
- if (tid == TID_ERROR)
- palloc_free_page (fn_copy);
+ strlcpy (args.file_name, file_name, PGSIZE);
+
+ /* Create a new thread to execute FILE_NAME.
+ If thread_create fails we free and return immediately since we know
+ that the thread didn't start.
+ Otherwise, the child thread can be scheduled freely so we explicitly
+ wait for the child to signal that it has read the args. Only then can
+ we free resources and return the tid. */
+ tid = thread_create (file_name, PRI_DEFAULT, start_process, &args);
+ if (tid == TID_ERROR) {
+ palloc_free_page (args.file_name);
+ } else {
+ //TODO thread created, wait to see if start_process worked
+ // return -1 if failed
+ }
+ printf("woops\n");
return tid;
}
/* A thread function that loads a user process and starts it
running. */
static void
-start_process (void *file_name_)
+start_process (void *args_)
{
- char *file_name = file_name_;
+ struct start_process_args *args = args_;
struct intr_frame if_;
bool success;
@@ -59,13 +78,17 @@ start_process (void *file_name_)
if_.gs = if_.fs = if_.es = if_.ds = if_.ss = SEL_UDSEG;
if_.cs = SEL_UCSEG;
if_.eflags = FLAG_IF | FLAG_MBS;
- success = load (file_name, &if_.eip, &if_.esp);
+ printf("reading\n");
+ success = load (args->file_name, &if_.eip, &if_.esp);
/* If load failed, quit. */
- palloc_free_page (file_name);
- if (!success)
+ palloc_free_page (args->file_name);
+ if (success) {
+ //TODO report success
+ } else {
+ //TODO report failure
thread_exit ();
-
+ }
/* Start the user process by simulating a return from an
interrupt, implemented by intr_exit (in
threads/intr-stubs.S). Because intr_exit takes all of its