diff --git a/qse/include/qse/cmn/pma.h b/qse/include/qse/cmn/pma.h index d6af449c..42dbcb37 100644 --- a/qse/include/qse/cmn/pma.h +++ b/qse/include/qse/cmn/pma.h @@ -86,6 +86,12 @@ void* qse_pma_alloc ( qse_size_t size ); +void* qse_pma_calloc ( + qse_pma_t* pma, + qse_size_t size +); + + void* qse_pma_realloc ( qse_pma_t* pma, /**< memory allocator */ void* blk, /**< memory block */ diff --git a/qse/lib/cmn/pma.c b/qse/lib/cmn/pma.c index d05deefc..c5cc5686 100644 --- a/qse/lib/cmn/pma.c +++ b/qse/lib/cmn/pma.c @@ -18,6 +18,11 @@ License along with QSE. If not, see . */ +/* + * This is the TRE memory allocator modified for QSE. + * See the original license notice below. + */ + /* tre-mem.c - TRE memory allocator @@ -35,35 +40,15 @@ #include #include "mem.h" -#define ALIGN(x,size) ((((x) + (size) - 1) / (size)) * (size)) +/* Returns number of bytes to add to (char *)ptr to make it + properly aligned for the type. */ +#define ALIGN(ptr, type) \ + ((((long)ptr) % sizeof(type))? \ + (sizeof(type) - (((long)ptr) % QSE_SIZEOF(type))) : 0) + 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; @@ -86,6 +71,31 @@ void qse_pma_close (qse_pma_t* pma) QSE_MMGR_FREE (pma->mmgr, 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) + { + tmp = l->next; + QSE_MMGR_FREE (pma->mmgr, l); + l = tmp; + } +} + +/* Returns a new memory allocator or NULL if out of memory. */ + /* 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) @@ -106,19 +116,14 @@ void* qse_pma_alloc (qse_pma_t* pma, qse_size_t size) else block_size = QSE_PMA_BLOCK_SIZE; - l = QSE_MMGR_ALLOC (pma->mmgr, QSE_SIZEOF(*l)); + l = QSE_MMGR_ALLOC (pma->mmgr, QSE_SIZEOF(*l) + block_size); 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->data = (void*)(l + 1); + l->next = QSE_NULL; if (pma->current != QSE_NULL) pma->current->next = l; if (pma->blocks == QSE_NULL) pma->blocks = l; @@ -128,7 +133,7 @@ void* qse_pma_alloc (qse_pma_t* pma, qse_size_t size) } /* Make sure the next pointer will be aligned. */ - size += ALIGN((long)(pma->ptr + size), QSE_SIZEOF(long)); + size += ALIGN((long)(pma->ptr + size), long); /* Allocate from current block. */ ptr = pma->ptr; @@ -138,6 +143,13 @@ void* qse_pma_alloc (qse_pma_t* pma, qse_size_t size) return ptr; } +void* qse_pma_calloc (qse_pma_t* pma, qse_size_t size) +{ + void* ptr = qse_pma_alloc (pma, size); + if (size) QSE_MEMSET (ptr, 0, 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 */ diff --git a/qse/samples/cmn/Makefile.am b/qse/samples/cmn/Makefile.am index 9beb03a0..edb2f046 100644 --- a/qse/samples/cmn/Makefile.am +++ b/qse/samples/cmn/Makefile.am @@ -6,13 +6,14 @@ AM_CPPFLAGS = \ -I$(includedir) -bin_PROGRAMS = xma fma chr str sll dll lda oht htb rbt fio pio sio time main main2 rex01 env +bin_PROGRAMS = xma fma pma chr str sll dll lda oht htb rbt fio pio sio time main main2 rex01 env LDFLAGS = -L../../lib/cmn LDADD = -lqsecmn xma_SOURCES = xma.c fma_SOURCES = fma.c +pma_SOURCES = pma.c chr_SOURCES = chr.c str_SOURCES = str.c sll_SOURCES = sll.c diff --git a/qse/samples/cmn/Makefile.in b/qse/samples/cmn/Makefile.in index 222560ff..5897a535 100644 --- a/qse/samples/cmn/Makefile.in +++ b/qse/samples/cmn/Makefile.in @@ -34,11 +34,11 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -bin_PROGRAMS = xma$(EXEEXT) fma$(EXEEXT) chr$(EXEEXT) str$(EXEEXT) \ - sll$(EXEEXT) dll$(EXEEXT) lda$(EXEEXT) oht$(EXEEXT) \ - htb$(EXEEXT) rbt$(EXEEXT) fio$(EXEEXT) pio$(EXEEXT) \ - sio$(EXEEXT) time$(EXEEXT) main$(EXEEXT) main2$(EXEEXT) \ - rex01$(EXEEXT) env$(EXEEXT) +bin_PROGRAMS = xma$(EXEEXT) fma$(EXEEXT) pma$(EXEEXT) chr$(EXEEXT) \ + str$(EXEEXT) sll$(EXEEXT) dll$(EXEEXT) lda$(EXEEXT) \ + oht$(EXEEXT) htb$(EXEEXT) rbt$(EXEEXT) fio$(EXEEXT) \ + pio$(EXEEXT) sio$(EXEEXT) time$(EXEEXT) main$(EXEEXT) \ + main2$(EXEEXT) rex01$(EXEEXT) env$(EXEEXT) subdir = samples/cmn DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -98,6 +98,10 @@ am_pio_OBJECTS = pio.$(OBJEXT) pio_OBJECTS = $(am_pio_OBJECTS) pio_LDADD = $(LDADD) pio_DEPENDENCIES = +am_pma_OBJECTS = pma.$(OBJEXT) +pma_OBJECTS = $(am_pma_OBJECTS) +pma_LDADD = $(LDADD) +pma_DEPENDENCIES = am_rbt_OBJECTS = rbt.$(OBJEXT) rbt_OBJECTS = $(am_rbt_OBJECTS) rbt_LDADD = $(LDADD) @@ -141,14 +145,14 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(chr_SOURCES) $(dll_SOURCES) $(env_SOURCES) $(fio_SOURCES) \ $(fma_SOURCES) $(htb_SOURCES) $(lda_SOURCES) $(main_SOURCES) \ - $(main2_SOURCES) $(oht_SOURCES) $(pio_SOURCES) $(rbt_SOURCES) \ - $(rex01_SOURCES) $(sio_SOURCES) $(sll_SOURCES) $(str_SOURCES) \ - $(time_SOURCES) $(xma_SOURCES) + $(main2_SOURCES) $(oht_SOURCES) $(pio_SOURCES) $(pma_SOURCES) \ + $(rbt_SOURCES) $(rex01_SOURCES) $(sio_SOURCES) $(sll_SOURCES) \ + $(str_SOURCES) $(time_SOURCES) $(xma_SOURCES) DIST_SOURCES = $(chr_SOURCES) $(dll_SOURCES) $(env_SOURCES) \ $(fio_SOURCES) $(fma_SOURCES) $(htb_SOURCES) $(lda_SOURCES) \ $(main_SOURCES) $(main2_SOURCES) $(oht_SOURCES) $(pio_SOURCES) \ - $(rbt_SOURCES) $(rex01_SOURCES) $(sio_SOURCES) $(sll_SOURCES) \ - $(str_SOURCES) $(time_SOURCES) $(xma_SOURCES) + $(pma_SOURCES) $(rbt_SOURCES) $(rex01_SOURCES) $(sio_SOURCES) \ + $(sll_SOURCES) $(str_SOURCES) $(time_SOURCES) $(xma_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -302,6 +306,7 @@ AM_CPPFLAGS = \ LDADD = -lqsecmn xma_SOURCES = xma.c fma_SOURCES = fma.c +pma_SOURCES = pma.c chr_SOURCES = chr.c str_SOURCES = str.c sll_SOURCES = sll.c @@ -428,6 +433,9 @@ oht$(EXEEXT): $(oht_OBJECTS) $(oht_DEPENDENCIES) pio$(EXEEXT): $(pio_OBJECTS) $(pio_DEPENDENCIES) @rm -f pio$(EXEEXT) $(LINK) $(pio_OBJECTS) $(pio_LDADD) $(LIBS) +pma$(EXEEXT): $(pma_OBJECTS) $(pma_DEPENDENCIES) + @rm -f pma$(EXEEXT) + $(LINK) $(pma_OBJECTS) $(pma_LDADD) $(LIBS) rbt$(EXEEXT): $(rbt_OBJECTS) $(rbt_DEPENDENCIES) @rm -f rbt$(EXEEXT) $(LINK) $(rbt_OBJECTS) $(rbt_LDADD) $(LIBS) @@ -467,6 +475,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oht.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pio.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pma.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rbt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rex01.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sio.Po@am__quote@ diff --git a/qse/samples/cmn/pma.c b/qse/samples/cmn/pma.c new file mode 100644 index 00000000..2db7852a --- /dev/null +++ b/qse/samples/cmn/pma.c @@ -0,0 +1,53 @@ +#include +#include +#include + +#define R(f) \ + do { \ + qse_printf (QSE_T("== %s ==\n"), QSE_T(#f)); \ + if (f() == -1) return -1; \ + } while (0) + +static int test1 () +{ + int i; + int* ptr[100]; + + qse_pma_t* pma = qse_pma_open (QSE_MMGR_GETDFL(), 0); + if (pma == QSE_NULL) + { + qse_printf (QSE_T("cannot open pma\n")); + return -1; + } + + for (i = 0; i < 100; i++) + { + ptr[i] = qse_pma_alloc (pma, sizeof(int)); + if (ptr[i]) + { + qse_printf (QSE_T("%d %p\n"), i, ptr[i]); + *(ptr[i]) = i; + } + else qse_printf (QSE_T("%d FAIL\n"), i); + } + + for (i = 0; i < 100; i++) + { + ptr[i] = qse_pma_alloc (pma, sizeof(int)); + if (ptr[i]) + { + qse_printf (QSE_T("%d %p\n"), i, ptr[i]); + *(ptr[i]) = i; + } + else qse_printf (QSE_T("%d FAIL\n"), i); + } + + qse_pma_close (pma); + return 0; +} + +int main () +{ + R (test1); + return 0; +}