-
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 9 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 |
---|---|---|
|
@@ -171,32 +171,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 +224,33 @@ 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; | ||
blkcnt = ((result->elem_cnt + elem_count - 1) / EITEMS_PER_BLOCK) + 1; | ||
if (blkcnt > curr_blkcnt) { // need append block | ||
if (!mblock_list_alloc((blkcnt - curr_blkcnt), &head, &last)) | ||
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. 필요한 block count를 먼저 계산 해 놓고, |
||
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,13 +261,13 @@ 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; | ||
} | ||
|
@@ -268,3 +285,14 @@ void eblk_add_elem(eblock_result_t *result, eitem *elem) { | |
|
||
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) { | ||
/* This function should not be used when there are multiple blocks. */ | ||
assert(result->blck_cnt == 1); | ||
if (result->tail_blk == NULL) { | ||
result->tail_blk = result->head_blk; | ||
result->elem_cnt = 0; | ||
} | ||
result->tail_blk->items[posi % EITEMS_PER_BLOCK] = (eitem *)elem; | ||
result->elem_cnt++; | ||
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. posi 라는 값이 위 코드는 어떤 mblock인지를 찾지 않고 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. 이 함수를 만든게 bop pwg연산 때문에 만들었고 이 연산에서 validation check할때 element 갯수를 100개로 제한하고 있어서 현재는 어떤 mblock인지 찾을 필요없이 그냥 넣으면 될 것 같아서 주석과 assert문만 넣어두었는데 어떤 mblock인지 찾는걸 추가해 둘까요? 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. 예. 어떤 mblock인지를 확인하는 것이 보다 안전해 보여요. 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. 반영해두겠습니다. |
||
} |
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을 밖에서 해주어야 합니다.