示例#1
0
文件: page.c 项目: henryxlau/OS
void page_unload(struct page *p, void *fp_addr)
{
	if (p->type == F)
	{
		if(pagedir_is_dirty(p->dir, p->f_addr))
		{
			pin_frame(p->kpage);

			file_seek(p->f, p->ofs);
			file_write(p->f, fp_addr, p->read);

			unpin_frame(p->kpage);
		}
	}
	else if(p->type == S)
	{
		p->type = S;
		p->swap_index = store_swap(fp_addr);
	}
	else if(pagedir_is_dirty(p->dir, p->f_addr))
	{
		p->swap_index = store_swap(fp_addr);
		p->type = S;
	}

	p->load = false;
	p->kpage = NULL;

	pagedir_clear_page(p->dir, p->f_addr);
}
示例#2
0
文件: frame.c 项目: chutchUCD/OS
/**
 * Allocate a new frame,
 * and return the address of the associated page.
 */
void*
vm_frame_allocate (enum palloc_flags flags, void *upage)
{
  lock_acquire (&frame_lock);

  void *frame_page = palloc_get_page (PAL_USER | flags);
  if (frame_page == NULL) {
    // page allocation failed.

    /* first, swap out the page */
    struct frame_table_entry *f_evicted = pick_frame_to_evict( thread_current()->pagedir );

#if DEBUG
    printf("f_evicted: %x th=%x, pagedir = %x, up = %x, kp = %x, hash_size=%d\n", f_evicted, f_evicted->t,
        f_evicted->t->pagedir, f_evicted->upage, f_evicted->kpage, hash_size(&frame_map));
#endif
    ASSERT (f_evicted != NULL && f_evicted->t != NULL);

    // clear the page mapping, and replace it with swap
    ASSERT (f_evicted->t->pagedir != (void*)0xcccccccc);
    pagedir_clear_page(f_evicted->t->pagedir, f_evicted->upage);

    bool is_dirty = false;
    is_dirty = is_dirty || pagedir_is_dirty(f_evicted->t->pagedir, f_evicted->upage);
    is_dirty = is_dirty || pagedir_is_dirty(f_evicted->t->pagedir, f_evicted->kpage);

    swap_index_t swap_idx = vm_swap_out( f_evicted->kpage );
    vm_supt_set_swap(f_evicted->t->supt, f_evicted->upage, swap_idx);
    vm_supt_set_dirty(f_evicted->t->supt, f_evicted->upage, is_dirty);
    vm_frame_do_free(f_evicted->kpage, true); // f_evicted is also invalidated

    frame_page = palloc_get_page (PAL_USER | flags);
    ASSERT (frame_page != NULL); // should success in this chance
  }

  struct frame_table_entry *frame = malloc(sizeof(struct frame_table_entry));
  if(frame == NULL) {
    // frame allocation failed. a critical state or panic?
    lock_release (&frame_lock);
    return NULL;
  }

  frame->t = thread_current ();
  frame->upage = upage;
  frame->kpage = frame_page;
  frame->pinned = true;         // can't be evicted yet

  // insert into hash table
  hash_insert (&frame_map, &frame->helem);
  list_push_back (&frame_list, &frame->lelem);

  lock_release (&frame_lock);
  return frame_page;
}
示例#3
0
void do_munmap(struct mmap_file *mmap_file)
{
	struct list_elem *e = list_begin(&mmap_file->vme_list);
	struct list_elem *next;
	struct vm_entry *entry;
	struct thread *t = thread_current();
	//printf("do_mumap start\n");
	while(e != list_end(&mmap_file->vme_list)) 
	{	next = list_next(e);

		entry = list_entry(e,struct vm_entry,mmap_elem);
		entry->pinned = true;
		if(entry->is_loaded)                             // is_loaded true -> page free, false-> pass
		{
			if(pagedir_is_dirty(t->pagedir,entry->vaddr)) // dirty -> write, no dirty -> pass
			{
				lock_acquire(&file_lock);
				file_write_at(entry->file,entry->vaddr,
					entry->read_bytes,entry->offset);
				lock_release(&file_lock);
			}

			free_page(pagedir_get_page(t->pagedir,
						entry->vaddr));
			pagedir_clear_page(t->pagedir,entry->vaddr);
		}
		list_remove(e);                                  // remove element on vme_list
		delete_vme(&t->vm,entry);                        // remove element on vm (hash)
		free(entry);

		e = next;
	}
	//printf("mummap end\n");
}
示例#4
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;
        }
    }
}
示例#5
0
/*! Memory ummap according the given mapid. */
void munmap(mapid_t mapping){
    
    uint32_t f_size, write_bytes, page_write_size, pws2;
    off_t ofs = 0;
    struct list_elem *e;
    struct supp_table* st;
    
    /* First find the mmap struct according to the given mapid. */
    struct mmap_elem *me = find_mmap_elem(mapping);
    struct thread* t = thread_current();
    
    /* Get the file length. And set write_bytes as file length.*/
    f_size = file_length(me->file);
    write_bytes = f_size;
    
    /* Freeing all the pages in this mmap struct. */
    while (!list_empty(&me->s_table)) {
        e = list_pop_front(&me->s_table);
        st = list_entry(e, struct supp_table, map_elem);
        if (st->fr) {
            /* Set up how many bytes is going to be freed in this page. */
            if (write_bytes >= PGSIZE)
                page_write_size = PGSIZE;
            else
                page_write_size = write_bytes;

            /* If the page is dirty, then write back the data to the file. */
            if (pagedir_is_dirty(t->pagedir, st->upage)){

                lock_acquire(&filesys_lock);
                pws2 = file_write_at(st->file, st->fr->physical_addr, 
                                                st->read_bytes, st->ofs);
                lock_release(&filesys_lock);
                ASSERT(pws2 == page_write_size);
            }
            
            /* Update the offset for file writing.*/
            ofs += page_write_size;
            /* Update remaining write_bytes.*/
            write_bytes -= page_write_size;
        }
        /* Destroy the freed supplemental page entry.*/
        spte_destructor_func(&(st->elem), NULL);
    }

    /* Close the file. */
    file_close(me->file);
    /* Remove the mmap struct from the mmap list of this process. */
    list_remove(&(me->elem));
    /* Free the memory of this struct. */
    free(me);
}
示例#6
0
struct list_elem* first_clean(){
  
      struct list_elem *e;

      for (e = list_rbegin (&framelist); e != list_rend (&framelist);
           e = list_prev(e))
        {
          struct frame *f = list_entry(e, struct frame , elem);
	  /* printf(" first clean %p %p \n ",f->upage,f->kpage); */
	  if(!pagedir_is_dirty(thread_current()->pagedir,f->upage) && f->thread==thread_current())
	    return e;
	  
        }
      return NULL;
}
示例#7
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);
        }
    }
}
示例#8
0
文件: page.c 项目: ktk1012/OOOS
/**
 * \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);
}
示例#9
0
文件: frame.c 项目: coweatyou/school
/* Evicts the page held in F. */
void evict(struct frame *f) {
	uint32_t *pd = thread_current()->pagedir;
    
  ASSERT(lock_held_by_current_thread(&f->evicting));
//  lock_acquire(&f->page->moving); /* You should never block here. */
  ASSERT(f->page != NULL);
  ASSERT(lock_held_by_current_thread(&f->page->moving));

	/* Clear page to prevent further writes. */
	pagedir_clear_page(f->page->thread->pagedir, f->page->vaddr);

	/* If the page had been written to, the changes must be saved. */
	if(pagedir_is_dirty(f->page->thread->pagedir, f->page->vaddr)) {
		if(f->page->status == PAGE_MAPPED) {
			/* If the page is mapped, write changes back to file. */
			bool have_lock = lock_held_by_current_thread(&fs_lock);

			if(!have_lock)
				lock_acquire(&fs_lock);
			if(file_write_at(f->page->file, f->addr, f->page->read_bytes, f->page->ofs) != f->page->read_bytes)
				PANIC("Didn't write expected %d bytes.", f->page->read_bytes);
			if(!have_lock)
				lock_release(&fs_lock);

		} else {
			/* Write page to swap. */
			ASSERT(pagedir_is_writeable(f->page->thread->pagedir, f->page->vaddr));
			ASSERT(f->page->writeable);
			swap_out(f);
		}
	}

	/* Unset link the page and frame. */
	f->page->current_frame = NULL;
	lock_release(&f->page->moving);
	f->page = NULL;
}
示例#10
0
void evict(){
 
  /* struct list_elem* e= first_clean(); */
  /* printf("thread %d ,waiting for flock",thread_current()->tid); */
  lock_acquire(&framelock);
 
  struct list_elem* e= list_front(&framelist);
  struct frame *f = list_entry(e, struct frame , elem);
   bool lock_held=lock_held_by_current_thread(&f->thread->SPT_lock);
   /* printf("framelock acquired %d %d current:%d \n",f->thread->tid,lock_held,thread_current()->tid);     */
   ASSERT(!lock_held) 
      lock_acquire(&f->thread->SPT_lock);
    /* printf("Evict called by %d ,evicted thread,%d evicted address %p and lock_held=%d and after acquire=%d\n",thread_current()->tid,f->thread->tid,f->upage,lock_held,lock_held_by_current_thread(&f->thread->SPT_lock)); */
  if (pagedir_is_dirty(f->thread->pagedir,f->upage))
  /* if(e==NULL) */
  {
     
      ASSERT(f!=NULL);
      /* printf("sector %d \n",sector); */
      struct page_data *p = SPT_lookup(f->upage,f->thread);
      if(p!=NULL){
	
	if(p->loc==mmap1)
	  {
	    printf("removing2\n");
		  write_back_map(f->upage,p->file,p->offset);	
		  remove_mapping(f->upage,f->kpage,e,f->thread); 
		  lock_release(&framelock);
		   if(!lock_held)lock_release(&f->thread->SPT_lock);
		   return;
	  }
	else
	  {
	    ASSERT(p->loc!=swap);
	    SPT_remove(p->vaddr,f->thread);
	  }
      }
      int sector= write_page_to_swap(f->kpage);
      /* printf("evicton 4 \n"); */
      struct page_data *p1= malloc(sizeof(struct page_data));
      p1->loc= swap;
      p1->vaddr=f->upage;
      p1->block_sector=sector;
      SPT_insert(p1,f->thread);
      
      /* printf("evicton 5 \n"); */
      /* printf("in evic3 %p , %p thread: %d\n", f->upage,f->kpage,f->thread->tid); */
      remove_mapping(f->upage,f->kpage,e,f->thread); 
    }
  else
    {
      /* printf("found a non dirty page \n"); */
      remove_mapping(f->upage,f->kpage,e,f->thread); 
    }

  /* printf("evict end%d and lock held =%d,lock_held2=%d \n",thread_current()->tid,lock_held_by_current_thread(&f->thread->SPT_lock),lock_held); */
 
    lock_release(&f->thread->SPT_lock);

  lock_release(&framelock);
  /* PANIC("OUT OF MEMORY"); */
}
示例#11
0
static void sys_munmap(int mapid)
{
  struct thread *curr = thread_current();
  struct list_elem *e;
  struct mapped_file_elem *mapped_elem=NULL;
  int check_valid = 0;
//  printf("start munmap\n");
  if(mapid<2)
  {
//    lock_release(&process_lock);
//    mmap_lock_release();
    return -1;
//    sys_exit(-1);
  }
  for( e = list_begin(&curr->mapfile_list) ; e != list_end(&curr->mapfile_list) ;
      e = list_next(e) )
  {
    mapped_elem=list_entry(e,struct mapped_file_elem,elem_m);
    if(mapped_elem->mapid==mapid)
    {
//      printf("yes here is\n");
      check_valid=1;
      break;
    }
  }
//  printf("here?\n");
  if(check_valid==0)
  {
//    lock_release(&process_lock);
//    mmap_lock_release();
    return -1;
//    sys_exit(-1);
  }
//  printf("here?\n");
  int read_bytes = mapped_elem->size;
//  printf("before real\n");
  struct hash_iterator i;
  hash_first(&i,&curr->pages);
//  frame_lock_acquire();
//  printf("start real\n");
  while( hash_next(&i) )
  {
    struct page *pa = hash_entry( hash_cur(&i), struct page, hash_elem);
    struct list_elem *e_f;
    struct frame_elem *f=NULL;
    if(pa->mapid == mapped_elem->mapid)
    {
//      printf("find this\n");
      for(e_f = list_begin( &frame_table ) ; e_f != list_end( &frame_table) ;
          e_f = list_next (e_f) )
      {
        f = list_entry( e_f ,struct frame_elem , elem);
        if(f->vaddr == pa->vaddr)
        {
//          printf("find frame too\n");
          break;
        }
      }
      if( pagedir_is_dirty(curr->pagedir,pa->vaddr) )
      {
//        printf("omg\n");
        if(mapped_elem != NULL)
        {
//          printf("here\n");
//          printf("aaa%s\n",f->paddr);
          file_seek( mapped_elem->mapped_file, pa->offset);
//          printf("should be 0 %d\n",pa->offset);
          file_write( mapped_elem->mapped_file, f->paddr ,PGSIZE);
        }
      }
//      frame_lock_acquire();
      pagedir_clear_page(curr->pagedir , pa->vaddr);
//      printf("here?\n");
      frame_free_page( f->paddr);
//      printf("here ???\n");
      page_free(pa->vaddr);
//      printf("here??????\n");
      hash_first(&i,&curr->pages);
//      frame_lock_release();
    }
  }
  file_seek( mapped_elem->mapped_file, 0);
  list_remove(&mapped_elem->elem_m);
//  free(mapped_elem->name);
  free(mapped_elem);
//  printf("munmap finish\n");
//    mmap_lock_release();
//  frame_lock_release();
}
示例#12
0
void sys_exit(int status)
{
  struct thread *curr=thread_current();
  struct thread *parent=curr->parent;
  struct child_list_elem *child_elem;
  struct list_elem *e;
  printf("%s: exit(%d)\n",curr->name,status);
  for( e= list_begin(&parent->child_list) ; e != list_end(&parent->child_list) 
      ; e = list_next(e) )
  {
    child_elem=list_entry(e,struct child_list_elem,elem_w);
    if(child_elem->tid==curr->tid)
    { 
      child_elem->exit_status[0]=1;
      child_elem->exit_status[1]=status;
    }
  }
  while(!list_empty( &curr->mapfile_list ) )
  {
//    printf("gogo~\n");
    struct list_elem *e = list_pop_front(&curr->mapfile_list);
//    printf("%d\n",list_entry(e,struct mapped_file_elem, elem_m)->mapid);
    struct mapped_file_elem *mapped_elem = 
      list_entry(e,struct mapped_file_elem,elem_m);
//    sys_munmap(mapped_elem->mapid);
    struct hash_iterator i;
    hash_first(&i,&curr->pages);
    //  printf("start real\n");
    while( hash_next(&i) )
    {
//      printf("dddd\n");
      struct page *pa = hash_entry( hash_cur(&i), struct page, hash_elem);
      struct list_elem *e_f;
      struct frame_elem *f=NULL;
      if(pa->mapid == mapped_elem->mapid)
      {
//        printf(" %s mapid : %d\n",curr->name,pa->mapid);
        //      printf("find this\n");
        for(e_f = list_begin( &frame_table ) ; e_f != list_end( &frame_table) ;
            e_f = list_next (e_f) )
        {
          f = list_entry( e_f ,struct frame_elem , elem);
          if(f->vaddr == pa->vaddr)
          {
            //          printf("find frame too\n");
            break;
          }
        }
        if( pagedir_is_dirty(curr->pagedir,pa->vaddr) )
        {
          //        printf("omg\n");
          if(mapped_elem != NULL)
          {
            //          printf("here\n");
            //          printf("aaa%s\n",f->paddr);
            file_seek( mapped_elem->mapped_file, pa->offset);
            //          printf("should be 0 %d\n",pa->offset);
            file_write( mapped_elem->mapped_file, f->paddr ,PGSIZE);
          }
        }
        frame_lock_acquire();
        pagedir_clear_page(curr->pagedir , pa->vaddr);
        //      printf("here?\n");
        //      printf("here ???\n");
        page_free(pa->vaddr);
        frame_free_page( f->paddr);
        frame_lock_release();
        //      printf("here??????\n");
        //sys_munmap(mapped_elem->mapid);
        hash_first(&i,&curr->pages);
      }
    }
    file_seek( mapped_elem->mapped_file, 0);
    list_remove(&mapped_elem->elem_m);
    //  free(mapped_elem->name);
    free(mapped_elem);
  }

 
  thread_exit();
}