コード例 #1
0
bool 
spage_table_load (struct spage_table_entry *spte, enum spage_types type)
{
  // P3: reduce race condition with frame eviction process.
  spte->inevictable = true;

  if (spte->in_memory) return false;

  if (type == SWAP)
    {
      uint8_t *f = frame_alloc (PAL_USER, spte);
      if (!f) return false;

      if (!install_page (spte->upage, f, spte->writable))
	{
	  frame_free (f);
	  return false;
	}

      swap_in (spte->swap_slot_id, spte->upage);
      spte->in_memory = true;
    }
  
  if (type == FILE || type == MMAP)
    {
      enum palloc_flags fg = PAL_USER;
      if (spte->file_read_bytes == 0) fg |= PAL_ZERO;

      uint8_t *f = frame_alloc (fg, spte);
      if (!f) return false;

      if (spte->file_read_bytes > 0)
	{
	  lock_acquire (&lock_f);
	  if ((int) spte->file_read_bytes != file_read_at (spte->file, f, spte->file_read_bytes,
							   spte->file_offset))
	    {
	      lock_release (&lock_f);
	      frame_free (f);
	      return false;
	    }
	  lock_release (&lock_f);
	  memset (f + spte->file_read_bytes, 0, spte->file_zero_bytes);
	}
      
      if (!install_page (spte->upage, f, spte->writable))
	{
	  frame_free (f);
	  return false;
	}
      
      spte->in_memory = true;  
    }
  
  return true;
}
コード例 #2
0
ファイル: page.c プロジェクト: ktk1012/OOOS
/**
 * \page_load_demand
 * \Load page on demand (call only fault occurred)
 *
 * \param   spte  Supplemental page table that fault occurred
 * \param   paddr physical address to be mapped
 *
 * \retval  true  if success
 * \retval  false if failed
 */
bool
page_load_demand (struct page_entry *spte, void *paddr)
{
	/* Read read_bytes from offset written in spte */
	if (file_read_at (spte->file, paddr, spte->read_bytes, spte->ofs)
	    != (int) spte->read_bytes)
		return false;

	/* Add zero padding */
	memset (paddr + spte->read_bytes, 0, spte->zero_bytes);

	/* Set this page is loaded in memory */
	spte->is_loaded = true;

	/* Install vaddr and paddr mapping into pagedir */
	return install_page (spte->vaddr, paddr, spte->writable);
}
コード例 #3
0
ファイル: syscall.c プロジェクト: jchen2caltech/pintos-cz
/*! Read from file */
int read(uint32_t fd, void *buffer, unsigned size) {
    uint8_t* addr_e;
    struct supp_table* st;
    
    /* Check the validity of given pointer */
    if ((!checkva(buffer)) || (!checkva(buffer + size))){
        exit(-1);
    }
    
    for (addr_e = (uint8_t*) pg_round_down(buffer); 
         addr_e < (uint8_t*) buffer + size; addr_e += PGSIZE){
        st = find_supp_table(addr_e);
        if (st && !st->writable)
            exit(-1);
    }
    
    int read_size = 0;
    if (fd == STDIN_FILENO) {
        /* If std-in, then read using input_getc() */
        unsigned i;
        for (i = 0; i < size; i++){
            *((uint8_t*) buffer) = input_getc();
            ++ read_size;
            ++ buffer;
        }
    } else {
        /* Otherwise, first find the file of this fd. */
        struct f_info* f = findfile(fd);
        
        /* We should read a dir like a file. */
        if (f->isdir)
            exit(-1);
        
        struct file* fin = f->f;
        off_t pos = f->pos;
        
        /* Read from the file at f->pos */
        //lock_acquire(&filesys_lock);
        read_size = (int) file_read_at(fin, buffer, (off_t) size, pos);
        f->pos += (off_t) read_size;
        //lock_release(&filesys_lock);
        
    }
    return read_size;

}
コード例 #4
0
ファイル: page.c プロジェクト: saranghattikar/Projects
/**
 * Loads the frame associated with the given virtual page with actual data either
 * from associated file or swapped disk or just zeroes
 */
bool load_frame_with_data (struct supplementary_page_table_entry *page)
{
  // Allocate given supplementary page table entry -> a new physical memory frame
  page->supplementary_frame_in_memory = allot_frame_for_page_in_memory (page);
  // No frames are avaible - or unable to evict any frame
  if (page->supplementary_frame_in_memory == NULL)
  {
    return false;
  }

  // if this page is associated with any file
  if (page->sup_file != NULL)
  {
    // Read rw_bytes into the physical frame
    off_t read_bytes = file_read_at (
        page->sup_file,
        page->supplementary_frame_in_memory->base_vir_address,
        page->rw_bytes,
        page->file_offset);

    // Copy this bytes into physical memory frame
    memset (page->supplementary_frame_in_memory->base_vir_address + read_bytes,
        0, PGSIZE - read_bytes);

    if (read_bytes != page->rw_bytes)
    {
      printf ("the number of bytes read are (%"PROTd") != number of bytes "
      "requested are (%"PROTd")\n", read_bytes, page->rw_bytes);
    }
  // Else check if physical frame was swapped to disk
  } else if (page->area_swap != (block_sector_t) -1)
  {
    // If yes, swap it back into physical frame memory
    swap_page_in_from_disk_to_frame (page);
  // Else write zeroes to the frame memory
  } else
  {
    memset (page->supplementary_frame_in_memory->base_vir_address, 0, PGSIZE);
  }

  // Return the operation status - i.e. it was successful
  return true;
}
コード例 #5
0
static int sys_mmap( int fd, void *vaddr )
{
  struct thread *curr = thread_current();
  struct list_elem *e;
  struct opened_file_elem *opened_elem;
  int check_valid = 0;
  int count = 0;
//  mmap_lock_acquire();
//  printf("read bytes : %d\n",read_bytes);
//  printf("aa\n");
  if(vaddr==0)
  {
//    mmap_lock_release();
   return -1;
  }
//  printf("%p\n",(int)vaddr&0xfff);
  if( ((int)vaddr & 0xfff) !=0 || ( (int)vaddr>=PHYS_BASE -8*1024*1024 &&
        (int)vaddr <=PHYS_BASE )  )
  {
//    printf("misalign\n");
//    mmap_lock_release();
    return -1;
  }
  struct page *check_page = page_lookup(curr,vaddr);
  if( check_page!=NULL&& (check_page->writable == 0 || check_page->type==p_file) )
  {
//    mmap_lock_release();
    return -1;
  }
  if(fd<2)
  {
//    mmap_lock_release();
    return -1;
  }
  for( e = list_begin(&curr->openfile_list) ; e != list_end(&curr->openfile_list) ;
      e = list_next(e) )
  {
    opened_elem=list_entry(e,struct opened_file_elem,elem_f);
    if(opened_elem->fd==fd)
    {
      check_valid=1;
      break;
    }
  }
  if(check_valid==0)
  {
//    mmap_lock_release();
    return -1;
  }
  for( e = list_begin(&curr->mapfile_list) ; e != list_end(&curr->mapfile_list) ;
      e = list_next(e) )
  {
//    printf("check\n");
    struct mapped_file_elem* mapped_elem=list_entry(e,struct mapped_file_elem,elem_m);
//    printf("%d\n",mapped_elem->size);
    if(  mapped_elem->vaddr<=vaddr && 
        vaddr<=mapped_elem->vaddr+mapped_elem->size)
    {
//    mmap_lock_release();
      return -1;
    }
    
  }
  struct mapped_file_elem *mapped_elem = (struct mapped_file_elem*)
    malloc(sizeof(struct mapped_file_elem));
//  char *name = (char*)malloc(strlen(opened_elem->name));
//  strlcpy(name, opened_elem->name , strlen(opened_elem->name)+1);
  int read_bytes = file_length(opened_elem->opened_file);
  mapped_elem->mapped_file = opened_elem->opened_file;
  mapped_elem->vaddr = vaddr;
  mapped_elem->size = read_bytes;
  mapped_elem->mapid = opened_elem->fd;
//  mapped_elem->name = name;
  list_push_back(&curr->mapfile_list,&mapped_elem->elem_m);
//  printf("mapid: %d\n",opened_elem->mapid);
  while(read_bytes >0)
  {
//    frame_lock_acquire();
    int page_read_bytes = read_bytes<PGSIZE ? read_bytes:PGSIZE;
    //    printf("doing mmap\n");
    //    printf(" read bytes: %d\n",read_bytes);
    page_allocate(vaddr, true, p_mmap, page_read_bytes,
        PGSIZE-read_bytes, count*PGSIZE, mapped_elem->mapid);
    //    printf("mapid : %d\n",page_lookup(curr,vaddr)->mapid);
    if(page_read_bytes < PGSIZE)
    {
      void *kpage=frame_elem_allocate(vaddr,true,PAL_USER);
      file_read_at( mapped_elem->mapped_file, kpage, page_read_bytes, count*PGSIZE );
      pagedir_set_page( thread_current()->pagedir,vaddr,kpage,true );
    }
    count+=1;
    read_bytes-=PGSIZE;
    vaddr+=PGSIZE;

//    frame_lock_release();
  }
//  printf(" page allocate num:%d\n",count);
//  printf("mmap finish\n");
//    mmap_lock_release();
  return mapped_elem->mapid;

}
コード例 #6
0
static void sys_close(int fd)
{
  struct thread *curr = thread_current();
  struct list_elem *e;
  struct list_elem *e_m;
  struct opened_file_elem *opened_elem;
  struct mapped_file_elem *mapped_elem;
  int check_valid=0;
  int check_map=0;
  int check_frame=0;
  int count=0;
//  printf("close start\n");
  if(fd<2)
  {
    lock_release(&process_lock);
    sys_exit(-1);
  }
  for( e = list_begin(&curr->openfile_list) ; e != list_end(&curr->openfile_list) ;
      e = list_next(e) )
  {
    opened_elem=list_entry(e,struct opened_file_elem,elem_f);
    if(opened_elem->fd==fd)
    {
      check_valid=1;
      break;
    }
  }
  for( e_m = list_begin(&curr->mapfile_list) ; e_m != list_end(&curr->mapfile_list) ;
      e_m = list_next(e_m) )
  {
    mapped_elem=list_entry(e_m,struct mapped_file_elem,elem_m);
    if(mapped_elem->mapid==fd)
    {
      check_map=1;
      break;
    }
  }
//  printf("%d clos!\n",fd);
//  printf("pick\n");
  if(check_map!=0)
  {
//    printf("find\n");
    struct hash_iterator i;
    hash_first(&i,&curr->pages);

    while(hash_next(&i))
    {
      //    printf("lazy mapping\n");
      struct page *pa = hash_entry( hash_cur(&i), struct page, hash_elem);
      struct list_elem *e_f;
      struct frame_elem *f;
      if(pa->mapid == mapped_elem->mapid )
      {
        for(e = list_begin( &frame_table ) ; e != list_end( &frame_table) ;
            e = list_next (e) )
        {
          f = list_entry( e,struct frame_elem , elem);
          if(f->vaddr == pa->vaddr)
          {
            check_frame=1;
            break;
          }
        }
        if( check_frame==0 )
        {
          int read_bytes = file_length(opened_elem->opened_file);
//          printf("adsfmlakdfmkl\n");
          while(read_bytes>0)
          {
//            frame_lock_acquire();
            int page_read_bytes = read_bytes<PGSIZE ? read_bytes:PGSIZE;
            void *kpage = frame_elem_allocate(pa->vaddr, true,PAL_USER|PAL_ZERO);
            pagedir_set_page(curr->pagedir, pa->vaddr, kpage, true);
            file_read_at( opened_elem->opened_file, kpage , page_read_bytes, pa->offset+count*PGSIZE);
            count+=1;
            read_bytes-=PGSIZE;
//            frame_lock_release();
          }
        }
      }
    }
  }

  if(check_valid==1)
  {
    list_remove(&opened_elem->elem_f);
    file_close(opened_elem->opened_file);
//    free(opened_elem->name);
    free(opened_elem);
  }
  if(check_valid==0)
  {
    lock_release(&process_lock);
    sys_exit(-1);
  }
//  printf("close succeed\n");
}