2개의 페이지 프레임 할당요청이 발생했다고 가정하자.
버디할당자는 우선 free_area[1]의 free_list를 검색한다. 왜냐 2페이지가 필요하다고 하니까 order가 1(2^1)인곳을 뒤지겠지.
아무튼 거기를 뒤져서 할당가능한 페이지프레임이 있으면 할당해주고 비트맵에 이를 반영해준다.
이때 또다시 2페이지 프레임 할당요청이 들어왔으나 free_area[1]의 free_list에 연속된 2개의 free프레임이 없으면 어떻게 할까?=> free_area[2]의 free_list에 연속된 4개의 페이지프레임을 분할하여 두페이지 프레임을 할당해주고 나머지 두개의 프레임은 free_area[1]의 free_list에 넣어준다.
급정리
버디 할당자는 요청된 크기를 만족하는 최소의 페이지 프레임을 할당 해 준다.
만약 페이지 프레임에 딱맞는 order에 가용한 페이지 프레임이 존재하지 않으면, 상위 order에서 페이지 프레임을 할당받아 두 부분으로 나누어 한부분은 할당해주고, 나머지 부분은 하위 order에서 가용 페이지 프레임으로 관리한다.
<나누어진 두 부분을 buddy라고 부르기 때문에 버디 할당자라는 이름이 붙었다고 한다 귀여워라.>
//참고코드 응용레벨 버디할당자 동작
/*main.c*/
#include "Header/buddy.h"
int main(void)
{
input_size();
int i = 0;
struct page* page;
struct page* page1;
init_memory();
page = alloc_pages(0, 2);
page1 = alloc_pages(0, 1);
_free_pages(page -> addr);
_free_pages(page1 -> addr);
for(i = 0; i <= 9; i++)
_show_free_order_list(i);
print("\n\n");
free_memory();
return 0;
}
1. input_size() 함수를 호출하여 사용자에게 KB단위로 할당할 메모리의 크기를 입력받고 헤더에 선언된 전역변수 mem_size에 *1024를 한다.
2.메모리를 할당받을 pageframe 구조체포인터를 선언한다.
typedef struct page
{
struct list_head list; //free_area_t 구조체와 연결하기 위한 리스트 구조체
void *addr; //page의 실제 주소
int order;
}
3. 버디 시스템을 초기화 하기위해 init_memory 함수를 호출한다.
void init_memory(void)
{
int i;
unsigned long cur_size = 0;
//#define PAGE_SHIFT 12
///#define PAGE_SIZE (1UL << PAGE_SHIFT) //한개의 페이지 크기 4096byte
//요청하는 메모리 사이즈가 0이하이거나, 4, 8, 16 이외의 값을 입력한경우... 종료한다.
if( (mem_size <= 0) || (mem_size % PAGE_SIZE) != 0)
{
print( "allocate size %d bytes, not permited \t \n", mem_size);
_exit(-1);
}
ready_for_memory();//mmap을 통한 메모리 영역 확보
//#define TOTAL_PAGES(size) (size >> PAGE_SHIFT)
//mem_size >> PAGE_SHIFT mem_size를 PAGE_SHIFT만큼 오른쪽으로 비트이동..?
free_pages = TOTAL_PAGES(mem_size);
}
4. 그후 mmap인터페이스를 통해서 메모리 영역을 확보한다.
/*메모리 할당 함수, size에 대해 버디에서 페이지를 할당 */
/* mmap 인터페이스를 통해 메모리를 할당한다.*/
void ready_for_memory( void )
{
//#define STRUCT_DATA (1 * 1024 * 1024) free_area 구조체, page 구조체를 위한 공간.
//mmap 인터페이스를 통해서 메모리를 할당받는다.
real_memory = mmap(0, mem_size + STRUCT_DATA, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANONIMAP_PRICATE, -1, 0);
}
'Today I learned' 카테고리의 다른 글
쿼리 결과가 없는 상태에서의 isnull (혹은nvl) 함수의 동작 (0) | 2019.06.10 |
---|---|
iamroot 커널스터디 5월 25일 1주차 (0) | 2019.05.25 |
리눅스 물리메모리 관리구조 (0) | 2019.05.21 |
메모리 관리기법과 가상메모리 (0) | 2019.05.20 |
iamroot 오리엔테이션 (0) | 2019.05.20 |
댓글