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;
+}