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

Supplemental Tabel Page κ΅¬ν˜„

κ°€μž₯ λ¨Όμ € κ΅¬ν˜„ν•΄μ•Όν•˜λŠ” 것이 Supplemental Table Page이닀.

기쑴의 page table을 λ³΄μ™„ν•˜κΈ° μœ„ν•΄ λ§Œλ“  κ²ƒμœΌλ‘œ, page듀에 λŒ€ν•΄ 좔가적인 λ°μ΄ν„°λ‘œ νŽ˜μ΄μ§€ ν…Œμ΄λΈ”μ„ λ³΄μ™„ν•˜κΈ° μœ„ν•œ λͺ©μ μ„ κ°€μ§€κ³  μžˆλ‹€.
μ•„λž˜ 2κ°€μ§€ κΈ°λŠ₯을 μˆ˜ν–‰ν•œλ‹€.

  • Page Fault λ°œμƒ μ‹œ 컀널이 sptμ—μ„œ 였λ₯˜κ°€ λ°œμƒν•œ 가상 νŽ˜μ΄μ§€λ₯Ό μ‘°νšŒν•˜μ—¬ μ–΄λ–€ 데이터가 μžˆμ–΄μ•Ό ν•˜λŠ”μ§€ ν™•μΈν•œλ‹€.
  • ν”„λ‘œμ„ΈμŠ€κ°€ μ’…λ£Œλ  λ•Œ 컀널이 sptλ₯Ό μ°Έμ‘°ν•˜μ—¬ μ–΄λ–€ λ¦¬μ†ŒμŠ€λ₯Ό freeμ‹œν‚¬ 것인지 κ²°μ •ν•œλ‹€.

SPT ꡬ쑰체

sptμ—μ„œλŠ” ν”„λ‘œμ„ΈμŠ€κ°€ μš”μ²­ν•œ νŽ˜μ΄μ§€λ“€μ— λŒ€ν•΄μ„œ 물리 νŽ˜μ΄μ§€λ₯Ό ν• λ‹Ήν•˜κΈ° μœ„ν•΄μ„œ ν•΄μ‹œ ν…Œμ΄λΈ” μžλ£Œκ΅¬μ‘°κ°€ μ‚¬μš©λœλ‹€.

struct supplemental_page_table
{
  struct hash hash_table;
};

/* Hash table. */
struct hash {
  size_t elem_cnt;            /* Number of elements in table. */
  size_t bucket_cnt;          /* Number of buckets, a power of 2. */
  struct list *buckets;       /* Array of `bucket_cnt' lists. */
  hash_hash_func *hash;       /* Hash function. */
  hash_less_func *less;       /* Comparison function. */
  void *aux;                  /* Auxiliary data for `hash' and `less'. */
};

ν•΄μ‹œ ν…Œμ΄λΈ”μ€ (key, value)둜 데이터λ₯Ό μ €μž₯ν•˜λŠ” μžλ£Œκ΅¬μ‘°λ‹€.
ν‰κ· μ μœΌλ‘œ 검색/μ‚­μ œ/μ‚½μž…μ΄ O(1)의 μ‹œκ°„λ³΅μž‘λ„λ₯Ό κ°€μ§„λ‹€.
λ”°λΌμ„œ λΉ λ₯΄κ²Œ 데이터λ₯Ό 검색 κ°€λŠ₯ν•˜λ‹€.


πŸ› οΈ 첫번째 λͺ©ν‘œ

vm/vm.cμ—μ„œ struct supplemental_page_table의 자료ꡬ쑰λ₯Ό μ„€κ³„ν•˜κ³ ,
μ΄ˆκΈ°ν™” ν•¨μˆ˜ supplemental_page_table_init()을 κ΅¬ν˜„ν•΄μ•Όν•œλ‹€.

  1. SPT에 μ‚¬μš©ν•  자료ꡬ쑰 섀계 - vm/vm.c

SPTλŠ” 각 μœ μ € ν”„λ‘œμ„ΈμŠ€λ§ˆλ‹€ μ‘΄μž¬ν•˜λŠ” 가상 νŽ˜μ΄μ§€ 정보λ₯Ό μ €μž₯ν•˜λŠ” ν…Œμ΄λΈ”μ΄λ‹€.
νŽ˜μ΄μ§€ ν΄νŠΈκ°€ λ°œμƒν–ˆμ„ λ•Œ, μ–΄λ–€ 데이터λ₯Ό λ‘œλ“œν•΄μ•Ό ν• μ§€, μ–΄λ–€ νƒ€μž…μ˜ νŽ˜μ΄μ§€μΈμ§€ 등을 이 ν…Œμ΄λΈ”μ—μ„œ ν™•μΈν•œλ‹€.

Pintosμ—μ„œλŠ” ν•΄μ‹œ ν…Œμ΄λΈ”μ„ SPT의 기반 자료ꡬ쑰둜 μ‚¬μš©ν•˜λŠ” 것이 μΌλ°˜μ μ΄λ‹€.

struct supplemental_page_table
{
  struct hash hash_table; // ν•΄μ‹œ ꡬ쑰체 μΆ”κ°€
};

hash_table은 νŽ˜μ΄μ§€ μ£Όμ†Œλ₯Ό ν‚€λ‘œ, νŽ˜μ΄μ§€ 정보λ₯Ό κ°’μœΌλ‘œ μ €μž₯ν•˜λŠ” ν•΄μ‹œ ν…Œμ΄λΈ”μ΄λ‹€.


  1. Hash용 page ꡬ쑰체 섀계 - include/vm/vm.h

이제 ν•΄μ‹œ ν…Œμ΄λΈ”μ—μ„œ μ‚¬μš©ν•  page ꡬ쑰체도 ν•„μš”ν•˜λ‹€.
이 κ΅¬μ‘°μ²΄λŠ” 후에 λ‹€μ–‘ν•œ νƒ€μž…μ˜ νŽ˜μ΄μ§€λ₯Ό λ‹€λ£° λ•Œ ν™•μž₯λœλ‹€.

struct page
{
  const struct page_operations *operations;
  void *va;            /* Address in terms of user space */
  struct frame *frame; /* Back reference for frame */

  /* Your implementation */ - μΆ”κ°€ν•œ λΆ€λΆ„
  struct hash_elem hash_elem; /* ν•΄μ‹œ ν…Œμ΄λΈ”μ— μ‚¬μš©λ  μš”μ†Œ */
  bool writable;

  // …
};

hash_elem


  1. ν•΄μ‹œ ν…Œμ΄λΈ”μ— μ‚¬μš©ν•  ν•΄μ‹œ 및 비ꡐ ν•¨μˆ˜ κ΅¬ν˜„ - page_hash(), page_less() - vm/vm.c

ν•΄μ‹œ ν…Œμ΄λΈ” μ‚¬μš©μ„ μœ„ν•΄ 두 ν•¨μˆ˜κ°€ ν•„μš”ν•˜λ‹€.

bool hash_init (struct hash *hash, hash_hash_func *hash_func,
                    hash_less_func *less_func, void *aux);
  • ν•΄μ‹œ ν•¨μˆ˜ (page_hash)
    • μš”μ†Œμ˜ 데이터λ₯Ό ν•΄μ‹±ν•œ 값을 unsigned int λ²”μœ„ λ‚΄μ—μ„œ λ°˜ν™˜ν•œλ‹€.
static unsigned page_hash(const struct hash_elem *e, void *aux UNUSED)
{
  const struct page *p = hash_entry(e, struct page, hash_elem);
  return hash_bytes(&p->va, sizeof(p->va));
}
  • 비ꡐ ν•¨μˆ˜ (page_less)
    • μš”μ†Œ a와 b에 μ €μž₯된 킀듀을 λΉ„κ΅ν•œλ‹€.
    • aκ°€ b보닀 μž‘μœΌλ©΄ true, κ·Έλ ‡μ§€ μ•ŠμœΌλ©΄ false
static bool page_less(const struct hash_elem *a,
                      const struct hash_elem *b,
                      void *aux UNUSED)
{
  const struct page *pa = hash_entry(a, struct page, hash_elem);
  const struct page *pb = hash_entry(b, struct page, hash_elem);

  return pa->va < pb->va;
}

  1. supplemental_page_table_init() κ΅¬ν˜„ - vm/vm.c

sptλ₯Ό μ΄ˆκΈ°ν™”ν•΄μ£ΌλŠ” 역할을 μˆ˜ν–‰ν•œλ‹€.

  • ν•΄μ‹œ ν…Œμ΄λΈ”λ‘œ sptλ₯Ό κ΅¬ν˜„ν–ˆκΈ°μ— hash_init() ν•¨μˆ˜λ₯Ό 톡해 μ΄ˆκΈ°ν™”ν•΄μ€€λ‹€.
  • 이 ν•¨μˆ˜λŠ” μƒˆλ‘œμš΄ ν”„λ‘œμ„ΈμŠ€κ°€ μ‹œμž‘λ λ•Œ(userprog/process.c의 initdν•¨μˆ˜)와 ν”„λ‘œμ„ΈμŠ€κ°€ 포크될 λ•Œ (process.c의 __do_fork()) ν˜ΈμΆœλœλ‹€.
void supplemental_page_table_init(struct supplemental_page_table *spt UNUSED)
{
  hash_init(&spt->hash_table, page_hash, page_less, NULL);
}
⚠️ **GitHub.com Fallback** ⚠️