-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FEATURE : Add block allocator for more efficient memory management(task/eblock) #113
Changes from all commits
06d95da
2c3285b
2de0288
1ba8c5c
bd09794
5cb240b
c110481
9d37f89
6341ad4
88bdb04
17aaf07
c8e71d8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,6 +39,17 @@ static void do_mblock_allocator_free_all() { | |
pool_tail = NULL; | ||
} | ||
|
||
static void prepare_eblk_add_elem(eblock_result_t *result) { | ||
if (result->tail_blk == NULL) { | ||
result->tail_blk = result->head_blk; | ||
result->elem_cnt = 0; | ||
} else { | ||
assert(result->elem_cnt > 0); | ||
if (result->elem_cnt % EITEMS_PER_BLOCK == 0) | ||
result->tail_blk = result->tail_blk->next; | ||
} | ||
} | ||
|
||
int mblock_allocator_init(size_t nblocks) { | ||
mem_block_t *helper = NULL; | ||
int i; | ||
|
@@ -171,32 +182,33 @@ bool mblock_list_alloc(uint32_t blck_cnt, mem_block_t **head_blk, mem_block_t ** | |
total_mblocks += new_cnt; | ||
//pthread_mutex_unlock(&pool_mutex); | ||
if (alloc_cnt < blck_cnt) { | ||
mblock_list_free(alloc_cnt, *head_blk, *tail_blk); | ||
mblock_list_free(alloc_cnt, head_blk, tail_blk); | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
void mblock_list_free(uint32_t blck_cnt, mem_block_t *head_blk, mem_block_t *tail_blk) { | ||
void mblock_list_free(uint32_t blck_cnt, mem_block_t **head_blk, mem_block_t **tail_blk) { | ||
//mem_block_t *bye = NULL; | ||
//mem_block_t *bye_helper = NULL; | ||
|
||
//pthread_mutex_lock(&pool_mutex); | ||
if (head_blk == NULL || blck_cnt == 0) | ||
if (*head_blk == NULL || blck_cnt == 0) | ||
return; | ||
|
||
assert(pool_tail == NULL || pool_tail->next == NULL); | ||
assert(tail_blk->next == NULL); | ||
assert((*tail_blk)->next == NULL); | ||
|
||
if (pool_head == NULL) { | ||
pool_head = head_blk; | ||
pool_head = *head_blk; | ||
} else { | ||
pool_tail->next = head_blk; | ||
pool_tail->next = *head_blk; | ||
} | ||
pool_tail = tail_blk; | ||
pool_tail = *tail_blk; | ||
|
||
*head_blk = *tail_blk = NULL; | ||
free_mblocks += blck_cnt; | ||
assert(free_mblocks <= total_mblocks); | ||
|
||
|
@@ -223,17 +235,35 @@ void mblock_list_free(uint32_t blck_cnt, mem_block_t *head_blk, mem_block_t *tai | |
free(bye_helper); | ||
}*/ | ||
} | ||
|
||
bool eblk_prepare(eblock_result_t *result, uint32_t elem_count) { | ||
assert(elem_count > 0); | ||
uint32_t blkcnt = ((elem_count - 1) / EITEMS_PER_BLOCK) + 1; | ||
if (!mblock_list_alloc(blkcnt, &result->head_blk, &result->last_blk)) { | ||
result->elem_cnt = 0; | ||
return false; | ||
uint32_t blkcnt; | ||
if (result->head_blk == NULL) { // empty block | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. head_blk이 NULL인 것으로 판단하는 것 보다 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 제가 저렇게 한 의도는 두가지인데
말씀해주신대로 flag를 추가하면 이해하는 측면에서는 더 나아보일 것 같은데, 지금 형태도 나쁘지는 않게 생각이 됩니다. |
||
blkcnt = ((elem_count - 1) / EITEMS_PER_BLOCK) + 1; | ||
if (!mblock_list_alloc(blkcnt, &result->head_blk, &result->last_blk)) { | ||
result->elem_cnt = 0; | ||
return false; | ||
} | ||
result->tail_blk = NULL; | ||
} else { | ||
mem_block_t *head; | ||
mem_block_t *last; | ||
uint32_t curr_blkcnt = result->blck_cnt; | ||
int alloc_blkcnt; | ||
blkcnt = ((result->elem_cnt + elem_count - 1) / EITEMS_PER_BLOCK) + 1; | ||
alloc_blkcnt = blkcnt - curr_blkcnt; | ||
if (alloc_blkcnt > 0) { // need append block | ||
if (!mblock_list_alloc((alloc_blkcnt), &head, &last)) | ||
return false; | ||
result->last_blk->next = head; | ||
result->last_blk = last; | ||
} | ||
} | ||
result->tail_blk = NULL; | ||
result->blck_cnt = blkcnt; | ||
return true; | ||
} | ||
|
||
void eblk_truncate(eblock_result_t *result) { | ||
assert(result->last_blk->next == NULL); | ||
/* returns empty blocklist */ | ||
|
@@ -244,27 +274,33 @@ void eblk_truncate(eblock_result_t *result) { | |
uint32_t used_nblks = ((result->elem_cnt - 1) / EITEMS_PER_BLOCK) + 1; | ||
uint32_t free_nblks = result->blck_cnt - used_nblks; | ||
|
||
mblock_list_free(free_nblks, free_head, free_tail); | ||
mblock_list_free(free_nblks, &free_head, &free_tail); | ||
result->tail_blk->next = NULL; | ||
result->last_blk = result->tail_blk; | ||
result->blck_cnt -= free_nblks; | ||
} | ||
} else { /* ENGINE_ELEM_ENOENT case */ | ||
mblock_list_free(result->blck_cnt, result->head_blk, result->last_blk); | ||
mblock_list_free(result->blck_cnt, &result->head_blk, &result->last_blk); | ||
result->head_blk = result->tail_blk = result->last_blk = NULL; | ||
result->elem_cnt = result->blck_cnt = 0; | ||
} | ||
} | ||
|
||
void eblk_add_elem(eblock_result_t *result, eitem *elem) { | ||
if (result->tail_blk == NULL) { | ||
result->tail_blk = result->head_blk; | ||
result->elem_cnt = 0; | ||
} else { | ||
assert(result->elem_cnt > 0); | ||
if (result->elem_cnt % EITEMS_PER_BLOCK == 0) | ||
result->tail_blk = result->tail_blk->next; | ||
prepare_eblk_add_elem(result); | ||
result->tail_blk->items[result->elem_cnt++ % EITEMS_PER_BLOCK] = (eitem *)elem; | ||
} | ||
|
||
void eblk_add_elem_with_posi(eblock_result_t *result, eitem *elem, int posi) { | ||
mem_block_t *curr_blk = result->head_blk; | ||
int move_block_count = (posi / EITEMS_PER_BLOCK); | ||
|
||
while (move_block_count > 0) { | ||
curr_blk = curr_blk->next; | ||
move_block_count--; | ||
} | ||
|
||
result->tail_blk->items[result->elem_cnt++ % EITEMS_PER_BLOCK] = (eitem *)elem; | ||
prepare_eblk_add_elem(result); | ||
curr_blk->items[posi % EITEMS_PER_BLOCK] = (eitem *)elem; | ||
result->elem_cnt++; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mblock_list_free() 함수에서 head_blk와 tail_blk의 data type을 변경할 이유가 없어 보입니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
바꾼 의도는 mget같은 연속적인 operation에서 기존 블록에 새 블록을 append할지 아니면 새로운 리스트를 받을지에 대한 판단을 head_blk가 NULL인지 여부로 판단하려고 했고
모든 operation이 eblk_prepare를 통해 블록리스트를 받은 후에는 mblock_list_free를 호출해서 여기서 head_blk를 NULL으로 반환하면 되겠다는 생각때문에 수정했는데 제가 잘못생각한걸까요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아래 글의 의미가 무엇 인지를 분명하게 설명해 주면 좋겠어요.
내 의견은
list의 head와 tail pointer를 받아오기 위해 mem_block_t ** 타입이 필요해요.
list의 head와 tail pointer 자체를 넘겨주면 되므로, mem_block_t *타입이면 충분해요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
일단 수정하면서 multiget과 get의 차이에 대한 판단을 mblock_prepare를 통해 넘어온 eblock_result_t 구조체의 head_blk를 보고 새로운 mblock list를 받거나, 기존 블록 리스트에 더 필요한 mblock들을 append하는 형태대로 수정을 하려고 했고
기존
변경
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prepare 단계에서 block을 붙여서 받을지에 대한 판단을
head_blk == NULL
로 하고 있기 때문에,free하는 단계에서 NULL setting을 해주기 위해선 @jooho812 의견처럼 mem_block_t ** 타입으로
해야될 것 같은데요, 혹시 더 괜찮은 의견이 있으신가요?
만약 free 함수 내부에서 NULL setting을 하지 않는다면, free 함수 호출하고 나서 NULL setting을 밖에서 해주어야 합니다.