Skip to content

Commit

Permalink
Merge pull request #144 from hangpark/develop
Browse files Browse the repository at this point in the history
Release v3.1.1
  • Loading branch information
hangpark authored May 21, 2017
2 parents c2d696c + 962da68 commit b86209d
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 51 deletions.
4 changes: 2 additions & 2 deletions src/userprog/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ process_exit (void)
{
struct process_mmap *mmap = list_entry (e, struct process_mmap, elem);
e = list_next (e);
unmap_mmap_item (mmap);
mmap_unmap_item (mmap);
}
#endif

Expand Down Expand Up @@ -643,7 +643,7 @@ load_segment (struct file *file, off_t ofs, uint8_t *upage,

#ifdef VM
if (!suppl_pt_set_file (upage, file, ofs, page_read_bytes,
page_zero_bytes, writable))
page_zero_bytes, writable, false))
return false;
#else
/* Get a page of memory. */
Expand Down
20 changes: 17 additions & 3 deletions src/userprog/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,8 @@ syscall_mmap (int fd, void *addr)
{
size_t read_bytes = (size_t) ofs + PGSIZE < size ? PGSIZE : size - ofs;
size_t zero_bytes = PGSIZE - read_bytes;
if (!suppl_pt_set_file (addr + ofs, f, ofs, read_bytes, zero_bytes, true))
if (!suppl_pt_set_file (addr + ofs, f, ofs, read_bytes, zero_bytes,
true, true))
{
fault_ofs = ofs;
goto fail;
Expand Down Expand Up @@ -463,14 +464,27 @@ syscall_munmap (mapid_t mapping)
struct process_mmap *mmap = process_get_mmap (mapping);
if (mmap == NULL)
return;
unmap_mmap_item (mmap);
mmap_unmap_item (mmap);
}

/* Wirtes data back to the original file with given offset. */
off_t
mmap_write_back (struct file *file, void *kpage, off_t ofs)
{
lock_acquire (&filesys_lock);
file = file_reopen (file);
if (file == NULL)
return -1;
off_t writes_byte = file_write_at (file, kpage, PGSIZE, ofs);
lock_release (&filesys_lock);
return writes_byte;
}

/* Unmaps the mapping, which must be a mapping ID returned by
a previous call to mmap by the same process that has not yet
been unmapped. */
void
unmap_mmap_item (struct process_mmap *mmap)
mmap_unmap_item (struct process_mmap *mmap)
{
ASSERT (pg_ofs (mmap->addr) == 0);

Expand Down
6 changes: 4 additions & 2 deletions src/userprog/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@
#define USERPROG_SYSCALL_H

#ifdef VM
#include "process.h"
#include "filesys/off_t.h"
#include "userprog/process.h"
#endif

void syscall_init (void);
void syscall_exit (int);

#ifdef VM
void unmap_mmap_item (struct process_mmap *);
off_t mmap_write_back (struct file *, void *kpage, off_t);
void mmap_unmap_item (struct process_mmap *);
#endif

#endif /* userprog/syscall.h */
58 changes: 33 additions & 25 deletions src/vm/frame.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,16 @@
#include "vm/swap.h"

/* Frame table lock. */
struct lock frame_table_lock;
static struct lock frame_table_lock;

/* Frame table. */
struct list frame_table;
static struct list frame_table;

#ifdef VM_CLOCK
/* Current frame table position. */
struct list_elem *frame_table_pos;
static struct list_elem *frame_table_pos;
#endif

/* Frame table element. */
struct frame
{
void *kpage; /* Kernel page maps to the frame. */
struct suppl_pte *suppl_pte; /* Supplemental page table entry. */
struct list_elem elem; /* List element. */
};

static struct frame *frame_evict_and_get (void);
#ifdef VM_CLOCK
static struct frame *frame_to_evict_clock (void);
Expand All @@ -53,7 +45,7 @@ frame_table_init (void)
/* Allocates a new user frame with given pte and flags.
Note that this method is used only for that user frame flag
is set. */
void *
struct frame *
frame_alloc (struct suppl_pte *pte, enum palloc_flags flags)
{
ASSERT (pte != NULL);
Expand All @@ -73,9 +65,11 @@ frame_alloc (struct suppl_pte *pte, enum palloc_flags flags)
}
f->suppl_pte = pte;

list_remove (&f->elem);

lock_release (&frame_table_lock);

return f->kpage;
return f;
}

f = malloc (sizeof (struct frame));
Expand All @@ -88,11 +82,17 @@ frame_alloc (struct suppl_pte *pte, enum palloc_flags flags)

f->kpage = kpage;
f->suppl_pte = pte;
list_push_back (&frame_table, &f->elem);

lock_release (&frame_table_lock);

return kpage;
return f;
}

/* Appends the frame entry into the frame table. */
void
frame_append (struct frame *frame)
{
list_push_back (&frame_table, &frame->elem);
}

/* Returns frame associated KPAGE. Returns NULL if failed. */
Expand Down Expand Up @@ -120,21 +120,17 @@ frame_search (void *kpage)
/* Frees the given frame at kpage.
If such frame exists in the frame table, remove it. */
void
frame_free (void *kpage)
frame_free (struct frame *frame)
{
lock_acquire (&frame_table_lock);

struct frame *f = frame_search (kpage);
if (f != NULL)
{
#ifdef VM_CLOCK
if (&f->elem == frame_table_pos)
frame_table_pos = list_next (frame_table_pos);
if (&frame->elem == frame_table_pos)
frame_table_pos = list_next (frame_table_pos);
#endif
list_remove (&f->elem);
free (f);
}
palloc_free_page (kpage);
list_remove (&frame->elem);
free (frame);
palloc_free_page (frame->kpage);

lock_release (&frame_table_lock);
}
Expand Down Expand Up @@ -182,6 +178,13 @@ frame_evict_and_get (void)
case PAGE_FILE:
if (!pte->writable)
break;
if (pte->mmap)
{
if (!suppl_pt_update_dirty (pte))
break;
if (mmap_write_back (pte->file, pte->kpage, pte->ofs) == -1)
return NULL;
}

case PAGE_ZERO:
if (!suppl_pt_update_dirty (pte))
Expand Down Expand Up @@ -216,6 +219,7 @@ static struct frame *
frame_next_circ (void)
{
ASSERT (!list_empty (&frame_table));
ASSERT (lock_held_by_current_thread (&frame_table_lock));

struct list_elem *next;
if (frame_table_pos == list_back (&frame_table)
Expand All @@ -233,6 +237,8 @@ frame_next_circ (void)
static struct frame *
frame_to_evict_clock (void)
{
ASSERT (lock_held_by_current_thread (&frame_table_lock));

struct frame *f;
for (f = frame_next_circ ();
pagedir_is_accessed (f->suppl_pte->pagedir, f->suppl_pte->upage);
Expand All @@ -248,6 +254,8 @@ frame_to_evict_clock (void)
static struct frame *
frame_to_evict_fifo (void)
{
ASSERT (lock_held_by_current_thread (&frame_table_lock));

struct frame *f = list_entry (list_begin (&frame_table), struct frame, elem);
list_remove (&f->elem);
list_push_back (&frame_table, &f->elem);
Expand Down
13 changes: 11 additions & 2 deletions src/vm/frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,18 @@
#include "threads/palloc.h"
#include "vm/page.h"

/* Frame table element. */
struct frame
{
void *kpage; /* Kernel page maps to the frame. */
struct suppl_pte *suppl_pte; /* Supplemental page table entry. */
struct list_elem elem; /* List element. */
};

void frame_table_init (void);
void *frame_alloc (struct suppl_pte *, enum palloc_flags);
void frame_free (void *kpage);
struct frame *frame_alloc (struct suppl_pte *, enum palloc_flags);
void frame_free (struct frame *);
void frame_remove (void *kpage);
void frame_append (struct frame *);

#endif /* vm/frame.h */
31 changes: 18 additions & 13 deletions src/vm/page.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ suppl_pt_set_zero (void *upage)
Note that this does not involve actual frame allocation. */
bool
suppl_pt_set_file (void *upage, struct file *file, off_t ofs,
uint32_t read_bytes, uint32_t zero_bytes, bool writable)
uint32_t read_bytes, uint32_t zero_bytes,
bool writable, bool mmap)
{
if (suppl_pt_get_page (upage) != NULL)
return false;
Expand All @@ -81,6 +82,7 @@ suppl_pt_set_file (void *upage, struct file *file, off_t ofs,
pte->read_bytes = read_bytes;
pte->zero_bytes = zero_bytes;
pte->writable = writable;
pte->mmap = mmap;

struct suppl_pt *pt = thread_current ()->suppl_pt;
hash_insert (&pt->hash, &pte->elem);
Expand All @@ -99,8 +101,8 @@ suppl_pt_load_page (void *upage)
return false;

/* Obtain a new frame. */
void *kpage = frame_alloc (pte, PAL_USER);
if (kpage == NULL)
struct frame *f = frame_alloc (pte, PAL_USER);
if (f == NULL)
return false;

/* Load page content for each page type. */
Expand All @@ -109,27 +111,27 @@ suppl_pt_load_page (void *upage)
{
/* Page filled with zeros. */
case PAGE_ZERO:
memset (kpage, 0, PGSIZE);
memset (f->kpage, 0, PGSIZE);
break;

/* Page content from the file system. */
case PAGE_FILE:
file_seek (pte->file, pte->ofs);
if (file_read (pte->file, kpage, pte->read_bytes)
if (file_read (pte->file, f->kpage, pte->read_bytes)
!= (int) pte->read_bytes)
{
frame_free (kpage);
frame_free (f);
return false;
}
memset (kpage + pte->read_bytes, 0, pte->zero_bytes);
memset (f->kpage + pte->read_bytes, 0, pte->zero_bytes);
writable = pte->writable;
break;

/* Page content from the swap disk. */
case PAGE_SWAP:
if (!swap_in (kpage, pte->swap_index))
if (!swap_in (f->kpage, pte->swap_index))
{
frame_free (kpage);
frame_free (f);
return false;
};
break;
Expand All @@ -140,17 +142,20 @@ suppl_pt_load_page (void *upage)
}

/* Install upage to kpage. */
if (!pagedir_set_page (pte->pagedir, upage, kpage, writable))
if (!pagedir_set_page (pte->pagedir, upage, f->kpage, writable))
{
frame_free (kpage);
frame_free (f);
return false;
}

/* Set dirty value of kernel page to false. */
pagedir_set_dirty (pte->pagedir, kpage, false);
pagedir_set_dirty (pte->pagedir, f->kpage, false);

/* Append result to supplemental page table. */
pte->kpage = kpage;
pte->kpage = f->kpage;

/* Append frame entry to the frame table. */
frame_append (f);

return true;
}
Expand Down
3 changes: 2 additions & 1 deletion src/vm/page.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ struct suppl_pte
uint32_t read_bytes; /* Read bytes. */
uint32_t zero_bytes; /* Zero bytes. */
bool writable; /* Writable flag. */
bool mmap; /* Memory mapped file. */
};
struct /* Only for page type PAGE_SWAP. */
{
Expand All @@ -52,7 +53,7 @@ void suppl_pt_destroy (struct suppl_pt *);

bool suppl_pt_set_zero (void *upage);
bool suppl_pt_set_file (void *upage, struct file *, off_t, uint32_t read_bytes,
uint32_t zero_bytes, bool writable);
uint32_t zero_bytes, bool writable, bool mmap);
bool suppl_pt_load_page (void *upage);
struct suppl_pte *suppl_pt_get_page (void *upage);
void suppl_pt_clear_page (void *upage);
Expand Down
Loading

0 comments on commit b86209d

Please sign in to comment.