-diff -urp pintos.orig/src/constants.h pintos/src/constants.h
+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-22 00:34:01.000000000 -0700
++++ pintos/src/constants.h 2004-09-27 16:41:17.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
-Only in pintos/src: constants.h~
-diff -urp pintos.orig/src/threads/synch.c pintos/src/threads/synch.c
+diff -urpN pintos.orig/src/threads/synch.c pintos/src/threads/synch.c
--- pintos.orig/src/threads/synch.c 2004-09-19 21:29:53.000000000 -0700
-+++ pintos/src/threads/synch.c 2004-09-22 00:30:05.000000000 -0700
++++ pintos/src/threads/synch.c 2004-09-27 16:41:17.000000000 -0700
@@ -330,3 +330,35 @@ cond_name (const struct condition *cond)
return cond->name;
+ }
+ lock_release (&latch->monitor_lock);
+}
-diff -urp pintos.orig/src/threads/synch.h pintos/src/threads/synch.h
+diff -urpN pintos.orig/src/threads/synch.h pintos/src/threads/synch.h
--- pintos.orig/src/threads/synch.h 2004-09-19 21:29:53.000000000 -0700
-+++ pintos/src/threads/synch.h 2004-09-22 00:30:05.000000000 -0700
++++ pintos/src/threads/synch.h 2004-09-27 16:41:17.000000000 -0700
@@ -44,4 +44,16 @@ void cond_signal (struct condition *, st
void cond_broadcast (struct condition *, struct lock *);
const char *cond_name (const struct condition *);
+void latch_release (struct latch *);
+
#endif /* threads/synch.h */
-diff -urp pintos.orig/src/threads/thread.c pintos/src/threads/thread.c
---- pintos.orig/src/threads/thread.c 2004-09-21 22:42:17.000000000 -0700
-+++ pintos/src/threads/thread.c 2004-09-22 00:32:39.000000000 -0700
+diff -urpN pintos.orig/src/threads/thread.c pintos/src/threads/thread.c
+--- pintos.orig/src/threads/thread.c 2004-09-26 14:15:17.000000000 -0700
++++ pintos/src/threads/thread.c 2004-09-27 16:41:17.000000000 -0700
@@ -13,6 +13,7 @@
#include "threads/synch.h"
#ifdef USERPROG
#endif
/* Random value for struct thread's `magic' member.
-@@ -75,6 +76,7 @@ thread_init (void)
+@@ -80,6 +81,7 @@ thread_init (void)
init_thread (initial_thread, "main", PRI_DEFAULT);
initial_thread->status = THREAD_RUNNING;
initial_thread->tid = allocate_tid ();
}
/* Starts preemptive thread scheduling by enabling interrupts.
-@@ -119,6 +121,7 @@ thread_create (const char *name, int pri
+@@ -148,6 +150,7 @@ thread_create (const char *name, int pri
/* Initialize thread. */
init_thread (t, name, priority);
tid = t->tid = allocate_tid ();
/* Stack frame for kernel_thread(). */
kf = alloc_frame (t, sizeof *kf);
-@@ -195,16 +198,36 @@ thread_tid (void)
+@@ -224,16 +227,36 @@ thread_tid (void)
void
thread_exit (void)
{
schedule ();
NOT_REACHED ();
}
-@@ -241,6 +264,26 @@ thread_block (void)
+@@ -270,6 +293,26 @@ thread_block (void)
thread_current ()->status = THREAD_BLOCKED;
schedule ();
}
\f
/* Idle thread. Executes when no other thread is ready to run. */
static void
-@@ -306,6 +349,12 @@ init_thread (struct thread *t, const cha
+@@ -335,6 +378,12 @@ init_thread (struct thread *t, const cha
strlcpy (t->name, name, sizeof t->name);
t->stack = (uint8_t *) t + PGSIZE;
t->priority = priority;
t->magic = THREAD_MAGIC;
}
-Only in pintos/src/threads: thread.c.orig
-Only in pintos/src/threads: thread.c.rej
-Only in pintos/src/threads: thread.c~
-diff -urp pintos.orig/src/threads/thread.h pintos/src/threads/thread.h
---- pintos.orig/src/threads/thread.h 2004-09-20 15:29:18.000000000 -0700
-+++ pintos/src/threads/thread.h 2004-09-22 00:30:05.000000000 -0700
+diff -urpN pintos.orig/src/threads/thread.h pintos/src/threads/thread.h
+--- pintos.orig/src/threads/thread.h 2004-09-26 14:15:17.000000000 -0700
++++ pintos/src/threads/thread.h 2004-09-27 16:41:17.000000000 -0700
@@ -4,6 +4,7 @@
#include <debug.h>
#include <list.h>
#endif
/* Owned by thread.c */
-@@ -117,7 +129,7 @@ void thread_yield (void);
+@@ -119,7 +131,7 @@ void thread_yield (void);
void thread_block (void);
/* This function will be implemented in problem 1-2. */
/* These functions will be implemented in problem 1-3. */
void thread_set_priority (int);
-Only in pintos/src/userprog: build
-diff -urp pintos.orig/src/userprog/exception.c pintos/src/userprog/exception.c
---- pintos.orig/src/userprog/exception.c 2004-09-20 12:06:58.000000000 -0700
-+++ pintos/src/userprog/exception.c 2004-09-22 00:30:05.000000000 -0700
-@@ -134,6 +134,13 @@ page_fault (struct intr_frame *f)
+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 16:41:17.000000000 -0700
+@@ -147,6 +147,13 @@ 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. */
-diff -urp pintos.orig/src/userprog/pagedir.c pintos/src/userprog/pagedir.c
---- pintos.orig/src/userprog/pagedir.c 2004-09-21 22:42:17.000000000 -0700
-+++ pintos/src/userprog/pagedir.c 2004-09-22 00:32:23.000000000 -0700
-@@ -99,7 +99,7 @@ pagedir_set_page (uint32_t *pd, void *up
- ASSERT (pg_ofs (upage) == 0);
- ASSERT (pg_ofs (kpage) == 0);
- ASSERT (upage < PHYS_BASE);
-- ASSERT (lookup_page (pd, upage, false) == NULL);
-+ ASSERT (pagedir_get_page (pd, upage) == NULL);
-
- pte = lookup_page (pd, upage, true);
- if (pte != NULL)
-Only in pintos/src/userprog: pagedir.c.orig
-Only in pintos/src/userprog: pagedir.c.rej
-Only in pintos/src/userprog: pagedir.c.rej~
-Only in pintos/src/userprog: pagedir.c~
-diff -urp pintos.orig/src/userprog/process.c pintos/src/userprog/process.c
---- pintos.orig/src/userprog/process.c 2004-09-21 22:42:17.000000000 -0700
-+++ pintos/src/userprog/process.c 2004-09-22 00:30:05.000000000 -0700
+diff -urpN pintos.orig/src/userprog/process.c pintos/src/userprog/process.c
+--- pintos.orig/src/userprog/process.c 2004-09-22 17:58:29.000000000 -0700
++++ pintos/src/userprog/process.c 2004-09-27 16:41:17.000000000 -0700
@@ -182,7 +182,7 @@ struct Elf32_Phdr
#define PF_R 4 /* Readable. */
uint8_t *kpage;
bool success = false;
@@ -382,9 +462,9 @@ setup_stack (void **esp)
- kpage = palloc_get (PAL_USER | PAL_ZERO);
+ kpage = palloc_get_page (PAL_USER | PAL_ZERO);
if (kpage != NULL)
{
- success = install_page (((uint8_t *) PHYS_BASE) - PGSIZE, kpage);
+ if (install_page (upage, kpage))
+ success = init_cmdline (kpage, upage, cmdline, esp);
else
- palloc_free (kpage);
+ palloc_free_page (kpage);
}
-Only in pintos/src/userprog: process.c.orig
-diff -urp pintos.orig/src/userprog/syscall.c pintos/src/userprog/syscall.c
---- pintos.orig/src/userprog/syscall.c 2004-09-05 22:19:19.000000000 -0700
-+++ pintos/src/userprog/syscall.c 2004-09-22 00:30:05.000000000 -0700
+diff -urpN pintos.orig/src/userprog/syscall.c pintos/src/userprog/syscall.c
+--- pintos.orig/src/userprog/syscall.c 2004-09-26 14:15:17.000000000 -0700
++++ pintos/src/userprog/syscall.c 2004-09-27 16:43:00.000000000 -0700
@@ -1,20 +1,429 @@
#include "userprog/syscall.h"
#include <stdio.h>
+#include "threads/mmu.h"
+#include "threads/palloc.h"
#include "threads/thread.h"
-
+-
++
+typedef int syscall_function (int, int, int);
-+
++
+static int sys_halt (void);
+static int sys_exit (int status);
+static int sys_exec (const char *ufile);
+static int sys_seek (int handle, unsigned position);
+static int sys_tell (int handle);
+static int sys_close (int handle);
-+
++
+struct syscall
+ {
+ size_t arg_cnt;
+ syscall_function *func;
+ };
-+
++
+struct syscall syscall_table[] =
+ {
+ {0, (syscall_function *) sys_halt},
+ {1, (syscall_function *) sys_close},
+ };
+static const int syscall_cnt = sizeof syscall_table / sizeof *syscall_table;
-+
++
static void syscall_handler (struct intr_frame *);
+-
+static void copy_in (void *, const void *, size_t);
-+
++
+static struct lock fs_lock;
-
++
void
syscall_init (void)
{
intr_register (0x30, 3, INTR_ON, syscall_handler, "syscall");
+ lock_init (&fs_lock, "fs");
}
-
+-
++
static void
- syscall_handler (struct intr_frame *f)
+-syscall_handler (struct intr_frame *f UNUSED)
++syscall_handler (struct intr_frame *f)
{
- printf ("system call!\n");
+ struct syscall *s;
+ int call_nr;
+ int args[3];
-+
++
+ copy_in (&call_nr, f->esp, sizeof call_nr);
+ if (call_nr < 0 || call_nr >= syscall_cnt)
+ {
+ printf ("bad syscall number %d\n", call_nr);
+ thread_exit ();
+ }
-+
++
+ s = syscall_table + call_nr;
+ ASSERT (s->arg_cnt <= sizeof args / sizeof *args);
+ memset (args, 0, sizeof args);
+ copy_in (args, (uint32_t *) f->esp + 1, sizeof *args * s->arg_cnt);
+ f->eax = s->func (args[0], args[1], args[2]);
+}
-+
++
+static bool
+verify_user (const void *uaddr)
+{
+ return pagedir_get_page (thread_current ()->pagedir, uaddr) != NULL;
+}
-+
++
+static inline bool get_user (uint8_t *dst, const uint8_t *usrc) {
+ int eax;
+ asm ("movl $1f, %%eax; movb %2, %%al; movb %%al, %0; 1:"
+ : "=m" (*dst), "=&a" (eax) : "m" (*usrc));
+ return eax != 0;
+}
-+
++
+static inline bool put_user (uint8_t *udst, uint8_t byte) {
+ int eax;
+ asm ("movl $1f, %%eax; movb %b2, %0; 1:"
+ : "=m" (*udst), "=&a" (eax) : "r" (byte));
+ return eax != 0;
+}
-+
++
+static void
+copy_in (void *dst_, const void *usrc_, size_t size)
+{
+ uint8_t *dst = dst_;
+ const uint8_t *usrc = usrc_;
-+
++
+ for (; size > 0; size--, dst++, usrc++)
+ if (usrc >= (uint8_t *) PHYS_BASE || !get_user (dst, usrc))
+ thread_exit ();
+}
-+
++
+static char *
+copy_in_string (const char *us)
+{
+ char *ks;
+ size_t length;
-+
-+ ks = palloc_get (0);
++
++ ks = palloc_get_page (0);
+ if (ks == NULL)
+ {
+ printf ("copy_in_string: out of memory\n");
+ thread_exit ();
+ }
-+
++
+ for (length = 0; length < PGSIZE; length++)
+ {
+ if (us >= (char *) PHYS_BASE || !get_user (ks + length, us++))
+ printf ("bad user reference (%p)\n", us + length);
+ thread_exit ();
+ }
-+
++
+ if (ks[length] == '\0')
+ return ks;
+ }
-+
++
+ printf ("copy_in_string: string too long\n");
-+ palloc_free (ks);
++ palloc_free_page (ks);
+ thread_exit ();
+}
-+
++
+static int
+sys_halt (void)
+{
+ power_off ();
+}
-+
++
+static int
+sys_exit (int ret_code)
+{
+ thread_exit ();
+ NOT_REACHED ();
+}
-+
++
+static int
+sys_exec (const char *ufile)
+{
+ tid_t tid;
+ char *kfile = copy_in_string (ufile);
-+
++
+ lock_acquire (&fs_lock);
+ tid = process_execute (kfile);
+ lock_release (&fs_lock);
-+
-+ palloc_free (kfile);
-+
++
++ palloc_free_page (kfile);
++
+ return tid;
+}
-+
++
+static int
+sys_join (tid_t child)
+{
+ return thread_join (child);
+}
-+
++
+static int
+sys_create (const char *ufile, unsigned initial_size)
+{
+ char *kfile = copy_in_string (ufile);
+ bool ok;
-+
++
+ lock_acquire (&fs_lock);
+ ok = filesys_create (kfile, initial_size);
+ lock_release (&fs_lock);
-+
-+ palloc_free (kfile);
-+
++
++ palloc_free_page (kfile);
++
+ return ok;
+}
-+
++
+static int
+sys_remove (const char *ufile)
+{
+ char *kfile = copy_in_string (ufile);
+ bool ok;
-+
++
+ lock_acquire (&fs_lock);
+ ok = filesys_remove (kfile);
+ lock_release (&fs_lock);
-+
-+ palloc_free (kfile);
-+
++
++ palloc_free_page (kfile);
++
+ return ok;
+}
-+
++
+struct fildes
+ {
+ list_elem elem;
+ struct file *file;
+ int handle;
+ };
-+
++
+static int
+sys_open (const char *ufile)
+{
+ char *kfile = copy_in_string (ufile);
+ struct fildes *fd;
+ int handle = -1;
-+
++
+ fd = malloc (sizeof *fd);
+ if (fd == NULL)
+ goto exit;
-+
++
+ lock_acquire (&fs_lock);
+ fd->file = filesys_open (kfile);
+ if (fd->file != NULL)
+ else
+ free (fd);
+ lock_release (&fs_lock);
-+
++
+ exit:
-+ palloc_free (kfile);
++ palloc_free_page (kfile);
+ return handle;
+}
-+
++
+static struct fildes *
+lookup_fd (int handle)
+{
+ struct thread *cur = thread_current ();
+ list_elem *e;
-+
++
+ for (e = list_begin (&cur->fds); e != list_end (&cur->fds);
+ e = list_next (e))
+ {
+ if (fd->handle == handle)
+ return fd;
+ }
-+
++
+ printf ("no handle %d\n", handle);
thread_exit ();
}
-+
++
+static int
+sys_filesize (int handle)
+{
+ struct fildes *fd = lookup_fd (handle);
+ int size;
-+
++
+ lock_acquire (&fs_lock);
+ size = file_length (fd->file);
+ lock_release (&fs_lock);
-+
++
+ return size;
+}
-+
++
+static int
+sys_read (int handle, void *udst_, unsigned size)
+{
+ uint8_t *udst = udst_;
+ struct fildes *fd;
+ int bytes_read = 0;
-+
++
+ if (handle == STDIN_FILENO)
+ {
+ for (bytes_read = 0; (size_t) bytes_read < size; bytes_read++)
+ thread_exit ();
+ return bytes_read;
+ }
-+
++
+ lock_acquire (&fs_lock);
+ fd = lookup_fd (handle);
+ while (size > 0)
+ size_t page_left = PGSIZE - pg_ofs (udst);
+ size_t read_amt = size < page_left ? size : page_left;
+ off_t retval;
-+
++
+ if (!verify_user (udst))
+ {
+ lock_release (&fs_lock);
+ thread_exit ();
+ }
-+
++
+ retval = file_read (fd->file, udst, read_amt);
+ if (retval < 0)
+ {
+ bytes_read = -1;
+ break;
+ }
-+
++
+ bytes_read += retval;
+ if (retval != (off_t) read_amt)
+ break;
-+
++
+ udst += retval;
+ size -= retval;
+ }
+ lock_release (&fs_lock);
-+
++
+ return bytes_read;
+}
-+
++
+static int
+sys_write (int handle, void *usrc_, unsigned size)
+{
+ uint8_t *usrc = usrc_;
+ struct fildes *fd = NULL;
+ int bytes_written = 0;
-+
++
+ lock_acquire (&fs_lock);
+ if (handle != STDOUT_FILENO)
+ fd = lookup_fd (handle);
+ size_t page_left = PGSIZE - pg_ofs (usrc);
+ size_t write_amt = size < page_left ? size : page_left;
+ off_t retval;
-+
++
+ if (!verify_user (usrc))
+ {
+ lock_release (&fs_lock);
+ thread_exit ();
+ }
-+
++
+ if (handle == STDOUT_FILENO)
+ {
+ putbuf (usrc, write_amt);
+ bytes_written = -1;
+ break;
+ }
-+
++
+ bytes_written += retval;
+ if (retval != (off_t) write_amt)
+ break;
-+
++
+ usrc += retval;
+ size -= retval;
+ }
+ lock_release (&fs_lock);
-+
++
+ return bytes_written;
+}
-+
++
+static int
+sys_seek (int handle, unsigned position)
+{
+ struct fildes *fd = lookup_fd (handle);
-+
++
+ lock_acquire (&fs_lock);
+ file_seek (fd->file, position);
+ lock_release (&fs_lock);
-+
++
+ return 0;
+}
-+
++
+static int
+sys_tell (int handle)
+{
+ struct fildes *fd = lookup_fd (handle);
+ unsigned position;
-+
++
+ lock_acquire (&fs_lock);
+ position = file_tell (fd->file);
+ lock_release (&fs_lock);
-+
++
+ return position;
+}
-+
++
+static int
+sys_close (int handle)
+{
+ free (fd);
+ return 0;
+}
-+
++
+void
+syscall_exit (void)
+{
+ struct thread *cur = thread_current ();
+ list_elem *e, *next;
-+
++
+ for (e = list_begin (&cur->fds); e != list_end (&cur->fds); e = next)
+ {
+ struct fildes *fd = list_entry (e, struct fildes, elem);
+ free (fd);
+ }
+}
-diff -urp pintos.orig/src/userprog/syscall.h pintos/src/userprog/syscall.h
+diff -urpN pintos.orig/src/userprog/syscall.h pintos/src/userprog/syscall.h
--- pintos.orig/src/userprog/syscall.h 2004-09-05 22:38:45.000000000 -0700
-+++ pintos/src/userprog/syscall.h 2004-09-22 00:30:05.000000000 -0700
++++ pintos/src/userprog/syscall.h 2004-09-27 16:41:17.000000000 -0700
@@ -2,5 +2,6 @@
#define USERPROG_SYSCALL_H