From f296a3e4590d4e6f1b515e18f6189625145fbdf7 Mon Sep 17 00:00:00 2001 From: yuqing Date: Fri, 19 Jun 2015 19:04:37 +0800 Subject: [PATCH] fast_mblock add fast_mblock_delay_free --- HISTORY | 3 +++ libfastcommon.spec | 2 +- src/fast_mblock.c | 67 +++++++++++++++++++++++++++++++++++++++++++--- src/fast_mblock.h | 42 ++++++++++++++++++++++++++++- 4 files changed, 109 insertions(+), 5 deletions(-) diff --git a/HISTORY b/HISTORY index 5f3fd8d..899e6e2 100644 --- a/HISTORY +++ b/HISTORY @@ -1,4 +1,7 @@ +Version 1.16 2015-06-19 + * fast_mblock add fast_mblock_delay_free + Version 1.15 2015-06-16 * fast_mblock.c support none lock * ioevent support set timeout diff --git a/libfastcommon.spec b/libfastcommon.spec index a6c717f..9f94008 100644 --- a/libfastcommon.spec +++ b/libfastcommon.spec @@ -1,5 +1,5 @@ Name: libfastcommon -Version: 1.0.15 +Version: 1.0.16 Release: 1%{?dist} Summary: c common functions library extracted from my open source projects FastDFS License: GPL diff --git a/src/fast_mblock.c b/src/fast_mblock.c index d7a0080..d3e2318 100644 --- a/src/fast_mblock.c +++ b/src/fast_mblock.c @@ -8,6 +8,7 @@ #include "logger.h" #include "shared_func.h" #include "pthread_func.h" +#include "sched_thread.h" int fast_mblock_init_ex(struct fast_mblock_man *mblock, const int element_size, const int alloc_elements_once, fast_mblock_alloc_init_func init_func, @@ -47,6 +48,8 @@ int fast_mblock_init_ex(struct fast_mblock_man *mblock, const int element_size, mblock->alloc_init_func = init_func; mblock->malloc_chain_head = NULL; mblock->free_chain_head = NULL; + mblock->delay_free_chain.head = NULL; + mblock->delay_free_chain.tail = NULL; mblock->total_count = 0; mblock->need_lock = need_lock; @@ -165,7 +168,17 @@ struct fast_mblock_node *fast_mblock_alloc(struct fast_mblock_man *mblock) } else { - if ((result=fast_mblock_prealloc(mblock)) == 0) + if (mblock->delay_free_chain.head != NULL && + mblock->delay_free_chain.head->recycle_timestamp <= get_current_time()) + { + pNode = mblock->delay_free_chain.head; + mblock->delay_free_chain.head = pNode->next; + if (mblock->delay_free_chain.tail == pNode) + { + mblock->delay_free_chain.tail = NULL; + } + } + else if ((result=fast_mblock_prealloc(mblock)) == 0) { pNode = mblock->free_chain_head; mblock->free_chain_head = pNode->next; @@ -215,7 +228,45 @@ int fast_mblock_free(struct fast_mblock_man *mblock, \ return 0; } -int fast_mblock_free_count(struct fast_mblock_man *mblock) +int fast_mblock_delay_free(struct fast_mblock_man *mblock, + struct fast_mblock_node *pNode, const int deley) +{ + int result; + + 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)); + return result; + } + + pNode->recycle_timestamp = get_current_time() + deley; + if (mblock->delay_free_chain.head == NULL) + { + mblock->delay_free_chain.head = pNode; + } + else + { + mblock->delay_free_chain.tail->next = pNode; + } + mblock->delay_free_chain.tail = pNode; + pNode->next = NULL; + + 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)); + } + + return 0; +} + +static int fast_mblock_chain_count(struct fast_mblock_man *mblock, + struct fast_mblock_node *head) { struct fast_mblock_node *pNode; int count; @@ -231,7 +282,7 @@ int fast_mblock_free_count(struct fast_mblock_man *mblock) } count = 0; - pNode = mblock->free_chain_head; + pNode = head; while (pNode != NULL) { pNode = pNode->next; @@ -249,3 +300,13 @@ int fast_mblock_free_count(struct fast_mblock_man *mblock) return count; } +int fast_mblock_free_count(struct fast_mblock_man *mblock) +{ + return fast_mblock_chain_count(mblock, mblock->free_chain_head); +} + +int fast_mblock_delay_free_count(struct fast_mblock_man *mblock) +{ + return fast_mblock_chain_count(mblock, mblock->delay_free_chain.head); +} + diff --git a/src/fast_mblock.h b/src/fast_mblock.h index d880ba5..b33c9cf 100644 --- a/src/fast_mblock.h +++ b/src/fast_mblock.h @@ -22,6 +22,7 @@ struct fast_mblock_node { struct fast_mblock_node *next; + int recycle_timestamp; char data[0]; //the data buffer }; @@ -31,11 +32,17 @@ struct fast_mblock_malloc struct fast_mblock_malloc *next; }; +struct fast_mblock_chain { + struct fast_mblock_node *head; + struct fast_mblock_node *tail; +}; + typedef int (*fast_mblock_alloc_init_func)(void *element); struct fast_mblock_man { - struct fast_mblock_node *free_chain_head; //free node chain + struct fast_mblock_node *free_chain_head; //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; int element_size; //element size @@ -93,6 +100,17 @@ return 0 for success, return none zero if fail int fast_mblock_free(struct fast_mblock_man *mblock, struct fast_mblock_node *pNode); +/** +delay free a node (put a node to the mblock) +parameters: + mblock: the mblock pointer + pNode: the node to free + delay: delay seconds to free +return 0 for success, return none zero if fail +*/ +int fast_mblock_delay_free(struct fast_mblock_man *mblock, + struct fast_mblock_node *pNode, const int delay); + /** alloc a object from the mblock parameters: @@ -123,6 +141,20 @@ static inline int fast_mblock_free_object(struct fast_mblock_man *mblock, return fast_mblock_free(mblock, fast_mblock_to_node_ptr(object)); } +/** +delay free a object (put a node to the mblock) +parameters: + mblock: the mblock pointer + pNode: the node to free + delay: delay seconds to free +return 0 for success, return none zero if fail +*/ +int fast_mblock_delay_free_object(struct fast_mblock_man *mblock, + void *object, const int delay) +{ + return fast_mblock_delay_free(mblock, fast_mblock_to_node_ptr(object), delay); +} + /** get node count of the mblock parameters: @@ -131,6 +163,14 @@ return the free node count of the mblock, return -1 if fail */ int fast_mblock_free_count(struct fast_mblock_man *mblock); +/** +get delay free node count of the mblock +parameters: + mblock: the mblock pointer +return the delay free node count of the mblock, return -1 if fail +*/ +int fast_mblock_delay_free_count(struct fast_mblock_man *mblock); + #define fast_mblock_total_count(mblock) (mblock)->total_count #ifdef __cplusplus