コード例 #1
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;
}
コード例 #2
0
ファイル: frame.c プロジェクト: linearhw/pintos
/* 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;
}