# Filesystem code.
filesys_SRC = filesys/filesys.c # Filesystem core.
-diff -urpN pintos.orig/src/constants.h pintos/src/constants.h
---- pintos.orig/src/constants.h 2004-09-21 17:26:39.000000000 -0700
-+++ pintos/src/constants.h 2004-09-27 13:29:43.000000000 -0700
-@@ -8,4 +8,4 @@
- /*#define MACRONAME 1 */
-
- /* Uncomment if if you've implemented thread_join(). */
--/*#define THREAD_JOIN_IMPLEMENTED 1*/
-+#define THREAD_JOIN_IMPLEMENTED 1
diff -urpN pintos.orig/src/threads/init.c pintos/src/threads/init.c
--- pintos.orig/src/threads/init.c 2004-09-26 14:15:17.000000000 -0700
+++ pintos/src/threads/init.c 2004-09-27 16:08:03.000000000 -0700
thread_exit (void)
{
+ struct thread *t = thread_current ();
-+ list_elem *e, *next;
++ struct list_elem *e, *next;
+
ASSERT (!intr_context ());
schedule ();
NOT_REACHED ();
}
-@@ -270,6 +293,26 @@ thread_block (void)
- thread_current ()->status = THREAD_BLOCKED;
- schedule ();
- }
-+
-+/* Waits for thread with tid CHILD_TID to die. */
+@@ -283,8 +290,22 @@ thread_block (void)
+ This function will be implemented in problem 1-2. For now, it
+ does nothing. */
+-void
+-thread_join (tid_t child_tid UNUSED)
+-{
+int
+thread_join (tid_t child_tid)
+{
+ struct thread *cur = thread_current ();
-+ list_elem *e;
++ struct list_elem *e;
+
+ for (e = list_begin (&cur->children); e != list_end (&cur->children); )
+ {
+ if (child->tid == child_tid)
+ {
+ latch_acquire (&child->ready_to_die);
-+ return child->ret_code;
++ return child->ret_code;
+ }
+ }
+ return -1;
-+}
- \f
- /* Idle thread. Executes when no other thread is ready to run. */
- static void
+ }
+
+ /* Sets the current thread's priority to NEW_PRIORITY. */
@@ -335,6 +378,12 @@ init_thread (struct thread *t, const cha
strlcpy (t->name, name, sizeof t->name);
t->stack = (uint8_t *) t + PGSIZE;
+ struct latch ready_to_die; /* Release when thread about to die. */
+ struct semaphore can_die; /* Up when thread allowed to die. */
+ struct list children; /* List of child threads. */
-+ list_elem children_elem; /* Element of `children' list. */
++ struct list_elem children_elem; /* Element of `children' list. */
+ int ret_code; /* Return status. */
+
/* Shared between thread.c and synch.c. */
- list_elem elem; /* List element. */
+ struct list_elem elem; /* List element. */
#ifdef USERPROG
/* Owned by userprog/process.c. */
#endif
/* Owned by thread.c */
-@@ -119,7 +133,7 @@ void thread_yield (void);
- void thread_block (void);
+@@ -120,7 +132,7 @@ void thread_exit (void) NO_RETURN;
+ void thread_exit (void) NO_RETURN;
+ void thread_yield (void);
- /* This function will be implemented in problem 1-2. */
-void thread_join (tid_t);
+int thread_join (tid_t);
- /* These functions will be implemented in problem 1-3. */
void thread_set_priority (int);
+ int thread_get_priority (void);
diff -urpN pintos.orig/src/userprog/exception.c pintos/src/userprog/exception.c
--- pintos.orig/src/userprog/exception.c 2004-09-26 14:15:17.000000000 -0700
+++ pintos/src/userprog/exception.c 2004-09-27 13:29:44.000000000 -0700
bool user; /* True: access by user, false: access by kernel. */
void *fault_addr; /* Fault address. */
+ struct user_page tmp_up, *up;
-+ hash_elem *e;
++ struct hash_elem *e;
/* Obtain faulting address, the virtual address that was
accessed to cause the fault. It may point to code or to
}
}
-@@ -182,7 +189,10 @@ struct Elf32_Phdr
+@@ -182,7 +189,11 @@ struct Elf32_Phdr
#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 *cmdline, void **esp);
-+static unsigned user_page_hash (const hash_elem *, void *);
-+static bool user_page_less (const hash_elem *, const hash_elem *, void *);
++static unsigned user_page_hash (const struct hash_elem *, void *);
++static bool user_page_less (const struct hash_elem *, const struct hash_elem *,
++ void *);
+static struct user_page *make_user_page (void *upage);
/* Aborts loading an executable, with an error message. */
/* Is this a read-only segment? Not currently used, so it's
commented out. You'll want to use it when implementing VM
-@@ -340,70 +380,206 @@ load_segment (struct file *file, const s
+@@ -340,70 +380,207 @@ load_segment (struct file *file, const s
/* Load the segment page-by-page into memory. */
filesz_left = phdr->p_filesz + (phdr->p_vaddr & PGMASK);
+}
+
+static unsigned
-+user_page_hash (const hash_elem *e, void *aux UNUSED)
++user_page_hash (const struct hash_elem *e, void *aux UNUSED)
+{
+ struct user_page *up = hash_entry (e, struct user_page, elem);
+ return hash_bytes (&up->upage, sizeof up->upage);
- kpage = palloc_get_page (PAL_USER | PAL_ZERO);
- if (kpage != NULL)
+static bool
-+user_page_less (const hash_elem *a_, const hash_elem *b_, void *aux UNUSED)
++user_page_less (const struct hash_elem *a_,
++ const struct hash_elem *b_, void *aux UNUSED)
+{
+ struct user_page *a = hash_entry (a_, struct user_page, elem);
+ struct user_page *b = hash_entry (b_, struct user_page, elem);
+
+struct user_page
+ {
-+ hash_elem elem;
++ struct hash_elem elem;
+ void *upage; /* Virtual address of mapping. */
+
+ /* If FRAME is nonnull, the page is in memory.
+
+struct fildes
+ {
-+ list_elem elem;
++ struct list_elem elem;
+ struct file *file;
+ int handle;
+ };
+lookup_fd (int handle)
+{
+ struct thread *cur = thread_current ();
-+ list_elem *e;
++ struct list_elem *e;
+
+ for (e = list_begin (&cur->fds); e != list_end (&cur->fds);
+ e = list_next (e))
+syscall_exit (void)
+{
+ struct thread *cur = thread_current ();
-+ list_elem *e, *next;
++ struct list_elem *e, *next;
+
+ for (e = list_begin (&cur->fds); e != list_end (&cur->fds); e = next)
+ {