add fast_allocator

pull/5/head
Yu Qing 2015-11-04 17:19:36 +08:00
parent 0fe90e35da
commit fb5abf5927
4 changed files with 301 additions and 3 deletions

View File

@ -8,6 +8,7 @@ Version 1.23 2015-11-04
ONLY support Linux and FreeBSD
* delay task can execute in a new thread
* fast_mblock reclaimed object pool
* add fast_allocator
Version 1.22 2015-10-10
* export php function: fastcommon_get_first_local_ip

View File

@ -10,21 +10,21 @@ FAST_SHARED_OBJS = hash.lo chain.lo shared_func.lo ini_file_reader.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_mpool.lo
connection_pool.lo fast_mpool.lo fast_allocator.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_mpool.o
connection_pool.o fast_mpool.o fast_allocator.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_define.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_mpool.h
connection_pool.h fast_mpool.h fast_allocator.h
ALL_OBJS = $(FAST_STATIC_OBJS) $(FAST_SHARED_OBJS)

200
src/fast_allocator.c Normal file
View File

@ -0,0 +1,200 @@
//fast_allocator.c
#include <errno.h>
#include <pthread.h>
#include "logger.h"
#include "shared_func.h"
#include "fast_allocator.h"
static int region_init(struct fast_allocator_context *acontext,
struct fast_region_info *region)
{
int result;
int bytes;
int element_size;
int allocator_count;
struct fast_mblock_man *mblock;
allocator_count = (region->end - region->start) / region->step;
bytes = sizeof(struct fast_mblock_man) * allocator_count;
region->allocators = (struct fast_mblock_man *)malloc(bytes);
if (region->allocators == NULL)
{
result = errno != 0 ? errno : ENOMEM;
logError("file: "__FILE__", line: %d, "
"malloc %d bytes fail, errno: %d, error info: %s",
__LINE__, bytes, result, STRERROR(result));
return result;
}
memset(region->allocators, 0, bytes);
result = 0;
mblock = region->allocators;
for (element_size=region->start+region->step; element_size<=region->end;
element_size+=region->step,mblock++)
{
result = fast_mblock_init_ex(mblock, element_size,
region->alloc_elements_once, NULL, acontext->need_lock);
if (result != 0)
{
break;
}
}
return result;
}
static void region_destroy(struct fast_allocator_context *acontext,
struct fast_region_info *region)
{
int element_size;
int allocator_count;
struct fast_mblock_man *mblock;
allocator_count = (region->end - region->start) / region->step;
mblock = region->allocators;
for (element_size=region->start+region->step; element_size<=region->end;
element_size+=region->step,mblock++)
{
fast_mblock_destroy(mblock);
}
free(region->allocators);
region->allocators = NULL;
}
int fast_allocator_init_ex(struct fast_allocator_context *acontext,
struct fast_region_info *regions, const int region_count,
const bool need_lock)
{
int result;
int bytes;
int previous_end;
struct fast_region_info *pRegion;
struct fast_region_info *region_end;
memset(acontext, 0, sizeof(*acontext));
if (region_count <= 0)
{
return EINVAL;
}
bytes = sizeof(struct fast_region_info) * region_count;
acontext->regions = (struct fast_region_info *)malloc(bytes);
if (acontext->regions == NULL)
{
result = errno != 0 ? errno : ENOMEM;
logError("file: "__FILE__", line: %d, "
"malloc %d bytes fail, errno: %d, error info: %s",
__LINE__, bytes, result, STRERROR(result));
return result;
}
memcpy(acontext->regions, regions, bytes);
acontext->region_count = region_count;
acontext->need_lock = need_lock;
result = 0;
previous_end = 0;
region_end = acontext->regions + acontext->region_count;
for (pRegion=acontext->regions; pRegion<region_end; pRegion++)
{
if (pRegion->start != previous_end)
{
logError("file: "__FILE__", line: %d, "
"invalid start: %d != last end: %d",
__LINE__, pRegion->start, previous_end);
result = EINVAL;
break;
}
if (pRegion->start >= pRegion->end)
{
logError("file: "__FILE__", line: %d, "
"invalid start: %d >= end: %d",
__LINE__, pRegion->start, pRegion->end);
result = EINVAL;
break;
}
if (pRegion->step <= 0)
{
logError("file: "__FILE__", line: %d, "
"invalid step: %d",
__LINE__, pRegion->step);
result = EINVAL;
break;
}
if (pRegion->start % pRegion->step != 0)
{
logError("file: "__FILE__", line: %d, "
"invalid start: %d, must multiple of step: %d",
__LINE__, pRegion->start, pRegion->step);
result = EINVAL;
break;
}
if (pRegion->end % pRegion->step != 0)
{
logError("file: "__FILE__", line: %d, "
"invalid end: %d, must multiple of step: %d",
__LINE__, pRegion->end, pRegion->step);
result = EINVAL;
break;
}
previous_end = pRegion->end;
if ((result=region_init(acontext, pRegion)) != 0)
{
break;
}
}
return result;
}
#define INIT_REGION(region, _start, _end, _step, _alloc_once) \
do { \
region.start = _start; \
region.end = _end; \
region.step = _step; \
region.alloc_elements_once = _alloc_once; \
} while(0)
int fast_allocator_init(struct fast_allocator_context *acontext,
const bool need_lock)
{
#define DEFAULT_REGION_COUNT 6
struct fast_region_info regions[DEFAULT_REGION_COUNT];
INIT_REGION(regions[0], 0, 256, 8, 4096);
INIT_REGION(regions[1], 256, 1024, 16, 1024);
INIT_REGION(regions[2], 1024, 4096, 64, 256);
INIT_REGION(regions[3], 4096, 16384, 256, 64);
INIT_REGION(regions[4], 16384, 65536, 1024, 16);
return fast_allocator_init_ex(acontext, regions,
DEFAULT_REGION_COUNT, need_lock);
}
void fast_allocator_destroy(struct fast_allocator_context *acontext)
{
struct fast_region_info *pRegion;
struct fast_region_info *region_end;
region_end = acontext->regions + acontext->region_count;
for (pRegion=acontext->regions; pRegion<region_end; pRegion++)
{
region_destroy(acontext, pRegion);
}
free(acontext->regions);
acontext->regions = NULL;
}
void* fast_allocator_alloc(struct fast_allocator_context *acontext,
const int bytes)
{
return NULL;
}
void fast_allocator_free(struct fast_allocator_context *acontext, void *ptr)
{
}

97
src/fast_allocator.h Normal file
View File

@ -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_allocator.h
#ifndef _FAST_ALLOCATOR_H
#define _FAST_ALLOCATOR_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "common_define.h"
#include "fast_mblock.h"
struct fast_region_info
{
int start;
int end;
int step;
int alloc_elements_once;
struct fast_mblock_man *allocators;
};
struct fast_allocator_context
{
struct fast_region_info *regions;
int region_count;
int64_t alloc_bytes;
bool need_lock; //if need mutex lock for acontext
};
#ifdef __cplusplus
extern "C" {
#endif
/**
allocator init by default region allocators
parameters:
acontext: the context pointer
need_lock: if need lock
return error no, 0 for success, != 0 fail
*/
int fast_allocator_init(struct fast_allocator_context *acontext,
const bool need_lock);
/**
allocator init
parameters:
acontext: the context pointer
regions: the region array
region_count: the region count
need_lock: if need lock
return error no, 0 for success, != 0 fail
*/
int fast_allocator_init_ex(struct fast_allocator_context *acontext,
struct fast_region_info *regions, const int region_count,
const bool need_lock);
/**
allocator destroy
parameters:
acontext: the context pointer
*/
void fast_allocator_destroy(struct fast_allocator_context *acontext);
/**
alloc memory from the context
parameters:
acontext: the context pointer
bytes: alloc bytes
return the alloced pointer, return NULL if fail
*/
void* fast_allocator_alloc(struct fast_allocator_context *acontext,
const int bytes);
/**
free a node (put a node to the context)
parameters:
acontext: the context pointer
ptr: the pointer to free
return none
*/
void fast_allocator_free(struct fast_allocator_context *acontext, void *ptr);
#ifdef __cplusplus
}
#endif
#endif