-Index: src/threads/thread.c
-diff -u src/threads/thread.c~ src/threads/thread.c
---- src/threads/thread.c~
-+++ src/threads/thread.c
-@@ -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,18 +252,19 @@ thread_tid (void)
- void
- thread_exit (void)
- {
- ASSERT (!intr_context ());
-
+@@ -351,7 +352,8 @@ thread_exit (void)
#ifdef USERPROG
process_exit ();
#endif
/* 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 ();
- list_remove (&thread_current()->allelem);
- thread_current ()->status = THREAD_DYING;
- schedule ();
- NOT_REACHED ();
- }
-@@ -400,6 +404,10 @@ init_thread (struct thread *t, const cha
+@@ -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->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~
-+++ src/threads/thread.h
-@@ -4,6 +4,7 @@
- #include <debug.h>
- #include <list.h>
- #include <stdint.h>
-+#include "threads/synch.h"
-
- /* States in a thread's life cycle. */
- enum thread_status
-@@ -89,6 +90,10 @@ 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. */
+ struct wait_status *wait_status; /* This process's completion status. */
/* 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
+
/* 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~
-+++ src/userprog/exception.c
-@@ -150,6 +150,14 @@ page_fault (struct intr_frame *f)
+ 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;
/* 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~
-+++ src/userprog/process.c
-@@ -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"
+ };
/* Starts a new thread running a user program loaded from
- FILE_NAME. The new thread may be scheduled (and may even exit)
-@@ -27,29 +39,37 @@ static bool load (const char *cmdline, v
+ FILENAME. The new thread may be scheduled (and may even exit)
+@@ -28,29 +40,37 @@ static bool load (const char *cmdline, void (**eip) (void), void **esp);
tid_t
process_execute (const char *file_name)
{
struct intr_frame if_;
bool success;
-@@ -58,10 +78,29 @@ start_process (void *file_name_)
+@@ -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;
if (!success)
thread_exit ();
-@@ -75,18 +113,47 @@ start_process (void *file_name_)
+@@ -76,18 +115,47 @@ start_process (void *file_name_)
NOT_REACHED ();
}
return -1;
}
-@@ -95,8 +162,30 @@ void
+@@ -96,8 +164,30 @@ void
process_exit (void)
{
struct thread *cur = thread_current ();
/* 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. */
+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
int i;
/* Allocate and activate page directory. */
-@@ -224,13 +317,22 @@ load (const char *file_name, void (**eip)
+@@ -221,13 +313,22 @@ load (const char *file_name, void (**eip) (void), void **esp)
goto done;
process_activate ();
/* Read and verify executable header. */
if (file_read (file, &ehdr, sizeof ehdr) != sizeof ehdr
-@@ -284,7 +386,7 @@ load (const char *file_name, void (**eip)
+@@ -302,7 +403,7 @@ load (const char *file_name, void (**eip) (void), void **esp)
}
/* Set up stack. */
goto done;
/* Start address. */
-@@ -294,7 +396,6 @@ load (const char *file_name, 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. */
return success;
}
\f
-@@ -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;
}
{
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)
{
else
palloc_free_page (kpage);
}
-Index: src/userprog/syscall.c
-diff -u src/userprog/syscall.c~ src/userprog/syscall.c
---- src/userprog/syscall.c~
-+++ src/userprog/syscall.c
+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 <stdio.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);
+ free (fd);
+ }
+}
-Index: src/userprog/syscall.h
-diff -u src/userprog/syscall.h~ src/userprog/syscall.h
---- src/userprog/syscall.h~
-+++ src/userprog/syscall.h
+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