/* Closes INODE and writes it to disk.
If this was the last reference to INODE, frees its memory.
If INODE was also a removed inode, frees its blocks. */
-@@ -158,18 +181,59 @@ inode_close (struct inode *inode)
+@@ -158,21 +181,60 @@ inode_close (struct inode *inode)
return;
/* Release resources if this was the last opener. */
/* Remove from inode list and release lock. */
list_remove (&inode->elem);
+ lock_release (&open_inodes_lock);
-
+
/* Deallocate blocks if removed. */
- if (inode->removed)
-- free_map_release (inode->sector,
-- bytes_to_sectors (inode->data.length));
--
+ if (inode->removed)
+- {
+- free_map_release (inode->sector, 1);
+- free_map_release (inode->data.start,
+- bytes_to_sectors (inode->data.length));
+- }
+ deallocate_inode (inode);
+
free (inode);
}
+ else
ASSERT (file != NULL);
ASSERT (phdr != NULL);
-@@ -332,69 +458,129 @@ load_segment (struct file *file, const s
+@@ -332,73 +458,129 @@ load_segment (struct file *file, const s
|| start == 0)
return false;
}
-/* Adds a mapping from user virtual address UPAGE to kernel
-- virtual address KPAGE to the page table. Fails if UPAGE is
-- already mapped or if memory allocation fails. */
+- virtual address KPAGE to the page table.
+- UPAGE must not already be mapped.
+- KPAGE should probably be a page obtained from the user pool
+- with palloc_get_page().
+- Returns true on success, false if UPAGE is already mapped or
+- if memory allocation fails. */
+/* Create a minimal stack for T by mapping a page at the
+ top of user virtual memory. Fills in the page using CMD_LINE
+ and sets *ESP to the stack pointer. */
diff -u src/vm/page.c~ src/vm/page.c
--- src/vm/page.c~ 1969-12-31 16:00:00.000000000 -0800
+++ src/vm/page.c 2005-06-16 15:09:31.000000000 -0700
-@@ -0,0 +1,297 @@
+@@ -0,0 +1,294 @@
+#include "vm/page.h"
+#include <stdio.h>
+#include <string.h>
+/* Maximum size of process stack, in bytes. */
+#define STACK_MAX (1024 * 1024)
+
++/* Destroys a page, which must be in the current process's
++ page table. Used as a callback for hash_destroy(). */
++static void
++destroy_page (struct hash_elem *p_, void *aux UNUSED)
++{
++ struct page *p = hash_entry (p_, struct page, hash_elem);
++ frame_lock (p);
++ if (p->frame)
++ frame_free (p->frame);
++ free (p);
++}
++
++
+/* Destroys the current process's page table. */
+void
+page_exit (void)
+{
-+ struct hash *h;
-+ struct hash_iterator i;
-+
-+ h = thread_current ()->pages;
-+ if (h == NULL)
-+ return;
-+
-+ hash_first (&i, h);
-+ hash_next (&i);
-+ while (hash_cur (&i))
-+ {
-+ struct page *p = hash_entry (hash_cur (&i), struct page, hash_elem);
-+ hash_next (&i);
-+ frame_lock (p);
-+ if (p->frame)
-+ frame_free (p->frame);
-+ free (p);
-+ }
-+ hash_destroy (h);
++ struct hash *h = thread_current ()->pages;
++ if (h != NULL)
++ hash_destroy (h, destroy_page);
+}
+
+/* Returns the page containing the given virtual ADDRESS,