Beispiel #1
0
/* Swap in a page on disk or on swap space, or initilize a zero page*/
bool swap_in (struct frame_struct *pframe)
{
  struct block *device;
  size_t length = pframe->length;
  block_sector_t sector_no = pframe->sector_no;
  uint32_t pos = pframe->flag & POSBITS;
  uint32_t is_all_zero = pframe->flag & FS_ZERO;

  /* Get a frame, from memory or by evict another frame */
  uint8_t *kpage = palloc_get_page (PAL_USER | PAL_ZERO);

  if (kpage == NULL)
  {
    /* Evict to get a frame */
    kpage = sup_pt_evict_frame ();
    if (kpage == NULL)
    {
      return false;
    }
  }
   
  /* If zero page, just write a page of 0's */
  if (is_all_zero)
  {
    memset (kpage, 0, PGSIZE);
    sup_pt_set_swap_in (pframe, kpage);
    return true;
  } 

  /* On disk */
  if (pos == POS_DISK)
  {
    /* Register filesys as block device */
    device = fs_device;
    /* Whether a newly loaded exec file page
       or a swapped out mem-mapped file page
       they are not dirty */
    pframe->flag &= ~FS_DIRTY;
  }
  /* On swap */
  else if (pos == POS_SWAP)
  {
    /* Register swap as block device */
    device = sp_device;
  }
  else
  {
    /* Already in memeory, other processes race to swap_in the frame */
    palloc_free_page (kpage);
    return false;
  }

  if (device == fs_device)
    lock_acquire (&glb_lock_filesys);
  else 
    lock_acquire (&glb_lock_swapsys);

  /* Read from disk or swap */
  block_sector_t i;
  for (i = 0; i < PGSIZE / BLOCK_SECTOR_SIZE; i++)
  {
    block_read (device, sector_no + i, kpage + BLOCK_SECTOR_SIZE * i); 
  }

  if (device == fs_device)
    lock_release (&glb_lock_filesys);
  else 
    lock_release (&glb_lock_swapsys);  

  /* Set remaining of the page to 0, only necessary for disk */
  if ((length < PGSIZE) && (device == fs_device))
    memset (kpage + length, 0, PGSIZE - length);
  
  /* Free swap table entries */
  if (device == sp_device)
   {
    lock_acquire (&swap_set_lock);
    bitmap_set_multiple (swap_free_map, sector_no,
			   PGSIZE / BLOCK_SECTOR_SIZE, false);
    lock_release (&swap_set_lock);
   }

  /* Update sup_pt entry information */
  sup_pt_set_swap_in (pframe, kpage);
  return true;
}
Beispiel #2
0
/* Makes CNT sectors starting at SECTOR available for use. */
void free_map_release (disk_sector_t sector, size_t cnt)
{
  ASSERT (bitmap_all (free_map, sector, cnt));
  bitmap_set_multiple (free_map, sector, cnt, false);
  bitmap_write (free_map, free_map_file);
}