solutions: Fix mangled p4.patch.
[pintos-anon] / solutions / p2.patch
index e1d72745b617dd3186bcfa4772d9f08bb67271f3..41f6764d445a0c27b2218abffec0bc202f95cf01 100644 (file)
@@ -1,6 +1,7 @@
+Index: src/threads/thread.c
 diff -u src/threads/thread.c~ src/threads/thread.c
---- src/threads/thread.c~ 2005-06-02 14:35:12.000000000 -0700
-+++ src/threads/thread.c 2005-06-08 13:45:28.000000000 -0700
+--- src/threads/thread.c~
++++ src/threads/thread.c
 @@ -13,6 +13,7 @@
  #include "threads/synch.h"
  #ifdef USERPROG
@@ -9,12 +10,10 @@ diff -u src/threads/thread.c~ src/threads/thread.c
  #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
@@ -23,29 +22,30 @@ diff -u src/threads/thread.c~ src/threads/thread.c
 -
 +  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 ();
  }
-@@ -400,6 +404,11 @@ init_thread (struct thread *t, const cha
+@@ -400,6 +404,10 @@ init_thread (struct thread *t, const cha
    strlcpy (t->name, name, sizeof t->name);
    t->stack = (uint8_t *) t + PGSIZE;
    t->priority = priority;
 +  list_init (&t->children);
-+  t->exit_code = -1;
 +  t->wait_status = NULL;
 +  list_init (&t->fds);
 +  t->next_handle = 2;
    t->magic = THREAD_MAGIC;
  }
  
+Index: src/threads/thread.h
 diff -u src/threads/thread.h~ src/threads/thread.h
---- src/threads/thread.h~ 2005-06-02 14:32:36.000000000 -0700
-+++ src/threads/thread.h 2005-06-08 13:47:09.000000000 -0700
+--- src/threads/thread.h~
++++ src/threads/thread.h
 @@ -4,6 +4,7 @@
  #include <debug.h>
  #include <list.h>
@@ -54,12 +54,11 @@ diff -u src/threads/thread.h~ src/threads/thread.h
  
  /* States in a thread's life cycle. */
  enum thread_status
-@@ -89,6 +90,11 @@ struct thread
+@@ -89,6 +90,10 @@ struct thread
      uint8_t *stack;                     /* Saved stack pointer. */
      int priority;                       /* Priority. */
  
 +    /* Owned by process.c. */
-+    int exit_code;                      /* Exit code. */
 +    struct wait_status *wait_status;    /* This process's completion status. */
 +    struct list children;               /* Completion status of children. */
 +
@@ -95,12 +94,13 @@ diff -u src/threads/thread.h~ src/threads/thread.h
 +    struct semaphore dead;              /* 1=child alive, 0=child dead. */
 +  };
 +
- void thread_init (void);
- void thread_start (void);
- void thread_tick (void);
+ /* If false (default), use round-robin scheduler.
+    If true, use multi-level feedback queue scheduler.
+    Controlled by kernel command-line options "-o mlfqs".
+Index: src/userprog/exception.c
 diff -u src/userprog/exception.c~ src/userprog/exception.c
---- src/userprog/exception.c~ 2005-01-01 18:09:59.000000000 -0800
-+++ src/userprog/exception.c 2005-06-08 13:45:28.000000000 -0700
+--- src/userprog/exception.c~
++++ src/userprog/exception.c
 @@ -150,6 +150,14 @@ page_fault (struct intr_frame *f) 
    write = (f->error_code & PF_W) != 0;
    user = (f->error_code & PF_U) != 0;
@@ -116,37 +116,38 @@ diff -u src/userprog/exception.c~ src/userprog/exception.c
    /* To implement virtual memory, delete the rest of the function
       body, and replace it with code that brings in the page to
       which fault_addr refers. */
+Index: src/userprog/process.c
 diff -u src/userprog/process.c~ src/userprog/process.c
---- src/userprog/process.c~ 2005-05-26 13:19:48.000000000 -0700
-+++ src/userprog/process.c 2005-06-08 13:49:13.000000000 -0700
+--- src/userprog/process.c~
++++ src/userprog/process.c
 @@ -14,11 +14,23 @@
  #include "threads/init.h"
  #include "threads/interrupt.h"
- #include "threads/mmu.h"
 +#include "threads/malloc.h"
  #include "threads/palloc.h"
  #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 
 +  {
-+    const char *filename;               /* Program to load. */
++    const char *file_name;              /* Program to load. */
 +    struct semaphore load_done;         /* "Up"ed when loading complete. */
 +    struct wait_status *wait_status;    /* Child process. */
 +    bool success;                       /* Program successfully loaded? */
 +  };
  
  /* Starts a new thread running a user program loaded from
-    FILENAME.  The new thread may be scheduled (and may even exit)
+    FILE_NAME.  The new thread may be scheduled (and may even exit)
 @@ -27,29 +39,37 @@ static bool load (const char *cmdline, v
  tid_t
- process_execute (const char *filename) 
+ process_execute (const char *file_name) 
  {
 -  char *fn_copy;
 +  struct exec_info exec;
@@ -154,23 +155,23 @@ diff -u src/userprog/process.c~ src/userprog/process.c
 +  char *save_ptr;
    tid_t tid;
  
--  /* Make a copy of FILENAME.
+-  /* 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)
 -    return TID_ERROR;
--  strlcpy (fn_copy, filename, PGSIZE);
+-  strlcpy (fn_copy, file_name, PGSIZE);
 +  /* Initialize exec_info. */
-+  exec.filename = filename;
++  exec.file_name = file_name;
 +  sema_init (&exec.load_done, 0);
  
-   /* Create a new thread to execute FILENAME. */
--  tid = thread_create (filename, PRI_DEFAULT, execute_thread, fn_copy);
+   /* 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 (thread_name, filename, sizeof thread_name);
++  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);
@@ -186,20 +187,20 @@ diff -u src/userprog/process.c~ src/userprog/process.c
  /* A thread function that loads a user process and starts it
     running. */
  static void
--execute_thread (void *filename_)
-+execute_thread (void *exec_)
+-start_process (void *file_name_)
++start_process (void *exec_)
  {
--  char *filename = filename_;
+-  char *file_name = file_name_;
 +  struct exec_info *exec = exec_;
    struct intr_frame if_;
    bool success;
  
-@@ -58,10 +78,28 @@ execute_thread (void *filename_)
+@@ -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;
--  success = load (filename, &if_.eip, &if_.esp);
-+  success = load (exec->filename, &if_.eip, &if_.esp);
+-  success = load (file_name, &if_.eip, &if_.esp);
++  success = load (exec->file_name, &if_.eip, &if_.esp);
 +
 +  /* Allocate wait_status. */
 +  if (success)
@@ -210,13 +211,14 @@ diff -u src/userprog/process.c~ src/userprog/process.c
 +    }
  
 -  /* If load failed, quit. */
--  palloc_free_page (filename);
+-  palloc_free_page (file_name);
 +  /* Initialize wait_status. */
 +  if (success) 
 +    {
 +      lock_init (&exec->wait_status->lock);
 +      exec->wait_status->ref_cnt = 2;
 +      exec->wait_status->tid = thread_current ()->tid;
++      exec->wait_status->exit_code = -1;
 +      sema_init (&exec->wait_status->dead, 0);
 +    }
 +  
@@ -226,7 +228,7 @@ diff -u src/userprog/process.c~ src/userprog/process.c
    if (!success) 
      thread_exit ();
  
-@@ -75,18 +113,47 @@ execute_thread (void *filename_)
+@@ -75,18 +113,47 @@ start_process (void *file_name_)
    NOT_REACHED ();
  }
  
@@ -279,15 +281,13 @@ diff -u src/userprog/process.c~ src/userprog/process.c
    return -1;
  }
  
-@@ -95,8 +162,32 @@ void
+@@ -95,8 +162,30 @@ void
  process_exit (void)
  {
    struct thread *cur = thread_current ();
 +  struct list_elem *e, *next;
    uint32_t *pd;
  
-+  printf ("%s: exit(%d)\n", cur->name, cur->exit_code);
-+
 +  /* Close executable (and allow writes). */
 +  file_close (cur->bin_file);
 +
@@ -295,7 +295,7 @@ diff -u src/userprog/process.c~ src/userprog/process.c
 +  if (cur->wait_status != NULL) 
 +    {
 +      struct wait_status *cs = cur->wait_status;
-+      cs->exit_code = cur->exit_code;
++      printf ("%s: exit(%d)\n", cur->name, cs->exit_code);
 +      sema_up (&cs->dead);
 +      release_child (cs);
 +    }
@@ -313,23 +313,23 @@ diff -u src/userprog/process.c~ src/userprog/process.c
       to the kernel-only page directory. */
    pd = cur->pagedir;
 @@ -193,7 +284,7 @@ struct Elf32_Phdr
+ #define PF_W 2          /* Writable. */
  #define PF_R 4          /* Readable. */
  
- static bool load_segment (struct file *, const struct Elf32_Phdr *);
 -static bool setup_stack (void **esp);
 +static bool setup_stack (const char *cmd_line, void **esp);
- /* Loads an ELF executable from FILENAME into the current thread.
-    Stores the executable's entry point into *EIP
+ static bool validate_segment (const struct Elf32_Phdr *, struct file *);
+ static bool load_segment (struct file *file, off_t ofs, uint8_t *upage,
+                           bool writable);
 @@ -209,13 +300,15 @@ static bool setup_stack (void **esp);
     and its initial stack pointer into *ESP.
     Returns true if successful, false otherwise. */
  bool
--load (const char *filename, void (**eip) (void), void **esp) 
+-load (const char *file_name, void (**eip) (void), void **esp) 
 +load (const char *cmd_line, void (**eip) (void), void **esp) 
  {
    struct thread *t = thread_current ();
-+  char filename[NAME_MAX + 2];
++  char file_name[NAME_MAX + 2];
    struct Elf32_Ehdr ehdr;
    struct file *file = NULL;
    off_t file_ofs;
@@ -338,31 +338,31 @@ diff -u src/userprog/process.c~ src/userprog/process.c
    int i;
  
    /* Allocate and activate page directory. */
-@@ -224,13 +317,22 @@ load (const char *filename, void (**eip)
+@@ -224,13 +317,22 @@ load (const char *file_name, void (**eip)
      goto done;
    process_activate ();
  
-+  /* Extract filename from command line. */
++  /* Extract file_name from command line. */
 +  while (*cmd_line == ' ')
 +    cmd_line++;
-+  strlcpy (filename, cmd_line, sizeof filename);
-+  cp = strchr (filename, ' ');
++  strlcpy (file_name, cmd_line, sizeof file_name);
++  cp = strchr (file_name, ' ');
 +  if (cp != NULL)
 +    *cp = '\0';
 +
    /* Open executable file. */
--  file = filesys_open (filename);
-+  t->bin_file = file = filesys_open (filename);
+-  file = filesys_open (file_name);
++  t->bin_file = file = filesys_open (file_name);
    if (file == NULL) 
      {
-       printf ("load: %s: open failed\n", filename);
+       printf ("load: %s: open failed\n", file_name);
        goto done; 
      }
 +  file_deny_write (file);
  
    /* Read and verify executable header. */
    if (file_read (file, &ehdr, sizeof ehdr) != sizeof ehdr
-@@ -284,7 +386,7 @@ load (const char *filename, void (**eip)
+@@ -284,7 +386,7 @@ load (const char *file_name, void (**eip)
      }
  
    /* Set up stack. */
@@ -371,7 +371,7 @@ diff -u src/userprog/process.c~ src/userprog/process.c
      goto done;
  
    /* Start address. */
-@@ -294,7 +396,6 @@ load (const char *filename, void (**eip)
+@@ -294,7 +396,6 @@ load (const char *file_name, void (**eip)
  
   done:
    /* We arrive here whether the load is successful or not. */
@@ -479,34 +479,35 @@ diff -u src/userprog/process.c~ src/userprog/process.c
    kpage = palloc_get_page (PAL_USER | PAL_ZERO);
    if (kpage != NULL) 
      {
--      success = install_page (((uint8_t *) PHYS_BASE) - PGSIZE, kpage);
+-      success = install_page (((uint8_t *) PHYS_BASE) - PGSIZE, kpage, true);
 -      if (success)
 -        *esp = PHYS_BASE;
 +      uint8_t *upage = ((uint8_t *) PHYS_BASE) - PGSIZE;
-+      if (install_page (upage, kpage))
++      if (install_page (upage, kpage, true))
 +        success = init_cmd_line (kpage, upage, cmd_line, esp);
        else
          palloc_free_page (kpage);
      }
+Index: src/userprog/syscall.c
 diff -u src/userprog/syscall.c~ src/userprog/syscall.c
---- src/userprog/syscall.c~ 2004-09-26 14:15:17.000000000 -0700
-+++ src/userprog/syscall.c 2005-06-08 13:45:28.000000000 -0700
-@@ -1,20 +1,480 @@
+--- src/userprog/syscall.c~
++++ src/userprog/syscall.c
+@@ -1,20 +1,486 @@
  #include "userprog/syscall.h"
  #include <stdio.h>
 +#include <string.h>
  #include <syscall-nr.h>
 +#include "userprog/process.h"
 +#include "userprog/pagedir.h"
-+#include "devices/kbd.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/mmu.h"
 +#include "threads/palloc.h"
  #include "threads/thread.h"
++#include "threads/vaddr.h"
 -
 + 
 + 
@@ -528,6 +529,7 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 -
 +static void copy_in (void *, const void *, size_t);
 + 
++/* Serializes file system operations. */
 +static struct lock fs_lock;
 + 
  void
@@ -617,7 +619,7 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +{
 +  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;
 +}
 + 
@@ -654,7 +656,10 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +  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;
@@ -667,14 +672,14 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +static int
 +sys_halt (void)
 +{
-+  power_off ();
++  shutdown_power_off ();
 +}
 + 
 +/* Exit system call. */
 +static int
 +sys_exit (int exit_code) 
 +{
-+  thread_current ()->exit_code = exit_code;
++  thread_current ()->wait_status->exit_code = exit_code;
 +  thread_exit ();
 +  NOT_REACHED ();
 +}
@@ -818,7 +823,7 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +  if (handle == STDIN_FILENO) 
 +    {
 +      for (bytes_read = 0; (size_t) bytes_read < size; bytes_read++)
-+        if (udst >= (uint8_t *) PHYS_BASE || !put_user (udst++, kbd_getc ()))
++        if (udst >= (uint8_t *) PHYS_BASE || !put_user (udst++, input_getc ()))
 +          thread_exit ();
 +      return bytes_read;
 +    }
@@ -972,13 +977,16 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c
 +      struct file_descriptor *fd;
 +      fd = list_entry (e, struct file_descriptor, elem);
 +      next = list_next (e);
++      lock_acquire (&fs_lock);
 +      file_close (fd->file);
++      lock_release (&fs_lock);
 +      free (fd);
 +    }
 +}
+Index: src/userprog/syscall.h
 diff -u src/userprog/syscall.h~ src/userprog/syscall.h
---- src/userprog/syscall.h~ 2004-09-05 22:38:45.000000000 -0700
-+++ src/userprog/syscall.h 2005-06-08 13:45:28.000000000 -0700
+--- src/userprog/syscall.h~
++++ src/userprog/syscall.h
 @@ -2,5 +2,6 @@
  #define USERPROG_SYSCALL_H