From ed6e5dd6dcde54d16569fc28f8b062bac81fb81a Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 26 Oct 2004 15:09:29 -0500 Subject: [svn-r9460] Purpose: Code cleanup & optimization Description: Bring back new metadata cache code from development branch. Platforms tested: FreeBSD 4.10 (sleipnir) w/parallel Solaris 2.7 (arabica) Linux 2.4 (heping) w/C++ & FORTRAN --- configure | 3 +- configure.in | 1 + src/H5AC.c | 1561 ++++++++++++++++------------------------------------- src/H5ACprivate.h | 106 ++-- src/H5B.c | 71 ++- src/H5C.c | 70 +-- src/H5F.c | 692 ++++++++++++------------ src/H5FL.c | 203 ++++--- src/H5FO.c | 14 +- src/H5FOprivate.h | 4 +- src/H5Fpkg.h | 2 +- src/H5Fprivate.h | 4 +- src/H5Gnode.c | 60 +- src/H5HG.c | 50 +- src/H5HGprivate.h | 2 + src/H5HL.c | 48 +- src/H5HLprivate.h | 6 + src/H5MM.c | 10 +- src/H5MPprivate.h | 4 +- src/H5O.c | 66 ++- src/H5Oattr.c | 17 +- src/H5Obogus.c | 16 +- src/H5Ocont.c | 14 +- src/Makefile.in | 6 +- test/ohdr.c | 12 +- 25 files changed, 1347 insertions(+), 1695 deletions(-) diff --git a/configure b/configure index 5a5ae29..ab01c5a 100755 --- a/configure +++ b/configure @@ -32212,7 +32212,7 @@ if test "X$HAVE_PABLO" = "Xyes"; then fi fi -ac_config_files="$ac_config_files src/libhdf5.settings config/depend1 config/depend2 config/depend3 config/depend4 config/dependN config/commence config/conclude Makefile src/Makefile $PABLO_MAKE test/Makefile $PARALLEL_MAKE perform/Makefile tools/Makefile tools/h5dump/Makefile tools/h5dump/testh5dump.sh tools/h5import/Makefile tools/h5diff/Makefile tools/h5jam/Makefile tools/h5repack/Makefile tools/h5repack/h5repack.sh tools/h5ls/Makefile tools/lib/Makefile tools/misc/Makefile tools/misc/h5cc tools/gifconv/Makefile examples/Makefile doc/Makefile doc/html/Makefile doc/html/ed_libs/Makefile doc/html/ed_styles/Makefile doc/html/ADGuide/Makefile doc/html/Graphics/Makefile doc/html/Intro/Makefile doc/html/PSandPDF/Makefile doc/html/TechNotes/Makefile doc/html/Tutor/Makefile doc/html/Tutor/Graphics/Makefile doc/html/Tutor/examples/Makefile doc/html/cpplus/Makefile doc/html/cpplus_RM/Makefile doc/html/cpplus_RM/header_files/Makefile doc/html/fortran/Makefile" +ac_config_files="$ac_config_files src/libhdf5.settings config/depend1 config/depend2 config/depend3 config/depend4 config/dependN config/commence config/conclude Makefile src/Makefile $PABLO_MAKE test/Makefile $PARALLEL_MAKE perform/Makefile tools/Makefile tools/h5dump/Makefile tools/h5dump/testh5dump.sh tools/h5import/Makefile tools/h5diff/Makefile tools/h5jam/Makefile tools/h5jam/testh5jam.sh tools/h5repack/Makefile tools/h5repack/h5repack.sh tools/h5ls/Makefile tools/lib/Makefile tools/misc/Makefile tools/misc/h5cc tools/gifconv/Makefile examples/Makefile doc/Makefile doc/html/Makefile doc/html/ed_libs/Makefile doc/html/ed_styles/Makefile doc/html/ADGuide/Makefile doc/html/Graphics/Makefile doc/html/Intro/Makefile doc/html/PSandPDF/Makefile doc/html/TechNotes/Makefile doc/html/Tutor/Makefile doc/html/Tutor/Graphics/Makefile doc/html/Tutor/examples/Makefile doc/html/cpplus/Makefile doc/html/cpplus_RM/Makefile doc/html/cpplus_RM/header_files/Makefile doc/html/fortran/Makefile" cat >confcache <<\_ACEOF @@ -32716,6 +32716,7 @@ do "tools/h5import/Makefile" ) CONFIG_FILES="$CONFIG_FILES tools/h5import/Makefile" ;; "tools/h5diff/Makefile" ) CONFIG_FILES="$CONFIG_FILES tools/h5diff/Makefile" ;; "tools/h5jam/Makefile" ) CONFIG_FILES="$CONFIG_FILES tools/h5jam/Makefile" ;; + "tools/h5jam/testh5jam.sh" ) CONFIG_FILES="$CONFIG_FILES tools/h5jam/testh5jam.sh" ;; "tools/h5repack/Makefile" ) CONFIG_FILES="$CONFIG_FILES tools/h5repack/Makefile" ;; "tools/h5repack/h5repack.sh" ) CONFIG_FILES="$CONFIG_FILES tools/h5repack/h5repack.sh" ;; "tools/h5ls/Makefile" ) CONFIG_FILES="$CONFIG_FILES tools/h5ls/Makefile" ;; diff --git a/configure.in b/configure.in index 7f62c91..5ae7862 100644 --- a/configure.in +++ b/configure.in @@ -2433,6 +2433,7 @@ AC_CONFIG_FILES([src/libhdf5.settings tools/h5import/Makefile tools/h5diff/Makefile tools/h5jam/Makefile + tools/h5jam/testh5jam.sh tools/h5repack/Makefile tools/h5repack/h5repack.sh tools/h5ls/Makefile diff --git a/src/H5AC.c b/src/H5AC.c index 4fe9e73..dced1ab 100644 --- a/src/H5AC.c +++ b/src/H5AC.c @@ -31,6 +31,14 @@ * Quincey Koziol, 22 Apr 2000 * Turned on "H5AC_SORT_BY_ADDR" * + * John Mainzer, 5/19/04 + * Complete redesign and rewrite. See the header comments for + * H5AC_t for an overview of what is going on. + * + * John Mainzer, 6/4/04 + * Factored the new cache code into a separate file (H5C.c) to + * facilitate re-use. Re-worked this file again to use H5C. + * *------------------------------------------------------------------------- */ @@ -46,9 +54,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* Files */ #include "H5FDprivate.h" /* File drivers */ -#include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ -#include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ /* Interface initialization */ @@ -57,51 +63,6 @@ static int interface_initialize_g = 0; static herr_t H5AC_init_interface(void); /* - * Private macros - */ - -/* Hash an address in the file to an offset in the cache */ -#define H5AC_HASH_DIVISOR 8 /* Attempt to spread out the hashing */ - /* This should be the same size as the alignment of */ - /* of the smallest file format object written to the file. */ -#define H5AC_HASH(F,ADDR) H5F_addr_hash((ADDR/H5AC_HASH_DIVISOR),(F)->shared->cache->nslots) - -/* - * Private typedefs & structs - */ - -#ifdef H5AC_DEBUG -typedef struct H5AC_prot_t { - int nprots; /*number of things protected */ - int aprots; /*nelmts of `prot' array */ - H5AC_info_t **slot; /*array of pointers to protected things */ -} H5AC_prot_t; -#endif /* H5AC_DEBUG */ - -struct H5AC_t { - unsigned nslots; /*number of cache slots */ - H5AC_info_t **slot; /*the cache slots, an array of pointers to the cached objects */ - H5AC_info_t **dslot; /*"held object" cache slots, an array of pointers to dirty cached objects */ -#ifdef H5AC_DEBUG - H5AC_prot_t *prot; /*the protected slots */ -#endif /* H5AC_DEBUG */ - int nprots; /*number of protected objects */ -#ifdef H5AC_DEBUG - struct { - unsigned nhits; /*number of cache hits */ - unsigned nmisses; /*number of cache misses */ - unsigned ninits; /*number of cache inits */ - unsigned nflushes; /*number of flushes to disk */ -#ifdef H5_HAVE_PARALLEL - unsigned ndestroys; /*number of cache destroys */ - unsigned nholds; /*number of cache holds */ - unsigned nrestores; /*number of cache restores */ -#endif /* H5_HAVE_PARALLEL */ - } diagnostics[H5AC_NTYPES]; /*diagnostics for each type of object*/ -#endif /* H5AC_DEBUG */ -}; - -/* * Private file-scope variables. */ @@ -120,21 +81,14 @@ static hid_t H5AC_noblock_dxpl_id=(-1); /* (Global variable definition, declaration is in H5ACprivate.h also) */ hid_t H5AC_ind_dxpl_id=(-1); -static H5AC_t *current_cache_g = NULL; /*for sorting */ - -/* Declare a free list to manage the H5AC_t struct */ -H5FL_DEFINE_STATIC(H5AC_t); -/* Declare a PQ free list to manage the cache mapping array information */ -H5FL_SEQ_DEFINE_STATIC(int); - -/* Declare a PQ free list to manage the cache slot array information */ -H5FL_SEQ_DEFINE_STATIC(H5AC_info_ptr_t); +/* + * Private file-scope function declarations: + */ -#ifdef H5AC_DEBUG -/* Declare a PQ free list to manage the protected slot array information */ -H5FL_SEQ_DEFINE_STATIC(H5AC_prot_t); -#endif /* H5AC_DEBUG */ +static herr_t H5AC_check_if_write_permitted(H5F_t *f, + hid_t dxpl_id, + hbool_t * write_permitted_ptr); /*------------------------------------------------------------------------- @@ -158,11 +112,11 @@ H5AC_init(void) { herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5AC_init, FAIL); + FUNC_ENTER_NOAPI(H5AC_init, FAIL) /* FUNC_ENTER() does all the work */ done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -315,10 +269,10 @@ H5AC_term_interface(void) n = 1; /* H5I */ /* Close H5AC dxpl */ - if (H5Pclose(H5AC_dxpl_id) < 0 || - H5Pclose(H5AC_noblock_dxpl_id) < 0 || - H5Pclose(H5AC_ind_dxpl_id) < 0) - H5E_clear(); /*ignore the error*/ + if (H5I_dec_ref(H5AC_dxpl_id) < 0 || + H5I_dec_ref(H5AC_noblock_dxpl_id) < 0 || + H5I_dec_ref(H5AC_ind_dxpl_id) < 0) + H5E_clear(); /*ignore error*/ else { /* Reset static IDs */ H5AC_dxpl_id=(-1); @@ -363,52 +317,82 @@ H5AC_term_interface(void) * * Modifications: * + * Complete re-design and re-write to support the re-designed + * metadata cache. + * + * At present, the size_hint is ignored, and the + * max_cache_size and min_clean_size fields are hard + * coded. This should be fixed, but a parameter + * list change will be required, so I will leave it + * for now. + * + * Since no-one seems to care, the function now returns + * one on success. + * JRM - 4/28/04 + * + * Reworked the function again after abstracting its guts to + * the similar function in H5C.c. The function is now a + * wrapper for H5C_create(). + * JRM - 6/4/04 *------------------------------------------------------------------------- */ + +const char * H5AC_entry_type_names[H5AC_NTYPES] = +{ + "B-tree nodes", + "symbol table nodes", + "local heaps", + "global heaps", + "object headers" +}; + int -H5AC_create(H5F_t *f, int size_hint) +H5AC_create(const H5F_t *f, int UNUSED size_hint) { - H5AC_t *cache = NULL; - int ret_value; /* Return value */ + H5AC_t *cache = NULL; + int ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5AC_create, FAIL); + FUNC_ENTER_NOAPI(H5AC_create, FAIL) - assert(f); - assert(NULL == f->shared->cache); - if (size_hint < 1) size_hint = H5AC_NSLOTS; - - if (NULL==(f->shared->cache = cache = H5FL_CALLOC(H5AC_t))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - cache->nslots = size_hint; - if (NULL==( cache->slot = H5FL_SEQ_CALLOC(H5AC_info_ptr_t,cache->nslots))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - if (NULL==( cache->dslot = H5FL_SEQ_CALLOC(H5AC_info_ptr_t,cache->nslots))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); -#ifdef H5AC_DEBUG - if ((cache->prot = H5FL_SEQ_CALLOC(H5AC_prot_t,cache->nslots))==NULL) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); -#endif /* H5AC_DEBUG */ + HDassert(f); + HDassert(NULL == f->shared->cache); - /* Set return value */ - ret_value=size_hint; + /* this is test code that should be removed when we start passing + * in proper size hints. + * -- JRM + */ + cache = H5C_create(H5C__DEFAULT_MAX_CACHE_SIZE, + H5C__DEFAULT_MIN_CLEAN_SIZE, + (H5AC_NTYPES - 1), + (const char **)H5AC_entry_type_names, + H5AC_check_if_write_permitted); + + if ( NULL == cache ) { + + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + + } else { + + f->shared->cache = cache; + + } done: - if(ret_value<0) { - if(cache!=NULL) { - if(cache->dslot !=NULL) - cache->dslot = H5FL_SEQ_FREE (H5AC_info_ptr_t,cache->dslot); - if(cache->slot !=NULL) - cache->slot = H5FL_SEQ_FREE (H5AC_info_ptr_t,cache->slot); -#ifdef H5AC_DEBUG - if(cache->prot !=NULL) - cache->prot = H5FL_SEQ_FREE (H5AC_prot_t,cache->prot); -#endif /* H5AC_DEBUG */ - f->shared->cache = H5FL_FREE (H5AC_t,f->shared->cache); + + if ( ret_value < 0 ) { + + if ( cache != NULL ) { + + H5C_dest_empty(cache); + f->shared->cache = NULL; + } /* end if */ + } /* end if */ - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5AC_create() */ /*------------------------------------------------------------------------- @@ -426,6 +410,15 @@ done: * * Modifications: * + * Complete re-design and re-write to support the re-designed + * metadata cache. + * JRM - 5/12/04 + * + * Abstracted the guts of the function to H5C_dest() in H5C.c, + * and then re-wrote the function as a wrapper for H5C_dest(). + * + * JRM - 6/7/04 + * *------------------------------------------------------------------------- */ herr_t @@ -434,92 +427,59 @@ H5AC_dest(H5F_t *f, hid_t dxpl_id) H5AC_t *cache = NULL; herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5AC_dest, FAIL); + FUNC_ENTER_NOAPI(H5AC_dest, FAIL) assert(f); assert(f->shared->cache); cache = f->shared->cache; - if (H5AC_flush(f, dxpl_id, NULL, HADDR_UNDEF, H5F_FLUSH_INVALIDATE) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache"); + f->shared->cache = NULL; -#ifdef H5AC_DEBUG - { - unsigned i; - for (i=0; inslots; i++) { - cache->prot[i].slot = H5MM_xfree(cache->prot[i].slot); - cache->prot[i].aprots = 0; - cache->prot[i].nprots = 0; - } - cache->prot = H5FL_SEQ_FREE(H5AC_prot_t,cache->prot); - } -#endif + if ( H5C_dest(f, dxpl_id, H5AC_noblock_dxpl_id, cache) < 0 ) { - cache->dslot = H5FL_SEQ_FREE(H5AC_info_ptr_t,cache->dslot); - cache->slot = H5FL_SEQ_FREE(H5AC_info_ptr_t,cache->slot); - cache->nslots = 0; - f->shared->cache = cache = H5FL_FREE(H5AC_t,cache); + HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "can't destroy cache") + } done: - FUNC_LEAVE_NOAPI(ret_value); -} - -/*------------------------------------------------------------------------- - * Function: H5AC_compare - * - * Purpose: Compare two hash entries by address. Unused entries are - * all equal to one another and greater than all used entries. - * - * Return: Success: -1, 0, 1 - * - * Failure: never fails - * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 12 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static int -H5AC_compare(const void *_a, const void *_b) -{ - int a = *((const int *) _a); - int b = *((const int *) _b); - int ret_value=0; - H5AC_info_t *slot_a; - H5AC_info_t *slot_b; - - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5AC_compare); - - assert(current_cache_g); - - /* Create aliases for slots */ - slot_a=current_cache_g->slot[a]; - slot_b=current_cache_g->slot[b]; - - assert(slot_a); - assert(slot_b); - assert(slot_a->type); - assert(slot_b->type); - - if (slot_a->addr < slot_b->addr) { - ret_value=(-1); - } else if (slot_a->addr > slot_b->addr) { - ret_value=1; - } + FUNC_LEAVE_NOAPI(ret_value) - FUNC_LEAVE_NOAPI(ret_value); -} +} /* H5AC_dest() */ /*------------------------------------------------------------------------- * Function: H5AC_flush * - * Purpose: Flushes (and destroys if DESTROY is non-zero) the specified + * Purpose: Flush (and possibly destroy) the metadata cache associated + * with the specified file. + * + * This is a re-write of an earlier version of the function + * which was reputedly capable of flushing (and destroying + * if requested) individual entries, individual entries if + * they match the supplied type, all entries of a given type, + * as well as all entries in the cache. + * + * As only this last capability is actually used at present, + * I have not implemented the other capabilities in this + * version of the function. + * + * The type and addr parameters are retained to avoid source + * code changed, but values other than NULL and HADDR_UNDEF + * respectively are errors. If all goes well, they should + * be removed, and the function renamed to something more + * descriptive -- perhaps H5AC_flush_cache. + * + * If the cache contains protected entries, the function will + * fail, as protected entries cannot be flushed. However + * all unprotected entries should be flushed before the + * function returns failure. + * + * For historical purposes, the original version of the + * purpose section is reproduced below: + * + * ============ Original Version of "Purpose:" ============ + * + * Flushes (and destroys if DESTROY is non-zero) the specified * entry from the cache. If the entry TYPE is CACHE_FREE and * ADDR is HADDR_UNDEF then all types of entries are * flushed. If TYPE is CACHE_FREE and ADDR is defined then @@ -540,258 +500,43 @@ H5AC_compare(const void *_a, const void *_b) * Modifications: * Robb Matzke, 1999-07-27 * The ADDR argument is passed by value. + * + * Complete re-write. See above for details. -- JRM 5/11/04 + * + * Abstracted the guts of the function to H5C_dest() in H5C.c, + * and then re-wrote the function as a wrapper for H5C_dest(). + * + * JRM - 6/7/04 + * *------------------------------------------------------------------------- */ herr_t -H5AC_flush(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, unsigned flags) +H5AC_flush(H5F_t *f, hid_t dxpl_id, unsigned flags) { - unsigned i; - herr_t status; - H5AC_flush_func_t flush=NULL; /* 'flush' callback for an object */ - H5AC_info_t **info; - int *map = NULL; - hbool_t destroy=(flags&H5F_FLUSH_INVALIDATE)>0; /* Flag for destroying objects */ - hbool_t clear_only=(flags&H5F_FLUSH_CLEAR_ONLY)>0; /* Flag for only clearing objects */ - unsigned nslots; - H5AC_t *cache; + herr_t status; herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5AC_flush, FAIL); + FUNC_ENTER_NOAPI(H5AC_flush, FAIL) - assert(f); - assert(f->shared->cache); + HDassert(f); + HDassert(f->shared->cache); - /* Get local copy of this information */ - cache = f->shared->cache; - - if (!H5F_addr_defined(addr)) { - unsigned first_flush=1; /* Indicate if this is the first flush */ + status = H5C_flush_cache(f, + dxpl_id, + H5AC_noblock_dxpl_id, + f->shared->cache, + flags); - /* - * Sort the cache entries by address since flushing them in - * ascending order by address is much more efficient. - */ - if (NULL==(map=H5FL_SEQ_MALLOC(int,cache->nslots))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); -#ifdef H5_HAVE_PARALLEL - /* If MPIO, MPIPOSIX, or FPHDF5 is used, do special parallel I/O actions */ - if(IS_H5FD_MPI(f)) { - H5AC_info_t **dinfo; -#ifdef H5AC_DEBUG - H5AC_subid_t type_id; -#endif /* H5AC_DEBUG */ -#ifndef NDEBUG - H5P_genplist_t *dxpl; /* Dataset transfer property list */ - H5FD_mpio_xfer_t xfer_mode; /* I/O transfer mode property value */ - - /* Get the dataset transfer property list */ - if (NULL == (dxpl = H5I_object(dxpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list"); - - /* Get the transfer mode property */ - if(H5P_get(dxpl, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve xfer mode"); - - /* Sanity check transfer mode */ - assert(xfer_mode==H5FD_MPIO_COLLECTIVE); -#endif /* NDEBUG */ - - /* Create the mapping */ - for (i = nslots = 0; i < cache->nslots; i++) { - info = cache->slot + i; - dinfo = cache->dslot + i; - - /* Move dirty metadata from 'held' slots into 'regular' slots */ - if((*dinfo)!=NULL) { - H5AC_dest_func_t dest; - - /* Various sanity checks */ - assert((*dinfo)->is_dirty); - assert((*info)!=NULL); - assert((*info)->is_dirty==0); - -#ifdef H5AC_DEBUG - type_id=(*info)->type->id; /* Remember this for later */ -#endif /* H5AC_DEBUG */ - - /* Destroy 'current' information */ - dest = (*info)->type->dest; - if ((dest)(f, (*info))<0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "unable to free cached object"); - - /* Restore 'held' information back to 'current' information */ - (*info)=(*dinfo); - - /* Clear 'held' information */ - (*dinfo)=NULL; - -#ifdef H5AC_DEBUG - cache->diagnostics[type_id].nrestores++; -#endif /* H5AC_DEBUG */ - } /* end if */ - if ((*info)) - map[nslots++] = i; - } /* end for */ - } /* end if */ - else { -#endif /* H5_HAVE_PARALLEL */ - for (i = nslots = 0; i < cache->nslots; i++) { - if (cache->slot[i]!=NULL) - map[nslots++] = i; - } -#ifdef H5_HAVE_PARALLEL - } /* end else */ -#endif /* H5_HAVE_PARALLEL */ - assert(NULL == current_cache_g); - current_cache_g = cache; - HDqsort(map, nslots, sizeof(int), H5AC_compare); - current_cache_g = NULL; -#ifndef NDEBUG - for (i = 1; i < nslots; i++) - assert(H5F_addr_lt(cache->slot[map[i - 1]]->addr, cache->slot[map[i]]->addr)); -#endif - - /* - * Look at all cache entries. - */ - for (i = 0; i < nslots; i++) { - info = cache->slot + map[i]; - assert(*info); - if (!type || type == (*info)->type) { -#ifdef H5AC_DEBUG - H5AC_subid_t type_id=(*info)->type->id; /* Remember this for later */ -#endif /* H5AC_DEBUG */ - - /* Clear the dirty flag only, if requested */ - if(clear_only) { - /* Call the callback routine to clear all dirty flags for object */ - if(((*info)->type->clear)(*info)<0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to clear cache"); - } /* end if */ - else { - flush = (*info)->type->flush; - - /* Only block for all the processes on the first piece of metadata */ - if(first_flush && (*info)->is_dirty) { - status = (flush)(f, dxpl_id, destroy, (*info)->addr, (*info)); - first_flush=0; - } /* end if */ - else - status = (flush)(f, H5AC_noblock_dxpl_id, destroy, (*info)->addr, (*info)); - if (status < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache"); -#ifdef H5AC_DEBUG - cache->diagnostics[type_id].nflushes++; -#endif /* H5AC_DEBUG */ - } /* end else */ - - /* Destroy entry also, if asked */ - if (destroy) - (*info)= NULL; - } - } - - /* - * If there are protected object then fail. However, everything - * else should have been flushed. - */ - if (cache->nprots > 0) - HGOTO_ERROR(H5E_CACHE, H5E_PROTECT, FAIL, "cache has protected items"); - } else { - i = H5AC_HASH(f, addr); - info = cache->slot + i; -#ifdef H5_HAVE_PARALLEL - /* If MPIO, MPIPOSIX, or FPHDF5 is used, do special parallel I/O actions */ - if(IS_H5FD_MPI(f)) { - H5AC_info_t **dinfo; -#ifdef H5AC_DEBUG - H5AC_subid_t type_id; -#endif /* H5AC_DEBUG */ -#ifndef NDEBUG - H5P_genplist_t *dxpl; /* Dataset transfer property list */ - H5FD_mpio_xfer_t xfer_mode; /* I/O transfer mode property value */ - - /* Get the dataset transfer property list */ - if (NULL == (dxpl = H5I_object(dxpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list"); - - /* Get the transfer mode property */ - if(H5P_get(dxpl, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve xfer mode"); - - /* Sanity check transfer mode */ - assert(xfer_mode==H5FD_MPIO_COLLECTIVE); -#endif /* NDEBUG */ - - dinfo = cache->dslot + i; - - /* Restore dirty metadata from 'held' slot to 'current' slot */ - if((*dinfo)!=NULL) { - H5AC_dest_func_t dest; - - /* Various sanity checks */ - assert((*dinfo)->is_dirty); - assert((*info)!=NULL); - assert((*info)->is_dirty==0); - -#ifdef H5AC_DEBUG - type_id=(*info)->type->id; /* Remember this for later */ -#endif /* H5AC_DEBUG */ - - /* Destroy 'current' information */ - dest = (*info)->type->dest; - if ((dest)(f, (*info))<0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "unable to free cached object"); - - /* Restore 'held' information back to 'current' information */ - (*info)=(*dinfo); - - /* Clear 'held' information */ - (*dinfo)=NULL; - -#ifdef H5AC_DEBUG - cache->diagnostics[type_id].nrestores++; -#endif /* H5AC_DEBUG */ - } /* end if */ - } /* end if */ -#endif /* H5_HAVE_PARALLEL */ - if ((*info) && (!type || (*info)->type == type) && - H5F_addr_eq((*info)->addr, addr)) { -#ifdef H5AC_DEBUG - H5AC_subid_t type_id=(*info)->type->id; /* Remember this for later */ -#endif /* H5AC_DEBUG */ - - /* - * Flush just this entry. - */ - - /* Clear the dirty flag only, if requested */ - if(clear_only) { - /* Call the callback routine to clear all dirty flags for object */ - if(((*info)->type->clear)(*info)<0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to clear cache"); - } /* end if */ - else { - flush = (*info)->type->flush; - if((flush)(f, dxpl_id, destroy, (*info)->addr, (*info)) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush object"); -#ifdef H5AC_DEBUG - cache->diagnostics[type_id].nflushes++; -#endif /* H5AC_DEBUG */ - } /* end else */ + if ( status < 0 ) { - /* Destroy entry also, if asked */ - if (destroy) - (*info)= NULL; - } /* end if */ - } /* end else */ + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush entry.") + } done: - if(map!=NULL) - map = H5FL_SEQ_FREE(int,map); - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5AC_flush() */ /*------------------------------------------------------------------------- @@ -813,143 +558,69 @@ done: * Modifications: * Robb Matzke, 1999-07-27 * The ADDR argument is passed by value. + * + * Bill Wendling, 2003-09-16 + * Added automatic "flush" if the FPHDF5 driver is being + * used. This'll write the metadata to the SAP where other, + * lesser processes can grab it. + * + * JRM - 5/13/04 + * Complete re-write for the new metadata cache. The new + * code is functionally almost identical to the old, although + * the sanity check for a protected entry is now an assert + * at the beginning of the function. + * + * JRM - 6/7/04 + * Abstracted the guts of the function to H5C_insert_entry() + * in H5C.c, and then re-wrote the function as a wrapper for + * H5C_insert_entry(). + * *------------------------------------------------------------------------- */ herr_t H5AC_set(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, void *thing) { - unsigned idx; - H5AC_flush_func_t flush; - H5AC_info_t **info; - H5AC_t *cache; + herr_t result; + H5AC_info_t *info; + H5AC_t *cache; herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5AC_set, FAIL); + FUNC_ENTER_NOAPI(H5AC_set, FAIL) - assert(f); - assert(f->shared->cache); - assert(type); - assert(type->flush); - assert(H5F_addr_defined(addr)); - assert(thing); + HDassert(f); + HDassert(f->shared->cache); + HDassert(type); + HDassert(type->flush); + HDassert(type->size); + HDassert(H5F_addr_defined(addr)); + HDassert(thing); /* Get local copy of this information */ - idx = H5AC_HASH(f, addr); cache = f->shared->cache; - info = cache->slot + idx; - -#ifdef H5AC_DEBUG - { - H5AC_prot_t *prot = NULL; - int i; + info = (H5AC_info_t *)thing; - prot = cache->prot + idx; - for (i = 0; i < prot->nprots; i++) - assert(H5F_addr_ne(addr, prot->slot[i]->addr)); - } -#endif + info->addr = addr; + info->type = type; + info->is_protected = FALSE; -#ifdef H5_HAVE_PARALLEL - /* If MPIO, MPIPOSIX, or FPHDF5 is used, do special parallel I/O actions */ - if(IS_H5FD_MPI(f)) { - H5AC_info_t **dinfo; -#ifdef H5AC_DEBUG - H5AC_subid_t type_id; -#endif /* H5AC_DEBUG */ - H5P_genplist_t *dxpl; /* Dataset transfer property list */ - H5FD_mpio_xfer_t xfer_mode; /* I/O transfer mode property value */ + result = H5C_insert_entry(f, + dxpl_id, + H5AC_noblock_dxpl_id, + cache, + type, + addr, + thing); - /* Get the dataset transfer property list */ - if (NULL == (dxpl = H5I_object(dxpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list"); + if ( result < 0 ) { - /* Get the transfer mode property */ - if(H5P_get(dxpl, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve xfer mode"); - - /* Get pointer to 'held' information */ - dinfo = cache->dslot + idx; - - /* Sanity check transfer mode */ - if(xfer_mode==H5FD_MPIO_COLLECTIVE) { - /* Check for dirty metadata */ - if(*dinfo) { - H5AC_dest_func_t dest; - - /* Various sanity checks */ - assert((*dinfo)->is_dirty); - assert((*info)!=NULL); - assert((*info)->is_dirty==0); - -#ifdef H5AC_DEBUG - type_id=(*info)->type->id; /* Remember this for later */ -#endif /* H5AC_DEBUG */ - - /* Destroy 'current' information */ - dest = (*info)->type->dest; - if ((dest)(f, (*info))<0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "unable to free cached object"); - - /* Restore 'held' information back to 'current' information */ - (*info)=(*dinfo); - - /* Clear 'held' information */ - (*dinfo)=NULL; - -#ifdef H5AC_DEBUG - cache->diagnostics[type_id].nrestores++; -#endif /* H5AC_DEBUG */ - } /* end if */ - } /* end if */ - else { - /* Sanity check */ - assert((*dinfo)==NULL); - assert(xfer_mode==H5FD_MPIO_INDEPENDENT); - - /* Make certain there will be no write of dirty metadata */ - if((*info) && (*info)->is_dirty) { - /* Sanity check new item */ - assert(((H5AC_info_t*)thing)->is_dirty==0); - - /* 'Hold' the current metadata for later */ - (*dinfo)=(*info); - - /* Reset the 'current' metadata, so it doesn't get flushed */ - (*info)=NULL; - -#ifdef H5AC_DEBUG - cache->diagnostics[(*dinfo)->type->id].nholds++; -#endif /* H5AC_DEBUG */ - } /* end if */ - } /* end else */ - } /* end if */ -#endif /* H5_HAVE_PARALLEL */ + HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, FAIL, "H5C_insert_entry() failed") + } - /* Flush any object already in cache slot */ - if ((*info)) { -#ifdef H5AC_DEBUG - H5AC_subid_t type_id=(*info)->type->id; /* Remember this for later */ -#endif /* H5AC_DEBUG */ - - flush = (*info)->type->flush; - if ((flush)(f, dxpl_id, TRUE, (*info)->addr, (*info)) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush object"); -#ifdef H5AC_DEBUG - cache->diagnostics[type_id].nflushes++; -#endif /* H5AC_DEBUG */ - } /* end if */ +done: - /* Cache this item */ - (*info)=thing; - (*info)->type = type; - (*info)->addr = addr; -#ifdef H5AC_DEBUG - cache->diagnostics[type->id].ninits++; -#endif /* H5AC_DEBUG */ + FUNC_LEAVE_NOAPI(ret_value) -done: - FUNC_LEAVE_NOAPI(ret_value); -} +} /* H5AC_set() */ /*------------------------------------------------------------------------- @@ -971,205 +642,74 @@ done: * Modifications: * Robb Matzke, 1999-07-27 * The OLD_ADDR and NEW_ADDR arguments are passed by value. + * + * JRM 5/17/04 + * Complete rewrite for the new meta-data cache. + * + * JRM - 6/7/04 + * Abstracted the guts of the function to H5C_rename_entry() + * in H5C.c, and then re-wrote the function as a wrapper for + * H5C_rename_entry(). + * *------------------------------------------------------------------------- */ herr_t -H5AC_rename(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t old_addr, +H5AC_rename(H5F_t *f, hid_t UNUSED dxpl_id, const H5AC_class_t *type, haddr_t old_addr, haddr_t new_addr) { - unsigned old_idx, new_idx; - H5AC_flush_func_t flush; - H5AC_t *cache; - H5AC_info_t **new_info = NULL; - H5AC_info_t **old_info = NULL; + herr_t result; herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5AC_rename, FAIL); - - assert(f); - assert(f->shared->cache); - assert(type); - - /* Get local copy of this information */ - old_idx = H5AC_HASH(f, old_addr); - new_idx = H5AC_HASH(f, new_addr); - cache = f->shared->cache; - new_info = cache->slot + new_idx; - old_info = cache->slot + old_idx; - -#ifdef H5AC_DEBUG - { - H5AC_prot_t *prot = NULL; - int i; - - prot = cache->prot + old_idx; - for (i = 0; i < prot->nprots; i++) - assert(H5F_addr_ne(old_addr, prot->slot[i]->addr)); - prot = cache->prot + new_idx; - for (i = 0; i < prot->nprots; i++) - assert(H5F_addr_ne(new_addr, prot->slot[i]->addr)); - } -#endif + FUNC_ENTER_NOAPI(H5AC_rename, FAIL) - /* - * We don't need to do anything if the object isn't cached or if the - * new hash value is the same as the old one. - */ - if (H5F_addr_ne((*old_info)->addr, old_addr) || (*old_info)->type!=type) - HGOTO_DONE(SUCCEED); - if (old_idx == new_idx) { - (*old_info)->addr = new_addr; - HGOTO_DONE(SUCCEED); - } + HDassert(f); + HDassert(f->shared->cache); + HDassert(type); + HDassert(H5F_addr_defined(old_addr)); + HDassert(H5F_addr_defined(new_addr)); + HDassert(H5F_addr_ne(old_addr, new_addr)); -#ifdef H5_HAVE_PARALLEL - /* If MPIO, MPIPOSIX, or FPHDF5 is used, do special parallel I/O actions */ - if(IS_H5FD_MPI(f)) { - H5AC_info_t **new_dinfo; -#ifdef H5AC_DEBUG - H5AC_subid_t type_id; -#endif /* H5AC_DEBUG */ - H5P_genplist_t *dxpl; /* Dataset transfer property list */ - H5FD_mpio_xfer_t xfer_mode; /* I/O transfer mode property value */ + result = H5C_rename_entry(f, + f->shared->cache, + type, + old_addr, + new_addr); - /* Get the dataset transfer property list */ - if (NULL == (dxpl = H5I_object(dxpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list"); + if ( result < 0 ) { - /* Get the transfer mode property */ - if(H5P_get(dxpl, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve xfer mode"); - - /* Get pointer to new 'held' information */ - new_dinfo = cache->dslot + new_idx; - - /* Sanity check transfer mode */ - if(xfer_mode==H5FD_MPIO_COLLECTIVE) { - /* Check for dirty metadata */ - if(*new_dinfo) { - H5AC_dest_func_t dest; - - /* Various sanity checks */ - assert((*new_dinfo)->is_dirty); - assert((*new_info)!=NULL); - assert((*new_info)->is_dirty==0); - -#ifdef H5AC_DEBUG - type_id=(*new_info)->type->id; /* Remember this for later */ -#endif /* H5AC_DEBUG */ - - /* Destroy 'current' information */ - dest = (*new_info)->type->dest; - if ((dest)(f, (*new_info))<0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "unable to free cached object"); - - /* Restore 'held' information back to 'current' information */ - (*new_info)=(*new_dinfo); - - /* Clear 'held' information */ - (*new_dinfo)=NULL; - -#ifdef H5AC_DEBUG - cache->diagnostics[type_id].nrestores++; -#endif /* H5AC_DEBUG */ - } /* end if */ - } /* end if */ - else { - /* Sanity check that there will be no write of dirty metadata */ - assert((*new_dinfo)==NULL); - assert(xfer_mode==H5FD_MPIO_INDEPENDENT); - - /* Make certain there will be no write of dirty metadata */ - if((*new_info) && (*new_info)->is_dirty) { - /* Sanity check that we won't put two pieces of dirty metadata in same cache location */ - assert((*old_info)->is_dirty==0); - - /* 'Hold' the current metadata for later */ - (*new_dinfo)=(*new_info); - - /* Reset the 'current' metadata, so it doesn't get flushed */ - (*new_info)=NULL; - -#ifdef H5AC_DEBUG - cache->diagnostics[(*new_dinfo)->type->id].nholds++; -#endif /* H5AC_DEBUG */ - } /* end if */ - } /* end else */ - } /* end if */ -#endif /* H5_HAVE_PARALLEL */ - - /* - * Free the item from the destination cache line. - */ - if (*new_info) { -#ifdef H5AC_DEBUG - H5AC_subid_t type_id=(*new_info)->type->id; /* Remember this for later */ -#endif /* H5AC_DEBUG */ - - flush = (*new_info)->type->flush; - if ( (flush)(f, dxpl_id, TRUE, (*new_info)->addr, (*new_info)) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush object"); -#ifdef H5AC_DEBUG - cache->diagnostics[type_id].nflushes++; -#endif /* H5AC_DEBUG */ + HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, FAIL, \ + "H5C_rename_entry() failed.") } - /* - * Move the source to the destination (it might not be cached) - */ - (*new_info)= (*old_info); - (*new_info)->addr = new_addr; - -#ifdef H5_HAVE_PARALLEL - /* If MPIO, MPIPOSIX, or FPHDF5 is used, do special parallel I/O actions */ - if(IS_H5FD_MPI(f)) { - H5AC_info_t **old_dinfo; -#ifdef H5AC_DEBUG - H5AC_subid_t type_id; -#endif /* H5AC_DEBUG */ - - /* Get pointer to new 'held' information */ - old_dinfo = cache->dslot + old_idx; - - /* Check for 'held' metadata in old location & restore it, if so */ - if(*old_dinfo) { - /* Sanity check */ - assert((*old_dinfo)->is_dirty); - -#ifdef H5AC_DEBUG - type_id=(*old_info)->type->id; /* Remember this for later */ -#endif /* H5AC_DEBUG */ - - /* Restore 'held' information back to 'current' information */ - (*old_info)=(*old_dinfo); - - /* Clear 'held' information */ - (*old_dinfo)=NULL; - -#ifdef H5AC_DEBUG - cache->diagnostics[type_id].nrestores++; -#endif /* H5AC_DEBUG */ - } /* end if */ - else - (*old_info)= NULL; - } /* end if */ - else { -#endif /* H5_HAVE_PARALLEL */ +done: - (*old_info)= NULL; -#ifdef H5_HAVE_PARALLEL - } /* end else */ -#endif /* H5_HAVE_PARALLEL */ + FUNC_LEAVE_NOAPI(ret_value) -done: - FUNC_LEAVE_NOAPI(ret_value); -} +} /* H5AC_rename() */ /*------------------------------------------------------------------------- * Function: H5AC_protect * - * Purpose: Similar to H5AC_find() except the object is removed from + * Purpose: If the target entry is not in the cache, load it. If + * necessary, attempt to evict one or more entries to keep + * the cache within its maximum size. + * + * Mark the target entry as protected, and return its address + * to the caller. The caller must call H5AC_unprotect() when + * finished with the entry. + * + * While it is protected, the entry may not be either evicted + * or flushed -- nor may it be accessed by another call to + * H5AC_protect. Any attempt to do so will result in a failure. + * + * This comment is a re-write of the original Purpose: section. + * For historical interest, the original version is reproduced + * below: + * + * Original Purpose section: + * + * Similar to H5AC_find() except the object is removed from * the cache and given to the caller, preventing other parts * of the program from modifying the protected object or * preempting it from the cache. @@ -1191,6 +731,20 @@ done: * Modifications: * Robb Matzke, 1999-07-27 * The ADDR argument is passed by value. + * + * Bill Wendling, 2003-09-10 + * Added parameter to indicate whether this is a READ or + * WRITE type of protect. + * + * JRM -- 5/17/04 + * Complete re-write for the new client cache. See revised + * Purpose section above. + * + * JRM - 6/7/04 + * Abstracted the guts of the function to H5C_protect() + * in H5C.c, and then re-wrote the function as a wrapper for + * H5C_protect(). + * *------------------------------------------------------------------------- */ void * @@ -1204,190 +758,68 @@ H5AC_protect(H5F_t *f, UNUSED rw) { - int idx; - void *thing=NULL; - H5AC_t *cache; - H5AC_info_t **info; - void *ret_value; /* Return value */ - -#ifdef H5AC_DEBUG - H5AC_prot_t *prot = NULL; - static int ncalls = 0; - - if (0 == ncalls++) { - if (H5DEBUG(AC)) { - fprintf(H5DEBUG(AC), "H5AC: debugging cache (expensive)\n"); - } - } -#endif + void * thing = NULL; + void * ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5AC_protect, NULL); + FUNC_ENTER_NOAPI(H5AC_protect, NULL) /* check args */ - assert(f); - assert(f->shared->cache); - assert(type); - assert(type->load); - assert(type->flush); - assert(H5F_addr_defined(addr)); - - /* Get local copy of this information */ - idx = H5AC_HASH(f, addr); - cache = f->shared->cache; - info = cache->slot + idx; -#ifdef H5AC_DEBUG - prot = cache->prot + idx; -#endif /* H5AC_DEBUG */ - -#ifdef H5_HAVE_PARALLEL - /* If MPIO, MPIPOSIX, or FPHDF5 is used, do special parallel I/O actions */ - if(IS_H5FD_MPI(f)) { - H5AC_info_t **dinfo; - - /* Get pointer to new 'held' information */ - dinfo = cache->dslot + idx; - - /* Check for 'held' metadata in location & handle it */ - if(*dinfo) { - /* Sanity checks */ - assert((*dinfo)->is_dirty); - assert((*info)); - assert((*info)->is_dirty==0); - assert((*dinfo)->addr!=(*info)->addr); - - /* Is 'held' metadata the metadata we are looking for? */ - if (H5F_addr_eq((*dinfo)->addr, addr) -#ifdef H5AC_DEBUG - && (*dinfo)->type==type -#endif /* H5AC_DEBUG */ - ) { -#ifndef H5AC_DEBUG - /* Sanity check that the object in the cache is the correct type */ - assert((*dinfo)->type==type); -#endif /* H5AC_DEBUG */ - /* - * The object is already cached; simply remove it from the cache. - */ - thing = (*dinfo); - (*dinfo)->type = NULL; - (*dinfo)->addr = HADDR_UNDEF; - (*dinfo)= NULL; -#ifdef H5AC_DEBUG - cache->diagnostics[(*dinfo)->type->id].nhits++; -#endif /* H5AC_DEBUG */ - } /* end if */ - /* 'held' metadata isn't what we are looking for, but check for 'current' metadata */ - else { - if(H5F_addr_eq((*info)->addr, addr) -#ifdef H5AC_DEBUG - && (*info)->type==type -#endif /* H5AC_DEBUG */ - ) { -#ifndef H5AC_DEBUG - /* Sanity check that the object in the cache is the correct type */ - assert((*info)->type==type); -#endif /* H5AC_DEBUG */ - /* - * The object is already cached; remove it from the cache. - * and bring the 'held' object into the 'regular' information - */ - thing = (*info); - (*info)->type = NULL; - (*info)->addr = HADDR_UNDEF; - (*info)= (*dinfo); - (*dinfo)= NULL; -#ifdef H5AC_DEBUG - cache->diagnostics[(*info)->type->id].nhits++; -#endif /* H5AC_DEBUG */ - } /* end if */ - } /* end else */ - } /* end if */ - } /* end if */ - - /* Check if we've already found the object to protect */ - if(thing==NULL) { -#endif /* H5_HAVE_PARALLEL */ - if ((*info) && H5F_addr_eq(addr,(*info)->addr) -#ifdef H5AC_DEBUG - && (*info)->type==type -#endif /* H5AC_DEBUG */ - ) { -#ifndef H5AC_DEBUG - /* Sanity check that the object in the cache is the correct type */ - assert((*info)->type==type); -#endif /* H5AC_DEBUG */ - - /* - * The object is already cached; simply remove it from the cache. - */ - thing = (*info); -#ifdef H5AC_DEBUG - cache->diagnostics[(*info)->type->id].nhits++; -#endif /* H5AC_DEBUG */ - (*info)->type = NULL; - (*info)->addr = HADDR_UNDEF; - (*info)= NULL; - } else { -#ifdef H5AC_DEBUG - /* - * Check that the requested thing isn't protected, for protected things - * can only be modified through the pointer already handed out by the - * H5AC_protect() function. - */ - int i; - - for (i = 0; i < prot->nprots; i++) - assert(H5F_addr_ne(addr, prot->slot[i]->addr)); -#endif /* H5AC_DEBUG */ - - /* - * Load a new thing. If it can't be loaded, then return an error - * without preempting anything. - */ - if (NULL == (thing = (type->load)(f, dxpl_id, addr, udata1, udata2))) - HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "unable to load object"); -#ifdef H5AC_DEBUG - cache->diagnostics[type->id].nmisses++; -#endif /* H5AC_DEBUG */ - } -#ifdef H5_HAVE_PARALLEL - } /* end if */ -#endif /* H5_HAVE_PARALLEL */ - -#ifdef H5AC_DEBUG - /* - * Add the protected object to the protect debugging fields of the - * cache. - */ - if (prot->nprots >= prot->aprots) { - size_t na = prot->aprots + 10; - H5AC_info_t **x = H5MM_realloc(prot->slot, na * sizeof(H5AC_info_t *)); - - if (NULL==x) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - prot->aprots = (int)na; - prot->slot = x; + HDassert(f); + HDassert(f->shared->cache); + HDassert(type); + HDassert(type->flush); + HDassert(type->load); + HDassert(H5F_addr_defined(addr)); + + + thing = H5C_protect(f, + dxpl_id, + H5AC_noblock_dxpl_id, + f->shared->cache, + type, + addr, + udata1, + udata2); + + if ( thing == NULL ) { + + HGOTO_ERROR(H5E_CACHE, H5E_PROTECT, NULL, "H5C_protect() failed.") } - prot->slot[prot->nprots]= thing; - prot->slot[prot->nprots]->type = type; - prot->slot[prot->nprots]->addr = addr; - prot->nprots += 1; -#endif /* H5AC_DEBUG */ - - cache->nprots += 1; /* Set return value */ - ret_value=thing; + ret_value = thing; done: - FUNC_LEAVE_NOAPI(ret_value); -} + + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5AC_protect() */ /*------------------------------------------------------------------------- * Function: H5AC_unprotect * - * Purpose: This function should be called to undo the effect of + * Purpose: Undo an H5AC_protect() call -- specifically, mark the + * entry as unprotected, remove it from the protected list, + * and give it back to the replacement policy. + * + * The TYPE and ADDR arguments must be the same as those in + * the corresponding call to H5AC_protect() and the THING + * argument must be the value returned by that call to + * H5AC_protect(). + * + * If the deleted flag is TRUE, simply remove the target entry + * from the cache, clear it, and free it without writing it to + * disk. + * + * This verion of the function is a complete re-write to + * use the new metadata cache. While there isn't all that + * much difference between the old and new Purpose sections, + * the original version is given below. + * + * Original purpose section: + * + * This function should be called to undo the effect of * H5AC_protect(). The TYPE and ADDR arguments should be the * same as the corresponding call to H5AC_protect() and the * THING argument should be the value returned by H5AC_protect(). @@ -1405,265 +837,188 @@ done: * Sep 2 1997 * * Modifications: - * Robb Matzke, 1999-07-27 + * Robb Matzke, 1999-07-27 * The ADDR argument is passed by value. * - * Quincey Koziol, 2003-03-19 + * Quincey Koziol, 2003-03-19 * Added "deleted" argument + * + * Bill Wendling, 2003-09-18 + * If this is an FPHDF5 driver and the data is dirty, + * perform a "flush" that writes the data to the SAP. + * + * John Mainzer 5/19/04 + * Complete re-write for the new metadata cache. + * + * JRM - 6/7/04 + * Abstracted the guts of the function to H5C_unprotect() + * in H5C.c, and then re-wrote the function as a wrapper for + * H5C_unprotect(). + * *------------------------------------------------------------------------- */ herr_t H5AC_unprotect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, void *thing, hbool_t deleted) { - unsigned idx; - H5AC_flush_func_t flush; - H5AC_t *cache; - H5AC_info_t **info; + herr_t result; herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5AC_unprotect, FAIL); - - /* check args */ - assert(f); - assert(f->shared->cache); - assert(type); - assert(type->flush); - assert(H5F_addr_defined(addr)); - assert(thing); - - /* Get local copy of this information */ - idx = H5AC_HASH(f, addr); - cache = f->shared->cache; - info = cache->slot + idx; - -#ifdef H5AC_DEBUG - /* - * Remove the object's protect data to indicate that it is no longer - * protected. - */ - { - H5AC_prot_t *prot = NULL; - int found, i; - - prot = cache->prot + idx; - for (i = 0, found = FALSE; i < prot->nprots && !found; i++) { - if (H5F_addr_eq(addr, prot->slot[i]->addr)) { - assert(prot->slot[i]->type == type); - HDmemmove(prot->slot + i, prot->slot + i + 1, - ((prot->nprots - i) - 1) * sizeof(H5AC_info_t *)); - prot->nprots -= 1; - found = TRUE; - } - } - assert(found); + FUNC_ENTER_NOAPI(H5AC_unprotect, FAIL) + + HDassert(f); + HDassert(f->shared->cache); + HDassert(type); + HDassert(type->clear); + HDassert(type->flush); + HDassert(H5F_addr_defined(addr)); + HDassert(thing); + HDassert( ((H5AC_info_t *)thing)->addr == addr ); + HDassert( ((H5AC_info_t *)thing)->type == type ); + + result = H5C_unprotect(f, + dxpl_id, + H5AC_noblock_dxpl_id, + f->shared->cache, + type, + addr, + thing, + deleted); + + if ( result < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_NOTCACHED, FAIL, \ + "H5C_unprotect() failed.") } -#endif /* H5AC_DEBUG */ - - /* Don't restore deleted objects to the cache */ - if(!deleted) { -#ifdef H5_HAVE_PARALLEL - /* If MPIO, MPIPOSIX, or FPHDF5 is used, do special parallel I/O actions */ - if(IS_H5FD_MPI(f)) { - H5AC_info_t **dinfo; -#ifdef H5AC_DEBUG - H5AC_subid_t type_id; -#endif /* H5AC_DEBUG */ - H5P_genplist_t *dxpl; /* Dataset transfer property list */ - H5FD_mpio_xfer_t xfer_mode; /* I/O transfer mode property value */ - - /* Get the dataset transfer property list */ - if (NULL == (dxpl = H5I_object(dxpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list"); - - /* Get the transfer mode property */ - if(H5P_get(dxpl, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve xfer mode"); - - /* Get pointer to 'held' information */ - dinfo = cache->dslot + idx; - - /* Sanity check transfer mode */ - if(xfer_mode==H5FD_MPIO_COLLECTIVE) { - /* Check for dirty metadata */ - if(*dinfo) { - H5AC_dest_func_t dest; - - /* Various sanity checks */ - assert((*dinfo)->is_dirty); - assert((*info)!=NULL); - assert((*info)->is_dirty==0); - -#ifdef H5AC_DEBUG - type_id=(*info)->type->id; /* Remember this for later */ -#endif /* H5AC_DEBUG */ - - /* Destroy 'current' information */ - dest = (*info)->type->dest; - if ((dest)(f, (*info))<0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "unable to free cached object"); - - /* Restore 'held' information back to 'current' information */ - (*info)=(*dinfo); - - /* Clear 'held' information */ - (*dinfo)=NULL; - -#ifdef H5AC_DEBUG - cache->diagnostics[type_id].nrestores++; -#endif /* H5AC_DEBUG */ - } /* end if */ - } /* end if */ - else { - /* Sanity check */ - assert((*dinfo)==NULL); - assert(xfer_mode==H5FD_MPIO_INDEPENDENT); - /* Make certain there will be no write of dirty metadata */ - if((*info) && (*info)->is_dirty) { - /* Sanity check new item */ - assert(((H5AC_info_t*)thing)->is_dirty==0); +done: - /* 'Hold' the current metadata for later */ - (*dinfo)=(*info); + FUNC_LEAVE_NOAPI(ret_value) - /* Reset the 'current' metadata, so it doesn't get flushed */ - (*info)=NULL; +} /* H5AC_unprotect() */ -#ifdef H5AC_DEBUG - cache->diagnostics[(*dinfo)->type->id].nholds++; -#endif /* H5AC_DEBUG */ - } /* end if */ - } /* end else */ - } /* end if */ -#endif /* H5_HAVE_PARALLEL */ - - /* - * Flush any object already in the cache at that location. It had - * better not be another copy of the protected object. - */ - if (*info) { -#ifdef H5AC_DEBUG - H5AC_subid_t type_id=(*info)->type->id; /* Remember this for later */ -#endif /* H5AC_DEBUG */ - - assert(H5F_addr_ne((*info)->addr, addr)); - flush = (*info)->type->flush; - if ((flush)(f, dxpl_id, TRUE, (*info)->addr, (*info)) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush object"); -#ifdef H5AC_DEBUG - cache->diagnostics[type_id].nflushes++; -#endif /* H5AC_DEBUG */ - } + +/*------------------------------------------------------------------------- + * Function: H5AC_stats + * + * Purpose: Prints statistics about the cache. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Thursday, October 30, 1997 + * + * Modifications: + * John Mainzer 5/19/04 + * Re-write to support the new metadata cache. + * + * JRM - 6/7/04 + * Abstracted the guts of the function to H5C_stats() + * in H5C.c, and then re-wrote the function as a wrapper for + * H5C_stats(). + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC_stats(H5F_t UNUSED *f) +{ + herr_t ret_value = SUCCEED; /* Return value */ - /* - * Insert the object back into the cache; it is no longer protected. - */ - (*info)=thing; - (*info)->type = type; - (*info)->addr = addr; - } /* end if */ - else { - /* Mark the thing as clean (prerequite for destroy routine) */ - if((type->clear)(thing)<0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to clear object"); + FUNC_ENTER_NOAPI(H5AC_stats, FAIL) - /* Destroy previously cached thing */ - if ((type->dest)(f, thing)<0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "unable to free object"); - } /* end else */ + HDassert(f); + HDassert(f->shared->cache); - /* Decrement the number of protected items outstanding */ - cache->nprots -= 1; + H5C_stats(f->shared->cache, f->name, FALSE); /* at present, this can't fail */ done: - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5AC_stats() */ +/*************************************************************************/ +/**************************** Private Functions: *************************/ +/*************************************************************************/ + /*------------------------------------------------------------------------- - * Function: H5AC_debug * - * Purpose: Prints debugging info about the cache. + * Function: H5AC_check_if_write_permitted * - * Return: Non-negative on success/Negative on failure + * Purpose: Determine if a write is permitted under the current + * circumstances, and set *write_permitted_ptr accordingly. + * As a general rule it is, but when we are running in parallel + * mode with collective I/O, we must ensure that a read cannot + * cause a write. * - * Programmer: Robb Matzke - * Thursday, October 30, 1997 + * In the event of failure, the value of *write_permitted_ptr + * is undefined. + * + * Return: Non-negative on success/Negative on failure. + * + * Programmer: John Mainzer, 5/15/04 * * Modifications: * *------------------------------------------------------------------------- */ -herr_t -H5AC_debug(H5F_t UNUSED *f) + +#ifdef H5_HAVE_PARALLEL +static herr_t +H5AC_check_if_write_permitted(H5F_t *f, + hid_t dxpl_id, + hbool_t * write_permitted_ptr) +#else /* H5_HAVE_PARALLEL */ +static herr_t +H5AC_check_if_write_permitted(H5F_t UNUSED * f, + hid_t UNUSED dxpl_id, + hbool_t * write_permitted_ptr) +#endif /* H5_HAVE_PARALLEL */ { -#ifdef H5AC_DEBUG - H5AC_subid_t i; - char s[32], ascii[32]; - H5AC_t *cache = f->shared->cache; - double miss_rate; -#endif /* H5AC_DEBUG */ - herr_t ret_value=SUCCEED; /* Return value */ + hbool_t write_permitted = TRUE; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5AC_check_if_write_permitted, FAIL) + +#ifdef H5_HAVE_PARALLEL + + if ( IS_H5FD_MPI(f) ) { + + H5P_genplist_t *dxpl; /* Dataset transfer property list */ + H5FD_mpio_xfer_t xfer_mode; /* I/O transfer mode property value */ + + /* Get the dataset transfer property list */ + if ( NULL == (dxpl = H5I_object(dxpl_id)) ) { + + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, \ + "not a dataset creation property list") + + } - FUNC_ENTER_NOAPI(H5AC_debug, FAIL); - -#ifdef H5AC_DEBUG - if (H5DEBUG(AC)) { - fprintf(H5DEBUG(AC), "H5AC: meta data cache statistics for file %s\n", - f->name); - fprintf(H5DEBUG(AC), " %-18s %8s %8s %8s %8s+%-8s\n", - "Layer", "Hits", "Misses", "MissRate", "Inits", "Flushes"); - fprintf(H5DEBUG(AC), " %-18s %8s %8s %8s %8s-%-8s\n", - "-----", "----", "------", "--------", "-----", "-------"); - - for (i = H5AC_BT_ID; i < H5AC_NTYPES; i++) { - - switch (i) { - case H5AC_BT_ID: - HDstrcpy(s, "B-tree nodes"); - break; - case H5AC_SNODE_ID: - HDstrcpy(s, "symbol table nodes"); - break; - case H5AC_LHEAP_ID: - HDstrcpy (s, "local heaps"); - break; - case H5AC_GHEAP_ID: - HDstrcpy (s, "global heaps"); - break; - case H5AC_OHDR_ID: - HDstrcpy(s, "object headers"); - break; - default: - sprintf(s, "unknown id %d", i); - } - - if (cache->diagnostics[i].nhits>0 || - cache->diagnostics[i].nmisses>0) { - miss_rate = 100.0 * cache->diagnostics[i].nmisses / - (cache->diagnostics[i].nhits+ - cache->diagnostics[i].nmisses); - } else { - miss_rate = 0.0; - } - - if (miss_rate > 100) { - sprintf(ascii, "%7d%%", (int) (miss_rate + 0.5)); - } else { - sprintf(ascii, "%7.2f%%", miss_rate); - } - fprintf(H5DEBUG(AC), " %-18s %8u %8u %7s %8u%+-9ld\n", s, - cache->diagnostics[i].nhits, - cache->diagnostics[i].nmisses, - ascii, - cache->diagnostics[i].ninits, - ((long)(cache->diagnostics[i].nflushes) - - (long)(cache->diagnostics[i].ninits))); - } + /* Get the transfer mode property */ + if( H5P_get(dxpl, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0 ) { + + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, \ + "can't retrieve xfer mode") + + } + + if ( xfer_mode == H5FD_MPIO_INDEPENDENT ) { + + write_permitted = FALSE; + + } else { + + HDassert(xfer_mode == H5FD_MPIO_COLLECTIVE ); + + } } -#endif /* H5AC_DEBUG */ + +#endif /* H5_HAVE_PARALLEL */ + + *write_permitted_ptr = write_permitted; done: - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5AC_check_if_write_permitted() */ diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h index c1a44e7..214f38e 100644 --- a/src/H5ACprivate.h +++ b/src/H5ACprivate.h @@ -21,7 +21,9 @@ * Purpose: Constants and typedefs available to the rest of the * library. * - * Modifications: + * Modifications: JRM - 6/4/04 + * Complete re-write for a new caching algorithm + * located in H5C.c * *------------------------------------------------------------------------- */ @@ -34,16 +36,34 @@ /* Pivate headers needed by this header */ #include "H5private.h" /* Generic Functions */ #include "H5Fprivate.h" /* File access */ +#include "H5Cprivate.h" /* cache */ -/* - * Feature: Define H5AC_DEBUG on the compiler command line if you want to - * debug H5AC_protect() and H5AC_unprotect() by insuring that - * nothing accesses protected objects. NDEBUG must not be defined - * in order for this to have any effect. + +#define H5AC_BT_ID 0 /*B-tree nodes */ +#define H5AC_SNODE_ID 1 /*symbol table nodes */ +#define H5AC_LHEAP_ID 2 /*local heap */ +#define H5AC_GHEAP_ID 3 /*global heap */ +#define H5AC_OHDR_ID 4 /*object header */ +#define H5AC_NTYPES 5 + +/* H5AC_DUMP_STATS_ON_CLOSE should always be FALSE when + * H5C_COLLECT_CACHE_STATS is FALSE. + * + * When H5C_COLLECT_CACHE_STATS is TRUE, H5AC_DUMP_STATS_ON_CLOSE must + * be FALSE for "make check" to succeed, but may be set to TRUE at other + * times for debugging purposes. + * + * Hence the following, somewhat odd set of #defines. */ -#ifdef NDEBUG -# undef H5AC_DEBUG -#endif +#if H5C_COLLECT_CACHE_STATS + +#define H5AC_DUMP_STATS_ON_CLOSE 0 + +#else /* H5C_COLLECT_CACHE_STATS */ + +#define H5AC_DUMP_STATS_ON_CLOSE 0 + +#endif /* H5C_COLLECT_CACHE_STATS */ /* * Class methods pertaining to caching. Each type of cached object will @@ -64,42 +84,38 @@ * DEST: Just frees memory allocated by the LOAD method. * * CLEAR: Just marks object as non-dirty. + * + * SIZE: Report the size (on disk) of the specified cache object. + * Note that the space allocated on disk may not be contiguous. */ -typedef enum H5AC_subid_t { - H5AC_BT_ID = 0, /*B-tree nodes */ - H5AC_SNODE_ID = 1, /*symbol table nodes */ - H5AC_LHEAP_ID = 2, /*local heap */ - H5AC_GHEAP_ID = 3, /*global heap */ - H5AC_OHDR_ID = 4, /*object header */ - H5AC_NTYPES = 5 /*THIS MUST BE LAST! */ -} H5AC_subid_t; - -typedef void *(*H5AC_load_func_t)(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata1, void *udata2); -typedef herr_t (*H5AC_flush_func_t)(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing); -typedef herr_t (*H5AC_dest_func_t)(H5F_t *f, void *thing); -typedef herr_t (*H5AC_clear_func_t)(void *thing); - -typedef struct H5AC_class_t { - H5AC_subid_t id; - H5AC_load_func_t load; - H5AC_flush_func_t flush; - H5AC_dest_func_t dest; - H5AC_clear_func_t clear; -} H5AC_class_t; -/* +typedef H5C_load_func_t H5AC_load_func_t; +typedef H5C_flush_func_t H5AC_flush_func_t; +typedef H5C_dest_func_t H5AC_dest_func_t; +typedef H5C_clear_func_t H5AC_clear_func_t; +typedef H5C_size_func_t H5AC_size_func_t; + +typedef H5C_class_t H5AC_class_t; + + +/* The H5AC_NSLOTS #define is now obsolete, as the metadata cache no longer + * uses slots. However I am leaving it in for now to avoid modifying the + * interface between the metadata cache and the rest of HDF. It should + * be removed when we get to dealing with the size_hint parameter in + * H5AC_create(). + * JRM - 5/20/04 + * + * Old comment on H5AC_NSLOTS follows: + * * A cache has a certain number of entries. Objects are mapped into a * cache entry by hashing the object's file address. Each file has its * own cache, an array of slots. */ -#define H5AC_NSLOTS 10330 /* The library "likes" this number... */ +#define H5AC_NSLOTS 10330 /* The library "likes" this number... */ + + +typedef H5C_cache_entry_t H5AC_info_t; -typedef struct H5AC_info_t { - const H5AC_class_t *type; /*type of object stored here */ - haddr_t addr; /*file address for object */ - hbool_t is_dirty; /* 'Dirty' flag for cached object */ -} H5AC_info_t; -typedef H5AC_info_t *H5AC_info_ptr_t; /* Typedef for free lists */ /*===----------------------------------------------------------------------=== * Protect Types @@ -115,8 +131,9 @@ typedef enum H5AC_protect_t { H5AC_READ /* Protect object for reading */ } H5AC_protect_t; -/* Typedef for metadata cache (defined in H5AC.c) */ -typedef struct H5AC_t H5AC_t; + +/* Typedef for metadata cache (defined in H5C.c) */ +typedef H5C_t H5AC_t; /* Metadata specific properties for FAPL */ /* (Only used for parallel I/O) */ @@ -146,20 +163,19 @@ extern hid_t H5AC_ind_dxpl_id; * Library prototypes. */ H5_DLL herr_t H5AC_init(void); -H5_DLL herr_t H5AC_create(H5F_t *f, int size_hint); +H5_DLL herr_t H5AC_create(const H5F_t *f, int size_hint); H5_DLL herr_t H5AC_set(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, void *thing); H5_DLL void *H5AC_protect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, const void *udata1, void *udata2, H5AC_protect_t rw); H5_DLL herr_t H5AC_unprotect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, - void *thing, hbool_t deleted); -H5_DLL herr_t H5AC_flush(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, - unsigned flags); + void *thing, hbool_t deleted); +H5_DLL herr_t H5AC_flush(H5F_t *f, hid_t dxpl_id, unsigned flags); H5_DLL herr_t H5AC_rename(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t old_addr, haddr_t new_addr); H5_DLL herr_t H5AC_dest(H5F_t *f, hid_t dxpl_id); -H5_DLL herr_t H5AC_debug(H5F_t *f); +H5_DLL herr_t H5AC_stats(H5F_t *f); #endif /* !_H5ACprivate_H */ diff --git a/src/H5B.c b/src/H5B.c index 0a9a1f2..2c660c4 100644 --- a/src/H5B.c +++ b/src/H5B.c @@ -151,7 +151,8 @@ static herr_t H5B_assert(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_ static H5B_t *H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata); static herr_t H5B_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B_t *b); static herr_t H5B_dest(H5F_t *f, H5B_t *b); -static herr_t H5B_clear(H5B_t *b); +static herr_t H5B_clear(H5F_t *f, H5B_t *b, hbool_t destroy); +static herr_t H5B_compute_size(H5F_t *f, H5B_t *bt, size_t *size_ptr); /* H5B inherits cache-like properties from H5AC */ static const H5AC_class_t H5AC_BT[1] = {{ @@ -160,6 +161,7 @@ static const H5AC_class_t H5AC_BT[1] = {{ (H5AC_flush_func_t)H5B_flush, (H5AC_dest_func_t)H5B_dest, (H5AC_clear_func_t)H5B_clear, + (H5AC_size_func_t)H5B_compute_size, }}; /* Interface initialization? */ @@ -563,9 +565,11 @@ H5B_dest(H5F_t UNUSED *f, H5B_t *bt) *------------------------------------------------------------------------- */ static herr_t -H5B_clear(H5B_t *bt) +H5B_clear(H5F_t *f, H5B_t *bt, hbool_t destroy) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B_clear) + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT(H5B_clear) /* * Check arguments. @@ -574,12 +578,71 @@ H5B_clear(H5B_t *bt) /* Reset the dirty flag. */ bt->cache_info.is_dirty = FALSE; + + if (destroy) + if (H5B_dest(f, bt) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree node") - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5B_clear() */ /*------------------------------------------------------------------------- + * Function: H5B_compute_size + * + * Purpose: Compute the size in bytes of the specified instance of + * H5B_t on disk, and return it in *len_ptr. On failure, + * the value of *len_ptr is undefined. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: John Mainzer + * 5/13/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5B_compute_size(H5F_t *f, H5B_t *bt, size_t *size_ptr) +{ + H5B_shared_t *shared; /* Pointer to shared B-tree info */ + size_t size; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5B_compute_size) + + /* check arguments */ + HDassert(f); + HDassert(bt); + HDassert(bt->rc_shared); + shared=H5RC_GET_OBJ(bt->rc_shared); + HDassert(shared); + HDassert(shared->type); + HDassert(size_ptr); + + size = H5B_nodesize(f, shared, NULL); + + if ( size == 0 ) { + + HGOTO_ERROR(H5E_RESOURCE, H5E_BADSIZE, FAIL, \ + "H5B_nodesize() failed"); + + } else { + + *size_ptr = size; + + } + +done: + + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5B_H5B_compute_size() */ + + +/*------------------------------------------------------------------------- * Function: H5B_find * * Purpose: Locate the specified information in a B-tree and return diff --git a/src/H5C.c b/src/H5C.c index 8c9c74b..f7f58cb 100644 --- a/src/H5C.c +++ b/src/H5C.c @@ -95,6 +95,10 @@ #include "H5Pprivate.h" /* Property lists */ #include "H5TBprivate.h" /* Threaded, Balanced, Binary Trees */ +/* Interface initialization? */ +#define INTERFACE_INIT NULL +static int interface_initialize_g = 0; + /**************************************************************************** * @@ -139,7 +143,7 @@ if ( ( (head_ptr) == NULL ) || \ ) \ ) \ ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fv), "DLL pre remove SC failed") \ + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, (fv), "DLL pre remove SC failed") \ } #define H5C__DLL_SC(head_ptr, tail_ptr, len, Size, fv) \ @@ -159,7 +163,7 @@ if ( ( ( ( (head_ptr) == NULL ) || ( (tail_ptr) == NULL ) ) && \ ) \ ) \ ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fv), "DLL sanity check failed") \ + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, (fv), "DLL sanity check failed") \ } #define H5C__DLL_PRE_INSERT_SC(entry_ptr, head_ptr, tail_ptr, len, Size, fv) \ @@ -181,7 +185,7 @@ if ( ( (entry_ptr) == NULL ) || \ ) \ ) \ ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fv), "DLL pre insert SC failed") \ + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, (fv), "DLL pre insert SC failed") \ } #else /* H5C_DO_SANITY_CHECKS */ @@ -282,7 +286,7 @@ if ( ( (hd_ptr) == NULL ) || \ ) \ ) \ ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fv), "aux DLL pre remove SC failed") \ + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, (fv), "aux DLL pre remove SC failed") \ } #define H5C__AUX_DLL_SC(head_ptr, tail_ptr, len, Size, fv) \ @@ -302,7 +306,7 @@ if ( ( ( ( (head_ptr) == NULL ) || ( (tail_ptr) == NULL ) ) && \ ) \ ) \ ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fv), "AUX DLL sanity check failed") \ + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, (fv), "AUX DLL sanity check failed") \ } #define H5C__AUX_DLL_PRE_INSERT_SC(entry_ptr, hd_ptr, tail_ptr, len, Size, fv) \ @@ -324,7 +328,7 @@ if ( ( (entry_ptr) == NULL ) || \ ) \ ) \ ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, (fv), "AUX DLL pre insert SC failed") \ + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, (fv), "AUX DLL pre insert SC failed") \ } #else /* H5C_DO_SANITY_CHECKS */ @@ -595,7 +599,7 @@ if ( ( (cache_ptr) == NULL ) || \ ( (entry_ptr)->size <= 0 ) || \ ( (k = H5C__HASH_FCN((entry_ptr)->addr)) < 0 ) || \ ( k >= H5C__HASH_TABLE_LEN ) ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, fail_val, \ + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, fail_val, \ "Pre HT insert SC failed") \ } @@ -617,7 +621,7 @@ if ( ( (cache_ptr) == NULL ) || \ ( ( ((cache_ptr)->index)[(H5C__HASH_FCN((entry_ptr)->addr))] == \ (entry_ptr) ) && \ ( (entry_ptr)->ht_prev != NULL ) ) ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Pre HT remove SC failed") \ + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "Pre HT remove SC failed") \ } #define H5C__PRE_HT_SEARCH_SC(cache_ptr, Addr, fail_val) \ @@ -626,7 +630,7 @@ if ( ( (cache_ptr) == NULL ) || \ ( ! H5F_addr_defined(Addr) ) || \ ( H5C__HASH_FCN(Addr) < 0 ) || \ ( H5C__HASH_FCN(Addr) >= H5C__HASH_TABLE_LEN ) ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, fail_val, "Pre HT search SC failed") \ + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, fail_val, "Pre HT search SC failed") \ } #define H5C__POST_SUC_HT_SEARCH_SC(cache_ptr, entry_ptr, Addr, k, fail_val) \ @@ -646,7 +650,7 @@ if ( ( (cache_ptr) == NULL ) || \ ( (entry_ptr)->ht_prev->ht_next != (entry_ptr) ) ) || \ ( ( (entry_ptr)->ht_next != NULL ) && \ ( (entry_ptr)->ht_next->ht_prev != (entry_ptr) ) ) ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, fail_val, \ + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, fail_val, \ "Post successful HT search SC failed") \ } @@ -654,7 +658,7 @@ if ( ( (cache_ptr) == NULL ) || \ if ( ( (cache_ptr) == NULL ) || \ ( ((cache_ptr)->index)[k] != (entry_ptr) ) || \ ( (entry_ptr)->ht_prev != NULL ) ) { \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, fail_val, \ + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, fail_val, \ "Post HT shift to front SC failed") \ } @@ -806,7 +810,7 @@ if ( ( (cache_ptr) == NULL ) || \ \ if ( loc_node_ptr == NULL ) { \ \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't insert entry in tree") \ + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "Can't insert entry in tree") \ } \ \ (entry_ptr)->in_tree = TRUE; \ @@ -860,7 +864,7 @@ if ( ( (cache_ptr) == NULL ) || \ if ( H5TB_rem(&((cache_ptr)->tree_ptr->root), (node_ptr), NULL) \ != (entry_ptr) ) { \ \ - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, \ "Can't delete entry from tree.") \ \ } else { \ @@ -2350,7 +2354,7 @@ H5C_dest_empty(H5C_t * cache_ptr) ( cache_ptr->magic != H5C__H5C_T_MAGIC ) || ( cache_ptr->index_len != 0 ) ) { - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, \ "Bad cache_ptr or non-empty cache on entry.") } @@ -2660,7 +2664,7 @@ H5C_insert_entry(H5F_t * f, if ( (type->size)(f, thing, &(entry_ptr->size)) < 0 ) { - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGETSIZE, FAIL, \ + HGOTO_ERROR(H5E_RESOURCE, H5E_BADSIZE, FAIL, \ "Can't get size of thing") } @@ -2691,7 +2695,7 @@ H5C_insert_entry(H5F_t * f, if ( result < 0 ) { - HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, \ + HGOTO_ERROR(H5E_CACHE, H5E_CANTINSERT, FAIL, \ "Can't get write_permitted") } } @@ -2734,7 +2738,7 @@ H5C_insert_entry(H5F_t * f, if ( result < 0 ) { - HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, \ + HGOTO_ERROR(H5E_CACHE, H5E_CANTINSERT, FAIL, \ "H5C_make_space_in_cache failed.") } } @@ -2749,12 +2753,12 @@ H5C_insert_entry(H5F_t * f, if ( test_entry_ptr == entry_ptr ) { - HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, \ + HGOTO_ERROR(H5E_CACHE, H5E_CANTINSERT, FAIL, \ "entry already in cache.") } else { - HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, \ + HGOTO_ERROR(H5E_CACHE, H5E_CANTINSERT, FAIL, \ "duplicate entry in cache.") } } @@ -2861,12 +2865,12 @@ H5C_rename_entry(H5F_t * f, if ( test_entry_ptr->type == type ) { - HGOTO_ERROR(H5E_CACHE, H5E_CANTRENAME, FAIL, \ + HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, FAIL, \ "Target already renamed & reinserted???.") } else { - HGOTO_ERROR(H5E_CACHE, H5E_CANTRENAME, FAIL, \ + HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, FAIL, \ "New address already in use?.") } } @@ -3012,7 +3016,7 @@ H5C_protect(H5F_t * f, if ( result < 0 ) { - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, \ + HGOTO_ERROR(H5E_CACHE, H5E_PROTECT, NULL, \ "Can't get write_permitted") } } @@ -3052,7 +3056,7 @@ H5C_protect(H5F_t * f, if ( result < 0 ) { - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, \ + HGOTO_ERROR(H5E_CACHE, H5E_PROTECT, NULL, \ "H5C_make_space_in_cache failed.") } } @@ -3075,7 +3079,7 @@ H5C_protect(H5F_t * f, if ( entry_ptr->is_protected ) { - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, \ + HGOTO_ERROR(H5E_CACHE, H5E_PROTECT, NULL, \ "Target already protected?!?.") } @@ -3170,7 +3174,7 @@ H5C_unprotect(H5F_t * f, if ( ! (entry_ptr->is_protected) ) { - HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, \ + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \ "Entry already unprotected??") } @@ -3211,12 +3215,12 @@ H5C_unprotect(H5F_t * f, if ( test_entry_ptr == NULL ) { - HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, \ + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \ "entry not in hash table?!?.") } else if ( test_entry_ptr != entry_ptr ) { - HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, \ + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \ "hash table contains multiple entries for addr?!?.") } @@ -3231,7 +3235,7 @@ H5C_unprotect(H5F_t * f, &dummy_first_flush, TRUE) < 0 ) { - HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "Can't flush.") + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush.") } } @@ -3301,7 +3305,7 @@ H5C_stats(H5C_t * cache_ptr, ( cache_ptr->magic != H5C__H5C_T_MAGIC ) || ( !cache_name ) ) { - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad cache_ptr or cache_name") + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "Bad cache_ptr or cache_name") } #if H5C_COLLECT_CACHE_STATS @@ -3617,7 +3621,7 @@ H5C_set_skip_flags(H5C_t * cache_ptr, */ if ( ( ! cache_ptr ) || ( cache_ptr->magic != H5C__H5C_T_MAGIC ) ) { - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad cache_ptr") + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "Bad cache_ptr") } cache_ptr->skip_file_checks = skip_file_checks; @@ -3740,7 +3744,7 @@ H5C_flush_single_entry(H5F_t * f, ( entry_ptr->addr != addr ) || ( node_ptr->data != node_ptr->key ) ) { - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, \ "Hash table and tree out of sync.") } } else if ( entry_ptr != NULL ) { @@ -3749,7 +3753,7 @@ H5C_flush_single_entry(H5F_t * f, ( entry_ptr->is_dirty ) || ( entry_ptr->addr != addr ) ) { - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, \ "entry failed sanity checks.") } } @@ -3952,7 +3956,7 @@ H5C_load_entry(H5F_t * f, if ( (type->size)(f, thing, &(entry_ptr->size)) < 0 ) { - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGETSIZE, NULL, \ + HGOTO_ERROR(H5E_RESOURCE, H5E_BADSIZE, NULL, \ "Can't get size of thing") } diff --git a/src/H5F.c b/src/H5F.c index 1de663c..c68c83b 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -2590,7 +2590,7 @@ H5F_flush(H5F_t *f, hid_t dxpl_id, H5F_scope_t scope, unsigned flags) } /* end if */ /* flush (and invalidate) the entire meta data cache */ - if (H5AC_flush(f, dxpl_id, NULL, HADDR_UNDEF, flags & (H5F_FLUSH_INVALIDATE|H5F_FLUSH_CLEAR_ONLY)) < 0) + if (H5AC_flush(f, dxpl_id, flags & (H5F_FLUSH_INVALIDATE|H5F_FLUSH_CLEAR_ONLY)) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush meta data cache"); } /* end if */ @@ -2987,9 +2987,9 @@ H5F_close(H5F_t *f) /* Only flush at this point if the file will be closed */ if (closing) { /* Dump debugging info */ -#ifdef H5AC_DEBUG - H5AC_debug(f); -#endif /* H5AC_DEBUG */ +#if H5AC_DUMP_STATS_ON_CLOSE + H5AC_stats(f); +#endif /* H5AC_DUMP_STATS_ON_CLOSE */ /* Only try to flush the file if it was opened with write access */ if(f->intent&H5F_ACC_RDWR) { @@ -3952,6 +3952,216 @@ done: /*------------------------------------------------------------------------- + * Function: H5F_get_id + * + * Purpose: Get the file ID, incrementing it, or "resurrecting" it as + * appropriate. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Raymond Lu + * Oct 29, 2003 + * + * Modifications: + *------------------------------------------------------------------------- + */ +hid_t +H5F_get_id(H5F_t *file) +{ + hid_t ret_value; + + FUNC_ENTER_NOAPI_NOINIT(H5F_get_id) + + assert(file); + + if(file->file_id == -1) { + if(H5I_remove(file->closing)==NULL) + HGOTO_ERROR(H5E_ATOM, H5E_READERROR, FAIL, "unable to remove from closing list") + + /* Get an atom for the file */ + if ((file->file_id = H5I_register(H5I_FILE, file))<0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file") + + /* Indicate file is not closing */ + file->closing = 0; + } else { + /* Increment reference count on atom. */ + if (H5I_inc_ref(file->file_id)<0) + HGOTO_ERROR (H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed"); + } + + ret_value = file->file_id; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_id() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_get_base_addr + * + * Purpose: Quick and dirty routine to retrieve the file's 'base_addr' value + * (Mainly added to stop non-file routines from poking about in the + * H5F_t data structure) + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Raymond Lu + * December 20, 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +haddr_t +H5F_get_base_addr(const H5F_t *f) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_base_addr) + + assert(f); + assert(f->shared); + + FUNC_LEAVE_NOAPI(f->shared->base_addr) +} /* end H5F_get_base_addr() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_get_eoa + * + * Purpose: Quick and dirty routine to retrieve the file's 'eoa' value + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * June 1, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +haddr_t +H5F_get_eoa(const H5F_t *f) +{ + haddr_t ret_value; + + FUNC_ENTER_NOAPI(H5F_get_eoa, HADDR_UNDEF) + + assert(f); + assert(f->shared); + + /* Dispatch to driver */ + if (HADDR_UNDEF==(ret_value=H5FD_get_eoa(f->shared->lf))) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "driver get_eoa request failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_eoa() */ + +#ifdef H5_HAVE_PARALLEL + +/*------------------------------------------------------------------------- + * Function: H5F_mpi_get_rank + * + * Purpose: Retrieves the rank of an MPI process. + * + * Return: Success: The rank (non-negative) + * + * Failure: Negative + * + * Programmer: Quincey Koziol + * Friday, January 30, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +H5F_mpi_get_rank(const H5F_t *f) +{ + int ret_value; + + FUNC_ENTER_NOAPI(H5F_mpi_get_rank, FAIL) + + assert(f && f->shared); + + /* Dispatch to driver */ + if ((ret_value=H5FD_mpi_get_rank(f->shared->lf))<0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "driver get_rank request failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_mpi_get_rank() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_mpi_get_comm + * + * Purpose: Retrieves the file's communicator + * + * Return: Success: The communicator (non-negative) + * + * Failure: Negative + * + * Programmer: Quincey Koziol + * Friday, January 30, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +MPI_Comm +H5F_mpi_get_comm(const H5F_t *f) +{ + MPI_Comm ret_value; + + FUNC_ENTER_NOAPI(H5F_mpi_get_comm, MPI_COMM_NULL) + + assert(f && f->shared); + + /* Dispatch to driver */ + if ((ret_value=H5FD_mpi_get_comm(f->shared->lf))==MPI_COMM_NULL) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, MPI_COMM_NULL, "driver get_comm request failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_mpi_get_comm() */ +#endif /* H5_HAVE_PARALLEL */ + + +/*------------------------------------------------------------------------- + * Function: H5F_grp_btree_shared + * + * Purpose: Replaced a macro to retrieve the shared B-tree node info + * now that the generic properties are being used to store + * the values. + * + * Return: Success: Non-void, and the shared B-tree node info + * is returned. + * + * Failure: void (should not happen) + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Jul 5 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5RC_t *H5F_grp_btree_shared(const H5F_t *f) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_grp_btree_shared) + + assert(f); + assert(f->shared); + + FUNC_LEAVE_NOAPI(f->shared->grp_btree_shared) +} /* end H5F_grp_btree_shared() */ + + +/*------------------------------------------------------------------------- * Function: H5F_block_read * * Purpose: Reads some data from a file/server/etc into a buffer. @@ -3987,7 +4197,7 @@ H5F_block_read(const H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size, hid_t haddr_t abs_addr; herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5F_block_read, FAIL); + FUNC_ENTER_NOAPI(H5F_block_read, FAIL) assert (f); assert (f->shared); @@ -3999,10 +4209,10 @@ H5F_block_read(const H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size, hid_t /* Read the data */ if (H5FD_read(f->shared->lf, type, dxpl_id, abs_addr, size, buf)<0) - HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed"); + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed") done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -4043,7 +4253,7 @@ H5F_block_write(const H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size, haddr_t abs_addr; herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5F_block_write, FAIL); + FUNC_ENTER_NOAPI(H5F_block_write, FAIL) assert (f); assert (f->shared); @@ -4051,17 +4261,17 @@ H5F_block_write(const H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size, assert (buf); if (0==(f->intent & H5F_ACC_RDWR)) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "no write intent"); + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "no write intent") /* Convert the relative address to an absolute address */ abs_addr = f->shared->base_addr + addr; /* Write the data */ if (H5FD_write(f->shared->lf, type, dxpl_id, abs_addr, size, buf)) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed"); + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed") done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } @@ -4083,7 +4293,7 @@ done: *------------------------------------------------------------------------- */ void -H5F_addr_encode(H5F_t *f, uint8_t **pp/*in,out*/, haddr_t addr) +H5F_addr_encode(const H5F_t *f, uint8_t **pp/*in,out*/, haddr_t addr) { unsigned i; @@ -4124,7 +4334,7 @@ H5F_addr_encode(H5F_t *f, uint8_t **pp/*in,out*/, haddr_t addr) *------------------------------------------------------------------------- */ void -H5F_addr_decode(H5F_t *f, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*out*/) +H5F_addr_decode(const H5F_t *f, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*out*/) { unsigned i; haddr_t tmp; @@ -4144,7 +4354,7 @@ H5F_addr_decode(H5F_t *f, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*out*/) if (i= 0); + /* Check args */ + if(NULL==(file=H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + + /* Go get the actual file size */ + if((eof = H5FDget_eof(file->shared->lf))==HADDR_UNDEF) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file size") + + *size = (hsize_t)eof; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Fget_filesize() */ + + +/*------------------------------------------------------------------------- + * Function: H5Fget_name + * + * Purpose: Gets the name of the file to which object OBJ_ID belongs. + * If `name' is non-NULL then write up to `size' bytes into that + * buffer and always return the length of the entry name. + * Otherwise `size' is ignored and the function does not store the name, + * just returning the number of characters required to store the name. + * If an error occurs then the buffer pointed to by `name' (NULL or non-NULL) + * is unchanged and the function returns a negative value. + * + * Return: Success: The length of the file name + * Failure: Negative + * + * Programmer: Raymond Lu + * June 29, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +ssize_t +H5Fget_name(hid_t obj_id, char *name/*out*/, size_t size) +{ + H5G_entry_t *ent; /*symbol table entry */ + size_t len=0; + ssize_t ret_value; + + FUNC_ENTER_API (H5Fget_name, FAIL); + H5TRACE3("Zs","ixz",obj_id,name,size); + + /* get symbol table entry */ + if((ent = H5G_loc(obj_id))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object ID") + + len = HDstrlen(ent->file->name); + + if(name) { + HDstrncpy(name, ent->file->name, MIN(len+1,size)); + if(len >= size) + name[size-1]='\0'; + } /* end if */ + + /* Set return value */ + ret_value=(ssize_t)len; + +done: + FUNC_LEAVE_API(ret_value); +} /* end H5Fget_name() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_debug + * + * Purpose: Prints a file header to the specified stream. Each line + * is indented and the field name occupies the specified width + * number of characters. + * + * Errors: + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 1 1997 + * + * Modifications: + * Robb Matzke, 1999-07-28 + * The ADDR argument is passed by value. + * + * Raymond Lu, 2001-10-14 + * Changed to the new generic property list. + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_debug(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, FILE * stream, int indent, + int fwidth) +{ + hsize_t userblock_size; + int super_vers, freespace_vers, obj_dir_vers, share_head_vers; + H5P_genplist_t *plist; /* Property list */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5F_debug, FAIL); + + /* check args */ + assert(f); + assert(H5F_addr_defined(addr)); + assert(stream); + assert(indent >= 0); assert(fwidth >= 0); /* Get property list */ @@ -4344,308 +4649,3 @@ H5F_debug(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, FILE * stream, int inden done: FUNC_LEAVE_NOAPI(ret_value); } - - -/*------------------------------------------------------------------------- - * Function: H5F_get_id - * - * Purpose: Get the file ID, incrementing it, or "resurrecting" it as - * appropriate. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Raymond Lu - * Oct 29, 2003 - * - * Modifications: - *------------------------------------------------------------------------- - */ -hid_t -H5F_get_id(H5F_t *file) -{ - hid_t ret_value; - - FUNC_ENTER_NOAPI_NOINIT(H5F_get_id) - - assert(file); - - if(file->file_id == -1) { - if(H5I_remove(file->closing)==NULL) - HGOTO_ERROR(H5E_ATOM, H5E_READERROR, FAIL, "unable to remove from closing list") - - /* Get an atom for the file */ - if ((file->file_id = H5I_register(H5I_FILE, file))<0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file") - - /* Indicate file is not closing */ - file->closing = 0; - } else { - /* Increment reference count on atom. */ - if (H5I_inc_ref(file->file_id)<0) - HGOTO_ERROR (H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed"); - } - - ret_value = file->file_id; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_get_id() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_get_base_addr - * - * Purpose: Quick and dirty routine to retrieve the file's 'base_addr' value - * (Mainly added to stop non-file routines from poking about in the - * H5F_t data structure) - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Raymond Lu - * December 20, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -haddr_t -H5F_get_base_addr(const H5F_t *f) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_base_addr) - - assert(f); - assert(f->shared); - - FUNC_LEAVE_NOAPI(f->shared->base_addr) -} /* end H5F_get_base_addr() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_get_eoa - * - * Purpose: Quick and dirty routine to retrieve the file's 'eoa' value - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * June 1, 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -haddr_t -H5F_get_eoa(const H5F_t *f) -{ - haddr_t ret_value; - - FUNC_ENTER_NOAPI(H5F_get_eoa, HADDR_UNDEF) - - assert(f); - assert(f->shared); - - /* Dispatch to driver */ - if (HADDR_UNDEF==(ret_value=H5FD_get_eoa(f->shared->lf))) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "driver get_eoa request failed") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_get_eoa() */ - -#ifdef H5_HAVE_PARALLEL - -/*------------------------------------------------------------------------- - * Function: H5F_mpi_get_rank - * - * Purpose: Retrieves the rank of an MPI process. - * - * Return: Success: The rank (non-negative) - * - * Failure: Negative - * - * Programmer: Quincey Koziol - * Friday, January 30, 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -int -H5F_mpi_get_rank(const H5F_t *f) -{ - int ret_value; - - FUNC_ENTER_NOAPI(H5F_mpi_get_rank, FAIL) - - assert(f && f->shared); - - /* Dispatch to driver */ - if ((ret_value=H5FD_mpi_get_rank(f->shared->lf))<0) - HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "driver get_rank request failed") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_mpi_get_rank() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_mpi_get_comm - * - * Purpose: Retrieves the file's communicator - * - * Return: Success: The communicator (non-negative) - * - * Failure: Negative - * - * Programmer: Quincey Koziol - * Friday, January 30, 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -MPI_Comm -H5F_mpi_get_comm(const H5F_t *f) -{ - MPI_Comm ret_value; - - FUNC_ENTER_NOAPI(H5F_mpi_get_comm, MPI_COMM_NULL) - - assert(f && f->shared); - - /* Dispatch to driver */ - if ((ret_value=H5FD_mpi_get_comm(f->shared->lf))==MPI_COMM_NULL) - HGOTO_ERROR(H5E_VFL, H5E_CANTGET, MPI_COMM_NULL, "driver get_comm request failed") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_mpi_get_comm() */ -#endif /* H5_HAVE_PARALLEL */ - - -/*------------------------------------------------------------------------- - * Function: H5F_grp_btree_shared - * - * Purpose: Replaced a macro to retrieve the shared B-tree node info - * now that the generic properties are being used to store - * the values. - * - * Return: Success: Non-void, and the shared B-tree node info - * is returned. - * - * Failure: void (should not happen) - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Jul 5 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -H5RC_t *H5F_grp_btree_shared(const H5F_t *f) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_grp_btree_shared) - - assert(f); - assert(f->shared); - - FUNC_LEAVE_NOAPI(f->shared->grp_btree_shared) -} /* end H5F_grp_btree_shared() */ - - -/*------------------------------------------------------------------------- - * Function: H5Fget_filesize - * - * Purpose: Retrieves the file size of the HDF5 file. This function - * is called after an existing file is opened in order - * to learn the true size of the underlying file. - * - * Return: Success: Non-negative - * Failure: Negative - * - * Programmer: David Pitt - * david.pitt@bigpond.com - * Apr 27, 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Fget_filesize(hid_t file_id, hsize_t *size) -{ - H5F_t *file=NULL; /* File object for file ID */ - herr_t ret_value = SUCCEED; /* Return value */ - haddr_t eof; - - FUNC_ENTER_API(H5Fget_filesize, FAIL) - H5TRACE2("e","i*h",file_id,size); - - /* Check args */ - if(NULL==(file=H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") - - /* Go get the actual file size */ - if((eof = H5FDget_eof(file->shared->lf))==HADDR_UNDEF) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file size") - - *size = (hsize_t)eof; - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Fget_filesize() */ - - -/*------------------------------------------------------------------------- - * Function: H5Fget_name - * - * Purpose: Gets the name of the file to which object OBJ_ID belongs. - * If `name' is non-NULL then write up to `size' bytes into that - * buffer and always return the length of the entry name. - * Otherwise `size' is ignored and the function does not store the name, - * just returning the number of characters required to store the name. - * If an error occurs then the buffer pointed to by `name' (NULL or non-NULL) - * is unchanged and the function returns a negative value. - * - * Return: Success: The length of the file name - * Failure: Negative - * - * Programmer: Raymond Lu - * June 29, 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -ssize_t -H5Fget_name(hid_t obj_id, char *name/*out*/, size_t size) -{ - H5G_entry_t *ent; /*symbol table entry */ - size_t len=0; - ssize_t ret_value; - - FUNC_ENTER_API (H5Fget_name, FAIL); - H5TRACE3("Zs","ixz",obj_id,name,size); - - /* get symbol table entry */ - if((ent = H5G_loc(obj_id))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object ID") - - len = HDstrlen(ent->file->name); - - if(name) { - HDstrncpy(name, ent->file->name, MIN(len+1,size)); - if(len >= size) - name[size-1]='\0'; - } /* end if */ - - /* Set return value */ - ret_value=(ssize_t)len; - -done: - FUNC_LEAVE_API(ret_value); -} /* end H5Fget_name() */ - diff --git a/src/H5FL.c b/src/H5FL.c index 0074f6d..1d49064 100644 --- a/src/H5FL.c +++ b/src/H5FL.c @@ -133,20 +133,21 @@ H5FL_malloc(size_t mem_size) { void *ret_value=NULL; /* return value*/ - FUNC_ENTER_NOAPI(H5FL_malloc, NULL); + FUNC_ENTER_NOAPI(H5FL_malloc, NULL) /* Attempt to allocate the memory requested */ if(NULL==(ret_value=H5MM_malloc(mem_size))) { /* If we can't allocate the memory now, try garbage collecting first */ - H5FL_garbage_coll(); + if(H5FL_garbage_coll()<0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, NULL, "garbage collection failed during allocation") /* Now try allocating the memory again */ if(NULL==(ret_value=H5MM_malloc(mem_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for chunk"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for chunk") } /* end if */ done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_malloc() */ @@ -172,11 +173,11 @@ H5FL_reg_init(H5FL_reg_head_t *head) H5FL_reg_gc_node_t *new_node; /* Pointer to the node for the new list to garbage collect */ herr_t ret_value=SUCCEED; /* return value*/ - FUNC_ENTER_NOAPI_NOINIT(H5FL_reg_init); + FUNC_ENTER_NOAPI_NOINIT(H5FL_reg_init) /* Allocate a new garbage collection node */ if (NULL==(new_node = H5MM_malloc(sizeof(H5FL_reg_gc_node_t)))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Initialize the new garbage collection node */ new_node->list=head; @@ -193,7 +194,7 @@ H5FL_reg_init(H5FL_reg_head_t *head) head->size=sizeof(void *); done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_reg_init() */ @@ -218,7 +219,7 @@ H5FL_reg_free(H5FL_reg_head_t *head, void *obj) H5FL_reg_node_t *temp; /* Temp. ptr to the new free list node allocated */ void *ret_value=NULL; /* Return value */ - FUNC_ENTER_NOAPI(H5FL_reg_free, NULL); + FUNC_ENTER_NOAPI(H5FL_reg_free, NULL) /* Double check parameters */ assert(head); @@ -250,14 +251,16 @@ H5FL_reg_free(H5FL_reg_head_t *head, void *obj) /* Check for exceeding free list memory use limits */ /* First check this particular list */ if(head->list_mem>H5FL_reg_lst_mem_lim) - H5FL_reg_gc_list(head); + if(H5FL_reg_gc_list(head)<0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, NULL, "garbage collection failed during free") /* Then check the global amount memory on regular free lists */ if(H5FL_reg_gc_head.mem_freed>H5FL_reg_glb_mem_lim) - H5FL_reg_gc(); + if(H5FL_reg_gc()<0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, NULL, "garbage collection failed during free") done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_reg_free() */ @@ -281,14 +284,15 @@ H5FL_reg_malloc(H5FL_reg_head_t *head) { void *ret_value; /* Pointer to object to return */ - FUNC_ENTER_NOAPI(H5FL_reg_malloc, NULL); + FUNC_ENTER_NOAPI(H5FL_reg_malloc, NULL) /* Double check parameters */ assert(head); /* Make certain the list is initialized first */ if(!head->init) - H5FL_reg_init(head); + if(H5FL_reg_init(head)<0) + HGOTO_ERROR (H5E_RESOURCE, H5E_CANTINIT, NULL, "can't initialize 'regular' blocks") /* Check for nodes available on the free list first */ if(head->list!=NULL) { @@ -309,14 +313,14 @@ H5FL_reg_malloc(H5FL_reg_head_t *head) /* Otherwise allocate a node */ else { if (NULL==(ret_value = H5FL_malloc(head->size))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Increment the number of blocks allocated in list */ head->allocated++; } /* end else */ done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_reg_malloc() */ @@ -340,20 +344,20 @@ H5FL_reg_calloc(H5FL_reg_head_t *head) { void *ret_value; /* Pointer to object to return */ - FUNC_ENTER_NOAPI(H5FL_reg_calloc, NULL); + FUNC_ENTER_NOAPI(H5FL_reg_calloc, NULL) /* Double check parameters */ assert(head); /* Allocate the block */ if (NULL==(ret_value = H5FL_reg_malloc(head))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Clear to zeros */ HDmemset(ret_value,0,head->size); done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_reg_calloc() */ @@ -379,7 +383,7 @@ H5FL_reg_gc_list(H5FL_reg_head_t *head) void *tmp; /* Temporary node pointer */ size_t total_mem; /* Total memory used on list */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FL_reg_gc_list); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FL_reg_gc_list) /* Calculate the total memory used on this list */ total_mem=head->onlist*head->size; @@ -410,7 +414,7 @@ H5FL_reg_gc_list(H5FL_reg_head_t *head) /* Decrement global count of free memory on "regular" lists */ H5FL_reg_gc_head.mem_freed-=total_mem; - FUNC_LEAVE_NOAPI(SUCCEED); + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5FL_reg_gc_list() */ @@ -435,14 +439,16 @@ static herr_t H5FL_reg_gc(void) { H5FL_reg_gc_node_t *gc_node; /* Pointer into the list of things to garbage collect */ + herr_t ret_value=SUCCEED; /* return value*/ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FL_reg_gc); + FUNC_ENTER_NOAPI_NOINIT(H5FL_reg_gc) /* Walk through all the free lists, free()'ing the nodes */ gc_node=H5FL_reg_gc_head.first; while(gc_node!=NULL) { /* Release the free nodes on the list */ - H5FL_reg_gc_list(gc_node->list); + if(H5FL_reg_gc_list(gc_node->list)<0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "garbage collection of list failed") /* Go on to the next free list to garbage collect */ gc_node=gc_node->next; @@ -451,7 +457,8 @@ H5FL_reg_gc(void) /* Double check that all the memory on the free lists is recycled */ assert(H5FL_reg_gc_head.mem_freed==0); - FUNC_LEAVE_NOAPI(SUCCEED); +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_reg_gc() */ @@ -486,7 +493,7 @@ H5FL_reg_term(void) H5FL_reg_gc_node_t *left; /* pointer to garbage collection lists with work left */ H5FL_reg_gc_node_t *tmp; /* Temporary pointer to a garbage collection node */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FL_reg_term); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FL_reg_term) if (interface_initialize_g) { /* Free the nodes on the garbage collection list, keeping nodes with allocations outstanding */ @@ -523,7 +530,7 @@ H5FL_reg_term(void) /* Terminating this layer never affects other layers; rather, other layers affect * the termination of this layer. */ - FUNC_LEAVE_NOAPI(0); + FUNC_LEAVE_NOAPI(0) } /* end H5FL_reg_term() */ @@ -613,11 +620,11 @@ 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; - FUNC_ENTER_NOAPI_NOINIT(H5FL_blk_create_list); + FUNC_ENTER_NOAPI_NOINIT(H5FL_blk_create_list) /* Allocate room for the new free list node */ if(NULL==(temp=H5FL_MALLOC(H5FL_blk_node_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for chunk info"); + 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; @@ -638,7 +645,7 @@ H5FL_blk_create_list(H5FL_blk_node_t **head, size_t size) ret_value=temp; done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_blk_create_list() */ @@ -664,11 +671,11 @@ H5FL_blk_init(H5FL_blk_head_t *head) H5FL_blk_gc_node_t *new_node; /* Pointer to the node for the new list to garbage collect */ herr_t ret_value=SUCCEED; /* return value*/ - FUNC_ENTER_NOAPI_NOINIT(H5FL_blk_init); + FUNC_ENTER_NOAPI_NOINIT(H5FL_blk_init) /* Allocate a new garbage collection node */ if (NULL==(new_node = H5MM_malloc(sizeof(H5FL_blk_gc_node_t)))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Initialize the new garbage collection node */ new_node->pq=head; @@ -681,7 +688,7 @@ H5FL_blk_init(H5FL_blk_head_t *head) head->init=1; done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_blk_init() */ @@ -707,7 +714,7 @@ H5FL_blk_free_block_avail(H5FL_blk_head_t *head, size_t size) H5FL_blk_node_t *free_list; /* The free list of nodes of correct size */ htri_t ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5FL_blk_free_block_avail, FAIL); + FUNC_ENTER_NOAPI(H5FL_blk_free_block_avail, FAIL) /* Double check parameters */ assert(head); @@ -719,7 +726,7 @@ H5FL_blk_free_block_avail(H5FL_blk_head_t *head, size_t size) else ret_value=FALSE; done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_blk_free_block_avail() */ @@ -748,7 +755,7 @@ H5FL_blk_malloc(H5FL_blk_head_t *head, size_t 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_NOAPI(H5FL_blk_malloc, NULL); + FUNC_ENTER_NOAPI(H5FL_blk_malloc, NULL) /* Double check parameters */ assert(head); @@ -756,7 +763,8 @@ H5FL_blk_malloc(H5FL_blk_head_t *head, size_t size) /* Make certain the list is initialized first */ if(!head->init) - H5FL_blk_init(head); + if(H5FL_blk_init(head)<0) + HGOTO_ERROR (H5E_RESOURCE, H5E_CANTINIT, NULL, "can't initialize 'block' list") /* check if there is a free list for blocks of this size */ /* and if there are any blocks available on the list */ @@ -783,7 +791,7 @@ H5FL_blk_malloc(H5FL_blk_head_t *head, size_t size) else { /* Allocate new node, with room for the page info header and the actual page data */ if(NULL==(temp=H5FL_malloc(sizeof(H5FL_blk_list_t)+size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for chunk"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for chunk") /* Increment the number of blocks allocated */ head->allocated++; @@ -796,7 +804,7 @@ H5FL_blk_malloc(H5FL_blk_head_t *head, size_t size) } /* end else */ done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_blk_malloc() */ @@ -824,7 +832,7 @@ H5FL_blk_calloc(H5FL_blk_head_t *head, size_t size) { void *ret_value; /* Pointer to the block to return to the user */ - FUNC_ENTER_NOAPI(H5FL_blk_calloc, NULL); + FUNC_ENTER_NOAPI(H5FL_blk_calloc, NULL) /* Double check parameters */ assert(head); @@ -832,13 +840,13 @@ H5FL_blk_calloc(H5FL_blk_head_t *head, size_t size) /* Allocate the block */ if (NULL==(ret_value = H5FL_blk_malloc(head,size))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Clear the block to zeros */ HDmemset(ret_value,0,size); done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_blk_calloc() */ @@ -868,14 +876,14 @@ H5FL_blk_free(H5FL_blk_head_t *head, void *block) size_t free_size; /* Size of the block freed */ void *ret_value=NULL; /* Return value */ - FUNC_ENTER_NOAPI(H5FL_blk_free, NULL); + FUNC_ENTER_NOAPI(H5FL_blk_free, NULL) /* Double check parameters */ assert(head); assert(block); /* 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-sizeof(H5FL_blk_list_t)); + temp=(H5FL_blk_list_t *)((unsigned char *)block-sizeof(H5FL_blk_list_t)); /*lint !e826 Pointer-to-pointer cast is appropriate here */ /* Save the block's size for later */ free_size=temp->size; @@ -902,14 +910,16 @@ H5FL_blk_free(H5FL_blk_head_t *head, void *block) /* Check for exceeding free list memory use limits */ /* First check this particular list */ if(head->list_mem>H5FL_blk_lst_mem_lim) - H5FL_blk_gc_list(head); + if(H5FL_blk_gc_list(head)<0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, NULL, "garbage collection failed during free") /* Then check the global amount memory on block free lists */ if(H5FL_blk_gc_head.mem_freed>H5FL_blk_glb_mem_lim) - H5FL_blk_gc(); + if(H5FL_blk_gc()<0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, NULL, "garbage collection failed during free") done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_blk_free() */ @@ -935,7 +945,7 @@ H5FL_blk_realloc(H5FL_blk_head_t *head, void *block, size_t new_size) { void *ret_value=NULL; /* Return value */ - FUNC_ENTER_NOAPI(H5FL_blk_realloc, NULL); + FUNC_ENTER_NOAPI(H5FL_blk_realloc, NULL) /* Double check parameters */ assert(head); @@ -946,14 +956,14 @@ 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 */ /* Get the pointer to the chunk info header in front of the chunk to free */ - temp=(H5FL_blk_list_t *)((unsigned char *)block-sizeof(H5FL_blk_list_t)); + temp=(H5FL_blk_list_t *)((unsigned char *)block-sizeof(H5FL_blk_list_t)); /*lint !e826 Pointer-to-pointer cast is appropriate here */ /* check if we are actually changing the size of the buffer */ if(new_size!=temp->size) { size_t blk_size; /* Temporary block size */ if((ret_value=H5FL_blk_malloc(head,new_size))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for block"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for block") blk_size=MIN(new_size,temp->size); HDmemcpy(ret_value,block,blk_size); H5FL_blk_free(head,block); @@ -966,7 +976,7 @@ H5FL_blk_realloc(H5FL_blk_head_t *head, void *block, size_t new_size) ret_value=H5FL_blk_malloc(head,new_size); done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_blk_realloc() */ @@ -992,7 +1002,7 @@ H5FL_blk_gc_list(H5FL_blk_head_t *head) void *next; /* Temp. ptr to the free list list node */ void *temp; /* Temp. ptr to the free list page node */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FL_blk_gc_list); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FL_blk_gc_list) /* Loop through all the nodes in the block free list queue */ while(head->head!=NULL) { @@ -1030,7 +1040,7 @@ H5FL_blk_gc_list(H5FL_blk_head_t *head) /* Double check that all the memory on this list is recycled */ assert(head->list_mem==0); - FUNC_LEAVE_NOAPI(SUCCEED); + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5FL_blk_gc_list() */ @@ -1053,14 +1063,16 @@ static herr_t H5FL_blk_gc(void) { H5FL_blk_gc_node_t *gc_node; /* Pointer into the list of things to garbage collect */ + herr_t ret_value=SUCCEED; /* return value*/ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FL_blk_gc); + FUNC_ENTER_NOAPI_NOINIT(H5FL_blk_gc) /* Walk through all the free lists, free()'ing the nodes */ gc_node=H5FL_blk_gc_head.first; while(gc_node!=NULL) { /* For each free list being garbage collected, walk through the nodes and free them */ - H5FL_blk_gc_list(gc_node->pq); + if(H5FL_blk_gc_list(gc_node->pq)<0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "garbage collection of list failed") /* Go on to the next free list to garbage collect */ gc_node=gc_node->next; @@ -1069,7 +1081,8 @@ H5FL_blk_gc(void) /* Double check that all the memory on the free lists are recycled */ assert(H5FL_blk_gc_head.mem_freed==0); - FUNC_LEAVE_NOAPI(SUCCEED); +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_blk_gc() */ @@ -1098,7 +1111,7 @@ H5FL_blk_term(void) H5FL_blk_gc_node_t *left; /* pointer to garbage collection lists with work left */ H5FL_blk_gc_node_t *tmp; /* Temporary pointer to a garbage collection node */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FL_blk_term); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FL_blk_term) /* Free the nodes on the garbage collection list, keeping nodes with allocations outstanding */ left=NULL; @@ -1130,7 +1143,7 @@ printf("H5FL_blk_term: head->name=%s, head->allocated=%d\n", H5FL_blk_gc_head.fi /* Point to the list of nodes left with allocations open, if any */ H5FL_blk_gc_head.first=left; - FUNC_LEAVE_NOAPI(H5FL_blk_gc_head.first!=NULL ? 1 : 0); + FUNC_LEAVE_NOAPI(H5FL_blk_gc_head.first!=NULL ? 1 : 0) } /* end H5FL_blk_term() */ @@ -1157,11 +1170,11 @@ H5FL_arr_init(H5FL_arr_head_t *head) size_t u; /* Local index variable */ herr_t ret_value=SUCCEED; /* return value*/ - FUNC_ENTER_NOAPI_NOINIT(H5FL_arr_init); + FUNC_ENTER_NOAPI_NOINIT(H5FL_arr_init) /* Allocate a new garbage collection node */ if (NULL==(new_node = H5MM_malloc(sizeof(H5FL_gc_arr_node_t)))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Initialize the new garbage collection node */ new_node->list=head; @@ -1182,7 +1195,7 @@ H5FL_arr_init(H5FL_arr_head_t *head) head->init=1; done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_arr_init() */ @@ -1209,11 +1222,11 @@ H5FL_arr_free(H5FL_arr_head_t *head, void *obj) size_t free_nelem; /* Number of elements in node being free'd */ void *ret_value=NULL; /* Return value */ - FUNC_ENTER_NOAPI(H5FL_arr_free, NULL); + FUNC_ENTER_NOAPI(H5FL_arr_free, NULL) /* The H5MM_xfree code allows obj to null */ if (!obj) - HGOTO_DONE (NULL); + HGOTO_DONE (NULL) /* Double check parameters */ assert(head); @@ -1249,14 +1262,16 @@ H5FL_arr_free(H5FL_arr_head_t *head, void *obj) /* Check for exceeding free list memory use limits */ /* First check this particular list */ if(head->list_mem>H5FL_arr_lst_mem_lim) - H5FL_arr_gc_list(head); + if(H5FL_arr_gc_list(head)<0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, NULL, "garbage collection failed during free") /* Then check the global amount memory on array free lists */ if(H5FL_arr_gc_head.mem_freed>H5FL_arr_glb_mem_lim) - H5FL_arr_gc(); + if(H5FL_arr_gc()<0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, NULL, "garbage collection failed during free") done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_arr_free() */ @@ -1282,7 +1297,7 @@ H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem) void *ret_value; /* Pointer to object to return */ size_t mem_size; /* Size of memory block being recycled */ - FUNC_ENTER_NOAPI(H5FL_arr_malloc, NULL); + FUNC_ENTER_NOAPI(H5FL_arr_malloc, NULL) /* Double check parameters */ assert(head); @@ -1290,7 +1305,8 @@ H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem) /* Make certain the list is initialized first */ if(!head->init) - H5FL_arr_init(head); + if(H5FL_arr_init(head)<0) + HGOTO_ERROR (H5E_RESOURCE, H5E_CANTINIT, NULL, "can't initialize 'array' blocks") /* Get the set of the memory block */ mem_size=head->list_arr[elem].size; @@ -1330,7 +1346,7 @@ H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem) ret_value=((char *)new_obj)+sizeof(H5FL_arr_list_t); done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_arr_malloc() */ @@ -1354,7 +1370,7 @@ H5FL_arr_calloc(H5FL_arr_head_t *head, size_t elem) { void *ret_value; /* Pointer to object to return */ - FUNC_ENTER_NOAPI(H5FL_arr_calloc, NULL); + FUNC_ENTER_NOAPI(H5FL_arr_calloc, NULL) /* Double check parameters */ assert(head); @@ -1362,13 +1378,13 @@ H5FL_arr_calloc(H5FL_arr_head_t *head, size_t elem) /* Allocate the array */ if (NULL==(ret_value = H5FL_arr_malloc(head,elem))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Clear to zeros */ HDmemset(ret_value,0,head->list_arr[elem].size); done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_arr_calloc() */ @@ -1392,7 +1408,7 @@ H5FL_arr_realloc(H5FL_arr_head_t *head, void * obj, size_t new_elem) { void *ret_value; /* Pointer to object to return */ - FUNC_ENTER_NOAPI(H5FL_arr_realloc, NULL); + FUNC_ENTER_NOAPI(H5FL_arr_realloc, NULL) /* Double check parameters */ assert(head); @@ -1429,7 +1445,7 @@ H5FL_arr_realloc(H5FL_arr_head_t *head, void * obj, size_t new_elem) } /* end else */ done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_arr_realloc() */ @@ -1456,7 +1472,7 @@ H5FL_arr_gc_list(H5FL_arr_head_t *head) unsigned u; /* Counter for array of free lists */ size_t total_mem; /* Total memory used on list */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FL_arr_gc_list); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FL_arr_gc_list) /* Walk through the array of free lists */ for(u=0; u<(unsigned)head->maxelem; u++) { @@ -1491,7 +1507,7 @@ H5FL_arr_gc_list(H5FL_arr_head_t *head) /* Double check that all the memory on this list is recycled */ assert(head->list_mem==0); - FUNC_LEAVE_NOAPI(SUCCEED); + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5FL_arr_gc_list() */ @@ -1514,14 +1530,16 @@ static herr_t H5FL_arr_gc(void) { H5FL_gc_arr_node_t *gc_arr_node; /* Pointer into the list of things to garbage collect */ + herr_t ret_value=SUCCEED; /* return value*/ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FL_arr_gc); + FUNC_ENTER_NOAPI_NOINIT(H5FL_arr_gc) /* Walk through all the free lists, free()'ing the nodes */ gc_arr_node=H5FL_arr_gc_head.first; while(gc_arr_node!=NULL) { /* Release the free nodes on the list */ - H5FL_arr_gc_list(gc_arr_node->list); + if(H5FL_arr_gc_list(gc_arr_node->list)<0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "garbage collection of list failed") /* Go on to the next free list to garbage collect */ gc_arr_node=gc_arr_node->next; @@ -1530,7 +1548,8 @@ H5FL_arr_gc(void) /* Double check that all the memory on the free lists are recycled */ assert(H5FL_arr_gc_head.mem_freed==0); - FUNC_LEAVE_NOAPI(SUCCEED); +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_arr_gc() */ @@ -1559,7 +1578,7 @@ H5FL_arr_term(void) H5FL_gc_arr_node_t *left; /* pointer to garbage collection lists with work left */ H5FL_gc_arr_node_t *tmp; /* Temporary pointer to a garbage collection node */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FL_arr_term); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FL_arr_term) /* Free the nodes on the garbage collection list, keeping nodes with allocations outstanding */ left=NULL; @@ -1593,7 +1612,7 @@ printf("H5FL_arr_term: head->name=%s, head->allocated=%d\n", H5FL_arr_gc_head.fi /* Point to the list of nodes left with allocations open, if any */ H5FL_arr_gc_head.first=left; - FUNC_LEAVE_NOAPI(H5FL_arr_gc_head.first!=NULL ? 1 : 0); + FUNC_LEAVE_NOAPI(H5FL_arr_gc_head.first!=NULL ? 1 : 0) } /* end H5FL_arr_term() */ @@ -1757,18 +1776,24 @@ done: herr_t H5FL_garbage_coll(void) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FL_garbage_coll); + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT(H5FL_garbage_coll) /* Garbage collect the free lists for array objects */ - H5FL_arr_gc(); + if(H5FL_arr_gc()<0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "can't garbage collect array objects") /* Garbage collect free lists for blocks */ - H5FL_blk_gc(); + if(H5FL_blk_gc()<0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "can't garbage collect block objects") /* Garbage collect the free lists for regular objects */ - H5FL_reg_gc(); + if(H5FL_reg_gc()<0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "can't garbage collect regular objects") - FUNC_LEAVE_NOAPI(SUCCEED); +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_garbage_coll() */ @@ -1807,7 +1832,7 @@ H5FL_set_free_list_limits(int reg_global_lim, int reg_list_lim, int arr_global_l { herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(H5FL_set_free_list_limits, FAIL); + FUNC_ENTER_NOAPI(H5FL_set_free_list_limits, FAIL) /* Set the limit variables */ /* limit on all regular free lists */ @@ -1824,7 +1849,7 @@ H5FL_set_free_list_limits(int reg_global_lim, int reg_list_lim, int arr_global_l H5FL_blk_lst_mem_lim=(blk_list_lim==-1 ? UINT_MAX : (size_t)blk_list_lim); done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_set_free_list_limits() */ @@ -1852,13 +1877,13 @@ H5FL_term_interface(void) { int ret_value=0; - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FL_term_interface); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FL_term_interface) /* Garbage collect any nodes on the free lists */ - H5FL_garbage_coll(); + (void)H5FL_garbage_coll(); ret_value=H5FL_reg_term()+H5FL_arr_term()+H5FL_blk_term(); - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } diff --git a/src/H5FO.c b/src/H5FO.c index d29712e..6a18510 100644 --- a/src/H5FO.c +++ b/src/H5FO.c @@ -40,9 +40,9 @@ static int interface_initialize_g = 0; /* Information about object objects in a file */ typedef struct H5FO_open_obj_t { - haddr_t addr; /* Address of object header for object */ + haddr_t addr; /* Address of object header for object */ /* THIS MUST BE FIRST FOR TBBT ROUTINES */ - void *obj; /* Pointer to the object */ + void *obj; /* Pointer to the object */ hbool_t deleted; /* Flag to indicate that the object was deleted from the file */ } H5FO_open_obj_t; @@ -94,12 +94,12 @@ done: PURPOSE Checks if an object at an address is already open in the file. USAGE - void *H5FO_opened(f,addr) + void * H5FO_opened(f,addr) const H5F_t *f; IN: File to check opened object info set haddr_t addr; IN: Address of object to check RETURNS - Returns a non-negative ID for the object on success, negative on failure + Returns a pointer to the object on success, NULL on failure DESCRIPTION Check is an object at an address (the address of the object's object header) is already open in the file and return the ID for that object if it is open. @@ -142,12 +142,12 @@ done: NAME H5FO_insert PURPOSE - Insert a newly opened object/ID pair into the opened object info set + Insert a newly opened object/pointer pair into the opened object info set USAGE herr_t H5FO_insert(f,addr,obj) H5F_t *f; IN/OUT: File's opened object info set haddr_t addr; IN: Address of object to insert - void *obj; IN: Pointer to object to insert + void *obj; IN: Pointer to object to insert int type; IN: Type of object being inserted RETURNS @@ -160,7 +160,7 @@ done: REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5FO_insert(const H5F_t *f, haddr_t addr, void * obj) +H5FO_insert(const H5F_t *f, haddr_t addr, void *obj) { H5FO_open_obj_t *open_obj; /* Information about open object */ herr_t ret_value=SUCCEED; /* Return value */ diff --git a/src/H5FOprivate.h b/src/H5FOprivate.h index 1f48f8b..de385f7 100644 --- a/src/H5FOprivate.h +++ b/src/H5FOprivate.h @@ -36,8 +36,8 @@ typedef H5TB_TREE H5FO_t; /* Currently, all open objects are stored in TBB /* Private routines */ H5_DLL herr_t H5FO_create(const H5F_t *f); -H5_DLL void * H5FO_opened(const H5F_t *f, haddr_t addr); -H5_DLL herr_t H5FO_insert(const H5F_t *f, haddr_t addr, void * obj); +H5_DLL void *H5FO_opened(const H5F_t *f, haddr_t addr); +H5_DLL herr_t H5FO_insert(const H5F_t *f, haddr_t addr, void *obj); H5_DLL herr_t H5FO_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr); H5_DLL herr_t H5FO_mark(const H5F_t *f, haddr_t addr, hbool_t deleted); H5_DLL htri_t H5FO_marked(const H5F_t *f, haddr_t addr); diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index c1f07fa..87be161 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -95,7 +95,7 @@ typedef struct H5F_file_t { unsigned super_chksum; /* Superblock checksum */ unsigned drvr_chksum; /* Driver info block checksum */ - struct H5AC_t *cache; /* The object cache */ + H5AC_t *cache; /* The object cache */ hid_t fcpl_id; /* File creation property list ID */ int mdc_nelmts; /* Size of meta data cache (elements) */ size_t rdcc_nelmts; /* Size of raw data chunk cache (elmts) */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 2401228..8c369fb 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -447,8 +447,8 @@ H5_DLL herr_t H5F_block_write(const H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size, hid_t dxpl_id, const void *buf); /* Address-related functions */ -H5_DLL void H5F_addr_encode(H5F_t *, uint8_t** /*in,out*/, haddr_t); -H5_DLL void H5F_addr_decode(H5F_t *, const uint8_t** /*in,out*/, +H5_DLL void H5F_addr_encode(const H5F_t *, uint8_t** /*in,out*/, haddr_t); +H5_DLL void H5F_addr_decode(const H5F_t *, const uint8_t** /*in,out*/, haddr_t* /*out*/); H5_DLL herr_t H5F_addr_pack(H5F_t *f, haddr_t *addr_p /*out*/, const unsigned long objno[2]); diff --git a/src/H5Gnode.c b/src/H5Gnode.c index d07e34e..48d9879 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -72,7 +72,8 @@ static H5G_node_t *H5G_node_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const vo static herr_t H5G_node_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5G_node_t *sym); static herr_t H5G_node_dest(H5F_t *f, H5G_node_t *sym); -static herr_t H5G_node_clear(H5G_node_t *sym); +static herr_t H5G_node_clear(H5F_t *f, H5G_node_t *sym, hbool_t destroy); +static herr_t H5G_compute_size(H5F_t *f, H5G_node_t *sym, size_t *size_ptr); /* B-tree callbacks */ static size_t H5G_node_sizeof_rkey(const H5F_t *f, const void *_udata); @@ -109,6 +110,7 @@ const H5AC_class_t H5AC_SNODE[1] = {{ (H5AC_flush_func_t)H5G_node_flush, (H5AC_dest_func_t)H5G_node_dest, (H5AC_clear_func_t)H5G_node_clear, + (H5AC_size_func_t)H5G_compute_size, }}; /* H5G inherits B-tree like properties from H5B */ @@ -638,11 +640,12 @@ H5G_node_dest(H5F_t UNUSED *f, H5G_node_t *sym) *------------------------------------------------------------------------- */ static herr_t -H5G_node_clear(H5G_node_t *sym) +H5G_node_clear(H5F_t *f, H5G_node_t *sym, hbool_t destroy) { int i; /* Local index variable */ + herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_node_clear); + FUNC_ENTER_NOAPI_NOINIT(H5G_node_clear); /* * Check arguments. @@ -655,11 +658,53 @@ H5G_node_clear(H5G_node_t *sym) sym->entry[i].dirty=FALSE; sym->cache_info.is_dirty = FALSE; - FUNC_LEAVE_NOAPI(SUCCEED); + /* + * Destroy the symbol node? This might happen if the node is being + * preempted from the cache. + */ + if (destroy) + if (H5G_node_dest(f, sym) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to destroy symbol table node"); + +done: + FUNC_LEAVE_NOAPI(ret_value); } /* end H5G_node_clear() */ /*------------------------------------------------------------------------- + * Function: H5G_compute_size + * + * Purpose: Compute the size in bytes of the specified instance of + * H5G_node_t on disk, and return it in *size_ptr. On failure + * the value of size_ptr is undefined. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: John Mainzer + * 5/13/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_compute_size(H5F_t *f, H5G_node_t UNUSED *sym, size_t *size_ptr) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_compute_size); + + /* + * Check arguments. + */ + assert(f); + assert(size_ptr); + + *size_ptr = H5G_node_size(f); + + FUNC_LEAVE_NOAPI(SUCCEED); +} /* H5G_compute_size() */ + + +/*------------------------------------------------------------------------- * Function: H5G_node_create * * Purpose: Creates a new empty symbol table node. This function is @@ -1748,9 +1793,7 @@ done: herr_t H5G_node_close(const H5F_t *f) { - herr_t ret_value=SUCCEED; - - FUNC_ENTER_NOAPI(H5G_node_close,FAIL) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_node_close) /* Check arguments. */ assert(f); @@ -1758,8 +1801,7 @@ H5G_node_close(const H5F_t *f) /* Free the raw B-tree node buffer */ H5RC_DEC(H5F_GRP_BTREE_SHARED(f)); -done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(SUCCEED); } /* end H5G_node_close */ diff --git a/src/H5HG.c b/src/H5HG.c index 5e29a00..42a38ab 100644 --- a/src/H5HG.c +++ b/src/H5HG.c @@ -131,7 +131,8 @@ static H5HG_heap_t *H5HG_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void static herr_t H5HG_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, H5HG_heap_t *heap); static herr_t H5HG_dest(H5F_t *f, H5HG_heap_t *heap); -static herr_t H5HG_clear(H5HG_heap_t *heap); +static herr_t H5HG_clear(H5F_t *f, H5HG_heap_t *heap, hbool_t destroy); +static herr_t H5HG_compute_size(H5F_t *f, H5HG_heap_t *heap, size_t *size_ptr); /* * H5HG inherits cache-like properties from H5AC @@ -142,6 +143,7 @@ const H5AC_class_t H5AC_GHEAP[1] = {{ (H5AC_flush_func_t)H5HG_flush, (H5AC_dest_func_t)H5HG_dest, (H5AC_clear_func_t)H5HG_clear, + (H5AC_size_func_t)H5HG_compute_size, }}; /* Interface initialization */ @@ -592,9 +594,11 @@ H5HG_dest (H5F_t *f, H5HG_heap_t *heap) *------------------------------------------------------------------------- */ static herr_t -H5HG_clear(H5HG_heap_t *heap) +H5HG_clear(H5F_t *f, H5HG_heap_t *heap, hbool_t destroy) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HG_clear); + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT(H5HG_clear); /* Check arguments */ assert (heap); @@ -602,11 +606,47 @@ H5HG_clear(H5HG_heap_t *heap) /* Mark heap as clean */ heap->cache_info.is_dirty = FALSE; - FUNC_LEAVE_NOAPI(SUCCEED); + if (destroy) + if (H5HG_dest(f, heap) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy global heap collection"); + +done: + FUNC_LEAVE_NOAPI(ret_value); } /* H5HG_clear() */ /*------------------------------------------------------------------------- + * Function: H5HG_compute_size + * + * Purpose: Compute the size in bytes of the specified instance of + * H5HG_heap_t on disk, and return it in *len_ptr. On failure, + * the value of *len_ptr is undefined. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: John Mainzer + * 5/13/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HG_compute_size(H5F_t UNUSED *f, H5HG_heap_t *heap, size_t *size_ptr) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HG_compute_size); + + /* Check arguments */ + HDassert(heap); + HDassert(size_ptr); + + *size_ptr = heap->size; + + FUNC_LEAVE_NOAPI(SUCCEED); +} /* H5HG_compute_size() */ + + +/*------------------------------------------------------------------------- * Function: H5HG_alloc * * Purpose: Given a heap with enough free space, this function will split @@ -990,7 +1030,6 @@ done: HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to unprotect heap."); FUNC_LEAVE_NOAPI(ret_value); - } /* H5HG_insert() */ @@ -1230,4 +1269,3 @@ done: FUNC_LEAVE_NOAPI(ret_value); } - diff --git a/src/H5HGprivate.h b/src/H5HGprivate.h index 904ce2f..93e7793 100644 --- a/src/H5HGprivate.h +++ b/src/H5HGprivate.h @@ -45,6 +45,8 @@ H5_DLL herr_t H5HG_insert(H5F_t *f, hid_t dxpl_id, size_t size, void *obj, H5_DLL void *H5HG_read(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj, void *object); H5_DLL int H5HG_link(H5F_t *f, hid_t dxpl_id, const H5HG_t *hobj, int adjust); H5_DLL herr_t H5HG_remove(H5F_t *f, hid_t dxpl_id, H5HG_t *hobj); + +/* Debugging functions */ H5_DLL herr_t H5HG_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth); diff --git a/src/H5HL.c b/src/H5HL.c index 8082b7f..f217eb5 100644 --- a/src/H5HL.c +++ b/src/H5HL.c @@ -71,7 +71,8 @@ static H5HL_t *H5HL_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udat void *udata2); static herr_t H5HL_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, H5HL_t *heap); static herr_t H5HL_dest(H5F_t *f, H5HL_t *heap); -static herr_t H5HL_clear(H5HL_t *heap); +static herr_t H5HL_clear(H5F_t *f, H5HL_t *heap, hbool_t destroy); +static herr_t H5HL_compute_size(H5F_t *f, H5HL_t *heap, size_t *size_ptr); /* * H5HL inherits cache-like properties from H5AC @@ -82,6 +83,7 @@ const H5AC_class_t H5AC_LHEAP[1] = {{ (H5AC_flush_func_t)H5HL_flush, (H5AC_dest_func_t)H5HL_dest, (H5AC_clear_func_t)H5HL_clear, + (H5AC_size_func_t)H5HL_compute_size, }}; /* Interface initialization */ @@ -660,9 +662,11 @@ H5HL_dest(H5F_t UNUSED *f, H5HL_t *heap) *------------------------------------------------------------------------- */ static herr_t -H5HL_clear(H5HL_t *heap) +H5HL_clear(H5F_t *f, H5HL_t *heap, hbool_t destroy) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HL_clear); + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT(H5HL_clear); /* check arguments */ assert(heap); @@ -670,11 +674,47 @@ H5HL_clear(H5HL_t *heap) /* Mark heap as clean */ heap->cache_info.is_dirty = FALSE; - FUNC_LEAVE_NOAPI(SUCCEED); + if (destroy) + if (H5HL_dest(f, heap) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy local heap collection"); + +done: + FUNC_LEAVE_NOAPI(ret_value); } /* end H5HL_clear() */ /*------------------------------------------------------------------------- + * Function: H5HL_compute_size + * + * Purpose: Compute the size in bytes of the specified instance of + * H5HL_t on disk, and return it in *len_ptr. On failure, + * the value of *len_ptr is undefined. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: John Mainzer + * 5/13/04 + * + * Modifications: + *------------------------------------------------------------------------- + */ +static herr_t +H5HL_compute_size(H5F_t *f, H5HL_t *heap, size_t *size_ptr) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HL_compute_size); + + /* check arguments */ + HDassert(f); + HDassert(heap); + HDassert(size_ptr); + + *size_ptr = H5HL_SIZEOF_HDR(f) + heap->disk_alloc; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HL_compute_size() */ + + +/*------------------------------------------------------------------------- * Function: H5HL_read * * Purpose: Reads some object (or part of an object) from the heap diff --git a/src/H5HLprivate.h b/src/H5HLprivate.h index 711f8b5..baf9561 100644 --- a/src/H5HLprivate.h +++ b/src/H5HLprivate.h @@ -51,6 +51,10 @@ H5HL_ALIGN(H5F_SIZEOF_SIZE (F) + /*ptr to next free block */ \ H5F_SIZEOF_SIZE (F)) /*size of this free block */ +/****************************/ +/* Library Private Typedefs */ +/****************************/ + /* Typedef for local heap in memory (defined in H5HL.c) */ typedef struct H5HL_t H5HL_t; @@ -65,6 +69,8 @@ H5_DLL size_t H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t size, const void *buf); H5_DLL herr_t H5HL_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size); H5_DLL herr_t H5HL_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr); + +/* Debugging functions */ H5_DLL herr_t H5HL_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int fwidth); #endif diff --git a/src/H5MM.c b/src/H5MM.c index afbf8b4..312c86e 100644 --- a/src/H5MM.c +++ b/src/H5MM.c @@ -24,12 +24,16 @@ * *------------------------------------------------------------------------- */ + +/* Pablo information */ +/* (Put before include files to avoid problems with inline functions) */ +#define PABLO_MASK H5MM_mask + #include "H5private.h" #include "H5Eprivate.h" #include "H5MMprivate.h" /* Interface initialization? */ -#define PABLO_MASK H5MM_mask static int interface_initialize_g = 0; #define INTERFACE_INIT NULL @@ -58,7 +62,7 @@ static int interface_initialize_g = 0; void * H5MM_malloc(size_t size) { - /* Use FUNC_ENTER_NOAPI_NOINIT here to avoid performance issues */ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MM_malloc); assert(size); @@ -91,7 +95,7 @@ H5MM_malloc(size_t size) void * H5MM_calloc(size_t size) { - /* Use FUNC_ENTER_NOAPI_NOINIT here to avoid performance issues */ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MM_calloc); assert(size); diff --git a/src/H5MPprivate.h b/src/H5MPprivate.h index 02b2a71..7d5fda7 100644 --- a/src/H5MPprivate.h +++ b/src/H5MPprivate.h @@ -246,7 +246,6 @@ #define color_H5FDwrite "red" #define color_H5FDflush "red" #define color_H5FDget_vfd_handle "red" -#define color_H5Premove_filter "red" #define color_H5Pset_fapl_core "red" #define color_H5Pget_fapl_core "red" #define color_H5Pset_fapl_family "red" @@ -324,6 +323,7 @@ #define color_H5Pget_nfilters "red" #define color_H5Pget_filter "red" #define color_H5Pget_filter_by_id "red" +#define color_H5Premove_filter "red" #define color_H5Pset_deflate "red" #define color_H5Pset_fletcher32 "red" #define color_H5Pset_szip "red" @@ -354,8 +354,8 @@ #define color_H5Pget_hyper_vector_size "red" #define color_H5Pset_small_data_block_size "red" #define color_H5Pget_small_data_block_size "red" -#define color_H5Pget_edc_check "red" #define color_H5Pset_edc_check "red" +#define color_H5Pget_edc_check "red" #define color_H5Pset_filter_callback "red" #define color_H5Screate "red" diff --git a/src/H5O.c b/src/H5O.c index c49768c..f2a1226 100644 --- a/src/H5O.c +++ b/src/H5O.c @@ -87,7 +87,8 @@ static H5O_t *H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_udata void *_udata2); static herr_t H5O_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5O_t *oh); static herr_t H5O_dest(H5F_t *f, H5O_t *oh); -static herr_t H5O_clear(H5O_t *oh); +static herr_t H5O_clear(H5F_t *f, H5O_t *oh, hbool_t destroy); +static herr_t H5O_compute_size(H5F_t *f, H5O_t *oh, size_t *size_ptr); /* H5O inherits cache-like properties from H5AC */ static const H5AC_class_t H5AC_OHDR[1] = {{ @@ -96,6 +97,7 @@ static const H5AC_class_t H5AC_OHDR[1] = {{ (H5AC_flush_func_t)H5O_flush, (H5AC_dest_func_t)H5O_dest, (H5AC_clear_func_t)H5O_clear, + (H5AC_size_func_t)H5O_compute_size, }}; /* Interface initialization */ @@ -867,11 +869,12 @@ H5O_dest(H5F_t UNUSED *f, H5O_t *oh) *------------------------------------------------------------------------- */ static herr_t -H5O_clear(H5O_t *oh) +H5O_clear(H5F_t *f, H5O_t *oh, hbool_t destroy) { unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_clear); + FUNC_ENTER_NOAPI_NOINIT(H5O_clear); /* check args */ assert(oh); @@ -887,11 +890,66 @@ H5O_clear(H5O_t *oh) /* Mark whole header as clean */ oh->cache_info.is_dirty=FALSE; - FUNC_LEAVE_NOAPI(SUCCEED); + if (destroy) + if (H5O_dest(f, oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header data"); + +done: + FUNC_LEAVE_NOAPI(ret_value); } /* end H5O_clear() */ /*------------------------------------------------------------------------- + * Function: H5O_compute_size + * + * Purpose: Compute the size in bytes of the specified instance of + * H5O_t on disk, and return it in *len_ptr. On failure, + * the value of *len_ptr is undefined. + * + * The value returned will probably be low unless the object + * has just been flushed, as we simply total up the size of + * the header with the sizes of the chunks. Thus any message + * that has been added since the last flush will not be + * reflected in the total. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: John Mainzer + * 5/13/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_compute_size(H5F_t *f, H5O_t *oh, size_t *size_ptr) +{ + unsigned u; + size_t size; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_compute_size); + + /* check args */ + HDassert(f); + HDassert(oh); + HDassert(size_ptr); + + size = H5O_SIZEOF_HDR(f); + + for (u = 0; u < oh->nchunks; u++) + { + size += oh->chunk[u].size; + } + + HDassert(size >= H5O_SIZEOF_HDR(f)); + + *size_ptr = size; + + FUNC_LEAVE_NOAPI(SUCCEED); +} /* H5O_compute_size() */ + + +/*------------------------------------------------------------------------- * Function: H5O_reset * * Purpose: Some message data structures have internal fields that diff --git a/src/H5Oattr.c b/src/H5Oattr.c index 3bb9bd8..d41db50 100644 --- a/src/H5Oattr.c +++ b/src/H5Oattr.c @@ -116,7 +116,7 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t UNUSED * unsigned flags=0; /* Attribute flags */ H5A_t *ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5O_attr_decode, NULL); + FUNC_ENTER_NOAPI_NOINIT(H5O_attr_decode); /* check args */ assert(f); @@ -257,7 +257,7 @@ H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg) hbool_t type_shared; /* Flag to indicate that a shared datatype is used for this attribute */ herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5O_attr_encode, FAIL); + FUNC_ENTER_NOAPI_NOINIT(H5O_attr_encode); /* check args */ assert(f); @@ -376,7 +376,7 @@ H5O_attr_copy(const void *_src, void *_dst) H5A_t *dst = NULL; void *ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5O_attr_copy, NULL); + FUNC_ENTER_NOAPI_NOINIT(H5O_attr_copy); /* check args */ assert(src); @@ -428,7 +428,7 @@ H5O_attr_size(H5F_t UNUSED *f, const void *_mesg) hbool_t type_shared; /* Flag to indicate that a shared datatype is used for this attribute */ size_t ret_value = 0; - FUNC_ENTER_NOAPI(H5O_attr_size, 0); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_attr_size); assert(attr); @@ -467,7 +467,6 @@ H5O_attr_size(H5F_t UNUSED *f, const void *_mesg) attr->ds_size + /*data space */ attr->data_size; /*the data itself */ -done: FUNC_LEAVE_NOAPI(ret_value); } @@ -494,7 +493,7 @@ H5O_attr_reset(void *_mesg) H5A_t *tmp = NULL; herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5O_attr_reset, FAIL); + FUNC_ENTER_NOAPI_NOINIT(H5O_attr_reset); if (attr) { if (NULL==(tmp = H5MM_malloc(sizeof(H5A_t)))) @@ -529,7 +528,7 @@ H5O_attr_delete(H5F_t UNUSED *f, hid_t dxpl_id, const void *_mesg) const H5A_t *attr = (const H5A_t *) _mesg; herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5O_attr_delete, FAIL); + FUNC_ENTER_NOAPI_NOINIT(H5O_attr_delete); /* check args */ assert(f); @@ -568,7 +567,7 @@ H5O_attr_link(H5F_t UNUSED *f, hid_t dxpl_id, const void *_mesg) const H5A_t *attr = (const H5A_t *) _mesg; herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5O_attr_link, FAIL); + FUNC_ENTER_NOAPI_NOINIT(H5O_attr_link); /* check args */ assert(f); @@ -614,7 +613,7 @@ H5O_attr_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int in herr_t (*debug)(H5F_t*, hid_t, const void*, FILE*, int, int)=NULL; herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5O_attr_debug, FAIL); + FUNC_ENTER_NOAPI_NOINIT(H5O_attr_debug); /* check args */ assert(f); diff --git a/src/H5Obogus.c b/src/H5Obogus.c index b049654..e1139c4 100644 --- a/src/H5Obogus.c +++ b/src/H5Obogus.c @@ -94,7 +94,7 @@ H5O_bogus_decode(H5F_t UNUSED *f, hid_t dxpl_id, const uint8_t *p, H5O_bogus_t *mesg=NULL; void *ret_value; /* Return value */ - FUNC_ENTER(H5O_bogus_decode, NULL); + FUNC_ENTER_NOAPI_NOINIT(H5O_bogus_decode); /* check args */ assert(f); @@ -119,7 +119,7 @@ done: if(ret_value==NULL && mesg!=NULL) H5MM_xfree(mesg); - FUNC_LEAVE(ret_value); + FUNC_LEAVE_NOAPI(ret_value); } /* end H5O_bogus_decode() */ @@ -141,7 +141,7 @@ done: static herr_t H5O_bogus_encode(H5F_t UNUSED *f, uint8_t *p, const void UNUSED *mesg) { - FUNC_ENTER(H5O_bogus_encode, FAIL); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_bogus_encode); /* check args */ assert(f); @@ -151,7 +151,7 @@ H5O_bogus_encode(H5F_t UNUSED *f, uint8_t *p, const void UNUSED *mesg) /* encode */ UINT32ENCODE(p, H5O_BOGUS_VALUE); - FUNC_LEAVE(SUCCEED); + FUNC_LEAVE_NOAPI(SUCCEED); } /* end H5O_bogus_encode() */ @@ -178,12 +178,12 @@ H5O_bogus_encode(H5F_t UNUSED *f, uint8_t *p, const void UNUSED *mesg) static size_t H5O_bogus_size(H5F_t UNUSED *f, const void UNUSED *mesg) { - FUNC_ENTER(H5O_bogus_size, 0); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_bogus_size); /* check args */ assert(f); - FUNC_LEAVE(4); + FUNC_LEAVE_NOAPI(4); } /* end H5O_bogus_size() */ @@ -208,7 +208,7 @@ H5O_bogus_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE * { const H5O_bogus_t *mesg = (const H5O_bogus_t *)_mesg; - FUNC_ENTER(H5O_name_debug, FAIL); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_name_debug); /* check args */ assert(f); @@ -220,7 +220,7 @@ H5O_bogus_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE * fprintf(stream, "%*s%-*s `%u'\n", indent, "", fwidth, "Bogus Value:", mesg->u); - FUNC_LEAVE(SUCCEED); + FUNC_LEAVE_NOAPI(SUCCEED); } #endif /* H5O_ENABLE_BOGUS */ diff --git a/src/H5Ocont.c b/src/H5Ocont.c index e8dca5b..1058b37 100644 --- a/src/H5Ocont.c +++ b/src/H5Ocont.c @@ -88,7 +88,7 @@ H5O_cont_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p, H5O_shared_t U H5O_cont_t *cont = NULL; void *ret_value; - FUNC_ENTER_NOAPI(H5O_cont_decode, NULL); + FUNC_ENTER_NOAPI_NOINIT(H5O_cont_decode); /* check args */ assert(f); @@ -128,9 +128,8 @@ static herr_t H5O_cont_encode(H5F_t *f, uint8_t *p, const void *_mesg) { const H5O_cont_t *cont = (const H5O_cont_t *) _mesg; - herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5O_cont_encode, FAIL); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_cont_encode); /* check args */ assert(f); @@ -141,8 +140,7 @@ H5O_cont_encode(H5F_t *f, uint8_t *p, const void *_mesg) H5F_addr_encode(f, &p, cont->addr); H5F_ENCODE_LENGTH(f, p, cont->size); -done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(SUCCEED); } @@ -166,9 +164,8 @@ H5O_cont_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE * int indent, int fwidth) { const H5O_cont_t *cont = (const H5O_cont_t *) _mesg; - herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5O_cont_debug, FAIL); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_cont_debug); /* check args */ assert(f); @@ -187,6 +184,5 @@ H5O_cont_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE * "Points to chunk number:", (int) (cont->chunkno)); -done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(SUCCEED); } diff --git a/src/Makefile.in b/src/Makefile.in index 8827351..f8c6e68 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -30,7 +30,7 @@ LIB=libhdf5.la DISTCLEAN=libhdf5.settings ## Source and object files for the library (lexicographically)... -LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5D.c H5Dcontig.c H5Dcompact.c H5Defl.c \ +LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5C.c H5D.c H5Dcontig.c H5Dcompact.c H5Defl.c \ H5Dio.c H5Distore.c H5Dmpio.c H5Dselect.c H5Dtest.c H5E.c H5F.c \ H5FD.c \ H5FDcore.c H5FDfamily.c H5FDgass.c H5FDlog.c H5FDmpi.c H5FDmpio.c \ @@ -54,7 +54,8 @@ LIB_OBJ=$(LIB_SRC:.c=.lo) 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 \ +PUB_HDR=H5public.h H5Apublic.h H5ACpublic.h H5Bpublic.h H5Cpublic.h \ + H5Dpublic.h \ H5Epublic.h H5Fpublic.h H5FDpublic.h H5FDcore.h H5FDfamily.h \ H5FDgass.h H5FDlog.h H5FDmpi.h H5FDmpio.h H5FDmpiposix.h \ H5FDmulti.h H5FDsec2.h H5FDsrb.h H5FDstdio.h H5FDstream.h \ @@ -64,6 +65,7 @@ PUB_HDR=H5public.h H5Apublic.h H5ACpublic.h H5Bpublic.h H5Dpublic.h \ ## Other header files (not to be installed)... PRIVATE_HDR=H5private.h H5Aprivate.h H5Apkg.h H5ACprivate.h H5Bprivate.h \ + H5Cprivate.h \ H5Dprivate.h H5Eprivate.h H5Fprivate.h H5FDprivate.h H5FLprivate.h \ H5FOprivate.h H5FSprivate.h H5Gprivate.h H5Gpkg.h \ H5HGprivate.h H5HLprivate.h H5HPprivate.h H5Iprivate.h H5MFprivate.h \ diff --git a/test/ohdr.c b/test/ohdr.c index 877ae19..261ae68 100644 --- a/test/ohdr.c +++ b/test/ohdr.c @@ -98,7 +98,7 @@ main(void) H5Eprint(stdout); goto error; } - if (H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, NULL, HADDR_UNDEF, TRUE)<0) { + if (H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE)<0) { H5_FAILED(); H5Eprint(stdout); goto error; @@ -126,7 +126,7 @@ main(void) H5Eprint(stdout); goto error; } - if (H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, NULL, HADDR_UNDEF, TRUE)<0) { + if (H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE)<0) { H5_FAILED(); H5Eprint(stdout); goto error; @@ -155,7 +155,7 @@ main(void) H5Eprint(stdout); goto error; } - if (H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, NULL, HADDR_UNDEF, TRUE)<0) { + if (H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE)<0) { H5_FAILED(); H5Eprint(stdout); goto error; @@ -183,7 +183,7 @@ main(void) H5Eprint(stdout); goto error; } - if (H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, NULL, HADDR_UNDEF, TRUE)<0) { + if (H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE)<0) { H5_FAILED(); H5Eprint(stdout); goto error; @@ -218,7 +218,7 @@ main(void) goto error; } } - if (H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, NULL, HADDR_UNDEF, TRUE)<0) { + if (H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE)<0) { H5_FAILED(); H5Eprint(stdout); goto error; @@ -237,7 +237,7 @@ main(void) H5Eprint(stdout); goto error; } - if (H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, NULL, HADDR_UNDEF, TRUE)<0) { + if (H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE)<0) { H5_FAILED(); H5Eprint(stdout); goto error; -- cgit v0.12