fast_mblock.[hc] support object destroy callback
parent
ba011767f8
commit
26abf68ebd
3
HISTORY
3
HISTORY
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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, "
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue