Ejemplo n.º 1
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");
}
Ejemplo n.º 2
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);

}
Ejemplo n.º 3
0
Archivo: page.c Proyecto: 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);
}
Ejemplo n.º 4
0
Archivo: frame.c Proyecto: gypintos/np4
void *fm_allocate (enum palloc_flags flags, bool lock) {
  lock_acquire(&frame_table_lock);
  void *kaddr = palloc_get_page(PAL_USER | flags);
  struct frame *fm;
  if (kaddr == NULL){
    fm = select_fm();
    fm->isPinned = true;
    fm->locked = lock;
    kaddr = fm->k_addr;
    struct hash *ht_thread_uaddr = &fm->ht_thread_uaddr;
    hash_first(&fm->iter_htu, ht_thread_uaddr);
    struct thread_uaddr *thread_uaddr;
    while (hash_next(&fm->iter_htu)){
      thread_uaddr = hash_entry(hash_cur(&fm->iter_htu), struct thread_uaddr, elem);
      struct page* p = find_page(thread_uaddr->uaddr, thread_uaddr->t);
      p->isLoaded = false;
      pagedir_clear_page(thread_uaddr->t->pagedir, p->vaddr);
      if (p->type == STACK){
        page_to_swap(p);
      } else if (p->type == SEGMENT){
        if (p->writable && (if_fm_dirty(fm) || p->isDirty)){
          p->isDirty = true;
          page_to_swap(p);
        }
      } else {
        write_mmap_page_to_file(p);
      }
    }
    hash_clear(&fm->ht_thread_uaddr, remove_thread_uaddr);
  } else {
Ejemplo n.º 5
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);
}
Ejemplo n.º 6
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;
        }
    }
}
Ejemplo n.º 7
0
Archivo: page.c Proyecto: 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;
}
Ejemplo n.º 8
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);
}
Ejemplo n.º 9
0
Archivo: frame.c Proyecto: 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;
}
Ejemplo n.º 10
0
static void 
spage_hash_remove (struct hash_elem *e, void *aux)
{
  struct spage_table_entry *spte = hash_entry (e, struct spage_table_entry, elem);
  struct thread *t = thread_current ();
  if (spte->in_memory)
    {
      frame_free (pagedir_get_page (t->pagedir, spte->upage));
      pagedir_clear_page (t->pagedir, spte->upage);
    }
  free (spte);
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
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);
}
Ejemplo n.º 13
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);
        }
    }
}
Ejemplo n.º 14
0
Archivo: page.c Proyecto: 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);
}
Ejemplo n.º 15
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;
}
Ejemplo n.º 16
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);
}
Ejemplo n.º 17
0
/* 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;
}
Ejemplo n.º 18
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();
}
Ejemplo n.º 19
0
void frame_remove(struct frame_table_entry* fte) {
	list_remove(&fte->elem);
	palloc_free_page(fte->kpg_vaddr);
	pagedir_clear_page(fte->owner->pagedir, fte->pg_vaddr);
	free(fte);
}
Ejemplo n.º 20
0
void*
frame_evict (void* uaddr)
{

  /* 1. Choose a frame to evict, using your page replacement algorithm.
        The "accessed" and "dirty" bits in the page table, described below, 
        will come in handy. */
  struct frame_table_entry *fte = NULL;
  switch (PAGE_EVICTION_ALGORITHM)
  {
    /* First in first out */
    case PAGE_EVICTION_FIFO:
      fte = frame_evict_choose_fifo ();
      break;

    /* Second chance */
    case PAGE_EVICTION_SECONDCHANCE:
      fte = frame_evict_choose_secondchance ();
      break;

    default:
      PANIC ("Invalid eviction algorithm choice.");
  }
  ASSERT (fte != NULL);


  /* 2. Remove references to the frame from any page table that refers to it.
        Unless you have implemented sharing, only a single page should refer to
        a frame at any given time. */
  pagedir_clear_page (fte->owner->pagedir, pg_round_down (fte->uaddr));


  /* 3. If necessary, write the page to the file system or to swap.
        The evicted frame may then be used to store a different page. */
  struct page *p_evict = 
      page_lookup (fte->owner->pages, pg_round_down (fte->uaddr));
  if (p_evict == NULL)
        PANIC ("Failed to get supp page for existing page.");

  /* Page to be evicted is in swap */
  if (p_evict->page_location_option == FILESYS)
    {
      if (p_evict->writable)
        {
          file_write_at (p_evict->file, fte->kaddr, p_evict->page_read_bytes,
              p_evict->ofs);
        }
    }
  else if (p_evict->page_location_option == ALLZERO)
    {
      // All zero, so can just be overwritten
    }
  else
    {
      // From stack
      int index = swap_to_disk (pg_round_down (fte->uaddr));
      
      /* Creates a supp page and insert it into pages. */
      struct page *p = page_create ();

      if (p == NULL)
        PANIC ("Failed to get supp page for swap slot.");

      p->addr = fte->uaddr;
      p->page_location_option = SWAPSLOT;
      p->swap_index = index;
      page_insert (fte->owner->pages, &p->hash_elem);
    }

  /* Replace virtual address with new virtual address */
  fte->owner = thread_current ();
  fte->uaddr = uaddr;

  /* Reinsert the frame table entry into the frame table */
  lock_acquire (&frame_table_lock);
  list_remove (&fte->elem);
  list_push_front (&frame_table, &fte->elem);
  lock_release (&frame_table_lock);

  return fte->kaddr;
}
Ejemplo n.º 21
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();
}