示例#1
0
文件: swap.c 项目: gjc13/ucore_os_lab
int
swap_out(struct mm_struct *mm, int n, int in_tick)
{
     int i;
     for (i = 0; i != n; ++ i)
     {
          uintptr_t v;
          //struct Page **ptr_page=NULL;
          struct Page *page;
          // cprintf("i %d, SWAP: call swap_out_victim\n",i);
          int r = sm->swap_out_victim(mm, &page, in_tick);
          if (r != 0) {
                  cprintf("i %d, swap_out: call swap_out_victim failed\n",i);
                  break;
          }          
          //assert(!PageReserved(page));

          //cprintf("SWAP: choose victim page 0x%08x\n", page);
          
          v=page->pra_vaddr; 
          pte_t *ptep = get_pte(mm->pgdir, v, 0);
          assert((*ptep & PTE_P) != 0);

          //Lab3_X: 2013011509
          //Only write back if dirty
          if (page->need_write_back) {
              if (swapfs_write((page->pra_vaddr / PGSIZE + 1) << 8, page) !=
                  0) {
                  cprintf("SWAP: failed to save\n");
                  sm->map_swappable(mm, v, page, 0);
                  continue;
              } else {
                  cprintf(
                      "swap_out: i %d, store page in vaddr 0x%x to disk swap "
                      "entry %d\n",
                      i, v, page->pra_vaddr / PGSIZE + 1);
                  *ptep = (page->pra_vaddr / PGSIZE + 1) << 8;
                  free_page(page);
                  page->has_backup = 1;
              }
          } else {
              *ptep = (page->pra_vaddr / PGSIZE + 1) << 8;
              free_page(page);
          }
          tlb_invalidate(mm->pgdir, v);
     }
     return i;
}
示例#2
0
// page_launder - try to move page to swap_active_list OR swap_inactive_list, 
//              - and call swap_fs_write to swap out pages in swap_inactive_list
int
page_launder(void) {
    size_t maxscan = nr_inactive_pages, free_count = 0;
    list_entry_t *list = &(inactive_list.swap_list), *le = list_next(list);
    while (maxscan -- > 0 && le != list) {
        struct Page *page = le2page(le, swap_link);
        le = list_next(le);
        if (!(PageSwap(page) && !PageActive(page))) {
            panic("inactive: wrong swap list.\n");
        }
        swap_list_del(page);
        if (page_ref(page) != 0) {
            swap_active_list_add(page);
            continue ;
        }
        swap_entry_t entry = page->index;
        if (!try_free_swap_entry(entry)) {
            if (PageDirty(page)) {
                ClearPageDirty(page);
                swap_duplicate(entry);
                if (swapfs_write(entry, page) != 0) {
                    SetPageDirty(page);
                }
                mem_map[swap_offset(entry)] --;
                if (page_ref(page) != 0) {
                    swap_active_list_add(page);
                    continue ;
                }
                if (PageDirty(page)) {
                    swap_inactive_list_add(page);
                    continue ;
                }
                try_free_swap_entry(entry);
            }
        }
        free_count ++;
        swap_free_page(page);
    }
    return free_count;
}