fast_mblock reclaimed object pool
parent
8f26a0a354
commit
f734884700
3
HISTORY
3
HISTORY
|
|
@ -1,11 +1,12 @@
|
||||||
|
|
||||||
Version 1.23 2015-11-02
|
Version 1.23 2015-11-03
|
||||||
* sched_thread.c: task can execute in a new thread
|
* sched_thread.c: task can execute in a new thread
|
||||||
* sched_thread.c: support delay tasks
|
* sched_thread.c: support delay tasks
|
||||||
* add function get_current_time_us and get_current_time_ms
|
* add function get_current_time_us and get_current_time_ms
|
||||||
* mblock add stat function
|
* mblock add stat function
|
||||||
* add function get_sys_total_mem_size, ONLY support Linux and FreeBSD
|
* add function get_sys_total_mem_size, ONLY support Linux and FreeBSD
|
||||||
* delay task can execute in a new thread
|
* delay task can execute in a new thread
|
||||||
|
* fast_mblock reclaimed object pool
|
||||||
|
|
||||||
Version 1.22 2015-10-10
|
Version 1.22 2015-10-10
|
||||||
* export php function: fastcommon_get_first_local_ip
|
* export php function: fastcommon_get_first_local_ip
|
||||||
|
|
|
||||||
|
|
@ -103,11 +103,13 @@ static void delete_from_mblock_list(struct fast_mblock_man *mblock)
|
||||||
strcpy(pStat->name, current->info.name); \
|
strcpy(pStat->name, current->info.name); \
|
||||||
pStat->element_size = current->info.element_size; \
|
pStat->element_size = current->info.element_size; \
|
||||||
} \
|
} \
|
||||||
pStat->total_count += current->info.total_count; \
|
pStat->element_total_count += current->info.element_total_count; \
|
||||||
pStat->used_count += current->info.used_count; \
|
pStat->element_used_count += current->info.element_used_count; \
|
||||||
|
pStat->trunk_total_count += current->info.trunk_total_count; \
|
||||||
|
pStat->trunk_used_count += current->info.trunk_used_count; \
|
||||||
pStat->instance_count += current->info.instance_count; \
|
pStat->instance_count += current->info.instance_count; \
|
||||||
/* logInfo("name: %s, element_size: %d, total_count: %d, used_count: %d", */ \
|
/* logInfo("name: %s, element_size: %d, total_count: %d, used_count: %d", */ \
|
||||||
/* pStat->name, pStat->element_size, pStat->total_count, pStat->used_count); */\
|
/* pStat->name, pStat->element_size, pStat->element_total_count, pStat->element_used_count); */\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
int fast_mblock_manager_stat(struct fast_mblock_info *stats,
|
int fast_mblock_manager_stat(struct fast_mblock_info *stats,
|
||||||
|
|
@ -209,19 +211,22 @@ int fast_mblock_manager_stat_print()
|
||||||
|
|
||||||
alloc_mem = 0;
|
alloc_mem = 0;
|
||||||
used_mem = 0;
|
used_mem = 0;
|
||||||
logInfo("%32s %12s %16s %12s %12s %12s", "name", "element_size",
|
logInfo("%32s %12s %16s %10s %10s %14s %12s %12s", "name", "element_size",
|
||||||
"instance_count", "alloc_count", "used_count", "used_ratio");
|
"instance_count", "trunc_alloc", "trunk_used",
|
||||||
|
"element_alloc", "element_used", "used_ratio");
|
||||||
stat_end = stats + count;
|
stat_end = stats + count;
|
||||||
for (pStat=stats; pStat<stat_end; pStat++)
|
for (pStat=stats; pStat<stat_end; pStat++)
|
||||||
{
|
{
|
||||||
block_size = GET_BLOCK_SIZE(*pStat);
|
block_size = GET_BLOCK_SIZE(*pStat);
|
||||||
alloc_mem += block_size * pStat->total_count;
|
alloc_mem += block_size * pStat->element_total_count;
|
||||||
used_mem += block_size * pStat->used_count;
|
used_mem += block_size * pStat->element_used_count;
|
||||||
logInfo("%32s %12d %16d %12d %12d %11.2f%%", pStat->name,
|
logInfo("%32s %12d %16d %10d %10d %14d %12d %11.2f%%", pStat->name,
|
||||||
pStat->element_size, pStat->instance_count,
|
pStat->element_size, pStat->instance_count,
|
||||||
pStat->total_count, pStat->used_count,
|
pStat->trunk_total_count, pStat->trunk_used_count,
|
||||||
pStat->total_count > 0 ? 100.00 * (double)pStat->used_count /
|
pStat->element_total_count, pStat->element_used_count,
|
||||||
(double)pStat->total_count : 0.00);
|
pStat->element_total_count > 0 ? 100.00 * (double)
|
||||||
|
pStat->element_used_count / (double)
|
||||||
|
pStat->element_total_count : 0.00);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alloc_mem < 1024)
|
if (alloc_mem < 1024)
|
||||||
|
|
@ -296,12 +301,14 @@ int fast_mblock_init_ex2(struct fast_mblock_man *mblock, const char *name,
|
||||||
}
|
}
|
||||||
|
|
||||||
mblock->alloc_init_func = init_func;
|
mblock->alloc_init_func = init_func;
|
||||||
mblock->malloc_chain_head = NULL;
|
INIT_HEAD(&mblock->trunks.head);
|
||||||
|
mblock->info.trunk_total_count = 0;
|
||||||
|
mblock->info.trunk_used_count = 0;
|
||||||
mblock->free_chain_head = NULL;
|
mblock->free_chain_head = NULL;
|
||||||
mblock->delay_free_chain.head = NULL;
|
mblock->delay_free_chain.head = NULL;
|
||||||
mblock->delay_free_chain.tail = NULL;
|
mblock->delay_free_chain.tail = NULL;
|
||||||
mblock->info.total_count = 0;
|
mblock->info.element_total_count = 0;
|
||||||
mblock->info.used_count = 0;
|
mblock->info.element_used_count = 0;
|
||||||
mblock->info.instance_count = 1;
|
mblock->info.instance_count = 1;
|
||||||
mblock->need_lock = need_lock;
|
mblock->need_lock = need_lock;
|
||||||
|
|
||||||
|
|
@ -361,6 +368,7 @@ static int fast_mblock_prealloc(struct fast_mblock_man *mblock)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pNode->offset = (int)(p - pNew);
|
||||||
pNode->next = (struct fast_mblock_node *)(p + block_size);
|
pNode->next = (struct fast_mblock_node *)(p + block_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -373,38 +381,88 @@ static int fast_mblock_prealloc(struct fast_mblock_man *mblock)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
((struct fast_mblock_node *)pLast)->offset = (int)(pLast - pNew);
|
||||||
((struct fast_mblock_node *)pLast)->next = NULL;
|
((struct fast_mblock_node *)pLast)->next = NULL;
|
||||||
mblock->free_chain_head = (struct fast_mblock_node *)pTrunkStart;
|
mblock->free_chain_head = (struct fast_mblock_node *)pTrunkStart;
|
||||||
|
|
||||||
pMallocNode->next = mblock->malloc_chain_head;
|
pMallocNode->ref_count = 0;
|
||||||
mblock->malloc_chain_head = pMallocNode;
|
pMallocNode->prev = mblock->trunks.head.prev;
|
||||||
mblock->info.total_count += mblock->alloc_elements_once;
|
pMallocNode->next = &mblock->trunks.head;
|
||||||
|
mblock->trunks.head.prev->next = pMallocNode;
|
||||||
|
mblock->trunks.head.prev = pMallocNode;
|
||||||
|
|
||||||
|
mblock->info.trunk_total_count++;
|
||||||
|
mblock->info.element_total_count += mblock->alloc_elements_once;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void fast_mblock_remove_trunk(struct fast_mblock_man *mblock,
|
||||||
|
struct fast_mblock_malloc *pMallocNode)
|
||||||
|
{
|
||||||
|
pMallocNode->prev->next = pMallocNode->next;
|
||||||
|
pMallocNode->next->prev = pMallocNode->prev;
|
||||||
|
mblock->info.trunk_total_count--;
|
||||||
|
mblock->info.element_total_count -= mblock->alloc_elements_once;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FAST_MBLOCK_GET_TRUNK(pNode) \
|
||||||
|
(struct fast_mblock_malloc *)((char *)pNode - pNode->offset)
|
||||||
|
|
||||||
|
static inline void fast_mblock_ref_counter_op(struct fast_mblock_man *mblock,
|
||||||
|
struct fast_mblock_node *pNode, const bool is_inc)
|
||||||
|
{
|
||||||
|
struct fast_mblock_malloc *pMallocNode;
|
||||||
|
|
||||||
|
pMallocNode = FAST_MBLOCK_GET_TRUNK(pNode);
|
||||||
|
if (is_inc)
|
||||||
|
{
|
||||||
|
if (pMallocNode->ref_count == 0)
|
||||||
|
{
|
||||||
|
mblock->info.trunk_used_count++;
|
||||||
|
}
|
||||||
|
pMallocNode->ref_count++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pMallocNode->ref_count--;
|
||||||
|
if (pMallocNode->ref_count == 0)
|
||||||
|
{
|
||||||
|
mblock->info.trunk_used_count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define fast_mblock_ref_counter_inc(mblock, pNode) \
|
||||||
|
fast_mblock_ref_counter_op(mblock, pNode, true)
|
||||||
|
|
||||||
|
#define fast_mblock_ref_counter_dec(mblock, pNode) \
|
||||||
|
fast_mblock_ref_counter_op(mblock, pNode, false)
|
||||||
|
|
||||||
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;
|
||||||
struct fast_mblock_malloc *pMallocTmp;
|
struct fast_mblock_malloc *pMallocTmp;
|
||||||
|
|
||||||
if (mblock->malloc_chain_head == NULL)
|
if (IS_EMPTY(&mblock->trunks.head))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pMallocNode = mblock->malloc_chain_head;
|
pMallocNode = mblock->trunks.head.next;
|
||||||
while (pMallocNode != NULL)
|
while (pMallocNode != &mblock->trunks.head)
|
||||||
{
|
{
|
||||||
pMallocTmp = pMallocNode;
|
pMallocTmp = pMallocNode;
|
||||||
pMallocNode = pMallocNode->next;
|
pMallocNode = pMallocNode->next;
|
||||||
|
|
||||||
free(pMallocTmp);
|
free(pMallocTmp);
|
||||||
}
|
}
|
||||||
mblock->malloc_chain_head = NULL;
|
|
||||||
|
INIT_HEAD(&mblock->trunks.head);
|
||||||
|
mblock->info.trunk_total_count = 0;
|
||||||
|
mblock->info.trunk_used_count = 0;
|
||||||
mblock->free_chain_head = NULL;
|
mblock->free_chain_head = NULL;
|
||||||
mblock->info.used_count = 0;
|
mblock->info.element_used_count = 0;
|
||||||
mblock->info.total_count = 0;
|
mblock->info.element_total_count = 0;
|
||||||
|
|
||||||
if (mblock->need_lock) pthread_mutex_destroy(&(mblock->lock));
|
if (mblock->need_lock) pthread_mutex_destroy(&(mblock->lock));
|
||||||
delete_from_mblock_list(mblock);
|
delete_from_mblock_list(mblock);
|
||||||
|
|
@ -428,7 +486,9 @@ struct fast_mblock_node *fast_mblock_alloc(struct fast_mblock_man *mblock)
|
||||||
{
|
{
|
||||||
pNode = mblock->free_chain_head;
|
pNode = mblock->free_chain_head;
|
||||||
mblock->free_chain_head = pNode->next;
|
mblock->free_chain_head = pNode->next;
|
||||||
mblock->info.used_count++;
|
mblock->info.element_used_count++;
|
||||||
|
|
||||||
|
fast_mblock_ref_counter_inc(mblock, pNode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -446,7 +506,8 @@ struct fast_mblock_node *fast_mblock_alloc(struct fast_mblock_man *mblock)
|
||||||
{
|
{
|
||||||
pNode = mblock->free_chain_head;
|
pNode = mblock->free_chain_head;
|
||||||
mblock->free_chain_head = pNode->next;
|
mblock->free_chain_head = pNode->next;
|
||||||
mblock->info.used_count++;
|
mblock->info.element_used_count++;
|
||||||
|
fast_mblock_ref_counter_inc(mblock, pNode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -481,7 +542,8 @@ int fast_mblock_free(struct fast_mblock_man *mblock, \
|
||||||
|
|
||||||
pNode->next = mblock->free_chain_head;
|
pNode->next = mblock->free_chain_head;
|
||||||
mblock->free_chain_head = pNode;
|
mblock->free_chain_head = pNode;
|
||||||
mblock->info.used_count--;
|
mblock->info.element_used_count--;
|
||||||
|
fast_mblock_ref_counter_dec(mblock, pNode);
|
||||||
|
|
||||||
if (mblock->need_lock && (result=pthread_mutex_unlock(&(mblock->lock))) != 0)
|
if (mblock->need_lock && (result=pthread_mutex_unlock(&(mblock->lock))) != 0)
|
||||||
{
|
{
|
||||||
|
|
@ -576,3 +638,181 @@ int fast_mblock_delay_free_count(struct fast_mblock_man *mblock)
|
||||||
return fast_mblock_chain_count(mblock, mblock->delay_free_chain.head);
|
return fast_mblock_chain_count(mblock, mblock->delay_free_chain.head);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int fast_mblock_do_reclaim(struct fast_mblock_man *mblock,
|
||||||
|
const int reclaim_target, int *reclaim_count,
|
||||||
|
struct fast_mblock_malloc **ppFreelist)
|
||||||
|
{
|
||||||
|
struct fast_mblock_node *pPrevious;
|
||||||
|
struct fast_mblock_node *pCurrent;
|
||||||
|
struct fast_mblock_malloc *pMallocNode;
|
||||||
|
struct fast_mblock_malloc *freelist;
|
||||||
|
bool lookup_done;
|
||||||
|
|
||||||
|
lookup_done = false;
|
||||||
|
*reclaim_count = 0;
|
||||||
|
freelist = NULL;
|
||||||
|
pPrevious = NULL;
|
||||||
|
pCurrent = mblock->free_chain_head;
|
||||||
|
mblock->free_chain_head = NULL;
|
||||||
|
while (pCurrent != NULL)
|
||||||
|
{
|
||||||
|
pMallocNode = FAST_MBLOCK_GET_TRUNK(pCurrent);
|
||||||
|
if (pMallocNode->ref_count > 0 ||
|
||||||
|
(pMallocNode->ref_count == 0 && lookup_done))
|
||||||
|
{ //keep in free chain
|
||||||
|
|
||||||
|
if (pPrevious != NULL)
|
||||||
|
{
|
||||||
|
pPrevious->next = pCurrent;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mblock->free_chain_head = pCurrent;
|
||||||
|
}
|
||||||
|
|
||||||
|
pPrevious = pCurrent;
|
||||||
|
pCurrent = pCurrent->next;
|
||||||
|
if (pCurrent == NULL)
|
||||||
|
{
|
||||||
|
goto OUTER;
|
||||||
|
}
|
||||||
|
pMallocNode = FAST_MBLOCK_GET_TRUNK(pCurrent);
|
||||||
|
|
||||||
|
while (pMallocNode->ref_count > 0 ||
|
||||||
|
(pMallocNode->ref_count == 0 && lookup_done))
|
||||||
|
{
|
||||||
|
pPrevious = pCurrent;
|
||||||
|
pCurrent = pCurrent->next;
|
||||||
|
if (pCurrent == NULL)
|
||||||
|
{
|
||||||
|
goto OUTER;
|
||||||
|
}
|
||||||
|
pMallocNode = FAST_MBLOCK_GET_TRUNK(pCurrent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (pMallocNode->ref_count < 0 ||
|
||||||
|
(pMallocNode->ref_count == 0 && !lookup_done))
|
||||||
|
{
|
||||||
|
if (pMallocNode->ref_count == 0) //trigger by the first node
|
||||||
|
{
|
||||||
|
fast_mblock_remove_trunk(mblock, pMallocNode);
|
||||||
|
pMallocNode->ref_count = -1;
|
||||||
|
|
||||||
|
pMallocNode->next = freelist;
|
||||||
|
freelist = pMallocNode;
|
||||||
|
(*reclaim_count)++;
|
||||||
|
if (*reclaim_count == reclaim_target)
|
||||||
|
{
|
||||||
|
lookup_done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pCurrent = pCurrent->next;
|
||||||
|
if (pCurrent == NULL)
|
||||||
|
{
|
||||||
|
goto OUTER;
|
||||||
|
}
|
||||||
|
pMallocNode = FAST_MBLOCK_GET_TRUNK(pCurrent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OUTER:
|
||||||
|
if (pPrevious != NULL)
|
||||||
|
{
|
||||||
|
pPrevious->next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
bool old_need_lock;
|
||||||
|
old_need_lock = mblock->need_lock;
|
||||||
|
mblock->need_lock = false;
|
||||||
|
logDebug("file: "__FILE__", line: %d, "
|
||||||
|
"reclaim trunks for %p, reclaimed trunks: %d, "
|
||||||
|
"free node count: %d", __LINE__,
|
||||||
|
mblock, *reclaim_count, fast_mblock_free_count(mblock));
|
||||||
|
mblock->need_lock = mblock->need_lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppFreelist = freelist;
|
||||||
|
return (freelist != NULL ? 0 : ENOENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fast_mblock_free_trunks(struct fast_mblock_man *mblock,
|
||||||
|
struct fast_mblock_malloc *freelist)
|
||||||
|
{
|
||||||
|
struct fast_mblock_malloc *pDeleted;
|
||||||
|
int count;
|
||||||
|
count = 0;
|
||||||
|
while (freelist != NULL)
|
||||||
|
{
|
||||||
|
pDeleted = freelist;
|
||||||
|
freelist = freelist->next;
|
||||||
|
free(pDeleted);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
logDebug("file: "__FILE__", line: %d, "
|
||||||
|
"free_trunks for %p, free trunks: %d", __LINE__,
|
||||||
|
mblock, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
int fast_mblock_reclaim(struct fast_mblock_man *mblock,
|
||||||
|
const int reclaim_target, int *reclaim_count,
|
||||||
|
fast_mblock_free_trunks_func free_trunks_func)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
struct fast_mblock_malloc *freelist;
|
||||||
|
|
||||||
|
if (reclaim_target <= 0)
|
||||||
|
{
|
||||||
|
*reclaim_count = 0;
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mblock->need_lock && (result=pthread_mutex_lock(&(mblock->lock))) != 0)
|
||||||
|
{
|
||||||
|
logError("file: "__FILE__", line: %d, " \
|
||||||
|
"call pthread_mutex_lock fail, " \
|
||||||
|
"errno: %d, error info: %s", \
|
||||||
|
__LINE__, result, STRERROR(result));
|
||||||
|
*reclaim_count = 0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mblock->info.trunk_total_count - mblock->info.trunk_used_count < reclaim_target)
|
||||||
|
{
|
||||||
|
*reclaim_count = 0;
|
||||||
|
result = E2BIG;
|
||||||
|
freelist = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = fast_mblock_do_reclaim(mblock, reclaim_target,
|
||||||
|
reclaim_count, &freelist);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mblock->need_lock && (result=pthread_mutex_unlock(&(mblock->lock))) != 0)
|
||||||
|
{
|
||||||
|
logError("file: "__FILE__", line: %d, " \
|
||||||
|
"call pthread_mutex_unlock fail, " \
|
||||||
|
"errno: %d, error info: %s", \
|
||||||
|
__LINE__, result, STRERROR(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == 0)
|
||||||
|
{
|
||||||
|
if (free_trunks_func != NULL)
|
||||||
|
{
|
||||||
|
free_trunks_func(mblock, freelist);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fast_mblock_free_trunks(mblock, freelist);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
struct fast_mblock_node
|
struct fast_mblock_node
|
||||||
{
|
{
|
||||||
struct fast_mblock_node *next;
|
struct fast_mblock_node *next;
|
||||||
|
int offset; //trunk offset
|
||||||
int recycle_timestamp;
|
int recycle_timestamp;
|
||||||
char data[0]; //the data buffer
|
char data[0]; //the data buffer
|
||||||
};
|
};
|
||||||
|
|
@ -31,6 +32,8 @@ struct fast_mblock_node
|
||||||
/* malloc chain */
|
/* malloc chain */
|
||||||
struct fast_mblock_malloc
|
struct fast_mblock_malloc
|
||||||
{
|
{
|
||||||
|
int64_t ref_count; //refference count
|
||||||
|
struct fast_mblock_malloc *prev;
|
||||||
struct fast_mblock_malloc *next;
|
struct fast_mblock_malloc *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -45,18 +48,26 @@ struct fast_mblock_info
|
||||||
{
|
{
|
||||||
char name[FAST_MBLOCK_NAME_SIZE];
|
char name[FAST_MBLOCK_NAME_SIZE];
|
||||||
int element_size; //element size
|
int element_size; //element size
|
||||||
int total_count; //total element count
|
int element_total_count; //total element count
|
||||||
int used_count; //used element count
|
int element_used_count; //used element count
|
||||||
|
int trunk_total_count; //total trunk count
|
||||||
|
int trunk_used_count; //used trunk count
|
||||||
int instance_count; //instance count
|
int instance_count; //instance count
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct fast_mblock_trunks
|
||||||
|
{
|
||||||
|
struct fast_mblock_malloc head; //malloc chain to be freed
|
||||||
|
};
|
||||||
|
|
||||||
struct fast_mblock_man
|
struct fast_mblock_man
|
||||||
{
|
{
|
||||||
struct fast_mblock_info info;
|
struct fast_mblock_info info;
|
||||||
int alloc_elements_once; //alloc elements once
|
int alloc_elements_once; //alloc elements once
|
||||||
struct fast_mblock_node *free_chain_head; //free node chain
|
struct fast_mblock_node *free_chain_head; //free node chain
|
||||||
|
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
|
||||||
struct fast_mblock_malloc *malloc_chain_head; //malloc chain to be freed
|
|
||||||
fast_mblock_alloc_init_func alloc_init_func;
|
fast_mblock_alloc_init_func alloc_init_func;
|
||||||
bool need_lock; //if need mutex lock
|
bool need_lock; //if need mutex lock
|
||||||
pthread_mutex_t lock; //the lock for read / write free node chain
|
pthread_mutex_t lock; //the lock for read / write free node chain
|
||||||
|
|
@ -233,6 +244,32 @@ return error no, 0 for success, != 0 fail
|
||||||
*/
|
*/
|
||||||
int fast_mblock_manager_stat_print();
|
int fast_mblock_manager_stat_print();
|
||||||
|
|
||||||
|
typedef void (*fast_mblock_free_trunks_func)(struct fast_mblock_man *mblock,
|
||||||
|
struct fast_mblock_malloc *freelist);
|
||||||
|
|
||||||
|
/**
|
||||||
|
free the trunks
|
||||||
|
parameters:
|
||||||
|
mblock: the mblock pointer
|
||||||
|
freelist: the trunks to free
|
||||||
|
return error no, 0 for success, != 0 fail
|
||||||
|
*/
|
||||||
|
void fast_mblock_free_trunks(struct fast_mblock_man *mblock,
|
||||||
|
struct fast_mblock_malloc *freelist);
|
||||||
|
|
||||||
|
/**
|
||||||
|
reclaim the free trunks of the mblock
|
||||||
|
parameters:
|
||||||
|
mblock: the mblock pointer
|
||||||
|
reclaim_target: reclaim target trunks
|
||||||
|
reclaim_count: reclaimed trunk count
|
||||||
|
freelist: the free trunks
|
||||||
|
return error no, 0 for success, != 0 fail
|
||||||
|
*/
|
||||||
|
int fast_mblock_reclaim(struct fast_mblock_man *mblock,
|
||||||
|
const int reclaim_target, int *reclaim_count,
|
||||||
|
fast_mblock_free_trunks_func free_trunks_func);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue