http://www.asmlove.co.kr/
)의 김기오(gurugio)씨의 Offline study로부터 내용정리| |
예제소스의 최신버젼 보기
| |
/*
Copyright (C) JAEHYUK CHO
All rights reserved.
Code by JaeHyuk Cho <mailto:minzkn@minzkn.com>
*/
/* object index의 단위를 나타내는 변수형입니다.
object수가 65536이상인 경우 이것은 좀 키워야 겠죠. */
typedef unsigned short int __mzslab_index_t;
#define mzslab_index_t __mzslab_index_t
#pragma pack(push,8)
typedef struct mzslab_ts {
/* object 의 크기를 나타냅니다. */
size_t object_size;
/* object 수를 나타냅니다. */
size_t objects;
/* 첫 object 의 포인터입니다.
이 또한 런타임에 계산 가능하지만 미리... */
unsigned char *entry;
/* 첫번째 해제된 Object 의 index를 저장합니다.
만약 이 값이 objects보다 같거나 크게 되면 할당가능한 object가 없게 됩니다. */
mzslab_index_t f;
}__mzslab_t;
#define mzslab_t __mzslab_t
#pragma pack(pop)
mzslab_t * mzslab_init(void *s_page, size_t s_page_size, size_t s_object_size)
{
size_t s_index;
mzslab_t *s_slab;
mzslab_index_t *s_nft; /* next free table */
/* page의 첫 선두부분을 slab구조저장영역으로 사용합니다. */
s_slab = (mzslab_t *)s_page;
/* 하나의 object가 가지는 유닛의 크기를 저장해둡니다. */
s_slab->object_size = s_object_size;
/* 여러가지 page의 크기에 따른 적절한 object수를 산출하기 위해서 slab index영역을 고려한 산출loop를 사용합니다. */
s_slab->objects = (s_page_size - sizeof(mzslab_t)) / s_object_size;
while((s_slab->objects > ((size_t)0)) && ((s_page_size - sizeof(mzslab_t)) < ((s_slab->objects * s_object_size) + (s_slab->objects * sizeof(mzslab_index_t))))) {
s_slab->objects--;
}
if(s_slab->objects <= ((size_t)0)) { /* object를 담기에 불가능한 크기인 경우 slab은 초기화 할수 없습니다. */
return((mzslab_t *)0);
}
/* 첫 object를 가르키는 포인터를 저장해둡니다. */
s_slab->entry = ((unsigned char *)(&s_slab[1])) + (s_slab->objects * sizeof(mzslab_index_t));
/* 할당되지 않은 object의 첫번째 index를 저장합니다. */
s_slab->f = (mzslab_index_t)0u;
/* 해제된 메모리로 표현하기 위하여 index를 초기화 합니다. */
s_nft = (mzslab_index_t *)(&s_slab[1]);
for(s_index = ((size_t)0u);s_index < s_slab->objects;s_index++) {
s_nft[s_index] = s_index + ((size_t)1u);
}
return(s_slab);
}
void * mzslab_alloc(mzslab_t *s_slab)
{
mzslab_index_t *s_nft = (mzslab_index_t *)(&s_slab[1]);
void *s_result;
if(s_slab->f >= s_slab->objects) {
/* 이 경우 메모리에 할당가능한 object가 없다고 판단하면 되겠습니다. */
s_result = (void *)0;
}
else { /* 할당가능한 object가 있으므로 이를 반환합니다. */
s_result = (void *)(&s_slab->entry[s_slab->f * s_slab->object_size]);
s_slab->f = s_nft[s_slab->f];
}
return(s_result);
}
/* 원래 s_slab은 전역 cache테이블로 감추고
s_ptr만으로 추출할수 있도록 구현하는게 바람직하지만
현재 예제를 들기 위한 부분이기에 그냥 인자로 넘겨 받도록 하여 소개합니다. */
void * mzslab_free(mzslab_t *s_slab, void *s_ptr)
{
mzslab_index_t *s_nft = (mzslab_index_t *)(&s_slab[1]);
size_t s_index;
s_index = (size_t)(((unsigned char *)s_ptr) - s_slab->entry) / s_slab->object_size;
s_nft[s_index] = s_slab->f;
s_slab->f = s_index;
return((void *)0);
}