add fast_mpool for memory pool
parent
693874d0b9
commit
59fbe9214a
|
|
@ -8,19 +8,22 @@ 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_mblock.lo connection_pool.lo
|
||||
fast_timer.lo process_ctrl.lo fast_mblock.lo \
|
||||
connection_pool.lo fast_mpool.lo
|
||||
|
||||
FAST_STATIC_OBJS = hash.o chain.o shared_func.o ini_file_reader.o \
|
||||
logger.o sockopt.o base64.o sched_thread.o \
|
||||
http_func.o md5.o pthread_func.o local_ip_func.o \
|
||||
avl_tree.o ioevent.o ioevent_loop.o fast_task_queue.o \
|
||||
fast_timer.o process_ctrl.o fast_mblock.o connection_pool.o
|
||||
fast_timer.o process_ctrl.o fast_mblock.o \
|
||||
connection_pool.o fast_mpool.o
|
||||
|
||||
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_mblock.h connection_pool.h
|
||||
fast_timer.h process_ctrl.h fast_mblock.h \
|
||||
connection_pool.h fast_mpool.h
|
||||
|
||||
ALL_OBJS = $(STATIC_OBJS) $(FAST_SHARED_OBJS)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,211 @@
|
|||
//fast_mpool.c
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/resource.h>
|
||||
#include <pthread.h>
|
||||
#include <assert.h>
|
||||
#include "fast_mpool.h"
|
||||
#include "logger.h"
|
||||
#include "shared_func.h"
|
||||
#include "pthread_func.h"
|
||||
#include "sched_thread.h"
|
||||
|
||||
int fast_mpool_init(struct fast_mpool_man *mpool,
|
||||
const int alloc_size_once, const int discard_size)
|
||||
{
|
||||
if (alloc_size_once > 0)
|
||||
{
|
||||
mpool->alloc_size_once = alloc_size_once;
|
||||
}
|
||||
else
|
||||
{
|
||||
mpool->alloc_size_once = 1024 * 1024;
|
||||
}
|
||||
|
||||
if (discard_size > 0)
|
||||
{
|
||||
mpool->discard_size = discard_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
mpool->discard_size = 64;
|
||||
}
|
||||
|
||||
mpool->malloc_chain_head = NULL;
|
||||
mpool->free_chain_head = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fast_mpool_prealloc(struct fast_mpool_man *mpool,
|
||||
const int alloc_size)
|
||||
{
|
||||
struct fast_mpool_malloc *pMallocNode;
|
||||
int bytes;
|
||||
|
||||
bytes = sizeof(struct fast_mpool_malloc) + alloc_size;
|
||||
pMallocNode = (struct fast_mpool_malloc *)malloc(bytes);
|
||||
if (pMallocNode == NULL)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, " \
|
||||
"malloc %d bytes fail, " \
|
||||
"errno: %d, error info: %s", \
|
||||
__LINE__, bytes, errno, STRERROR(errno));
|
||||
return errno != 0 ? errno : ENOMEM;
|
||||
}
|
||||
|
||||
pMallocNode->alloc_size = alloc_size;
|
||||
pMallocNode->base_ptr = (char *)(pMallocNode + 1);
|
||||
pMallocNode->end_ptr = pMallocNode->base_ptr + alloc_size;
|
||||
pMallocNode->free_ptr = pMallocNode->base_ptr;
|
||||
|
||||
pMallocNode->free_next = mpool->free_chain_head;
|
||||
mpool->free_chain_head = pMallocNode;
|
||||
|
||||
pMallocNode->malloc_next = mpool->malloc_chain_head;
|
||||
mpool->malloc_chain_head = pMallocNode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fast_mpool_destroy(struct fast_mpool_man *mpool)
|
||||
{
|
||||
struct fast_mpool_malloc *pMallocNode;
|
||||
struct fast_mpool_malloc *pMallocTmp;
|
||||
|
||||
if (mpool->malloc_chain_head == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pMallocNode = mpool->malloc_chain_head;
|
||||
while (pMallocNode != NULL)
|
||||
{
|
||||
pMallocTmp = pMallocNode;
|
||||
pMallocNode = pMallocNode->malloc_next;
|
||||
|
||||
free(pMallocTmp);
|
||||
}
|
||||
mpool->malloc_chain_head = NULL;
|
||||
mpool->free_chain_head = NULL;
|
||||
}
|
||||
|
||||
static void fast_mpool_remove_free_node(struct fast_mpool_man *mpool,
|
||||
struct fast_mpool_malloc *pMallocNode)
|
||||
{
|
||||
struct fast_mpool_malloc *previous;
|
||||
|
||||
if (mpool->free_chain_head == pMallocNode)
|
||||
{
|
||||
mpool->free_chain_head = pMallocNode->free_next;
|
||||
return;
|
||||
}
|
||||
|
||||
previous = mpool->free_chain_head;
|
||||
while (previous->free_next != NULL)
|
||||
{
|
||||
if (previous->free_next == pMallocNode)
|
||||
{
|
||||
previous->free_next = pMallocNode->free_next;
|
||||
return;
|
||||
}
|
||||
previous = previous->free_next;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void *fast_mpool_do_alloc(struct fast_mpool_man *mpool,
|
||||
struct fast_mpool_malloc *pMallocNode, const int size)
|
||||
{
|
||||
void *ptr;
|
||||
if ((int)(pMallocNode->end_ptr - pMallocNode->free_ptr) >= size)
|
||||
{
|
||||
ptr = pMallocNode->free_ptr;
|
||||
pMallocNode->free_ptr += size;
|
||||
if ((int)(pMallocNode->end_ptr - pMallocNode->free_ptr) <=
|
||||
mpool->discard_size)
|
||||
{
|
||||
fast_mpool_remove_free_node(mpool, pMallocNode);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *fast_mpool_alloc(struct fast_mpool_man *mpool, const int size)
|
||||
{
|
||||
struct fast_mpool_malloc *pMallocNode;
|
||||
void *ptr;
|
||||
int result;
|
||||
int alloc_size;
|
||||
|
||||
pMallocNode = mpool->free_chain_head;
|
||||
while (pMallocNode != NULL)
|
||||
{
|
||||
if ((ptr=fast_mpool_do_alloc(mpool, pMallocNode, size)) != NULL)
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
pMallocNode = pMallocNode->free_next;
|
||||
}
|
||||
|
||||
if (size < mpool->alloc_size_once)
|
||||
{
|
||||
alloc_size = mpool->alloc_size_once;
|
||||
}
|
||||
else
|
||||
{
|
||||
alloc_size = size;
|
||||
}
|
||||
if ((result=fast_mpool_prealloc(mpool, alloc_size)) == 0)
|
||||
{
|
||||
return fast_mpool_do_alloc(mpool, mpool->free_chain_head, size);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void fast_mpool_reset(struct fast_mpool_man *mpool)
|
||||
{
|
||||
struct fast_mpool_malloc *pMallocNode;
|
||||
|
||||
mpool->free_chain_head = NULL;
|
||||
pMallocNode = mpool->malloc_chain_head;
|
||||
while (pMallocNode != NULL)
|
||||
{
|
||||
pMallocNode->free_ptr = pMallocNode->base_ptr;
|
||||
|
||||
pMallocNode->free_next = mpool->free_chain_head;
|
||||
mpool->free_chain_head = pMallocNode;
|
||||
|
||||
pMallocNode = pMallocNode->malloc_next;
|
||||
}
|
||||
}
|
||||
|
||||
void fast_mpool_stats(struct fast_mpool_man *mpool, struct fast_mpool_stats *stats)
|
||||
{
|
||||
struct fast_mpool_malloc *pMallocNode;
|
||||
|
||||
stats->total_bytes = 0;
|
||||
stats->free_bytes = 0;
|
||||
stats->total_trunk_count = 0;
|
||||
stats->free_trunk_count = 0;
|
||||
|
||||
pMallocNode = mpool->malloc_chain_head;
|
||||
while (pMallocNode != NULL)
|
||||
{
|
||||
stats->total_bytes += pMallocNode->alloc_size;
|
||||
stats->free_bytes += (int)(pMallocNode->end_ptr - pMallocNode->free_ptr);
|
||||
stats->total_trunk_count++;
|
||||
|
||||
pMallocNode = pMallocNode->malloc_next;
|
||||
}
|
||||
|
||||
pMallocNode = mpool->free_chain_head;
|
||||
while (pMallocNode != NULL)
|
||||
{
|
||||
stats->free_trunk_count++;
|
||||
pMallocNode = pMallocNode->free_next;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/**
|
||||
* 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_mpool.h
|
||||
|
||||
#ifndef _FAST_MPOOL_H
|
||||
#define _FAST_MPOOL_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include "common_define.h"
|
||||
|
||||
/* malloc chain */
|
||||
struct fast_mpool_malloc
|
||||
{
|
||||
int alloc_size;
|
||||
char *base_ptr;
|
||||
char *end_ptr;
|
||||
char *free_ptr;
|
||||
struct fast_mpool_malloc *malloc_next;
|
||||
struct fast_mpool_malloc *free_next;
|
||||
};
|
||||
|
||||
struct fast_mpool_man
|
||||
{
|
||||
struct fast_mpool_malloc *malloc_chain_head; //malloc chain to be freed
|
||||
struct fast_mpool_malloc *free_chain_head; //free node chain
|
||||
int alloc_size_once; //alloc size once, default: 1MB
|
||||
int discard_size; //discard size, default: 64 bytes
|
||||
};
|
||||
|
||||
struct fast_mpool_stats
|
||||
{
|
||||
int64_t total_bytes;
|
||||
int64_t free_bytes;
|
||||
int total_trunk_count;
|
||||
int free_trunk_count;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
mpool init
|
||||
parameters:
|
||||
mpool: the mpool pointer
|
||||
alloc_size_once: malloc elements once, 0 for malloc 1MB memory once
|
||||
discard_size: discard when remain size <= discard_size, 0 for 8 bytes
|
||||
return error no, 0 for success, != 0 fail
|
||||
*/
|
||||
int fast_mpool_init(struct fast_mpool_man *mpool,
|
||||
const int alloc_size_once, const int discard_size);
|
||||
|
||||
/**
|
||||
mpool destroy
|
||||
parameters:
|
||||
mpool: the mpool pointer
|
||||
*/
|
||||
void fast_mpool_destroy(struct fast_mpool_man *mpool);
|
||||
|
||||
/**
|
||||
free a node (put a node to the mpool)
|
||||
parameters:
|
||||
mpool: the mpool pointer
|
||||
pNode: the node to free
|
||||
*/
|
||||
void fast_mpool_reset(struct fast_mpool_man *mpool);
|
||||
|
||||
/**
|
||||
alloc a node from the mpool
|
||||
parameters:
|
||||
mpool: the mpool pointer
|
||||
return the alloced ptr, return NULL if fail
|
||||
*/
|
||||
void *fast_mpool_alloc(struct fast_mpool_man *mpool, const int size);
|
||||
|
||||
/**
|
||||
get stats
|
||||
parameters:
|
||||
mpool: the mpool pointer
|
||||
*/
|
||||
void fast_mpool_stats(struct fast_mpool_man *mpool, struct fast_mpool_stats *stats);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
Reference in New Issue