add object memory pool
parent
df3e985540
commit
80fba80f41
3
HISTORY
3
HISTORY
|
|
@ -1,7 +1,8 @@
|
|||
|
||||
Version 1.06 2014-05-30
|
||||
Version 1.06 2014-06-05
|
||||
* update source code from FastDFS V5.02
|
||||
* add function short2buff and buff2short
|
||||
* add object memory pool (fast_mblock.h and fast_mblock.c)
|
||||
|
||||
Version 1.05 2012-07-08
|
||||
* update source code from FastDFS V3.09
|
||||
|
|
|
|||
|
|
@ -8,13 +8,13 @@ FAST_SHARED_OBJS = hash.lo chain.lo shared_func.lo ini_file_reader.lo \
|
|||
logger.lo sockopt.lo base64.lo sched_thread.lo \
|
||||
http_func.lo md5.lo pthread_func.lo local_ip_func.lo \
|
||||
avl_tree.lo ioevent.lo ioevent_loop.lo fast_task_queue.lo \
|
||||
fast_timer.lo process_ctrl.lo
|
||||
fast_timer.lo process_ctrl.lo fast_mblock.lo
|
||||
|
||||
HEADER_FILES = common_define.h hash.h chain.h logger.h base64.h \
|
||||
shared_func.h pthread_func.h ini_file_reader.h _os_bits.h \
|
||||
sockopt.h sched_thread.h http_func.h md5.h local_ip_func.h \
|
||||
avl_tree.h ioevent.h ioevent_loop.h fast_task_queue.h \
|
||||
fast_timer.h process_ctrl.h
|
||||
fast_timer.h process_ctrl.h fast_mblock.h
|
||||
|
||||
ALL_OBJS = $(STATIC_OBJS) $(FAST_SHARED_OBJS)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,225 @@
|
|||
//fast_mblock.c
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/resource.h>
|
||||
#include <pthread.h>
|
||||
#include "fast_mblock.h"
|
||||
#include "logger.h"
|
||||
#include "shared_func.h"
|
||||
#include "pthread_func.h"
|
||||
|
||||
int fast_mblock_init(struct fast_mblock_man *mblock, const int element_size, \
|
||||
const int alloc_elements_once)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (element_size <= 0)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"invalid block size: %d", \
|
||||
__LINE__, element_size);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
mblock->element_size = element_size;
|
||||
if (alloc_elements_once > 0)
|
||||
{
|
||||
mblock->alloc_elements_once = alloc_elements_once;
|
||||
}
|
||||
else
|
||||
{
|
||||
int block_size;
|
||||
block_size = MEM_ALIGN(sizeof(struct fast_mblock_node) \
|
||||
+ element_size);
|
||||
mblock->alloc_elements_once = (1024 * 1024) / block_size;
|
||||
}
|
||||
|
||||
if ((result=init_pthread_lock(&(mblock->lock))) != 0)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"init_pthread_lock fail, errno: %d, error info: %s", \
|
||||
__LINE__, result, STRERROR(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
mblock->malloc_chain_head = NULL;
|
||||
mblock->free_chain_head = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fast_mblock_prealloc(struct fast_mblock_man *mblock)
|
||||
{
|
||||
struct fast_mblock_node *pNode;
|
||||
struct fast_mblock_malloc *pMallocNode;
|
||||
char *pNew;
|
||||
char *pTrunkStart;
|
||||
char *p;
|
||||
char *pLast;
|
||||
int block_size;
|
||||
int alloc_size;
|
||||
|
||||
block_size = MEM_ALIGN(sizeof(struct fast_mblock_node) + \
|
||||
mblock->element_size);
|
||||
alloc_size = sizeof(struct fast_mblock_malloc) + block_size * \
|
||||
mblock->alloc_elements_once;
|
||||
|
||||
pNew = (char *)malloc(alloc_size);
|
||||
if (pNew == NULL)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"malloc %d bytes fail, " \
|
||||
"errno: %d, error info: %s", \
|
||||
__LINE__, alloc_size, errno, STRERROR(errno));
|
||||
return errno != 0 ? errno : ENOMEM;
|
||||
}
|
||||
memset(pNew, 0, alloc_size);
|
||||
|
||||
pMallocNode = (struct fast_mblock_malloc *)pNew;
|
||||
|
||||
pTrunkStart = pNew + sizeof(struct fast_mblock_malloc);
|
||||
pLast = pNew + (alloc_size - block_size);
|
||||
for (p=pTrunkStart; p<pLast; p += block_size)
|
||||
{
|
||||
pNode = (struct fast_mblock_node *)p;
|
||||
pNode->next = (struct fast_mblock_node *)(p + block_size);
|
||||
}
|
||||
|
||||
((struct fast_mblock_node *)pLast)->next = NULL;
|
||||
mblock->free_chain_head = (struct fast_mblock_node *)pTrunkStart;
|
||||
|
||||
pMallocNode->next = mblock->malloc_chain_head;
|
||||
mblock->malloc_chain_head = pMallocNode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fast_mblock_destroy(struct fast_mblock_man *mblock)
|
||||
{
|
||||
struct fast_mblock_malloc *pMallocNode;
|
||||
struct fast_mblock_malloc *pMallocTmp;
|
||||
|
||||
if (mblock->malloc_chain_head == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pMallocNode = mblock->malloc_chain_head;
|
||||
while (pMallocNode != NULL)
|
||||
{
|
||||
pMallocTmp = pMallocNode;
|
||||
pMallocNode = pMallocNode->next;
|
||||
|
||||
free(pMallocTmp);
|
||||
}
|
||||
mblock->malloc_chain_head = NULL;
|
||||
mblock->free_chain_head = NULL;
|
||||
|
||||
pthread_mutex_destroy(&(mblock->lock));
|
||||
}
|
||||
|
||||
struct fast_mblock_node *fast_mblock_alloc(struct fast_mblock_man *mblock)
|
||||
{
|
||||
struct fast_mblock_node *pNode;
|
||||
int result;
|
||||
|
||||
if ((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 NULL;
|
||||
}
|
||||
|
||||
if (mblock->free_chain_head != NULL)
|
||||
{
|
||||
pNode = mblock->free_chain_head;
|
||||
mblock->free_chain_head = pNode->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((result=fast_mblock_prealloc(mblock)) == 0)
|
||||
{
|
||||
pNode = mblock->free_chain_head;
|
||||
mblock->free_chain_head = pNode->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNode = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((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 pNode;
|
||||
}
|
||||
|
||||
int fast_mblock_free(struct fast_mblock_man *mblock, \
|
||||
struct fast_mblock_node *pNode)
|
||||
{
|
||||
int result;
|
||||
|
||||
if ((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->next = mblock->free_chain_head;
|
||||
mblock->free_chain_head = pNode;
|
||||
|
||||
if ((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;
|
||||
}
|
||||
|
||||
int fast_mblock_count(struct fast_mblock_man *mblock)
|
||||
{
|
||||
struct fast_mblock_node *pNode;
|
||||
int count;
|
||||
int result;
|
||||
|
||||
if ((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 -1;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
pNode = mblock->free_chain_head;
|
||||
while (pNode != NULL)
|
||||
{
|
||||
pNode = pNode->next;
|
||||
count++;
|
||||
}
|
||||
|
||||
if ((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 count;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* Copyright (C) 2008 Happy Fish / YuQing
|
||||
*
|
||||
* FastDFS may be copied only under the terms of the GNU General
|
||||
* Public License V3, which may be found in the FastDFS source kit.
|
||||
* Please visit the FastDFS Home Page http://www.csource.org/ for more detail.
|
||||
**/
|
||||
|
||||
//fast_mblock.h
|
||||
|
||||
#ifndef _FAST_MBLOCK_H
|
||||
#define _FAST_MBLOCK_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include "common_define.h"
|
||||
#include "chain.h"
|
||||
|
||||
/* free node chain */
|
||||
struct fast_mblock_node
|
||||
{
|
||||
struct fast_mblock_node *next;
|
||||
char data[0]; //the data buffer
|
||||
};
|
||||
|
||||
/* malloc chain */
|
||||
struct fast_mblock_malloc
|
||||
{
|
||||
struct fast_mblock_malloc *next;
|
||||
};
|
||||
|
||||
struct fast_mblock_man
|
||||
{
|
||||
struct fast_mblock_node *free_chain_head; //free node chain
|
||||
struct fast_mblock_malloc *malloc_chain_head; //malloc chain to be freed
|
||||
int element_size; //element size
|
||||
int alloc_elements_once; //alloc elements once
|
||||
pthread_mutex_t lock; //the lock for read / write free node chain
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
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 once
|
||||
return error no, 0 for success, != 0 fail
|
||||
*/
|
||||
int fast_mblock_init(struct fast_mblock_man *mblock, const int element_size, \
|
||||
const int alloc_elements_once);
|
||||
|
||||
/**
|
||||
mblock destroy
|
||||
parameters:
|
||||
mblock: the mblock pointer
|
||||
*/
|
||||
void fast_mblock_destroy(struct fast_mblock_man *mblock);
|
||||
|
||||
/**
|
||||
alloc a node from the mblock
|
||||
parameters:
|
||||
mblock: the mblock pointer
|
||||
return the alloced node, return NULL if fail
|
||||
*/
|
||||
struct fast_mblock_node *fast_mblock_alloc(struct fast_mblock_man *mblock);
|
||||
|
||||
/**
|
||||
free a node (put a node to the mblock)
|
||||
parameters:
|
||||
mblock: the mblock pointer
|
||||
pNode: the node to free
|
||||
return the alloced node, return NULL if fail
|
||||
*/
|
||||
int fast_mblock_free(struct fast_mblock_man *mblock, \
|
||||
struct fast_mblock_node *pNode);
|
||||
|
||||
/**
|
||||
get node count of the mblock
|
||||
parameters:
|
||||
mblock: the mblock pointer
|
||||
return the free node count of the mblock, return -1 if fail
|
||||
*/
|
||||
int fast_mblock_count(struct fast_mblock_man *mblock);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
Reference in New Issue