From 02e4ee5edf5d1c8fe285497def5cd7b7afbf77e4 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 4 Apr 2000 16:00:31 -0500 Subject: [svn-r2073] Added free-list code to the library and took out the older "temporary buffer" code, since the functionality was superceded. See the followup document for details on the free-list code. --- MANIFEST | 5 +- src/Dependencies | 13 - src/H5.c | 39 +- src/H5B.c | 72 +-- src/H5D.c | 105 +++-- src/H5Distore.c | 121 +++++- src/H5FL.c | 1257 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/H5FLprivate.h | 173 ++++++++ src/H5Fistore.c | 121 +++++- src/H5Fprivate.h | 5 + src/H5Gnode.c | 97 +++-- src/H5HG.c | 58 ++- src/H5I.c | 126 ++---- src/H5O.c | 132 +++--- src/H5Oattr.c | 12 +- src/H5Ocomp.c | 59 ++- src/H5Ocont.c | 1 + src/H5Odtype.c | 96 ++-- src/H5Oefl.c | 1 + src/H5Ofill.c | 1 + src/H5Olayout.c | 44 +- src/H5Omtime.c | 39 +- src/H5Oname.c | 1 + src/H5Onull.c | 1 + src/H5Oprivate.h | 1 + src/H5Osdspace.c | 117 +++-- src/H5Oshared.c | 1 + src/H5Ostab.c | 1 + src/H5P.c | 316 ++++++++------ src/H5S.c | 49 ++- src/H5Sall.c | 79 ++++ src/H5Shyper.c | 566 ++++++++++++++++++------ src/H5Snone.c | 82 ++++ src/H5Spoint.c | 149 ++++++- src/H5Sprivate.h | 10 +- src/H5Sselect.c | 577 +----------------------- src/H5T.c | 72 +-- src/H5TB.c | 539 ----------------------- src/H5TBprivate.h | 26 -- src/H5Tconv.c | 23 +- src/H5Tprivate.h | 14 +- src/H5Zdeflate.c | 15 +- src/H5detect.c | 7 +- src/H5private.h | 1 - src/H5public.h | 1 + src/Makefile.in | 34 +- test/big.c | 8 +- test/dtypes.c | 17 +- 48 files changed, 3335 insertions(+), 1949 deletions(-) create mode 100644 src/H5FL.c create mode 100644 src/H5FLprivate.h delete mode 100644 src/H5TB.c delete mode 100644 src/H5TBprivate.h diff --git a/MANIFEST b/MANIFEST index 63d6205..53e210a 100644 --- a/MANIFEST +++ b/MANIFEST @@ -278,6 +278,9 @@ ./src/H5FDsec2.h ./src/H5FDstdio.c ./src/H5FDstdio.h +./src/H5FL.c +./src/H5FLprivate.h +./src/H5FLpublic.h ./src/H5G.c ./src/H5Gent.c ./src/H5Gnode.c @@ -340,8 +343,6 @@ ./src/H5Tprivate.h ./src/H5Tpublic.h ./src/H5Tvlen.c -./src/H5TB.c -./src/H5TBprivate.h ./src/H5V.c ./src/H5Vprivate.h ./src/H5Z.c 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 /*B-link trees */ #include /*error handling */ #include /*file driver */ +#include /*Free Lists */ #include /*atoms */ #include /*memory management */ #include /*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 /*B-link trees */ #include /*error handling */ #include /*file access */ +#include /*Free Lists */ #include /*file memory management */ #include /*core memory management */ #include /*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 /* Cache */ #include /* Dataset functions */ #include /* Error handling */ +#include /*Free Lists */ #include /* Group headers */ #include /* Name heap */ #include /* Memory management */ #include /* Object headers */ #include /* Property lists */ #include /* Dataspace functions rky 980813 */ -#include /* Temporary buffers */ #include /* Vector and array functions */ #include /* 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 #include #include +#include /*Free Lists */ #include #include #include @@ -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 + * 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 /*library */ +#include /*error handling */ +#include /*Core memory management */ +#include /*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; imaxelem; 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 + * + * Purpose: Private non-prototype header. + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +#ifndef _H5FLprivate_H +#define _H5FLprivate_H + +/* Public headers needed by this file */ +#ifdef LATER +#include /*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 #include #include +#include /*Free Lists */ #include #include #include @@ -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 /*B-link trees */ #include /*error handling */ #include /*file access */ +#include /*Free Lists */ #include /*me */ #include /*local heap */ #include /*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 /*library */ #include /*caching */ #include /*error handling */ +#include /*Free Lists */ #include /*global heaps */ #include /*file memory management */ #include /*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; ishared->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; ishared->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 #include #include +#include /*Free Lists */ #include /* 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; grpid_list) { - n++; - } - } - - /* If no groups are used then clean up */ - if (0==n) { - for (grp=(H5I_type_t)0; grpnext; - H5MM_xfree(curr); - } - } - - /* Mark interface closed */ - interface_initialize_g = 0; + /* How many groups are still being used? */ + for (grp=(H5I_type_t)0; grpid_list) + n++; + } + + /* If no groups are used then clean up */ + if (0==n) { + for (grp=(H5I_type_t)0; grpnext; - 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 #include #include +#include /*Free Lists */ #include #include #include @@ -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 #include +#include /*Free Lists */ #include #include #include @@ -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 #include +#include /*Free Lists */ #include #include @@ -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; infilters; 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; infilters; 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; infilters; 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 #include +#include /*Free Lists */ #include #include #include @@ -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; ju.compnd.memb[i].ndims; j++) { + for (j=0; ju.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 #include #include +#include /*Free Lists */ #include #include @@ -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 #include +#include /*Free Lists */ #include #include @@ -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 #include +#include /*Free Lists */ #include #include #include @@ -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 /* Datasets */ #include /* Error handling */ #include /* File drivers */ +#include /* Free Lists */ #include /* Memory management */ #include /* 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 /* Generic Functions */ #include /* ID Functions */ #include /* Error handling */ +#include /* Free Lists */ #include /* Memory Management functions */ #include /* object headers */ #include /* 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 #include #include +#include /*Free Lists */ #include #include #include #include -#include #include /* 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=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=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=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=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; iextent.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; iextent.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; iextent.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 && opextent.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; iextent.u.simple.rank; i++) { + if(stride[i]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; iextent.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; iextent.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; jextent.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; iextent.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 && opspace->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 + 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 + 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 #include +#include /*Free Lists */ #include #include #include #include -#include /* 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 && opextent.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; iextent.u.simple.rank; i++) { - if(stride[i]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; iextent.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; iextent.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; jextent.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; iextent.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 - 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 - 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 /*datasets (for H5Tcopy) */ #include /*ID functions */ #include /*error handling */ +#include /*Free Lists */ #include /*groups */ #include /*global heap */ #include /*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; iu.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; iu.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; iu.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; iu.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 - * - * 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 /* Generic Functions */ -#include /* ID Functions */ -#include /* Error handling */ -#include /* Memory Management functions */ -#include /* 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 && sizesize) - 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 #include +#include /*Free Lists */ #include #include #include -#include /* 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_sizeu.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 \n\ #include \n\ #include \n\ +#include \n\ #include \n\ #include \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. diff --git a/test/big.c b/test/big.c index 985e1de..463b5cc 100644 --- a/test/big.c +++ b/test/big.c @@ -386,23 +386,23 @@ main (void) if (sizeof(long_long)<8 || 0==GB8LL) { puts("Test skipped because sizeof(long_long) is too small. This"); puts("hardware apparently doesn't support 64-bit integer types."); - H5Pclose(fapl); + h5_cleanup(fapl); exit(0); } if (!is_sparse()) { puts("Test skipped because file system does not support holes."); - H5Pclose(fapl); + h5_cleanup(fapl); exit(0); } if (!enough_room(fapl)) { puts("Test skipped because of quota (file size or num open files)."); - H5Pclose(fapl); + h5_cleanup(fapl); exit(0); } if (sizeof(hsize_t)<=4) { puts("Test skipped because the hdf5 library was configured with the"); puts("--disable-hsizet flag in order to work around a compiler bug."); - H5Pclose(fapl); + h5_cleanup(fapl); exit(0); } diff --git a/test/dtypes.c b/test/dtypes.c index bf369e6..285a174 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -13,6 +13,9 @@ /* Number of times to run each test */ #define NTESTS 1 +/* Number of elements in each test */ +#define NTESTELEM 100000 + /* Define if you want to see a count of overflows */ #undef SHOW_OVERFLOWS @@ -436,7 +439,7 @@ test_compound_2(void) int e, d, c[4], b, a; } *d_ptr; - const int nelmts = 200000; + const int nelmts = NTESTELEM; const size_t four = 4; unsigned char *buf=NULL, *orig=NULL, *bkg=NULL; hid_t st=-1, dt=-1; @@ -550,7 +553,7 @@ test_compound_3(void) int a, c[4], e; } *d_ptr; - const int nelmts = 200000; + const int nelmts = NTESTELEM; const size_t four = 4; unsigned char *buf=NULL, *orig=NULL, *bkg=NULL; hid_t st=-1, dt=-1; @@ -664,7 +667,7 @@ test_compound_4(void) int e; } *d_ptr; - const int nelmts = 200000; + const int nelmts = NTESTELEM; const size_t four = 4; unsigned char *buf=NULL, *orig=NULL, *bkg=NULL; hid_t st=-1, dt=-1; @@ -1363,7 +1366,7 @@ test_conv_str_2(void) { char *buf=NULL, s[80]; hid_t c_type, f_type; - const size_t nelmts = 200000, ntests=NTESTS; + const size_t nelmts = NTESTELEM, ntests=NTESTS; size_t i, j, nchars; int ret_value = 1; @@ -1423,7 +1426,7 @@ test_conv_str_2(void) static int test_conv_enum_1(void) { - const int nelmts=200000, ntests=NTESTS; + const int nelmts=NTESTELEM, ntests=NTESTS; int i, val, *buf=NULL; hid_t t1, t2; char s[80]; @@ -1808,7 +1811,7 @@ static int test_conv_int_1(const char *name, hid_t src, hid_t dst) { const size_t ntests=NTESTS; /*number of tests */ - const size_t nelmts=200000; /*num values per test */ + const size_t nelmts=NTESTELEM; /*num values per test */ const size_t max_fails=8; /*max number of failures*/ size_t fails_all_tests=0; /*number of failures */ size_t fails_this_test; /*fails for this test */ @@ -2960,7 +2963,7 @@ test_conv_flt_1 (const char *name, hid_t src, hid_t dst) { flt_t src_type, dst_type; /*data types */ const size_t ntests=NTESTS; /*number of tests */ - const size_t nelmts=200000; /*num values per test */ + const size_t nelmts=NTESTELEM; /*num values per test */ const size_t max_fails=8; /*max number of failures*/ size_t fails_all_tests=0; /*number of failures */ size_t fails_this_test; /*fails for this test */ -- cgit v0.12