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 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

View File

@ -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;

View File

@ -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, "

View File

@ -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: