jun-wiki

View My GitHub Profile

Posts (Latest 10 updated) :
Read all
Contents:
  1. 메모리 할당 (Memory Allocation)
    1. 페이지 할당자 (Page Allocator)
      1. 추가 사항
    2. 블록 할당자 (Block Allocator)
      1. 추가 사항

메모리 할당자

Pintos에서 이는 중요한 개념이다

사실 당연히 중요하겠지만 아무튼


메모리 할당 (Memory Allocation)

pintos에는 두 종류의 메모리 할당자가 존재한다

하나는 페이지 단위

다른 하나는 임의의 크기로다


페이지 할당자 (Page Allocator)

include/threads/palloc.h에 페이지 할당자가 선언되어 있는데

페이지(page) 단위로 메모리를 할당한다

보통 한 번에 한 페이지로 쓰지만 여러 페이지도 한 번에 가능하다

페이지 할당자는 자신이 관리하는 메모리를 두 개의 풀로 나눈다

커널 풀(kernel pool) 유저 풀(user pool)

기본적으로, 1MB를 초과하는 시스템 메모리를 두 풀이 반반씩 나눠 갖지만,
이 비율은 ul 커널 명령줄 옵션으로 변경가능하다

할당 요청은 둘 중 하나에서만 이뤄지고 말이다

  • 유저 풀은 사용자 프로세스용 메모리

  • 커널 풀은 그 외 모든 할당

각 풀의 사용 현황은 비트맵(bitmap) 으로 추적한다

0이면 비어있고 1이면 차있다는 거 말이다

이것도 메모리 할당이라 단편화가 발생한다

이를 피하고자 연속 할당 요청은 자제 하란다


추가 사항

페이지 할당자의 타입과 함수DA-ZE✩

void *palloc_get_page (enum palloc_flags flags)
void *palloc_get_multiple (enum palloc_flags flags, size_t page_cnt)

각각 한 페이지, 연속한 page_cnt 페이지 확보하고 포인터 반환한다

할당 실패시 NULL 포인터 반환

flasgs 인자는 이런 것들의 조합이DA-ZE✩

  • PAL_ASSERT
    페이지를 할당하지 못하면 커널 패닉을 발생시킨다
    이는 커널 초기화 시점에만 쓸만 하다

  • PAL_ZERO
    반환하기 전에 할당된 모든 바이트를 0으로 초기화한다
    설정하지 않으면, 새로 할당된 페이지의 내용 개판난다

  • PAL_USER
    페이지를 유저 풀에서 가져온다
    설정하지 않으면 커널 풀에서 할당한다


블록 할당자 (Block Allocator)

threads/malloc.h에 선언되어 있고 임의의 크기의 블록 할당한다

얘도 방법 2가지다

  • 1kB 이하(= 페이지 크기의 1/4 이하) 블록
    크기를 가장 가까운 2의 거듭제곱으로 반올림 한다 (단, 최소 16바이트)
    이후 그 크기 전용 페이지 만들어 그 안에서만 할당

  • 1kB 초과 블록
    오버헤드를 더해 가장 가까운 페이지 크기로 반올림

둘 다 단편화 발생하지만

알빠임?

그건 실무 OS에서 신경쓸 일이지

우리는 교육용이라 신경 안쓴다

작은 할당은 상관 없으나 큰 할당 할 경우

페이지 할당자 호출하여야 하기에

너무 큰 거 부르면 단편화 때문에 실패 할 수 있으니

큰 할당(대략 4kB 초과)은 가능하면 줄이자

블록 할당자는 인터럽트 컨스텍트에선 호출 불가


추가 사항

표준 C 라이브러리 함수들과 인터페이스 동일하다

void *malloc (size_t size)

최소 size 바이트 이상 확보하며 반환
사이즈가 0이거나 못하면 NULL 포인터 반환


void *calloc (size_t a, size_t b)

최소 a * b 바이트 이상 확보하여 반환
블록 내용은 0으로 초기화
ab가 0이거나 못하면 NULL 포인터 반환


void *realloc (void *block, size_t new_size)

blocknew_sizerealloc한다
실패하면 NULL 반환하고 기존 블록 유효하다
block NULL이면 malloc()이고 new_size가 0이면 free()


void free (void *block)

해제되지 않은 block 해제한다