예제 #1
0
/*! Obtain a frame, either through palloc() or through eviction */
struct frame_table_entry *obtain_frame(enum palloc_flags flag, 
                                       struct supp_table *pte) {
    void *page;
    struct frame_table_entry *newframe;

    page = palloc_get_page(flag);
    if (!page)
        page = frame_evict(flag);
    if (!page) 
        PANIC("run out of frames!\n");

    /*! Allocate a frame table entry and initialize it */
    newframe = (struct frame_table_entry *)\
               malloc(sizeof(struct frame_table_entry));
    if (!newframe)
        PANIC("malloc failure\n");
    newframe->physical_addr = page;
    newframe->owner = thread_current();
    newframe->spt = pte;
    if (f_table.lock.holder != thread_current())
        lock_acquire(&f_table.lock);
    list_push_back(&f_table.table, &newframe->elem);
    lock_release(&f_table.lock);
    return newframe;
}
예제 #2
0
/*
 * Searches for a free frame and returns one if available.
 * If all frames are full, evict a frame and return pointer to evicted frame.
 */
void*
frame_get_free() {
    lock_acquire_re(&vm_lock);
    log_debug("+++ frame_get_free (used: %d, own used: %d) +++\n", frametable.used, frametable.own_used);
    // TODO
    if (frametable.used < frametable.size) {
        // some free frames left
        while(1) {
            if (frametable.frametable[frametable.search_ptr].pte == NULL) {
                // FIXME reserve entry by changing pointer
                frametable.frametable[frametable.search_ptr].pte = (void*) 0xFFFFFFFF;
                frametable.used++;
                void* tmp = pagenum_to_page(frametable.search_ptr);
                log_debug("### Free page at 0x%08x ###\n", (uint32_t) tmp);
                lock_release_re(&vm_lock);
                return tmp;
            }
            // jump to next position
            frametable.search_ptr = (frametable.search_ptr + 1) % frametable.size;
        }
    } else {
        // no free frames left
        // evict frame
        void *tmp = frame_evict();
        lock_release_re(&vm_lock);
        return tmp;
    }
    NOT_REACHED();
    return NULL;
}
예제 #3
0
/* Given a virtual address (page) find a frame to put the page in and return 
   the physical address of the frame */
void*
frame_obtain (enum palloc_flags flags, void* uaddr)
{
  struct frame_table_entry* fte;
  /* Try and obtain frame in user memory */
  void *kaddr = palloc_get_page (flags);

  
  /* Successfully obtained frame */
  if (kaddr != NULL)
    {
      /* Create new frame table entry mapping the given page to the 
         allocated frame */
      fte = (struct frame_table_entry *) malloc 
                (sizeof (struct frame_table_entry));

      fte->owner = thread_current ();
      fte->kaddr = kaddr;
      fte->uaddr = pg_round_down (uaddr);

      lock_acquire (&frame_table_lock);
      list_push_front (&frame_table, &fte->elem);
      lock_release (&frame_table_lock);

      return fte->kaddr;
    }

  /* Failed to obtain frame */
  else
    {
      /* Perform eviction to release a frame and try allocation again */
      if (PAGE_EVICTION)
      {
        return frame_evict (uaddr);
      }
      else
      {
        PANIC ("Failed to allocate frame - eviction disabled.");
      }
    }

}
예제 #4
0
void *
frame_alloc (enum palloc_flags flags, struct SP_entry *page_entry)
{
    if ((flags & PAL_USER) == 0) {
        return NULL;
    }
    void *frame = palloc_get_page (flags);
    if (frame) {
        frame_add (frame, page_entry);
    } else {
        while (!frame) {
            frame = frame_evict (flags);
        }
        if (!frame) {
            PANIC ("Frame evict failed. Swap is full!");
        }
        frame_add (frame, page_entry);
    }
    return frame;
}