spt_insert_page() - sihyun10/pintos-lab-vm GitHub Wiki

πŸ› οΈ μ„Έλ²ˆμ§Έ λͺ©ν‘œ - spt_insert_page()ν•¨μˆ˜ κ΅¬ν˜„

이 ν•¨μˆ˜λŠ” μ£Όμ–΄μ§„ supplemental_page_table에 pageλ₯Ό μ‚½μž…ν•˜λŠ” ν•¨μˆ˜μ΄λ‹€.
μ΄λ•Œ 쑰건은, ν•΄λ‹Ή page의 κ°€μƒμ£Όμ†Œ(va)κ°€ 이미 μ‘΄μž¬ν•˜λ©΄ μ‚½μž…ν•˜μ§€ μ•Šκ³ , falseλ₯Ό λ°˜ν™˜ν•œλ‹€.
μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ©΄ μ‚½μž…ν•˜κ³ , trueλ₯Ό λ°˜ν™˜ν•œλ‹€.


  • 가상 μ£Όμ†Œ μœ νš¨μ„± 검사 (is_user_vaddr())
  • page의 vaλ₯Ό ν‚€λ‘œ ν•˜μ—¬ 이미 μ‘΄μž¬ν•˜λŠ” νŽ˜μ΄μ§€κ°€ μžˆλŠ”μ§€ 검사 (spt_find_page())
  • μ—†λ‹€λ©΄ hash_insert()둜 μ‚½μž… μ‹œλ„
  • μ‚½μž… 성곡 μ‹œ true λ°˜ν™˜, μ‹€νŒ¨ μ‹œ false λ°˜ν™˜

κ΅¬ν˜„ μ½”λ“œ

// 검증을 톡해 spt에 PAGEλ₯Ό μ‚½μž…ν•©λ‹ˆλ‹€.
bool spt_insert_page(struct supplemental_page_table *spt UNUSED,
                     struct page *page UNUSED)
{
  int succ = false; // μ‚½μž… 성곡 μ—¬λΆ€λ₯Ό μ €μž₯ν•  λ³€μˆ˜

  if (is_user_vaddr(page->va))
  {
    if (spt_find_page(spt, page->va) == NULL)
    {
      hash_insert(&spt->hash_table, &page->hash_elem);
      succ = true;
    }
  }

  return succ;
}

κ΅¬ν˜„ μ½”λ“œ μ„€λͺ…

bool spt_insert_page(struct supplemental_page_table *spt UNUSED,
                     struct page *page UNUSED)
  • spt : μ‚½μž…ν•  λŒ€μƒ - supplemental_page_table
  • page : μ‚½μž…ν•˜λ €λŠ” νŽ˜μ΄μ§€ 객체

| 가상 μ£Όμ†Œ μœ νš¨μ„± 검사

if (is_user_vaddr(page->va))

μ‚½μž…ν•˜λ €λŠ” νŽ˜μ΄μ§€μ˜ μ£Όμ†Œκ°€ μ‚¬μš©μž 곡간 μ£Όμ†ŒμΈμ§€ ν™•μΈν•œλ‹€.
컀널 μ£Όμ†Œ 곡간을 잘λͺ» λ„£λŠ” 경우λ₯Ό λ°©μ§€ν•œλ‹€.

μ•„λž˜μ˜ is_user_vaddr()λ₯Ό ν™œμš©ν•˜μ—¬ μ‚¬μš©μž 곡간 μ£Όμ†ŒμΈμ§€ κ²€μ‚¬ν•œλ‹€.

// vaκ°€ μœ μ € μ£Όμ†ŒμΈκ°€?
#define is_user_vaddr(vaddr) (!is_kernel_vaddr((vaddr)))

| page의 vaλ₯Ό ν‚€λ‘œ ν•˜μ—¬ 이미 μ‘΄μž¬ν•˜λŠ” νŽ˜μ΄μ§€κ°€ μžˆλŠ”μ§€ 검사

if (spt_find_page(spt, page->va) == NULL)

μš°λ¦¬κ°€ 이전에 κ΅¬ν˜„ν•΄λ‘” spt_find_page()λ₯Ό ν™œμ˜ν•˜μ—¬ ν˜„μž¬ spt에 이미 λ™μΌν•œ vaλ₯Ό κ°€μ§„ νŽ˜μ΄μ§€κ°€ μ‘΄μž¬ν•˜λŠ”μ§€ ν™•μΈν•œλ‹€.
λ§Œμ•½, μ—†λ‹€λ©΄ μ‚½μž… κ°€λŠ₯ν•˜λ‹€!

| μ—†λ‹€λ©΄ hash_insert()둜 μ‚½μž… μ‹œλ„

struct hash_elem *
hash_insert (struct hash *h, struct hash_elem *new) {
  struct list *bucket = find_bucket (h, new);
  struct hash_elem *old = find_elem (h, bucket, new);

  if (old == NULL)
    insert_elem (h, bucket, new);

  rehash (h);

  return old;
}

μœ„ hash_insert() ν•¨μˆ˜λ₯Ό ν™œμš©ν•˜μ—¬ νŽ˜μ΄μ§€μ˜ ν•΄μ‹œ μš”μ†Œλ₯Ό ν•΄μ‹œ ν…Œμ΄λΈ”μ— μ‚½μž…ν•œλ‹€.

hash_insert(&spt->hash_table, &page->hash_elem);
succ = true;

쀑볡 ν‚€κ°€ μ—†λŠ” κ²½μš°μ—λ§Œ μ„±κ³΅ν•œλ‹€.
λ”°λΌμ„œ μ‚½μž…μ— μ„±κ³΅ν–ˆκΈ°μ— succλ₯Ό true둜 λ°”κΏ”μ€€λ‹€.