fast_mblock.[hc]: support wait with element limit

storage_pool
YuQing 2021-01-14 15:25:37 +08:00
parent 1f126476bc
commit c822e92b19
3 changed files with 112 additions and 52 deletions

View File

@ -1,6 +1,7 @@
Version 1.47 2021-01-11
Version 1.47 2021-01-14
* fc_atomic.h: add FC_ATOMIC_SET
* fast_mblock.[hc]: support wait with element limit
Version 1.46 2020-12-29
* add function get_time_item_from_conf_ex

View File

@ -18,11 +18,10 @@
#include <errno.h>
#include <sys/resource.h>
#include <pthread.h>
#include <assert.h>
#include "logger.h"
#include "shared_func.h"
#include "pthread_func.h"
#include "sched_thread.h"
#include "pthread_func.h"
#include "fast_mblock.h"
struct _fast_mblock_manager
@ -402,7 +401,7 @@ int fast_mblock_init_ex2(struct fast_mblock_man *mblock, const char *name,
mblock->alloc_elements.once = mblock->alloc_elements.limit;
}
if (need_lock && (result=init_pthread_lock(&(mblock->lock))) != 0)
if (need_lock && (result=init_pthread_lock_cond_pair(&(mblock->lcp))) != 0)
{
logError("file: "__FILE__", line: %d, " \
"init_pthread_lock fail, errno: %d, error info: %s", \
@ -425,7 +424,9 @@ int fast_mblock_init_ex2(struct fast_mblock_man *mblock, const char *name,
mblock->info.trunk_size = fast_mblock_get_trunk_size(mblock,
block_size, mblock->alloc_elements.once);
mblock->need_lock = need_lock;
mblock->exceed_log_level = LOG_ERR;
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;
@ -464,10 +465,13 @@ static int fast_mblock_prealloc(struct fast_mblock_man *mblock)
mblock->info.element_total_count;
if (avail_count <= 0)
{
log_it_ex(&g_log_context, mblock->exceed_log_level,
"file: "__FILE__", line: %d, "
"allocated elements exceed limit: %"PRId64,
__LINE__, mblock->alloc_elements.limit);
if (FC_LOG_BY_LEVEL(mblock->alloc_elements.exceed_log_level))
{
log_it_ex(&g_log_context, mblock->alloc_elements.
exceed_log_level, "file: "__FILE__", line: %d, "
"allocated elements exceed limit: %"PRId64,
__LINE__, mblock->alloc_elements.limit);
}
return EOVERFLOW;
}
@ -615,7 +619,7 @@ void fast_mblock_destroy(struct fast_mblock_man *mblock)
mblock->info.delay_free_elements = 0;
mblock->info.element_total_count = 0;
if (mblock->need_lock) pthread_mutex_destroy(&(mblock->lock));
if (mblock->need_lock) destroy_pthread_lock_cond_pair(&(mblock->lcp));
delete_from_mblock_list(mblock);
}
@ -624,7 +628,8 @@ struct fast_mblock_node *fast_mblock_alloc(struct fast_mblock_man *mblock)
struct fast_mblock_node *pNode;
int result;
if (mblock->need_lock && (result=pthread_mutex_lock(&(mblock->lock))) != 0)
if (mblock->need_lock && (result=pthread_mutex_lock(
&mblock->lcp.lock)) != 0)
{
logError("file: "__FILE__", line: %d, "
"call pthread_mutex_lock fail, "
@ -633,15 +638,18 @@ struct fast_mblock_node *fast_mblock_alloc(struct fast_mblock_man *mblock)
return NULL;
}
if (mblock->free_chain_head != NULL)
{
pNode = mblock->free_chain_head;
mblock->free_chain_head = pNode->next;
}
else
{
while (1)
{
if (mblock->free_chain_head != NULL)
{
pNode = mblock->free_chain_head;
mblock->free_chain_head = pNode->next;
break;
}
if (mblock->delay_free_chain.head != NULL &&
mblock->delay_free_chain.head->recycle_timestamp <= get_current_time())
mblock->delay_free_chain.head->
recycle_timestamp <= get_current_time())
{
pNode = mblock->delay_free_chain.head;
mblock->delay_free_chain.head = pNode->next;
@ -651,24 +659,37 @@ struct fast_mblock_node *fast_mblock_alloc(struct fast_mblock_man *mblock)
}
mblock->info.delay_free_elements--;
break;
}
else if ((result=fast_mblock_prealloc(mblock)) == 0)
{
pNode = mblock->free_chain_head;
mblock->free_chain_head = pNode->next;
}
else
{
pNode = NULL;
}
}
if ((result=fast_mblock_prealloc(mblock)) == 0)
{
pNode = mblock->free_chain_head;
mblock->free_chain_head = pNode->next;
break;
}
if (!mblock->alloc_elements.need_wait)
{
pNode = NULL;
break;
}
pthread_cond_wait(&mblock->lcp.cond, &mblock->lcp.lock);
if (!*(mblock->alloc_elements.pcontinue_flag))
{
pNode = NULL;
break;
}
}
if (pNode != NULL)
{
mblock->info.element_used_count++;
fast_mblock_ref_counter_inc(mblock, pNode);
}
if (mblock->need_lock && (result=pthread_mutex_unlock(&(mblock->lock))) != 0)
if (mblock->need_lock && (result=pthread_mutex_unlock(
&mblock->lcp.lock)) != 0)
{
logError("file: "__FILE__", line: %d, " \
"call pthread_mutex_unlock fail, " \
@ -683,8 +704,10 @@ int fast_mblock_free(struct fast_mblock_man *mblock, \
struct fast_mblock_node *pNode)
{
int result;
bool notify;
if (mblock->need_lock && (result=pthread_mutex_lock(&(mblock->lock))) != 0)
if (mblock->need_lock && (result=pthread_mutex_lock(
&mblock->lcp.lock)) != 0)
{
logError("file: "__FILE__", line: %d, " \
"call pthread_mutex_lock fail, " \
@ -693,16 +716,23 @@ int fast_mblock_free(struct fast_mblock_man *mblock, \
return result;
}
notify = (mblock->free_chain_head == NULL);
pNode->next = mblock->free_chain_head;
mblock->free_chain_head = pNode;
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->alloc_elements.need_wait && notify)
{
pthread_cond_signal(&mblock->lcp.cond);
}
if (mblock->need_lock && (result=pthread_mutex_unlock(
&mblock->lcp.lock)) != 0)
{
logError("file: "__FILE__", line: %d, " \
"call pthread_mutex_unlock fail, " \
"errno: %d, error info: %s", \
logError("file: "__FILE__", line: %d, "
"call pthread_mutex_unlock fail, "
"errno: %d, error info: %s",
__LINE__, result, STRERROR(result));
}
@ -714,7 +744,8 @@ int fast_mblock_delay_free(struct fast_mblock_man *mblock,
{
int result;
if (mblock->need_lock && (result=pthread_mutex_lock(&(mblock->lock))) != 0)
if (mblock->need_lock && (result=pthread_mutex_lock(
&mblock->lcp.lock)) != 0)
{
logError("file: "__FILE__", line: %d, " \
"call pthread_mutex_lock fail, " \
@ -739,7 +770,8 @@ int fast_mblock_delay_free(struct fast_mblock_man *mblock,
mblock->info.delay_free_elements++;
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->lcp.lock)) != 0)
{
logError("file: "__FILE__", line: %d, " \
"call pthread_mutex_unlock fail, " \
@ -757,7 +789,8 @@ static int fast_mblock_chain_count(struct fast_mblock_man *mblock,
int count;
int result;
if (mblock->need_lock && (result=pthread_mutex_lock(&(mblock->lock))) != 0)
if (mblock->need_lock && (result=pthread_mutex_lock(
&mblock->lcp.lock)) != 0)
{
logError("file: "__FILE__", line: %d, " \
"call pthread_mutex_lock fail, " \
@ -774,7 +807,8 @@ static int fast_mblock_chain_count(struct fast_mblock_man *mblock,
count++;
}
if (mblock->need_lock && (result=pthread_mutex_unlock(&(mblock->lock))) != 0)
if (mblock->need_lock && (result=pthread_mutex_unlock(
&mblock->lcp.lock)) != 0)
{
logError("file: "__FILE__", line: %d, " \
"call pthread_mutex_unlock fail, " \
@ -929,15 +963,16 @@ int fast_mblock_reclaim(struct fast_mblock_man *mblock,
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));
if (mblock->need_lock && (result=pthread_mutex_lock(
&mblock->lcp.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;
}
return result;
}
if (reclaim_target > 0 && mblock->info.trunk_total_count -
mblock->info.trunk_used_count < reclaim_target)
@ -952,7 +987,8 @@ int fast_mblock_reclaim(struct fast_mblock_man *mblock,
reclaim_count, &freelist);
}
if (mblock->need_lock && (result=pthread_mutex_unlock(&(mblock->lock))) != 0)
if (mblock->need_lock && (result=pthread_mutex_unlock(
&mblock->lcp.lock)) != 0)
{
logError("file: "__FILE__", line: %d, " \
"call pthread_mutex_unlock fail, " \

View File

@ -25,6 +25,7 @@
#include "common_define.h"
#include "fc_memory.h"
#include "chain.h"
#include "logger.h"
#define FAST_MBLOCK_NAME_SIZE 32
@ -92,8 +93,11 @@ struct fast_mblock_man
{
struct fast_mblock_info info;
struct {
int once; //alloc elements once
int64_t limit; //<= 0 for no limit
bool need_wait;
int exceed_log_level; //for exceed limit
int once; //alloc elements once
int64_t limit; //<= 0 for no limit
bool *pcontinue_flag;
} alloc_elements;
struct fast_mblock_node *free_chain_head; //free node chain
struct fast_mblock_trunks trunks;
@ -103,8 +107,7 @@ struct fast_mblock_man
struct fast_mblock_malloc_trunk_callback malloc_trunk_callback;
bool need_lock; //if need mutex lock
int exceed_log_level; //log level for exceed limit
pthread_mutex_t lock; //the lock 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 *next; //for stat manager
void *init_args; //args for alloc_init_func
@ -202,6 +205,26 @@ parameters:
*/
void fast_mblock_destroy(struct fast_mblock_man *mblock);
static inline int fast_mblock_set_need_wait(struct fast_mblock_man *mblock,
const bool need_wait, bool * volatile pcontinue_flag)
{
if (!mblock->need_lock || mblock->alloc_elements.limit <= 0)
{
logError("file: "__FILE__", line: %d, "
"need_lock: %d != 1 or alloc_elements.limit: %"PRId64" <= 0",
__LINE__, mblock->need_lock, mblock->alloc_elements.limit);
return EINVAL;
}
mblock->alloc_elements.need_wait = need_wait;
mblock->alloc_elements.pcontinue_flag = pcontinue_flag;
if (need_wait)
{
mblock->alloc_elements.exceed_log_level = LOG_NOTHING;
}
return 0;
}
/**
alloc a node from the mblock
parameters: