#endif
/* Random value for struct thread's `magic' member.
-@@ -251,16 +252,19 @@ thread_tid (void)
+@@ -251,18 +252,19 @@ thread_tid (void)
void
thread_exit (void)
{
-+ struct thread *t = thread_current ();
-+
ASSERT (!intr_context ());
#ifdef USERPROG
-
+ syscall_exit ();
+
- /* Just set our status to dying and schedule another process.
- We will be destroyed during the call to schedule_tail(). */
+ /* Remove thread from all threads list, set our status to dying,
+ and schedule another process. That process will destroy us
+ when it calls thread_schedule_tail(). */
intr_disable ();
-- thread_current ()->status = THREAD_DYING;
-+ t->status = THREAD_DYING;
+ list_remove (&thread_current()->allelem);
+ thread_current ()->status = THREAD_DYING;
schedule ();
NOT_REACHED ();
}
#include "threads/thread.h"
#include "threads/vaddr.h"
- static thread_func execute_thread NO_RETURN;
+ static thread_func start_process NO_RETURN;
-static bool load (const char *cmdline, void (**eip) (void), void **esp);
+static bool load (const char *cmd_line, void (**eip) (void), void **esp);
+
+/* Data structure shared between process_execute() in the
-+ invoking thread and execute_thread() in the newly invoked
++ invoking thread and start_process() in the newly invoked
+ thread. */
+struct exec_info
+ {
+ sema_init (&exec.load_done, 0);
/* Create a new thread to execute FILE_NAME. */
-- tid = thread_create (file_name, PRI_DEFAULT, execute_thread, fn_copy);
+- tid = thread_create (file_name, PRI_DEFAULT, start_process, fn_copy);
- if (tid == TID_ERROR)
- palloc_free_page (fn_copy);
+ strlcpy (thread_name, file_name, sizeof thread_name);
+ strtok_r (thread_name, " ", &save_ptr);
-+ tid = thread_create (thread_name, PRI_DEFAULT, execute_thread, &exec);
++ tid = thread_create (thread_name, PRI_DEFAULT, start_process, &exec);
+ if (tid != TID_ERROR)
+ {
+ sema_down (&exec.load_done);
/* A thread function that loads a user process and starts it
running. */
static void
--execute_thread (void *file_name_)
-+execute_thread (void *exec_)
+-start_process (void *file_name_)
++start_process (void *exec_)
{
- char *file_name = file_name_;
+ struct exec_info *exec = exec_;
struct intr_frame if_;
bool success;
-@@ -58,10 +78,29 @@ execute_thread (void *file_name_)
+@@ -58,10 +78,29 @@ 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;
if (!success)
thread_exit ();
-@@ -75,18 +113,47 @@ execute_thread (void *file_name_)
+@@ -75,18 +113,47 @@ start_process (void *file_name_)
NOT_REACHED ();
}
diff -u src/userprog/syscall.c~ src/userprog/syscall.c
--- src/userprog/syscall.c~
+++ src/userprog/syscall.c
-@@ -1,20 +1,483 @@
+@@ -1,20 +1,486 @@
#include "userprog/syscall.h"
#include <stdio.h>
+#include <string.h>
+#include "userprog/process.h"
+#include "userprog/pagedir.h"
+#include "devices/input.h"
++#include "devices/shutdown.h"
+#include "filesys/filesys.h"
+#include "filesys/file.h"
-+#include "threads/init.h"
#include "threads/interrupt.h"
+#include "threads/malloc.h"
+#include "threads/palloc.h"
+{
+ int eax;
+ asm ("movl $1f, %%eax; movb %b2, %0; 1:"
-+ : "=m" (*udst), "=&a" (eax) : "r" (byte));
++ : "=m" (*udst), "=&a" (eax) : "q" (byte));
+ return eax != 0;
+}
+
+ for (length = 0; length < PGSIZE; length++)
+ {
+ if (us >= (char *) PHYS_BASE || !get_user (ks + length, us++))
-+ thread_exit ();
++ {
++ palloc_free_page (ks);
++ thread_exit ();
++ }
+
+ if (ks[length] == '\0')
+ return ks;
+static int
+sys_halt (void)
+{
-+ power_off ();
++ shutdown_power_off ();
+}
+
+/* Exit system call. */