summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2005-05-17 19:01:07 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2005-05-17 19:01:07 (GMT)
commit9b4c1ce9f6e79cf3194b3777813365a623688c47 (patch)
treec28c7fcf1c9fb58011a46602ab48b54179375c18 /test
parent2afe0fcda114dd398e518d9f1242307f06b72fbc (diff)
downloadhdf5-9b4c1ce9f6e79cf3194b3777813365a623688c47.zip
hdf5-9b4c1ce9f6e79cf3194b3777813365a623688c47.tar.gz
hdf5-9b4c1ce9f6e79cf3194b3777813365a623688c47.tar.bz2
[svn-r10750] Purpose:
New feature. Description: Add "memory pool" internal data structure. This set of routines is designed to add a way to allocate small pieces of information for a particular purpose and then free all the pieces at once (i.e. without having to free each piece individually). Memory pools are also good for localizing lots of small allocations that logically belong together. For example, if you were constructing a temporary linked list, you could create a new memory pool, allocate all the nodes for the list from the memory pool and when you were done with the list, just destroy the pool instead of tracking through the list and freeing each block independently. Platforms tested: FreeBSD 4.11 (sleipnir) h5committest
Diffstat (limited to 'test')
-rw-r--r--test/Makefile.am2
-rw-r--r--test/Makefile.in44
-rw-r--r--test/pool.c775
3 files changed, 802 insertions, 19 deletions
diff --git a/test/Makefile.am b/test/Makefile.am
index ed903c8..4a700a4 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -30,7 +30,7 @@ check_SCRIPTS = $(TEST_SCRIPT)
# These are our main targets. They should be listed in the order to be
# executed, generally most specific tests to least specific tests.
TEST_PROG=testhdf5 lheap ohdr stab gheap cache btree2 blocktrack sheap \
- hyperslab istore bittests dt_atomic \
+ pool hyperslab istore bittests dt_atomic \
dtypes dsets cmpd_dset extend external links unlink big mtime \
fillval mount flush1 flush2 enum \
set_extent ttsafe stream_test \
diff --git a/test/Makefile.in b/test/Makefile.in
index c6623ff..d360fef 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -29,7 +29,7 @@
#
# HDF5 Library Test Makefile(.in)
#
-SOURCES = $(libh5test_la_SOURCES) big.c bittests.c blocktrack.c btree2.c cache.c cmpd_dset.c dangle.c dsets.c dt_atomic.c dtransform.c dtypes.c enum.c err_compat.c error_test.c extend.c external.c file_handle.c filename.c fillval.c flush1.c flush2.c getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c mtime.c ntypes.c ohdr.c reserved.c set_extent.c sheap.c stab.c stream_test.c $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c
+SOURCES = $(libh5test_la_SOURCES) big.c bittests.c blocktrack.c btree2.c cache.c cmpd_dset.c dangle.c dsets.c dt_atomic.c dtransform.c dtypes.c enum.c err_compat.c error_test.c extend.c external.c file_handle.c filename.c fillval.c flush1.c flush2.c getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c mtime.c ntypes.c ohdr.c pool.c reserved.c set_extent.c sheap.c stab.c stream_test.c $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c
srcdir = @srcdir@
top_srcdir = @top_srcdir@
@@ -72,16 +72,16 @@ am_libh5test_la_OBJECTS = h5test.lo testframe.lo
libh5test_la_OBJECTS = $(am_libh5test_la_OBJECTS)
am__EXEEXT_1 = testhdf5$(EXEEXT) lheap$(EXEEXT) ohdr$(EXEEXT) \
stab$(EXEEXT) gheap$(EXEEXT) cache$(EXEEXT) btree2$(EXEEXT) \
- blocktrack$(EXEEXT) sheap$(EXEEXT) hyperslab$(EXEEXT) \
- istore$(EXEEXT) bittests$(EXEEXT) dt_atomic$(EXEEXT) \
- dtypes$(EXEEXT) dsets$(EXEEXT) cmpd_dset$(EXEEXT) \
- extend$(EXEEXT) external$(EXEEXT) links$(EXEEXT) \
- unlink$(EXEEXT) big$(EXEEXT) mtime$(EXEEXT) fillval$(EXEEXT) \
- mount$(EXEEXT) flush1$(EXEEXT) flush2$(EXEEXT) enum$(EXEEXT) \
- set_extent$(EXEEXT) ttsafe$(EXEEXT) stream_test$(EXEEXT) \
- getname$(EXEEXT) file_handle$(EXEEXT) ntypes$(EXEEXT) \
- dangle$(EXEEXT) dtransform$(EXEEXT) filename$(EXEEXT) \
- reserved$(EXEEXT)
+ blocktrack$(EXEEXT) sheap$(EXEEXT) pool$(EXEEXT) \
+ hyperslab$(EXEEXT) istore$(EXEEXT) bittests$(EXEEXT) \
+ dt_atomic$(EXEEXT) dtypes$(EXEEXT) dsets$(EXEEXT) \
+ cmpd_dset$(EXEEXT) extend$(EXEEXT) external$(EXEEXT) \
+ links$(EXEEXT) unlink$(EXEEXT) big$(EXEEXT) mtime$(EXEEXT) \
+ fillval$(EXEEXT) mount$(EXEEXT) flush1$(EXEEXT) \
+ flush2$(EXEEXT) enum$(EXEEXT) set_extent$(EXEEXT) \
+ ttsafe$(EXEEXT) stream_test$(EXEEXT) getname$(EXEEXT) \
+ file_handle$(EXEEXT) ntypes$(EXEEXT) dangle$(EXEEXT) \
+ dtransform$(EXEEXT) filename$(EXEEXT) reserved$(EXEEXT)
big_SOURCES = big.c
big_OBJECTS = big.$(OBJEXT)
big_LDADD = $(LDADD)
@@ -206,6 +206,10 @@ ohdr_SOURCES = ohdr.c
ohdr_OBJECTS = ohdr.$(OBJEXT)
ohdr_LDADD = $(LDADD)
ohdr_DEPENDENCIES = libh5test.la $(am__DEPENDENCIES_1)
+pool_SOURCES = pool.c
+pool_OBJECTS = pool.$(OBJEXT)
+pool_LDADD = $(LDADD)
+pool_DEPENDENCIES = libh5test.la $(am__DEPENDENCIES_1)
reserved_SOURCES = reserved.c
reserved_OBJECTS = reserved.$(OBJEXT)
reserved_LDADD = $(LDADD)
@@ -266,17 +270,17 @@ SOURCES = $(libh5test_la_SOURCES) big.c bittests.c blocktrack.c \
dtransform.c dtypes.c enum.c err_compat.c error_test.c \
extend.c external.c file_handle.c filename.c fillval.c \
flush1.c flush2.c getname.c gheap.c hyperslab.c istore.c \
- lheap.c links.c mount.c mtime.c ntypes.c ohdr.c reserved.c \
- set_extent.c sheap.c stab.c stream_test.c $(testhdf5_SOURCES) \
- testmeta.c $(ttsafe_SOURCES) unlink.c
+ lheap.c links.c mount.c mtime.c ntypes.c ohdr.c pool.c \
+ reserved.c set_extent.c sheap.c stab.c stream_test.c \
+ $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c
DIST_SOURCES = $(libh5test_la_SOURCES) big.c bittests.c blocktrack.c \
btree2.c cache.c cmpd_dset.c dangle.c dsets.c dt_atomic.c \
dtransform.c dtypes.c enum.c err_compat.c error_test.c \
extend.c external.c file_handle.c filename.c fillval.c \
flush1.c flush2.c getname.c gheap.c hyperslab.c istore.c \
- lheap.c links.c mount.c mtime.c ntypes.c ohdr.c reserved.c \
- set_extent.c sheap.c stab.c stream_test.c $(testhdf5_SOURCES) \
- testmeta.c $(ttsafe_SOURCES) unlink.c
+ lheap.c links.c mount.c mtime.c ntypes.c ohdr.c pool.c \
+ reserved.c set_extent.c sheap.c stab.c stream_test.c \
+ $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -495,7 +499,7 @@ check_SCRIPTS = $(TEST_SCRIPT)
# These are our main targets. They should be listed in the order to be
# executed, generally most specific tests to least specific tests.
TEST_PROG = testhdf5 lheap ohdr stab gheap cache btree2 blocktrack sheap \
- hyperslab istore bittests dt_atomic \
+ pool hyperslab istore bittests dt_atomic \
dtypes dsets cmpd_dset extend external links unlink big mtime \
fillval mount flush1 flush2 enum \
set_extent ttsafe stream_test \
@@ -704,6 +708,9 @@ ntypes$(EXEEXT): $(ntypes_OBJECTS) $(ntypes_DEPENDENCIES)
ohdr$(EXEEXT): $(ohdr_OBJECTS) $(ohdr_DEPENDENCIES)
@rm -f ohdr$(EXEEXT)
$(LINK) $(ohdr_LDFLAGS) $(ohdr_OBJECTS) $(ohdr_LDADD) $(LIBS)
+pool$(EXEEXT): $(pool_OBJECTS) $(pool_DEPENDENCIES)
+ @rm -f pool$(EXEEXT)
+ $(LINK) $(pool_LDFLAGS) $(pool_OBJECTS) $(pool_LDADD) $(LIBS)
reserved$(EXEEXT): $(reserved_OBJECTS) $(reserved_DEPENDENCIES)
@rm -f reserved$(EXEEXT)
$(LINK) $(reserved_LDFLAGS) $(reserved_OBJECTS) $(reserved_LDADD) $(LIBS)
@@ -770,6 +777,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mtime.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntypes.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ohdr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reserved.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_extent.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sheap.Po@am__quote@
diff --git a/test/pool.c b/test/pool.c
new file mode 100644
index 0000000..5170c77
--- /dev/null
+++ b/test/pool.c
@@ -0,0 +1,775 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/* Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
+ * Tuesday, May 3, 2005
+ */
+#include "h5test.h"
+
+/*
+ * This file needs to access private datatypes from the H5MP package.
+ * This file also needs to access the memory pool testing code.
+ */
+#define H5MP_PACKAGE
+#define H5MP_TESTING
+#include "H5MPpkg.h" /* Memory Pools */
+
+/* Other private headers that this test requires */
+
+/* Local macros */
+#define MPOOL_PAGE_SIZE H5MP_PAGE_SIZE_DEFAULT
+#define MPOOL_FLAGS H5MP_FLG_DEFAULT
+#define MPOOL_NUM_NORMAL_BLOCKS 15
+#define MPOOL_NORMAL_BLOCK 512
+#define MPOOL_LARGE_BLOCK (MPOOL_PAGE_SIZE * 3)
+#define MPOOL_NUM_SMALL_BLOCKS 64
+#define MPOOL_SMALL_BLOCK 1
+#define MPOOL_NUM_RANDOM 10*1024
+#define MPOOL_RANDOM_MAX_SIZE (MPOOL_PAGE_SIZE * 2)
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_create
+ *
+ * Purpose: Test trivial creating & closing memory pool
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, May 3, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_create(void)
+{
+ H5MP_pool_t *mp; /* Memory pool */
+ H5MP_page_t *page; /* Memory pool page */
+ size_t free_size; /* Free size in pool */
+
+ /*
+ * Test memory pool creation
+ */
+ TESTING("memory pool creation");
+
+ /* Create a memory pool */
+ if (NULL == (mp = H5MP_create(MPOOL_PAGE_SIZE, MPOOL_FLAGS)))
+ TEST_ERROR
+
+ /* Check free space */
+ if (H5MP_get_pool_free_size(mp, &free_size) < 0)
+ TEST_ERROR;
+ if(free_size != 0)
+ TEST_ERROR
+
+ /* Check first page */
+ if (H5MP_get_pool_first_page(mp, &page) < 0)
+ TEST_ERROR;
+ if(page != NULL)
+ TEST_ERROR
+
+ /* Close the memory pool */
+ if (H5MP_close(mp) < 0)
+ TEST_ERROR
+
+ PASSED();
+
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ } H5E_END_TRY;
+ return 1;
+} /* test_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_close_one
+ *
+ * Purpose: Tests closing pool with one block allocated
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Friday, May 6, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_close_one(void)
+{
+ H5MP_pool_t *mp; /* Memory pool */
+ void *spc1; /* Pointer to space allocated */
+
+ /*
+ * Test memory pool closing
+ */
+ TESTING("closing pool with blocks still allocated in one page");
+
+ /* Create a memory pool */
+ if (NULL == (mp = H5MP_create(MPOOL_PAGE_SIZE, MPOOL_FLAGS)))
+ TEST_ERROR
+
+ /* Allocate space in pool */
+ if (NULL == (spc1 = H5MP_malloc(mp, MPOOL_NORMAL_BLOCK)))
+ TEST_ERROR
+
+ /* Close the memory pool */
+ if (H5MP_close(mp) < 0)
+ TEST_ERROR
+
+ PASSED();
+
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ } H5E_END_TRY;
+ return 1;
+} /* test_close_one() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_allocate_first
+ *
+ * Purpose: Tests allocating first block in pool
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, May 3, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_allocate_first(void)
+{
+ H5MP_pool_t *mp; /* Memory pool */
+ H5MP_page_t *page; /* Memory pool page */
+ size_t free_size; /* Free size in pool */
+ void *spc; /* Pointer to space allocated */
+
+ /*
+ * Test memory pool allocation
+ */
+ TESTING("allocating first block in pool");
+
+ /* Create a memory pool */
+ if (NULL == (mp = H5MP_create(MPOOL_PAGE_SIZE, MPOOL_FLAGS)))
+ TEST_ERROR
+
+ /* Allocate space in pool */
+ if (NULL == (spc = H5MP_malloc(mp, MPOOL_NORMAL_BLOCK)))
+ TEST_ERROR
+
+ /* Check pool's free space */
+ if (H5MP_get_pool_free_size(mp, &free_size) < 0)
+ TEST_ERROR;
+ if(free_size != MPOOL_PAGE_SIZE - (H5MP_BLOCK_ALIGN(MPOOL_NORMAL_BLOCK) + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_blk_t)) + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t))))
+ TEST_ERROR
+
+ /* Get first page */
+ if (H5MP_get_pool_first_page(mp, &page) < 0)
+ TEST_ERROR;
+ if(page == NULL)
+ TEST_ERROR
+
+ /* Check page's free space */
+ if (H5MP_get_page_free_size(page, &free_size) < 0)
+ TEST_ERROR;
+ if(free_size != MPOOL_PAGE_SIZE - (H5MP_BLOCK_ALIGN(MPOOL_NORMAL_BLOCK) + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_blk_t)) + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t))))
+ TEST_ERROR
+
+ /* Check that free space totals match */
+ if (H5MP_pool_is_free_size_correct(mp) <= 0)
+ TEST_ERROR;
+
+ /* Check next page */
+ if (H5MP_get_page_next_page(page, &page) < 0)
+ TEST_ERROR;
+ if(page != NULL)
+ TEST_ERROR
+
+ /* Free space in pool */
+ H5MP_free(mp, spc);
+
+ /* Check pool's free space */
+ if (H5MP_get_pool_free_size(mp, &free_size) < 0)
+ TEST_ERROR;
+ if(free_size != MPOOL_PAGE_SIZE - H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t)))
+ TEST_ERROR
+
+ /* Check that free space totals match */
+ if (H5MP_pool_is_free_size_correct(mp) <= 0)
+ TEST_ERROR;
+
+ /* Close the memory pool */
+ if (H5MP_close(mp) < 0)
+ TEST_ERROR
+
+ PASSED();
+
+ TESTING("allocating large first block in pool");
+
+ /* Create a memory pool */
+ if (NULL == (mp = H5MP_create(MPOOL_PAGE_SIZE, MPOOL_FLAGS)))
+ TEST_ERROR
+
+ /* Allocate space in pool */
+ if (NULL == (spc = H5MP_malloc(mp, MPOOL_LARGE_BLOCK)))
+ TEST_ERROR
+
+ /* Check pool's free space */
+ if (H5MP_get_pool_free_size(mp, &free_size) < 0)
+ TEST_ERROR;
+ if(free_size != 0)
+ TEST_ERROR
+
+ /* Get first page */
+ if (H5MP_get_pool_first_page(mp, &page) < 0)
+ TEST_ERROR;
+ if(page == NULL)
+ TEST_ERROR
+
+ /* Check page's free space */
+ if (H5MP_get_page_free_size(page, &free_size) < 0)
+ TEST_ERROR;
+ if(free_size != 0)
+ TEST_ERROR
+
+ /* Check that free space totals match */
+ if (H5MP_pool_is_free_size_correct(mp) <= 0)
+ TEST_ERROR;
+
+ /* Check next page */
+ if (H5MP_get_page_next_page(page, &page) < 0)
+ TEST_ERROR;
+ if(page != NULL)
+ TEST_ERROR
+
+ /* Free space in pool */
+ H5MP_free(mp, spc);
+
+ /* Check pool's free space */
+ if (H5MP_get_pool_free_size(mp, &free_size) < 0)
+ TEST_ERROR;
+ if(free_size != MPOOL_LARGE_BLOCK + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_blk_t)))
+ TEST_ERROR
+
+ /* Check that free space totals match */
+ if (H5MP_pool_is_free_size_correct(mp) <= 0)
+ TEST_ERROR;
+
+ /* Close the memory pool */
+ if (H5MP_close(mp) < 0)
+ TEST_ERROR
+
+ PASSED();
+
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ } H5E_END_TRY;
+ return 1;
+} /* test_allocate_first() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_allocate_split
+ *
+ * Purpose: Tests allocating block in pool that requires splitting
+ * existing block
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, May 3, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_allocate_split(void)
+{
+ H5MP_pool_t *mp; /* Memory pool */
+ size_t free_size; /* Free size in pool */
+ void *spc1; /* Pointer to space allocated */
+ void *spc2; /* Pointer to space allocated */
+
+ /*
+ * Test memory pool allocation
+ */
+ TESTING("splitting block in pool");
+
+ /* Create a memory pool */
+ if (NULL == (mp = H5MP_create(MPOOL_PAGE_SIZE, MPOOL_FLAGS)))
+ TEST_ERROR
+
+ /* Allocate space in pool */
+ if (NULL == (spc1 = H5MP_malloc(mp, MPOOL_NORMAL_BLOCK)))
+ TEST_ERROR
+
+ /* Check pool's free space */
+ if (H5MP_get_pool_free_size(mp, &free_size) < 0)
+ TEST_ERROR;
+ if(free_size != MPOOL_PAGE_SIZE - (H5MP_BLOCK_ALIGN(MPOOL_NORMAL_BLOCK) + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_blk_t)) + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t))))
+ TEST_ERROR
+
+ /* Check that free space totals match */
+ if (H5MP_pool_is_free_size_correct(mp) <= 0)
+ TEST_ERROR;
+
+ /* Allocate more space in pool */
+ if (NULL == (spc2 = H5MP_malloc(mp, MPOOL_NORMAL_BLOCK)))
+ TEST_ERROR
+
+ /* Check pool's free space */
+ if (H5MP_get_pool_free_size(mp, &free_size) < 0)
+ TEST_ERROR;
+ if(free_size != MPOOL_PAGE_SIZE - (((H5MP_BLOCK_ALIGN(MPOOL_NORMAL_BLOCK) + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_blk_t))) * 2) + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t))))
+ TEST_ERROR
+
+ /* Check that free space totals match */
+ if (H5MP_pool_is_free_size_correct(mp) <= 0)
+ TEST_ERROR;
+
+ /* Free first block in pool */
+ H5MP_free(mp, spc1);
+
+ /* Check pool's free space */
+ if (H5MP_get_pool_free_size(mp, &free_size) < 0)
+ TEST_ERROR;
+ if(free_size != MPOOL_PAGE_SIZE - (H5MP_BLOCK_ALIGN(MPOOL_NORMAL_BLOCK) + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_blk_t)) + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t))))
+ TEST_ERROR
+
+ /* Check that free space totals match */
+ if (H5MP_pool_is_free_size_correct(mp) <= 0)
+ TEST_ERROR;
+
+ /* Free second block in pool (should merge with first block) */
+ H5MP_free(mp, spc2);
+
+ /* Check pool's free space */
+ if (H5MP_get_pool_free_size(mp, &free_size) < 0)
+ TEST_ERROR;
+ if(free_size != MPOOL_PAGE_SIZE - H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t)))
+ TEST_ERROR
+
+ /* Check that free space totals match */
+ if (H5MP_pool_is_free_size_correct(mp) <= 0)
+ TEST_ERROR;
+
+ /* Close the memory pool */
+ if (H5MP_close(mp) < 0)
+ TEST_ERROR
+
+ PASSED();
+
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ } H5E_END_TRY;
+ return 1;
+} /* test_allocate_split() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_allocate_many_small
+ *
+ * Purpose: Tests allocating many small blocks in a pool
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, May 6, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_allocate_many_small(void)
+{
+ H5MP_pool_t *mp; /* Memory pool */
+ size_t free_size; /* Free size in pool */
+ void *spc[MPOOL_NUM_SMALL_BLOCKS]; /* Pointers to space allocated */
+ int i; /* Local index variable */
+
+ /*
+ * Test memory pool allocation
+ */
+ TESTING("allocating many small blocks");
+
+ /* Create a memory pool */
+ if (NULL == (mp = H5MP_create(MPOOL_PAGE_SIZE, MPOOL_FLAGS)))
+ TEST_ERROR
+
+ /* Allocate space in pool */
+ for (i = 0; i < MPOOL_NUM_SMALL_BLOCKS; i++)
+ if (NULL == (spc[i] = H5MP_malloc(mp, MPOOL_SMALL_BLOCK)))
+ TEST_ERROR
+
+ /* Check pool's free space */
+ if (H5MP_get_pool_free_size(mp, &free_size) < 0)
+ TEST_ERROR;
+ if(free_size != MPOOL_PAGE_SIZE - (((H5MP_BLOCK_ALIGN(MPOOL_SMALL_BLOCK) + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_blk_t))) * MPOOL_NUM_SMALL_BLOCKS) + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t))))
+ TEST_ERROR
+
+ /* Check that free space totals match */
+ if (H5MP_pool_is_free_size_correct(mp) <= 0)
+ TEST_ERROR;
+
+ /* Free blocks in pool */
+ /* (Tests free block merging with block after it */
+ for(i = (MPOOL_NUM_SMALL_BLOCKS - 1); i >= 0; i--)
+ H5MP_free(mp, spc[i]);
+
+ /* Check pool's free space */
+ if (H5MP_get_pool_free_size(mp, &free_size) < 0)
+ TEST_ERROR;
+ if(free_size != MPOOL_PAGE_SIZE - H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t)))
+ TEST_ERROR
+
+ /* Check that free space totals match */
+ if (H5MP_pool_is_free_size_correct(mp) <= 0)
+ TEST_ERROR;
+
+ /* Close the memory pool */
+ if (H5MP_close(mp) < 0)
+ TEST_ERROR
+
+ PASSED();
+
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ } H5E_END_TRY;
+ return 1;
+} /* test_allocate_many_small() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_allocate_new_page
+ *
+ * Purpose: Tests allocating block in pool that requires allocating
+ * new page
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Friday, May 6, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_allocate_new_page(void)
+{
+ H5MP_pool_t *mp; /* Memory pool */
+ size_t free_size; /* Free size in pool */
+ size_t u; /* Local index variable */
+ void *spc[MPOOL_NUM_NORMAL_BLOCKS]; /* Pointer to space allocated */
+ void *spc1; /* Pointer to space allocated */
+ void *spc2; /* Pointer to space allocated */
+
+ /*
+ * Test memory pool allocation
+ */
+ TESTING("allocate normal-sized block in new page");
+
+ /* Create a memory pool */
+ if (NULL == (mp = H5MP_create(MPOOL_PAGE_SIZE, MPOOL_FLAGS)))
+ TEST_ERROR
+
+ /* Allocate space in pool */
+ for(u = 0; u < MPOOL_NUM_NORMAL_BLOCKS; u++)
+ if (NULL == (spc[u] = H5MP_malloc(mp, MPOOL_NORMAL_BLOCK)))
+ TEST_ERROR
+
+ /* Check pool's free space */
+ if (H5MP_get_pool_free_size(mp, &free_size) < 0)
+ TEST_ERROR;
+ if(free_size != (MPOOL_PAGE_SIZE * 3) - (((H5MP_BLOCK_ALIGN(MPOOL_NORMAL_BLOCK) + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_blk_t))) * MPOOL_NUM_NORMAL_BLOCKS) + (H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t)) * 3)))
+ TEST_ERROR
+
+ /* Check that free space totals match */
+ if (H5MP_pool_is_free_size_correct(mp) <= 0)
+ TEST_ERROR;
+
+ /* Free blocks in pool */
+ /* (Free alternating blocks, in two passes, which tests block merging w/both neighbors) */
+ for(u = 0; u < MPOOL_NUM_NORMAL_BLOCKS; u+=2)
+ H5MP_free(mp, spc[u]);
+ for(u = 1; u < MPOOL_NUM_NORMAL_BLOCKS; u+=2)
+ H5MP_free(mp, spc[u]);
+
+ /* Check pool's free space */
+ if (H5MP_get_pool_free_size(mp, &free_size) < 0)
+ TEST_ERROR;
+ if(free_size != ((MPOOL_PAGE_SIZE - H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t))) * 3))
+ TEST_ERROR
+
+ /* Check that free space totals match */
+ if (H5MP_pool_is_free_size_correct(mp) <= 0)
+ TEST_ERROR;
+
+ /* Close the memory pool */
+ if (H5MP_close(mp) < 0)
+ TEST_ERROR
+
+ PASSED();
+
+ TESTING("allocate large-sized block in new page");
+
+ /* Create a memory pool */
+ if (NULL == (mp = H5MP_create(MPOOL_PAGE_SIZE, MPOOL_FLAGS)))
+ TEST_ERROR
+
+ /* Allocate space in pool */
+ /* (Normal sized block) */
+ if (NULL == (spc1 = H5MP_malloc(mp, MPOOL_NORMAL_BLOCK)))
+ TEST_ERROR
+ /* (Larger sized block) */
+ if (NULL == (spc2 = H5MP_malloc(mp, MPOOL_LARGE_BLOCK)))
+ TEST_ERROR
+
+ /* Check pool's free space */
+ if (H5MP_get_pool_free_size(mp, &free_size) < 0)
+ TEST_ERROR;
+ if(free_size != MPOOL_PAGE_SIZE - (H5MP_BLOCK_ALIGN(MPOOL_NORMAL_BLOCK) + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_blk_t)) + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t))))
+ TEST_ERROR
+
+ /* Check that free space totals match */
+ if (H5MP_pool_is_free_size_correct(mp) <= 0)
+ TEST_ERROR;
+
+ /* Free blocks in pool */
+ H5MP_free(mp, spc1);
+ H5MP_free(mp, spc2);
+
+ /* Check pool's free space */
+ if (H5MP_get_pool_free_size(mp, &free_size) < 0)
+ TEST_ERROR;
+ if(free_size != ((MPOOL_PAGE_SIZE - H5MP_BLOCK_ALIGN(sizeof(H5MP_page_t))) +
+ MPOOL_LARGE_BLOCK + H5MP_BLOCK_ALIGN(sizeof(H5MP_page_blk_t))))
+ TEST_ERROR
+
+ /* Check that free space totals match */
+ if (H5MP_pool_is_free_size_correct(mp) <= 0)
+ TEST_ERROR;
+
+ /* Close the memory pool */
+ if (H5MP_close(mp) < 0)
+ TEST_ERROR
+
+ PASSED();
+
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ } H5E_END_TRY;
+ return 1;
+} /* test_allocate_new_page() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_allocate_random
+ *
+ * Purpose: Tests allocating random sized blocks in pool
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Friday, May 6, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_allocate_random(void)
+{
+ H5MP_pool_t *mp; /* Memory pool */
+ size_t u; /* Local index variable */
+ time_t curr_time; /* Current time, for seeding random number generator */
+ size_t *blk_size = NULL; /* Pointer to block sizes */
+ void **spc = NULL; /* Pointer to space allocated */
+ size_t swap_idx; /* Location to swap with when shuffling */
+ void *swap_ptr; /* Pointer to swap when shuffling */
+
+ /*
+ * Test memory pool allocation
+ */
+ TESTING("allocate many random sized blocks");
+
+ /* Initialize random number seed */
+ curr_time=HDtime(NULL);
+#ifdef QAK
+curr_time=1115412944;
+HDfprintf(stderr,"curr_time=%lu\n",(unsigned long)curr_time);
+#endif /* QAK */
+ HDsrandom((unsigned long)curr_time);
+
+ /* Create a memory pool */
+ if (NULL == (mp = H5MP_create(MPOOL_PAGE_SIZE, MPOOL_FLAGS)))
+ TEST_ERROR
+
+ /* Allocate space for the block sizes */
+ if(NULL == (blk_size = HDmalloc(sizeof(size_t) * MPOOL_NUM_RANDOM)))
+ TEST_ERROR
+
+ /* Allocate space for the block pointers */
+ if(NULL == (spc = HDmalloc(sizeof(void *) * MPOOL_NUM_RANDOM)))
+ TEST_ERROR
+
+ /* Initialize the block sizes with random values */
+ for(u = 0; u < MPOOL_NUM_RANDOM; u++)
+ blk_size[u] = (size_t)(HDrandom() % MPOOL_RANDOM_MAX_SIZE) + 1;
+
+ /* Allocate space in pool */
+ for(u = 0; u < MPOOL_NUM_RANDOM; u++)
+ if (NULL == (spc[u] = H5MP_malloc(mp, blk_size[u])))
+ TEST_ERROR
+
+ /* Check that free space totals match */
+ if (H5MP_pool_is_free_size_correct(mp) <= 0)
+ TEST_ERROR;
+
+ /* Shuffle pointers to free */
+ for(u = 0; u < MPOOL_NUM_RANDOM; u++) {
+ swap_idx = (size_t)(HDrandom() % (MPOOL_NUM_RANDOM - u)) + u;
+ swap_ptr = spc[u];
+ spc[u] = spc[swap_idx];
+ spc[swap_idx] = swap_ptr;
+ } /* end for */
+
+ /* Free blocks in pool */
+ for(u = 0; u < MPOOL_NUM_RANDOM; u++)
+ H5MP_free(mp, spc[u]);
+
+ /* Check that free space totals match */
+ if (H5MP_pool_is_free_size_correct(mp) <= 0)
+ TEST_ERROR;
+
+ /* Initialize the block sizes with random values */
+ for(u = 0; u < MPOOL_NUM_RANDOM; u++)
+ blk_size[u] = (size_t)(HDrandom() % MPOOL_RANDOM_MAX_SIZE) + 1;
+
+ /* Allocate space in pool (again) */
+ /* (Leave allocated to test closing pool with many blocks still allocated) */
+ for(u = 0; u < MPOOL_NUM_RANDOM; u++)
+ if (NULL == (spc[u] = H5MP_malloc(mp, blk_size[u])))
+ TEST_ERROR
+
+ /* Check that free space totals match */
+ if (H5MP_pool_is_free_size_correct(mp) <= 0)
+ TEST_ERROR;
+
+ /* Close the memory pool */
+ if (H5MP_close(mp) < 0)
+ TEST_ERROR
+
+ /* Free memory for block sizes & pointers */
+ HDfree(blk_size);
+ HDfree(spc);
+
+ PASSED();
+
+ return 0;
+
+error:
+ if(blk_size)
+ HDfree(blk_size);
+ if(spc)
+ HDfree(spc);
+ H5E_BEGIN_TRY {
+ } H5E_END_TRY;
+ return 1;
+} /* test_allocate_random() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: Test the memory pool code
+ *
+ * Return: Success:
+ *
+ * Failure:
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, May 3, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main(void)
+{
+ int nerrors=0;
+
+ /* Reset library */
+ h5_reset();
+
+ /* Test memory pool creation */
+ nerrors += test_create();
+
+ /* Test memory pool space closing */
+ nerrors += test_close_one();
+
+ /* Test memory pool space allocation */
+ nerrors += test_allocate_first();
+ nerrors += test_allocate_split();
+ nerrors += test_allocate_many_small();
+ nerrors += test_allocate_new_page();
+ nerrors += test_allocate_random();
+
+ if (nerrors) goto error;
+ puts("All memory pool tests passed.");
+ return 0;
+
+error:
+ puts("*** TESTS FAILED ***");
+ H5E_BEGIN_TRY {
+ } H5E_END_TRY;
+ return 1;
+}
+