Beispiel #1
0
bool from_file (struct spage_entry *se)
{
  struct thread *t = thread_current ();

  struct file *file = se->myfile;
  off_t ofs = se->ofs;
  uint8_t upage = se->upage;
  uint32_t read_bytes = se->read_bytes;
  uint32_t zero_bytes = se->zero_bytes;
  bool writable = se->writable;

  ASSERT ((read_bytes + zero_bytes) % PGSIZE == 0);
  ASSERT (pg_ofs (upage) == 0);
  ASSERT (ofs % PGSIZE == 0);

//  lock_acquire (&filesys_lock);
  file_seek (file, ofs);
//  lock_release (&filesys_lock);

  if ( !(read_bytes > 0 || zero_bytes > 0) )
    return false; 
    
      /* Calculate how to fill this page.
         We will read PAGE_READ_BYTES bytes from FILE
         and zero the final PAGE_ZERO_BYTES bytes. */  
      size_t page_read_bytes = read_bytes < PGSIZE ? read_bytes : PGSIZE;
      size_t page_zero_bytes = PGSIZE - page_read_bytes;

      /* Get a page of memory. */  
      uint8_t *kpage = palloc_get_page (PAL_USER);
      if (kpage == NULL)
        return false;

      /* Load this page. */  
//      lock_acquire (&filesys_lock);
      if (file_read (file, kpage, page_read_bytes) != (int) page_read_bytes)
        {
//          lock_release (&filesys_lock);
          palloc_free_page (kpage);
          return false; 
        }
//          lock_release (&filesys_lock);
      memset (kpage + page_read_bytes, 0, page_zero_bytes);

      /* Add the page to the process's address space. */  
      if (!install_page (upage, kpage, writable)) 
        {
          palloc_free_page (kpage);
          return false; 
        }

  return true;
}
Beispiel #2
0
void frame_free(void *frame){
	struct list_elem *e;

	lock_acquire(&frame_table_lock);
	for(e= list_begin(&frame_table);
			e!= list_end(&frame_table);
			e= list_next(e))
	{

		//searh 함수 만들기

		struct frame_entry *f= list_entry(e, struct frame_entry, elem);

		if(f->frame == frame)
		{

			list_remove(e);
			free(f);
			palloc_free_page(frame);
			break;
		}

	}

	lock_release(&frame_table_lock);


}
Beispiel #3
0
/* Open system call. */
static int
sys_open (const char *ufile) 
{
  char *kfile = copy_in_string (ufile);
  struct file_descriptor *fd;
  int handle = -1;
 
  fd = calloc (1, sizeof *fd);
  if (fd != NULL)
    {
      struct inode *inode = filesys_open (kfile);
      if (inode != NULL)
        {
          if (inode_get_type (inode) == FILE_INODE)
            fd->file = file_open (inode);
          else
            fd->dir = dir_open (inode);
          if (fd->file != NULL || fd->dir != NULL)
            {
              struct thread *cur = thread_current ();
              handle = fd->handle = cur->next_handle++;
              list_push_front (&cur->fds, &fd->elem);
            }
          else 
            {
              free (fd);
              inode_close (inode);
            }
        }
    }
  
  palloc_free_page (kfile);
  return handle;
}
Beispiel #4
0
/* Open system call. */
static int
sys_open (const char *ufile) 
{
  char *kfile = copy_in_string (ufile);
  struct file_descriptor *fd;
  int handle = -1;
 
  fd = malloc (sizeof *fd);
  if (fd != NULL)
    {
      lock_acquire (&fs_lock);
      fd->file = filesys_open (kfile);
      if (fd->file != NULL)
        {
          struct thread *cur = thread_current ();
          handle = fd->handle = cur->next_handle++;
          list_push_front (&cur->fds, &fd->elem);
        }
      else 
        free (fd);
      lock_release (&fs_lock);
    }
  
  palloc_free_page (kfile);
  return handle;
}
Beispiel #5
0
void* frame_victim (enum palloc_flags flag)
{

	lock_acquire(&frame_table_lock);


	struct list_elem *e= list_begin(&frame_table);

//list_
	
	
	victim_frame=list_pop_front(&frame_table);
	if(victim_frame ==NULL)
	{
	}
	else
	{
		victim_frame->page->valid=false;
		pagedir_clear_page(victim_frame->thread->pagedir, victim_frame->page->vaddr);
		palloc_free_page(victim_frame->frame);
		return palloc_get_page(flag);
	}

	lock_release(&frame_table_lock);

}
Beispiel #6
0
/**
 * An (internal, private) method --
 * Deallocates a frame or page (internal procedure)
 * MUST BE CALLED with 'frame_lock' held.
 */
void
vm_frame_do_free (void *kpage, bool free_page)
{
  ASSERT (lock_held_by_current_thread(&frame_lock) == true);
  ASSERT (is_kernel_vaddr(kpage));
  ASSERT (pg_ofs (kpage) == 0); // should be aligned

  // hash lookup : a temporary entry
  struct frame_table_entry f_tmp;
  f_tmp.kpage = kpage;

  struct hash_elem *h = hash_find (&frame_map, &(f_tmp.helem));
  if (h == NULL) {
    PANIC ("The page to be freed is not stored in the table");
  }

  struct frame_table_entry *f;
  f = hash_entry(h, struct frame_table_entry, helem);

  hash_delete (&frame_map, &f->helem);
  list_remove (&f->lelem);

  // Free resources
  if(free_page) palloc_free_page(kpage);
  free(f);
}
Beispiel #7
0
void do_free_page (struct page *page)
{
	page->vme->is_loaded = false;
	del_page_from_lru_list(page);
	pagedir_clear_page(page->thread->pagedir, page->vme->vaddr);
	palloc_free_page(page->kaddr);
	free(page);
}
Beispiel #8
0
/*! Use the clock algorithm to select a frame to evict and execute the
    eviction. */
void * frame_evict(enum palloc_flags flag) {
    struct list_elem *ce;
    struct thread *ct;
    struct frame_table_entry *cf;
    int i;
    
    if (f_table.lock.holder != thread_current())
        lock_acquire(&f_table.lock);    /* Get frame table lock */
    if (list_empty(&f_table.table)) {
        lock_release(&f_table.lock);    /* Nothing to evict */
        return NULL;
    }
    f_table.hand = f_table.hand % list_size(&f_table.table);
    ce = list_begin(&f_table.table);    /* Begin iteration */
    for (i = 0; i < f_table.hand; i++) {
        /* Find where the "hand" points to: that is where the 
           iteration starts */
        ce = list_next(ce);
    }
    while (true) {
        cf = list_entry(ce, struct frame_table_entry, elem);
        ct = cf->owner;
        if (!cf->spt->pinned) {
            /* If pinned, skip this frame */
            if (pagedir_is_accessed(ct->pagedir, cf->spt->upage))
                /* If accessed, clear accessed bit */
                pagedir_set_accessed(ct->pagedir, cf->spt->upage, false);
            else {
                /* Swap out the page! */
                if (cf->spt->type != SPT_MMAP) {
                    cf->spt->fr = NULL;
                    cf->spt->type = SPT_SWAP;
                    cf->spt->swap_index = swap_out(cf->physical_addr);
                }
                /* Write the frame back to the map'd file */
                else if (cf->spt->type == SPT_MMAP &&
                         pagedir_is_dirty(ct->pagedir, cf->spt->upage)) {
                    cf->spt->fr = NULL;
                    file_write_at(cf->spt->file, cf->physical_addr, 
                                  cf->spt->read_bytes, cf->spt->ofs);
                }
                /* Clear the frame */
                list_remove(ce);
                pagedir_clear_page(ct->pagedir, cf->spt->upage);
                palloc_free_page(cf->physical_addr);
                free(cf);
                lock_release(&f_table.lock);
                return palloc_get_page(flag);
            }
        }
        ce = list_next(ce);
        ++f_table.hand;
        if (ce == list_end(&f_table.table)) { /* Iterate circularly */
            ce = list_begin(&f_table.table);
            f_table.hand = 0;
        }
    }
}
void remove_mapping(void *upage, void *kpage, struct list_elem *e,struct thread *t){
  /* printf("bool %d \n",list_empty(&framelist)); */
  list_remove(e);
  /* printf("list size %d \n",list_size(&framelist)); */
 
  /* printf("are we here %p ]\n" ,upage); */
  pagedir_clear_page(t->pagedir,upage);
  palloc_free_page(kpage);
}
Beispiel #10
0
/* Remove system call. */
static int
sys_remove (const char *ufile) 
{
  char *kfile = copy_in_string (ufile);
  bool ok = filesys_remove (kfile);
  palloc_free_page (kfile);
 
  return ok;
}
Beispiel #11
0
/* Create system call. */
static int
sys_create (const char *ufile, unsigned initial_size) 
{
  char *kfile = copy_in_string (ufile);
  bool ok = filesys_create (kfile, initial_size, FILE_INODE);
  palloc_free_page (kfile);
 
  return ok;
}
Beispiel #12
0
/* Loads a segment starting at offset OFS in FILE at address
   UPAGE.  In total, READ_BYTES + ZERO_BYTES bytes of virtual
   memory are initialized, as follows:

        - READ_BYTES bytes at UPAGE must be read from FILE
          starting at offset OFS.

        - ZERO_BYTES bytes at UPAGE + READ_BYTES must be zeroed.

   The pages initialized by this function must be writable by the
   user process if WRITABLE is true, read-only otherwise.

   Return true if successful, false if a memory allocation error
   or disk read error occurs. */
static bool
load_segment (struct file *file, off_t ofs, uint8_t *upage,
              uint32_t read_bytes, uint32_t zero_bytes, bool writable) 
{
  ASSERT ((read_bytes + zero_bytes) % PGSIZE == 0);
  ASSERT (pg_ofs (upage) == 0);
  ASSERT (ofs % PGSIZE == 0);

  file_seek (file, ofs);
  while (read_bytes > 0 || zero_bytes > 0) 
    {
      /* Calculate how to fill this page.
         We will read PAGE_READ_BYTES bytes from FILE
         and zero the final PAGE_ZERO_BYTES bytes. */
      size_t page_read_bytes = read_bytes < PGSIZE ? read_bytes : PGSIZE;
      size_t page_zero_bytes = PGSIZE - page_read_bytes;

      /* Get a page of memory. */
      uint8_t *kpage = palloc_get_page (PAL_USER);
      if (kpage == NULL)
        return false;

      /* Load this page. */
      if (file_read (file, kpage, page_read_bytes) != (int) page_read_bytes)
        {
          palloc_free_page (kpage);
          return false; 
        }
      memset (kpage + page_read_bytes, 0, page_zero_bytes);

      /* Add the page to the process's address space. */
      if (!install_page (upage, kpage, writable)) 
        {
          palloc_free_page (kpage);
          return false; 
        }

      /* Advance. */
      read_bytes -= page_read_bytes;
      zero_bytes -= page_zero_bytes;
      upage += PGSIZE;
    }
  return true;
}
Beispiel #13
0
/* Frees the PAGE_CNT pages starting at PAGES. */
void palloc_free_umultiple(void *pages, size_t page_cnt) 
// NOTE: THIS FUNCTION IS NOT CORRECT!!!
{
  size_t i;
  for(i = 0; i < page_cnt; i++)
  {
     void * kpage =lookup_page(thread_current()->pagedir, pages + i * PGSIZE, false);
     palloc_free_page(kpage);
  }
}
Beispiel #14
0
/* Exec system call. */
static int
sys_exec (const char *ufile) 
{
  tid_t tid;
  char *kfile = copy_in_string (ufile);
 
  tid = process_execute (kfile);
 
  palloc_free_page (kfile);
 
  return tid;
}
Beispiel #15
0
void sys_close(int fd) {
  lock_acquire (&filesys_lock);
  struct file_desc* file_d = find_file_desc(thread_current(), fd, FD_FILE | FD_DIRECTORY);

  if(file_d && file_d->file) {
    file_close(file_d->file);
    if(file_d->dir) dir_close(file_d->dir);
    list_remove(&(file_d->elem));
    palloc_free_page(file_d);
  }
  lock_release (&filesys_lock);
}
Beispiel #16
0
/* Release the frame holding the page specified by uaddr */
void
frame_release (void* uaddr)
{
  lock_acquire (&frame_table_lock);

  struct frame_table_entry *fte = frame_lookup_uaddr (uaddr);
  ASSERT (fte != NULL);

  list_remove (&fte->elem);
  palloc_free_page (&fte->uaddr);
  free (fte);
  lock_release (&frame_table_lock);
}
Beispiel #17
0
/* Exec system call. */
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_page (kfile);
 
  return tid;
}
Beispiel #18
0
/* Create system call. */
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_page (kfile);
 
  return ok;
}
Beispiel #19
0
/* Remove system call. */
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_page (kfile);
 
  return ok;
}
Beispiel #20
0
/* Create a minimal stack by mapping a zeroed page at the top of
   user virtual memory. */
static bool
setup_stack (void **esp) 
{
  uint8_t *kpage;
  bool success = false;

  kpage = palloc_get_page (PAL_USER | PAL_ZERO);
  if (kpage != NULL) 
    {
      success = install_page (((uint8_t *) PHYS_BASE) - PGSIZE, kpage, true);
      if (success)
        *esp = PHYS_BASE;
      else
        palloc_free_page (kpage);
    }
  return success;
}
Beispiel #21
0
/* Frees a frame from the physical memory */
void 
frame_free_page (uint32_t *kpage)
{
  struct frame_element *fe = frame_table_find (kpage);

  /* if the frame about to be evicted is pointed at by
     the clock hand, move the clock hand to the next
     frame */
  if (&fe->frame_elem == clock_hand)
      clock_hand = list_next (clock_hand);

  if (fe != NULL)
    {
      list_remove (&fe->frame_elem);
      free (fe);
      palloc_free_page (kpage);
    }
}
Beispiel #22
0
void frame_free(struct frame *f) {
	// here we free the frame held by the process
	lock_acquire(&ftable_lock);
	struct list_elem *elem = list_begin(&frame_list);
	while (elem != list_end(&frame_list)) {
		struct frame *fe = list_entry(elem, struct frame, frame_list_elem);
		if (fe != f) {
			elem = list_next(elem);
			continue;
		}
		// if current process frame that is to be freed is in the list, then remove it from list and free memory
		list_remove(elem);
		pagedir_clear_page(fe->page->frame_holder_thread->pagedir, fe->page->addr);
		palloc_free_page(fe->base); // free the page currently held by the frame
		free(fe); // then free the frame
		break;
	}
	lock_release(&ftable_lock);
}
Beispiel #23
0
/* Evicte random frame */
struct vm_frame *vm_evict_frame(struct supp_page_entry *s){
    ASSERT(!list_empty(&vm_frames_list));

    /* Choose frame - FIFO */
    lock_acquire(&vm_lock); 
    struct list_elem *e = list_front(&vm_frames_list);
    struct vm_frame *victim = list_entry(e, struct vm_frame, elem);
    lock_release(&vm_lock);
   
    /* Settings */
    pagedir_clear_page(victim->thread->pagedir, victim->spte->upage);
    victim->spte->type = S;
    victim->spte->swap_idx = vm_swap_out(victim->page);
    victim->thread = thread_current();
    victim->spte = s;

    palloc_free_page(victim->page);
    return victim;
}
Beispiel #24
0
/* Free's all data associated with the frame with kernel virtual address PG. */
void frame_free(struct frame *f) {
  struct hash_elem *e;
  ASSERT(lock_held_by_current_thread(&f->evicting));

  /* Delete frame from frame table. */
  lock_acquire(&ft_lock);
  ASSERT(hash_delete(&frame_table, &f->elem) != NULL);

	/* Evict page from frame. */
 	if(f->page != NULL)
	  evict(f);
  		
  ASSERT(list_empty(&f->evicting.semaphore.waiters));

	/* Free resources */
	palloc_free_page(f->addr);
  free(f);
  lock_release(&ft_lock);
}
Beispiel #25
0
void *
frame_evict (enum palloc_flags flags)
{
    lock_acquire (&frame_table_lock);
    struct list_elem *e = list_begin (&frame_table);

    while (true) {
        struct frame_entry *frame_entry = list_entry (e, struct frame_entry, elem);
        struct SP_entry *page_entry = frame_entry->page_entry;
        if (!page_entry->pinned) {
            struct thread *t = frame_entry->thread;
            if (pagedir_is_accessed (t->pagedir, page_entry->page)) {
                pagedir_set_accessed (t->pagedir, page_entry->page, false);
            } else {
                if (pagedir_is_dirty (t->pagedir, page_entry->page) ||
                    page_entry->type == SP_SWAP) {
                    if (page_entry->type == SP_MMAP) {
                        lock_acquire (&filesys_lock);
                        file_write_at (page_entry->file, frame_entry->frame,
                                       page_entry->read_bytes,
                                       page_entry->offset);
                        lock_release (&filesys_lock);
                    } else {
                        page_entry->type = SP_SWAP;
                        page_entry->swap_index = swap_out (frame_entry->frame);
                    }
                }
                page_entry->is_loaded = false;
                list_remove (&frame_entry->elem);
                pagedir_clear_page (t->pagedir, page_entry->page);
                palloc_free_page (frame_entry->frame);
                free (frame_entry);
                lock_release (&frame_table_lock);
                return palloc_get_page (flags);
            }
        }
        e = list_next (e);
        if (e == list_end (&frame_table)) {
            e = list_begin (&frame_table);
        }
    }
}
Beispiel #26
0
/**
 * \page_munmap
 * \unmap the page
 *
 * \param   table supplemental page table
 * \param   spte  supplemental page table entry
 * \param   pagedir pagedirectory of corresponding process
 *
 * \retval  void
 */
void
page_munmap (struct hash *table, struct page_entry *spte, void *pagedir)
{
	/* If page is loaded in memory, free it */
	if (spte->is_loaded)
	{
		void *paddr = pagedir_get_page (pagedir, spte->vaddr);
		/* If this page is dirty, write back to file */
		if (pagedir_is_dirty (pagedir, spte->vaddr))
		{
			file_write_at (spte->file, paddr, spte->read_bytes, spte->ofs);
		}
		palloc_free_page (paddr);
	}

	/* Delete entry and set vaddr regin to be not present */
	hash_delete (table, &spte->elem);
	pagedir_clear_page (pagedir, spte->vaddr);
	free (spte);
}
Beispiel #27
0
void *
swap (void)
{
  struct frame_entry *victim_frame = find_victim();
  
  struct spage_entry *victim_spage_entry = victim_frame->spe;
  uint32_t sectornum = swap_out(victim_frame->frame);

  pagedir_clear_page(victim_frame->t->pagedir,victim_spage_entry->uaddr);
  
  victim_spage_entry->indisk = true;
  victim_spage_entry->sec_no = sectornum;
  
  palloc_free_page(victim_frame->frame);
  falloc_free_frame(victim_frame->frame);

  void *kpage = palloc_get_page(PAL_USER|PAL_ZERO);
  ASSERT(kpage != NULL);
  
  return kpage;
}
Beispiel #28
0
int sys_open(const char* file) {
  // memory validation
  check_user((const uint8_t*) file);

  struct file* file_opened;
  struct file_desc* fd = palloc_get_page(0);
  if (!fd) {
    return -1;
  }

  lock_acquire (&filesys_lock);
  file_opened = filesys_open(file);
  if (!file_opened) {
    palloc_free_page (fd);
    lock_release (&filesys_lock);
    return -1;
  }

  fd->file = file_opened; //file save

  // directory handling
  struct inode *inode = file_get_inode(fd->file);
  if(inode != NULL && inode_is_directory(inode)) {
    fd->dir = dir_open( inode_reopen(inode) );
  }
  else fd->dir = NULL;

  struct list* fd_list = &thread_current()->file_descriptors;
  if (list_empty(fd_list)) {
    // 0, 1, 2 are reserved for stdin, stdout, stderr
    fd->id = 3;
  }
  else {
    fd->id = (list_entry(list_back(fd_list), struct file_desc, elem)->id) + 1;
  }
  list_push_back(fd_list, &(fd->elem));

  lock_release (&filesys_lock);
  return fd->id;
}
Beispiel #29
0
/* The implementation of LRU 'clock' algorithm follows.. we make use of the PTE's accessed bit and dirty bit:
 on any read or write to a page  ==> accessed bit = 1;
 on any write ==> dirty bit = 1;

 Step 1: We navigate through the pages in a circular order.. i.e., if we hit the end of the frame list,
 we circle back to the start and continue our processing..

 Step 2: If the accessed bit is 'accessed', turn it to 'not accessed', skip the page and proceed to look-up the next one in the list

 Step 3: If the accessed bit is 'not accessed', we can proceed with our page replacement */
void evict_page() {
	struct list_elem *e;
	int count = 0;
	lock_acquire(&ftable_lock);
	for (e = list_begin(&frame_list); e != list_end(&frame_list);
			e = list_next(e)) {
		struct frame *frame = list_entry(e, struct frame, frame_list_elem);
		// printf ("\n%d , %d", count, list_size(&frame_list) - 1);
		if (count != list_size(&frame_list) - 1) {
			// get the accessed flag for the current page
			bool accessed_flag = pagedir_is_accessed(
					frame->page->frame_holder_thread->pagedir, frame->page->addr);
			if (accessed_flag)
				pagedir_set_accessed(frame->page->frame_holder_thread->pagedir,
						frame->page->addr, !accessed_flag);
			else {
				// we need to page replace.. i.e.,
				// step 1: remove the existing page from the frame (swap_out call)
				// step 2: remove the existing page from the page directory
				// step 3: set the accessed flag of the page to 'accessed'
				// step 4: free the page and free the frame, for subsequent use
				list_remove(e);
				swap_out(frame->page);
				frame->page->swap_flag = 1;
				pagedir_clear_page(frame->page->frame_holder_thread->pagedir,
						frame->page->addr);
				palloc_free_page(frame->base);
				free(frame);
				// frame->page->swap_flag = 1;
				break;
			}
			count++;
		} else {
			count = 0;
			e = list_begin(&frame_list);
		}
	}
	lock_release(&ftable_lock);
}
Beispiel #30
0
/* Creates a copy of user string US in kernel memory
   and returns it as a page that must be freed with
   palloc_free_page().
   Truncates the string at PGSIZE bytes in size.
   Call thread_exit() if any of the user accesses are invalid. */
static char *
copy_in_string (const char *us) 
{
  char *ks;
  char *upage;
  size_t length;
 
  ks = palloc_get_page (0);
  if (ks == NULL) 
    thread_exit ();

  length = 0;
  for (;;) 
    {
      upage = pg_round_down (us);
      if (!page_lock (upage, false))
        goto lock_error;

      for (; us < upage + PGSIZE; us++) 
        {
          ks[length++] = *us;
          if (*us == '\0') 
            {
              page_unlock (upage);
              return ks; 
            }
          else if (length >= PGSIZE) 
            goto too_long_error;
        }

      page_unlock (upage);
    }

 too_long_error:
  page_unlock (upage);
 lock_error:
  palloc_free_page (ks);
  thread_exit ();
}