diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/userprog/process.c | 53 |
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 |
