add fast_allocator
parent
0fe90e35da
commit
fb5abf5927
1
HISTORY
1
HISTORY
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
Loading…
Reference in New Issue