[PintOS] API 정리

CorinBeom·2025년 5월 31일

PintOS

목록 보기
9/19
post-thumbnail

이제와서 쓰는 핀토스에 기본적으로 구현되어 있는 VM 구현 시 자주 만나는 API ! 를 정리해보자

우리는 지금까지 많은 로직들을 구현해오며 기본으로 제공되는 API들을 사용해왔다.

정리해놓으면 나중에 찾아보기 좋을 것 같아서 정리해본다.


비트맵 API

이 친구들은 Project 3 익명 페이지 스왑에서 자주 사용될 것만 같은 친구들이다(아직 구현안함)

하나하나 간단하게 알아보자

1. 비트맵 생성

bitmap_create(size_t bit_cnt);
  • swap_disk의 총 섹터 수 / 섹터 당 페이지에 필요한 개수 (예 : 8)만큼 bit_cnt 설정

  • 예 : 디스크에 8192개의 섹터가 있다면 → bitmap_create(8192 / 8) → 1024개의 스왑 슬롯 관리 가능

2. 빈 스왑 슬롯 찾기 + 점유 처리

bitmap_scan_and_flip(bitmap, start, cnt, false);
  • 의미: false (비어있는 슬롯)을 가진 cnt개 연속 비트를 찾고, true로 전환

  • 보통은 cnt = 1 고정 → 한 슬롯만 필요하니까

  • 반환값: 사용 가능한 슬롯의 인덱스, 없으면 BITMAP_ERROR

3. 슬롯 해제

bitmap_reset(bitmap, slot_index);
  • 해당 슬롯을 다시 비어있는 상태로 되돌림

  • anon_swap_in()이 끝난 후, 스왑 슬롯을 재사용 가능하게 할 때 사용

4. 슬롯 사용 여부 확인

bitmap_test(bitmap, index);
  • 해당 인덱스의 슬롯이 사용 중 (true)인지 비어 있는지(false) 확인

Hash API (해쉬스완 아님)

1. Hash Init

hash_init(&spt->spt_hash, page_hash, page_less, NULL);
  • 해시 테이블 초기화 API

  • 인자값으로 들어가있는 page_hash, page_less 이 친구들은 커스텀 사용시 직접 구현해줘야 하는 함수들이다.

2. Hash Insert

hash_insert(struct hash *h, struct hash_elem *new);
  • new 삽입. 동일 키 존재 시 삽입 안 하고 기존 항목 반환

3. Hash Find

hash_find(struct hash *h, struct hash_elem *e);
  • 동일 키 요소를 찾아서 반환 (없으면 NULL 반환)

4. Hash Delete

hash_delete(struct hash *h, struct hash_elem *e);
  • 동일 키 요소를 삭제하고 반환

5. Hash Clear

hash_clear(struct hash *h, hash_action_func *destructor)

이 다섯개의 함수만 기억하면 SPT나 가상 메모리용 해시 테이블은 충분히 구현 할 수 있다고 한다 (FEAT. GPT)


PML4 API

이 친구들은 MMU와 가상 주소 ↔ 물리 주소 매핑에 직접 관여한다.
주로 페이지를 클레임할 때 vm_do_claim_page()에서 사용된다.

1. 가상 주소를 물리 주소에 매핑

pml4_set_page(pml4, va, pa, writable);
  • 가상 주소 va를 물리 주소 pa에 매핑

  • writable 플래그로 쓰기 권한 지정

2. 매핑된 물리 주소 확인

pml4_get_page(pml4, va);
  • 해당 가상 주소가 어떤 물리 주소에 매핑되어 있는지 확인

3. 매핑 해제

pml4_clear_page(pml4, va);
  • 가상 주소 va의 매핑을 해제

  • 스왑 아웃 이후나 페이지 제거 시 사용된다 !

4. Dirty / Accessed 비트 확인 및 설정

pml4_is_dirty(pml4, va);
pml4_set_dirty(pml4, va, bool);
pml4_is_accessed(pml4, va);
pml4_set_accessed(pml4, va, bool);
  • Dirty : 페이지 내용이 수정되었는지 여부

  • Accessed : 해당 페이지가 최근 접근된 적이 있는지 여부


Palloc (Page Allocation) API

물리 메모리 프레임을 할당하고 반납할 때 사용된다.
커널 메모리/유저 메모리를 구분해서 플래그로 지정해야 한다.

1. 한 페이지 할당

palloc_get_apge(PAL_USER | PAL_ZERO);
  • PAL_USER : 사용자 공간에서 할당하겠다 !

  • PAL_ZERO : 0으로 초기화된 페이지를 !

2. 한 페이지 해제

palloc_free_page(addr);
  • addr에 해당하는 페이지를 반환할게요 ㅜㅜ

3. 여러 페이지 할당/반환

palloc_get_multiple(flags, count);
palloc_free_multiple(addr, count);
  • 스레드 FDT 같은 구조처럼 페이지 여러 개를 한번에 다룰 때 사용한다 !

List API

사실 이 친구들을 가장 먼저 적어야 했을 듯 싶다. 그만큼 광범위하게 사용해서 알면 알수록 좋다 !

1. 리스트 초기화

list_init(struct list *list);
  • 리스트를 빈 상태로 초기화

  • 구조체 안에 struct list가 들어있으면 이걸 먼저 초기화해야 함

2. 리스트가 비어있는지 확인

list_empty(struct list *list);
  • 리스트에 요소가 하나도 없으면 true 반환

3. 리스트 앞/뒤에 요소 추가

list_push_front(struct list *list, struct list_elem *e);
list_push_back(struct list *list, struct list_elem *e);
  • 요소 e를 리스트의 앞이나 뒤에 추가한다.

  • 여기까지 구현해왔다면 다들 알겠지만 큐, 스택, 스케줄러 등 구현에 따라 선택적으로 사용된다 !

4. 리스트 앞에서 요소 꺼내기

list_pop_front(struct list *list);
  • 리스트의 맨 앞 요소를 제거하고 반환한다

  • 주로 FIFO 큐처럼 사용할 때 유용함~

5. 특정 요소 제거

list_remove(struct list_elem *e);
  • 리스트 중간에 있는 특정 요소를 제거할 때 사용

  • SPT, FrameTable, PriorityQueue 등에서 자주 등장

6. 순회 (iteration)

list_begin(struct list *list);
list_end(struct list *list);
list_next(struct list_elem *e);
  • for문을 통해 리스트를 순회할 때 사용한다

  • list_begin부터 list_end 전 까지 list_next로 순회

  • 얘도 은근 많이 쓴 것 같다

7. 리스트 요소 → 구조체 변환

list_entry(struct list_elem *e, struct your_struct, member);
  • 리스트 안에 있는 요소를 본래 구조체 포인터로 변환할 때 사용

  • hash_entry() 와 방식이 유사하다

  • 얘도 많이 썼다.

8. 정렬된 삽입

list_insert_ordered(struct list *list, struct list_elem *e, list_less_func *less, void *aux);
  • less 함수를 기준으로 정렬되도록 삽입

  • Priority Scheduling 등에서 유~용하게 씀

9. 기타🎸

list_size(struct list *list);   // 전체 요소 개수 반환  
list_sort(...)                  // 정렬 (선택적)

각 API 마다 많이 쓰이는 것 같은 친구들만 정리해보았다.
나중에 더 생기면 추가해야 될 것 같다

profile
Before Sunrise

0개의 댓글