X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=solutions%2Fp2.patch;h=5b3646734279ff500bfa36983947062b20594ca3;hb=8d7983955c13e43c2901480cdbc60752d533062b;hp=90faed7b9995b39316ac53a802c1bfdadbadbc74;hpb=a85e535e696138054a7b461ea8072f0d76c5b668;p=pintos-anon diff --git a/solutions/p2.patch b/solutions/p2.patch index 90faed7..5b36467 100644 --- a/solutions/p2.patch +++ b/solutions/p2.patch @@ -1,72 +1,52 @@ -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 -@@ -13,6 +13,7 @@ - #include "threads/synch.h" +diff --git a/src/threads/thread.c b/src/threads/thread.c +index 86614f5..9fa7f1c 100644 +--- a/src/threads/thread.c ++++ b/src/threads/thread.c +@@ -15,6 +15,7 @@ + #include "threads/vaddr.h" #ifdef USERPROG #include "userprog/process.h" +#include "userprog/syscall.h" #endif /* Random value for struct thread's `magic' member. -@@ -251,16 +252,19 @@ thread_tid (void) - void - thread_exit (void) - { -+ struct thread *t = thread_current (); -+ - ASSERT (!intr_context ()); - +@@ -351,7 +352,8 @@ thread_exit (void) #ifdef USERPROG process_exit (); #endif - + syscall_exit (); + - /* Just set our status to dying and schedule another process. - We will be destroyed during the call to schedule_tail(). */ - intr_disable (); -- thread_current ()->status = THREAD_DYING; -+ t->status = THREAD_DYING; - schedule (); - NOT_REACHED (); - } -@@ -400,6 +404,11 @@ init_thread (struct thread *t, const cha + /* 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(). */ +@@ -608,6 +610,10 @@ init_thread (struct thread *t, const char *name, int priority) strlcpy (t->name, name, sizeof t->name); t->stack = (uint8_t *) t + PGSIZE; - t->priority = priority; + t->priority = t->normal_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; - } - -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 -@@ -4,6 +4,7 @@ - #include - #include - #include -+#include "threads/synch.h" - - /* States in a thread's life cycle. */ - enum thread_status -@@ -89,6 +90,11 @@ struct thread - uint8_t *stack; /* Saved stack pointer. */ - int priority; /* Priority. */ + sema_init (&t->timer_sema, 0); + list_init (&t->donors); +diff --git a/src/threads/thread.h b/src/threads/thread.h +index 6601963..2c85d88 100644 +--- a/src/threads/thread.h ++++ b/src/threads/thread.h +@@ -101,6 +101,10 @@ struct thread + fixed_point_t recent_cpu; /* Recent amount of CPU time. */ + struct list_elem allelem; /* List element for all threads list. */ + /* 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. */ + /* Shared between thread.c and synch.c. */ struct list_elem elem; /* List element. */ -@@ -96,11 +102,31 @@ struct thread +@@ -113,11 +117,31 @@ struct thread /* Owned by userprog/process.c. */ uint32_t *pagedir; /* Page directory. */ #endif @@ -95,13 +75,14 @@ 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); -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 -@@ -150,6 +150,14 @@ page_fault (struct intr_frame *f) + /* If false (default), use round-robin scheduler. + If true, use multi-level feedback queue scheduler. + Controlled by kernel command-line option "-o mlfqs". */ +diff --git a/src/userprog/exception.c b/src/userprog/exception.c +index 19aca12..3682478 100644 +--- a/src/userprog/exception.c ++++ b/src/userprog/exception.c +@@ -148,6 +148,14 @@ page_fault (struct intr_frame *f) write = (f->error_code & PF_W) != 0; user = (f->error_code & PF_U) != 0; @@ -116,10 +97,12 @@ 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. */ -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 -@@ -14,11 +14,23 @@ +diff --git a/src/userprog/process.c b/src/userprog/process.c +index c0e5215..06ff27e 100644 +--- a/src/userprog/process.c ++++ b/src/userprog/process.c +@@ -14,12 +14,24 @@ + #include "threads/flags.h" #include "threads/init.h" #include "threads/interrupt.h" +#include "threads/malloc.h" @@ -127,16 +110,16 @@ diff -u src/userprog/process.c~ src/userprog/process.c #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? */ @@ -144,9 +127,9 @@ diff -u src/userprog/process.c~ src/userprog/process.c /* Starts a new thread running a user program loaded from FILENAME. The new thread may be scheduled (and may even exit) -@@ -27,29 +39,37 @@ static bool load (const char *cmdline, v +@@ -28,29 +40,37 @@ static bool load (const char *cmdline, void (**eip) (void), void **esp); tid_t - process_execute (const char *filename) + process_execute (const char *file_name) { - char *fn_copy; + struct exec_info exec; @@ -154,23 +137,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 +169,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_) +@@ -59,10 +79,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 +193,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 +210,7 @@ diff -u src/userprog/process.c~ src/userprog/process.c if (!success) thread_exit (); -@@ -75,18 +113,47 @@ execute_thread (void *filename_) +@@ -76,18 +115,47 @@ start_process (void *file_name_) NOT_REACHED (); } @@ -279,15 +263,13 @@ diff -u src/userprog/process.c~ src/userprog/process.c return -1; } -@@ -95,8 +162,32 @@ void +@@ -96,8 +164,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 +277,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); + } @@ -312,7 +294,7 @@ diff -u src/userprog/process.c~ src/userprog/process.c /* Destroy the current process's page directory and switch back to the kernel-only page directory. */ pd = cur->pagedir; -@@ -193,7 +284,7 @@ struct Elf32_Phdr +@@ -195,7 +285,7 @@ struct Elf32_Phdr #define PF_W 2 /* Writable. */ #define PF_R 4 /* Readable. */ @@ -320,16 +302,16 @@ diff -u src/userprog/process.c~ src/userprog/process.c +static bool setup_stack (const char *cmd_line, void **esp); 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); + uint32_t read_bytes, uint32_t zero_bytes, +@@ -206,13 +296,15 @@ static bool load_segment (struct file *file, off_t ofs, uint8_t *upage, 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 +320,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) +@@ -221,13 +313,22 @@ load (const char *file_name, void (**eip) (void), void **esp) 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) +@@ -302,7 +403,7 @@ load (const char *file_name, void (**eip) (void), void **esp) } /* Set up stack. */ @@ -371,7 +353,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) +@@ -312,7 +413,6 @@ load (const char *file_name, void (**eip) (void), void **esp) done: /* We arrive here whether the load is successful or not. */ @@ -379,7 +361,7 @@ diff -u src/userprog/process.c~ src/userprog/process.c return success; } -@@ -393,10 +494,92 @@ load_segment (struct file *file, const s +@@ -424,10 +524,92 @@ load_segment (struct file *file, off_t ofs, uint8_t *upage, return true; } @@ -475,7 +457,7 @@ diff -u src/userprog/process.c~ src/userprog/process.c { uint8_t *kpage; bool success = false; -@@ -404,9 +587,9 @@ setup_stack (void **esp) +@@ -435,9 +617,9 @@ setup_stack (void **esp) kpage = palloc_get_page (PAL_USER | PAL_ZERO); if (kpage != NULL) { @@ -488,26 +470,27 @@ diff -u src/userprog/process.c~ src/userprog/process.c else palloc_free_page (kpage); } -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 @@ +diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c +index 370c89b..ef31316 100644 +--- a/src/userprog/syscall.c ++++ b/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 "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" #include "threads/thread.h" -+#include "threads/vaddr.h" - ++#include "threads/vaddr.h" + + +static int sys_halt (void); @@ -528,6 +511,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 +601,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 +638,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 +654,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 +805,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 +959,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); + } +} -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 +diff --git a/src/userprog/syscall.h b/src/userprog/syscall.h +index 9059096..9d156f0 100644 +--- a/src/userprog/syscall.h ++++ b/src/userprog/syscall.h @@ -2,5 +2,6 @@ #define USERPROG_SYSCALL_H