added pooled memory allocator taking code from tre for tre porting

This commit is contained in:
hyung-hwan 2011-05-23 09:03:30 +00:00
parent 483ce8b5bb
commit bc941f10db
6 changed files with 270 additions and 17 deletions

View File

@ -16,6 +16,7 @@ pkginclude_HEADERS = \
oht.h \
opt.h \
pio.h \
pma.h \
rbt.h \
rex.h \
sio.h \

View File

@ -51,9 +51,9 @@ CONFIG_CLEAN_VPATH_FILES =
SOURCES =
DIST_SOURCES =
am__pkginclude_HEADERS_DIST = alg.h chr.h dll.h fio.h fma.h gdl.h \
htb.h lda.h main.h map.h mem.h misc.h oht.h opt.h pio.h rbt.h \
rex.h sio.h sll.h stdio.h str.h time.h tio.h xma.h Mmgr.hpp \
StdMmgr.hpp Mmged.hpp
htb.h lda.h main.h map.h mem.h misc.h oht.h opt.h pio.h pma.h \
rbt.h rex.h sio.h sll.h stdio.h str.h time.h tio.h xma.h \
Mmgr.hpp StdMmgr.hpp Mmged.hpp
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@ -219,8 +219,8 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
pkginclude_HEADERS = alg.h chr.h dll.h fio.h fma.h gdl.h htb.h lda.h \
main.h map.h mem.h misc.h oht.h opt.h pio.h rbt.h rex.h sio.h \
sll.h stdio.h str.h time.h tio.h xma.h $(am__append_1)
main.h map.h mem.h misc.h oht.h opt.h pio.h pma.h rbt.h rex.h \
sio.h sll.h stdio.h str.h time.h tio.h xma.h $(am__append_1)
all: all-am
.SUFFIXES:

100
qse/include/qse/cmn/pma.h Normal file
View File

@ -0,0 +1,100 @@
/*
* $Id$
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
QSE is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
QSE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
*/
/*
tre-mem.h - TRE memory allocator interface
This software is released under a BSD-style license.
See the file LICENSE for details and copyright.
*/
#ifndef _QSE_CMN_PMA_H_
#define _QSE_CMN_PMA_H_
#include <qse/types.h>
#include <qse/macros.h>
#define QSE_PMA_BLOCK_SIZE 1024
typedef struct qse_pma_blk_t qse_pma_blk_t;
struct qse_pma_blk_t
{
void *data;
qse_pma_blk_t* next;
};
typedef struct qse_pma_t qse_pma_t;
struct qse_pma_t
{
QSE_DEFINE_COMMON_FIELDS (pma)
qse_pma_blk_t* blocks;
qse_pma_blk_t* current;
char *ptr;
qse_size_t n;
int failed;
};
#ifdef __cplusplus
extern "C" {
#endif
QSE_DEFINE_COMMON_FUNCTIONS (pma)
qse_pma_t* qse_pma_open (
qse_mmgr_t* mmgr, /**< memory manager */
qse_size_t xtnsize /**< extension size in bytes */
);
void qse_pma_close (
qse_pma_t* pma /**< memory allocator */
);
qse_pma_t* qse_pma_init (
qse_pma_t* pma, /**< memory allocator */
qse_mmgr_t* mmgr /**< memory manager */
);
void qse_pma_fini (
qse_pma_t* pma /**< memory allocator */
);
void* qse_pma_alloc (
qse_pma_t* pma,
qse_size_t size
);
void* qse_pma_realloc (
qse_pma_t* pma, /**< memory allocator */
void* blk, /**< memory block */
qse_size_t size /**< new size in bytes */
);
void qse_pma_free (
qse_pma_t* pma, /**< memory allocator */
void* blk /**< memory block */
);
#endif

View File

@ -8,7 +8,7 @@ AM_CPPFLAGS = \
lib_LTLIBRARIES = libqsecmn.la
libqsecmn_la_SOURCES = \
syscall.h mem.h \
mem.c xma.c fma.c chr.c chr_cnv.c rex.c \
mem.c xma.c fma.c pma.c chr.c chr_cnv.c rex.c \
str_beg.c str_cat.c str_chr.c str_cnv.c str_cmp.c str_cpy.c \
str_del.c str_dup.c str_dynm.c str_dynw.c str_end.c str_excl.c \
str_fcpy.c str_incl.c str_len.c str_pac.c str_pbrk.c str_put.c \

View File

@ -72,16 +72,16 @@ am__base_list = \
am__installdirs = "$(DESTDIR)$(libdir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libqsecmn_la_DEPENDENCIES =
am_libqsecmn_la_OBJECTS = mem.lo xma.lo fma.lo chr.lo chr_cnv.lo \
rex.lo str_beg.lo str_cat.lo str_chr.lo str_cnv.lo str_cmp.lo \
str_cpy.lo str_del.lo str_dup.lo str_dynm.lo str_dynw.lo \
str_end.lo str_excl.lo str_fcpy.lo str_incl.lo str_len.lo \
str_pac.lo str_pbrk.lo str_put.lo str_rev.lo str_rot.lo \
str_set.lo str_spl.lo str_spn.lo str_str.lo str_subst.lo \
str_tok.lo str_trm.lo str_word.lo lda.lo oht.lo htb.lo rbt.lo \
sll.lo gdl.lo dll.lo opt.lo tio.lo tio_get.lo tio_put.lo \
fio.lo pio.lo sio.lo alg_search.lo alg_sort.lo time.lo misc.lo \
assert.lo main.lo stdio.lo
am_libqsecmn_la_OBJECTS = mem.lo xma.lo fma.lo pma.lo chr.lo \
chr_cnv.lo rex.lo str_beg.lo str_cat.lo str_chr.lo str_cnv.lo \
str_cmp.lo str_cpy.lo str_del.lo str_dup.lo str_dynm.lo \
str_dynw.lo str_end.lo str_excl.lo str_fcpy.lo str_incl.lo \
str_len.lo str_pac.lo str_pbrk.lo str_put.lo str_rev.lo \
str_rot.lo str_set.lo str_spl.lo str_spn.lo str_str.lo \
str_subst.lo str_tok.lo str_trm.lo str_word.lo lda.lo oht.lo \
htb.lo rbt.lo sll.lo gdl.lo dll.lo opt.lo tio.lo tio_get.lo \
tio_put.lo fio.lo pio.lo sio.lo alg_search.lo alg_sort.lo \
time.lo misc.lo assert.lo main.lo stdio.lo
libqsecmn_la_OBJECTS = $(am_libqsecmn_la_OBJECTS)
libqsecmn_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@ -268,7 +268,7 @@ AM_CPPFLAGS = \
lib_LTLIBRARIES = libqsecmn.la $(am__append_1)
libqsecmn_la_SOURCES = \
syscall.h mem.h \
mem.c xma.c fma.c chr.c chr_cnv.c rex.c \
mem.c xma.c fma.c pma.c chr.c chr_cnv.c rex.c \
str_beg.c str_cat.c str_chr.c str_cnv.c str_cmp.c str_cpy.c \
str_del.c str_dup.c str_dynm.c str_dynw.c str_end.c str_excl.c \
str_fcpy.c str_incl.c str_len.c str_pac.c str_pbrk.c str_put.c \
@ -386,6 +386,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oht.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pio.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pma.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rbt.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rex.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sio.Plo@am__quote@

151
qse/lib/cmn/pma.c Normal file
View File

@ -0,0 +1,151 @@
/*
* $Id$
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
QSE is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
QSE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
*/
/*
tre-mem.c - TRE memory allocator
This software is released under a BSD-style license.
See the file LICENSE for details and copyright.
*/
/*
This memory allocator is for allocating small memory blocks efficiently
in terms of memory overhead and execution speed. The allocated blocks
cannot be freed individually, only all at once. There can be multiple
allocators, though.
*/
#include <qse/cmn/pma.h>
#include "mem.h"
#define ALIGN(x,size) ((((x) + (size) - 1) / (size)) * (size))
QSE_IMPLEMENT_COMMON_FUNCTIONS (pma)
qse_pma_t* qse_pma_init (qse_pma_t* pma, qse_mmgr_t* mmgr)
{
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
QSE_MEMSET (pma, 0, QSE_SIZEOF(*pma));
pma->mmgr = mmgr;
return pma;
}
/* Frees the memory allocator and all memory allocated with it. */
void qse_pma_fini (qse_pma_t* pma)
{
qse_pma_blk_t* tmp, * l = pma->blocks;
while (l != QSE_NULL)
{
QSE_MMGR_FREE (pma->mmgr, l->data);
tmp = l->next;
QSE_MMGR_FREE (pma->mmgr, l);
l = tmp;
}
}
/* Returns a new memory allocator or NULL if out of memory. */
qse_pma_t* qse_pma_open (qse_mmgr_t* mmgr, qse_size_t xtnsize)
{
qse_pma_t* pma;
pma = (qse_pma_t*)QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(*pma) + xtnsize);
if (pma == QSE_NULL) return QSE_NULL;
if (qse_pma_init (pma, mmgr) == QSE_NULL)
{
QSE_MMGR_FREE (mmgr, pma);
return QSE_NULL;
}
return pma;
}
void qse_pma_close (qse_pma_t* pma)
{
qse_pma_fini (pma);
QSE_MMGR_FREE (pma->mmgr, pma);
}
/* Allocates a block of `size' bytes from `mem'. Returns a pointer to the
allocated block or NULL if an underlying malloc() failed. */
void* qse_pma_alloc (qse_pma_t* pma, qse_size_t size)
{
void *ptr;
if (pma->failed) return QSE_NULL;
if (pma->n < size)
{
/* We need more memory than is available in the current block.
Allocate a new block. */
qse_pma_blk_t* l;
int block_size;
if (size * 8 > QSE_PMA_BLOCK_SIZE)
block_size = size * 8;
else
block_size = QSE_PMA_BLOCK_SIZE;
l = QSE_MMGR_ALLOC (pma->mmgr, QSE_SIZEOF(*l));
if (l == QSE_NULL)
{
pma->failed = 1;
return QSE_NULL;
}
l->data = QSE_MMGR_ALLOC (pma->mmgr, block_size);
if (l->data == QSE_NULL)
{
QSE_MMGR_FREE (pma->mmgr, l);
pma->failed = 1;
return QSE_NULL;
}
l->next = QSE_NULL;
if (pma->current != QSE_NULL) pma->current->next = l;
if (pma->blocks == QSE_NULL) pma->blocks = l;
pma->current = l;
pma->ptr = l->data;
pma->n = block_size;
}
/* Make sure the next pointer will be aligned. */
size += ALIGN((long)(pma->ptr + size), QSE_SIZEOF(long));
/* Allocate from current block. */
ptr = pma->ptr;
pma->ptr += size;
pma->n -= size;
return ptr;
}
void* qse_pma_realloc (qse_pma_t* pma, void* blk, qse_size_t size)
{
/* do nothing. you can't resize an individual memory chunk */
return QSE_NULL;
}
void qse_pma_free (qse_pma_t* pma, void* blk)
{
/* do nothing. you can't free an individual memory chunk */
}