summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Dependencies13
-rw-r--r--src/H5.c39
-rw-r--r--src/H5B.c72
-rw-r--r--src/H5D.c105
-rw-r--r--src/H5Distore.c121
-rw-r--r--src/H5FL.c1257
-rw-r--r--src/H5FLprivate.h173
-rw-r--r--src/H5Fistore.c121
-rw-r--r--src/H5Fprivate.h5
-rw-r--r--src/H5Gnode.c97
-rw-r--r--src/H5HG.c58
-rw-r--r--src/H5I.c126
-rw-r--r--src/H5O.c132
-rw-r--r--src/H5Oattr.c12
-rw-r--r--src/H5Ocomp.c59
-rw-r--r--src/H5Ocont.c1
-rw-r--r--src/H5Odtype.c96
-rw-r--r--src/H5Oefl.c1
-rw-r--r--src/H5Ofill.c1
-rw-r--r--src/H5Olayout.c44
-rw-r--r--src/H5Omtime.c39
-rw-r--r--src/H5Oname.c1
-rw-r--r--src/H5Onull.c1
-rw-r--r--src/H5Oprivate.h1
-rw-r--r--src/H5Osdspace.c117
-rw-r--r--src/H5Oshared.c1
-rw-r--r--src/H5Ostab.c1
-rw-r--r--src/H5P.c316
-rw-r--r--src/H5S.c49
-rw-r--r--src/H5Sall.c79
-rw-r--r--src/H5Shyper.c566
-rw-r--r--src/H5Snone.c82
-rw-r--r--src/H5Spoint.c149
-rw-r--r--src/H5Sprivate.h10
-rw-r--r--src/H5Sselect.c577
-rw-r--r--src/H5T.c72
-rw-r--r--src/H5TB.c539
-rw-r--r--src/H5TBprivate.h26
-rw-r--r--src/H5Tconv.c23
-rw-r--r--src/H5Tprivate.h14
-rw-r--r--src/H5Zdeflate.c15
-rw-r--r--src/H5detect.c7
-rw-r--r--src/H5private.h1
-rw-r--r--src/H5public.h1
-rw-r--r--src/Makefile.in34
45 files changed, 3318 insertions, 1936 deletions
diff --git a/src/Dependencies b/src/Dependencies
index f1b31aa..42870ae 100644
--- a/src/Dependencies
+++ b/src/Dependencies
@@ -157,7 +157,6 @@ H5D.lo: \
$(srcdir)/H5MMprivate.h \
$(srcdir)/H5Pprivate.h \
$(srcdir)/H5Ppublic.h \
- $(srcdir)/H5TBprivate.h \
$(srcdir)/H5Vprivate.h
H5E.lo: \
$(srcdir)/H5E.c \
@@ -1607,18 +1606,6 @@ H5Tvlen.lo: \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h
-H5TB.lo: \
- $(srcdir)/H5TB.c \
- $(srcdir)/H5private.h \
- $(srcdir)/H5public.h \
- H5pubconf.h \
- $(srcdir)/H5api_adpt.h \
- H5config.h \
- $(srcdir)/H5Iprivate.h \
- $(srcdir)/H5Ipublic.h \
- $(srcdir)/H5Eprivate.h \
- $(srcdir)/H5Epublic.h \
- $(srcdir)/H5MMprivate.h
H5V.lo: \
$(srcdir)/H5V.c \
$(srcdir)/H5private.h \
diff --git a/src/H5.c b/src/H5.c
index 2c9839a..b2f6b06 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -22,6 +22,7 @@ static char RcsId[] = "@(#)$Revision$";
#include <H5Bprivate.h> /*B-link trees */
#include <H5Eprivate.h> /*error handling */
#include <H5FDprivate.h> /*file driver */
+#include <H5FLprivate.h> /*Free Lists */
#include <H5Iprivate.h> /*atoms */
#include <H5MMprivate.h> /*memory management */
#include <H5Pprivate.h> /*property lists */
@@ -164,10 +165,10 @@ H5_term_library(void)
pending += DOWN(F);
pending += DOWN(FD);
pending += DOWN(D);
- pending += DOWN(TB);
pending += DOWN(Z);
pending += DOWN(RA);
pending += DOWN(G);
+ pending += DOWN(FL);
pending += DOWN(R);
pending += DOWN(S);
pending += DOWN(TN);
@@ -224,6 +225,42 @@ H5dont_atexit(void)
/*-------------------------------------------------------------------------
+ * Function: H5garbage_collect
+ *
+ * Purpose: Walks through all the garbage collection routines for the
+ * library, which are supposed to free any unused memory they have
+ * allocated.
+ *
+ * These should probably be registered dynamicly in a linked list of
+ * functions to call, but there aren't that many right now, so we
+ * hard-wire them...
+ *
+ * Return: Success: non-negative
+ *
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, March 11, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5garbage_collect(void)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER(H5garbage_collect, FAIL);
+
+ /* Call the garbage collection routines in the library */
+ H5FL_garbage_coll();
+
+ FUNC_LEAVE(ret_value);
+} /* end H5garbage_collect() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5_debug_mask
*
* Purpose: Set runtime debugging flags according to the string S. The
diff --git a/src/H5B.c b/src/H5B.c
index 47a6e15..acb3079 100644
--- a/src/H5B.c
+++ b/src/H5B.c
@@ -92,6 +92,7 @@
#include <H5Bprivate.h> /*B-link trees */
#include <H5Eprivate.h> /*error handling */
#include <H5Fprivate.h> /*file access */
+#include <H5FLprivate.h> /*Free Lists */
#include <H5MFprivate.h> /*file memory management */
#include <H5MMprivate.h> /*core memory management */
#include <H5Pprivate.h> /*property lists */
@@ -141,6 +142,21 @@ static const H5AC_class_t H5AC_BT[1] = {{
#define INTERFACE_INIT NULL
static intn interface_initialize_g = 0;
+/* Declare a free list to manage the page information */
+H5FL_BLK_DEFINE_STATIC(page);
+
+/* Declare a PQ free list to manage the native block information */
+H5FL_BLK_DEFINE_STATIC(native_block);
+
+/* Declare a free list to manage the H5B_key_t array information */
+H5FL_ARR_DEFINE_STATIC(H5B_key_t,-1);
+
+/* Declare a free list to manage the haddr_t array information */
+H5FL_ARR_DEFINE_STATIC(haddr_t,-1);
+
+/* Declare a free list to manage the H5B_t struct */
+H5FL_DEFINE_STATIC(H5B_t);
+
/*-------------------------------------------------------------------------
* Function: H5B_create
@@ -194,7 +210,7 @@ H5B_create(H5F_t *f, const H5B_class_t *type, void *udata,
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"file allocation failed for B-tree root node");
}
- if (NULL==(bt = H5MM_calloc(sizeof(H5B_t)))) {
+ if (NULL==(bt = H5FL_ALLOC(H5B_t,1))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed for B-tree root node");
}
@@ -207,10 +223,10 @@ H5B_create(H5F_t *f, const H5B_class_t *type, void *udata,
bt->left = HADDR_UNDEF;
bt->right = HADDR_UNDEF;
bt->nchildren = 0;
- if (NULL==(bt->page=H5MM_calloc(size)) ||
- NULL==(bt->native=H5MM_malloc(total_native_keysize)) ||
- NULL==(bt->child=H5MM_malloc(2*H5B_K(f,type)*sizeof(haddr_t))) ||
- NULL==(bt->key=H5MM_malloc((2*H5B_K(f,type)+1)*sizeof(H5B_key_t)))) {
+ if (NULL==(bt->page=H5FL_BLK_ALLOC(page,size,1)) ||
+ NULL==(bt->native=H5FL_BLK_ALLOC(native_block,total_native_keysize,0)) ||
+ NULL==(bt->child=H5FL_ARR_ALLOC(haddr_t,2*H5B_K(f,type),0)) ||
+ NULL==(bt->key=H5FL_ARR_ALLOC(H5B_key_t,(2*H5B_K(f,type)+1),0))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed for B-tree root node");
}
@@ -253,11 +269,11 @@ H5B_create(H5F_t *f, const H5B_class_t *type, void *udata,
if (ret_value<0) {
H5MF_xfree(f, H5FD_MEM_BTREE, *addr_p, size);
if (bt) {
- H5MM_xfree (bt->page);
- H5MM_xfree (bt->native);
- H5MM_xfree (bt->child);
- H5MM_xfree (bt->key);
- H5MM_xfree (bt);
+ H5FL_BLK_FREE (page,bt->page);
+ H5FL_BLK_FREE (native_block,bt->native);
+ H5FL_ARR_FREE (haddr_t,bt->child);
+ H5FL_ARR_FREE (H5B_key_t,bt->key);
+ H5FL_FREE (H5B_t,bt);
}
}
@@ -301,7 +317,7 @@ H5B_load(H5F_t *f, haddr_t addr, const void *_type, void *udata)
assert(type);
assert(type->get_sizeof_rkey);
- if (NULL==(bt = H5MM_calloc(sizeof(H5B_t)))) {
+ if (NULL==(bt = H5FL_ALLOC(H5B_t,1))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -310,10 +326,10 @@ H5B_load(H5F_t *f, haddr_t addr, const void *_type, void *udata)
bt->type = type;
bt->dirty = FALSE;
bt->ndirty = 0;
- if (NULL==(bt->page=H5MM_malloc(size)) ||
- NULL==(bt->native=H5MM_malloc(total_nkey_size)) ||
- NULL==(bt->key=H5MM_malloc((2*H5B_K(f,type)+1)*sizeof(H5B_key_t))) ||
- NULL==(bt->child=H5MM_malloc(2*H5B_K(f,type)*sizeof(haddr_t)))) {
+ if (NULL==(bt->page=H5FL_BLK_ALLOC(page,size,0)) ||
+ NULL==(bt->native=H5FL_BLK_ALLOC(native_block,total_nkey_size,0)) ||
+ NULL==(bt->key=H5FL_ARR_ALLOC(H5B_key_t,(2*H5B_K(f,type)+1),0)) ||
+ NULL==(bt->child=H5FL_ARR_ALLOC(haddr_t,2*H5B_K(f,type),0))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -367,11 +383,11 @@ H5B_load(H5F_t *f, haddr_t addr, const void *_type, void *udata)
done:
if (!ret_value && bt) {
- H5MM_xfree(bt->child);
- H5MM_xfree(bt->key);
- H5MM_xfree(bt->page);
- H5MM_xfree(bt->native);
- H5MM_xfree(bt);
+ H5FL_ARR_FREE(haddr_t,bt->child);
+ H5FL_ARR_FREE(H5B_key_t,bt->key);
+ H5FL_BLK_FREE(page,bt->page);
+ H5FL_BLK_FREE(native_block,bt->native);
+ H5FL_FREE(H5B_t,bt);
}
FUNC_LEAVE(ret_value);
}
@@ -474,11 +490,11 @@ H5B_flush(H5F_t *f, hbool_t destroy, haddr_t addr, H5B_t *bt)
bt->ndirty = 0;
}
if (destroy) {
- H5MM_xfree(bt->child);
- H5MM_xfree(bt->key);
- H5MM_xfree(bt->page);
- H5MM_xfree(bt->native);
- H5MM_xfree(bt);
+ H5FL_ARR_FREE(haddr_t,bt->child);
+ H5FL_ARR_FREE(H5B_key_t,bt->key);
+ H5FL_BLK_FREE(page,bt->page);
+ H5FL_BLK_FREE(native_block,bt->native);
+ H5FL_FREE(H5B_t,bt);
}
FUNC_LEAVE(SUCCEED);
}
@@ -1542,7 +1558,7 @@ H5B_iterate (H5F_t *f, const H5B_class_t *type, haddr_t addr, void *udata)
* We've reached the left-most leaf. Now follow the right-sibling
* pointer from leaf to leaf until we've processed all leaves.
*/
- if (NULL==(child=H5MM_malloc(2*H5B_K(f,type)*sizeof(haddr_t))) ||
+ if (NULL==(child=H5FL_ARR_ALLOC(haddr_t,2*H5B_K(f,type),0)) ||
NULL==(key=H5MM_malloc((2*H5B_K(f, type)+1)*type->sizeof_nkey))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
@@ -1587,8 +1603,8 @@ H5B_iterate (H5F_t *f, const H5B_class_t *type, haddr_t addr, void *udata)
}
}
- done:
- H5MM_xfree(child);
+done:
+ H5FL_ARR_FREE(haddr_t,child);
H5MM_xfree(key);
FUNC_LEAVE(ret_value);
}
diff --git a/src/H5D.c b/src/H5D.c
index 2372c76..e1f318b 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -21,13 +21,13 @@ static char RcsId[] = "@(#)$Revision$";
#include <H5ACprivate.h> /* Cache */
#include <H5Dprivate.h> /* Dataset functions */
#include <H5Eprivate.h> /* Error handling */
+#include <H5FLprivate.h> /*Free Lists */
#include <H5Gprivate.h> /* Group headers */
#include <H5HLprivate.h> /* Name heap */
#include <H5MMprivate.h> /* Memory management */
#include <H5Oprivate.h> /* Object headers */
#include <H5Pprivate.h> /* Property lists */
#include <H5Sprivate.h> /* Dataspace functions rky 980813 */
-#include <H5TBprivate.h> /* Temporary buffers */
#include <H5Vprivate.h> /* Vector and array functions */
#include <H5Zprivate.h> /* Data filters */
@@ -84,6 +84,24 @@ static herr_t H5D_init_interface(void);
static herr_t H5D_init_storage(H5D_t *dataset, const H5S_t *space);
H5D_t * H5D_new(const H5D_create_t *create_parms);
+/* Declare a free list to manage the H5D_t struct */
+H5FL_DEFINE_STATIC(H5D_t);
+
+/* Declare a free list to manage blocks of type conversion data */
+H5FL_BLK_DEFINE_STATIC(type_conv);
+
+/* Declare a free list to manage blocks of background conversion data */
+H5FL_BLK_DEFINE_STATIC(bkgr_conv);
+
+/* Declare a free list to manage blocks of fill conversion data */
+H5FL_BLK_DEFINE_STATIC(fill_conv);
+
+/* Declare a free list to manage blocks of VL data */
+H5FL_BLK_DEFINE_STATIC(vlen_vl_buf);
+
+/* Declare a free list to manage other blocks of VL data */
+H5FL_BLK_DEFINE_STATIC(vlen_fl_buf);
+
/*--------------------------------------------------------------------------
NAME
@@ -815,7 +833,7 @@ H5D_new(const H5D_create_t *create_parms)
/* check args */
/* Nothing to check */
- if (NULL==(ret_value = H5MM_calloc(sizeof(H5D_t)))) {
+ if (NULL==(ret_value = H5FL_ALLOC(H5D_t,1))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -1113,7 +1131,7 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
H5O_close(&(new_dset->ent));
}
new_dset->ent.file = NULL;
- H5MM_xfree(new_dset);
+ H5FL_FREE(H5D_t,new_dset);
}
FUNC_LEAVE(ret_value);
}
@@ -1369,7 +1387,7 @@ done:
H5P_close (H5P_DATASET_CREATE, dataset->create_parms);
}
dataset->ent.file = NULL;
- H5MM_xfree(dataset);
+ H5FL_FREE(H5D_t,dataset);
}
FUNC_LEAVE(ret_value);
}
@@ -1423,7 +1441,7 @@ H5D_close(H5D_t *dataset)
* above).
*/
dataset->ent.file = NULL;
- H5MM_xfree(dataset);
+ H5FL_FREE(H5D_t,dataset);
if (free_failed) {
HRETURN_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
@@ -1468,8 +1486,6 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
hssize_t nelmts; /*number of elements */
size_t smine_start; /*strip mine start loc */
size_t n, smine_nelmts; /*elements per strip */
- hid_t tconv_id=FAIL; /*type conv buffer ID */
- hid_t bkg_id=FAIL; /*background buffer ID */
uint8_t *tconv_buf = NULL; /*data type conv buffer */
uint8_t *bkg_buf = NULL; /*background buffer */
H5T_path_t *tpath = NULL; /*type conversion info */
@@ -1667,18 +1683,15 @@ printf("%s: check 2.0, src_type_size=%d, dst_type_size=%d, target_size=%d, min_e
}
if (NULL==(tconv_buf=xfer_parms->tconv_buf)) {
/* Allocate temporary buffer */
- if ((tconv_id = H5TB_get_buf(target_size, 1, (void **)&tconv_buf))<0) {
+ if((tconv_buf=H5FL_BLK_ALLOC(type_conv,target_size,0))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed for type conversion");
- }
}
if (need_bkg && NULL==(bkg_buf=xfer_parms->bkg_buf)) {
/* Allocate temporary buffer */
- if ((bkg_id=H5TB_get_buf(request_nelmts*dst_type_size, 1,
- (void **)&bkg_buf))<0) {
+ if((bkg_buf=H5FL_BLK_ALLOC(bkgr_conv,request_nelmts*dst_type_size,0))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "memory allocation failed for type conversion");
- }
+ "memory allocation failed for background conversion");
}
#ifdef QAK
@@ -1809,8 +1822,10 @@ printf("%s: check 2.0, src_type_size=%d, dst_type_size=%d, target_size=%d, min_e
if (src_id >= 0) H5I_dec_ref(src_id);
if (dst_id >= 0) H5I_dec_ref(dst_id);
- if (tconv_buf && NULL==xfer_parms->tconv_buf) H5TB_release_buf(tconv_id);
- if (bkg_buf && NULL==xfer_parms->bkg_buf) H5TB_release_buf (bkg_id);
+ if (tconv_buf && NULL==xfer_parms->tconv_buf)
+ H5FL_BLK_FREE(type_conv,tconv_buf);
+ if (bkg_buf && NULL==xfer_parms->bkg_buf)
+ H5FL_BLK_FREE(bkgr_conv,bkg_buf);
if (free_this_space) H5S_close(free_this_space);
FUNC_LEAVE(ret_value);
}
@@ -1848,8 +1863,6 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
hssize_t nelmts; /*total number of elmts */
size_t smine_start; /*strip mine start loc */
size_t n, smine_nelmts; /*elements per strip */
- hid_t tconv_id=FAIL; /*type conv buffer ID */
- hid_t bkg_id=FAIL; /*background buffer ID */
uint8_t *tconv_buf = NULL; /*data type conv buffer */
uint8_t *bkg_buf = NULL; /*background buffer */
H5T_path_t *tpath = NULL; /*type conversion info */
@@ -2080,18 +2093,15 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
}
if (NULL==(tconv_buf=xfer_parms->tconv_buf)) {
/* Allocate temporary buffer */
- if ((tconv_id=H5TB_get_buf(target_size, 1, (void **)&tconv_buf))<0) {
+ if((tconv_buf=H5FL_BLK_ALLOC(type_conv,target_size,0))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed for type conversion");
- }
}
if (need_bkg && NULL==(bkg_buf=xfer_parms->bkg_buf)) {
/* Allocate temporary buffer */
- if ((bkg_id=H5TB_get_buf(request_nelmts*dst_type_size, 1,
- (void **)&bkg_buf))<0) {
+ if((bkg_buf=H5FL_BLK_ALLOC(bkgr_conv,request_nelmts*dst_type_size,0))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "memory allocation failed for type conversion");
- }
+ "memory allocation failed for background conversion");
}
#ifdef QAK
@@ -2233,8 +2243,10 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
if (src_id >= 0) H5I_dec_ref(src_id);
if (dst_id >= 0) H5I_dec_ref(dst_id);
- if (tconv_buf && NULL==xfer_parms->tconv_buf) H5TB_release_buf(tconv_id);
- if (bkg_buf && NULL==xfer_parms->bkg_buf) H5TB_release_buf (bkg_id);
+ if (tconv_buf && NULL==xfer_parms->tconv_buf)
+ H5FL_BLK_FREE(type_conv,tconv_buf);
+ if (bkg_buf && NULL==xfer_parms->bkg_buf)
+ H5FL_BLK_FREE(bkgr_conv,bkg_buf);
if (free_this_space) H5S_close(free_this_space);
FUNC_LEAVE(ret_value);
}
@@ -2421,7 +2433,6 @@ H5D_init_storage(H5D_t *dset, const H5S_t *space)
{
hssize_t npoints, ptsperbuf;
size_t size, bufsize=8*1024;
- hid_t buf_id = -1;
haddr_t addr;
herr_t ret_value = FAIL;
void *buf = NULL;
@@ -2448,10 +2459,12 @@ H5D_init_storage(H5D_t *dset, const H5S_t *space)
ptsperbuf = (hssize_t)MAX(1,
bufsize/dset->create_parms->fill.size);
bufsize = ptsperbuf * dset->create_parms->fill.size;
- if ((buf_id=H5TB_get_buf(bufsize, TRUE, &buf))<0) {
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to get buffer for fill value");
- }
+
+ /* Allocate temporary buffer */
+ if ((buf=H5FL_BLK_ALLOC(fill_conv,bufsize,0))==NULL)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "memory allocation failed for fill buffer");
+
H5V_array_fill(buf, dset->create_parms->fill.buf,
dset->create_parms->fill.size, ptsperbuf);
if (dset->create_parms->efl.nused) {
@@ -2520,10 +2533,8 @@ H5D_init_storage(H5D_t *dset, const H5S_t *space)
ret_value = SUCCEED;
done:
- if (buf_id>=0 && H5TB_release_buf(buf_id)<0) {
- HRETURN_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
- "unable to release fill value temporary buffer");
- }
+ if (buf)
+ H5FL_BLK_FREE(fill_conv,buf);
FUNC_LEAVE(ret_value);
}
@@ -2763,15 +2774,14 @@ H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf)
void *H5D_vlen_get_buf_size_alloc(size_t size, void *info)
{
H5T_vlen_bufsize_t *vlen_bufsize=(H5T_vlen_bufsize_t *)info;
- void *ret_value=NULL; /* Pointer to return */
FUNC_ENTER(H5D_vlen_get_buf_size_alloc, NULL);
/* Get a temporary pointer to space for the VL data */
- if (H5TB_resize_buf(vlen_bufsize->vl_tbuf_id,size,&ret_value)>=0)
+ if ((vlen_bufsize->vl_tbuf=H5FL_BLK_REALLOC(vlen_vl_buf,vlen_bufsize->vl_tbuf,size))!=NULL)
vlen_bufsize->size+=size;
- FUNC_LEAVE(ret_value);
+ FUNC_LEAVE(vlen_bufsize->vl_tbuf);
} /* end H5D_vlen_get_buf_size_alloc() */
@@ -2787,7 +2797,7 @@ void *H5D_vlen_get_buf_size_alloc(size_t size, void *info)
*
* Implementation: This routine actually performs the read with a custom
* memory manager which basically just counts the bytes requested and
- * uses a temporary memory buffer (through the H5TB API) to make certain
+ * uses a temporary memory buffer (through the H5FL API) to make certain
* enough space is available to perform the read. Then the temporary
* buffer is released and the number of bytes allocated is returned.
* Kinda kludgy, but easier than the other method of trying to figure out
@@ -2806,7 +2816,6 @@ herr_t
H5D_vlen_get_buf_size(void UNUSED *elem, hid_t type_id, hsize_t UNUSED ndim, hssize_t *point, void *op_data)
{
H5T_vlen_bufsize_t *vlen_bufsize=(H5T_vlen_bufsize_t *)op_data;
- void *tbuf; /* pointer to temporary buffer */
H5T_t *dt = NULL;
herr_t ret_value=FAIL;
@@ -2820,7 +2829,7 @@ H5D_vlen_get_buf_size(void UNUSED *elem, hid_t type_id, hsize_t UNUSED ndim, hss
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
/* Make certain there is enough fixed-length buffer available */
- if (H5TB_resize_buf(vlen_bufsize->fl_tbuf_id,H5T_get_size(dt),&tbuf)<0)
+ if ((vlen_bufsize->fl_tbuf=H5FL_BLK_REALLOC(vlen_fl_buf,vlen_bufsize->fl_tbuf,H5T_get_size(dt)))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't resize tbuf");
/* Select point to read in */
@@ -2828,7 +2837,7 @@ H5D_vlen_get_buf_size(void UNUSED *elem, hid_t type_id, hsize_t UNUSED ndim, hss
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't select point");
/* Read in the point (with the custom VL memory allocator) */
- if(H5Dread(vlen_bufsize->dataset_id,type_id,vlen_bufsize->mspace_id,vlen_bufsize->fspace_id,vlen_bufsize->xfer_pid,tbuf)<0)
+ if(H5Dread(vlen_bufsize->dataset_id,type_id,vlen_bufsize->mspace_id,vlen_bufsize->fspace_id,vlen_bufsize->xfer_pid,vlen_bufsize->fl_tbuf)<0)
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read point");
/* Set the correct return value, if we get this far */
@@ -2851,7 +2860,7 @@ done:
*
* Implementation: This routine actually performs the read with a custom
* memory manager which basically just counts the bytes requested and
- * uses a temporary memory buffer (through the H5TB API) to make certain
+ * uses a temporary memory buffer (through the H5FL API) to make certain
* enough space is available to perform the read. Then the temporary
* buffer is released and the number of bytes allocated is returned.
* Kinda kludgy, but easier than the other method of trying to figure out
@@ -2896,9 +2905,9 @@ H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id,
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't create dataspace");
/* Grab the temporary buffers required */
- if((vlen_bufsize.fl_tbuf_id=H5TB_get_buf(1,0,NULL))<0)
+ if((vlen_bufsize.fl_tbuf=H5FL_BLK_ALLOC(vlen_fl_buf,1,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "no temporary buffers available");
- if((vlen_bufsize.vl_tbuf_id=H5TB_get_buf(1,0,NULL))<0)
+ if((vlen_bufsize.vl_tbuf=H5FL_BLK_ALLOC(vlen_vl_buf,1,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "no temporary buffers available");
/* Change to the custom memory allocation routines for reading VL data */
@@ -2924,10 +2933,10 @@ done:
H5Sclose(vlen_bufsize.fspace_id);
if(vlen_bufsize.mspace_id>0)
H5Sclose(vlen_bufsize.mspace_id);
- if(vlen_bufsize.fl_tbuf_id>0)
- H5TB_release_buf(vlen_bufsize.fl_tbuf_id);
- if(vlen_bufsize.vl_tbuf_id>0)
- H5TB_release_buf(vlen_bufsize.vl_tbuf_id);
+ if(vlen_bufsize.fl_tbuf!=NULL)
+ H5FL_BLK_FREE(vlen_fl_buf,vlen_bufsize.fl_tbuf);
+ if(vlen_bufsize.vl_tbuf!=NULL)
+ H5FL_BLK_FREE(vlen_vl_buf,vlen_bufsize.vl_tbuf);
if(vlen_bufsize.xfer_pid>0)
H5Pclose(vlen_bufsize.xfer_pid);
diff --git a/src/H5Distore.c b/src/H5Distore.c
index 31506e6..c4728ad 100644
--- a/src/H5Distore.c
+++ b/src/H5Distore.c
@@ -33,6 +33,7 @@
#include <H5Dprivate.h>
#include <H5Eprivate.h>
#include <H5Fprivate.h>
+#include <H5FLprivate.h> /*Free Lists */
#include <H5Iprivate.h>
#include <H5MFprivate.h>
#include <H5MMprivate.h>
@@ -186,6 +187,103 @@ H5B_class_t H5B_ISTORE[1] = {{
}
+/* Declare a free list to manage the chunk information */
+H5FL_BLK_DEFINE_STATIC(istore_chunk);
+
+/* Declare a free list to manage H5F_rdcc_ent_t objects */
+H5FL_DEFINE_STATIC(H5F_rdcc_ent_t);
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_chunk_alloc
+ *
+ * Purpose: Allocates memory for a chunk of a dataset. This routine is used
+ * instead of malloc because the chunks can be kept on a free list so
+ * they don't thrash malloc/free as much.
+ *
+ * Return: Success: valid pointer to the chunk
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, March 21, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5F_istore_chunk_alloc(size_t chunk_size)
+{
+ void *ret_value; /* Pointer to the chunk to return to the user */
+
+ FUNC_ENTER(H5F_istore_chunk_alloc, NULL);
+
+ ret_value=H5FL_BLK_ALLOC(istore_chunk,chunk_size,0);
+
+ FUNC_LEAVE(ret_value);
+} /* end H5F_istore_chunk_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_chunk_free
+ *
+ * Purpose: Releases memory for a chunk of a dataset. This routine is used
+ * instead of free because the chunks can be kept on a free list so
+ * they don't thrash malloc/free as much.
+ *
+ * Return: Success: NULL
+ *
+ * Failure: never fails
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, March 21, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5F_istore_chunk_free(void *chunk)
+{
+ FUNC_ENTER(H5F_istore_chunk_free, NULL);
+
+ H5FL_BLK_FREE(istore_chunk,chunk);
+
+ FUNC_LEAVE(NULL);
+} /* end H5F_istore_chunk_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_chunk_realloc
+ *
+ * Purpose: Resizes a chunk in chunking memory allocation system. This
+ * does things the straightforward, simple way, not actually using
+ * realloc.
+ *
+ * Return: Success: NULL
+ *
+ * Failure: never fails
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, March 21, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5F_istore_chunk_realloc(void *chunk, size_t new_size)
+{
+ void *ret_value=NULL; /* Return value */
+
+ FUNC_ENTER(H5F_istore_chunk_realloc, NULL);
+
+ ret_value=H5FL_BLK_REALLOC(istore_chunk,chunk,new_size);
+
+ FUNC_LEAVE(ret_value);
+} /* end H5F_istore_chunk_realloc() */
+
/*-------------------------------------------------------------------------
* Function: H5F_istore_sizeof_rkey
@@ -871,7 +969,7 @@ H5F_istore_flush_entry(H5F_t *f, H5F_rdcc_ent_t *ent, hbool_t reset)
* for later.
*/
alloc = ent->chunk_size;
- if (NULL==(buf = H5MM_malloc(alloc))) {
+ if (NULL==(buf = H5F_istore_chunk_alloc(alloc))) {
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed for pipeline");
}
@@ -920,14 +1018,15 @@ H5F_istore_flush_entry(H5F_t *f, H5F_rdcc_ent_t *ent, hbool_t reset)
ent->layout = H5O_free(H5O_LAYOUT, ent->layout);
ent->pline = H5O_free(H5O_PLINE, ent->pline);
if (buf==ent->chunk) buf = NULL;
- ent->chunk = H5MM_xfree(ent->chunk);
+ if(ent->chunk!=NULL)
+ ent->chunk = H5F_istore_chunk_free(ent->chunk);
}
ret_value = SUCCEED;
done:
/* Free the temp buffer only if it's different than the entry chunk */
- if (buf!=ent->chunk) H5MM_xfree(buf);
+ if (buf!=ent->chunk) H5F_istore_chunk_free(buf);
/*
* If we reached the point of no return then we have no choice but to
@@ -938,7 +1037,8 @@ H5F_istore_flush_entry(H5F_t *f, H5F_rdcc_ent_t *ent, hbool_t reset)
if (ret_value<0 && point_of_no_return) {
ent->layout = H5O_free(H5O_LAYOUT, ent->layout);
ent->pline = H5O_free(H5O_PLINE, ent->pline);
- ent->chunk = H5MM_xfree(ent->chunk);
+ if(ent->chunk)
+ ent->chunk = H5F_istore_chunk_free(ent->chunk);
}
FUNC_LEAVE(ret_value);
}
@@ -993,7 +1093,7 @@ H5F_istore_preempt (H5F_t *f, H5F_rdcc_ent_t *ent)
--rdcc->nused;
/* Free */
- H5MM_xfree(ent);
+ H5FL_FREE(H5F_rdcc_ent_t, ent);
FUNC_LEAVE (SUCCEED);
}
@@ -1291,7 +1391,7 @@ H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
chunk_size *= layout->dim[i];
}
chunk_alloc = chunk_size;
- if (NULL==(chunk=H5MM_malloc (chunk_alloc))) {
+ if (NULL==(chunk=H5F_istore_chunk_alloc (chunk_alloc))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed for raw data chunk");
}
@@ -1310,7 +1410,7 @@ H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
udata.addr = HADDR_UNDEF;
status = H5B_find (f, H5B_ISTORE, layout->addr, &udata);
H5E_clear ();
- if (NULL==(chunk = H5MM_malloc (chunk_alloc))) {
+ if (NULL==(chunk = H5F_istore_chunk_alloc (chunk_alloc))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed for raw data chunk");
}
@@ -1386,7 +1486,7 @@ H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
}
/* Create a new entry */
- ent = H5MM_malloc(sizeof(H5F_rdcc_ent_t));
+ ent = H5FL_ALLOC(H5F_rdcc_ent_t,0);
ent->locked = 0;
ent->dirty = FALSE;
ent->chunk_size = chunk_size;
@@ -1471,7 +1571,7 @@ H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
ret_value = chunk;
done:
- if (!ret_value) H5MM_xfree (chunk);
+ if (!ret_value) H5F_istore_chunk_free (chunk);
FUNC_LEAVE (ret_value);
}
@@ -1552,7 +1652,8 @@ H5F_istore_unlock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
H5F_istore_flush_entry (f, &x, TRUE);
} else {
- H5MM_xfree (chunk);
+ if(chunk)
+ H5F_istore_chunk_free (chunk);
}
} else {
/*
diff --git a/src/H5FL.c b/src/H5FL.c
new file mode 100644
index 0000000..a3c4725
--- /dev/null
+++ b/src/H5FL.c
@@ -0,0 +1,1257 @@
+/*
+ * Copyright (C) 2000 NCSA
+ * All rights reserved.
+ *
+ * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
+ * Thursday, March 23, 2000
+ *
+ * Purpose: Manage priority queues of free-lists (of blocks of bytes).
+ * These are used in various places in the library which allocate and
+ * free differently blocks of bytes repeatedly. Usually the same size
+ * of block is allocated and freed repeatly in a loop, while writing out
+ * chunked data for example, but the blocks may also be of different sizes
+ * from different datasets and an attempt is made to optimize access to
+ * the proper free list of blocks by using these priority queues to
+ * move frequently accessed free lists to the head of the queue.
+ */
+
+/* #define H5FL_DEBUG */
+
+#include <H5private.h> /*library */
+#include <H5Eprivate.h> /*error handling */
+#include <H5MMprivate.h> /*Core memory management */
+#include <H5FLprivate.h> /*Priority queues */
+
+#define PABLO_MASK H5FL_mask
+static intn interface_initialize_g = 0;
+#define INTERFACE_INIT NULL
+
+/*
+ * Private type definitions
+ */
+
+/* A garbage collection node for priority queues */
+typedef struct H5FL_blk_gc_list_t {
+ H5FL_blk_head_t *pq; /* Pointer to the head of the PQ to garbage collect */
+ struct H5FL_blk_gc_list_t *next; /* Pointer to the next node in the list of things to garbage collect */
+} H5FL_blk_gc_list_t;
+
+/* A garbage collection node for regular free lists */
+typedef struct H5FL_gc_list_t {
+ H5FL_head_t *list; /* Pointer to the head of the list to garbage collect */
+ struct H5FL_gc_list_t *next; /* Pointer to the next node in the list of things to garbage collect */
+} H5FL_gc_list_t;
+
+/* A garbage collection node for array free lists */
+typedef struct H5FL_gc_arr_list_t {
+ H5FL_arr_head_t *list; /* Pointer to the head of the list to garbage collect */
+ struct H5FL_gc_arr_list_t *next; /* Pointer to the next node in the list of things to garbage collect */
+} H5FL_gc_arr_list_t;
+
+/* The head of the list of PQs to garbage collect */
+static H5FL_blk_gc_list_t *H5FL_blk_gc_head=NULL;
+
+/* The head of the list of things to garbage collect */
+static H5FL_gc_list_t *H5FL_gc_head=NULL;
+
+/* The head of the list of array things to garbage collect */
+static H5FL_gc_arr_list_t *H5FL_gc_arr_head=NULL;
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_init
+ *
+ * Purpose: Initialize a free list for a certain type. Right now, this just
+ * adds the free list to the list of things to garbage collect.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Friday, March 24, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FL_init(H5FL_head_t *head)
+{
+ H5FL_gc_list_t *new_list; /* Pointer to the node for the new list to garbage collect */
+ herr_t ret_value=SUCCEED; /* return value*/
+
+ FUNC_ENTER (H5FL_init, FAIL);
+
+ /* Allocate a new garbage collection node */
+ if (NULL==(new_list = H5MM_malloc(sizeof(H5FL_gc_list_t))))
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+
+ /* Initialize the new garbage collection node */
+ new_list->list=head;
+
+ /* Link in to the garbage collection list */
+ new_list->next=H5FL_gc_head;
+ H5FL_gc_head=new_list;
+
+ /* Indicate that the free list is initialized */
+ head->init=1;
+
+ FUNC_LEAVE (ret_value);
+} /* end H5FL_init() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_free
+ *
+ * Purpose: Release an object & put on free list
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Friday, March 24, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5FL_free(H5FL_head_t *head, void *obj)
+{
+ H5FL_node_t *temp; /* Temp. ptr to the new free list node allocated */
+
+ FUNC_ENTER (H5FL_free, NULL);
+
+ /* Make certain that the free list is initialized */
+ assert(head->init);
+
+ /* Get the pointer to the info header in front of the block to free */
+ temp=(H5FL_node_t *)((unsigned char *)obj-offsetof(H5FL_node_t,block));
+
+#ifdef H5FL_DEBUG
+ assert(temp->inuse);
+ temp->inuse=0;
+#endif /* H5FL_DEBUG */
+
+ /* Link into the free list */
+ temp->next=head->list;
+
+ /* Point free list at the node freed */
+ head->list=temp;
+
+ /* Increment the number of blocks on free list */
+ head->onlist++;
+
+ FUNC_LEAVE(NULL);
+} /* end H5FL_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_alloc
+ *
+ * Purpose: Allocate a block on a free list
+ *
+ * Return: Success: Pointer to a valid object
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Friday, March 24, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5FL_alloc(H5FL_head_t *head, uintn clear)
+{
+ H5FL_node_t *new_obj; /* Pointer to the new free list node allocated */
+ void *ret_value; /* Pointer to object to return */
+
+ FUNC_ENTER (H5FL_alloc, NULL);
+
+ /* Make certain the list is initialized first */
+ if(!head->init)
+ H5FL_init(head);
+
+ /* Check for nodes available on the free list first */
+ if(head->list!=NULL) {
+ /* Get a pointer to the block on the free list */
+ ret_value=&(head->list->block);
+
+#ifdef H5FL_DEBUG
+ head->list->inuse=1;
+#endif /* H5FL_DEBUG */
+
+ /* Remove node from free list */
+ head->list=head->list->next;
+
+ /* Decrement the number of blocks on free list */
+ head->onlist--;
+ } /* end if */
+ /* Otherwise allocate a node */
+ else {
+ if (NULL==(new_obj = H5MM_malloc(sizeof(H5FL_node_t)+(head->size-1))))
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+
+#ifdef H5FL_DEBUG
+ new_obj->inuse=1;
+#endif /* H5FL_DEBUG */
+
+ /* Increment the number of blocks allocated in list */
+ head->allocated++;
+
+ /* Get a pointer to the new block */
+ ret_value=&(new_obj->block);
+ } /* end else */
+
+ /* Clear to zeros, if asked */
+ if(clear)
+ HDmemset(ret_value,0,head->size);
+
+ FUNC_LEAVE (ret_value);
+} /* end H5FL_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_gc
+ *
+ * Purpose: Garbage collect on all the object free lists
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Friday, March 24, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FL_gc(void)
+{
+ H5FL_gc_list_t *gc_list; /* Pointer into the list of things to garbage collect */
+ H5FL_head_t *list_head; /* Pointer to head of free list to garbage collect */
+ H5FL_node_t *free_list; /* Pointer to nodes in free list being garbage collected */
+ void *tmp; /* Temporary node pointer */
+
+ /* FUNC_ENTER_INIT() should not be called, it causes an infinite loop at library termination */
+ H5_trace(FALSE, "H5FL_gc", "");
+
+ /* Walk through all the free lists, free()'ing the nodes */
+ gc_list=H5FL_gc_head;
+ while(gc_list!=NULL) {
+ /* Get the pointer to the list head */
+ list_head=gc_list->list;
+
+ /* For each free list being garbage collected, walk through the nodes and free them */
+ free_list=list_head->list;
+ while(free_list!=NULL) {
+ tmp=free_list->next;
+
+ /* Decrement the count of nodes allocated and free the node */
+ list_head->allocated--;
+
+#ifdef H5FL_DEBUG
+ assert(!free_list->inuse);
+#endif /* H5FL_DEBUG */
+
+ H5MM_xfree(free_list);
+
+ free_list=tmp;
+ } /* end while */
+
+ /* Indicate no free nodes on the free list */
+ list_head->list=NULL;
+ list_head->onlist=0;
+
+ /* Go on to the next free list to garbage collect */
+ gc_list=gc_list->next;
+ } /* end while */
+
+ H5_trace(TRUE, NULL, "e", SUCCEED);
+ return(SUCCEED);
+} /* end H5FL_gc() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5FL_term
+ PURPOSE
+ Terminate various H5FL object free lists
+ USAGE
+ intn H5FL_term()
+ RETURNS
+ Success: Positive if any action might have caused a change in some
+ other interface; zero otherwise.
+ Failure: Negative
+ DESCRIPTION
+ Release any resources allocated.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Can't report errors...
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static intn
+H5FL_term(void)
+{
+ H5FL_gc_list_t *left; /* pointer to garbage collection lists with work left */
+ H5FL_gc_list_t *tmp; /* Temporary pointer to a garbage collection node */
+
+ /* Free the nodes on the garbage collection list, keeping nodes with allocations outstanding */
+ left=NULL;
+ while(H5FL_gc_head!=NULL) {
+ tmp=H5FL_gc_head->next;
+
+#ifdef H5FL_DEBUG
+printf("H5FL_term: head->name=%s, head->allocated=%d\n", H5FL_gc_head->list->name,(int)H5FL_gc_head->list->allocated);
+#endif /* H5FL_DEBUG */
+ /* Check if the list has allocations outstanding */
+ if(H5FL_gc_head->list->allocated>0) {
+ /* Add free list to the list of nodes with allocations open still */
+ H5FL_gc_head->next=left;
+ left=H5FL_gc_head;
+ } /* end if */
+ /* No allocations left open for list, get rid of it */
+ else {
+ /* Reset the "initialized" flag, in case we restat this list somehow (I don't know how..) */
+ H5FL_gc_head->list->init=0;
+
+ /* Free the node from the garbage collection list */
+ H5MM_xfree(H5FL_gc_head);
+ } /* end else */
+
+ H5FL_gc_head=tmp;
+ } /* end while */
+
+ /* Point to the list of nodes left with allocations open, if any */
+ H5FL_gc_head=left;
+
+ return (H5FL_gc_head!=NULL ? 1 : 0);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_blk_find_list
+ *
+ * Purpose: Finds the free list for blocks of a given size. Also moves that
+ * free list node to the head of the priority queue (if it isn't there
+ * already). This routine does not manage the actual free list, it just
+ * works with the priority queue.
+ *
+ * Return: Success: valid pointer to the free list node
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, March 23, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5FL_blk_node_t *
+H5FL_blk_find_list(H5FL_blk_node_t **head, size_t size)
+{
+ H5FL_blk_node_t *temp; /* Temp. pointer to node in the native list */
+ H5FL_blk_node_t *ret_value=NULL;
+
+ FUNC_ENTER(H5FL_blk_find_list, NULL);
+
+ /* Find the correct free list */
+ temp=*head;
+ while(temp!=NULL && temp->size!=size)
+ temp=temp->next;
+
+ /* If the free list exists, move it to the front of the queue, if it's not there already */
+ if(temp!=NULL && temp!=*head) {
+ /* Take the node found out of it's current position */
+ if(temp->next==NULL) {
+ temp->prev->next=NULL;
+ } /* end if */
+ else {
+ temp->prev->next=temp->next;
+ temp->next->prev=temp->prev;
+ } /* end else */
+
+ /* Move the found node to the head of the list */
+ temp->prev=NULL;
+ temp->next=*head;
+ (*head)->prev=temp;
+ *head=temp;
+ } /* end if */
+
+ ret_value=temp;
+
+ FUNC_LEAVE(ret_value);
+} /* end H5FL_blk_find_list() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_blk_create_list
+ *
+ * Purpose: Creates a new free list for blocks of the given size at the
+ * head of the priority queue.
+ *
+ * Return: Success: valid pointer to the free list node
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, March 23, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5FL_blk_node_t *
+H5FL_blk_create_list(H5FL_blk_node_t **head, size_t size)
+{
+ H5FL_blk_node_t *temp; /* Temp. pointer to node in the list */
+ H5FL_blk_node_t *ret_value=NULL;
+
+ FUNC_ENTER(H5FL_blk_create_list, NULL);
+
+ /* Allocate room for the new free list node */
+ if(NULL==(temp=H5MM_malloc(sizeof(H5FL_blk_node_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for chunk info");
+
+ /* Set the correct values for the new free list */
+ temp->size=size;
+ temp->list=NULL;
+
+ /* Attach to head of priority queue */
+ if(*head==NULL) {
+ *head=temp;
+ temp->next=temp->prev=NULL;
+ } /* end if */
+ else {
+ temp->next=*head;
+ (*head)->prev=temp;
+ temp->prev=NULL;
+ *head=temp;
+ } /* end else */
+
+ ret_value=temp;
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5FL_blk_create_list() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_blk_init
+ *
+ * Purpose: Initialize a priority queue of a certain type. Right now, this just
+ * adds the PQ to the list of things to garbage collect.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, March 25, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FL_blk_init(H5FL_blk_head_t *head)
+{
+ H5FL_blk_gc_list_t *new_pq; /* Pointer to the node for the new list to garbage collect */
+ herr_t ret_value=SUCCEED; /* return value*/
+
+ FUNC_ENTER (H5FL_blk_init, FAIL);
+
+ /* Allocate a new garbage collection node */
+ if (NULL==(new_pq = H5MM_malloc(sizeof(H5FL_blk_gc_list_t))))
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+
+ /* Initialize the new garbage collection node */
+ new_pq->pq=head;
+
+ /* Link in to the garbage collection list */
+ new_pq->next=H5FL_blk_gc_head;
+ H5FL_blk_gc_head=new_pq;
+
+ /* Indicate that the PQ is initialized */
+ head->init=1;
+
+ FUNC_LEAVE (ret_value);
+} /* end H5FL_blk_init() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_blk_alloc
+ *
+ * Purpose: Allocates memory for a block. This routine is used
+ * instead of malloc because the block can be kept on a free list so
+ * they don't thrash malloc/free as much.
+ *
+ * Return: Success: valid pointer to the block
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, March 23, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5FL_blk_alloc(H5FL_blk_head_t *head, size_t size, uintn clear)
+{
+ H5FL_blk_node_t *free_list; /* The free list of nodes of correct size */
+ H5FL_blk_list_t *temp; /* Temp. ptr to the new native list allocated */
+ void *ret_value; /* Pointer to the block to return to the user */
+
+ FUNC_ENTER(H5FL_blk_alloc, NULL);
+
+ /* Make certain the list is initialized first */
+ if(!head->init)
+ H5FL_blk_init(head);
+
+ /* check if there is a free list for blocks of this size */
+ /* and if there are any blocks available on the list */
+ if((free_list=H5FL_blk_find_list(&(head->head),size))!=NULL && free_list->list!=NULL) {
+ /* Remove the first node from the list and return it */
+ ret_value=(void *)&(free_list->list->block);
+ free_list->list=free_list->list->next;
+
+ /* Decrement the number of blocks on free list */
+ head->onlist--;
+ } /* end if */
+ /* No free list available, or there are no nodes on the list, allocate a new node to give to the user */
+ else {
+ /* Allocate new node, with room for the page info header and the actual page data */
+ if(NULL==(temp=H5MM_malloc(sizeof(H5FL_blk_list_t)+(size-1))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for chunk");
+
+ /* Increment the number of blocks allocated */
+ head->allocated++;
+
+ /* Initialize the block allocated */
+ temp->size=size;
+ temp->next=NULL;
+
+ /* Set the return value to the block itself */
+ ret_value=(void *)&(temp->block);
+ } /* end else */
+
+ /* Clear the block to zeros, if requested */
+ if(clear)
+ HDmemset(ret_value,0,size);
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* end H5FL_blk_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_blk_free
+ *
+ * Purpose: Releases memory for a block. This routine is used
+ * instead of free because the blocks can be kept on a free list so
+ * they don't thrash malloc/free as much.
+ *
+ * Return: Success: NULL
+ *
+ * Failure: never fails
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, March 23, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5FL_blk_free(H5FL_blk_head_t *head, void *block)
+{
+ H5FL_blk_node_t *free_list; /* The free list of nodes of correct size */
+ H5FL_blk_list_t *temp; /* Temp. ptr to the new free list node allocated */
+
+ FUNC_ENTER(H5FL_blk_free, NULL);
+
+ /* Get the pointer to the native block info header in front of the native block to free */
+ temp=(H5FL_blk_list_t *)((unsigned char *)block-offsetof(H5FL_blk_list_t,block));
+
+ /* check if there is a free list for native blocks of this size */
+ if((free_list=H5FL_blk_find_list(&(head->head),temp->size))==NULL) {
+ /* No free list available, create a new list node and insert it to the queue */
+ free_list=H5FL_blk_create_list(&(head->head),temp->size);
+ } /* end if */
+
+ /* Prepend the free'd native block to the front of the free list */
+ if(free_list!=NULL) {
+ temp->next=free_list->list;
+ free_list->list=temp;
+ } /* end if */
+
+ /* Increment the number of blocks on free list */
+ head->onlist++;
+
+ FUNC_LEAVE(NULL);
+} /* end H5FL_blk_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_blk_realloc
+ *
+ * Purpose: Resizes a block. This does things the straightforward, simple way,
+ * not actually using realloc.
+ *
+ * Return: Success: NULL
+ *
+ * Failure: never fails
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, March 23, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5FL_blk_realloc(H5FL_blk_head_t *head, void *block, size_t new_size)
+{
+ H5FL_blk_list_t *temp; /* Temp. ptr to the new block node allocated */
+ void *ret_value=NULL; /* Return value */
+
+ FUNC_ENTER(H5FL_blk_realloc, NULL);
+
+ /* Check if we are actually re-allocating a block */
+ if(block!=NULL) {
+ /* Get the pointer to the chunk info header in front of the chunk to free */
+ temp=(H5FL_blk_list_t *)((unsigned char *)block-offsetof(H5FL_blk_list_t,block));
+
+ /* check if we are actually changing the size of the buffer */
+ if(new_size!=temp->size) {
+ ret_value=H5FL_blk_alloc(head,new_size,0);
+ HDmemcpy(ret_value,block,MIN(new_size,temp->size));
+ H5FL_blk_free(head,block);
+ } /* end if */
+ else
+ ret_value=block;
+ } /* end if */
+ /* Not re-allocating, just allocate a fresh block */
+ else
+ ret_value=H5FL_blk_alloc(head,new_size,0);
+
+ FUNC_LEAVE(ret_value);
+} /* end H5FL_blk_realloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_blk_gc_list
+ *
+ * Purpose: Garbage collect a priority queue
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, March 23, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FL_blk_gc_list(H5FL_blk_head_t *head)
+{
+ H5FL_blk_list_t *list; /* The free list of native nodes of a particular size */
+ void *next; /* Temp. ptr to the free list list node */
+ void *temp; /* Temp. ptr to the free list page node */
+
+ /* FUNC_ENTER_INIT() should not be called, it causes an infinite loop at library termination */
+ H5_trace(FALSE, "H5FL_blk_gc_list", "");
+
+ /* Loop through all the nodes in the block free list queue */
+ while(head->head!=NULL) {
+ temp=head->head->next;
+
+ /* Loop through all the blocks in the free list, freeing them */
+ list=head->head->list;
+ while(list!=NULL) {
+ next=list->next;
+
+ /* Decrement the number of blocks allocated from this PQ */
+ head->allocated--;
+
+ /* Free the block */
+ H5MM_xfree(list);
+
+ list=next;
+ } /* end while */
+
+ /* Free the free list node */
+ H5MM_xfree(head->head);
+
+ /* Advance to the next free list */
+ head->head=temp;
+ } /* end while */
+
+ H5_trace(TRUE, NULL, "e", SUCCEED);
+ return(SUCCEED);
+} /* end H5FL_blk_gc_list() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_blk_gc
+ *
+ * Purpose: Garbage collect on all the priority queues
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, March 25, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FL_blk_gc(void)
+{
+ H5FL_blk_gc_list_t *gc_list; /* Pointer into the list of things to garbage collect */
+ H5FL_blk_head_t *pq_head; /* Pointer to head of PQ to garbage collect */
+
+ /* FUNC_ENTER_INIT() should not be called, it causes an infinite loop at library termination */
+ H5_trace(FALSE, "H5FL_blk_gc", "");
+
+ /* Walk through all the free lists, free()'ing the nodes */
+ gc_list=H5FL_blk_gc_head;
+ while(gc_list!=NULL) {
+ /* Get the pointer to the list head */
+ pq_head=gc_list->pq;
+
+ /* For each free list being garbage collected, walk through the nodes and free them */
+ H5FL_blk_gc_list(gc_list->pq);
+
+ /* Indicate no free nodes on the free list */
+ pq_head->head=NULL;
+ pq_head->onlist=0;
+
+ /* Go on to the next free list to garbage collect */
+ gc_list=gc_list->next;
+ } /* end while */
+
+ H5_trace(TRUE, NULL, "e", SUCCEED);
+ return(SUCCEED);
+} /* end H5FL_blk_gc() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5FL_blk_term
+ PURPOSE
+ Terminate various H5FL_blk objects
+ USAGE
+ void H5FL_blk_term()
+ RETURNS
+ Success: Positive if any action might have caused a change in some
+ other interface; zero otherwise.
+ Failure: Negative
+ DESCRIPTION
+ Release any resources allocated.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Can't report errors...
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static intn
+H5FL_blk_term(void)
+{
+ H5FL_blk_gc_list_t *left; /* pointer to garbage collection lists with work left */
+ H5FL_blk_gc_list_t *tmp; /* Temporary pointer to a garbage collection node */
+
+ /* Free the nodes on the garbage collection list, keeping nodes with allocations outstanding */
+ left=NULL;
+ while(H5FL_blk_gc_head!=NULL) {
+ tmp=H5FL_blk_gc_head->next;
+
+#ifdef H5FL_DEBUG
+printf("H5FL_blk_term: head->name=%s, head->allocated=%d\n", H5FL_blk_gc_head->pq->name,(int)H5FL_blk_gc_head->pq->allocated);
+#endif /* H5FL_DEBUG */
+ /* Check if the list has allocations outstanding */
+ if(H5FL_blk_gc_head->pq->allocated>0) {
+ /* Add free list to the list of nodes with allocations open still */
+ H5FL_blk_gc_head->next=left;
+ left=H5FL_blk_gc_head;
+ } /* end if */
+ /* No allocations left open for list, get rid of it */
+ else {
+ /* Reset the "initialized" flag, in case we restat this list somehow (I don't know how..) */
+ H5FL_blk_gc_head->pq->init=0;
+
+ /* Free the node from the garbage collection list */
+ H5MM_xfree(H5FL_blk_gc_head);
+ } /* end else */
+
+ H5FL_blk_gc_head=tmp;
+ } /* end while */
+
+ /* Point to the list of nodes left with allocations open, if any */
+ H5FL_blk_gc_head=left;
+
+ return (H5FL_blk_gc_head!=NULL ? 1 : 0);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_arr_init
+ *
+ * Purpose: Initialize a free list for a arrays of certain type. Right now,
+ * this just adds the free list to the list of things to garbage collect.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, March 25, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FL_arr_init(H5FL_arr_head_t *head)
+{
+ H5FL_gc_arr_list_t *new_list; /* Pointer to the node for the new list to garbage collect */
+ herr_t ret_value=SUCCEED; /* return value*/
+
+ FUNC_ENTER (H5FL_arr_init, FAIL);
+
+ /* Allocate a new garbage collection node */
+ if (NULL==(new_list = H5MM_malloc(sizeof(H5FL_gc_arr_list_t))))
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+
+ /* Initialize the new garbage collection node */
+ new_list->list=head;
+
+ /* Link in to the garbage collection list */
+ new_list->next=H5FL_gc_arr_head;
+ H5FL_gc_arr_head=new_list;
+
+ /* Allocate room for the free lists, if the arrays have a maximum size */
+ if(head->maxelem>0) {
+ if (NULL==(head->u.list_arr = H5MM_calloc(head->maxelem*sizeof(H5FL_arr_node_t *))))
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ } /* end if */
+ else {
+ head->u.queue.init=0;
+ head->u.queue.allocated=0;
+ head->u.queue.onlist=0;
+ head->u.queue.name=head->name;
+ head->u.queue.head=NULL;
+ } /* end else */
+
+ /* Indicate that the free list is initialized */
+ head->init=1;
+
+ FUNC_LEAVE (ret_value);
+} /* end H5FL_arr_init() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_arr_free
+ *
+ * Purpose: Release an array of objects & put on free list
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Friday, March 24, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5FL_arr_free(H5FL_arr_head_t *head, void *obj)
+{
+ H5FL_arr_node_t *temp; /* Temp. ptr to the new free list node allocated */
+
+ FUNC_ENTER (H5FL_arr_free, NULL);
+
+ /* Make certain that the free list is initialized */
+ assert(head->init);
+
+ /* Check if there are a maximum number of elements in list */
+ if(head->maxelem>0) {
+ /* Get the pointer to the info header in front of the block to free */
+ temp=(H5FL_arr_node_t *)((unsigned char *)obj-offsetof(H5FL_arr_node_t,arr));
+
+ /* Double-check that there is enough room for arrays of this size */
+ assert((intn)temp->nelem<=head->maxelem);
+
+ /* Link into the free list */
+ temp->next=head->u.list_arr[temp->nelem];
+
+ /* Point free list at the node freed */
+ head->u.list_arr[temp->nelem]=temp;
+
+ /* Increment the number of blocks on free lists */
+ head->onlist++;
+ } /* end if */
+ /* No maximum number of elements, use PQ routine */
+ else {
+ H5FL_blk_free(&(head->u.queue),obj);
+ } /* end else */
+
+ FUNC_LEAVE(NULL);
+} /* end H5FL_arr_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_arr_alloc
+ *
+ * Purpose: Allocate an array of objects
+ *
+ * Return: Success: Pointer to a valid array object
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, March 25, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5FL_arr_alloc(H5FL_arr_head_t *head, uintn elem, uintn clear)
+{
+ H5FL_arr_node_t *new_obj; /* Pointer to the new free list node allocated */
+ void *ret_value; /* Pointer to object to return */
+
+ FUNC_ENTER (H5FL_arr_alloc, NULL);
+
+ /* Make certain the list is initialized first */
+ if(!head->init)
+ H5FL_arr_init(head);
+
+ /* Check if there is a maximum number of elements in array */
+ if(head->maxelem>0) {
+ /* Check for nodes available on the free list first */
+ if(head->u.list_arr[elem]!=NULL) {
+ /* Get a pointer to the block on the free list */
+ ret_value=&(head->u.list_arr[elem]->arr);
+
+ /* Remove node from free list */
+ head->u.list_arr[elem]=head->u.list_arr[elem]->next;
+
+ /* Decrement the number of blocks on free list */
+ head->onlist--;
+ } /* end if */
+ /* Otherwise allocate a node */
+ else {
+ if (NULL==(new_obj = H5MM_malloc(sizeof(H5FL_arr_node_t)+((head->size)*elem)-1)))
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+
+ /* Increment the number of blocks allocated in list */
+ head->allocated++;
+
+ /* Initialize the new object */
+ new_obj->nelem=elem;
+ new_obj->next=NULL;
+
+ /* Get a pointer to the new block */
+ ret_value=&(new_obj->arr);
+ } /* end else */
+
+ /* Clear to zeros, if asked */
+ if(clear)
+ HDmemset(ret_value,0,head->size*elem);
+ } /* end if */
+ /* No fixed number of elements, use PQ routine */
+ else {
+ ret_value=H5FL_blk_alloc(&(head->u.queue),head->size*elem,clear);
+ } /* end else */
+
+ FUNC_LEAVE (ret_value);
+} /* end H5FL_arr_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_arr_realloc
+ *
+ * Purpose: Reallocate an array of objects
+ *
+ * Return: Success: Pointer to a valid array object
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, March 25, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5FL_arr_realloc(H5FL_arr_head_t *head, void * obj, uintn new_elem)
+{
+ H5FL_arr_node_t *temp; /* Temp. ptr to the new free list node allocated */
+ void *ret_value; /* Pointer to object to return */
+
+ FUNC_ENTER (H5FL_arr_realloc, NULL);
+
+ /* Check if we are really allocating the object */
+ if(obj==NULL) {
+ ret_value=H5FL_arr_alloc(head,new_elem,0);
+ } /* end if */
+ else {
+ /* Check if there is a maximum number of elements in array */
+ if(head->maxelem>0) {
+ /* Get the pointer to the info header in front of the block to free */
+ temp=(H5FL_arr_node_t *)((unsigned char *)obj-offsetof(H5FL_arr_node_t,arr));
+
+ /* Check if the size is really changing */
+ if(temp->nelem!=new_elem) {
+ /* Get the new array of objects */
+ ret_value=H5FL_arr_alloc(head,new_elem,0);
+
+ /* Copy the appropriate amount of elements */
+ HDmemcpy(ret_value,obj,head->size*MIN(temp->nelem,new_elem));
+
+ /* Free the old block */
+ H5FL_arr_free(head,obj);
+ } /* end if */
+ else
+ ret_value=obj;
+ } /* end if */
+ /* No fixed number of elements, use block routine */
+ else {
+ ret_value=H5FL_blk_realloc(&(head->u.queue),obj,head->size*new_elem);
+ } /* end else */
+ } /* end else */
+
+ FUNC_LEAVE (ret_value);
+} /* end H5FL_arr_realloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_arr_gc
+ *
+ * Purpose: Garbage collect on all the array object free lists
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, March 25, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FL_arr_gc(void)
+{
+ H5FL_gc_arr_list_t *gc_arr_list; /* Pointer into the list of things to garbage collect */
+ H5FL_arr_head_t *arr_list_head; /* Pointer to head of free list to garbage collect */
+ H5FL_arr_node_t *arr_free_list; /* Pointer to nodes in free list being garbage collected */
+ void *tmp; /* Temporary node pointer */
+ intn i; /* Counter for array of free lists */
+
+ /* FUNC_ENTER_INIT() should not be called, it causes an infinite loop at library termination */
+ H5_trace(FALSE, "H5FL_arr_gc", "");
+
+ /* Walk through all the free lists, free()'ing the nodes */
+ gc_arr_list=H5FL_gc_arr_head;
+ while(gc_arr_list!=NULL) {
+ /* Get the pointer to the list head */
+ arr_list_head=gc_arr_list->list;
+
+ /* Check if the array has a fixed maximum number of elements */
+ if(arr_list_head->maxelem>0) {
+ /* Walk through the array of free lists */
+ for(i=0; i<arr_list_head->maxelem; i++) {
+
+ /* For each free list being garbage collected, walk through the nodes and free them */
+ arr_free_list=arr_list_head->u.list_arr[i];
+ while(arr_free_list!=NULL) {
+ tmp=arr_free_list->next;
+
+ /* Decrement the count of nodes allocated and free the node */
+ arr_list_head->allocated--;
+ H5MM_xfree(arr_free_list);
+
+ arr_free_list=tmp;
+ } /* end while */
+
+ /* Indicate no free nodes on the free list */
+ arr_list_head->u.list_arr[i]=NULL;
+ arr_list_head->onlist=0;
+ } /* end for */
+ } /* end if */
+ /* No maximum number of elements, just use the PQ call to garbage collect */
+ else {
+ H5FL_blk_gc_list(&(arr_list_head->u.queue));
+ } /* end else */
+
+ /* Go on to the next free list to garbage collect */
+ gc_arr_list=gc_arr_list->next;
+ } /* end while */
+
+ H5_trace(TRUE, NULL, "e", SUCCEED);
+ return(SUCCEED);
+} /* end H5FL_arr_gc() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5FL_arr_term
+ PURPOSE
+ Terminate various H5FL array object free lists
+ USAGE
+ intn H5FL_arr_term()
+ RETURNS
+ Success: Positive if any action might have caused a change in some
+ other interface; zero otherwise.
+ Failure: Negative
+ DESCRIPTION
+ Release any resources allocated.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Can't report errors...
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static intn
+H5FL_arr_term(void)
+{
+ H5FL_gc_arr_list_t *left; /* pointer to garbage collection lists with work left */
+ H5FL_gc_arr_list_t *tmp; /* Temporary pointer to a garbage collection node */
+
+ /* Free the nodes on the garbage collection list, keeping nodes with allocations outstanding */
+ left=NULL;
+ while(H5FL_gc_arr_head!=NULL) {
+ tmp=H5FL_gc_arr_head->next;
+
+ /* Check if the array has a fixed maximum number of elements */
+ if(H5FL_gc_arr_head->list->maxelem>0) {
+ /* Check if the list has allocations outstanding */
+#ifdef H5FL_DEBUG
+printf("H5FL_arr_term: head->name=%s, head->allocated=%d\n", H5FL_gc_arr_head->list->name,(int)H5FL_gc_arr_head->list->allocated);
+#endif /* H5FL_DEBUG */
+ if(H5FL_gc_arr_head->list->allocated>0) {
+ /* Add free list to the list of nodes with allocations open still */
+ H5FL_gc_arr_head->next=left;
+ left=H5FL_gc_arr_head;
+ } /* end if */
+ /* No allocations left open for list, get rid of it */
+ else {
+ /* Free the array of free lists */
+ H5MM_xfree(H5FL_gc_arr_head->list->u.list_arr);
+
+ /* Reset the "initialized" flag, in case we restart this list somehow (I don't know how..) */
+ H5FL_gc_arr_head->list->init=0;
+
+ /* Free the node from the garbage collection list */
+ H5MM_xfree(H5FL_gc_arr_head);
+ } /* end else */
+ } /* end if */
+ /* No maximum number of elements, use the PQ information */
+ else {
+#ifdef H5FL_DEBUG
+printf("H5FL_arr_term: head->name=%s, head->allocated=%d\n", H5FL_gc_arr_head->list->name,(int)H5FL_gc_arr_head->list->u.queue.allocated);
+#endif /* H5FL_DEBUG */
+ /* Check if the list has allocations outstanding */
+ if(H5FL_gc_arr_head->list->u.queue.allocated>0) {
+ /* Add free list to the list of nodes with allocations open still */
+ H5FL_gc_arr_head->next=left;
+ left=H5FL_gc_arr_head;
+ } /* end if */
+ /* No allocations left open for list, get rid of it */
+ else {
+ /* Reset the "initialized" flag, in case we restart this list somehow (I don't know how..) */
+ H5FL_gc_arr_head->list->init=0;
+
+ /* Free the node from the garbage collection list */
+ H5MM_xfree(H5FL_gc_arr_head);
+ } /* end else */
+ } /* end else */
+
+ H5FL_gc_arr_head=tmp;
+ } /* end while */
+
+ /* Point to the list of nodes left with allocations open, if any */
+ H5FL_gc_arr_head=left;
+
+ return (H5FL_gc_arr_head!=NULL ? 1 : 0);
+} /* end H5FL_arr_term() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FL_garbage_coll
+ *
+ * Purpose: Garbage collect on all the free lists
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Friday, March 24, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FL_garbage_coll(void)
+{
+ /* FUNC_ENTER_INIT() should not be called, it causes an infinite loop at library termination */
+ H5_trace(FALSE, "H5FL_garbage_coll", "");
+
+ /* Garbage collect the free lists for regular objects */
+ H5FL_gc();
+
+ /* Garbage collect the free lists for array objects */
+ H5FL_arr_gc();
+
+ /* Garbage collect free lists for blocks */
+ H5FL_blk_gc();
+
+ H5_trace(TRUE, NULL, "e", SUCCEED);
+ return(SUCCEED);
+} /* end H5FL_garbage_coll() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5FL_term_interface
+ PURPOSE
+ Terminate various H5FL objects
+ USAGE
+ void H5FL_term_interface()
+ RETURNS
+ Success: Positive if any action might have caused a change in some
+ other interface; zero otherwise.
+ Failure: Negative
+ DESCRIPTION
+ Release any resources allocated.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Can't report errors...
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+intn
+H5FL_term_interface(void)
+{
+ intn ret_value=0;
+
+ /* Garbage collect any nodes on the free lists */
+ H5FL_garbage_coll();
+
+ ret_value=H5FL_term()+H5FL_arr_term()+H5FL_blk_term();
+
+ return(ret_value);
+}
+
diff --git a/src/H5FLprivate.h b/src/H5FLprivate.h
new file mode 100644
index 0000000..d5caa32
--- /dev/null
+++ b/src/H5FLprivate.h
@@ -0,0 +1,173 @@
+/*-------------------------------------------------------------------------
+ * Copyright (C) 2000 National Center for Supercomputing Applications.
+ * All rights reserved.
+ *
+ *-------------------------------------------------------------------------
+ *
+ * Created: H5FLprivate.h
+ * Mar 23 2000
+ * Quincey Koziol <koziol@ncsa.uiuc.edu>
+ *
+ * Purpose: Private non-prototype header.
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef _H5FLprivate_H
+#define _H5FLprivate_H
+
+/* Public headers needed by this file */
+#ifdef LATER
+#include <H5FLpublic.h> /*API prototypes */
+#endif /* LATER */
+
+/* Private headers needed by this file */
+
+/*
+ * Private datatypes.
+ */
+
+/* Data structure to store each block in free list */
+typedef struct H5FL_node_t {
+ struct H5FL_node_t *next; /* Pointer to next block in free list */
+#ifdef H5FL_DEBUG
+ uintn inuse; /* Indicate when object is in use */
+#endif /* H5FL_DEBUG */
+ unsigned char block; /* Actual storage for the data */
+} H5FL_node_t;
+
+/* Data structure for free list of blocks */
+typedef struct H5FL_head_t {
+ uintn init; /* Whether the free list has been initialized */
+ uintn allocated; /* Number of blocks allocated */
+ uintn onlist; /* Number of blocks on free list */
+ const char *name; /* Name of the type */
+ size_t size; /* Size of the blocks in the list */
+ H5FL_node_t *list; /* List of free blocks */
+} H5FL_head_t;
+
+/*
+ * Macros for defining & using free lists for a type
+ */
+/* Declare a free list to manage objects of type 't' */
+#define H5FL_DEFINE(t) H5FL_head_t t##_free_list={0,0,0,#t,sizeof(t),NULL}
+
+/* Reference a free list for type 't' defined in another file */
+#define H5FL_EXTERN(t) extern H5FL_head_t t##_free_list
+
+/* Declare a static free list to manage objects of type 't' */
+#define H5FL_DEFINE_STATIC(t) static H5FL_DEFINE(t)
+
+/* Allocate an object of type 't' */
+#define H5FL_ALLOC(t,clr) H5FL_alloc(&(t##_free_list),clr)
+
+/* Free an object of type 't' */
+#define H5FL_FREE(t,obj) H5FL_free(&(t##_free_list),obj)
+
+/* Re-allocating an object of type 't' is not defined, because these free-lists
+ * only support fixed sized types, like structs, etc..
+ */
+
+/* Data structure to store each block in free list */
+typedef struct H5FL_blk_list_t {
+ size_t size; /* Size of the page */
+ struct H5FL_blk_list_t *next; /* Pointer to next block in free list */
+ unsigned char block; /* Actual storage for the data */
+} H5FL_blk_list_t;
+
+/* Data structure for priority queue node of block free lists */
+typedef struct H5FL_blk_node_t {
+ size_t size; /* Size of the blocks in the list */
+ H5FL_blk_list_t *list; /* List of free blocks */
+ struct H5FL_blk_node_t *next; /* Pointer to next free list in queue */
+ struct H5FL_blk_node_t *prev; /* Pointer to previous free list in queue */
+} H5FL_blk_node_t;
+
+/* Data structure for priority queue of native block free lists */
+typedef struct H5FL_blk_head_t {
+ uintn init; /* Whether the free list has been initialized */
+ uintn allocated; /* Number of blocks allocated */
+ uintn onlist; /* Number of blocks on free list */
+ const char *name; /* Name of the type */
+ H5FL_blk_node_t *head; /* Pointer to first free list in queue */
+}H5FL_blk_head_t;
+
+/*
+ * Macros for defining & using priority queues
+ */
+/* Declare a free list to manage objects of type 't' */
+#define H5FL_BLK_DEFINE(t) H5FL_blk_head_t t##_pq={0,0,0,#t,NULL}
+
+/* Reference a free list for type 't' defined in another file */
+#define H5FL_BLK_EXTERN(t) extern H5FL_blk_head_t t##_pq
+
+/* Declare a static free list to manage objects of type 't' */
+#define H5FL_BLK_DEFINE_STATIC(t) static H5FL_BLK_DEFINE(t)
+
+/* Allocate an block of type 't' */
+#define H5FL_BLK_ALLOC(t,size,clr) H5FL_blk_alloc(&(t##_pq),size,clr)
+
+/* Free a block of type 't' */
+#define H5FL_BLK_FREE(t,blk) H5FL_blk_free(&(t##_pq),blk)
+
+/* Re-allocate a block of type 't' */
+#define H5FL_BLK_REALLOC(t,blk,new_size) H5FL_blk_realloc(&(t##_pq),blk,new_size)
+
+/* Data structure to store each array in free list */
+typedef struct H5FL_arr_node_t {
+ struct H5FL_arr_node_t *next; /* Pointer to next block in free list */
+ size_t nelem; /* Number of elements in this array */
+ unsigned char arr; /* Actual storage for the array data */
+} H5FL_arr_node_t;
+
+/* Data structure for free list of array blocks */
+typedef struct H5FL_arr_head_t {
+ uintn init; /* Whether the free list has been initialized */
+ uintn allocated; /* Number of blocks allocated */
+ uintn onlist; /* Number of blocks on free list */
+ const char *name; /* Name of the type */
+ intn maxelem; /* Maximum number of elements in an array */
+ size_t size; /* Size of the array elements in the list */
+ union {
+ H5FL_arr_node_t **list_arr; /* Array of lists of free blocks */
+ H5FL_blk_head_t queue; /* Priority queue of array blocks */
+ }u;
+} H5FL_arr_head_t;
+
+/*
+ * Macros for defining & using free lists for an array of a type
+ */
+/* Declare a free list to manage arrays of type 't' */
+#define H5FL_ARR_DEFINE(t,m) H5FL_arr_head_t t##_arr_free_list={0,0,0,#t##"_arr",m,sizeof(t),{NULL}}
+
+/* Reference a free list for arrays of type 't' defined in another file */
+#define H5FL_ARR_EXTERN(t) extern H5FL_arr_head_t t##_arr_free_list
+
+/* Declare a static free list to manage arrays of type 't' */
+#define H5FL_ARR_DEFINE_STATIC(t,m) static H5FL_ARR_DEFINE(t,m)
+
+/* Allocate an array of type 't' */
+#define H5FL_ARR_ALLOC(t,elem,clr) H5FL_arr_alloc(&(t##_arr_free_list),elem,clr)
+
+/* Free an array of type 't' */
+#define H5FL_ARR_FREE(t,obj) H5FL_arr_free(&(t##_arr_free_list),obj)
+
+/* Re-allocate an array of type 't' */
+#define H5FL_ARR_REALLOC(t,obj,new_elem) H5FL_arr_realloc(&(t##_arr_free_list),obj,new_elem)
+
+/*
+ * Library prototypes.
+ */
+__DLL__ void * H5FL_blk_alloc(H5FL_blk_head_t *head, size_t size, uintn clear);
+__DLL__ void * H5FL_blk_free(H5FL_blk_head_t *head, void *block);
+__DLL__ void * H5FL_blk_realloc(H5FL_blk_head_t *head, void *block, size_t new_size);
+__DLL__ void * H5FL_alloc(H5FL_head_t *head, uintn clear);
+__DLL__ void * H5FL_free(H5FL_head_t *head, void *obj);
+__DLL__ void * H5FL_arr_alloc(H5FL_arr_head_t *head, uintn elem, uintn clear);
+__DLL__ void * H5FL_arr_free(H5FL_arr_head_t *head, void *obj);
+__DLL__ void * H5FL_arr_realloc(H5FL_arr_head_t *head, void *obj, uintn new_elem);
+__DLL__ herr_t H5FL_garbage_coll(void);
+__DLL__ intn H5FL_term_interface(void);
+
+#endif
diff --git a/src/H5Fistore.c b/src/H5Fistore.c
index 31506e6..c4728ad 100644
--- a/src/H5Fistore.c
+++ b/src/H5Fistore.c
@@ -33,6 +33,7 @@
#include <H5Dprivate.h>
#include <H5Eprivate.h>
#include <H5Fprivate.h>
+#include <H5FLprivate.h> /*Free Lists */
#include <H5Iprivate.h>
#include <H5MFprivate.h>
#include <H5MMprivate.h>
@@ -186,6 +187,103 @@ H5B_class_t H5B_ISTORE[1] = {{
}
+/* Declare a free list to manage the chunk information */
+H5FL_BLK_DEFINE_STATIC(istore_chunk);
+
+/* Declare a free list to manage H5F_rdcc_ent_t objects */
+H5FL_DEFINE_STATIC(H5F_rdcc_ent_t);
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_chunk_alloc
+ *
+ * Purpose: Allocates memory for a chunk of a dataset. This routine is used
+ * instead of malloc because the chunks can be kept on a free list so
+ * they don't thrash malloc/free as much.
+ *
+ * Return: Success: valid pointer to the chunk
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, March 21, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5F_istore_chunk_alloc(size_t chunk_size)
+{
+ void *ret_value; /* Pointer to the chunk to return to the user */
+
+ FUNC_ENTER(H5F_istore_chunk_alloc, NULL);
+
+ ret_value=H5FL_BLK_ALLOC(istore_chunk,chunk_size,0);
+
+ FUNC_LEAVE(ret_value);
+} /* end H5F_istore_chunk_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_chunk_free
+ *
+ * Purpose: Releases memory for a chunk of a dataset. This routine is used
+ * instead of free because the chunks can be kept on a free list so
+ * they don't thrash malloc/free as much.
+ *
+ * Return: Success: NULL
+ *
+ * Failure: never fails
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, March 21, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5F_istore_chunk_free(void *chunk)
+{
+ FUNC_ENTER(H5F_istore_chunk_free, NULL);
+
+ H5FL_BLK_FREE(istore_chunk,chunk);
+
+ FUNC_LEAVE(NULL);
+} /* end H5F_istore_chunk_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_istore_chunk_realloc
+ *
+ * Purpose: Resizes a chunk in chunking memory allocation system. This
+ * does things the straightforward, simple way, not actually using
+ * realloc.
+ *
+ * Return: Success: NULL
+ *
+ * Failure: never fails
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, March 21, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5F_istore_chunk_realloc(void *chunk, size_t new_size)
+{
+ void *ret_value=NULL; /* Return value */
+
+ FUNC_ENTER(H5F_istore_chunk_realloc, NULL);
+
+ ret_value=H5FL_BLK_REALLOC(istore_chunk,chunk,new_size);
+
+ FUNC_LEAVE(ret_value);
+} /* end H5F_istore_chunk_realloc() */
+
/*-------------------------------------------------------------------------
* Function: H5F_istore_sizeof_rkey
@@ -871,7 +969,7 @@ H5F_istore_flush_entry(H5F_t *f, H5F_rdcc_ent_t *ent, hbool_t reset)
* for later.
*/
alloc = ent->chunk_size;
- if (NULL==(buf = H5MM_malloc(alloc))) {
+ if (NULL==(buf = H5F_istore_chunk_alloc(alloc))) {
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed for pipeline");
}
@@ -920,14 +1018,15 @@ H5F_istore_flush_entry(H5F_t *f, H5F_rdcc_ent_t *ent, hbool_t reset)
ent->layout = H5O_free(H5O_LAYOUT, ent->layout);
ent->pline = H5O_free(H5O_PLINE, ent->pline);
if (buf==ent->chunk) buf = NULL;
- ent->chunk = H5MM_xfree(ent->chunk);
+ if(ent->chunk!=NULL)
+ ent->chunk = H5F_istore_chunk_free(ent->chunk);
}
ret_value = SUCCEED;
done:
/* Free the temp buffer only if it's different than the entry chunk */
- if (buf!=ent->chunk) H5MM_xfree(buf);
+ if (buf!=ent->chunk) H5F_istore_chunk_free(buf);
/*
* If we reached the point of no return then we have no choice but to
@@ -938,7 +1037,8 @@ H5F_istore_flush_entry(H5F_t *f, H5F_rdcc_ent_t *ent, hbool_t reset)
if (ret_value<0 && point_of_no_return) {
ent->layout = H5O_free(H5O_LAYOUT, ent->layout);
ent->pline = H5O_free(H5O_PLINE, ent->pline);
- ent->chunk = H5MM_xfree(ent->chunk);
+ if(ent->chunk)
+ ent->chunk = H5F_istore_chunk_free(ent->chunk);
}
FUNC_LEAVE(ret_value);
}
@@ -993,7 +1093,7 @@ H5F_istore_preempt (H5F_t *f, H5F_rdcc_ent_t *ent)
--rdcc->nused;
/* Free */
- H5MM_xfree(ent);
+ H5FL_FREE(H5F_rdcc_ent_t, ent);
FUNC_LEAVE (SUCCEED);
}
@@ -1291,7 +1391,7 @@ H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
chunk_size *= layout->dim[i];
}
chunk_alloc = chunk_size;
- if (NULL==(chunk=H5MM_malloc (chunk_alloc))) {
+ if (NULL==(chunk=H5F_istore_chunk_alloc (chunk_alloc))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed for raw data chunk");
}
@@ -1310,7 +1410,7 @@ H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
udata.addr = HADDR_UNDEF;
status = H5B_find (f, H5B_ISTORE, layout->addr, &udata);
H5E_clear ();
- if (NULL==(chunk = H5MM_malloc (chunk_alloc))) {
+ if (NULL==(chunk = H5F_istore_chunk_alloc (chunk_alloc))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed for raw data chunk");
}
@@ -1386,7 +1486,7 @@ H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
}
/* Create a new entry */
- ent = H5MM_malloc(sizeof(H5F_rdcc_ent_t));
+ ent = H5FL_ALLOC(H5F_rdcc_ent_t,0);
ent->locked = 0;
ent->dirty = FALSE;
ent->chunk_size = chunk_size;
@@ -1471,7 +1571,7 @@ H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
ret_value = chunk;
done:
- if (!ret_value) H5MM_xfree (chunk);
+ if (!ret_value) H5F_istore_chunk_free (chunk);
FUNC_LEAVE (ret_value);
}
@@ -1552,7 +1652,8 @@ H5F_istore_unlock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
H5F_istore_flush_entry (f, &x, TRUE);
} else {
- H5MM_xfree (chunk);
+ if(chunk)
+ H5F_istore_chunk_free (chunk);
}
} else {
/*
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index fff050b..d9952a8 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -525,4 +525,9 @@ __DLL__ void H5F_addr_decode(H5F_t *, const uint8_t**/*in,out*/,
__DLL__ herr_t H5F_addr_pack(H5F_t UNUSED *f, haddr_t *addr_p/*out*/,
const unsigned long objno[2]);
+/* Functions for allocation/releasing chunks */
+__DLL__ void * H5F_istore_chunk_alloc(size_t chunk_size);
+__DLL__ void * H5F_istore_chunk_free(void *chunk);
+__DLL__ void * H5F_istore_chunk_realloc(void *chunk, size_t new_size);
+
#endif
diff --git a/src/H5Gnode.c b/src/H5Gnode.c
index a65f187..b0071d5 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -25,6 +25,7 @@
#include <H5Bprivate.h> /*B-link trees */
#include <H5Eprivate.h> /*error handling */
#include <H5Fprivate.h> /*file access */
+#include <H5FLprivate.h> /*Free Lists */
#include <H5Gpkg.h> /*me */
#include <H5HLprivate.h> /*local heap */
#include <H5MFprivate.h> /*file memory management */
@@ -97,6 +98,15 @@ H5B_class_t H5B_SNODE[1] = {{
static intn interface_initialize_g = 0;
#define INTERFACE_INIT NULL
+/* Declare a free list to manage the H5G_node_t struct */
+H5FL_DEFINE_STATIC(H5G_node_t);
+
+/* Declare a free list to manage arrays of H5G_entry_t's */
+H5FL_ARR_DEFINE_STATIC(H5G_entry_t,-1);
+
+/* Declare a free list to manage blocks of symbol node data */
+H5FL_BLK_DEFINE_STATIC(symbol_node);
+
/*-------------------------------------------------------------------------
* Function: H5G_node_sizeof_rkey
@@ -250,26 +260,26 @@ H5G_node_create(H5F_t *f, H5B_ins_t UNUSED op, void *_lt_key,
assert(f);
assert(H5B_INS_FIRST == op);
- if (NULL==(sym = H5MM_calloc(sizeof(H5G_node_t)))) {
+ if (NULL==(sym = H5FL_ALLOC(H5G_node_t,1))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
size = H5G_node_size(f);
if (HADDR_UNDEF==(*addr_p=H5MF_alloc(f, H5FD_MEM_BTREE, size))) {
- H5MM_xfree(sym);
+ H5FL_FREE(H5G_node_t,sym);
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL,
"unable to allocate file space");
}
sym->dirty = TRUE;
- sym->entry = H5MM_calloc(2*H5G_NODE_K(f)*sizeof(H5G_entry_t));
+ sym->entry = H5FL_ARR_ALLOC(H5G_entry_t,2*H5G_NODE_K(f),1);
if (NULL==sym->entry) {
- H5MM_xfree (sym);
+ H5FL_FREE(H5G_node_t,sym);
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
if (H5AC_set(f, H5AC_SNODE, *addr_p, sym) < 0) {
- H5MM_xfree(sym->entry);
- H5MM_xfree(sym);
+ H5FL_ARR_FREE(H5G_entry_t,sym->entry);
+ H5FL_FREE(H5G_node_t,sym);
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL,
"unable to cache symbol table leaf node");
}
@@ -333,46 +343,49 @@ H5G_node_flush(H5F_t *f, hbool_t destroy, haddr_t addr, H5G_node_t *sym)
* Write the symbol node to disk.
*/
if (sym->dirty) {
- size = H5G_node_size(f);
- if (NULL==(buf = p = H5MM_malloc(size))) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "memory allocation failed");
- }
+ size = H5G_node_size(f);
- /* magic number */
- HDmemcpy(p, H5G_NODE_MAGIC, H5G_NODE_SIZEOF_MAGIC);
- p += 4;
+ /* Allocate temporary buffer */
+ if ((buf=H5FL_BLK_ALLOC(symbol_node,size, 0))==NULL)
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "memory allocation failed");
+ p=buf;
- /* version number */
- *p++ = H5G_NODE_VERS;
+ /* magic number */
+ HDmemcpy(p, H5G_NODE_MAGIC, H5G_NODE_SIZEOF_MAGIC);
+ p += 4;
- /* reserved */
- *p++ = 0;
+ /* version number */
+ *p++ = H5G_NODE_VERS;
- /* number of symbols */
- UINT16ENCODE(p, sym->nsyms);
+ /* reserved */
+ *p++ = 0;
- /* entries */
- H5G_ent_encode_vec(f, &p, sym->entry, sym->nsyms);
- HDmemset(p, 0, size - (p - buf));
+ /* number of symbols */
+ UINT16ENCODE(p, sym->nsyms);
+
+ /* entries */
+ H5G_ent_encode_vec(f, &p, sym->entry, sym->nsyms);
+ HDmemset(p, 0, size - (p - buf));
#ifdef H5_HAVE_PARALLEL
- if (IS_H5FD_MPIO(f))
- H5FD_mpio_tas_allsame(f->shared->lf, TRUE); /*only p0 will write*/
+ if (IS_H5FD_MPIO(f))
+ H5FD_mpio_tas_allsame(f->shared->lf, TRUE); /*only p0 will write*/
#endif /* H5_HAVE_PARALLEL */
- status = H5F_block_write(f, addr, (hsize_t)size, H5P_DEFAULT, buf);
- buf = H5MM_xfree(buf);
- if (status < 0)
- HRETURN_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL,
- "unable to write symbol table node to the file");
+ status = H5F_block_write(f, addr, (hsize_t)size, H5P_DEFAULT, buf);
+ if (status < 0)
+ HRETURN_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL,
+ "unable to write symbol table node to the file");
+ if (buf)
+ H5FL_BLK_FREE(symbol_node,buf);
}
/*
* Destroy the symbol node? This might happen if the node is being
* preempted from the cache.
*/
if (destroy) {
- sym->entry = H5MM_xfree(sym->entry);
- H5MM_xfree(sym);
+ sym->entry = H5FL_ARR_FREE(H5G_entry_t,sym->entry);
+ H5FL_FREE(H5G_node_t,sym);
}
FUNC_LEAVE(SUCCEED);
}
@@ -420,12 +433,12 @@ H5G_node_load(H5F_t *f, haddr_t addr, const void UNUSED *_udata1,
* Initialize variables.
*/
size = H5G_node_size(f);
- if (NULL==(p = buf = H5MM_malloc(size))) {
+ if ((buf=H5FL_BLK_ALLOC(symbol_node,size,0))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed for symbol table node");
- }
- if (NULL==(sym = H5MM_calloc(sizeof(H5G_node_t))) ||
- NULL==(sym->entry=H5MM_calloc(2*H5G_NODE_K(f)*sizeof(H5G_entry_t)))) {
+ p=buf;
+ if (NULL==(sym = H5FL_ALLOC(H5G_node_t,1)) ||
+ NULL==(sym->entry=H5FL_ARR_ALLOC(H5G_entry_t,2*H5G_NODE_K(f),1))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -456,17 +469,17 @@ H5G_node_load(H5F_t *f, haddr_t addr, const void UNUSED *_udata1,
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL,
"unable to decode symbol table entries");
}
- buf = H5MM_xfree(buf);
ret_value = sym;
done:
+ if (buf)
+ H5FL_BLK_FREE(symbol_node,buf);
if (!ret_value) {
- buf = H5MM_xfree(buf);
- if (sym) {
- sym->entry = H5MM_xfree(sym->entry);
- sym = H5MM_xfree(sym);
- }
+ if (sym) {
+ sym->entry = H5FL_ARR_FREE(H5G_entry_t,sym->entry);
+ sym = H5FL_FREE(H5G_node_t,sym);
+ }
}
FUNC_LEAVE(ret_value);
}
diff --git a/src/H5HG.c b/src/H5HG.c
index bcf0939..5d6ebe3 100644
--- a/src/H5HG.c
+++ b/src/H5HG.c
@@ -27,6 +27,7 @@
#include <H5private.h> /*library */
#include <H5ACprivate.h> /*caching */
#include <H5Eprivate.h> /*error handling */
+#include <H5FLprivate.h> /*Free Lists */
#include <H5HGprivate.h> /*global heaps */
#include <H5MFprivate.h> /*file memory management */
#include <H5MMprivate.h> /*core memory management */
@@ -68,6 +69,15 @@ static const H5AC_class_t H5AC_GHEAP[1] = {{
static intn interface_initialize_g = 0;
#define INTERFACE_INIT NULL
+/* Declare a free list to manage the H5HG_t struct */
+H5FL_DEFINE_STATIC(H5HG_heap_t);
+
+/* Declare a free list to manage arrays of H5HG_obj_t's */
+H5FL_ARR_DEFINE_STATIC(H5HG_obj_t,-1);
+
+/* Declare a PQ free list to manage heap chunks */
+H5FL_BLK_DEFINE_STATIC(heap_chunk);
+
/*-------------------------------------------------------------------------
* Function: H5HG_create
@@ -111,19 +121,19 @@ H5HG_create (H5F_t *f, size_t size)
HGOTO_ERROR (H5E_HEAP, H5E_CANTINIT, NULL,
"unable to allocate file space for global heap");
}
- if (NULL==(heap = H5MM_calloc (sizeof(H5HG_heap_t)))) {
+ if (NULL==(heap = H5FL_ALLOC (H5HG_heap_t,1))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
heap->addr = addr;
heap->size = size;
heap->dirty = TRUE;
- if (NULL==(heap->chunk = H5MM_malloc (size))) {
+ if (NULL==(heap->chunk = H5FL_BLK_ALLOC (heap_chunk,size,0))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
heap->nalloc = H5HG_NOBJS (f, size);
- if (NULL==(heap->obj = H5MM_calloc (heap->nalloc*sizeof(H5HG_obj_t)))) {
+ if (NULL==(heap->obj = H5FL_ARR_ALLOC (H5HG_obj_t,heap->nalloc,1))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -182,9 +192,9 @@ H5HG_create (H5F_t *f, size_t size)
done:
if (!ret_value && heap) {
- H5MM_xfree (heap->chunk);
- H5MM_xfree (heap->obj);
- H5MM_xfree (heap);
+ H5FL_BLK_FREE(heap_chunk,heap->chunk);
+ H5FL_ARR_FREE (H5HG_obj_t,heap->obj);
+ H5FL_FREE (H5HG_heap_t,heap);
}
FUNC_LEAVE (ret_value);
}
@@ -226,12 +236,12 @@ H5HG_load (H5F_t *f, haddr_t addr, const void UNUSED *udata1,
assert (!udata2);
/* Read the initial 4k page */
- if (NULL==(heap = H5MM_calloc (sizeof(H5HG_heap_t)))) {
+ if (NULL==(heap = H5FL_ALLOC (H5HG_heap_t,1))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
heap->addr = addr;
- if (NULL==(heap->chunk = H5MM_malloc (H5HG_MINSIZE))) {
+ if (NULL==(heap->chunk = H5FL_BLK_ALLOC (heap_chunk,H5HG_MINSIZE,0))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -267,7 +277,7 @@ H5HG_load (H5F_t *f, haddr_t addr, const void UNUSED *udata1,
*/
if (heap->size > H5HG_MINSIZE) {
haddr_t next_addr = addr + (hsize_t)H5HG_MINSIZE;
- if (NULL==(heap->chunk = H5MM_realloc (heap->chunk, heap->size))) {
+ if (NULL==(heap->chunk = H5FL_BLK_REALLOC (heap_chunk, heap->chunk, heap->size))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -281,7 +291,7 @@ H5HG_load (H5F_t *f, haddr_t addr, const void UNUSED *udata1,
/* Decode each object */
p = heap->chunk + H5HG_SIZEOF_HDR (f);
nalloc = H5HG_NOBJS (f, heap->size);
- if (NULL==(heap->obj = H5MM_calloc (nalloc*sizeof(H5HG_obj_t)))) {
+ if (NULL==(heap->obj = H5FL_ARR_ALLOC (H5HG_obj_t,nalloc,1))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -358,9 +368,9 @@ H5HG_load (H5F_t *f, haddr_t addr, const void UNUSED *udata1,
done:
if (!ret_value && heap) {
- H5MM_xfree (heap->chunk);
- H5MM_xfree (heap->obj);
- H5MM_xfree (heap);
+ H5FL_BLK_FREE (heap_chunk,heap->chunk);
+ H5FL_ARR_FREE(H5HG_obj_t,heap->obj);
+ H5FL_FREE (H5HG_heap_t,heap);
}
FUNC_LEAVE (ret_value);
}
@@ -405,17 +415,17 @@ H5HG_flush (H5F_t *f, hbool_t destroy, haddr_t addr, H5HG_heap_t *heap)
}
if (destroy) {
- for (i=0; i<f->shared->ncwfs; i++) {
- if (f->shared->cwfs[i]==heap) {
- f->shared->ncwfs -= 1;
- HDmemmove (f->shared->cwfs+i, f->shared->cwfs+i+1,
- (f->shared->ncwfs-i) * sizeof(H5HG_heap_t*));
- break;
- }
- }
- heap->chunk = H5MM_xfree (heap->chunk);
- heap->obj = H5MM_xfree (heap->obj);
- H5MM_xfree (heap);
+ for (i=0; i<f->shared->ncwfs; i++) {
+ if (f->shared->cwfs[i]==heap) {
+ f->shared->ncwfs -= 1;
+ HDmemmove (f->shared->cwfs+i, f->shared->cwfs+i+1,
+ (f->shared->ncwfs-i) * sizeof(H5HG_heap_t*));
+ break;
+ }
+ }
+ heap->chunk = H5FL_BLK_FREE(heap_chunk,heap->chunk);
+ heap->obj = H5FL_ARR_FREE(H5HG_obj_t,heap->obj);
+ H5FL_FREE (H5HG_heap_t,heap);
}
FUNC_LEAVE (SUCCEED);
diff --git a/src/H5I.c b/src/H5I.c
index bf80dce..3337116 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -38,6 +38,7 @@ static char RcsId[] = "@(#)$Revision$";
#include <H5private.h>
#include <H5Iprivate.h>
#include <H5Eprivate.h>
+#include <H5FLprivate.h> /*Free Lists */
#include <H5MMprivate.h>
/* Interface initialialization? */
@@ -106,14 +107,14 @@ static H5I_id_info_t *H5I_cache_g[ID_CACHE_SIZE];
/* Array of pointers to atomic groups */
static H5I_id_group_t *H5I_id_group_list_g[H5I_NGROUPS];
-/* Pointer to the atom node free list */
-static H5I_id_info_t *H5I_id_free_list_g = NULL;
+/* Declare a free list to manage the H5I_id_info_t struct */
+H5FL_DEFINE_STATIC(H5I_id_info_t);
/*--------------------- Local function prototypes ---------------------------*/
static H5I_id_info_t *H5I_find_id(hid_t id);
-static H5I_id_info_t *H5I_get_id_node(void);
-static herr_t H5I_release_id_node(H5I_id_info_t *id);
+#ifdef H5I_DEBUG_OUTPUT
static herr_t H5I_debug(H5I_type_t grp);
+#endif /* H5I_DEBUG_OUTPUT */
/*-------------------------------------------------------------------------
@@ -169,37 +170,27 @@ intn
H5I_term_interface(void)
{
H5I_id_group_t *grp_ptr;
- H5I_id_info_t *curr;
H5I_type_t grp;
intn n=0;
if (interface_initialize_g) {
-
- /* How many groups are still being used? */
- for (grp=(H5I_type_t)0; grp<H5I_NGROUPS; grp++) {
- if ((grp_ptr=H5I_id_group_list_g[grp]) && grp_ptr->id_list) {
- n++;
- }
- }
-
- /* If no groups are used then clean up */
- if (0==n) {
- for (grp=(H5I_type_t)0; grp<H5I_NGROUPS; grp++) {
- grp_ptr = H5I_id_group_list_g[grp];
- H5MM_xfree(grp_ptr);
- H5I_id_group_list_g[grp] = NULL;
- }
-
- /* Release the global free list */
- while (H5I_id_free_list_g) {
- curr = H5I_id_free_list_g;
- H5I_id_free_list_g = H5I_id_free_list_g->next;
- H5MM_xfree(curr);
- }
- }
-
- /* Mark interface closed */
- interface_initialize_g = 0;
+ /* How many groups are still being used? */
+ for (grp=(H5I_type_t)0; grp<H5I_NGROUPS; grp++) {
+ if ((grp_ptr=H5I_id_group_list_g[grp]) && grp_ptr->id_list)
+ n++;
+ }
+
+ /* If no groups are used then clean up */
+ if (0==n) {
+ for (grp=(H5I_type_t)0; grp<H5I_NGROUPS; grp++) {
+ grp_ptr = H5I_id_group_list_g[grp];
+ H5MM_xfree(grp_ptr);
+ H5I_id_group_list_g[grp] = NULL;
+ }
+ }
+
+ /* Mark interface closed */
+ interface_initialize_g = 0;
}
return n;
}
@@ -432,7 +423,7 @@ H5I_clear_group(H5I_type_t grp, hbool_t force)
#endif /*H5I_DEBUG*/
/* Add ID struct to free list */
next = cur->next;
- H5I_release_id_node(cur);
+ H5FL_FREE(H5I_id_info_t,cur);
} else {
if (prev) prev->next = cur;
else grp_ptr->id_list[i] = cur;
@@ -441,7 +432,7 @@ H5I_clear_group(H5I_type_t grp, hbool_t force)
} else {
/* Add ID struct to free list */
next = cur->next;
- H5I_release_id_node(cur);
+ H5FL_FREE(H5I_id_info_t,cur);
}
}
if (!prev) grp_ptr->id_list[i]=NULL;
@@ -552,7 +543,7 @@ H5I_register(H5I_type_t grp, void *object)
if (grp_ptr == NULL || grp_ptr->count <= 0) {
HGOTO_DONE(FAIL);
}
- if ((id_ptr = H5I_get_id_node()) == NULL) {
+ if ((id_ptr = H5FL_ALLOC(H5I_id_info_t,0)) == NULL) {
HGOTO_DONE(FAIL);
}
@@ -793,7 +784,7 @@ H5I_remove(hid_t id)
last_id->next = curr_id->next;
}
ret_value = curr_id->obj_ptr;
- H5I_release_id_node(curr_id);
+ H5FL_FREE(H5I_id_info_t,curr_id);
} else {
/* couldn't find the ID in the proper place */
HGOTO_DONE(NULL);
@@ -883,7 +874,7 @@ H5I_dec_ref(hid_t id)
H5I_remove(id);
ret_value = 0;
} else {
- ret_value = FAIL;
+ ret_value = 1;
}
} else {
ret_value = --(id_ptr->count);
@@ -1080,69 +1071,6 @@ H5I_find_id(hid_t id)
/*-------------------------------------------------------------------------
- * Function: H5I_get_id_node
- *
- * Purpose: Either gets an ID node from the free list (if there is one
- * available) or allocate a node.
- *
- * Return: Success: ID pointer
- *
- * Failure: NULL
- *
- * Programmer:
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static H5I_id_info_t *
-H5I_get_id_node(void)
-{
- H5I_id_info_t *ret_value = NULL;
-
- FUNC_ENTER(H5I_get_id_node, NULL);
-
- if (H5I_id_free_list_g != NULL) {
- ret_value = H5I_id_free_list_g;
- H5I_id_free_list_g = H5I_id_free_list_g->next;
- } else if (NULL==(ret_value = H5MM_malloc(sizeof(H5I_id_info_t)))) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
- "memory allocation failed");
- }
-
- FUNC_LEAVE(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5I_release_id_node
- *
- * Purpose: Release an ID node and return it to the free list.
- *
- * Return: Success: Non-negative
- *
- * Failure: Negative
- *
- * Programmer:
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5I_release_id_node(H5I_id_info_t *id)
-{
- FUNC_ENTER(H5I_release_id_node, FAIL);
-
- /* Insert the ID at the beginning of the free list */
- id->next = H5I_id_free_list_g;
- H5I_id_free_list_g = id;
-
- FUNC_LEAVE(SUCCEED);
-}
-
-
-/*-------------------------------------------------------------------------
* Function: H5I_debug
*
* Purpose: Dump the contents of a group to stderr for debugging.
diff --git a/src/H5O.c b/src/H5O.c
index 29ff4b9..5d1fe99 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -18,6 +18,7 @@
#include <H5ACprivate.h>
#include <H5Eprivate.h>
#include <H5Fprivate.h>
+#include <H5FLprivate.h> /*Free Lists */
#include <H5Iprivate.h>
#include <H5MFprivate.h>
#include <H5MMprivate.h>
@@ -84,6 +85,22 @@ static const H5O_class_t *const message_type_g[] = {
static void *(*H5O_fast_g[H5G_NCACHED]) (const H5G_cache_t *,
const H5O_class_t *,
void *);
+
+/* Declare a free list to manage the H5O_t struct */
+H5FL_DEFINE_STATIC(H5O_t);
+
+/* Declare a PQ free list to manage the H5O_mesg_t array information */
+H5FL_ARR_DEFINE_STATIC(H5O_mesg_t,-1);
+
+/* Declare a PQ free list to manage the H5O_chunk_t array information */
+H5FL_ARR_DEFINE_STATIC(H5O_chunk_t,-1);
+
+/* Declare a PQ free list to manage the chunk image information */
+H5FL_BLK_DEFINE_STATIC(chunk_image);
+
+/* Declare external the free list for time_t's */
+H5FL_EXTERN(time_t);
+
/*-------------------------------------------------------------------------
* Function: H5O_init_interface
@@ -159,7 +176,7 @@ H5O_create(H5F_t *f, size_t size_hint, H5G_entry_t *ent/*out*/)
}
/* allocate the object header and fill in header fields */
- if (NULL==(oh = H5MM_calloc(sizeof(H5O_t)))) {
+ if (NULL==(oh = H5FL_ALLOC(H5O_t,1))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
@@ -170,7 +187,7 @@ H5O_create(H5F_t *f, size_t size_hint, H5G_entry_t *ent/*out*/)
/* create the chunk list and initialize the first chunk */
oh->nchunks = 1;
oh->alloc_nchunks = H5O_NCHUNKS;
- if (NULL==(oh->chunk=H5MM_malloc(oh->alloc_nchunks*sizeof(H5O_chunk_t)))) {
+ if (NULL==(oh->chunk=H5FL_ARR_ALLOC(H5O_chunk_t,oh->alloc_nchunks,0))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
@@ -178,7 +195,7 @@ H5O_create(H5F_t *f, size_t size_hint, H5G_entry_t *ent/*out*/)
oh->chunk[0].dirty = TRUE;
oh->chunk[0].addr = tmp_addr;
oh->chunk[0].size = size_hint;
- if (NULL==(oh->chunk[0].image = H5MM_calloc(size_hint))) {
+ if (NULL==(oh->chunk[0].image = H5FL_BLK_ALLOC(chunk_image,size_hint,1))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
@@ -186,7 +203,7 @@ H5O_create(H5F_t *f, size_t size_hint, H5G_entry_t *ent/*out*/)
/* create the message list and initialize the first message */
oh->nmesgs = 1;
oh->alloc_nmesgs = H5O_NMESGS;
- if (NULL==(oh->mesg=H5MM_calloc(oh->alloc_nmesgs*sizeof(H5O_mesg_t)))) {
+ if (NULL==(oh->mesg=H5FL_ARR_ALLOC(H5O_mesg_t,oh->alloc_nmesgs,1))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
@@ -199,7 +216,7 @@ H5O_create(H5F_t *f, size_t size_hint, H5G_entry_t *ent/*out*/)
/* cache it */
if (H5AC_set(f, H5AC_OHDR, ent->header, oh) < 0) {
- H5MM_xfree(oh);
+ H5FL_FREE(H5O_t,oh);
HRETURN_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL,
"unable to cache object header");
}
@@ -350,7 +367,7 @@ H5O_load(H5F_t *f, haddr_t addr, const void UNUSED *_udata1,
assert(!_udata2);
/* allocate ohdr and init chunk list */
- if (NULL==(oh = H5MM_calloc(sizeof(H5O_t)))) {
+ if (NULL==(oh = H5FL_ALLOC(H5O_t,1))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -385,7 +402,7 @@ H5O_load(H5F_t *f, haddr_t addr, const void UNUSED *_udata1,
/* build the message array */
oh->alloc_nmesgs = MAX(H5O_NMESGS, nmesgs);
- if (NULL==(oh->mesg=H5MM_calloc(oh->alloc_nmesgs*sizeof(H5O_mesg_t)))) {
+ if (NULL==(oh->mesg=H5FL_ARR_ALLOC(H5O_mesg_t,oh->alloc_nmesgs,1))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -396,7 +413,7 @@ H5O_load(H5F_t *f, haddr_t addr, const void UNUSED *_udata1,
/* increase chunk array size */
if (oh->nchunks >= oh->alloc_nchunks) {
size_t na = oh->alloc_nchunks + H5O_NCHUNKS;
- H5O_chunk_t *x = H5MM_realloc (oh->chunk, na*sizeof(H5O_chunk_t));
+ H5O_chunk_t *x = H5FL_ARR_REALLOC (H5O_chunk_t, oh->chunk, na);
if (!x) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
@@ -410,7 +427,7 @@ H5O_load(H5F_t *f, haddr_t addr, const void UNUSED *_udata1,
oh->chunk[chunkno].dirty = FALSE;
oh->chunk[chunkno].addr = chunk_addr;
oh->chunk[chunkno].size = chunk_size;
- if (NULL==(oh->chunk[chunkno].image = H5MM_malloc(chunk_size))) {
+ if (NULL==(oh->chunk[chunkno].image = H5FL_BLK_ALLOC(chunk_image,chunk_size,0))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -478,18 +495,18 @@ H5O_load(H5F_t *f, haddr_t addr, const void UNUSED *_udata1,
}
ret_value = oh;
- done:
+done:
if (!ret_value && oh) {
- /*
- * Free resources.
- */
- int i;
- for (i = 0; i < oh->nchunks; i++) {
- oh->chunk[i].image = H5MM_xfree(oh->chunk[i].image);
- }
- oh->chunk = H5MM_xfree(oh->chunk);
- oh->mesg = H5MM_xfree(oh->mesg);
- oh = H5MM_xfree(oh);
+ /*
+ * Free resources.
+ */
+ int i;
+
+ for (i = 0; i < oh->nchunks; i++)
+ oh->chunk[i].image = H5FL_BLK_FREE(chunk_image,oh->chunk[i].image);
+ oh->chunk = H5FL_ARR_FREE(H5O_chunk_t,oh->chunk);
+ oh->mesg = H5FL_ARR_FREE(H5O_mesg_t,oh->mesg);
+ H5FL_FREE(H5O_t,oh);
}
FUNC_LEAVE(ret_value);
}
@@ -655,26 +672,25 @@ H5O_flush(H5F_t *f, hbool_t destroy, haddr_t addr, H5O_t *oh)
it calls its own version of malloc and free and does checks on the mem.
causes problems with this code so i am taking it out for the win32 debug
version until i can figure out a way around it*/
-#if !defined(WIN32) && !defined(_DEBUG)
- for (i = 0; i < oh->nchunks; i++) {
- oh->chunk[i].image = H5MM_xfree(oh->chunk[i].image);
- }
-#endif
- oh->chunk = H5MM_xfree(oh->chunk);
+/* I commented this back in to use the new free list routines - QAK 3/23/00 */
+/* #if !defined(WIN32) && !defined(_DEBUG) */
+ for (i = 0; i < oh->nchunks; i++)
+ oh->chunk[i].image = H5FL_BLK_FREE(chunk_image,oh->chunk[i].image);
+/* #endif */
+ oh->chunk = H5FL_ARR_FREE(H5O_chunk_t,oh->chunk);
/* destroy messages */
for (i = 0; i < oh->nmesgs; i++) {
if (oh->mesg[i].flags & H5O_FLAG_SHARED) {
- H5O_reset (H5O_SHARED, oh->mesg[i].native);
+ H5O_free(H5O_SHARED, oh->mesg[i].native);
} else {
- H5O_reset(oh->mesg[i].type, oh->mesg[i].native);
+ H5O_free(oh->mesg[i].type, oh->mesg[i].native);
}
- oh->mesg[i].native = H5MM_xfree(oh->mesg[i].native);
}
- oh->mesg = H5MM_xfree(oh->mesg);
+ oh->mesg = H5FL_ARR_FREE(H5O_mesg_t,oh->mesg);
/* destroy object header */
- H5MM_xfree(oh);
+ H5FL_FREE(H5O_t,oh);
}
FUNC_LEAVE(SUCCEED);
}
@@ -739,8 +755,11 @@ H5O_free (const H5O_class_t *type, void *mesg)
FUNC_ENTER (H5O_free, NULL);
if (mesg) {
- H5O_reset (type, mesg);
- H5MM_xfree (mesg);
+ H5O_reset (type, mesg);
+ if (NULL!=(type->free))
+ (type->free)(mesg);
+ else
+ H5MM_xfree (mesg);
}
FUNC_LEAVE (NULL);
@@ -1195,7 +1214,7 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, intn overwrite,
intn idx, sequence;
intn ret_value = FAIL;
size_t size = 0;
- H5O_shared_t *sh_mesg = NULL;
+ H5O_shared_t sh_mesg = {0,{{0,0}}};
FUNC_ENTER(H5O_modify, FAIL);
@@ -1241,27 +1260,23 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, intn overwrite,
HGOTO_ERROR (H5E_OHDR, H5E_UNSUPPORTED, FAIL,
"message class is not sharable");
}
- if (NULL==(sh_mesg = H5MM_calloc (sizeof *sh_mesg))) {
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "memory allocation failed");
- }
- if ((type->get_share)(ent->file, mesg, sh_mesg/*out*/)<0) {
+ if ((type->get_share)(ent->file, mesg, &sh_mesg/*out*/)<0) {
/*
* If the message isn't shared then turn off the shared bit
* and treat it as an unshared message.
*/
H5E_clear ();
flags &= ~H5O_FLAG_SHARED;
- } else if (sh_mesg->in_gh) {
+ } else if (sh_mesg.in_gh) {
/*
* The shared message is stored in the global heap.
* Increment the reference count on the global heap message.
*/
- if (H5HG_link (ent->file, &(sh_mesg->u.gh), 1)<0) {
+ if (H5HG_link (ent->file, &(sh_mesg.u.gh), 1)<0) {
HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL,
"unable to adjust shared object link count");
}
- size = (H5O_SHARED->raw_size)(ent->file, sh_mesg);
+ size = (H5O_SHARED->raw_size)(ent->file, &sh_mesg);
} else {
/*
* The shared message is stored in some other object header.
@@ -1269,15 +1284,15 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, intn overwrite,
* new object header. Increment the reference count on that
* object header.
*/
- if (sh_mesg->u.ent.file->shared != ent->file->shared) {
+ if (sh_mesg.u.ent.file->shared != ent->file->shared) {
HGOTO_ERROR(H5E_OHDR, H5E_LINK, FAIL,
"interfile hard links are not allowed");
}
- if (H5O_link (&(sh_mesg->u.ent), 1)<0) {
+ if (H5O_link (&(sh_mesg.u.ent), 1)<0) {
HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL,
"unable to adjust shared object link count");
}
- size = (H5O_SHARED->raw_size)(ent->file, sh_mesg);
+ size = (H5O_SHARED->raw_size)(ent->file, &sh_mesg);
}
}
if (0==(flags & H5O_FLAG_SHARED)) {
@@ -1305,8 +1320,11 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, intn overwrite,
/* Copy the native value into the object header */
if (flags & H5O_FLAG_SHARED) {
- oh->mesg[idx].native = sh_mesg;
- sh_mesg = NULL;
+ if (NULL==(oh->mesg[idx].native = H5MM_malloc (sizeof (H5O_shared_t)))) {
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "memory allocation failed");
+ }
+ HDmemcpy(oh->mesg[idx].native,&sh_mesg,sizeof(H5O_shared_t));
} else {
if (oh->mesg[idx].native) {
H5O_reset (oh->mesg[idx].type, oh->mesg[idx].native);
@@ -1327,7 +1345,6 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, intn overwrite,
ret_value = sequence;
done:
- H5MM_xfree(sh_mesg);
if (oh && H5AC_unprotect(ent->file, H5AC_OHDR, ent->header, oh) < 0) {
HRETURN_ERROR(H5E_OHDR, H5E_PROTECT, FAIL,
"unable to release object header");
@@ -1381,7 +1398,7 @@ H5O_touch_oh(H5F_t *f, H5O_t *oh, hbool_t force)
/* Update the native part */
if (NULL==oh->mesg[idx].native) {
- if (NULL==(oh->mesg[idx].native = H5MM_malloc(sizeof(time_t)))) {
+ if (NULL==(oh->mesg[idx].native = H5FL_ALLOC(time_t,0))) {
HRETURN_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL,
"memory allocation failed for modification time "
"message");
@@ -1627,9 +1644,8 @@ H5O_alloc_extend_chunk(H5O_t *oh, intn chunkno, size_t size)
old_addr = oh->chunk[chunkno].image;
/* Be careful not to indroduce garbage */
- oh->chunk[chunkno].image = H5MM_realloc(old_addr,
- (oh->chunk[chunkno].size +
- delta));
+ oh->chunk[chunkno].image = H5FL_BLK_REALLOC(chunk_image,old_addr,
+ (oh->chunk[chunkno].size + delta));
if (NULL==oh->chunk[chunkno].image) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
@@ -1654,7 +1670,7 @@ H5O_alloc_extend_chunk(H5O_t *oh, intn chunkno, size_t size)
/* create a new null message */
if (oh->nmesgs >= oh->alloc_nmesgs) {
size_t na = oh->alloc_nmesgs + H5O_NMESGS;
- H5O_mesg_t *x = H5MM_realloc (oh->mesg, na*sizeof(H5O_mesg_t));
+ H5O_mesg_t *x = H5FL_ARR_REALLOC (H5O_mesg_t, oh->mesg, na);
if (NULL==x) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
@@ -1677,7 +1693,7 @@ H5O_alloc_extend_chunk(H5O_t *oh, intn chunkno, size_t size)
old_addr = oh->chunk[chunkno].image;
old_size = oh->chunk[chunkno].size;
oh->chunk[chunkno].size += delta;
- oh->chunk[chunkno].image = H5MM_realloc(old_addr,
+ oh->chunk[chunkno].image = H5FL_BLK_REALLOC(chunk_image,old_addr,
oh->chunk[chunkno].size);
if (NULL==oh->chunk[chunkno].image) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
@@ -1793,7 +1809,7 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size)
*/
if (oh->nchunks >= oh->alloc_nchunks) {
size_t na = oh->alloc_nchunks + H5O_NCHUNKS;
- H5O_chunk_t *x = H5MM_realloc (oh->chunk, na*sizeof(H5O_chunk_t));
+ H5O_chunk_t *x = H5FL_ARR_REALLOC (H5O_chunk_t, oh->chunk, na);
if (!x) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
@@ -1805,7 +1821,7 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size)
oh->chunk[chunkno].dirty = TRUE;
oh->chunk[chunkno].addr = HADDR_UNDEF;
oh->chunk[chunkno].size = size;
- if (NULL==(oh->chunk[chunkno].image = p = H5MM_calloc(size))) {
+ if (NULL==(oh->chunk[chunkno].image = p = H5FL_BLK_ALLOC(chunk_image,size,1))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
@@ -1817,7 +1833,7 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size)
if (oh->nmesgs + 3 > oh->alloc_nmesgs) {
int old_alloc=oh->alloc_nmesgs;
size_t na = oh->alloc_nmesgs + MAX (H5O_NMESGS, 3);
- H5O_mesg_t *x = H5MM_realloc (oh->mesg, na*sizeof(H5O_mesg_t));
+ H5O_mesg_t *x = H5FL_ARR_REALLOC (H5O_mesg_t, oh->mesg, na);
if (!x) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
@@ -1974,7 +1990,7 @@ H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type, size_t size)
if (oh->nmesgs >= oh->alloc_nmesgs) {
int old_alloc=oh->alloc_nmesgs;
size_t na = oh->alloc_nmesgs + H5O_NMESGS;
- H5O_mesg_t *x = H5MM_realloc (oh->mesg, na*sizeof(H5O_mesg_t));
+ H5O_mesg_t *x = H5FL_ARR_REALLOC (H5O_mesg_t, oh->mesg, na);
if (!x) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
diff --git a/src/H5Oattr.c b/src/H5Oattr.c
index b5a99d6..7caadbd 100644
--- a/src/H5Oattr.c
+++ b/src/H5Oattr.c
@@ -20,6 +20,7 @@ static char RcsId[] = "@(#)$Revision$";
#include <H5private.h>
#include <H5Eprivate.h>
+#include <H5FLprivate.h> /*Free Lists */
#include <H5Gprivate.h>
#include <H5MMprivate.h>
#include <H5Oprivate.h>
@@ -46,6 +47,7 @@ const H5O_class_t H5O_ATTR[1] = {{
H5O_attr_copy, /* copy the native value */
H5O_attr_size, /* size of raw message */
H5O_attr_reset, /* reset method */
+ NULL, /* default free method */
NULL, /* get share method */
NULL, /* set share method */
H5O_attr_debug, /* debug the message */
@@ -57,6 +59,12 @@ const H5O_class_t H5O_ATTR[1] = {{
static intn interface_initialize_g = 0;
#define INTERFACE_INIT NULL
+/* Declare external the free list for H5S_t's */
+H5FL_EXTERN(H5S_t);
+
+/* Declare external the free list for H5S_simple_t's */
+H5FL_EXTERN(H5S_simple_t);
+
/*--------------------------------------------------------------------------
NAME
H5O_attr_decode
@@ -135,14 +143,14 @@ H5O_attr_decode(H5F_t *f, const uint8_t *p, H5O_shared_t UNUSED *sh)
p += H5O_ALIGN(attr->dt_size);
/* decode the attribute dataspace */
- if (NULL==(attr->ds = H5MM_calloc(sizeof(H5S_t)))) {
+ if (NULL==(attr->ds = H5FL_ALLOC(H5S_t,1))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
if((simple=(H5O_SDSPACE->decode)(f,p,NULL))!=NULL) {
attr->ds->extent.type = H5S_SIMPLE;
HDmemcpy(&(attr->ds->extent.u.simple),simple, sizeof(H5S_simple_t));
- H5MM_xfree(simple);
+ H5FL_FREE(H5S_simple_t,simple);
} else {
attr->ds->extent.type = H5S_SCALAR;
}
diff --git a/src/H5Ocomp.c b/src/H5Ocomp.c
index f812253..4f1a3e0 100644
--- a/src/H5Ocomp.c
+++ b/src/H5Ocomp.c
@@ -9,6 +9,7 @@
*/
#include <H5private.h>
#include <H5Eprivate.h>
+#include <H5FLprivate.h> /*Free Lists */
#include <H5MMprivate.h>
#include <H5Oprivate.h>
@@ -24,6 +25,7 @@ static void *H5O_pline_decode (H5F_t *f, const uint8_t *p, H5O_shared_t *sh);
static void *H5O_pline_copy (const void *_mesg, void *_dest);
static size_t H5O_pline_size (H5F_t *f, const void *_mesg);
static herr_t H5O_pline_reset (void *_mesg);
+static herr_t H5O_pline_free (void *_mesg);
static herr_t H5O_pline_debug (H5F_t *f, const void *_mesg,
FILE * stream, intn indent, intn fwidth);
@@ -37,12 +39,16 @@ const H5O_class_t H5O_PLINE[1] = {{
H5O_pline_copy, /* copy the native value */
H5O_pline_size, /* size of raw message */
H5O_pline_reset, /* reset method */
+ H5O_pline_free, /* free method */
NULL, /* get share method */
NULL, /* set share method */
H5O_pline_debug, /* debug the message */
}};
+/* Declare a free list to manage the H5O_pline_t struct */
+H5FL_DEFINE(H5O_pline_t);
+
/*-------------------------------------------------------------------------
* Function: H5O_pline_decode
@@ -75,7 +81,7 @@ H5O_pline_decode(H5F_t UNUSED *f, const uint8_t *p,
assert(p);
/* Decode */
- if (NULL==(pline = H5MM_calloc(sizeof *pline))) {
+ if (NULL==(pline = H5FL_ALLOC(H5O_pline_t,1))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -137,14 +143,14 @@ H5O_pline_decode(H5F_t UNUSED *f, const uint8_t *p,
done:
if (NULL==ret_value && pline) {
- if (pline->filter) {
- for (i=0; i<pline->nfilters; i++) {
- H5MM_xfree(pline->filter[i].name);
- H5MM_xfree(pline->filter[i].cd_values);
- }
- H5MM_xfree(pline->filter);
- }
- H5MM_xfree(pline);
+ if (pline->filter) {
+ for (i=0; i<pline->nfilters; i++) {
+ H5MM_xfree(pline->filter[i].name);
+ H5MM_xfree(pline->filter[i].cd_values);
+ }
+ H5MM_xfree(pline->filter);
+ }
+ H5FL_FREE(H5O_pline_t,pline);
}
FUNC_LEAVE(ret_value);
}
@@ -249,7 +255,7 @@ H5O_pline_copy (const void *_src, void *_dst/*out*/)
FUNC_ENTER (H5O_pline_copy, NULL);
- if (!dst && NULL==(dst = H5MM_malloc (sizeof *dst))) {
+ if (!dst && NULL==(dst = H5FL_ALLOC (H5O_pline_t,0))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -293,7 +299,7 @@ H5O_pline_copy (const void *_src, void *_dst/*out*/)
}
H5MM_xfree(dst->filter);
}
- if (!_dst) H5MM_xfree(dst);
+ if (!_dst) H5FL_FREE(H5O_pline_t,dst);
}
FUNC_LEAVE (ret_value);
@@ -379,8 +385,8 @@ H5O_pline_reset (void *mesg)
assert (pline);
for (i=0; i<pline->nfilters; i++) {
- H5MM_xfree(pline->filter[i].name);
- H5MM_xfree(pline->filter[i].cd_values);
+ H5MM_xfree(pline->filter[i].name);
+ H5MM_xfree(pline->filter[i].cd_values);
}
H5MM_xfree(pline->filter);
HDmemset(pline, 0, sizeof *pline);
@@ -390,6 +396,33 @@ H5O_pline_reset (void *mesg)
/*-------------------------------------------------------------------------
+ * Function: H5O_pline_free
+ *
+ * Purpose: Free's the message
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, March 11, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_pline_free (void *mesg)
+{
+ FUNC_ENTER (H5O_pline_free, FAIL);
+
+ assert (mesg);
+
+ H5FL_FREE(H5O_pline_t,mesg);
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_pline_debug
*
* Purpose: Prints debugging information for filter pipeline message MESG
diff --git a/src/H5Ocont.c b/src/H5Ocont.c
index 997ea0d..45b3e31 100644
--- a/src/H5Ocont.c
+++ b/src/H5Ocont.c
@@ -40,6 +40,7 @@ const H5O_class_t H5O_CONT[1] = {{
NULL, /*no copy method */
NULL, /*no size method */
NULL, /*default reset method */
+ NULL, /* default free method */
NULL, /*get share method */
NULL, /*set share method */
H5O_cont_debug, /*debugging */
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index 4d4322b..ad7faa0 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -20,6 +20,7 @@ static char RcsId[] = "@(#)$Revision$";
#include <H5private.h>
#include <H5Eprivate.h>
+#include <H5FLprivate.h> /*Free Lists */
#include <H5Gprivate.h>
#include <H5MMprivate.h>
#include <H5Oprivate.h>
@@ -33,6 +34,7 @@ static void *H5O_dtype_decode (H5F_t *f, const uint8_t *p, H5O_shared_t *sh);
static void *H5O_dtype_copy (const void *_mesg, void *_dest);
static size_t H5O_dtype_size (H5F_t *f, const void *_mesg);
static herr_t H5O_dtype_reset (void *_mesg);
+static herr_t H5O_dtype_free (void *_mesg);
static herr_t H5O_dtype_get_share (H5F_t *f, const void *_mesg,
H5O_shared_t *sh);
static herr_t H5O_dtype_set_share (H5F_t *f, void *_mesg,
@@ -50,6 +52,7 @@ const H5O_class_t H5O_DTYPE[1] = {{
H5O_dtype_copy, /* copy the native value */
H5O_dtype_size, /* size of raw message */
H5O_dtype_reset, /* reset method */
+ H5O_dtype_free, /* free method */
H5O_dtype_get_share, /* get share method */
H5O_dtype_set_share, /* set share method */
H5O_dtype_debug, /* debug the message */
@@ -60,6 +63,10 @@ const H5O_class_t H5O_DTYPE[1] = {{
/* Interface initialization */
static intn interface_initialize_g = 0;
#define INTERFACE_INIT NULL
+
+/* Declare external the free list for H5T_t's */
+H5FL_EXTERN(H5T_t);
+
/*-------------------------------------------------------------------------
* Function: H5O_dtype_decode_helper
@@ -201,24 +208,25 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
dt->u.compnd.memb[i].perm[1] = (perm_word >> 8) & 0xff;
dt->u.compnd.memb[i].perm[2] = (perm_word >> 16) & 0xff;
dt->u.compnd.memb[i].perm[3] = (perm_word >> 24) & 0xff;
- dt->u.compnd.memb[i].type = H5MM_calloc (sizeof(H5T_t));
+ dt->u.compnd.memb[i].type = H5FL_ALLOC (H5T_t,1);
+ if (NULL==dt->u.compnd.memb[i].type) {
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "memory allocation failed");
+ }
/* Reserved */
*pp += 4;
/* Dimension sizes */
- for (j=0; j<4; j++) {
- UINT32DECODE(*pp, dt->u.compnd.memb[i].dim[j]);
- }
- if (NULL==dt->u.compnd.memb[i].type) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "memory allocation failed");
- }
+ for (j=0; j<4; j++)
+ UINT32DECODE(*pp, dt->u.compnd.memb[i].dim[j]);
+
dt->u.compnd.memb[i].type->ent.header = HADDR_UNDEF;
if (H5O_dtype_decode_helper(f, pp, dt->u.compnd.memb[i].type)<0) {
- for (j=0; j<=i; j++) H5MM_xfree(dt->u.compnd.memb[j].name);
- H5MM_xfree(dt->u.compnd.memb);
- HRETURN_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL,
+ for (j=0; j<=i; j++)
+ H5MM_xfree(dt->u.compnd.memb[j].name);
+ H5MM_xfree(dt->u.compnd.memb);
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL,
"unable to decode member type");
}
@@ -231,9 +239,8 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
/* Total member size */
dt->u.compnd.memb[i].size = dt->u.compnd.memb[i].type->size;
- for (j=0; j<dt->u.compnd.memb[i].ndims; j++) {
+ for (j=0; j<dt->u.compnd.memb[i].ndims; j++)
dt->u.compnd.memb[i].size *= dt->u.compnd.memb[i].dim[j];
- }
}
break;
@@ -243,7 +250,7 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
*/
dt->u.enumer.nmembs = dt->u.enumer.nalloc = flags & 0xffff;
assert(dt->u.enumer.nmembs>=0);
- if (NULL==(dt->parent=H5MM_calloc(sizeof(H5T_t)))) {
+ if (NULL==(dt->parent=H5FL_ALLOC(H5T_t,1))) {
HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
@@ -300,7 +307,7 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
dt->u.vlen.type = (H5T_vlen_type_t)(flags & 0x0f);
/* Decode base type of VL information */
- if (NULL==(dt->parent = H5MM_calloc(sizeof(H5T_t))))
+ if (NULL==(dt->parent = H5FL_ALLOC(H5T_t,1)))
HRETURN_ERROR (H5E_DATATYPE, H5E_NOSPACE, FAIL,
"memory allocation failed");
dt->parent->ent.header = HADDR_UNDEF;
@@ -691,15 +698,15 @@ H5O_dtype_decode(H5F_t *f, const uint8_t *p,
/* check args */
assert(p);
- if (NULL==(dt = H5MM_calloc(sizeof(H5T_t)))) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
+ if (NULL==(dt = H5FL_ALLOC(H5T_t,1))) {
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
dt->ent.header = HADDR_UNDEF;
if (H5O_dtype_decode_helper(f, &p, dt) < 0) {
- H5MM_xfree(dt);
- HRETURN_ERROR(H5E_DATATYPE, H5E_CANTDECODE, NULL,
+ H5FL_FREE(H5T_t,dt);
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTDECODE, NULL,
"can't decode type");
}
FUNC_LEAVE(dt);
@@ -771,14 +778,14 @@ H5O_dtype_copy(const void *_src, void *_dst)
assert(src);
/* copy */
- if (NULL == (dst = H5T_copy(src, H5T_COPY_ALL))) {
- HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "can't copy type");
- }
+ if (NULL == (dst = H5T_copy(src, H5T_COPY_ALL)))
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "can't copy type");
+
/* was result already allocated? */
if (_dst) {
- *((H5T_t *) _dst) = *dst;
- H5MM_xfree(dst);
- dst = (H5T_t *) _dst;
+ *((H5T_t *) _dst) = *dst;
+ H5FL_FREE(H5T_t,dst);
+ dst = (H5T_t *) _dst;
}
FUNC_LEAVE((void *) dst);
}
@@ -884,19 +891,46 @@ H5O_dtype_reset(void *_mesg)
FUNC_ENTER(H5O_dtype_reset, FAIL);
if (dt) {
- if (NULL==(tmp = H5MM_malloc(sizeof(H5T_t)))) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ if (NULL==(tmp = H5FL_ALLOC(H5T_t,0))) {
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
- }
- *tmp = *dt;
- H5T_close(tmp);
- HDmemset(dt, 0, sizeof(H5T_t));
+ }
+ *tmp = *dt;
+ H5T_close(tmp);
+ HDmemset(dt, 0, sizeof(H5T_t));
}
FUNC_LEAVE(SUCCEED);
}
/*-------------------------------------------------------------------------
+ * Function: H5O_dtype_free
+ *
+ * Purpose: Free's the message
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, March 30, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_dtype_free (void *mesg)
+{
+ FUNC_ENTER (H5O_dtype_free, FAIL);
+
+ assert (mesg);
+
+ H5FL_FREE(H5T_t,mesg);
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_dtype_get_share
*
* Purpose: Returns information about where the shared message is located
diff --git a/src/H5Oefl.c b/src/H5Oefl.c
index 8030005..0a16485 100644
--- a/src/H5Oefl.c
+++ b/src/H5Oefl.c
@@ -32,6 +32,7 @@ const H5O_class_t H5O_EFL[1] = {{
H5O_efl_copy, /*copy native value */
H5O_efl_size, /*size of message on disk */
H5O_efl_reset, /*reset method */
+ NULL, /* free method */
NULL, /*get share method */
NULL, /*set share method */
H5O_efl_debug, /*debug the message */
diff --git a/src/H5Ofill.c b/src/H5Ofill.c
index 7018ae2..2992606 100644
--- a/src/H5Ofill.c
+++ b/src/H5Ofill.c
@@ -35,6 +35,7 @@ const H5O_class_t H5O_FILL[1] = {{
H5O_fill_copy, /*copy the native value */
H5O_fill_size, /*raw message size */
H5O_fill_reset, /*free internal memory */
+ NULL, /* free method */
NULL, /*get share method */
NULL, /*set share method */
H5O_fill_debug, /*debug the message */
diff --git a/src/H5Olayout.c b/src/H5Olayout.c
index 69043d3..b494ea1 100644
--- a/src/H5Olayout.c
+++ b/src/H5Olayout.c
@@ -10,6 +10,7 @@
#include <H5private.h>
#include <H5Dprivate.h>
#include <H5Eprivate.h>
+#include <H5FLprivate.h> /*Free Lists */
#include <H5MMprivate.h>
#include <H5Oprivate.h>
@@ -18,6 +19,7 @@ static void *H5O_layout_decode(H5F_t *f, const uint8_t *p, H5O_shared_t *sh);
static herr_t H5O_layout_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static void *H5O_layout_copy(const void *_mesg, void *_dest);
static size_t H5O_layout_size(H5F_t *f, const void *_mesg);
+static herr_t H5O_layout_free (void *_mesg);
static herr_t H5O_layout_debug(H5F_t *f, const void *_mesg, FILE * stream,
intn indent, intn fwidth);
@@ -31,6 +33,7 @@ const H5O_class_t H5O_LAYOUT[1] = {{
H5O_layout_copy, /*copy the native value */
H5O_layout_size, /*size of message on disk */
NULL, /*reset method */
+ H5O_layout_free, /*free the struct */
NULL, /*get share method */
NULL, /*set share method */
H5O_layout_debug, /*debug the message */
@@ -43,6 +46,9 @@ const H5O_class_t H5O_LAYOUT[1] = {{
static intn interface_initialize_g = 0;
#define INTERFACE_INIT NULL
+/* Declare a free list to manage the H5O_layout_t struct */
+H5FL_DEFINE(H5O_layout_t);
+
/*-------------------------------------------------------------------------
* Function: H5O_layout_decode
@@ -77,7 +83,7 @@ H5O_layout_decode(H5F_t *f, const uint8_t *p, H5O_shared_t UNUSED *sh)
assert (!sh);
/* decode */
- if (NULL==(mesg = H5MM_calloc(sizeof(H5O_layout_t)))) {
+ if (NULL==(mesg = H5FL_ALLOC(H5O_layout_t,1))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -92,8 +98,8 @@ H5O_layout_decode(H5F_t *f, const uint8_t *p, H5O_shared_t UNUSED *sh)
/* Dimensionality */
mesg->ndims = *p++;
if (mesg->ndims>H5O_LAYOUT_NDIMS) {
- H5MM_xfree(mesg);
- HRETURN_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL,
+ H5FL_FREE(H5O_layout_t,mesg);
+ HRETURN_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL,
"dimensionality is too large");
}
@@ -195,8 +201,8 @@ H5O_layout_copy(const void *_mesg, void *_dest)
/* check args */
assert(mesg);
- if (!dest && NULL==(dest=H5MM_calloc(sizeof(H5O_layout_t)))) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
+ if (!dest && NULL==(dest=H5FL_ALLOC(H5O_layout_t,0))) {
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -245,6 +251,34 @@ H5O_layout_size(H5F_t *f, const void *_mesg)
FUNC_LEAVE(ret_value);
}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_layout_free
+ *
+ * Purpose: Free's the message
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, March 11, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_layout_free (void *mesg)
+{
+ FUNC_ENTER (H5O_layout_free, FAIL);
+
+ assert (mesg);
+
+ H5FL_FREE(H5O_layout_t,mesg);
+
+ FUNC_LEAVE (SUCCEED);
+}
+
/*-------------------------------------------------------------------------
* Function: H5O_layout_debug
diff --git a/src/H5Omtime.c b/src/H5Omtime.c
index e16b283..fc57f58 100644
--- a/src/H5Omtime.c
+++ b/src/H5Omtime.c
@@ -9,6 +9,7 @@
*/
#include <H5private.h>
#include <H5Eprivate.h>
+#include <H5FLprivate.h> /*Free Lists */
#include <H5MMprivate.h>
#include <H5Oprivate.h>
@@ -18,6 +19,7 @@ static void *H5O_mtime_decode(H5F_t *f, const uint8_t *p, H5O_shared_t *sh);
static herr_t H5O_mtime_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static void *H5O_mtime_copy(const void *_mesg, void *_dest);
static size_t H5O_mtime_size(H5F_t *f, const void *_mesg);
+static herr_t H5O_mtime_free (void *_mesg);
static herr_t H5O_mtime_debug(H5F_t *f, const void *_mesg, FILE *stream,
intn indent, intn fwidth);
@@ -31,6 +33,7 @@ const H5O_class_t H5O_MTIME[1] = {{
H5O_mtime_copy, /*copy the native value */
H5O_mtime_size, /*raw message size */
NULL, /*free internal memory */
+ H5O_mtime_free, /* free method */
NULL, /*get share method */
NULL, /*set share method */
H5O_mtime_debug, /*debug the message */
@@ -40,6 +43,9 @@ const H5O_class_t H5O_MTIME[1] = {{
static intn interface_initialize_g = 0;
#define INTERFACE_INIT NULL
+/* Declare a free list to manage the time_t struct */
+H5FL_DEFINE(time_t);
+
/*-------------------------------------------------------------------------
* Function: H5O_mtime_decode
@@ -149,7 +155,7 @@ H5O_mtime_decode(H5F_t UNUSED *f, const uint8_t *p,
#endif
/* The return value */
- if (NULL==(mesg = H5MM_calloc(sizeof(time_t)))) {
+ if (NULL==(mesg = H5FL_ALLOC(time_t,1))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -226,8 +232,8 @@ H5O_mtime_copy(const void *_mesg, void *_dest)
/* check args */
assert(mesg);
- if (!dest && NULL==(dest = H5MM_calloc(sizeof(time_t)))) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
+ if (!dest && NULL==(dest = H5FL_ALLOC(time_t,0))) {
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -271,6 +277,33 @@ H5O_mtime_size(H5F_t UNUSED *f, const void UNUSED *mesg)
/*-------------------------------------------------------------------------
+ * Function: H5O_mtime_free
+ *
+ * Purpose: Free's the message
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, March 30, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_mtime_free (void *mesg)
+{
+ FUNC_ENTER (H5O_mtime_free, FAIL);
+
+ assert (mesg);
+
+ H5FL_FREE(time_t,mesg);
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_mtime_debug
*
* Purpose: Prints debugging info for the message.
diff --git a/src/H5Oname.c b/src/H5Oname.c
index ed9c294..97f4bbc 100644
--- a/src/H5Oname.c
+++ b/src/H5Oname.c
@@ -40,6 +40,7 @@ const H5O_class_t H5O_NAME[1] = {{
H5O_name_copy, /*copy the native value */
H5O_name_size, /*raw message size */
H5O_name_reset, /*free internal memory */
+ NULL, /* free method */
NULL, /*get share method */
NULL, /*set share method */
H5O_name_debug, /*debug the message */
diff --git a/src/H5Onull.c b/src/H5Onull.c
index ff33d42..e9611f7 100644
--- a/src/H5Onull.c
+++ b/src/H5Onull.c
@@ -29,6 +29,7 @@ const H5O_class_t H5O_NULL[1] = {{
NULL, /*no copy method */
NULL, /*no size method */
NULL, /*no reset method */
+ NULL, /*no free method */
NULL, /*no get share method */
NULL, /*no set share method */
NULL, /*no debug method */
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 0577a35..826d0bb 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -76,6 +76,7 @@ typedef struct H5O_class_t {
void *(*copy)(const void*, void*); /*copy native value */
size_t (*raw_size)(H5F_t*, const void*);/*sizeof raw val */
herr_t (*reset)(void *); /*free nested data structs */
+ herr_t (*free)(void *); /*free main data struct */
herr_t (*get_share)(H5F_t*, const void*, struct H5O_shared_t*);
herr_t (*set_share)(H5F_t*, void*, const struct H5O_shared_t*);
herr_t (*debug)(H5F_t*, const void*, FILE*, intn, intn);
diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c
index f76b7bc..1a7e0a8 100644
--- a/src/H5Osdspace.c
+++ b/src/H5Osdspace.c
@@ -18,6 +18,7 @@ static char RcsId[] = "@(#)$Revision$";
#include <H5private.h>
#include <H5Eprivate.h>
+#include <H5FLprivate.h> /*Free Lists */
#include <H5Gprivate.h>
#include <H5MMprivate.h>
#include <H5Oprivate.h>
@@ -29,9 +30,10 @@ static void *H5O_sdspace_decode(H5F_t *f, const uint8_t *p, H5O_shared_t *sh);
static herr_t H5O_sdspace_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static void *H5O_sdspace_copy(const void *_mesg, void *_dest);
static size_t H5O_sdspace_size(H5F_t *f, const void *_mesg);
+static herr_t H5O_sdspace_reset(void *_mesg);
+static herr_t H5O_sdspace_free (void *_mesg);
static herr_t H5O_sdspace_debug(H5F_t *f, const void *_mesg,
FILE * stream, intn indent, intn fwidth);
-static herr_t H5O_sdspace_reset(void *_mesg);
/* This message derives from H5O */
const H5O_class_t H5O_SDSPACE[1] = {{
@@ -43,6 +45,7 @@ const H5O_class_t H5O_SDSPACE[1] = {{
H5O_sdspace_copy, /* copy the native value */
H5O_sdspace_size, /* size of symbol table entry */
H5O_sdspace_reset, /* default reset method */
+ H5O_sdspace_free, /* free method */
NULL, /* get share method */
NULL, /* set share method */
H5O_sdspace_debug, /* debug the message */
@@ -54,6 +57,12 @@ const H5O_class_t H5O_SDSPACE[1] = {{
static intn interface_initialize_g = 0;
#define INTERFACE_INIT NULL
+/* Declare external the free list for H5S_simple_t's */
+H5FL_EXTERN(H5S_simple_t);
+
+/* Declare external the free list for hsize_t arrays */
+H5FL_ARR_EXTERN(hsize_t);
+
/*--------------------------------------------------------------------------
NAME
H5O_sdspace_decode
@@ -96,7 +105,7 @@ H5O_sdspace_decode(H5F_t *f, const uint8_t *p, H5O_shared_t UNUSED *sh)
assert (!sh);
/* decode */
- if ((sdim = H5MM_calloc(sizeof(H5S_simple_t))) != NULL) {
+ if ((sdim = H5FL_ALLOC(H5S_simple_t,1)) != NULL) {
version = *p++;
if (version!=H5O_SDSPACE_VERSION) {
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL,
@@ -111,8 +120,7 @@ H5O_sdspace_decode(H5F_t *f, const uint8_t *p, H5O_shared_t UNUSED *sh)
p += 5; /*reserved*/
if (sdim->rank > 0) {
- if (NULL==(sdim->size=H5MM_malloc(sizeof(sdim->size[0])*
- sdim->rank))) {
+ if (NULL==(sdim->size=H5FL_ARR_ALLOC(hsize_t,sdim->rank,0))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -120,8 +128,7 @@ H5O_sdspace_decode(H5F_t *f, const uint8_t *p, H5O_shared_t UNUSED *sh)
H5F_decode_length (f, p, sdim->size[u]);
}
if (flags & H5S_VALID_MAX) {
- if (NULL==(sdim->max=H5MM_malloc(sizeof(sdim->max[0])*
- sdim->rank))) {
+ if (NULL==(sdim->max=H5FL_ARR_ALLOC(hsize_t,sdim->rank,0))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -131,8 +138,7 @@ H5O_sdspace_decode(H5F_t *f, const uint8_t *p, H5O_shared_t UNUSED *sh)
}
#ifdef LATER
if (flags & H5S_VALID_PERM) {
- if (NULL==(sdim->perm=H5MM_malloc(sizeof(sdim->perm[0])*
- sdim->rank))) {
+ if (NULL==(sdim->perm=H5FL_ARR_ALLOC(hsize_t,sdim->rank,0))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -145,7 +151,7 @@ H5O_sdspace_decode(H5F_t *f, const uint8_t *p, H5O_shared_t UNUSED *sh)
ret_value = (void*)sdim; /*success*/
done:
- if (!ret_value) H5MM_xfree(sdim);
+ if (!ret_value) H5FL_FREE(H5S_simple_t,sdim);
FUNC_LEAVE(ret_value);
}
@@ -248,7 +254,7 @@ H5O_sdspace_copy(const void *mesg, void *dest)
/* check args */
assert(src);
- if (!dst && NULL==(dst = H5MM_calloc(sizeof(H5S_simple_t)))) {
+ if (!dst && NULL==(dst = H5FL_ALLOC(H5S_simple_t,0))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -257,14 +263,14 @@ H5O_sdspace_copy(const void *mesg, void *dest)
HDmemcpy(dst, src, sizeof(H5S_simple_t));
if (src->size) {
- if (NULL==(dst->size = H5MM_calloc(src->rank*sizeof(src->size[0])))) {
+ if (NULL==(dst->size = H5FL_ARR_ALLOC(hsize_t,src->rank,0))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
HDmemcpy (dst->size, src->size, src->rank*sizeof(src->size[0]));
}
if (src->max) {
- if (NULL==(dst->max=H5MM_calloc(src->rank*sizeof(src->max[0])))) {
+ if (NULL==(dst->max=H5FL_ARR_ALLOC(hsize_t,src->rank,0))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -272,7 +278,7 @@ H5O_sdspace_copy(const void *mesg, void *dest)
}
#ifdef LATER
if (src->perm) {
- if (NULL==(dst->perm=H5MM_calloc(src->rank*sizeof(src->perm[0])))) {
+ if (NULL==(dst->perm=H5FL_ARR_ALLOC(hsize_t,src->rank,0))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -283,36 +289,6 @@ H5O_sdspace_copy(const void *mesg, void *dest)
FUNC_LEAVE((void *) dst);
}
-
-/*-------------------------------------------------------------------------
- * Function: H5O_sdspace_reset
- *
- * Purpose: Frees the inside of a dataspace message and resets it to some
- * initial value.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * Thursday, April 30, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5O_sdspace_reset(void *_mesg)
-{
- H5S_simple_t *mesg = (H5S_simple_t*)_mesg;
-
- FUNC_ENTER (H5O_sdspace_reset, FAIL);
- mesg->size = H5MM_xfree (mesg->size);
- mesg->max = H5MM_xfree (mesg->max);
-#ifdef LATER
- mesg->perm = H5MM_xfree (mesg->perm);
-#endif
- FUNC_LEAVE (SUCCEED);
-}
-
/*--------------------------------------------------------------------------
NAME
H5O_sdspace_size
@@ -360,6 +336,61 @@ H5O_sdspace_size(H5F_t *f, const void *mesg)
FUNC_LEAVE(ret_value);
}
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_sdspace_reset
+ *
+ * Purpose: Frees the inside of a dataspace message and resets it to some
+ * initial value.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Thursday, April 30, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_sdspace_reset(void *_mesg)
+{
+ H5S_simple_t *mesg = (H5S_simple_t*)_mesg;
+
+ FUNC_ENTER (H5O_sdspace_reset, FAIL);
+
+ H5S_release_simple(mesg);
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_sdsdpace_free
+ *
+ * Purpose: Free's the message
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, March 30, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_sdspace_free (void *mesg)
+{
+ FUNC_ENTER (H5O_sdspace_free, FAIL);
+
+ assert (mesg);
+
+ H5FL_FREE(H5S_simple_t,mesg);
+
+ FUNC_LEAVE (SUCCEED);
+}
+
/*--------------------------------------------------------------------------
NAME
H5O_sdspace_debug
diff --git a/src/H5Oshared.c b/src/H5Oshared.c
index 9c70385..1e1216b 100644
--- a/src/H5Oshared.c
+++ b/src/H5Oshared.c
@@ -33,6 +33,7 @@ const H5O_class_t H5O_SHARED[1] = {{
NULL, /*no copy method */
H5O_shared_size, /*size method */
NULL, /*no reset method */
+ NULL, /*no free method */
NULL, /*get share method */
NULL, /*set share method */
H5O_shared_debug, /*debug method */
diff --git a/src/H5Ostab.c b/src/H5Ostab.c
index 2d5559d..a2af9ed 100644
--- a/src/H5Ostab.c
+++ b/src/H5Ostab.c
@@ -40,6 +40,7 @@ const H5O_class_t H5O_STAB[1] = {{
H5O_stab_copy, /*copy the native value */
H5O_stab_size, /*size of symbol table entry */
NULL, /*default reset method */
+ NULL, /*default free method */
NULL, /*get share method */
NULL, /*set share method */
H5O_stab_debug, /*debug the message */
diff --git a/src/H5P.c b/src/H5P.c
index de523ce..441ab53 100644
--- a/src/H5P.c
+++ b/src/H5P.c
@@ -23,6 +23,7 @@ static char RcsId[] = "@(#)$Revision$";
#include <H5Dprivate.h> /* Datasets */
#include <H5Eprivate.h> /* Error handling */
#include <H5FDprivate.h> /* File drivers */
+#include <H5FLprivate.h> /* Free Lists */
#include <H5MMprivate.h> /* Memory management */
#include <H5Pprivate.h> /* Property lists */
@@ -36,6 +37,21 @@ static intn interface_initialize_g = 0;
#define INTERFACE_INIT H5P_init_interface
static herr_t H5P_init_interface(void);
+/* Declare a free list to manage the H5F_create_t struct */
+H5FL_DEFINE_STATIC(H5F_create_t);
+
+/* Declare a free list to manage the H5F_access_t struct */
+H5FL_DEFINE_STATIC(H5F_access_t);
+
+/* Declare a free list to manage the H5D_create_t struct */
+H5FL_DEFINE_STATIC(H5D_create_t);
+
+/* Declare a free list to manage the H5F_xfer_t struct */
+H5FL_DEFINE_STATIC(H5F_xfer_t);
+
+/* Declare a free list to manage the H5F_mprop_t struct */
+H5FL_DEFINE_STATIC(H5F_mprop_t);
+
/*--------------------------------------------------------------------------
NAME
H5P_init_interface -- Initialize interface-specific information
@@ -158,23 +174,23 @@ H5Pcreate(H5P_class_t type)
/* Allocate a new property list and initialize it with default values */
switch (type) {
- case H5P_FILE_CREATE:
- src = &H5F_create_dflt;
- break;
- case H5P_FILE_ACCESS:
- src = &H5F_access_dflt;
- break;
- case H5P_DATASET_CREATE:
- src = &H5D_create_dflt;
- break;
- case H5P_DATA_XFER:
- src = &H5F_xfer_dflt;
- break;
- case H5P_MOUNT:
- src = &H5F_mount_dflt;
- break;
- default:
- HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
+ case H5P_FILE_CREATE:
+ src = &H5F_create_dflt;
+ break;
+ case H5P_FILE_ACCESS:
+ src = &H5F_access_dflt;
+ break;
+ case H5P_DATASET_CREATE:
+ src = &H5D_create_dflt;
+ break;
+ case H5P_DATA_XFER:
+ src = &H5F_xfer_dflt;
+ break;
+ case H5P_MOUNT:
+ src = &H5F_mount_dflt;
+ break;
+ default:
+ HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
"unknown property list class");
}
@@ -309,45 +325,46 @@ H5P_close(H5P_class_t type, void *plist)
/* Some property lists may need to do special things */
switch (type) {
- case H5P_FILE_ACCESS:
- if (fa_list->driver_id>=0) {
- H5FD_fapl_free(fa_list->driver_id, fa_list->driver_info);
- H5I_dec_ref(fa_list->driver_id);
- fa_list->driver_info = NULL;
- fa_list->driver_id = -1;
- }
- break;
-
- case H5P_FILE_CREATE:
- /*nothing to do*/
- break;
-
- case H5P_DATASET_CREATE:
- H5O_reset(H5O_FILL, &(dc_list->fill));
- H5O_reset(H5O_EFL, &(dc_list->efl));
- H5O_reset(H5O_PLINE, &(dc_list->pline));
- break;
-
- case H5P_DATA_XFER:
- if (dx_list->driver_id>=0) {
- H5FD_dxpl_free(dx_list->driver_id, dx_list->driver_info);
- H5I_dec_ref(dx_list->driver_id);
- dx_list->driver_info = NULL;
- dx_list->driver_id = -1;
- }
- break;
-
- case H5P_MOUNT:
- /*nothing to do*/
- break;
-
- default:
- HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL,
- "unknown property list class");
+ case H5P_FILE_ACCESS:
+ if (fa_list->driver_id>=0) {
+ H5FD_fapl_free(fa_list->driver_id, fa_list->driver_info);
+ H5I_dec_ref(fa_list->driver_id);
+ fa_list->driver_info = NULL;
+ fa_list->driver_id = -1;
+ }
+ H5FL_FREE(H5F_access_t,plist);
+ break;
+
+ case H5P_FILE_CREATE:
+ H5FL_FREE(H5F_create_t,plist);
+ break;
+
+ case H5P_DATASET_CREATE:
+ H5O_reset(H5O_FILL, &(dc_list->fill));
+ H5O_reset(H5O_EFL, &(dc_list->efl));
+ H5O_reset(H5O_PLINE, &(dc_list->pline));
+ H5FL_FREE(H5D_create_t,plist);
+ break;
+
+ case H5P_DATA_XFER:
+ if (dx_list->driver_id>=0) {
+ H5FD_dxpl_free(dx_list->driver_id, dx_list->driver_info);
+ H5I_dec_ref(dx_list->driver_id);
+ dx_list->driver_info = NULL;
+ dx_list->driver_id = -1;
+ }
+ H5FL_FREE(H5F_xfer_t,plist);
+ break;
+
+ case H5P_MOUNT:
+ H5FL_FREE(H5F_mprop_t,plist);
+ break;
+
+ default:
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL,
+ "unknown property list class");
}
- /* Free the property list struct and return */
- H5MM_xfree(plist);
FUNC_LEAVE(SUCCEED);
}
@@ -2614,96 +2631,115 @@ H5P_copy (H5P_class_t type, const void *src)
/* How big is the property list */
switch (type) {
- case H5P_FILE_CREATE:
- size = sizeof(H5F_create_t);
- break;
-
- case H5P_FILE_ACCESS:
- size = sizeof(H5F_access_t);
- break;
-
- case H5P_DATASET_CREATE:
- size = sizeof(H5D_create_t);
- break;
-
- case H5P_DATA_XFER:
- size = sizeof(H5F_xfer_t);
- break;
-
- case H5P_MOUNT:
- size = sizeof(H5F_mprop_t);
- break;
-
- default:
- HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, NULL,
- "unknown property list class");
- }
-
- /* Create the new property list */
- if (NULL==(dst = H5MM_malloc(size))) {
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
- "memory allocation failed");
- }
+ case H5P_FILE_CREATE:
+ /* Create the new property list */
+ if (NULL==(dst = H5FL_ALLOC(H5F_create_t,0))) {
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
+ "memory allocation failed");
+ }
+ size = sizeof(H5F_create_t);
+ break;
+
+ case H5P_FILE_ACCESS:
+ /* Create the new property list */
+ if (NULL==(dst = H5FL_ALLOC(H5F_access_t,0))) {
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
+ "memory allocation failed");
+ }
+ size = sizeof(H5F_access_t);
+ break;
+
+ case H5P_DATASET_CREATE:
+ /* Create the new property list */
+ if (NULL==(dst = H5FL_ALLOC(H5D_create_t,0))) {
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
+ "memory allocation failed");
+ }
+ size = sizeof(H5D_create_t);
+ break;
+
+ case H5P_DATA_XFER:
+ /* Create the new property list */
+ if (NULL==(dst = H5FL_ALLOC(H5F_xfer_t,0))) {
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
+ "memory allocation failed");
+ }
+ size = sizeof(H5F_xfer_t);
+ break;
+
+ case H5P_MOUNT:
+ /* Create the new property list */
+ if (NULL==(dst = H5FL_ALLOC(H5F_mprop_t,0))) {
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
+ "memory allocation failed");
+ }
+ size = sizeof(H5F_mprop_t);
+ break;
+
+ default:
+ HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, NULL,
+ "unknown property list class");
+ }
+
+ /* Copy into new object */
HDmemcpy(dst, src, size);
/* Deep-copy pointers */
switch (type) {
- case H5P_FILE_CREATE:
- break;
-
- case H5P_FILE_ACCESS:
- fa_dst = (H5F_access_t*)dst;
-
- if (fa_dst->driver_id>=0) {
- H5I_inc_ref(fa_dst->driver_id);
- fa_dst->driver_info = H5FD_fapl_copy(fa_dst->driver_id,
- fa_dst->driver_info);
- }
- break;
-
- case H5P_DATASET_CREATE:
- dc_src = (const H5D_create_t*)src;
- dc_dst = (H5D_create_t*)dst;
-
- /* Copy the fill value */
- if (NULL==H5O_copy(H5O_FILL, &(dc_src->fill), &(dc_dst->fill))) {
- HRETURN_ERROR(H5E_PLIST, H5E_CANTINIT, NULL,
- "unabe to copy fill value message");
- }
-
- /* Copy the external file list */
- HDmemset(&(dc_dst->efl), 0, sizeof(dc_dst->efl));
- if (NULL==H5O_copy(H5O_EFL, &(dc_src->efl), &(dc_dst->efl))) {
- HRETURN_ERROR(H5E_PLIST, H5E_CANTINIT, NULL,
- "unable to copy external file list message");
- }
-
- /* Copy the filter pipeline */
- if (NULL==H5O_copy(H5O_PLINE, &(dc_src->pline), &(dc_dst->pline))) {
- HRETURN_ERROR(H5E_PLIST, H5E_CANTINIT, NULL,
- "unable to copy filter pipeline message");
- }
-
-
- break;
-
- case H5P_DATA_XFER:
- dx_dst = (H5F_xfer_t*)dst;
-
- if (dx_dst->driver_id>=0) {
- H5I_inc_ref(dx_dst->driver_id);
- dx_dst->driver_info = H5FD_dxpl_copy(dx_dst->driver_id,
- dx_dst->driver_info);
- }
- break;
-
- case H5P_MOUNT:
- /* Nothing to do */
- break;
-
- default:
- HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, NULL,
- "unknown property list class");
+ case H5P_FILE_CREATE:
+ break;
+
+ case H5P_FILE_ACCESS:
+ fa_dst = (H5F_access_t*)dst;
+
+ if (fa_dst->driver_id>=0) {
+ H5I_inc_ref(fa_dst->driver_id);
+ fa_dst->driver_info = H5FD_fapl_copy(fa_dst->driver_id,
+ fa_dst->driver_info);
+ }
+ break;
+
+ case H5P_DATASET_CREATE:
+ dc_src = (const H5D_create_t*)src;
+ dc_dst = (H5D_create_t*)dst;
+
+ /* Copy the fill value */
+ if (NULL==H5O_copy(H5O_FILL, &(dc_src->fill), &(dc_dst->fill))) {
+ HRETURN_ERROR(H5E_PLIST, H5E_CANTINIT, NULL,
+ "unabe to copy fill value message");
+ }
+
+ /* Copy the external file list */
+ HDmemset(&(dc_dst->efl), 0, sizeof(dc_dst->efl));
+ if (NULL==H5O_copy(H5O_EFL, &(dc_src->efl), &(dc_dst->efl))) {
+ HRETURN_ERROR(H5E_PLIST, H5E_CANTINIT, NULL,
+ "unable to copy external file list message");
+ }
+
+ /* Copy the filter pipeline */
+ if (NULL==H5O_copy(H5O_PLINE, &(dc_src->pline), &(dc_dst->pline))) {
+ HRETURN_ERROR(H5E_PLIST, H5E_CANTINIT, NULL,
+ "unable to copy filter pipeline message");
+ }
+ break;
+
+ case H5P_DATA_XFER:
+ dx_dst = (H5F_xfer_t*)dst;
+
+ if (dx_dst->driver_id>=0) {
+ H5I_inc_ref(dx_dst->driver_id);
+ dx_dst->driver_info = H5FD_dxpl_copy(dx_dst->driver_id,
+ dx_dst->driver_info);
+ }
+ break;
+
+ case H5P_MOUNT:
+ /* Nothing to do */
+ break;
+
+ default:
+ HRETURN_ERROR(H5E_ARGS, H5E_BADRANGE, NULL,
+ "unknown property list class");
}
FUNC_LEAVE (dst);
diff --git a/src/H5S.c b/src/H5S.c
index 95f7338..65a45ff 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -20,6 +20,7 @@ static char RcsId[] = "@(#)$Revision$";
#include <H5private.h> /* Generic Functions */
#include <H5Iprivate.h> /* ID Functions */
#include <H5Eprivate.h> /* Error handling */
+#include <H5FLprivate.h> /* Free Lists */
#include <H5MMprivate.h> /* Memory Management functions */
#include <H5Oprivate.h> /* object headers */
#include <H5Sprivate.h> /* Data-space functions */
@@ -44,6 +45,18 @@ static size_t H5S_nconv_g = 0; /*entries used*/
hbool_t H5_mpi_opt_types_g = FALSE;
#endif
+/* Declare a free list to manage the H5S_simple_t struct */
+H5FL_DEFINE(H5S_simple_t);
+
+/* Declare a free list to manage the H5S_t struct */
+H5FL_DEFINE(H5S_t);
+
+/* Declare a free list to manage the array's of hsize_t's */
+H5FL_ARR_DEFINE(hsize_t,H5S_MAX_RANK);
+
+/* Declare a free list to manage the array's of hssize_t's */
+H5FL_ARR_DEFINE(hssize_t,H5S_MAX_RANK);
+
/*--------------------------------------------------------------------------
NAME
@@ -327,7 +340,7 @@ H5S_create(H5S_class_t type)
FUNC_ENTER(H5S_create, NULL);
/* Create a new data space */
- if((ret_value = H5MM_calloc(sizeof(H5S_t)))!=NULL)
+ if((ret_value = H5FL_ALLOC(H5S_t,1))!=NULL)
{
ret_value->extent.type = type;
ret_value->select.type = H5S_SEL_ALL; /* Entire extent selected by default */
@@ -455,7 +468,7 @@ H5S_close(H5S_t *ds)
/* If there was a previous offset for the selection, release it */
if(ds->select.offset!=NULL)
- ds->select.offset=H5MM_xfree(ds->select.offset);
+ ds->select.offset=H5FL_ARR_FREE(hssize_t,ds->select.offset);
/* Release selection (this should come before the extent release) */
H5S_select_release(ds);
@@ -464,7 +477,7 @@ H5S_close(H5S_t *ds)
H5S_extent_release(ds);
/* Release the main structure */
- H5MM_xfree(ds);
+ H5FL_FREE(H5S_t,ds);
FUNC_LEAVE(SUCCEED);
}
@@ -526,9 +539,13 @@ H5S_release_simple(H5S_simple_t *simple)
assert(simple);
if(simple->size)
- H5MM_xfree(simple->size);
+ H5FL_ARR_FREE(hsize_t,simple->size);
if(simple->max)
- H5MM_xfree(simple->max);
+ H5FL_ARR_FREE(hsize_t,simple->max);
+#ifdef LATER
+ if(simple->perm)
+ H5FL_ARR_FREE(hsize_t,simple->perm);
+#endif /* LATER */
FUNC_LEAVE(SUCCEED);
}
@@ -649,15 +666,13 @@ H5S_extent_copy(H5S_extent_t *dst, const H5S_extent_t *src)
case H5S_SIMPLE:
if (src->u.simple.size) {
- dst->u.simple.size = H5MM_malloc(src->u.simple.rank *
- sizeof(src->u.simple.size[0]));
+ dst->u.simple.size = H5FL_ARR_ALLOC(hsize_t,src->u.simple.rank,0);
for (i = 0; i < src->u.simple.rank; i++) {
dst->u.simple.size[i] = src->u.simple.size[i];
}
}
if (src->u.simple.max) {
- dst->u.simple.max = H5MM_malloc(src->u.simple.rank *
- sizeof(src->u.simple.max[0]));
+ dst->u.simple.max = H5FL_ARR_ALLOC(hsize_t,src->u.simple.rank,0);
for (i = 0; i < src->u.simple.rank; i++) {
dst->u.simple.max[i] = src->u.simple.max[i];
}
@@ -700,7 +715,7 @@ H5S_copy(const H5S_t *src)
FUNC_ENTER(H5S_copy, NULL);
- if (NULL==(dst = H5MM_malloc(sizeof(H5S_t)))) {
+ if (NULL==(dst = H5FL_ALLOC(H5S_t,0))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
}
*dst = *src;
@@ -1132,7 +1147,7 @@ H5S_read(H5G_entry_t *ent)
/* check args */
assert(ent);
- if (NULL==(ds = H5MM_calloc(sizeof(H5S_t)))) {
+ if (NULL==(ds = H5FL_ALLOC(H5S_t,1))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -1147,7 +1162,7 @@ H5S_read(H5G_entry_t *ent)
ds->select.type=H5S_SEL_ALL;
/* Allocate space for the offset and set it to zeros */
- if (NULL==(ds->select.offset = H5MM_calloc(ds->extent.u.simple.rank*sizeof(hssize_t)))) {
+ if (NULL==(ds->select.offset = H5FL_ARR_ALLOC(hssize_t,ds->extent.u.simple.rank,1))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
}
@@ -1397,10 +1412,10 @@ H5S_set_extent_simple (H5S_t *space, int rank, const hsize_t *dims,
/* If there was a previous offset for the selection, release it */
if(space->select.offset!=NULL)
- space->select.offset=H5MM_xfree(space->select.offset);
+ space->select.offset=H5FL_ARR_FREE(hssize_t,space->select.offset);
/* Allocate space for the offset and set it to zeros */
- if (NULL==(space->select.offset = H5MM_calloc(rank*sizeof(hssize_t)))) {
+ if (NULL==(space->select.offset = H5FL_ARR_ALLOC(hssize_t,rank,1))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
@@ -1435,12 +1450,12 @@ H5S_set_extent_simple (H5S_t *space, int rank, const hsize_t *dims,
/* Set the rank and copy the dims */
space->extent.u.simple.rank = rank;
- space->extent.u.simple.size = H5MM_malloc(rank*sizeof(hsize_t));
+ space->extent.u.simple.size = H5FL_ARR_ALLOC(hsize_t,rank,0);
HDmemcpy(space->extent.u.simple.size, dims, sizeof(hsize_t) * rank);
/* Copy the maximum dimensions if specified */
if(max!=NULL) {
- space->extent.u.simple.max = H5MM_malloc(rank*sizeof(hsize_t));
+ space->extent.u.simple.max = H5FL_ARR_ALLOC(hsize_t,rank,0);
HDmemcpy(space->extent.u.simple.max, max, sizeof(hsize_t) * rank);
} /* end if */
}
@@ -1807,7 +1822,7 @@ H5Soffset_simple(hid_t space_id, const hssize_t *offset)
/* Allocate space for new offset */
if(space->select.offset==NULL) {
- if (NULL==(space->select.offset = H5MM_malloc(sizeof(hssize_t)*space->extent.u.simple.rank))) {
+ if (NULL==(space->select.offset = H5FL_ARR_ALLOC(hssize_t,space->extent.u.simple.rank,0))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
diff --git a/src/H5Sall.c b/src/H5Sall.c
index 525e9e2..d7b2c2d 100644
--- a/src/H5Sall.c
+++ b/src/H5Sall.c
@@ -43,6 +43,7 @@ static size_t H5S_all_mgath (const void *_buf, size_t elmt_size,
static herr_t H5S_all_mscat (const void *_tconv_buf, size_t elmt_size,
const H5S_t *mem_space, H5S_sel_iter_t *mem_iter,
size_t nelmts, void *_buf/*out*/);
+static herr_t H5S_select_all(H5S_t *space);
const H5S_fconv_t H5S_ALL_FCONV[1] = {{
"all", /*name */
@@ -931,6 +932,84 @@ H5S_all_bounds(H5S_t *space, hsize_t *start, hsize_t *end)
/*--------------------------------------------------------------------------
NAME
+ H5S_select_all
+ PURPOSE
+ Specify the the entire extent is selected
+ USAGE
+ herr_t H5S_select_all(dsid)
+ hid_t dsid; IN: Dataspace ID of selection to modify
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ This function selects the entire extent for a dataspace.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t H5S_select_all (H5S_t *space)
+{
+ herr_t ret_value=SUCCEED; /* return value */
+
+ FUNC_ENTER (H5S_select_all, FAIL);
+
+ /* Check args */
+ assert(space);
+
+ /* Remove current selection first */
+ if(H5S_select_release(space)<0) {
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection");
+ } /* end if */
+
+ /* Set selection type */
+ space->select.type=H5S_SEL_ALL;
+
+done:
+ FUNC_LEAVE (ret_value);
+} /* H5S_select_all() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Sselect_all
+ PURPOSE
+ Specify the the entire extent is selected
+ USAGE
+ herr_t H5Sselect_all(dsid)
+ hid_t dsid; IN: Dataspace ID of selection to modify
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ This function selects the entire extent for a dataspace.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t H5Sselect_all (hid_t spaceid)
+{
+ H5S_t *space = NULL; /* Dataspace to modify selection of */
+ herr_t ret_value=SUCCEED; /* return value */
+
+ FUNC_ENTER (H5Sselect_all, FAIL);
+
+ /* Check args */
+ if (H5I_DATASPACE != H5I_get_type(spaceid) || NULL == (space=H5I_object(spaceid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+ }
+
+ /* Remove current selection first */
+ if((ret_value=H5S_select_all(space))<0) {
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection");
+ } /* end if */
+
+done:
+ FUNC_LEAVE (ret_value);
+} /* H5Sselect_all() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_all_select_iterate
PURPOSE
Iterate over a "all" selection, calling a user's function for each
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index 5be59dc..554f59c 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -10,11 +10,11 @@
#include <H5private.h>
#include <H5Dprivate.h>
#include <H5Eprivate.h>
+#include <H5FLprivate.h> /*Free Lists */
#include <H5Iprivate.h>
#include <H5MMprivate.h>
#include <H5Pprivate.h>
#include <H5Sprivate.h>
-#include <H5TBprivate.h>
#include <H5Vprivate.h>
/* Interface initialization */
@@ -62,9 +62,8 @@ typedef struct {
/* Static function prototypes */
static intn H5S_hyper_bsearch(hssize_t size, H5S_hyper_bound_t *barr,
size_t count);
-static hid_t
-H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
- H5S_hyper_bound_t **lo_bounds,
+static H5S_hyper_region_t * H5S_hyper_get_regions (size_t *num_regions,
+ intn dim, size_t bound_count, H5S_hyper_bound_t **lo_bounds,
H5S_hyper_bound_t **hi_bounds, hssize_t *pos,
hssize_t *offset);
static size_t H5S_hyper_fread (intn dim, H5S_hyper_io_info_t *io_info);
@@ -117,6 +116,31 @@ const H5S_mconv_t H5S_HYPER_MCONV[1] = {{
/* Array for use with I/O algorithms which frequently need array of zeros */
static const hssize_t zero[H5O_LAYOUT_NDIMS]={0}; /* Array of zeros */
+/* Declare a free list to manage the H5S_hyper_node_t struct */
+H5FL_DEFINE_STATIC(H5S_hyper_node_t);
+
+/* Declare a free list to manage the H5S_hyper_list_t struct */
+H5FL_DEFINE_STATIC(H5S_hyper_list_t);
+
+/* Declare a free list to manage arrays of hsize_t */
+H5FL_ARR_DEFINE_STATIC(hsize_t,H5S_MAX_RANK);
+
+typedef H5S_hyper_bound_t *H5S_hyper_bound_ptr_t;
+/* Declare a free list to manage arrays of H5S_hyper_bound_ptr_t */
+H5FL_ARR_DEFINE_STATIC(H5S_hyper_bound_ptr_t,H5S_MAX_RANK);
+
+/* Declare a free list to manage arrays of H5S_hyper_dim_t */
+H5FL_ARR_DEFINE_STATIC(H5S_hyper_dim_t,H5S_MAX_RANK);
+
+/* Declare a free list to manage arrays of H5S_hyper_bound_t */
+H5FL_ARR_DEFINE_STATIC(H5S_hyper_bound_t,-1);
+
+/* Declare a free list to manage arrays of H5S_hyper_region_t */
+H5FL_ARR_DEFINE_STATIC(H5S_hyper_region_t,-1);
+
+/* Declare a free list to manage blocks of hyperslab data */
+H5FL_BLK_DEFINE_STATIC(hyper_block);
+
/*-------------------------------------------------------------------------
* Function: H5S_hyper_init
@@ -147,7 +171,7 @@ H5S_hyper_init (const struct H5O_layout_t UNUSED *layout,
sel_iter->hyp.elmt_left=space->select.num_elem;
/* Allocate the position & initialize to invalid location */
- sel_iter->hyp.pos = H5MM_malloc(space->extent.u.simple.rank * sizeof(hssize_t));
+ sel_iter->hyp.pos = H5FL_ARR_ALLOC(hsize_t,space->extent.u.simple.rank,0);
sel_iter->hyp.pos[0]=(-1);
H5V_array_fill(sel_iter->hyp.pos, sel_iter->hyp.pos, sizeof(hssize_t),
space->extent.u.simple.rank);
@@ -229,12 +253,12 @@ H5S_hyper_compare_regions (const void *r1, const void *r2)
*
*-------------------------------------------------------------------------
*/
-static hid_t
+static H5S_hyper_region_t *
H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
H5S_hyper_bound_t **lo_bounds, H5S_hyper_bound_t **hi_bounds, hssize_t *pos,
hssize_t *offset)
{
- hid_t ret_value=FAIL; /* Id of temporary buffer to return */
+ H5S_hyper_region_t *ret_value=NULL; /* Pointer to array of regions to return */
H5S_hyper_region_t *reg=NULL; /* Pointer to array of regions */
H5S_hyper_node_t *node; /* Region node for a given boundary */
size_t num_reg=0; /* Number of regions in array */
@@ -244,7 +268,7 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
intn temp_dim; /* Temporary dim. holder */
size_t i; /* Counters */
- FUNC_ENTER (H5S_hyper_get_regions, FAIL);
+ FUNC_ENTER (H5S_hyper_get_regions, NULL);
assert(num_regions);
assert(lo_bounds);
@@ -271,7 +295,7 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
/* Check if we've allocated the array yet */
if(num_reg==0) {
/* Allocate temporary buffer */
- ret_value=H5TB_get_buf(sizeof(H5S_hyper_region_t),0,(void **)&reg);
+ reg=H5FL_ARR_ALLOC(H5S_hyper_region_t,1,0);
/* Initialize with first region */
reg[0].start=MAX(lo_bounds[0][i].bound,pos[0])+offset[0];
@@ -294,7 +318,7 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
hi_bounds[0][i].bound!=reg[curr_reg].end) {
/* Enlarge array */
- H5TB_resize_buf(ret_value,(sizeof(H5S_hyper_region_t)*(num_reg+1)),(void **)&reg);
+ reg=H5FL_ARR_REALLOC(H5S_hyper_region_t,reg,num_reg+1);
/* Initialize with new region */
reg[num_reg].start=lo_bounds[0][i].bound+offset[0];
@@ -360,7 +384,7 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
printf("%s: check 3.1\n", FUNC);
#endif /* QAK */
/* Allocate temporary buffer */
- ret_value=H5TB_get_buf(sizeof(H5S_hyper_region_t),0,(void **)&reg);
+ reg=H5FL_ARR_ALLOC(H5S_hyper_region_t,1,0);
/* Initialize with first region */
reg[0].start=MAX(node->start[next_dim],pos[next_dim])+offset[next_dim];
@@ -387,7 +411,7 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
(int)reg[curr_reg].end);
#endif /* QAK */
/* Enlarge array */
- H5TB_resize_buf(ret_value,(sizeof(H5S_hyper_region_t)*(num_reg+1)),(void **)&reg);
+ reg=H5FL_ARR_REALLOC(H5S_hyper_region_t,reg,num_reg+1);
/* Initialize with new region */
reg[num_reg].start=node->start[next_dim]+offset[next_dim];
@@ -421,6 +445,9 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
/* Save the number of regions we generated */
*num_regions=num_reg;
+ /* Set return value */
+ ret_value=reg;
+
#ifdef QAK
printf("%s: check 10.0, reg=%p, num_reg=%d\n",
FUNC,reg,num_reg);
@@ -460,7 +487,7 @@ H5S_hyper_block_cache (H5S_hyper_node_t *node,
assert(io_info);
/* Allocate temporary buffer of proper size */
- if((node->cinfo.block_id=H5TB_get_buf(node->cinfo.size*io_info->elmt_size,1,(void **)&(node->cinfo.block)))<0)
+ if((node->cinfo.block=H5FL_BLK_ALLOC(hyper_block,node->cinfo.size*io_info->elmt_size,0))==NULL)
HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"can't allocate hyperslab cache block");
@@ -534,7 +561,7 @@ H5S_hyper_block_read (H5S_hyper_node_t *node, H5S_hyper_io_info_t *io_info, hsiz
/* If we've read in all the elements from the block, throw it away */
if(node->cinfo.rleft==0 && (node->cinfo.wleft==0 || node->cinfo.wleft==node->cinfo.size)) {
/* Release the temporary buffer */
- H5TB_release_buf(node->cinfo.block_id);
+ H5FL_BLK_FREE(hyper_block,node->cinfo.block);
/* Reset the caching flag for next time */
node->cinfo.cached=0;
@@ -603,7 +630,7 @@ H5S_hyper_block_write (H5S_hyper_node_t *node,
HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error");
/* Release the temporary buffer */
- H5TB_release_buf(node->cinfo.block_id);
+ H5FL_BLK_FREE(hyper_block,node->cinfo.block);
/* Reset the caching flag for next time */
node->cinfo.cached=0;
@@ -634,7 +661,6 @@ H5S_hyper_fread (intn dim, H5S_hyper_io_info_t *io_info)
{
hsize_t region_size; /* Size of lowest region */
uintn parm_init=0; /* Whether one-shot parameters set up */
- hid_t reg_id; /* ID of temporary region buffer */
H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */
size_t num_regions; /* number of regions overlapped */
size_t i; /* Counters */
@@ -658,15 +684,12 @@ H5S_hyper_fread (intn dim, H5S_hyper_io_info_t *io_info)
/* Get a sorted list (in the next dimension down) of the regions which */
/* overlap the current index in this dim */
- if((reg_id=H5S_hyper_get_regions(&num_regions,dim,
+ if((regions=H5S_hyper_get_regions(&num_regions,dim,
io_info->space->select.sel_info.hslab.hyper_lst->count,
io_info->lo_bounds, io_info->hi_bounds,
- io_info->iter->hyp.pos,io_info->space->select.offset))>=0) {
+ io_info->iter->hyp.pos,io_info->space->select.offset))!=NULL) {
- /* Get the pointer to the actual regions array */
- regions=H5TB_buf_ptr(reg_id);
-
- /*
+ /*
* Check if this is the second to last dimension in dataset (Which
* means that we've got a list of the regions in the fastest changing
* dimension and should input those regions).
@@ -790,7 +813,7 @@ H5S_hyper_fread (intn dim, H5S_hyper_io_info_t *io_info)
} /* end else */
/* Release the temporary buffer */
- H5TB_release_buf(reg_id);
+ H5FL_ARR_FREE(H5S_hyper_region_t,regions);
} /* end if */
FUNC_LEAVE (num_read);
@@ -829,11 +852,12 @@ H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout,
const H5S_t *file_space, H5S_sel_iter_t *file_iter,
size_t nelmts, hid_t dxpl_id, void *_buf/*out*/)
{
- H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */
- H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */
+ H5S_hyper_bound_t **lo_bounds=NULL; /* Lower (closest to the origin) bound array for each dimension */
+ H5S_hyper_bound_t **hi_bounds=NULL; /* Upper (farthest from the origin) bound array for each dimension */
H5S_hyper_io_info_t io_info; /* Block of parameters to pass into recursive calls */
intn i; /*counters */
- size_t num_read; /* number of elements read into buffer */
+ size_t num_read=0; /* number of elements read into buffer */
+ herr_t ret_value=SUCCEED;
FUNC_ENTER (H5S_hyper_fgath, 0);
@@ -850,10 +874,10 @@ H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout,
printf("%s: check 1.0\n", FUNC);
#endif /* QAK */
/* Allocate space for the low & high bound arrays */
- lo_bounds = H5MM_malloc(file_space->extent.u.simple.rank *
- sizeof(H5S_hyper_bound_t *));
- hi_bounds = H5MM_malloc(file_space->extent.u.simple.rank *
- sizeof(H5S_hyper_bound_t *));
+ if((lo_bounds=H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,file_space->extent.u.simple.rank,0))==NULL)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
+ if((hi_bounds=H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,file_space->extent.u.simple.rank,0))==NULL)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
/* Initialize to correct order to walk through arrays.
(When another iteration order besides the default 'C' order is chosen,
@@ -896,12 +920,16 @@ H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout,
printf("%s: check 5.0, num_read=%d\n",FUNC,(int)num_read);
#endif /* QAK */
+done:
/* Release the memory we allocated */
- H5MM_xfree(lo_bounds);
- H5MM_xfree(hi_bounds);
+ if (lo_bounds)
+ H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,lo_bounds);
+ if (hi_bounds)
+ H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,hi_bounds);
- FUNC_LEAVE (num_read);
+ FUNC_LEAVE (ret_value==SUCCEED ? num_read : 0);
} /* H5S_hyper_fgath() */
+
/*-------------------------------------------------------------------------
* Function: H5S_hyper_fwrite
@@ -925,7 +953,6 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_io_info_t *io_info)
{
hsize_t region_size; /* Size of lowest region */
uintn parm_init=0; /* Whether one-shot parameters set up */
- hid_t reg_id; /* ID of temporary region buffer */
H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */
size_t num_regions; /* number of regions overlapped */
size_t i; /* Counters */
@@ -948,13 +975,11 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_io_info_t *io_info)
#endif /* QAK */
/* Get a sorted list (in the next dimension down) of the regions which */
/* overlap the current index in this dim */
- if((reg_id=H5S_hyper_get_regions(&num_regions,dim,
+ if((regions=H5S_hyper_get_regions(&num_regions,dim,
io_info->space->select.sel_info.hslab.hyper_lst->count,
io_info->lo_bounds, io_info->hi_bounds,
- io_info->iter->hyp.pos,io_info->space->select.offset))>=0) {
+ io_info->iter->hyp.pos,io_info->space->select.offset))!=NULL) {
- /* Get the pointer to the actual regions array */
- regions=H5TB_buf_ptr(reg_id);
#ifdef QAK
printf("%s: check 1.1, regions=%p\n", FUNC,regions);
printf("%s: check 1.2, rank=%d\n",
@@ -1056,7 +1081,7 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_io_info_t *io_info)
} /* end else */
/* Release the temporary buffer */
- H5TB_release_buf(reg_id);
+ H5FL_ARR_FREE(H5S_hyper_region_t,regions);
} /* end if */
#ifdef QAK
@@ -1093,11 +1118,12 @@ H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout,
const H5S_t *file_space, H5S_sel_iter_t *file_iter,
size_t nelmts, hid_t dxpl_id, const void *_buf)
{
- H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */
- H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */
+ H5S_hyper_bound_t **lo_bounds=NULL; /* Lower (closest to the origin) bound array for each dimension */
+ H5S_hyper_bound_t **hi_bounds=NULL; /* Upper (farthest from the origin) bound array for each dimension */
H5S_hyper_io_info_t io_info; /* Block of parameters to pass into recursive calls */
intn i; /*counters */
- size_t num_written; /* number of elements read into buffer */
+ size_t num_written=0; /* number of elements read into buffer */
+ herr_t ret_value=SUCCEED;
FUNC_ENTER (H5S_hyper_fscat, 0);
@@ -1114,10 +1140,11 @@ H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout,
printf("%s: check 1.0\n", FUNC);
#endif /* QAK */
/* Allocate space for the low & high bound arrays */
- lo_bounds = H5MM_malloc(file_space->extent.u.simple.rank *
- sizeof(H5S_hyper_bound_t *));
- hi_bounds = H5MM_malloc(file_space->extent.u.simple.rank *
- sizeof(H5S_hyper_bound_t *));
+ if((lo_bounds=H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,file_space->extent.u.simple.rank,0))==NULL)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for low bounds");
+
+ if((hi_bounds=H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,file_space->extent.u.simple.rank,0))==NULL)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for high bounds");
/*
* Initialize to correct order to walk through arrays. (When another
@@ -1155,15 +1182,19 @@ H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout,
/* starting with the slowest changing dimension */
num_written=H5S_hyper_fwrite(-1,&io_info);
- /* Release the memory we allocated */
- H5MM_xfree(lo_bounds);
- H5MM_xfree(hi_bounds);
+done:
+ /* Release the memory we allocated back to the free list*/
+ if (lo_bounds)
+ H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,lo_bounds);
+ if (hi_bounds)
+ H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,hi_bounds);
#ifdef QAK
printf("%s: check 2.0\n", FUNC);
#endif /* QAK */
- FUNC_LEAVE (num_written >0 ? SUCCEED : FAIL);
+ FUNC_LEAVE (ret_value==FAIL ? ret_value : (num_written >0) ? SUCCEED : FAIL);
} /* H5S_hyper_fscat() */
+
/*-------------------------------------------------------------------------
* Function: H5S_hyper_mread
@@ -1186,7 +1217,6 @@ static size_t
H5S_hyper_mread (intn dim, H5S_hyper_io_info_t *io_info)
{
hsize_t region_size; /* Size of lowest region */
- hid_t reg_id; /* ID of temporary region buffer */
H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */
size_t num_regions; /* number of regions overlapped */
size_t i; /* Counters */
@@ -1203,13 +1233,10 @@ H5S_hyper_mread (intn dim, H5S_hyper_io_info_t *io_info)
/* Get a sorted list (in the next dimension down) of the regions which */
/* overlap the current index in this dim */
- if((reg_id=H5S_hyper_get_regions(&num_regions,dim,
+ if((regions=H5S_hyper_get_regions(&num_regions,dim,
io_info->space->select.sel_info.hslab.hyper_lst->count,
io_info->lo_bounds, io_info->hi_bounds,
- io_info->iter->hyp.pos,io_info->space->select.offset))>=0) {
-
- /* Get the pointer to the actual regions array */
- regions=H5TB_buf_ptr(reg_id);
+ io_info->iter->hyp.pos,io_info->space->select.offset))!=NULL) {
/* Check if this is the second to last dimension in dataset */
/* (Which means that we've got a list of the regions in the fastest */
@@ -1303,11 +1330,12 @@ H5S_hyper_mread (intn dim, H5S_hyper_io_info_t *io_info)
} /* end else */
/* Release the temporary buffer */
- H5TB_release_buf(reg_id);
+ H5FL_ARR_FREE(H5S_hyper_region_t,regions);
} /* end if */
FUNC_LEAVE (num_read);
} /* H5S_hyper_mread() */
+
/*-------------------------------------------------------------------------
* Function: H5S_hyper_mgath
@@ -1366,10 +1394,8 @@ H5S_hyper_mgath (const void *_buf, size_t elmt_size,
#endif /* QAK */
/* Allocate space for the low & high bound arrays */
- lo_bounds = H5MM_malloc(mem_space->extent.u.simple.rank *
- sizeof(H5S_hyper_bound_t *));
- hi_bounds = H5MM_malloc(mem_space->extent.u.simple.rank *
- sizeof(H5S_hyper_bound_t *));
+ lo_bounds = H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,mem_space->extent.u.simple.rank,0);
+ hi_bounds = H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,mem_space->extent.u.simple.rank,0);
/*
* Initialize to correct order to walk through arrays. (When another
@@ -1423,8 +1449,8 @@ H5S_hyper_mgath (const void *_buf, size_t elmt_size,
#endif /* QAK */
/* Release the memory we allocated */
- H5MM_xfree(lo_bounds);
- H5MM_xfree(hi_bounds);
+ H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,lo_bounds);
+ H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,hi_bounds);
FUNC_LEAVE (num_read);
} /* H5S_hyper_mgath() */
@@ -1450,7 +1476,6 @@ static size_t
H5S_hyper_mwrite (intn dim, H5S_hyper_io_info_t *io_info)
{
hsize_t region_size; /* Size of lowest region */
- hid_t reg_id; /* ID of temporary region buffer */
H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */
size_t num_regions; /* number of regions overlapped */
size_t i; /* Counters */
@@ -1466,13 +1491,10 @@ H5S_hyper_mwrite (intn dim, H5S_hyper_io_info_t *io_info)
/* Get a sorted list (in the next dimension down) of the regions which */
/* overlap the current index in this dim */
- if((reg_id=H5S_hyper_get_regions(&num_regions,dim,
+ if((regions=H5S_hyper_get_regions(&num_regions,dim,
io_info->space->select.sel_info.hslab.hyper_lst->count,
io_info->lo_bounds, io_info->hi_bounds,
- io_info->iter->hyp.pos,io_info->space->select.offset))>=0) {
-
- /* Get the pointer to the actual regions array */
- regions=H5TB_buf_ptr(reg_id);
+ io_info->iter->hyp.pos,io_info->space->select.offset))!=NULL) {
#ifdef QAK
printf("%s: check 2.0, rank=%d\n",
@@ -1568,11 +1590,12 @@ H5S_hyper_mwrite (intn dim, H5S_hyper_io_info_t *io_info)
} /* end else */
/* Release the temporary buffer */
- H5TB_release_buf(reg_id);
+ H5FL_ARR_FREE(H5S_hyper_region_t,regions);
} /* end if */
FUNC_LEAVE (num_read);
} /* H5S_hyper_mwrite() */
+
/*-------------------------------------------------------------------------
* Function: H5S_hyper_mscat
@@ -1613,10 +1636,8 @@ H5S_hyper_mscat (const void *_tconv_buf, size_t elmt_size,
assert (_tconv_buf);
/* Allocate space for the low & high bound arrays */
- lo_bounds = H5MM_malloc(mem_space->extent.u.simple.rank *
- sizeof(H5S_hyper_bound_t *));
- hi_bounds = H5MM_malloc(mem_space->extent.u.simple.rank *
- sizeof(H5S_hyper_bound_t *));
+ lo_bounds = H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,mem_space->extent.u.simple.rank,0);
+ hi_bounds = H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,mem_space->extent.u.simple.rank,0);
/*
* Initialize to correct order to walk through arrays. (When another
@@ -1659,11 +1680,12 @@ H5S_hyper_mscat (const void *_tconv_buf, size_t elmt_size,
#endif /* QAK */
/* Release the memory we allocated */
- H5MM_xfree(lo_bounds);
- H5MM_xfree(hi_bounds);
+ H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,lo_bounds);
+ H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,hi_bounds);
FUNC_LEAVE (num_read>0 ? SUCCEED : FAIL);
} /* H5S_hyper_mscat() */
+
/*--------------------------------------------------------------------------
NAME
@@ -1760,11 +1782,11 @@ H5S_hyper_node_add (H5S_hyper_node_t **head, intn endflag, intn rank, const hssi
assert (size);
/* Create new hyperslab node to insert */
- if((slab = H5MM_malloc(sizeof(H5S_hyper_node_t)))==NULL)
+ if((slab = H5FL_ALLOC(H5S_hyper_node_t,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab node");
- if((slab->start = H5MM_malloc(sizeof(hsize_t)* rank))==NULL)
+ if((slab->start = H5FL_ARR_ALLOC(hsize_t,rank,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab start boundary");
- if((slab->end = H5MM_malloc(sizeof(hsize_t)* rank))==NULL)
+ if((slab->end = H5FL_ARR_ALLOC(hsize_t,rank,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab end boundary");
/* Set boundary on new node */
@@ -1848,9 +1870,9 @@ H5S_hyper_node_release (H5S_hyper_node_t *node)
assert (node);
/* Free the hyperslab node */
- node->start = H5MM_xfree(node->start);
- node->end = H5MM_xfree(node->end);
- H5MM_xfree(node);
+ H5FL_ARR_FREE(hsize_t,node->start);
+ H5FL_ARR_FREE(hsize_t,node->end);
+ H5FL_FREE(H5S_hyper_node_t,node);
FUNC_LEAVE (ret_value);
} /* H5S_hyper_node_release() */
@@ -1896,11 +1918,11 @@ H5S_hyper_add (H5S_t *space, const hssize_t *start, const hsize_t *end)
printf("%s: check 1.0\n",FUNC);
#endif /* QAK */
/* Create new hyperslab node to insert */
- if((slab = H5MM_malloc(sizeof(H5S_hyper_node_t)))==NULL)
+ if((slab = H5FL_ALLOC(H5S_hyper_node_t,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab node");
- if((slab->start = H5MM_malloc(sizeof(hsize_t)*space->extent.u.simple.rank))==NULL)
+ if((slab->start = H5FL_ARR_ALLOC(hsize_t,space->extent.u.simple.rank,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab start boundary");
- if((slab->end = H5MM_malloc(sizeof(hsize_t)*space->extent.u.simple.rank))==NULL)
+ if((slab->end = H5FL_ARR_ALLOC(hsize_t,space->extent.u.simple.rank,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab end boundary");
#ifdef QAK
@@ -1921,7 +1943,6 @@ H5S_hyper_add (H5S_t *space, const hssize_t *start, const hsize_t *end)
slab->cinfo.cached=0;
slab->cinfo.size=elem_count;
slab->cinfo.wleft=slab->cinfo.rleft=0;
- slab->cinfo.block_id=(-1);
slab->cinfo.block=slab->cinfo.wpos=slab->cinfo.rpos=NULL;
#ifdef QAK
@@ -1935,7 +1956,7 @@ H5S_hyper_add (H5S_t *space, const hssize_t *start, const hsize_t *end)
#ifdef QAK
printf("%s: check 3.1, i=%d, space->sel_info.count=%d, tmp=%p\n",FUNC,(int)i, space->select.sel_info.hslab.hyper_lst->count,tmp);
#endif /* QAK */
- if((space->select.sel_info.hslab.hyper_lst->lo_bounds[i]=H5MM_realloc(tmp,sizeof(H5S_hyper_bound_t)*(space->select.sel_info.hslab.hyper_lst->count+1)))==NULL) {
+ if((space->select.sel_info.hslab.hyper_lst->lo_bounds[i]=H5FL_ARR_REALLOC(H5S_hyper_bound_t,tmp,(space->select.sel_info.hslab.hyper_lst->count+1)))==NULL) {
space->select.sel_info.hslab.hyper_lst->lo_bounds[i]=tmp;
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"can't allocate hyperslab lo boundary array");
@@ -1944,7 +1965,7 @@ H5S_hyper_add (H5S_t *space, const hssize_t *start, const hsize_t *end)
printf("%s: check 3.2, i=%d\n",FUNC,(int)i);
#endif /* QAK */
tmp=space->select.sel_info.hslab.hyper_lst->hi_bounds[i];
- if((space->select.sel_info.hslab.hyper_lst->hi_bounds[i]=H5MM_realloc(tmp,sizeof(H5S_hyper_bound_t)*(space->select.sel_info.hslab.hyper_lst->count+1)))==NULL) {
+ if((space->select.sel_info.hslab.hyper_lst->hi_bounds[i]=H5FL_ARR_REALLOC(H5S_hyper_bound_t,tmp,(space->select.sel_info.hslab.hyper_lst->count+1)))==NULL) {
space->select.sel_info.hslab.hyper_lst->hi_bounds[i]=tmp;
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"can't allocate hyperslab hi boundary array");
@@ -2142,7 +2163,7 @@ H5S_hyper_clip (H5S_t *space, H5S_hyper_node_t *nodes, H5S_hyper_node_t **uniq,
H5S_hyper_node_t *region, /* Temp. hyperslab selection region pointer */
*node, /* Temp. hyperslab node pointer */
*next_node; /* Pointer to next node in node list */
- hssize_t *start; /* Temporary arrays of start & sizes (for splitting nodes) */
+ hssize_t *start=NULL; /* Temporary arrays of start & sizes (for splitting nodes) */
hsize_t *end=NULL; /* Temporary arrays of start & sizes (for splitting nodes) */
intn rank; /* Cached copy of the rank of the dataspace */
intn overlapped; /* Flag for overlapping nodes */
@@ -2160,9 +2181,9 @@ H5S_hyper_clip (H5S_t *space, H5S_hyper_node_t *nodes, H5S_hyper_node_t **uniq,
assert (uniq || overlap);
/* Allocate space for the temporary starts & sizes */
- if((start = H5MM_malloc(sizeof(hssize_t)*space->extent.u.simple.rank))==NULL)
+ if((start = H5FL_ARR_ALLOC(hsize_t,space->extent.u.simple.rank,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab start array");
- if((end = H5MM_malloc(sizeof(hsize_t)*space->extent.u.simple.rank))==NULL)
+ if((end = H5FL_ARR_ALLOC(hsize_t,space->extent.u.simple.rank,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab size array");
/* Set up local variables */
@@ -2304,9 +2325,9 @@ H5S_hyper_clip (H5S_t *space, H5S_hyper_node_t *nodes, H5S_hyper_node_t **uniq,
done:
if(start!=NULL)
- H5MM_xfree(start);
+ H5FL_ARR_FREE(hsize_t,start);
if(end!=NULL)
- H5MM_xfree(end);
+ H5FL_ARR_FREE(hsize_t,end);
FUNC_LEAVE (ret_value);
} /* H5S_hyper_clip() */
@@ -2352,19 +2373,19 @@ H5S_hyper_release (H5S_t *space)
/* Release the per-dimension selection info */
if(space->select.sel_info.hslab.diminfo!=NULL)
- H5MM_xfree(space->select.sel_info.hslab.diminfo);
+ H5FL_ARR_FREE(H5S_hyper_dim_t,space->select.sel_info.hslab.diminfo);
space->select.sel_info.hslab.diminfo = NULL;
/* Release hi and lo boundary information */
for(i=0; i<space->extent.u.simple.rank; i++) {
- H5MM_xfree(space->select.sel_info.hslab.hyper_lst->lo_bounds[i]);
+ H5FL_ARR_FREE(H5S_hyper_bound_t,space->select.sel_info.hslab.hyper_lst->lo_bounds[i]);
space->select.sel_info.hslab.hyper_lst->lo_bounds[i] = NULL;
- H5MM_xfree(space->select.sel_info.hslab.hyper_lst->hi_bounds[i]);
+ H5FL_ARR_FREE(H5S_hyper_bound_t,space->select.sel_info.hslab.hyper_lst->hi_bounds[i]);
space->select.sel_info.hslab.hyper_lst->hi_bounds[i] = NULL;
} /* end for */
- H5MM_xfree(space->select.sel_info.hslab.hyper_lst->lo_bounds);
+ H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,space->select.sel_info.hslab.hyper_lst->lo_bounds);
space->select.sel_info.hslab.hyper_lst->lo_bounds = NULL;
- H5MM_xfree(space->select.sel_info.hslab.hyper_lst->hi_bounds);
+ H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,space->select.sel_info.hslab.hyper_lst->hi_bounds);
space->select.sel_info.hslab.hyper_lst->hi_bounds = NULL;
/* Release list of selected regions */
@@ -2376,7 +2397,7 @@ H5S_hyper_release (H5S_t *space)
} /* end while */
/* Release hyperslab selection node itself */
- H5MM_xfree(space->select.sel_info.hslab.hyper_lst);
+ H5FL_FREE(H5S_hyper_list_t,space->select.sel_info.hslab.hyper_lst);
space->select.sel_info.hslab.hyper_lst=NULL;
#ifdef QAK
@@ -2441,7 +2462,7 @@ H5S_hyper_sel_iter_release (H5S_sel_iter_t *sel_iter)
assert (sel_iter);
if(sel_iter->hyp.pos!=NULL)
- H5MM_xfree(sel_iter->hyp.pos);
+ H5FL_ARR_FREE(hsize_t,sel_iter->hyp.pos);
FUNC_LEAVE (SUCCEED);
} /* H5S_hyper_sel_iter_release() */
@@ -2513,7 +2534,7 @@ H5S_hyper_copy (H5S_t *dst, const H5S_t *src)
#endif /* QAK */
if(src->select.sel_info.hslab.diminfo!=NULL) {
/* Create the per-dimension selection info */
- if((new_diminfo = H5MM_malloc(sizeof(H5S_hyper_dim_t)*src->extent.u.simple.rank))==NULL)
+ if((new_diminfo = H5FL_ARR_ALLOC(H5S_hyper_dim_t,src->extent.u.simple.rank,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate per-dimension array");
/* Copy the per-dimension selection info */
@@ -2527,7 +2548,7 @@ H5S_hyper_copy (H5S_t *dst, const H5S_t *src)
dst->select.sel_info.hslab.diminfo = new_diminfo;
/* Create the new hyperslab information node */
- if((new_hyper = H5MM_malloc(sizeof(H5S_hyper_list_t)))==NULL)
+ if((new_hyper = H5FL_ALLOC(H5S_hyper_list_t,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"can't allocate point node");
@@ -2541,17 +2562,17 @@ H5S_hyper_copy (H5S_t *dst, const H5S_t *src)
printf("%s: check 4.0\n", FUNC);
#endif /* QAK */
/* Allocate space for the low & high bound arrays */
- if((new_hyper->lo_bounds = H5MM_malloc(sizeof(H5S_hyper_bound_t *)*src->extent.u.simple.rank))==NULL)
+ if((new_hyper->lo_bounds = H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,src->extent.u.simple.rank,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"can't allocate point node");
- if((new_hyper->hi_bounds = H5MM_malloc(sizeof(H5S_hyper_bound_t *)*src->extent.u.simple.rank))==NULL)
+ if((new_hyper->hi_bounds = H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,src->extent.u.simple.rank,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"can't allocate point node");
for(i=0; i<src->extent.u.simple.rank; i++) {
- if((new_hyper->lo_bounds[i] = H5MM_malloc(sizeof(H5S_hyper_bound_t)*src->select.sel_info.hslab.hyper_lst->count))==NULL)
+ if((new_hyper->lo_bounds[i] = H5FL_ARR_ALLOC(H5S_hyper_bound_t,src->select.sel_info.hslab.hyper_lst->count,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"can't allocate point node");
- if((new_hyper->hi_bounds[i] = H5MM_malloc(sizeof(H5S_hyper_bound_t)*src->select.sel_info.hslab.hyper_lst->count))==NULL)
+ if((new_hyper->hi_bounds[i] = H5FL_ARR_ALLOC(H5S_hyper_bound_t,src->select.sel_info.hslab.hyper_lst->count,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"can't allocate point node");
} /* end for */
@@ -2568,14 +2589,14 @@ H5S_hyper_copy (H5S_t *dst, const H5S_t *src)
printf("%s: check 5.1\n", FUNC);
#endif /* QAK */
/* Create each point */
- if((new = H5MM_malloc(sizeof(H5S_hyper_node_t)))==NULL)
+ if((new = H5FL_ALLOC(H5S_hyper_node_t,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"can't allocate point node");
HDmemcpy(new,curr,sizeof(H5S_hyper_node_t)); /* copy caching information */
- if((new->start = H5MM_malloc(src->extent.u.simple.rank*sizeof(hssize_t)))==NULL)
+ if((new->start = H5FL_ARR_ALLOC(hsize_t,src->extent.u.simple.rank,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"can't allocate coordinate information");
- if((new->end = H5MM_malloc(src->extent.u.simple.rank*sizeof(hssize_t)))==NULL)
+ if((new->end = H5FL_ARR_ALLOC(hsize_t,src->extent.u.simple.rank,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"can't allocate coordinate information");
HDmemcpy(new->start,curr->start,(src->extent.u.simple.rank*sizeof(hssize_t)));
@@ -2607,10 +2628,8 @@ H5S_hyper_copy (H5S_t *dst, const H5S_t *src)
/* Sort the boundary arrays */
for(i=0; i<src->extent.u.simple.rank; i++) {
- HDqsort(new_hyper->lo_bounds[i], new_hyper->count,
- sizeof(H5S_hyper_bound_t), H5S_hyper_compare_bounds);
- HDqsort(new_hyper->hi_bounds[i], new_hyper->count,
- sizeof(H5S_hyper_bound_t), H5S_hyper_compare_bounds);
+ HDqsort(new_hyper->lo_bounds[i], new_hyper->count, sizeof(H5S_hyper_bound_t), H5S_hyper_compare_bounds);
+ HDqsort(new_hyper->hi_bounds[i], new_hyper->count, sizeof(H5S_hyper_bound_t), H5S_hyper_compare_bounds);
} /* end for */
#ifdef QAK
printf("%s: check 7.0\n", FUNC);
@@ -2837,9 +2856,9 @@ H5S_hyper_select_deserialize (H5S_t *space, const uint8_t *buf)
UINT32DECODE(buf,num_elem); /* decode the number of points */
/* Allocate space for the coordinates */
- if((start = H5MM_malloc(rank*sizeof(hssize_t)))==NULL)
+ if((start = H5FL_ARR_ALLOC(hsize_t,rank,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab information");
- if((count = H5MM_malloc(rank*sizeof(hssize_t)))==NULL)
+ if((count = H5FL_ARR_ALLOC(hsize_t,rank,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab information");
/* Retrieve the coordinates from the buffer */
@@ -2863,8 +2882,8 @@ H5S_hyper_select_deserialize (H5S_t *space, const uint8_t *buf)
} /* end for */
/* Free temporary buffers */
- H5MM_xfree(start);
- H5MM_xfree(count);
+ H5FL_ARR_FREE(hsize_t,start);
+ H5FL_ARR_FREE(hsize_t,count);
done:
FUNC_LEAVE (ret_value);
@@ -2986,6 +3005,301 @@ H5S_hyper_select_contiguous(const H5S_t *space)
/*-------------------------------------------------------------------------
+ * Function: H5S_select_hyperslab
+ *
+ * Purpose: Internal version of H5Sselect_hyperslab().
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke (split from HSselect_hyperslab()).
+ * Tuesday, August 25, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
+ const hssize_t start[/*space_id*/],
+ const hsize_t stride[/*space_id*/],
+ const hsize_t count[/*space_id*/],
+ const hsize_t block[/*space_id*/])
+{
+ hsize_t *_stride=NULL; /* Stride array */
+ hsize_t *_block=NULL; /* Block size array */
+ hssize_t slab[H5O_LAYOUT_NDIMS]; /* Location of the block to add for strided selections */
+ size_t slice[H5O_LAYOUT_NDIMS]; /* Size of preceding dimension's slice */
+ H5S_hyper_node_t *add=NULL, /* List of hyperslab nodes to add */
+ *uniq=NULL, /* List of unique hyperslab nodes */
+ *tmp; /* Temporary hyperslab node */
+ uintn acc; /* Accumulator for building slices */
+ uintn contig; /* whether selection is contiguous or not */
+ int i,j; /* Counters */
+ H5S_hyper_dim_t *diminfo; /* per-dimension info for the selection */
+ herr_t ret_value=FAIL; /* return value */
+
+ FUNC_ENTER (H5S_select_hyperslab, FAIL);
+
+ /* Check args */
+ assert(space);
+ assert(start);
+ assert(count);
+ assert(op>H5S_SELECT_NOOP && op<H5S_SELECT_INVALID);
+
+ /* Fill in the correct stride values */
+ if(stride==NULL) {
+ hssize_t fill=1;
+
+ /* Allocate temporary buffer */
+ if ((_stride=H5FL_ARR_ALLOC(hsize_t,space->extent.u.simple.rank,0))==NULL)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "memory allocation failed for stride buffer");
+ H5V_array_fill(_stride,&fill,sizeof(hssize_t),space->extent.u.simple.rank);
+ stride = _stride;
+ }
+
+ /* Fill in the correct block values */
+ if(block==NULL) {
+ hssize_t fill=1;
+
+ /* Allocate temporary buffer */
+ if ((_block=H5FL_ARR_ALLOC(hsize_t,space->extent.u.simple.rank,0))==NULL)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "memory allocation failed for stride buffer");
+ H5V_array_fill(_block,&fill,sizeof(hssize_t),space->extent.u.simple.rank);
+ block = _block;
+ }
+
+ /*
+ * Check for overlapping hyperslab blocks in new selection (remove when
+ * real block-merging algorithm is in place? -QAK).
+ */
+ if(op==H5S_SELECT_SET && block!=NULL) {
+ for(i=0; i<space->extent.u.simple.rank; i++) {
+ if(stride[i]<block[i]) {
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
+ "hyperslab blocks overlap");
+ } /* end if */
+ } /* end for */
+ } /* end if */
+
+ /* Determine if selection is contiguous */
+ /* assume hyperslab is contiguous, until proven otherwise */
+ contig=1;
+ for(i=0; i<space->extent.u.simple.rank; i++) {
+ /* contiguous hyperslabs have the block size equal to the stride */
+ if(stride[i]!=block[i]) {
+ contig=0; /* hyperslab isn't contiguous */
+ break; /* no use looking further */
+ } /* end if */
+ } /* end for */
+
+#ifdef QAK
+ printf("%s: check 1.0, contig=%d, op=%s\n",FUNC,(int)contig,(op==H5S_SELECT_SET? "H5S_SELECT_SET" : (op==H5S_SELECT_OR ? "H5S_SELECT_OR" : "Unknown")));
+#endif /* QAK */
+ /* If we are setting a new selection, remove current selection first */
+ if(op==H5S_SELECT_SET) {
+ if(H5S_select_release(space)<0) {
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL,
+ "can't release hyperslab");
+ } /* end if */
+ } /* end if */
+
+#ifdef QAK
+ printf("%s: check 2.0, rank=%d\n",FUNC,(int)space->extent.u.simple.rank);
+#endif /* QAK */
+ /* Allocate space for the hyperslab selection information if necessary */
+ if(space->select.type!=H5S_SEL_HYPERSLABS || space->select.sel_info.hslab.hyper_lst==NULL) {
+ if((space->select.sel_info.hslab.hyper_lst = H5FL_ALLOC(H5S_hyper_list_t,0))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab information");
+
+ /* Set the fields for the hyperslab list */
+ space->select.sel_info.hslab.hyper_lst->count=0;
+ space->select.sel_info.hslab.hyper_lst->head=NULL;
+ if((space->select.sel_info.hslab.hyper_lst->lo_bounds = H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,space->extent.u.simple.rank,1))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab lo bound information");
+ if((space->select.sel_info.hslab.hyper_lst->hi_bounds = H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,space->extent.u.simple.rank,1))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab lo bound information");
+ } /* end if */
+
+#ifdef QAK
+ printf("%s: check 3.0\n",FUNC);
+#endif /* QAK */
+ /* Generate list of blocks to add/remove based on selection operation */
+ switch(op) {
+ case H5S_SELECT_SET:
+ case H5S_SELECT_OR:
+#ifdef QAK
+ printf("%s: check 4.0\n",FUNC);
+#endif /* QAK */
+ /* Generate list of blocks to add to selection */
+ if(contig) { /* Check for trivial case */
+#ifdef QAK
+ printf("%s: check 4.1\n",FUNC);
+#endif /* QAK */
+
+ /* Account for strides & blocks being equal, but larger than one */
+ /* (Why someone would torture us this way, I don't know... -QAK :-) */
+ for(i=0; i<space->extent.u.simple.rank; i++)
+ slab[i]=count[i]*stride[i];
+
+ /* Add the contiguous hyperslab to the selection */
+ if(H5S_hyper_node_add(&add,0,space->extent.u.simple.rank,start,(const hsize_t *)slab)<0) {
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslab");
+ }
+ } else {
+#ifdef QAK
+ printf("%s: check 4.3\n",FUNC);
+#endif /* QAK */
+ /* Build the slice sizes for each dimension */
+ for(i=0, acc=1; i<space->extent.u.simple.rank; i++) {
+ slice[i]=acc;
+ acc*=count[i];
+ } /* end for */
+
+ /* Step through all the blocks to add */
+ /* (reuse the count in ACC above) */
+ /* Adding the blocks in reverse order reduces the time spent moving memory around in H5S_hyper_add() */
+ for(i=(int)acc-1; i>=0; i--) {
+ /* Build the location of the block */
+ for(j=0; j<space->extent.u.simple.rank; j++)
+ slab[j]=start[j]+((i/slice[j])%count[j])*stride[j];
+
+ /* Add the block to the list of hyperslab selections */
+ if(H5S_hyper_node_add(&add,0,space->extent.u.simple.rank,(const hssize_t *)slab, (const hsize_t *)block)<0) {
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslab");
+ } /* end if */
+ } /* end for */
+ } /* end else */
+
+#ifdef QAK
+ printf("%s: check 4.5\n",FUNC);
+#endif /* QAK */
+ /* Clip list of new blocks to add against current selection */
+ if(op==H5S_SELECT_OR) {
+ H5S_hyper_clip(space,add,&uniq,NULL);
+ add=uniq;
+ } /* end if */
+ else {
+ /* Copy all the per-dimension selection info into the space descriptor */
+ if((diminfo = H5FL_ARR_ALLOC(H5S_hyper_dim_t,space->extent.u.simple.rank,0))==NULL) {
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate per-dimension vector");
+ } /* end if */
+ for(i=0; i<space->extent.u.simple.rank; i++) {
+ diminfo[i].start = start[i];
+ diminfo[i].stride = stride[i];
+ diminfo[i].count = count[i];
+ diminfo[i].block = block[i];
+ } /* end for */
+ space->select.sel_info.hslab.diminfo = diminfo;
+ } /* end else */
+ break;
+
+ default:
+ HRETURN_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation");
+ } /* end switch */
+
+#ifdef QAK
+ printf("%s: check 5.0\n",FUNC);
+#endif /* QAK */
+ /* Add new blocks to current selection */
+ while(add!=NULL) {
+ tmp=add->next;
+
+ /* Add new block */
+ if(H5S_hyper_add(space,(const hssize_t *)add->start, (const hsize_t *)add->end)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslab");
+
+ /* Free node in list */
+ H5S_hyper_node_release(add);
+
+ /* Go to next node */
+ add=tmp;
+ } /* end while */
+
+ /* Merge blocks for better I/O performance */
+ /* Regenerate lo/hi bounds arrays? */
+
+#ifdef QAK
+ printf("%s: check 6.0\n",FUNC);
+#endif /* QAK */
+
+ /* Set selection type */
+ space->select.type=H5S_SEL_HYPERSLABS;
+ ret_value=SUCCEED;
+
+done:
+ if(_stride!=NULL)
+ H5FL_ARR_FREE(hsize_t,_stride);
+ if(_block!=NULL)
+ H5FL_ARR_FREE(hsize_t,_block);
+ FUNC_LEAVE (ret_value);
+}
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Sselect_hyperslab
+ PURPOSE
+ Specify a hyperslab to combine with the current hyperslab selection
+ USAGE
+ herr_t H5Sselect_hyperslab(dsid, op, start, stride, count, block)
+ hid_t dsid; IN: Dataspace ID of selection to modify
+ H5S_seloper_t op; IN: Operation to perform on current selection
+ const hssize_t *start; IN: Offset of start of hyperslab
+ const hssize_t *stride; IN: Hyperslab stride
+ const hssize_t *count; IN: Number of blocks included in hyperslab
+ const hssize_t *block; IN: Size of block in hyperslab
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ Combines a hyperslab selection with the current selection for a dataspace.
+ If the current selection is not a hyperslab, it is freed and the hyperslab
+ parameters passed in are combined with the H5S_SEL_ALL hyperslab (ie. a
+ selection composing the entire current extent). Currently, only the
+ H5S_SELECT_SET & H5S_SELECT_OR operations are supported. If STRIDE or
+ BLOCK is NULL, they are assumed to be set to all '1'.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5Sselect_hyperslab(hid_t space_id, H5S_seloper_t op,
+ const hssize_t start[/*space_id*/],
+ const hsize_t _stride[/*space_id*/],
+ const hsize_t count[/*space_id*/],
+ const hsize_t _block[/*space_id*/])
+{
+ H5S_t *space = NULL; /* Dataspace to modify selection of */
+
+ FUNC_ENTER (H5Sselect_hyperslab, FAIL);
+ H5TRACE6("e","iSs*[a0]Hs*[a0]h*[a0]h*[a0]h",space_id,op,start,_stride,
+ count,_block);
+
+ /* Check args */
+ if (H5I_DATASPACE != H5I_get_type(space_id) ||
+ NULL == (space=H5I_object(space_id))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+ }
+ if(start==NULL || count==NULL) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hyperslab not specified");
+ } /* end if */
+
+ if(!(op>H5S_SELECT_NOOP && op<H5S_SELECT_INVALID)) {
+ HRETURN_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation");
+ } /* end if */
+
+ if (H5S_select_hyperslab(space, op, start, _stride, count, _block)<0) {
+ HRETURN_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL,
+ "unable to set hyperslab selection");
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5S_hyper_select_iterate_mem
*
* Purpose: Recursively iterates over data points in memory using the parameters
@@ -3007,7 +3321,6 @@ H5S_hyper_select_iterate_mem (intn dim, H5S_hyper_iter_info_t *iter_info)
{
hsize_t offset; /* offset of region in buffer */
void *tmp_buf; /* temporary location of the element in the buffer */
- hid_t reg_id; /* ID of temporary region buffer */
H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */
size_t num_regions; /* number of regions overlapped */
herr_t user_ret=0; /* User's return value */
@@ -3020,13 +3333,10 @@ H5S_hyper_select_iterate_mem (intn dim, H5S_hyper_iter_info_t *iter_info)
/* Get a sorted list (in the next dimension down) of the regions which */
/* overlap the current index in this dim */
- if((reg_id=H5S_hyper_get_regions(&num_regions,dim,
+ if((regions=H5S_hyper_get_regions(&num_regions,dim,
iter_info->space->select.sel_info.hslab.hyper_lst->count,
iter_info->lo_bounds, iter_info->hi_bounds,
- iter_info->iter->hyp.pos,iter_info->space->select.offset))>=0) {
-
- /* Get the pointer to the actual regions array */
- regions=H5TB_buf_ptr(reg_id);
+ iter_info->iter->hyp.pos,iter_info->space->select.offset))!=NULL) {
/* Check if this is the second to last dimension in dataset */
/* (Which means that we've got a list of the regions in the fastest */
@@ -3092,7 +3402,7 @@ H5S_hyper_select_iterate_mem (intn dim, H5S_hyper_iter_info_t *iter_info)
} /* end else */
/* Release the temporary buffer */
- H5TB_release_buf(reg_id);
+ H5FL_ARR_FREE(H5S_hyper_region_t,regions);
} /* end if */
FUNC_LEAVE (user_ret);
@@ -3161,8 +3471,8 @@ H5S_hyper_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t
}
/* Allocate space for the low & high bound arrays */
- lo_bounds = H5MM_malloc(space->extent.u.simple.rank * sizeof(H5S_hyper_bound_t *));
- hi_bounds = H5MM_malloc(space->extent.u.simple.rank * sizeof(H5S_hyper_bound_t *));
+ lo_bounds = H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,space->extent.u.simple.rank,0);
+ hi_bounds = H5FL_ARR_ALLOC(H5S_hyper_bound_ptr_t,space->extent.u.simple.rank,0);
/*
* Initialize to correct order to walk through arrays. (When another
@@ -3196,8 +3506,8 @@ H5S_hyper_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t
ret_value=H5S_hyper_select_iterate_mem(-1,&iter_info);
/* Release the memory we allocated */
- H5MM_xfree(lo_bounds);
- H5MM_xfree(hi_bounds);
+ H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,lo_bounds);
+ H5FL_ARR_FREE(H5S_hyper_bound_ptr_t,hi_bounds);
/* Release selection iterator */
H5S_sel_iter_release(space,&iter);
diff --git a/src/H5Snone.c b/src/H5Snone.c
index 75f1543..cba2af4 100644
--- a/src/H5Snone.c
+++ b/src/H5Snone.c
@@ -19,6 +19,8 @@
#define INTERFACE_INIT NULL
static intn interface_initialize_g = 0;
+static herr_t H5S_select_none(H5S_t *space);
+
/*--------------------------------------------------------------------------
NAME
@@ -100,6 +102,86 @@ done:
/*--------------------------------------------------------------------------
NAME
+ H5S_select_none
+ PURPOSE
+ Specify that nothing is selected in the extent
+ USAGE
+ herr_t H5S_select_none(dsid)
+ hid_t dsid; IN: Dataspace ID of selection to modify
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ This function de-selects the entire extent for a dataspace.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t H5S_select_none (H5S_t *space)
+{
+ herr_t ret_value=SUCCEED; /* return value */
+
+ FUNC_ENTER (H5S_select_none, FAIL);
+
+ /* Check args */
+ assert(space);
+
+ /* Remove current selection first */
+ if(H5S_select_release(space)<0) {
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL,
+ "can't release hyperslab");
+ } /* end if */
+
+ /* Set selection type */
+ space->select.type=H5S_SEL_NONE;
+
+done:
+ FUNC_LEAVE (ret_value);
+} /* H5S_select_none() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Sselect_none
+ PURPOSE
+ Specify that nothing is selected in the extent
+ USAGE
+ herr_t H5Sselect_none(dsid)
+ hid_t dsid; IN: Dataspace ID of selection to modify
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ This function de-selects the entire extent for a dataspace.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t H5Sselect_none (hid_t spaceid)
+{
+ H5S_t *space = NULL; /* Dataspace to modify selection of */
+ herr_t ret_value=FAIL; /* return value */
+
+ FUNC_ENTER (H5Sselect_none, FAIL);
+
+ /* Check args */
+ if (H5I_DATASPACE != H5I_get_type(spaceid) ||
+ NULL == (space=H5I_object(spaceid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+ }
+
+ /* Change to "none" selection */
+ if((ret_value=H5S_select_none(space))<0) {
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection");
+ } /* end if */
+
+done:
+ FUNC_LEAVE (ret_value);
+} /* H5Sselect_none() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_none_select_iterate
PURPOSE
Iterate over a none selection, calling a user's function for each
diff --git a/src/H5Spoint.c b/src/H5Spoint.c
index 19d991f..6c47996 100644
--- a/src/H5Spoint.c
+++ b/src/H5Spoint.c
@@ -46,6 +46,8 @@ static herr_t H5S_point_mscat (const void *_tconv_buf, size_t elmt_size,
const H5S_t *mem_space,
H5S_sel_iter_t *mem_iter, size_t nelmts,
void *_buf/*out*/);
+static herr_t H5S_select_elements(H5S_t *space, H5S_seloper_t op,
+ size_t num_elem, const hssize_t **coord);
const H5S_fconv_t H5S_POINT_FCONV[1] = {{
"point", /*name */
@@ -1140,6 +1142,151 @@ H5S_point_select_contiguous(const H5S_t *space)
/*--------------------------------------------------------------------------
NAME
+ H5S_select_elements
+ PURPOSE
+ Specify a series of elements in the dataspace to select
+ USAGE
+ herr_t H5S_select_elements(dsid, op, num_elem, coord)
+ hid_t dsid; IN: Dataspace ID of selection to modify
+ H5S_seloper_t op; IN: Operation to perform on current selection
+ size_t num_elem; IN: Number of elements in COORD array.
+ const hssize_t **coord; IN: The location of each element selected
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ This function selects array elements to be included in the selection for
+ the dataspace. The COORD array is a 2-D array of size <dataspace rank>
+ by NUM_ELEM (ie. a list of coordinates in the dataspace). The order of
+ the element coordinates in the COORD array specifies the order that the
+ array elements are iterated through when I/O is performed. Duplicate
+ coordinates are not checked for. The selection operator, OP, determines
+ how the new selection is to be combined with the existing selection for
+ the dataspace. Currently, only H5S_SELECT_SET is supported, which replaces
+ the existing selection with the one defined in this call. When operators
+ other than H5S_SELECT_SET are used to combine a new selection with an
+ existing selection, the selection ordering is reset to 'C' array ordering.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t H5S_select_elements (H5S_t *space, H5S_seloper_t op, size_t num_elem,
+ const hssize_t **coord)
+{
+ herr_t ret_value=SUCCEED; /* return value */
+
+ FUNC_ENTER (H5S_select_elements, FAIL);
+
+ /* Check args */
+ assert(space);
+ assert(num_elem);
+ assert(coord);
+ assert(op==H5S_SELECT_SET || op==H5S_SELECT_APPEND || op==H5S_SELECT_PREPEND);
+
+#ifdef QAK
+ printf("%s: check 1.0\n",FUNC);
+#endif /* QAK */
+ /* If we are setting a new selection, remove current selection first */
+ if(op==H5S_SELECT_SET) {
+ if(H5S_select_release(space)<0) {
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL,
+ "can't release hyperslab");
+ } /* end if */
+ } /* end if */
+
+#ifdef QAK
+ printf("%s: check 2.0\n",FUNC);
+#endif /* QAK */
+ /* Allocate space for the point selection information if necessary */
+ if(space->select.type!=H5S_SEL_POINTS || space->select.sel_info.pnt_lst==NULL) {
+ if((space->select.sel_info.pnt_lst = H5MM_calloc(sizeof(H5S_pnt_list_t)))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "can't allocate element information");
+ } /* end if */
+
+#ifdef QAK
+ printf("%s: check 3.0\n",FUNC);
+#endif /* QAK */
+ /* Add points to selection */
+ if(H5S_point_add(space,op,num_elem,coord)<0) {
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL,
+ "can't insert elements");
+ }
+
+ /* Set selection type */
+ space->select.type=H5S_SEL_POINTS;
+#ifdef QAK
+ printf("%s: check 4.0\n",FUNC);
+#endif /* QAK */
+
+done:
+ FUNC_LEAVE (ret_value);
+} /* H5S_select_elements() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Sselect_elements
+ PURPOSE
+ Specify a series of elements in the dataspace to select
+ USAGE
+ herr_t H5Sselect_elements(dsid, op, num_elem, coord)
+ hid_t dsid; IN: Dataspace ID of selection to modify
+ H5S_seloper_t op; IN: Operation to perform on current selection
+ size_t num_elem; IN: Number of elements in COORD array.
+ const hssize_t **coord; IN: The location of each element selected
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ This function selects array elements to be included in the selection for
+ the dataspace. The COORD array is a 2-D array of size <dataspace rank>
+ by NUM_ELEM (ie. a list of coordinates in the dataspace). The order of
+ the element coordinates in the COORD array specifies the order that the
+ array elements are iterated through when I/O is performed. Duplicate
+ coordinates are not checked for. The selection operator, OP, determines
+ how the new selection is to be combined with the existing selection for
+ the dataspace. Currently, only H5S_SELECT_SET is supported, which replaces
+ the existing selection with the one defined in this call. When operators
+ other than H5S_SELECT_SET are used to combine a new selection with an
+ existing selection, the selection ordering is reset to 'C' array ordering.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t H5Sselect_elements (hid_t spaceid, H5S_seloper_t op, size_t num_elem,
+ const hssize_t **coord)
+{
+ H5S_t *space = NULL; /* Dataspace to modify selection of */
+ herr_t ret_value=SUCCEED; /* return value */
+
+ FUNC_ENTER (H5Sselect_elements, FAIL);
+
+ /* Check args */
+ if (H5I_DATASPACE != H5I_get_type(spaceid) ||
+ NULL == (space=H5I_object(spaceid))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+ }
+ if(coord==NULL || num_elem==0) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "elements not specified");
+ } /* end if */
+ if(!(op==H5S_SELECT_SET || op==H5S_SELECT_APPEND || op==H5S_SELECT_PREPEND)) {
+ HRETURN_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL,
+ "operations other than H5S_SELECT_SET not supported currently");
+ } /* end if */
+
+ /* Call the real element selection routine */
+ if((ret_value=H5S_select_elements(space,op,num_elem,coord))<0) {
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't select elements");
+ } /* end if */
+
+done:
+ FUNC_LEAVE (ret_value);
+} /* H5Sselect_elements() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_point_select_iterate
PURPOSE
Iterate over a point selection, calling a user's function for each
@@ -1176,7 +1323,7 @@ H5S_point_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t
void *operator_data)
{
hsize_t mem_size[H5O_LAYOUT_NDIMS]; /* Dataspace size */
- hsize_t mem_offset[H5O_LAYOUT_NDIMS]; /* Point offset */
+ hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /* Point offset */
hsize_t offset; /* offset of region in buffer */
void *tmp_buf; /* temporary location of the element in the buffer */
H5S_pnt_node_t *node; /* Point node */
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index ac822be..bc0fff0 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -39,6 +39,9 @@ typedef struct H5S_simple_t {
intn rank; /* Number of dimensions */
hsize_t *size; /* Current size of the dimensions */
hsize_t *max; /* Maximum size of the dimensions */
+#ifdef LATER
+ hsize_t *perm; /* Dimension permutation array */
+#endif /* LATER */
} H5S_simple_t;
/* Extent container */
@@ -82,8 +85,7 @@ typedef struct H5S_hyper_node_tag {
size_t size; /* Size of cached block (in elements) */
uintn rleft; /* Read elements left to access in block */
uintn wleft; /* Write elements left to access in block */
- hid_t block_id; /* Temporary buffer ID */
- uint8_t *block; /* Pointer into temporary buffer for cache */
+ uint8_t *block; /* Pointer into buffer for cache */
uint8_t *rpos; /* Pointer to current read location within block */
uint8_t *wpos; /* Pointer to current write location within block */
} cinfo;
@@ -324,10 +326,6 @@ __DLL__ herr_t H5S_extent_release(H5S_t *space);
__DLL__ herr_t H5S_select_release(H5S_t *space);
__DLL__ herr_t H5S_sel_iter_release(const H5S_t *space,
H5S_sel_iter_t *sel_iter);
-__DLL__ herr_t H5S_select_elements(H5S_t *space, H5S_seloper_t op,
- size_t num_elem, const hssize_t **coord);
-__DLL__ herr_t H5S_select_all(H5S_t *space);
-__DLL__ herr_t H5S_select_none(H5S_t *space);
__DLL__ hssize_t H5S_get_select_npoints(const H5S_t *space);
__DLL__ intn H5S_extend(H5S_t *space, const hsize_t *size);
__DLL__ herr_t H5S_set_extent_simple(H5S_t *space, int rank,
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index 32054f7..4c80cb3 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -10,11 +10,11 @@
#include <H5private.h>
#include <H5Eprivate.h>
+#include <H5FLprivate.h> /*Free Lists */
#include <H5Iprivate.h>
#include <H5MMprivate.h>
#include <H5Sprivate.h>
#include <H5Vprivate.h>
-#include <H5TBprivate.h>
/* Interface initialization */
#define PABLO_MASK H5Sselect_mask
@@ -27,6 +27,9 @@ static herr_t H5S_get_select_hyper_blocklist(H5S_t *space, hsize_t startblock, h
static herr_t H5S_get_select_elem_pointlist(H5S_t *space, hsize_t startpoint, hsize_t numpoints, hsize_t *buf);
static herr_t H5S_get_select_bounds(H5S_t *space, hsize_t *start, hsize_t *end);
+/* Declare external the free list for hssize_t arrays */
+H5FL_ARR_EXTERN(hssize_t);
+
/*--------------------------------------------------------------------------
NAME
@@ -64,7 +67,7 @@ H5S_select_copy (H5S_t *dst, const H5S_t *src)
/* Need to copy order information still */
/* Copy offset information */
- if (NULL==(dst->select.offset = H5MM_calloc(src->extent.u.simple.rank*sizeof(hssize_t)))) {
+ if (NULL==(dst->select.offset = H5FL_ARR_ALLOC(hssize_t, src->extent.u.simple.rank,1))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
@@ -164,577 +167,7 @@ H5S_select_release (H5S_t *space)
FUNC_LEAVE (ret_value);
} /* H5S_select_release() */
-
-/*-------------------------------------------------------------------------
- * Function: H5S_select_hyperslab
- *
- * Purpose: Internal version of H5Sselect_hyperslab().
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke (split from HSselect_hyperslab()).
- * Tuesday, August 25, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
- const hssize_t start[/*space_id*/],
- const hsize_t stride[/*space_id*/],
- const hsize_t count[/*space_id*/],
- const hsize_t block[/*space_id*/])
-{
- hid_t stride_id=FAIL,block_id=FAIL; /* Stride & block temp. buffer IDs */
- hsize_t *_stride=NULL; /* Stride array */
- hsize_t *_block=NULL; /* Block size array */
- hssize_t slab[H5O_LAYOUT_NDIMS]; /* Location of the block to add for strided selections */
- size_t slice[H5O_LAYOUT_NDIMS]; /* Size of preceding dimension's slice */
- H5S_hyper_node_t *add=NULL, /* List of hyperslab nodes to add */
- *uniq=NULL, /* List of unique hyperslab nodes */
- *tmp; /* Temporary hyperslab node */
- uintn acc; /* Accumulator for building slices */
- uintn contig; /* whether selection is contiguous or not */
- int i,j; /* Counters */
- H5S_hyper_dim_t *diminfo; /* per-dimension info for the selection */
- herr_t ret_value=FAIL; /* return value */
-
- FUNC_ENTER (H5S_select_hyperslab, FAIL);
-
- /* Check args */
- assert(space);
- assert(start);
- assert(count);
- assert(op>H5S_SELECT_NOOP && op<H5S_SELECT_INVALID);
-
- /* Fill in the correct stride values */
- if(stride==NULL) {
- hssize_t fill=1;
-
- /* Allocate temporary buffer */
- if((stride_id = H5TB_get_buf(sizeof(hssize_t)*space->extent.u.simple.rank,0,(void **)&_stride))<0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "can't allocate stride vector");
- H5V_array_fill(_stride,&fill,sizeof(hssize_t),space->extent.u.simple.rank);
- stride = _stride;
- }
-
- /* Fill in the correct block values */
- if(block==NULL) {
- hssize_t fill=1;
-
- if((block_id = H5TB_get_buf(sizeof(hssize_t)*space->extent.u.simple.rank,0,(void **)&_block))<0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "can't allocate block vector");
- H5V_array_fill(_block,&fill,sizeof(hssize_t),space->extent.u.simple.rank);
- block = _block;
- }
-
- /*
- * Check for overlapping hyperslab blocks in new selection (remove when
- * real block-merging algorithm is in place? -QAK).
- */
- if(op==H5S_SELECT_SET && block!=NULL) {
- for(i=0; i<space->extent.u.simple.rank; i++) {
- if(stride[i]<block[i]) {
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
- "hyperslab blocks overlap");
- } /* end if */
- } /* end for */
- } /* end if */
-
- /* Determine if selection is contiguous */
- /* assume hyperslab is contiguous, until proven otherwise */
- contig=1;
- for(i=0; i<space->extent.u.simple.rank; i++) {
- /* contiguous hyperslabs have the block size equal to the stride */
- if(stride[i]!=block[i]) {
- contig=0; /* hyperslab isn't contiguous */
- break; /* no use looking further */
- } /* end if */
- } /* end for */
-
-#ifdef QAK
- printf("%s: check 1.0\n",FUNC);
-#endif /* QAK */
- /* If we are setting a new selection, remove current selection first */
- if(op==H5S_SELECT_SET) {
- if(H5S_select_release(space)<0) {
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL,
- "can't release hyperslab");
- } /* end if */
- } /* end if */
-
-#ifdef QAK
- printf("%s: check 2.0\n",FUNC);
-#endif /* QAK */
- /* Allocate space for the hyperslab selection information if necessary */
- if(space->select.type!=H5S_SEL_HYPERSLABS || space->select.sel_info.hslab.hyper_lst==NULL) {
- if((space->select.sel_info.hslab.hyper_lst = H5MM_calloc(sizeof(H5S_hyper_list_t)))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab information");
- if((space->select.sel_info.hslab.hyper_lst->lo_bounds = H5MM_calloc(space->extent.u.simple.rank* sizeof(H5S_hyper_bound_t *)))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab lo bound information");
- if((space->select.sel_info.hslab.hyper_lst->hi_bounds = H5MM_calloc(space->extent.u.simple.rank* sizeof(H5S_hyper_bound_t *)))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab lo bound information");
- } /* end if */
-
- /* Generate list of blocks to add/remove based on selection operation */
- switch(op) {
- case H5S_SELECT_SET:
- case H5S_SELECT_OR:
- /* Generate list of blocks to add to selection */
- if(contig) { /* Check for trivial case */
-
- /* Account for strides & blocks being equal, but larger than one */
- /* (Why someone would torture us this way, I don't know... -QAK :-) */
- for(i=0; i<space->extent.u.simple.rank; i++)
- slab[i]=count[i]*stride[i];
-
- /* Add the contiguous hyperslab to the selection */
- if(H5S_hyper_node_add(&add,0,space->extent.u.simple.rank,start,(const hsize_t *)slab)<0) {
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslab");
- }
- } else {
- /* Build the slice sizes for each dimension */
- for(i=0, acc=1; i<space->extent.u.simple.rank; i++) {
- slice[i]=acc;
- acc*=count[i];
- } /* end for */
-
- /* Step through all the blocks to add */
- /* (reuse the count in ACC above) */
- /* Adding the blocks in reverse order reduces the time spent moving memory around in H5S_hyper_add() */
- for(i=(int)acc-1; i>=0; i--) {
- /* Build the location of the block */
- for(j=0; j<space->extent.u.simple.rank; j++)
- slab[j]=start[j]+((i/slice[j])%count[j])*stride[j];
-
- /* Add the block to the list of hyperslab selections */
- if(H5S_hyper_node_add(&add,0,space->extent.u.simple.rank,(const hssize_t *)slab, (const hsize_t *)block)<0) {
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslab");
- } /* end if */
- } /* end for */
- } /* end else */
-
- /* Clip list of new blocks to add against current selection */
- if(op==H5S_SELECT_OR) {
- H5S_hyper_clip(space,add,&uniq,NULL);
- add=uniq;
- } /* end if */
- else {
- /* Copy all the per-dimension selection info into the space descriptor */
- if((diminfo = H5MM_malloc(sizeof(H5S_hyper_dim_t)*space->extent.u.simple.rank))==NULL) {
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate per-dimension vector");
- } /* end if */
- for(i=0; i<space->extent.u.simple.rank; i++) {
- diminfo[i].start = start[i];
- diminfo[i].stride = stride[i];
- diminfo[i].count = count[i];
- diminfo[i].block = block[i];
- } /* end for */
- space->select.sel_info.hslab.diminfo = diminfo;
- } /* end else */
- break;
-
- default:
- HRETURN_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation");
- } /* end switch */
-
- /* Add new blocks to current selection */
- while(add!=NULL) {
- tmp=add->next;
-
- /* Add new block */
- if(H5S_hyper_add(space,(const hssize_t *)add->start, (const hsize_t *)add->end)<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslab");
-
- /* Free nodes in list */
- H5MM_xfree(add->start);
- H5MM_xfree(add->end);
- H5MM_xfree(add);
-
- /* Go to next node */
- add=tmp;
- } /* end while */
-
- /* Merge blocks for better I/O performance */
- /* Regenerate lo/hi bounds arrays? */
-
-#ifdef QAK
- printf("%s: check 3.0\n",FUNC);
-#endif /* QAK */
-
- /* Set selection type */
- space->select.type=H5S_SEL_HYPERSLABS;
- ret_value=SUCCEED;
-#ifdef QAK
- printf("%s: check 4.0\n",FUNC);
-#endif /* QAK */
-
-done:
- if(_stride!=NULL) H5TB_release_buf(stride_id);
- if(_block!=NULL) H5TB_release_buf(block_id);
- FUNC_LEAVE (ret_value);
-}
-
-/*--------------------------------------------------------------------------
- NAME
- H5Sselect_hyperslab
- PURPOSE
- Specify a hyperslab to combine with the current hyperslab selection
- USAGE
- herr_t H5Sselect_hyperslab(dsid, op, start, stride, count, block)
- hid_t dsid; IN: Dataspace ID of selection to modify
- H5S_seloper_t op; IN: Operation to perform on current selection
- const hssize_t *start; IN: Offset of start of hyperslab
- const hssize_t *stride; IN: Hyperslab stride
- const hssize_t *count; IN: Number of blocks included in hyperslab
- const hssize_t *block; IN: Size of block in hyperslab
- RETURNS
- Non-negative on success/Negative on failure
- DESCRIPTION
- Combines a hyperslab selection with the current selection for a dataspace.
- If the current selection is not a hyperslab, it is freed and the hyperslab
- parameters passed in are combined with the H5S_SEL_ALL hyperslab (ie. a
- selection composing the entire current extent). Currently, only the
- H5S_SELECT_SET & H5S_SELECT_OR operations are supported. If STRIDE or
- BLOCK is NULL, they are assumed to be set to all '1'.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-herr_t
-H5Sselect_hyperslab(hid_t space_id, H5S_seloper_t op,
- const hssize_t start[/*space_id*/],
- const hsize_t _stride[/*space_id*/],
- const hsize_t count[/*space_id*/],
- const hsize_t _block[/*space_id*/])
-{
- H5S_t *space = NULL; /* Dataspace to modify selection of */
-
- FUNC_ENTER (H5Sselect_hyperslab, FAIL);
- H5TRACE6("e","iSs*[a0]Hs*[a0]h*[a0]h*[a0]h",space_id,op,start,_stride,
- count,_block);
-
- /* Check args */
- if (H5I_DATASPACE != H5I_get_type(space_id) ||
- NULL == (space=H5I_object(space_id))) {
- HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
- }
- if(start==NULL || count==NULL) {
- HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hyperslab not specified");
- } /* end if */
-
- if(!(op>H5S_SELECT_NOOP && op<H5S_SELECT_INVALID)) {
- HRETURN_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation");
- } /* end if */
- if (H5S_select_hyperslab(space, op, start, _stride, count, _block)<0) {
- HRETURN_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL,
- "unable to set hyperslab selection");
- }
-
- FUNC_LEAVE (SUCCEED);
-}
-
-/*--------------------------------------------------------------------------
- NAME
- H5S_select_elements
- PURPOSE
- Specify a series of elements in the dataspace to select
- USAGE
- herr_t H5S_select_elements(dsid, op, num_elem, coord)
- hid_t dsid; IN: Dataspace ID of selection to modify
- H5S_seloper_t op; IN: Operation to perform on current selection
- size_t num_elem; IN: Number of elements in COORD array.
- const hssize_t **coord; IN: The location of each element selected
- RETURNS
- Non-negative on success/Negative on failure
- DESCRIPTION
- This function selects array elements to be included in the selection for
- the dataspace. The COORD array is a 2-D array of size <dataspace rank>
- by NUM_ELEM (ie. a list of coordinates in the dataspace). The order of
- the element coordinates in the COORD array specifies the order that the
- array elements are iterated through when I/O is performed. Duplicate
- coordinates are not checked for. The selection operator, OP, determines
- how the new selection is to be combined with the existing selection for
- the dataspace. Currently, only H5S_SELECT_SET is supported, which replaces
- the existing selection with the one defined in this call. When operators
- other than H5S_SELECT_SET are used to combine a new selection with an
- existing selection, the selection ordering is reset to 'C' array ordering.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-herr_t H5S_select_elements (H5S_t *space, H5S_seloper_t op, size_t num_elem,
- const hssize_t **coord)
-{
- herr_t ret_value=SUCCEED; /* return value */
-
- FUNC_ENTER (H5S_select_elements, FAIL);
-
- /* Check args */
- assert(space);
- assert(num_elem);
- assert(coord);
- assert(op==H5S_SELECT_SET || op==H5S_SELECT_APPEND || op==H5S_SELECT_PREPEND);
-
-#ifdef QAK
- printf("%s: check 1.0\n",FUNC);
-#endif /* QAK */
- /* If we are setting a new selection, remove current selection first */
- if(op==H5S_SELECT_SET) {
- if(H5S_select_release(space)<0) {
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL,
- "can't release hyperslab");
- } /* end if */
- } /* end if */
-
-#ifdef QAK
- printf("%s: check 2.0\n",FUNC);
-#endif /* QAK */
- /* Allocate space for the point selection information if necessary */
- if(space->select.type!=H5S_SEL_POINTS || space->select.sel_info.pnt_lst==NULL) {
- if((space->select.sel_info.pnt_lst = H5MM_calloc(sizeof(H5S_pnt_list_t)))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "can't allocate element information");
- } /* end if */
-
-#ifdef QAK
- printf("%s: check 3.0\n",FUNC);
-#endif /* QAK */
- /* Add points to selection */
- if(H5S_point_add(space,op,num_elem,coord)<0) {
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL,
- "can't insert elements");
- }
-
- /* Set selection type */
- space->select.type=H5S_SEL_POINTS;
-#ifdef QAK
- printf("%s: check 4.0\n",FUNC);
-#endif /* QAK */
-
-done:
- FUNC_LEAVE (ret_value);
-} /* H5S_select_elements() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5Sselect_elements
- PURPOSE
- Specify a series of elements in the dataspace to select
- USAGE
- herr_t H5Sselect_elements(dsid, op, num_elem, coord)
- hid_t dsid; IN: Dataspace ID of selection to modify
- H5S_seloper_t op; IN: Operation to perform on current selection
- size_t num_elem; IN: Number of elements in COORD array.
- const hssize_t **coord; IN: The location of each element selected
- RETURNS
- Non-negative on success/Negative on failure
- DESCRIPTION
- This function selects array elements to be included in the selection for
- the dataspace. The COORD array is a 2-D array of size <dataspace rank>
- by NUM_ELEM (ie. a list of coordinates in the dataspace). The order of
- the element coordinates in the COORD array specifies the order that the
- array elements are iterated through when I/O is performed. Duplicate
- coordinates are not checked for. The selection operator, OP, determines
- how the new selection is to be combined with the existing selection for
- the dataspace. Currently, only H5S_SELECT_SET is supported, which replaces
- the existing selection with the one defined in this call. When operators
- other than H5S_SELECT_SET are used to combine a new selection with an
- existing selection, the selection ordering is reset to 'C' array ordering.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-herr_t H5Sselect_elements (hid_t spaceid, H5S_seloper_t op, size_t num_elem,
- const hssize_t **coord)
-{
- H5S_t *space = NULL; /* Dataspace to modify selection of */
- herr_t ret_value=SUCCEED; /* return value */
-
- FUNC_ENTER (H5Sselect_elements, FAIL);
-
- /* Check args */
- if (H5I_DATASPACE != H5I_get_type(spaceid) ||
- NULL == (space=H5I_object(spaceid))) {
- HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
- }
- if(coord==NULL || num_elem==0) {
- HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "elements not specified");
- } /* end if */
- if(!(op==H5S_SELECT_SET || op==H5S_SELECT_APPEND || op==H5S_SELECT_PREPEND)) {
- HRETURN_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL,
- "operations other than H5S_SELECT_SET not supported currently");
- } /* end if */
-
- /* Call the real element selection routine */
- if((ret_value=H5S_select_elements(space,op,num_elem,coord))<0) {
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't select elements");
- } /* end if */
-
-done:
- FUNC_LEAVE (ret_value);
-} /* H5Sselect_elements() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5S_select_all
- PURPOSE
- Specify the the entire extent is selected
- USAGE
- herr_t H5S_select_all(dsid)
- hid_t dsid; IN: Dataspace ID of selection to modify
- RETURNS
- Non-negative on success/Negative on failure
- DESCRIPTION
- This function selects the entire extent for a dataspace.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-herr_t H5S_select_all (H5S_t *space)
-{
- herr_t ret_value=SUCCEED; /* return value */
-
- FUNC_ENTER (H5S_select_all, FAIL);
-
- /* Check args */
- assert(space);
-
- /* Remove current selection first */
- if(H5S_select_release(space)<0) {
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection");
- } /* end if */
-
- /* Set selection type */
- space->select.type=H5S_SEL_ALL;
-
-done:
- FUNC_LEAVE (ret_value);
-} /* H5S_select_all() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5Sselect_all
- PURPOSE
- Specify the the entire extent is selected
- USAGE
- herr_t H5Sselect_all(dsid)
- hid_t dsid; IN: Dataspace ID of selection to modify
- RETURNS
- Non-negative on success/Negative on failure
- DESCRIPTION
- This function selects the entire extent for a dataspace.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-herr_t H5Sselect_all (hid_t spaceid)
-{
- H5S_t *space = NULL; /* Dataspace to modify selection of */
- herr_t ret_value=SUCCEED; /* return value */
-
- FUNC_ENTER (H5Sselect_all, FAIL);
-
- /* Check args */
- if (H5I_DATASPACE != H5I_get_type(spaceid) || NULL == (space=H5I_object(spaceid))) {
- HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
- }
-
- /* Remove current selection first */
- if((ret_value=H5S_select_all(space))<0) {
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection");
- } /* end if */
-
-done:
- FUNC_LEAVE (ret_value);
-} /* H5Sselect_all() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5S_select_none
- PURPOSE
- Specify that nothing is selected in the extent
- USAGE
- herr_t H5S_select_none(dsid)
- hid_t dsid; IN: Dataspace ID of selection to modify
- RETURNS
- Non-negative on success/Negative on failure
- DESCRIPTION
- This function de-selects the entire extent for a dataspace.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-herr_t H5S_select_none (H5S_t *space)
-{
- herr_t ret_value=SUCCEED; /* return value */
-
- FUNC_ENTER (H5S_select_none, FAIL);
-
- /* Check args */
- assert(space);
-
- /* Remove current selection first */
- if(H5S_select_release(space)<0) {
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL,
- "can't release hyperslab");
- } /* end if */
-
- /* Set selection type */
- space->select.type=H5S_SEL_NONE;
-
-done:
- FUNC_LEAVE (ret_value);
-} /* H5S_select_none() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5Sselect_none
- PURPOSE
- Specify that nothing is selected in the extent
- USAGE
- herr_t H5Sselect_none(dsid)
- hid_t dsid; IN: Dataspace ID of selection to modify
- RETURNS
- Non-negative on success/Negative on failure
- DESCRIPTION
- This function de-selects the entire extent for a dataspace.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-herr_t H5Sselect_none (hid_t spaceid)
-{
- H5S_t *space = NULL; /* Dataspace to modify selection of */
- herr_t ret_value=FAIL; /* return value */
-
- FUNC_ENTER (H5Sselect_none, FAIL);
-
- /* Check args */
- if (H5I_DATASPACE != H5I_get_type(spaceid) ||
- NULL == (space=H5I_object(spaceid))) {
- HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
- }
-
- /* Change to "none" selection */
- if((ret_value=H5S_select_none(space))<0) {
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection");
- } /* end if */
-
-done:
- FUNC_LEAVE (ret_value);
-} /* H5Sselect_none() */
/*--------------------------------------------------------------------------
NAME
diff --git a/src/H5T.c b/src/H5T.c
index 39459f5..d6d9a86 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -15,6 +15,7 @@ static char RcsId[] = "@(#)$Revision$";
#include <H5Dprivate.h> /*datasets (for H5Tcopy) */
#include <H5Iprivate.h> /*ID functions */
#include <H5Eprivate.h> /*error handling */
+#include <H5FLprivate.h> /*Free Lists */
#include <H5Gprivate.h> /*groups */
#include <H5HGprivate.h> /*global heap */
#include <H5MMprivate.h> /*memory management */
@@ -196,8 +197,12 @@ static struct {
/* The overflow handler */
H5T_overflow_t H5T_overflow_g = NULL;
+/* Local static functions */
static herr_t H5T_print_stats(H5T_path_t *path, intn *nprint/*in,out*/);
+/* Declare the free list for H5T_t's */
+H5FL_DEFINE(H5T_t);
+
/*-------------------------------------------------------------------------
* Function: H5T_init
@@ -458,7 +463,7 @@ H5T_init_interface(void)
dt->u.atomic.prec = 64;
/* Opaque data */
- if (NULL==(dt = H5MM_calloc(sizeof(H5T_t)))) {
+ if (NULL==(dt = H5FL_ALLOC(H5T_t,1))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
@@ -840,7 +845,7 @@ H5T_init_interface(void)
*/
/* One-byte character string */
- if (NULL==(dt = H5MM_calloc(sizeof(H5T_t)))) {
+ if (NULL==(dt = H5FL_ALLOC(H5T_t,1))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
@@ -866,7 +871,7 @@ H5T_init_interface(void)
*/
/* One-byte character string */
- if (NULL==(dt = H5MM_calloc(sizeof(H5T_t)))) {
+ if (NULL==(dt = H5FL_ALLOC(H5T_t,1))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
@@ -892,7 +897,7 @@ H5T_init_interface(void)
*/
/* Object pointer (i.e. object header address in file) */
- if (NULL==(dt = H5MM_calloc(sizeof(H5T_t)))) {
+ if (NULL==(dt = H5FL_ALLOC(H5T_t,1))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
@@ -912,7 +917,7 @@ H5T_init_interface(void)
}
/* Dataset Region pointer (i.e. selection inside a dataset) */
- if (NULL==(dt = H5MM_calloc(sizeof(H5T_t)))) {
+ if (NULL==(dt = H5FL_ALLOC(H5T_t,1))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
@@ -3620,7 +3625,7 @@ H5Tenum_create(hid_t parent_id)
}
/* Build new type */
- if (NULL==(dt=H5MM_calloc(sizeof(H5T_t)))) {
+ if (NULL==(dt = H5FL_ALLOC(H5T_t,1))) {
HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
@@ -3926,7 +3931,7 @@ H5Tvlen_create(hid_t base_id)
}
/* Build new type */
- if (NULL==(dt=H5MM_calloc(sizeof(H5T_t)))) {
+ if (NULL==(dt = H5FL_ALLOC(H5T_t,1))) {
HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
@@ -4584,7 +4589,7 @@ H5T_create(H5T_class_t type, size_t size)
case H5T_OPAQUE:
case H5T_COMPOUND:
- if (NULL==(dt = H5MM_calloc(sizeof(H5T_t)))) {
+ if (NULL==(dt = H5FL_ALLOC(H5T_t,1))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -4606,14 +4611,14 @@ H5T_create(H5T_class_t type, size_t size)
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL,
"no applicable native integer type");
}
- if (NULL==(dt = H5MM_calloc(sizeof(H5T_t)))) {
+ if (NULL==(dt = H5FL_ALLOC(H5T_t,1))) {
HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
dt->type = type;
if (NULL==(dt->parent=H5T_copy(H5I_object(subtype),
H5T_COPY_ALL))) {
- H5MM_xfree(dt);
+ H5FL_FREE(H5T_t,dt);
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL,
"unable to copy base data type");
}
@@ -4801,7 +4806,7 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method)
assert(old_dt);
/* copy */
- if (NULL==(new_dt = H5MM_calloc(sizeof(H5T_t)))) {
+ if (NULL==(new_dt = H5FL_ALLOC(H5T_t,0))) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
@@ -4841,7 +4846,7 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method)
*/
if (H5F_addr_defined(new_dt->ent.header)) {
if (H5O_open (&(new_dt->ent))<0) {
- H5MM_xfree (new_dt);
+ H5FL_FREE (H5T_t,new_dt);
HRETURN_ERROR (H5E_DATATYPE, H5E_CANTOPENOBJ, NULL,
"unable to reopen named data type");
}
@@ -5099,33 +5104,32 @@ H5T_close(H5T_t *dt)
/* Close the datatype */
switch (dt->type) {
- case H5T_COMPOUND:
- for (i=0; i<dt->u.compnd.nmembs; i++) {
- H5MM_xfree(dt->u.compnd.memb[i].name);
- H5T_close(dt->u.compnd.memb[i].type);
- }
- H5MM_xfree(dt->u.compnd.memb);
- H5MM_xfree(dt);
- break;
+ case H5T_COMPOUND:
+ for (i=0; i<dt->u.compnd.nmembs; i++) {
+ H5MM_xfree(dt->u.compnd.memb[i].name);
+ H5T_close(dt->u.compnd.memb[i].type);
+ }
+ H5MM_xfree(dt->u.compnd.memb);
+ break;
- case H5T_ENUM:
- for (i=0; i<dt->u.enumer.nmembs; i++) {
- H5MM_xfree(dt->u.enumer.name[i]);
- }
- H5MM_xfree(dt->u.enumer.name);
- H5MM_xfree(dt->u.enumer.value);
- H5MM_xfree(dt);
- break;
+ case H5T_ENUM:
+ for (i=0; i<dt->u.enumer.nmembs; i++)
+ H5MM_xfree(dt->u.enumer.name[i]);
+ H5MM_xfree(dt->u.enumer.name);
+ H5MM_xfree(dt->u.enumer.value);
+ break;
- case H5T_OPAQUE:
- H5MM_xfree(dt->u.opaque.tag);
- H5MM_xfree(dt);
- break;
+ case H5T_OPAQUE:
+ H5MM_xfree(dt->u.opaque.tag);
+ break;
- default:
- H5MM_xfree(dt);
+ default:
+ break;
}
+ /* Free the datatype struct */
+ H5FL_FREE(H5T_t,dt);
+
/* Close the parent */
if (parent && H5T_close(parent)<0) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
diff --git a/src/H5TB.c b/src/H5TB.c
deleted file mode 100644
index 7712de8..0000000
--- a/src/H5TB.c
+++ /dev/null
@@ -1,539 +0,0 @@
-/****************************************************************************
-* NCSA HDF *
-* Software Development Group *
-* National Center for Supercomputing Applications *
-* University of Illinois at Urbana-Champaign *
-* 605 E. Springfield, Champaign IL 61820 *
-* *
-* For conditions of distribution and use, see the accompanying *
-* hdf/COPYING file. *
-* *
-****************************************************************************/
-
-/*
- * Created: H5TB.c
- * Jun 11 1998
- * Quincey Koziol <koziol@ncsa.uiuc.edu>
- *
- * Purpose: Temporary buffer management functions
- *
- * Library Public API Functions:
- * H5TB_get_buf - Get an ID for a temporary buffer
- * H5TB_buf_ptr - Get a pointer to the temporary buffer's memory
- * H5TB_resize_buf - Resize a temporary buffer
- * H5TB_garbage_coll- Free all unused temporary buffers
- * H5TB_release_buf - Release temporary buffer
- *
- * Modifications:
- *
- */
-
-#ifdef RCSID
-static char RcsId[] = "@(#)$Revision$";
-#endif
-
-/* $Id$ */
-
-#include <H5private.h> /* Generic Functions */
-#include <H5Iprivate.h> /* ID Functions */
-#include <H5Eprivate.h> /* Error handling */
-#include <H5MMprivate.h> /* Memory Management functions */
-#include <H5TBprivate.h> /* Temporary buffer info */
-
-/* Interface init/term information */
-#define PABLO_MASK H5TB_mask
-#define INTERFACE_INIT H5TB_init_interface
-static intn interface_initialize_g = 0;
-static herr_t H5TB_init_interface(void);
-
-/* Local information for managing buffers */
-#define H5TB_RESERVED_ATOMS 0
-
-typedef struct tag_H5TB_t {
- hbool_t inuse; /* Flag to indicate whether the buffer is in use or not */
- hsize_t size; /* Current size of the buffer */
- struct tag_H5TB_t *next; /* Pointer to next buffer in list */
- struct tag_H5TB_t *prev; /* Pointer to previous buffer in list */
- void *buf; /* Pointer to actual temporary buffer */
-} H5TB_t;
-
-static H5TB_t * H5TB_list_head=NULL; /* pointer to beginning of temp. buffer list (list is in order of increasing size) */
-static H5TB_t * H5TB_list_tail=NULL; /* pointer to end of temp. buffer list */
-
-/* Local functions */
-herr_t H5TB_close(H5TB_t *tb);
-
-
-/*--------------------------------------------------------------------------
-NAME
- H5TB_init_interface -- Initialize interface-specific information
-USAGE
- herr_t H5TB_init_interface()
-
-RETURNS
- Non-negative on success/Negative on failure
-DESCRIPTION
- Initializes any interface-specific data or routines.
-
---------------------------------------------------------------------------*/
-static herr_t
-H5TB_init_interface(void)
-{
- FUNC_ENTER(H5TB_init_interface, FAIL);
-
- /* Initialize the atom group for the file IDs */
- if (H5I_init_group(H5I_TEMPBUF, H5I_TEMPBUFID_HASHSIZE,
- H5TB_RESERVED_ATOMS, NULL)<0) {
- HRETURN_ERROR (H5E_INTERNAL, H5E_CANTINIT, FAIL,
- "unable to initialize interface");
- }
- FUNC_LEAVE(SUCCEED);
-}
-
-
-/*--------------------------------------------------------------------------
- NAME
- H5TB_term_interface
- PURPOSE
- Terminate various H5TB objects
- USAGE
- void H5TB_term_interface()
- RETURNS
- Non-negative on success/Negative on failure
- DESCRIPTION
- Release the atom group and any other resources allocated.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- Can't report errors...
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-intn
-H5TB_term_interface(void)
-{
- H5TB_t *curr=H5TB_list_head, /* pointer to current temp. buffer */
- *next; /* pointer to next temp. buffer */
- intn n=0;
-
- if (interface_initialize_g) {
- if ((n=H5I_nmembers(H5I_TEMPBUF))) {
- H5I_clear_group(H5I_TEMPBUF, FALSE);
- } else {
- /* Free group and buffers */
- H5I_destroy_group(H5I_TEMPBUF);
- while(curr!=NULL) {
- next=curr->next;
-
- if(curr->buf!=NULL)
- H5MM_xfree(curr->buf);
- H5MM_xfree(curr);
-
- curr=next;
- }
- H5TB_list_head=H5TB_list_tail=NULL;
- interface_initialize_g = 0;
- n = 1; /*H5I*/
- }
- }
- return n;
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5TB_close
- *
- * Purpose: Releases all memory associated with a temporary buffer.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Thursday, June 11, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-herr_t H5TB_close(H5TB_t *tb)
-{
- FUNC_ENTER(H5TB_close, FAIL);
-
- assert(tb);
-
-
- /* Release the main structure */
- H5MM_xfree(tb);
-
- FUNC_LEAVE(SUCCEED);
-}
-
-/*--------------------------------------------------------------------------
- NAME
- H5TB_get_buf
- PURPOSE
- Get an ID for a temporary buffer
- USAGE
- hid_t H5TB_get_buf(size,resize,ptr)
- hsize_t size; IN: Minimum size of buffer requested
- hbool_t resize; IN: Whether to resize an existing buffer or get a
- new buffer if one doesn't match the correct size
- void **ptr; OUT: Pointer to a pointer to set to the buffer
- address, if not NULL
- RETURNS
- Valid buffer ID on success, negative on failure
- DESCRIPTION
- Checks for an available temporary buffer of at least the size requested and
- returns an ID for an appropriate one. If a buffer of the minimum size
- requested is not available and the resize flag is set, the smallest buffer
- available is resized to be the correct size and returned, otherwise a new
- buffer of the correct size is allocated and returned.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-hid_t
-H5TB_get_buf(hsize_t size, hbool_t resize, void **ptr)
-{
- hid_t ret_value = FAIL;
- H5TB_t *curr=H5TB_list_head, /* pointer to current temp. buffer */
- *new; /* pointer to a newly created temp. buffer */
-
- FUNC_ENTER (H5TB_get_buf, FAIL);
-
- while(curr!=NULL) {
- if(!curr->inuse && size<=curr->size)
- break;
- curr=curr->next;
- } /* end while */
-
- /* Check if we found a block or not */
- if(curr!=NULL) {
- curr->inuse=TRUE;
- } else {
- if(resize) {
- curr=H5TB_list_head; /* start at beginning again */
-
- /* Search for first node which isn't in use */
- while(curr!=NULL) {
- if(!curr->inuse)
- break;
- curr=curr->next;
- } /* end while */
-
- /* Mark the buffer in use and resize the buffer */
- if(curr!=NULL) {
- void * old_ptr=curr->buf;
-
- if((curr->buf = H5MM_realloc(curr->buf, size))==NULL) {
- curr->buf=old_ptr; /* restore pointer if no memory available */
- HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "unable to allocate space for temporary buffer");
- }
- curr->inuse=TRUE;
- }
- } /* end if */
- } /* end else */
-
- /* No blocks in the list are acceptable */
- /* (either too small or not able to be resized) */
- if(curr==NULL) {
- if((new=H5MM_calloc(sizeof(H5TB_t)))==NULL)
- HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "unable to allocate space for temporary buffer struct");
- new->inuse=TRUE;
- new->size=size;
- if((new->buf=H5MM_malloc(size))==NULL) {
- H5MM_xfree(new); /* free structure */
- HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "unable to allocate space for temporary buffer");
- }
-
- /* Check if this is the first node in the list */
- if(H5TB_list_head==NULL) {
- H5TB_list_head=H5TB_list_tail=curr=new;
- } else {
- /* Find correct place to insert in list */
- for(curr=H5TB_list_head; curr!=NULL; curr=curr->next) {
- /* Found node to insert before */
- if(curr->size > new->size) {
- H5TB_t *tmp=curr->prev; /* temporary pointer */
-
- /* Inserting at head of list */
- if(tmp==NULL) {
- H5TB_list_head=new;
- new->next=curr;
- curr->prev=new;
- } else {
- tmp->next=new;
- new->prev=tmp;
- curr->prev=new;
- new->next=curr;
- } /* end else */
-
- /* set this so we can fall through to getting the ID */
- curr=new;
- break;
- } /* end if */
- } /* end for */
-
- /* Add to end of list */
- if(curr==NULL) {
- curr=H5TB_list_tail;
- H5TB_list_tail=curr->next=new;
- new->prev=curr;
- } /* end if */
-
- /* set this so we can fall through to getting the ID */
- curr=new;
- } /* end else */
- } /* end if */
-
- /* Atomize */
- if ((ret_value=H5I_register (H5I_TEMPBUF, curr))<0) {
- HGOTO_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register temp. buffer atom");
- }
-
- /* Assign the pointer to the buffer, if requested */
- if(ptr!=NULL)
- *ptr=curr->buf;
-
-done:
- if (ret_value < 0) {
- }
- FUNC_LEAVE(ret_value);
-} /* H5TB_get_buf() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5TB_buf_ptr
- PURPOSE
- Get the pointer to a temp. buffer memory
- USAGE
- void *H5TB_buf_ptr(tbuf_id)
- hid_t tbuf_id; IN: Temp. buffer ID
- RETURNS
- Non-NULL pointer to buffer memory on success, NULL on failure
- DESCRIPTION
- Gets the pointer to a temp. buffer's memory.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-void *
-H5TB_buf_ptr(hid_t tbuf_id)
-{
- void *ret_value = NULL;
- H5TB_t *tbuf; /* Pointer to temporary buffer */
-
- FUNC_ENTER (H5TB_buf_ptr, NULL);
-
- if (H5I_TEMPBUF != H5I_get_type(tbuf_id) ||
- NULL == (tbuf = H5I_object(tbuf_id))) {
- HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a temp. buffer");
- }
-
- ret_value=tbuf->buf;
-
-#ifdef LATER
-done:
-#endif
- if (ret_value == NULL) {
- }
- FUNC_LEAVE(ret_value);
-} /* H5TB_buf_ptr() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5TB_resize_buf
- PURPOSE
- Resize a temp. buffer to a new size
- USAGE
- herr_t H5TB_resize_buf(tbid, size, ptr)
- hid_t tbid; IN: Temp. buffer ID to resize
- hsize_t size; IN: New size of temp. buffer
- void **ptr; OUT: Pointer to a pointer to set to the buffer
- address, if not NULL
- RETURNS
- non-negative on success, negative on failure
- DESCRIPTION
- Resizes a temporary buffer to a new size.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-herr_t
-H5TB_resize_buf(hid_t tbuf_id, hsize_t size, void **ptr)
-{
- H5TB_t *tbuf, /* Pointer to temporary buffer */
- *curr; /* Pointer to temp. buffer node */
- void * old_ptr; /* Pointer to the previous buffer */
-
- FUNC_ENTER (H5TB_resize_buf, FAIL);
-
- if (H5I_TEMPBUF != H5I_get_type(tbuf_id) ||
- NULL == (tbuf = H5I_object(tbuf_id))) {
- HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a temp. buffer");
- }
-
- /* Check if we actually need to re-size the buffer */
- if(size > tbuf->size) {
- /* Save old pointer for later */
- old_ptr=tbuf->buf;
-
- /* Try to resize buffer to new size */
- if((tbuf->buf = H5MM_realloc(tbuf->buf, size))==NULL) {
- tbuf->buf=old_ptr; /* restore pointer if no memory available */
- HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "unable to allocate space for temporary buffer");
- }
-
- /* Change the size of the buffer */
- tbuf->size=size;
-
- /*
- * Check if we need to move the buffer in the sorted list
- */
-
- /* Check if this is not the last node and it needs to move */
- if(tbuf->next!=NULL && tbuf->next->size < tbuf->size) {
- /* Remove this node from the list */
- if(tbuf->prev==NULL) { /* remove from head of list */
- H5TB_list_head=tbuf->next;
- tbuf->next->prev=NULL;
- } else { /* remove from middle of list */
- tbuf->prev->next=tbuf->next;
- tbuf->next->prev=tbuf->prev;
- } /* end if */
-
- /* Find correct position in list */
- curr=H5TB_list_head;
- while(curr!=NULL) {
- if(!curr->inuse && size<curr->size)
- break;
- curr=curr->next;
- } /* end while */
-
- /* Insert into correct position in list */
- if(curr!=NULL) {
- /*
- * Can't be adding to the beginning of list, so this is in the
- * middle somewhere.
- */
- curr->prev->next=tbuf;
- tbuf->prev=curr->prev;
- curr->prev=tbuf;
- tbuf->next=curr;
- } else { /* append to end of list */
- H5TB_list_tail->next=tbuf;
- tbuf->prev=H5TB_list_tail;
- tbuf->next=NULL;
- H5TB_list_tail=tbuf;
- } /* end else */
- } /* end if */
- } /* end if */
-
- /* Assign the pointer to the buffer, if requested */
- if(ptr!=NULL)
- *ptr=tbuf->buf;
-
- FUNC_LEAVE(SUCCEED);
-} /* H5TB_resize_buf() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5TB_garbage_coll
- PURPOSE
- Release all unused temporary buffers
- USAGE
- herr_t H5TB_garbase_coll()
- RETURNS
- non-negative on success, negative on failure
- DESCRIPTION
- Steps through the list of temporary buffers, removing unused nodes from the
- list and freeing their memory
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-herr_t
-H5TB_garbage_coll(void)
-{
- herr_t ret_value = FAIL;
- H5TB_t *curr,*next; /* Current temp. buffer node */
-
- FUNC_ENTER (H5TB_garbage_coll, FAIL);
-
- /*
- * Step through the list, remove each unused node, repair the list and
- * free the node.
- */
- curr=H5TB_list_head;
- while(curr!=NULL) {
- next=curr->next;
- if(!curr->inuse) {
- /* maintain list head & tail */
- if(H5TB_list_head==curr)
- H5TB_list_head=curr->next;
- if(H5TB_list_tail==curr)
- H5TB_list_tail=curr->prev;
-
- /* Delete node from list */
- if(curr->prev!=NULL)
- curr->prev->next=curr->next;
- if(curr->next!=NULL)
- curr->next->prev=curr->prev;
-
- /* Free memory for node */
- if(curr->buf!=NULL)
- H5MM_xfree(curr->buf);
- H5MM_xfree(curr);
- } /* end if */
- curr=next;
- } /* end while */
-
- ret_value=SUCCEED;
-
- FUNC_LEAVE(ret_value);
-} /* H5TB_garbage_coll() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5TB_release_buf
- PURPOSE
- Release a temp. buffer back to the list of unused ones.
- USAGE
- herr_t H5TB_release_buf(tbuf_id)
- hid_t tbuf_id; IN: Temp. buffer ID to release
- RETURNS
- non-negative on success, negative on failure
- DESCRIPTION
- Releases a temporary buffer.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-herr_t
-H5TB_release_buf(hid_t tbuf_id)
-{
- herr_t ret_value = FAIL;
- H5TB_t *tbuf; /* Pointer to temporary buffer */
-
- FUNC_ENTER (H5TB_release_buf, FAIL);
-
- if (H5I_TEMPBUF != H5I_get_type(tbuf_id) ||
- NULL == (tbuf = H5I_remove(tbuf_id))) {
- HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a temp. buffer");
- }
-
- /* Release the buffer */
- tbuf->inuse=FALSE;
-
- ret_value=SUCCEED;
-
- FUNC_LEAVE(ret_value);
-} /* H5TB_release_buf() */
-
diff --git a/src/H5TBprivate.h b/src/H5TBprivate.h
deleted file mode 100644
index 3b2ac39..0000000
--- a/src/H5TBprivate.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/****************************************************************************
- * NCSA HDF *
- * Software Development Group *
- * National Center for Supercomputing Applications *
- * University of Illinois at Urbana-Champaign *
- * 605 E. Springfield, Champaign IL 61820 *
- * *
- * For conditions of distribution and use, see the accompanying *
- * hdf/COPYING file. *
- * *
- ****************************************************************************/
-
-/*
- * This file contains private information about the H5TB module
- */
-#ifndef _H5TBprivate_H
-#define _H5TBprivate_H
-
-/* Functions defined in H5TB.c */
-__DLL__ hid_t H5TB_get_buf(hsize_t size, hbool_t resize, void **ptr);
-__DLL__ void *H5TB_buf_ptr(hid_t tbid);
-__DLL__ herr_t H5TB_resize_buf(hid_t tbid, hsize_t size, void **ptr);
-__DLL__ herr_t H5TB_garbage_coll(void);
-__DLL__ herr_t H5TB_release_buf(hid_t tbid);
-
-#endif
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index 3d29e7d..abd1e9b 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -12,10 +12,10 @@
#define PABLO_MASK H5Tconv_mask
#include <H5Iprivate.h>
#include <H5Eprivate.h>
+#include <H5FLprivate.h> /*Free Lists */
#include <H5MMprivate.h>
#include <H5Pprivate.h>
#include <H5Tpkg.h>
-#include <H5TBprivate.h>
/* Conversion data for H5T_conv_struct() */
typedef struct H5T_conv_struct_t {
@@ -43,6 +43,9 @@ typedef struct H5T_conv_hw_t {
static intn interface_initialize_g = 0;
#define INTERFACE_INIT NULL
+/* Declare a free list to manage pieces of vlen data */
+H5FL_BLK_DEFINE_STATIC(vlen_seq);
+
/*
* These macros are for the bodies of functions that convert buffers of one
* integer type to another using hardware. They all start with `H5T_CONV_'
@@ -1781,8 +1784,7 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
hssize_t seq_len; /*the number of elements in the current sequence*/
size_t src_base_size, dst_base_size;/*source & destination base size*/
size_t src_size, dst_size;/*source & destination total size in bytes*/
- hid_t conv_buf_id; /*ID for comversion buffer */
- void *conv_buf_ptr; /*temporary conversion buffer */
+ void *conv_buf=NULL; /*temporary conversion buffer */
hsize_t conv_buf_size; /*size of conversion buffer in bytes */
uint8_t dbuf[64],*dbuf_ptr=dbuf;/*temp destination buffer */
intn direction; /*direction of traversal */
@@ -1877,8 +1879,9 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
/* Get initial conversion buffer */
conv_buf_size=MAX(src_base_size,dst_base_size);
- if((conv_buf_id=H5TB_get_buf(conv_buf_size,FALSE,&conv_buf_ptr))==FAIL)
- HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
+ if ((conv_buf=H5FL_BLK_ALLOC(vlen_seq,conv_buf_size,0))==NULL)
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "memory allocation failed for type conversion");
/* Set up conversion path for base elements */
tpath = H5T_path_find(src->parent, dst->parent, NULL, NULL);
@@ -1904,20 +1907,20 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
/* Check if conversion buffer is large enough, resize if necessary */
if(conv_buf_size<MAX(src_size,dst_size)) {
conv_buf_size=MAX(src_size,dst_size);
- if(H5TB_resize_buf(conv_buf_id,conv_buf_size,&conv_buf_ptr)<0)
+ if((conv_buf=H5FL_BLK_REALLOC(vlen_seq,conv_buf,conv_buf_size))==NULL)
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
} /* end if */
/* Read in VL sequence */
- if((*(src->u.vlen.read))(src->u.vlen.f,s,conv_buf_ptr,src_size)<0)
+ if((*(src->u.vlen.read))(src->u.vlen.f,s,conv_buf,src_size)<0)
HRETURN_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read VL data");
/* Convert VL sequence */
- if (H5T_convert(tpath, tsrc_id, tdst_id, seq_len, 0, conv_buf_ptr, NULL, dset_xfer_plist)<0)
+ if (H5T_convert(tpath, tsrc_id, tdst_id, seq_len, 0, conv_buf, NULL, dset_xfer_plist)<0)
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed");
/* Write sequence to destination location */
- if((*(dst->u.vlen.write))(xfer_parms,dst->u.vlen.f,d,conv_buf_ptr,seq_len,dst_base_size)<0)
+ if((*(dst->u.vlen.write))(xfer_parms,dst->u.vlen.f,d,conv_buf,seq_len,dst_base_size)<0)
HRETURN_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "can't write VL data");
/*
@@ -1938,7 +1941,7 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
}
/* Release the conversion buffer */
- H5TB_release_buf(conv_buf_id);
+ H5FL_BLK_FREE(vlen_seq,conv_buf);
/* Release the temporary datatype IDs used */
if (tsrc_id >= 0) H5I_dec_ref(tsrc_id);
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index be50a6a..0b21060 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -74,13 +74,13 @@ typedef enum {
* Internal data structure for passing information to H5T_vlen_get_buf_size
*/
typedef struct {
- hid_t dataset_id; /* ID of the dataset we are working on */
- hid_t fspace_id; /* ID of the file dataset's dataspace we are working on */
- hid_t mspace_id; /* ID of the memory dataset's dataspace we are working on */
- hid_t fl_tbuf_id; /* ID of the temporary buffer we are using for fixed-length data */
- hid_t vl_tbuf_id; /* ID of the temporary buffer we are using for VL data */
- hid_t xfer_pid; /* ID of the dataset xfer property list */
- hsize_t size; /* Accumulated number of bytes for the selection */
+ hid_t dataset_id; /* ID of the dataset we are working on */
+ hid_t fspace_id; /* ID of the file dataset's dataspace we are working on */
+ hid_t mspace_id; /* ID of the memory dataset's dataspace we are working on */
+ void *fl_tbuf; /* Ptr to the temporary buffer we are using for fixed-length data */
+ void *vl_tbuf; /* Ptr to the temporary buffer we are using for VL data */
+ hid_t xfer_pid; /* ID of the dataset xfer property list */
+ hsize_t size; /* Accumulated number of bytes for the selection */
} H5T_vlen_bufsize_t;
/*
diff --git a/src/H5Zdeflate.c b/src/H5Zdeflate.c
index a764c4b..5f523f5 100644
--- a/src/H5Zdeflate.c
+++ b/src/H5Zdeflate.c
@@ -66,7 +66,7 @@ H5Z_filter_deflate (unsigned flags, size_t cd_nelmts,
z_stream z_strm;
size_t nalloc = *buf_size;
- if (NULL==(outbuf = H5MM_malloc(nalloc))) {
+ if (NULL==(outbuf = H5F_istore_chunk_alloc(nalloc))) {
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0,
"memory allocation failed for deflate uncompression");
}
@@ -87,7 +87,7 @@ H5Z_filter_deflate (unsigned flags, size_t cd_nelmts,
}
if (Z_OK==status && 0==z_strm.avail_out) {
nalloc *= 2;
- if (NULL==(outbuf = H5MM_realloc(outbuf, nalloc))) {
+ if (NULL==(outbuf = H5F_istore_chunk_realloc(outbuf, nalloc))) {
inflateEnd(&z_strm);
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0,
"memory allocation failed for deflate "
@@ -98,7 +98,7 @@ H5Z_filter_deflate (unsigned flags, size_t cd_nelmts,
}
}
- H5MM_xfree(*buf);
+ H5F_istore_chunk_free(*buf);
*buf = outbuf;
outbuf = NULL;
*buf_size = nalloc;
@@ -116,7 +116,7 @@ H5Z_filter_deflate (unsigned flags, size_t cd_nelmts,
uLongf z_dst_nbytes = (uLongf)nbytes;
uLong z_src_nbytes = (uLong)nbytes;
- if (NULL==(z_dst=outbuf=H5MM_malloc(nbytes))) {
+ if (NULL==(z_dst=outbuf=H5F_istore_chunk_alloc(nbytes))) {
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0,
"unable to allocate deflate destination buffer");
}
@@ -129,7 +129,7 @@ H5Z_filter_deflate (unsigned flags, size_t cd_nelmts,
} else if (Z_OK!=status) {
HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, 0, "deflate error");
} else {
- H5MM_xfree(*buf);
+ H5F_istore_chunk_free(*buf);
*buf = outbuf;
outbuf = NULL;
*buf_size = nbytes;
@@ -141,7 +141,8 @@ H5Z_filter_deflate (unsigned flags, size_t cd_nelmts,
"hdf5 was not compiled with zlib-1.0.2 or better");
#endif
- done:
- H5MM_xfree(outbuf);
+done:
+ if(outbuf)
+ H5F_istore_chunk_free(outbuf);
FUNC_LEAVE (ret_value);
}
diff --git a/src/H5detect.c b/src/H5detect.c
index d4cb4f0..cbb3d1a 100644
--- a/src/H5detect.c
+++ b/src/H5detect.c
@@ -395,11 +395,16 @@ print_results(int nd, detected_t *d)
#include <H5private.h>\n\
#include <H5Iprivate.h>\n\
#include <H5Eprivate.h>\n\
+#include <H5FLprivate.h>\n\
#include <H5MMprivate.h>\n\
#include <H5Tpkg.h>\n\
\n\
static intn interface_initialize_g = 0;\n\
#define INTERFACE_INIT NULL\n\
+\n\
+/* Declare external the free list for H5T_t's */\n\
+H5FL_EXTERN(H5T_t);\n\
+\n\
\n");
/* The interface termination function */
@@ -429,7 +434,7 @@ H5TN_init_interface(void)\n\
/* The part common to fixed and floating types */
printf("\
- if (NULL==(dt = H5MM_calloc (sizeof(H5T_t)))) {\n\
+ if (NULL==(dt = H5FL_ALLOC (H5T_t,1))) {\n\
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,\n\
\"memory allocation failed\");\n\
}\n\
diff --git a/src/H5private.h b/src/H5private.h
index 898c65e..bdb59a9 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -954,7 +954,6 @@ __DLL__ intn H5P_term_interface(void);
__DLL__ intn H5RA_term_interface(void);
__DLL__ intn H5R_term_interface(void);
__DLL__ intn H5S_term_interface(void);
-__DLL__ intn H5TB_term_interface(void);
__DLL__ intn H5TN_term_interface(void);
__DLL__ intn H5T_term_interface(void);
__DLL__ intn H5Z_term_interface(void);
diff --git a/src/H5public.h b/src/H5public.h
index a4a7f78..34cfa49 100644
--- a/src/H5public.h
+++ b/src/H5public.h
@@ -140,6 +140,7 @@ extern "C" {
__DLL__ herr_t H5open(void);
__DLL__ herr_t H5close(void);
__DLL__ herr_t H5dont_atexit(void);
+__DLL__ herr_t H5garbage_collect(void);
__DLL__ herr_t H5get_libversion(unsigned *majnum, unsigned *minnum,
unsigned *relnum);
__DLL__ herr_t H5check_version(unsigned majnum, unsigned minnum,
diff --git a/src/Makefile.in b/src/Makefile.in
index 3ab5fe2..c36a0f2 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -20,13 +20,13 @@ CLEAN=libhdf5.settings
## Source and object files for the library (lexicographically)...
LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5D.c H5E.c H5F.c H5Farray.c H5Fistore.c \
- H5FD.c H5FDsec2.c H5FDfamily.c H5FDmpio.c H5FDcore.c H5FDmulti.c \
- H5FDgass.c H5FDstdio.c H5G.c H5Gent.c H5Gnode.c H5Gstab.c H5HG.c H5HL.c \
- H5I.c H5MF.c H5MM.c H5O.c H5Oattr.c H5Ocomp.c H5Ocont.c H5Odtype.c \
- H5Oefl.c H5Ofill.c H5Olayout.c H5Omtime.c H5Oname.c H5Onull.c \
- H5Osdspace.c H5Oshared.c H5Ostab.c H5P.c H5R.c H5RA.c H5S.c H5Sall.c \
- H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c H5Sselect.c H5T.c H5Tbit.c \
- H5Tconv.c H5Tinit.c H5Tvlen.c H5TB.c H5V.c H5Z.c H5Zdeflate.c H5FDdpss.c
+ H5FD.c H5FDsec2.c H5FDfamily.c H5FDmpio.c H5FDcore.c H5FDdpss.c \
+ H5FDmulti.c H5FDgass.c H5FDstdio.c H5FL.c H5G.c H5Gent.c H5Gnode.c \
+ H5Gstab.c H5HG.c H5HL.c H5I.c H5MF.c H5MM.c H5O.c H5Oattr.c H5Ocomp.c \
+ H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c H5Olayout.c H5Omtime.c H5Oname.c \
+ H5Onull.c H5Osdspace.c H5Oshared.c H5Ostab.c H5P.c H5R.c H5RA.c H5S.c \
+ H5Sall.c H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c H5Sselect.c H5T.c \
+ H5Tbit.c H5Tconv.c H5Tinit.c H5Tvlen.c H5V.c H5Z.c H5Zdeflate.c
LIB_OBJ=$(LIB_SRC:.c=.lo)
@@ -35,19 +35,19 @@ MOSTLYCLEAN=H5detect.o H5detect.lo H5detect H5Tinit.o H5Tinit.lo H5Tinit.c
## Public header files (to be installed)...
PUB_HDR=H5public.h H5Apublic.h H5ACpublic.h H5Bpublic.h H5Dpublic.h \
- H5Epublic.h H5Fpublic.h H5FDpublic.h H5FDfamily.h H5FDgass.h H5FDmpio.h \
- H5FDsec2.h H5FDcore.h H5FDmulti.h H5FDstdio.h H5Gpublic.h H5HGpublic.h \
- H5HLpublic.h H5Ipublic.h H5MMpublic.h H5Opublic.h H5Ppublic.h H5Rpublic.h \
- H5RApublic.h H5Spublic.h H5Tpublic.h H5Zpublic.h H5pubconf.h hdf5.h \
- H5api_adpt.h H5FDdpss.h
+ H5Epublic.h H5Fpublic.h H5FDpublic.h H5FDdpss.h H5FDfamily.h H5FDgass.h \
+ H5FDmpio.h H5FDsec2.h H5FDcore.h H5FDmulti.h H5FDstdio.h H5Gpublic.h \
+ H5HGpublic.h H5HLpublic.h H5Ipublic.h H5MMpublic.h H5Opublic.h H5Ppublic.h \
+ H5Rpublic.h H5RApublic.h H5Spublic.h H5Tpublic.h H5Zpublic.h H5pubconf.h \
+ hdf5.h H5api_adpt.h
## Other header files (not to be installed)...
PRIVATE_HDR=H5private.h H5Aprivate.h H5Apkg.h H5ACprivate.h H5Bprivate.h \
- H5Dprivate.h H5Eprivate.h H5Fprivate.h H5FDprivate.h H5Gprivate.h \
- H5Gpkg.h H5HGprivate.h H5HLprivate.h H5Iprivate.h H5MFprivate.h \
- H5MMprivate.h H5Oprivate.h H5Pprivate.h H5Rprivate.h H5RAprivate.h \
- H5Sprivate.h H5Tprivate.h H5TBprivate.h H5Tpkg.h H5Vprivate.h \
- H5Zprivate.h H5config.h
+ H5Dprivate.h H5Eprivate.h H5Fprivate.h H5FDprivate.h H5FLprivate.h \
+ H5Gprivate.h H5Gpkg.h H5HGprivate.h H5HLprivate.h H5Iprivate.h \
+ H5MFprivate.h H5MMprivate.h H5Oprivate.h H5Pprivate.h H5Rprivate.h \
+ H5RAprivate.h H5Sprivate.h H5Tprivate.h H5TBprivate.h H5Tpkg.h \
+ H5Vprivate.h H5Zprivate.h H5config.h
## Number format detection
## The LD_LIBRARY_PATH setting is a klutch.