X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=solutions%2Fp2.patch;h=0940c141ee2d9b97c4c898cf3e8c2c57d1110041;hb=a4d72a2eec532fd923e507399bc33e75bb1c3fe5;hp=90faed7b9995b39316ac53a802c1bfdadbadbc74;hpb=a85e535e696138054a7b461ea8072f0d76c5b668;p=pintos-anon diff --git a/solutions/p2.patch b/solutions/p2.patch index 90faed7..0940c14 100644 --- a/solutions/p2.patch +++ b/solutions/p2.patch @@ -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 @@ -31,21 +32,21 @@ diff -u src/threads/thread.c~ src/threads/thread.c 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 #include @@ -54,12 +55,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 +95,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,9 +117,10 @@ 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" @@ -136,17 +138,17 @@ diff -u src/userprog/process.c~ src/userprog/process.c + 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,21 +156,21 @@ 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, execute_thread, 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); + if (tid != TID_ERROR) @@ -186,20 +188,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 *file_name_) +execute_thread (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 @@ execute_thread (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 +212,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 +229,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 @@ execute_thread (void *file_name_) NOT_REACHED (); } @@ -279,15 +282,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 +296,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); + } @@ -325,11 +326,11 @@ diff -u src/userprog/process.c~ src/userprog/process.c 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 +339,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 +372,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. */ @@ -488,17 +489,18 @@ diff -u src/userprog/process.c~ src/userprog/process.c 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 +#include #include +#include "userprog/process.h" +#include "userprog/pagedir.h" -+#include "devices/kbd.h" ++#include "devices/input.h" +#include "filesys/filesys.h" +#include "filesys/file.h" +#include "threads/init.h" @@ -528,6 +530,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 @@ -654,7 +657,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; @@ -674,7 +680,7 @@ diff -u src/userprog/syscall.c~ src/userprog/syscall.c +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 +824,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 +978,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