Example #1
0
static bool 
install_page (void *upage, void *kpage, bool writable)
{
  struct thread *t = thread_current ();
  return (pagedir_get_page (t->pagedir, upage) == NULL
          && pagedir_set_page (t->pagedir, upage, kpage, writable));
}
Example #2
0
File: page.c Project: henryxlau/OS
bool page_load(struct page *p, void *fp_addr)
{
	lock_acquire(&load);
	p->kpage = get_frame(PAL_USER);

	lock_release(&load);
	set_page_frame(p->kpage, p);

	pin_frame(p->kpage);

	if(p->kpage == NULL)
	{
		unpin_frame(p->kpage);
		return false;
	}

	bool temp = true;

	if(p->type == S)
	{
		temp = swap_load(p->kpage, p);
	}
	else if(p->type == F)
	{
		temp = file_load(p->kpage, p);
	}
	else
	{
		temp = zero_load(p->kpage);
	}

	if(!temp)
	{
		unpin_frame(p->kpage);
		return false;
	}

	pagedir_clear_page(p->dir, fp_addr);
	if(!pagedir_set_page(p->dir, fp_addr, p->kpage, p->write))
	{
		unpin_frame(p->kpage);
		return false;
	}
	else if(!pagedir_get_page(p->dir, fp_addr))
	{
		unpin_frame(p->kpage);
		return false;
	}

	p->load = true;

	pagedir_set_dirty(p->dir, fp_addr, false);
	pagedir_set_accessed(p->dir, fp_addr, true);

	unpin_frame(p->kpage);

	return true;
}
Example #3
0
static bool
install_page (void *upage, void *kpage, bool writable)
{
  struct thread *t = thread_current ();

  /* Verify that there's not already a page at that virtual
     address, then map our page there. */
  return (pagedir_get_page (t->pagedir, upage) == NULL
          && pagedir_set_page (t->pagedir, upage, kpage, writable));
}
Example #4
0
bool add_mapping(void *upage,void *kpage, bool writable,bool setdirty){
  lock_acquire(&framelock);
  
  struct thread *t = thread_current ();
  /* Verify that there's not already a page at that virtual
     address, then map our page there. */
 
  bool status= (pagedir_get_page (t->pagedir, upage) == NULL
		&& pagedir_set_page (t->pagedir, upage, kpage, writable));
  if(status){
    if(setdirty) pagedir_set_dirty(t->pagedir,upage,true);
    add_list(kpage,upage);
  }
  lock_release(&framelock);
  return status;
  
}
Example #5
0
/* Adds a mapping from user virtual address UPAGE to kernel
   virtual address KPAGE to the page table.
   If WRITABLE is true, the user process may modify the page;
   otherwise, it is read-only.
   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. */
bool
install_page (void *upage, void *kpage, bool writable)
{
  struct thread *t = thread_current ();

  /* Verify that there's not already a page at that virtual
     address, then map our page there. */

  bool pageset = false;
  bool isnull = (pagedir_get_page (t->pagedir, upage) == NULL);
  
  if(isnull)
     pageset = pagedir_set_page (t->pagedir, upage, kpage, writable);

if(DBG)printf("pageset boolean in install page = %d\n", pageset);
if(DBG)printf("isnull boolean in install page = %d\n", isnull);

  return (isnull && pageset);
}
Example #6
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;

}
Example #7
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");
}
Example #8
0
/*! Obtains and returns a group of PAGE_CNT contiguous free pages starting at
    START_ADDR.  If PAL_USER is set, the pages are obtained from the user pool,
    otherwise from the kernel pool.  If PAL_ZERO is set in FLAGS, then the pages
    are filled with zeros.  If PAL_PIN is set in FLGAS, then the pages are
    pinned.  If too few pages are available, returns a null pointer, unless 
    PAL_ASSERT is set in FLAGS, in which case the kernel panics.  If LOAD_TYPE
    is ZERO_PAGE, then the page data pointer is set to NULL, otherwise it is set
    to the passed pointer DATA.  If LOAD_TYPE is FILE_PAGE, the page's file
    offset is set to F_OFS. */
void *palloc_make_multiple_addr(void * start_addr,
                                enum palloc_flags flags,
                                size_t page_cnt,
                                enum page_load load_type,
                                void *data,
                                void *f_ofs) {

    struct list *alloc_page_list;
    uint32_t i;
    struct thread *t = thread_current();
    uint32_t *pagedir;
    uint32_t *pte;
    void *vaddr;
    void *curr_f_ofs = f_ofs;

    /* Page data should not be in a frame. */
    if (load_type == FRAME_PAGE) {
        /* TODO: case where it is in a frame. */
        ASSERT(false);
    }

    /* Use to correct pool based on whether it is paging data or not. */
    if (flags & PAL_PAGING) {
        alloc_page_list = init_page_dir_sup;
        pagedir = init_page_dir;
    } else {
        alloc_page_list = &(t->page_entries);
        pagedir = t->pagedir;
    }

    /* If block at specified address is not open, return NULL. */
    if (!palloc_block_open(start_addr, page_cnt)) {
        if (flags & PAL_ASSERT) {
            PANIC("palloc: out of pages");
        }
        return NULL;
    }

    /* Allocate all pages for the block. */
    for (i = 0; i < page_cnt; i++) {

        /* Create a supplemental entry for the page. */
        struct page_entry *page_i = get_page_entry();

        ASSERT (page_i != NULL);

        /* Get the virtual address for the page. */
        vaddr = (uint8_t *) (start_addr + (i * PGSIZE)) + PGSIZE * 1000;

        /* Initialize the page. */
        page_i->vaddr = vaddr;
        page_i->source = load_type;

        if (load_type == ZERO_PAGE) {
            page_i->data = NULL;
        }
        else {
            page_i->data = data;
        }

        if (load_type == FILE_PAGE) {
            /* Get the file offset. */
            curr_f_ofs += PGSIZE;
            page_i->f_ofs = curr_f_ofs;
        }
        else {
            page_i->f_ofs = NULL;
        }
        
        /* Add to list of allocated pages in order by address. */
        list_insert_ordered(alloc_page_list, &(page_i->elem), 
                            palloc_page_less, NULL);

        if (flags & PAL_USER) {
            pagedir_set_page(pagedir, vaddr, 0, !(flags & PAL_READO));
        } else {
            if(!pagedir_set_page_kernel(pagedir, vaddr, 0, !(flags & PAL_READO))) {
                if (flags & PAL_ASSERT) {
                    PANIC("palloc: out of pages");
                }
                return NULL;
            }
        }
        
        pte = lookup_page(pagedir, vaddr, false);

        /* Pin the page if necessary. */
        if (flags & PAL_PIN) {
           *pte = *pte | PTE_PIN;
        }
        
    }
    return start_addr;
}