diff --git a/HISTORY b/HISTORY index 1f541ba..46631a4 100644 --- a/HISTORY +++ b/HISTORY @@ -1,7 +1,8 @@ -Version 1.57 2022-03-16 +Version 1.57 2022-03-17 * add function fc_format_path * add functions: fc_get_path_child_count and fc_copy_file + * fast_mblock.[hc] support object destroy callback Version 1.56 2022-03-09 * add function fc_gettid diff --git a/src/fast_allocator.c b/src/fast_allocator.c index 51a8f46..6bc72a5 100644 --- a/src/fast_allocator.c +++ b/src/fast_allocator.c @@ -148,6 +148,7 @@ static int region_init(struct fast_allocator_context *acontext, int result; int bytes; int element_size; + struct fast_mblock_trunk_callbacks trunk_callbacks; struct fast_allocator_info *allocator; char *name; char name_buff[FAST_MBLOCK_NAME_SIZE]; @@ -176,6 +177,8 @@ static int region_init(struct fast_allocator_context *acontext, region->end += sizeof(struct allocator_wrapper); } + trunk_callbacks.check_func = fast_allocator_malloc_trunk_check; + trunk_callbacks.notify_func = fast_allocator_malloc_trunk_notify_func; name = name_buff; result = 0; allocator = region->allocators; @@ -192,10 +195,11 @@ static int region_init(struct fast_allocator_context *acontext, { name = NULL; } + + trunk_callbacks.args = acontext; result = fast_mblock_init_ex2(&allocator->mblock, name, element_size, - region->alloc_elements_once, alloc_elements_limit, NULL, NULL, - acontext->need_lock, fast_allocator_malloc_trunk_check, - fast_allocator_malloc_trunk_notify_func, acontext); + region->alloc_elements_once, alloc_elements_limit, NULL, + acontext->need_lock, &trunk_callbacks); if (result != 0) { break; diff --git a/src/fast_mblock.c b/src/fast_mblock.c index 8fc0f50..9421641 100644 --- a/src/fast_mblock.c +++ b/src/fast_mblock.c @@ -401,25 +401,12 @@ int fast_mblock_manager_stat_print_ex(const bool hide_empty, const int order_by) return 0; } -int fast_mblock_init_ex(struct fast_mblock_man *mblock, - const int element_size, const int alloc_elements_once, - const int64_t alloc_elements_limit, - fast_mblock_alloc_init_func init_func, void *init_args, - const bool need_lock) -{ - return fast_mblock_init_ex2(mblock, NULL, element_size, - alloc_elements_once, alloc_elements_limit, init_func, - init_args, need_lock, NULL, NULL, NULL); -} - int fast_mblock_init_ex2(struct fast_mblock_man *mblock, const char *name, const int element_size, const int alloc_elements_once, const int64_t alloc_elements_limit, - fast_mblock_alloc_init_func init_func, - void *init_args, const bool need_lock, - fast_mblock_malloc_trunk_check_func malloc_trunk_check, - fast_mblock_malloc_trunk_notify_func malloc_trunk_notify, - void *malloc_trunk_args) + struct fast_mblock_object_callbacks *object_callbacks, + const bool need_lock, struct fast_mblock_trunk_callbacks + *trunk_callbacks) { int result; @@ -456,8 +443,17 @@ int fast_mblock_init_ex2(struct fast_mblock_man *mblock, const char *name, return result; } - mblock->alloc_init_func = init_func; - mblock->init_args = init_args; + if (object_callbacks == NULL) + { + mblock->object_callbacks.init_func = NULL; + mblock->object_callbacks.destroy_func = NULL; + mblock->object_callbacks.args = NULL; + } + else + { + mblock->object_callbacks = *object_callbacks; + } + INIT_HEAD(&mblock->trunks.head); mblock->info.trunk_total_count = 0; mblock->info.trunk_used_count = 0; @@ -474,9 +470,17 @@ int fast_mblock_init_ex2(struct fast_mblock_man *mblock, const char *name, mblock->alloc_elements.need_wait = false; mblock->alloc_elements.pcontinue_flag = NULL; mblock->alloc_elements.exceed_log_level = LOG_ERR; - mblock->malloc_trunk_callback.check_func = malloc_trunk_check; - mblock->malloc_trunk_callback.notify_func = malloc_trunk_notify; - mblock->malloc_trunk_callback.args = malloc_trunk_args; + + if (trunk_callbacks == NULL) + { + mblock->trunk_callbacks.check_func = NULL; + mblock->trunk_callbacks.notify_func = NULL; + mblock->trunk_callbacks.args = NULL; + } + else + { + mblock->trunk_callbacks = *trunk_callbacks; + } if (name != NULL) { @@ -531,9 +535,9 @@ static int fast_mblock_prealloc(struct fast_mblock_man *mblock) trunk_size = mblock->info.trunk_size; } - if (mblock->malloc_trunk_callback.check_func != NULL && - mblock->malloc_trunk_callback.check_func(trunk_size, - mblock->malloc_trunk_callback.args) != 0) + if (mblock->trunk_callbacks.check_func != NULL && + mblock->trunk_callbacks.check_func(trunk_size, + mblock->trunk_callbacks.args) != 0) { return ENOMEM; } @@ -551,10 +555,10 @@ static int fast_mblock_prealloc(struct fast_mblock_man *mblock) for (p=pTrunkStart; p<=pLast; p += mblock->info.block_size) { pNode = (struct fast_mblock_node *)p; - if (mblock->alloc_init_func != NULL) + if (mblock->object_callbacks.init_func != NULL) { - if ((result=mblock->alloc_init_func(pNode->data, - mblock->init_args)) != 0) + if ((result=mblock->object_callbacks.init_func(pNode->data, + mblock->object_callbacks.args)) != 0) { free(pNew); return result; @@ -583,10 +587,10 @@ static int fast_mblock_prealloc(struct fast_mblock_man *mblock) mblock->info.trunk_total_count++; mblock->info.element_total_count += alloc_count; - if (mblock->malloc_trunk_callback.notify_func != NULL) + if (mblock->trunk_callbacks.notify_func != NULL) { - mblock->malloc_trunk_callback.notify_func(trunk_size, - mblock->malloc_trunk_callback.args); + mblock->trunk_callbacks.notify_func(trunk_size, + mblock->trunk_callbacks.args); } return 0; @@ -600,10 +604,10 @@ static inline void fast_mblock_remove_trunk(struct fast_mblock_man *mblock, mblock->info.trunk_total_count--; mblock->info.element_total_count -= pMallocNode->alloc_count; - if (mblock->malloc_trunk_callback.notify_func != NULL) + if (mblock->trunk_callbacks.notify_func != NULL) { - mblock->malloc_trunk_callback.notify_func(-1 * pMallocNode->trunk_size, - mblock->malloc_trunk_callback.args); + mblock->trunk_callbacks.notify_func(-1 * pMallocNode->trunk_size, + mblock->trunk_callbacks.args); } } @@ -658,6 +662,28 @@ static inline void fast_mblock_ref_counter_op(struct fast_mblock_man *mblock, #define fast_mblock_ref_counter_dec(mblock, pNode) \ fast_mblock_ref_counter_op(mblock, pNode, false) +static void fast_mblock_free_trunk(struct fast_mblock_man *mblock, + struct fast_mblock_malloc *trunk) +{ + char *start; + char *p; + char *last; + + if (mblock->object_callbacks.destroy_func != NULL) + { + start = (char *)(trunk + 1); + last = (char *)trunk + (trunk->trunk_size - mblock->info.block_size); + for (p = start; p <= last; p += mblock->info.block_size) + { + mblock->object_callbacks.destroy_func( + ((struct fast_mblock_node *)p)->data, + mblock->object_callbacks.args); + } + } + + free(trunk); +} + void fast_mblock_destroy(struct fast_mblock_man *mblock) { struct fast_mblock_malloc *pMallocNode; @@ -671,7 +697,7 @@ void fast_mblock_destroy(struct fast_mblock_man *mblock) pMallocTmp = pMallocNode; pMallocNode = pMallocNode->next; - free(pMallocTmp); + fast_mblock_free_trunk(mblock, pMallocTmp); } INIT_HEAD(&mblock->trunks.head); @@ -1152,7 +1178,8 @@ void fast_mblock_free_trunks(struct fast_mblock_man *mblock, { pDeleted = freelist; freelist = freelist->next; - free(pDeleted); + + fast_mblock_free_trunk(mblock, pDeleted); count++; } logDebug("file: "__FILE__", line: %d, " diff --git a/src/fast_mblock.h b/src/fast_mblock.h index bc79bc9..c0ea45c 100644 --- a/src/fast_mblock.h +++ b/src/fast_mblock.h @@ -67,7 +67,11 @@ struct fast_mblock_chain { struct fast_mblock_node *tail; }; -typedef int (*fast_mblock_alloc_init_func)(void *element, void *args); +/* call by alloc trunk */ +typedef int (*fast_mblock_object_init_func)(void *element, void *args); + +/* call by free trunk */ +typedef void (*fast_mblock_object_destroy_func)(void *element, void *args); typedef int (*fast_mblock_malloc_trunk_check_func)( const int alloc_bytes, void *args); @@ -94,7 +98,13 @@ struct fast_mblock_trunks struct fast_mblock_malloc head; //malloc chain to be freed }; -struct fast_mblock_malloc_trunk_callback +struct fast_mblock_object_callbacks { + fast_mblock_object_init_func init_func; + fast_mblock_object_destroy_func destroy_func; + void *args; +}; + +struct fast_mblock_trunk_callbacks { fast_mblock_malloc_trunk_check_func check_func; fast_mblock_malloc_trunk_notify_func notify_func; @@ -115,14 +125,13 @@ struct fast_mblock_man struct fast_mblock_trunks trunks; struct fast_mblock_chain delay_free_chain; //delay free node chain - fast_mblock_alloc_init_func alloc_init_func; - struct fast_mblock_malloc_trunk_callback malloc_trunk_callback; + struct fast_mblock_object_callbacks object_callbacks; + struct fast_mblock_trunk_callbacks trunk_callbacks; bool need_lock; //if need mutex lock pthread_lock_cond_pair_t lcp; //for read / write free node chain struct fast_mblock_man *prev; //for stat manager struct fast_mblock_man *next; //for stat manager - void *init_args; //args for alloc_init_func }; #define GET_BLOCK_SIZE(info) \ @@ -139,27 +148,9 @@ extern "C" { #endif #define fast_mblock_init(mblock, element_size, alloc_elements_once) \ - fast_mblock_init_ex(mblock, element_size, alloc_elements_once, \ + fast_mblock_init_ex(mblock, element_size, alloc_elements_once, \ 0, NULL, NULL, true) -/** -mblock init -parameters: - mblock: the mblock pointer - element_size: element size, such as sizeof(struct xxx) - alloc_elements_once: malloc elements once, 0 for malloc 1MB memory once - alloc_elements_limit: malloc elements limit, <= 0 for no limit - init_func: the init function - init_args: the args for init_func - need_lock: if need lock -return error no, 0 for success, != 0 fail -*/ -int fast_mblock_init_ex(struct fast_mblock_man *mblock, - const int element_size, const int alloc_elements_once, - const int64_t alloc_elements_limit, - fast_mblock_alloc_init_func init_func, void *init_args, - const bool need_lock); - /** mblock init parameters: @@ -168,22 +159,17 @@ parameters: element_size: element size, such as sizeof(struct xxx) alloc_elements_once: malloc elements once, 0 for malloc 1MB memory once alloc_elements_limit: malloc elements limit, <= 0 for no limit - init_func: the init function - init_args: the args for init_func + object_callbacks: the object callback functions and args need_lock: if need lock - malloc_trunk_check: the malloc trunk check function pointor - malloc_trunk_notify: the malloc trunk notify function pointor - malloc_trunk_args: the malloc trunk args + trunk_callbacks: the trunk callback functions and args return error no, 0 for success, != 0 fail */ int fast_mblock_init_ex2(struct fast_mblock_man *mblock, const char *name, const int element_size, const int alloc_elements_once, const int64_t alloc_elements_limit, - fast_mblock_alloc_init_func init_func, - void *init_args, const bool need_lock, - fast_mblock_malloc_trunk_check_func malloc_trunk_check, - fast_mblock_malloc_trunk_notify_func malloc_trunk_notify, - void *malloc_trunk_args); + struct fast_mblock_object_callbacks *object_callbacks, + const bool need_lock, struct fast_mblock_trunk_callbacks + *trunk_callbacks); /** mblock init @@ -193,23 +179,50 @@ parameters: element_size: element size, such as sizeof(struct xxx) alloc_elements_once: malloc elements once, 0 for malloc 1MB memory once alloc_elements_limit: malloc elements limit, <= 0 for no limit - init_func: the init function - init_args: the args for init_func + init_func: the object init function + init_args: the args for object init function need_lock: if need lock return error no, 0 for success, != 0 fail */ static inline int fast_mblock_init_ex1(struct fast_mblock_man *mblock, const char *name, const int element_size, - const int alloc_elements_once, - const int64_t alloc_elements_limit, - fast_mblock_alloc_init_func init_func, - void *init_args, const bool need_lock) + const int alloc_elements_once, const int64_t alloc_elements_limit, + fast_mblock_object_init_func init_func, void *init_args, + const bool need_lock) { + struct fast_mblock_object_callbacks object_callbacks; + + object_callbacks.init_func = init_func; + object_callbacks.destroy_func = NULL; + object_callbacks.args = init_args; return fast_mblock_init_ex2(mblock, name, element_size, - alloc_elements_once, alloc_elements_limit, init_func, - init_args, need_lock, NULL, NULL, NULL); + alloc_elements_once, alloc_elements_limit, + &object_callbacks, need_lock, NULL); } +/** +mblock init +parameters: + mblock: the mblock pointer + element_size: element size, such as sizeof(struct xxx) + alloc_elements_once: malloc elements once, 0 for malloc 1MB memory once + alloc_elements_limit: malloc elements limit, <= 0 for no limit + object_callbacks: the object callback functions and args + need_lock: if need lock +return error no, 0 for success, != 0 fail +*/ +static inline int fast_mblock_init_ex(struct fast_mblock_man *mblock, + const int element_size, const int alloc_elements_once, + const int64_t alloc_elements_limit, + fast_mblock_object_init_func init_func, void *init_args, + const bool need_lock) +{ + return fast_mblock_init_ex1(mblock, NULL, element_size, + alloc_elements_once, alloc_elements_limit, + init_func, init_args, need_lock); +} + + /** mblock destroy parameters: