fast_mblock.[hc] support object destroy callback

recovery_and_balance
YuQing 2022-03-17 20:50:06 +08:00
parent ba011767f8
commit 26abf68ebd
4 changed files with 126 additions and 81 deletions

View File

@ -1,7 +1,8 @@
Version 1.57 2022-03-16 Version 1.57 2022-03-17
* add function fc_format_path * add function fc_format_path
* add functions: fc_get_path_child_count and fc_copy_file * add functions: fc_get_path_child_count and fc_copy_file
* fast_mblock.[hc] support object destroy callback
Version 1.56 2022-03-09 Version 1.56 2022-03-09
* add function fc_gettid * add function fc_gettid

View File

@ -148,6 +148,7 @@ static int region_init(struct fast_allocator_context *acontext,
int result; int result;
int bytes; int bytes;
int element_size; int element_size;
struct fast_mblock_trunk_callbacks trunk_callbacks;
struct fast_allocator_info *allocator; struct fast_allocator_info *allocator;
char *name; char *name;
char name_buff[FAST_MBLOCK_NAME_SIZE]; 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); 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; name = name_buff;
result = 0; result = 0;
allocator = region->allocators; allocator = region->allocators;
@ -192,10 +195,11 @@ static int region_init(struct fast_allocator_context *acontext,
{ {
name = NULL; name = NULL;
} }
trunk_callbacks.args = acontext;
result = fast_mblock_init_ex2(&allocator->mblock, name, element_size, result = fast_mblock_init_ex2(&allocator->mblock, name, element_size,
region->alloc_elements_once, alloc_elements_limit, NULL, NULL, region->alloc_elements_once, alloc_elements_limit, NULL,
acontext->need_lock, fast_allocator_malloc_trunk_check, acontext->need_lock, &trunk_callbacks);
fast_allocator_malloc_trunk_notify_func, acontext);
if (result != 0) if (result != 0)
{ {
break; break;

View File

@ -401,25 +401,12 @@ int fast_mblock_manager_stat_print_ex(const bool hide_empty, const int order_by)
return 0; 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, int fast_mblock_init_ex2(struct fast_mblock_man *mblock, const char *name,
const int element_size, const int alloc_elements_once, const int element_size, const int alloc_elements_once,
const int64_t alloc_elements_limit, const int64_t alloc_elements_limit,
fast_mblock_alloc_init_func init_func, struct fast_mblock_object_callbacks *object_callbacks,
void *init_args, const bool need_lock, const bool need_lock, struct fast_mblock_trunk_callbacks
fast_mblock_malloc_trunk_check_func malloc_trunk_check, *trunk_callbacks)
fast_mblock_malloc_trunk_notify_func malloc_trunk_notify,
void *malloc_trunk_args)
{ {
int result; int result;
@ -456,8 +443,17 @@ int fast_mblock_init_ex2(struct fast_mblock_man *mblock, const char *name,
return result; return result;
} }
mblock->alloc_init_func = init_func; if (object_callbacks == NULL)
mblock->init_args = init_args; {
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); INIT_HEAD(&mblock->trunks.head);
mblock->info.trunk_total_count = 0; mblock->info.trunk_total_count = 0;
mblock->info.trunk_used_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.need_wait = false;
mblock->alloc_elements.pcontinue_flag = NULL; mblock->alloc_elements.pcontinue_flag = NULL;
mblock->alloc_elements.exceed_log_level = LOG_ERR; 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; if (trunk_callbacks == NULL)
mblock->malloc_trunk_callback.args = malloc_trunk_args; {
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) if (name != NULL)
{ {
@ -531,9 +535,9 @@ static int fast_mblock_prealloc(struct fast_mblock_man *mblock)
trunk_size = mblock->info.trunk_size; trunk_size = mblock->info.trunk_size;
} }
if (mblock->malloc_trunk_callback.check_func != NULL && if (mblock->trunk_callbacks.check_func != NULL &&
mblock->malloc_trunk_callback.check_func(trunk_size, mblock->trunk_callbacks.check_func(trunk_size,
mblock->malloc_trunk_callback.args) != 0) mblock->trunk_callbacks.args) != 0)
{ {
return ENOMEM; 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) for (p=pTrunkStart; p<=pLast; p += mblock->info.block_size)
{ {
pNode = (struct fast_mblock_node *)p; 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, if ((result=mblock->object_callbacks.init_func(pNode->data,
mblock->init_args)) != 0) mblock->object_callbacks.args)) != 0)
{ {
free(pNew); free(pNew);
return result; return result;
@ -583,10 +587,10 @@ static int fast_mblock_prealloc(struct fast_mblock_man *mblock)
mblock->info.trunk_total_count++; mblock->info.trunk_total_count++;
mblock->info.element_total_count += alloc_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->trunk_callbacks.notify_func(trunk_size,
mblock->malloc_trunk_callback.args); mblock->trunk_callbacks.args);
} }
return 0; 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.trunk_total_count--;
mblock->info.element_total_count -= pMallocNode->alloc_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->trunk_callbacks.notify_func(-1 * pMallocNode->trunk_size,
mblock->malloc_trunk_callback.args); 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) \ #define fast_mblock_ref_counter_dec(mblock, pNode) \
fast_mblock_ref_counter_op(mblock, pNode, false) 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) void fast_mblock_destroy(struct fast_mblock_man *mblock)
{ {
struct fast_mblock_malloc *pMallocNode; struct fast_mblock_malloc *pMallocNode;
@ -671,7 +697,7 @@ void fast_mblock_destroy(struct fast_mblock_man *mblock)
pMallocTmp = pMallocNode; pMallocTmp = pMallocNode;
pMallocNode = pMallocNode->next; pMallocNode = pMallocNode->next;
free(pMallocTmp); fast_mblock_free_trunk(mblock, pMallocTmp);
} }
INIT_HEAD(&mblock->trunks.head); INIT_HEAD(&mblock->trunks.head);
@ -1152,7 +1178,8 @@ void fast_mblock_free_trunks(struct fast_mblock_man *mblock,
{ {
pDeleted = freelist; pDeleted = freelist;
freelist = freelist->next; freelist = freelist->next;
free(pDeleted);
fast_mblock_free_trunk(mblock, pDeleted);
count++; count++;
} }
logDebug("file: "__FILE__", line: %d, " logDebug("file: "__FILE__", line: %d, "

View File

@ -67,7 +67,11 @@ struct fast_mblock_chain {
struct fast_mblock_node *tail; 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)( typedef int (*fast_mblock_malloc_trunk_check_func)(
const int alloc_bytes, void *args); 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 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_check_func check_func;
fast_mblock_malloc_trunk_notify_func notify_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_trunks trunks;
struct fast_mblock_chain delay_free_chain; //delay free node chain struct fast_mblock_chain delay_free_chain; //delay free node chain
fast_mblock_alloc_init_func alloc_init_func; struct fast_mblock_object_callbacks object_callbacks;
struct fast_mblock_malloc_trunk_callback malloc_trunk_callback; struct fast_mblock_trunk_callbacks trunk_callbacks;
bool need_lock; //if need mutex lock bool need_lock; //if need mutex lock
pthread_lock_cond_pair_t lcp; //for read / write free node chain pthread_lock_cond_pair_t lcp; //for read / write free node chain
struct fast_mblock_man *prev; //for stat manager struct fast_mblock_man *prev; //for stat manager
struct fast_mblock_man *next; //for stat manager struct fast_mblock_man *next; //for stat manager
void *init_args; //args for alloc_init_func
}; };
#define GET_BLOCK_SIZE(info) \ #define GET_BLOCK_SIZE(info) \
@ -139,27 +148,9 @@ extern "C" {
#endif #endif
#define fast_mblock_init(mblock, element_size, alloc_elements_once) \ #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) 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 mblock init
parameters: parameters:
@ -168,22 +159,17 @@ parameters:
element_size: element size, such as sizeof(struct xxx) element_size: element size, such as sizeof(struct xxx)
alloc_elements_once: malloc elements once, 0 for malloc 1MB memory once alloc_elements_once: malloc elements once, 0 for malloc 1MB memory once
alloc_elements_limit: malloc elements limit, <= 0 for no limit alloc_elements_limit: malloc elements limit, <= 0 for no limit
init_func: the init function object_callbacks: the object callback functions and args
init_args: the args for init_func
need_lock: if need lock need_lock: if need lock
malloc_trunk_check: the malloc trunk check function pointor trunk_callbacks: the trunk callback functions and args
malloc_trunk_notify: the malloc trunk notify function pointor
malloc_trunk_args: the malloc trunk args
return error no, 0 for success, != 0 fail return error no, 0 for success, != 0 fail
*/ */
int fast_mblock_init_ex2(struct fast_mblock_man *mblock, const char *name, int fast_mblock_init_ex2(struct fast_mblock_man *mblock, const char *name,
const int element_size, const int alloc_elements_once, const int element_size, const int alloc_elements_once,
const int64_t alloc_elements_limit, const int64_t alloc_elements_limit,
fast_mblock_alloc_init_func init_func, struct fast_mblock_object_callbacks *object_callbacks,
void *init_args, const bool need_lock, const bool need_lock, struct fast_mblock_trunk_callbacks
fast_mblock_malloc_trunk_check_func malloc_trunk_check, *trunk_callbacks);
fast_mblock_malloc_trunk_notify_func malloc_trunk_notify,
void *malloc_trunk_args);
/** /**
mblock init mblock init
@ -193,23 +179,50 @@ parameters:
element_size: element size, such as sizeof(struct xxx) element_size: element size, such as sizeof(struct xxx)
alloc_elements_once: malloc elements once, 0 for malloc 1MB memory once alloc_elements_once: malloc elements once, 0 for malloc 1MB memory once
alloc_elements_limit: malloc elements limit, <= 0 for no limit alloc_elements_limit: malloc elements limit, <= 0 for no limit
init_func: the init function init_func: the object init function
init_args: the args for init_func init_args: the args for object init function
need_lock: if need lock need_lock: if need lock
return error no, 0 for success, != 0 fail return error no, 0 for success, != 0 fail
*/ */
static inline int fast_mblock_init_ex1(struct fast_mblock_man *mblock, static inline int fast_mblock_init_ex1(struct fast_mblock_man *mblock,
const char *name, const int element_size, const char *name, const int element_size,
const int alloc_elements_once, const int alloc_elements_once, const int64_t alloc_elements_limit,
const int64_t alloc_elements_limit, fast_mblock_object_init_func init_func, void *init_args,
fast_mblock_alloc_init_func init_func, const bool need_lock)
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, return fast_mblock_init_ex2(mblock, name, element_size,
alloc_elements_once, alloc_elements_limit, init_func, alloc_elements_once, alloc_elements_limit,
init_args, need_lock, NULL, NULL, NULL); &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 mblock destroy
parameters: parameters: