pintos proj3 중간 다리

hodeethelion·2023년 5월 12일
0

SW Intense Academy

목록 보기
12/12
post-thumbnail

다음 단계 나아가기 위한 부분

  1. git stash가 무엇인지 정확히 알기
  2. hash find 찾아보기
  3. frame이 어떻게 되어있는 지 알아보기

1. git stash

  • git stash 라는 것은 변경사항을 일단 담아두는 방법 같다
    + git stash: 지금까지의 변경사항을 일시적으로 저장해둠
    + git stash list: 일시적으로 저장해둔 작업 목록을 확인.
    + git stash clear: 일시적으로 저장해 둔 작업을 모두 삭제하고 싶다.

2번 정리해보기

2. hash find 확인하기

struct page *

spt_find_page(struct supplemental_page_table *spt UNUSED, void *va UNUSED)

{

// struct page *page = NULL;

/* TODO: Fill this function. */

struct page *page = palloc_get_page(PAL_ZERO); // page = 더미같은 새로할당한 주소값
page->va = pg_round_down(va); // 페이지의 시작주소 = 페이지 시작점(받아온 va)
struct hash_elem *e;
e = hash_find(&spt->spt_hash, &page->hash_elem); // 해쉬를 찾기
palloc_free_page(page);
if (e == NULL)
{
return NULL;
}
return hash_entry(e, struct page, hash_elem);
}

이게 어떠한 방식으로 hash를 찾는지가 궁금하다
1. palloc_get_page에서는 분명 새로 할당받은 주솟값을 리턴
2. page 구조체에서는 virtual address 만 넣어 주었다.
3. page 구조체에는 그렇다면 들어있는것은 빈페이지, 그리고 virtual address 밖에 존재하지않는다

궁금한 라인은 도대체 이 아래 라인이 어떻게 작동하는것인가?

e = hash_find(&spt->spt_hash, &page->hash_elem);

hash_find 는 과연 어떤 방식으로 작동하는가?

struct hash_elem *
hash_find (struct hash *h, struct hash_elem *e) {
return find_elem (h, find_bucket (h, e), e);
}

여기에서 결과적으로 find_elempage_less, find_bucketpage_hash라는 함수로 element를 찾아주게 된다.
먼저 find_bucket(h, e)라는 함수를 자세하게 살펴보자.

static struct list *
find_bucket (struct hash *h, struct hash_elem *e) {
size_t bucket_idx = h->hash (e, h->aux) & (h->bucket_cnt - 1);
return &h->buckets[bucket_idx];
}

결과적으로 size_t bucket_idx = h->hash (e, h->aux) & (h->bucket_cnt - 1);
여기 함수에서 hash라는 function으로 확인 할 수 있는데 이는 hash_hash_func로 찾아준다. 우리의 case 인경우 page_hash라는 function으로 찾아주는 것이다.

/* Gitbook참고: Returns a hash value for page p. */
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_hash는 page가 필요하기도 하고 virtual address도 필요하므로 우리가 처음에 빈 페이지를 그냥 이 함수를 찾을 용도로 활용하는 것이다.

page_hash 라는 함수는 결과적으로 page의 VA를 가져와서 hash_bytes를 실행시켜주는데 이것은 결과적으로 bucket index를 반환해준다고 생각하면 좋을 것같다.

find_bucket으로 다시 돌아가서 확인해보자

static struct list *
find_bucket (struct hash *h, struct hash_elem *e) {
size_t bucket_idx = h->hash (e, h->aux) & (h->bucket_cnt - 1);
return &h->buckets[bucket_idx];
}

aux는 여기서 쓰이지 않기 때문에 굳이... find_bucket에서 막 저렇게 안해줘도 되고 (어차피 안쓰일 꺼니까) 다음과 같이 NULL로 바꿔도 작동할것이다.

static struct list *
find_bucket (struct hash *h, struct hash_elem *e) {
size_t bucket_idx = h->hash (e, NULL) & (h->bucket_cnt - 1);
return &h->buckets[bucket_idx];
}

물론 find_bucket을 언젠간 제대로 aux를 이용해서 쓸수도 있겟찌 ? 아니면 그냥 UNUSED 라 상관이 없을라나. 무튼 굳이 세팅되어있는 함수를 바꿀 필요는 없을 것 같다.

결론:

  • find_hash 함수를 실행시키면 find_bucket이 먼저 작동하게 된다.
    내부에서는 hash의 butket인덱스를 뿜어내게 된다
    size_t bucket_idx = h->hash (e, h->aux) & (h->bucket_cnt - 1);
    이때의 h->hash (e, h->aux)에서의 hash function은 우리가 처음에 hash_init할 때 넣어준
    hash_hash_func 이라고 볼 수 있다! 우리의 경우 page_hash함수를 쓴것, 또한 나머지 elem을 찾을 때는page_less function을 써준것! (gitbook 참고)

/* 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'. */
};

여기서 page_hash는 언제 들어가는 것이냐면 supplemental_page_table_init 해줄 때 들어가게 되는데, 짧게 말해서 spt_init은 gitbook에서도 나온것처럼 2가지 상황에서 initialize를 해준다
1. __do_fork
2. initd
이때를 보면 언제hash_hash_func가 세팅 되어있는 지 알 수 있다.
frame 에 관해서는 다음 시간에 ...

profile
가슴을 따라가자

0개의 댓글

관련 채용 정보