From cd5ad177a23698c1daf6fb8c4195336865d795d2 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Sat, 11 Aug 2012 21:20:43 -0500 Subject: [svn-r22669] Description: Merge r22634:2266 from trunk to revise_chunks branch Tested on: Mac OSX/64 10.7.4 (amazon) w/debug, gcc-4.7.x, C++, FORTRAN and threadsafe (h5committest not needed on this branch) --- CMakeLists.txt | 8 + hl/test/test_image.c | 7 +- src/H5ACprivate.h | 2 + src/H5C.c | 464 ++++++++++++++++++++++++------------- src/H5Cpkg.h | 19 ++ src/H5Cprivate.h | 27 ++- src/H5Dchunk.c | 4 +- src/H5Doh.c | 2 +- src/H5Eint.c | 10 +- src/H5F.c | 12 +- src/H5FDcore.c | 10 +- src/H5FDmpi.c | 19 +- src/H5FDmpiposix.c | 20 +- src/H5FS.c | 129 ++++++++--- src/H5FScache.c | 33 ++- src/H5FSsection.c | 6 +- src/H5Fsuper.c | 2 +- src/H5Fsuper_cache.c | 44 +++- src/H5HFsection.c | 12 +- src/H5HG.c | 2 +- src/H5MF.c | 4 + src/H5Ocopy.c | 5 +- src/H5Otest.c | 2 +- src/H5Pfapl.c | 47 ++-- src/H5Shyper.c | 2 +- src/H5Spoint.c | 2 +- src/H5Sselect.c | 2 +- src/H5Tarray.c | 3 +- src/H5trace.c | 1 + test/accum.c | 18 +- test/cache.c | 4 +- test/cache_common.c | 2 +- test/cache_tagging.c | 8 +- test/dsets.c | 14 +- test/dt_arith.c | 6 +- test/dtypes.c | 35 +-- test/file_image.c | 26 ++- test/freespace.c | 2 + test/h5test.c | 4 + test/ntypes.c | 1 + test/objcopy.c | 2 +- test/tsohm.c | 8 +- test/tunicode.c | 2 + testpar/t_dset.c | 6 +- testpar/testphdf5.c | 20 +- tools/h5dump/CMakeLists.txt | 33 ++- tools/h5import/CMakeLists.txt | 4 +- tools/h5repack/h5repack_copy.c | 2 +- tools/h5repack/h5repack_opttable.c | 2 +- tools/lib/h5diff.c | 27 +-- tools/misc/talign.c | 15 +- 51 files changed, 778 insertions(+), 363 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c51eb7..0f18bdc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -563,6 +563,9 @@ IF (HDF5_ENABLE_Z_LIB_SUPPORT) IF (NOT H5_ZLIB_HEADER) IF (NOT ZLIB_USE_EXTERNAL) FIND_PACKAGE (ZLIB NAMES ${ZLIB_PACKAGE_NAME}${HDF_PACKAGE_EXT}) + IF (NOT ZLIB_FOUND) + FIND_PACKAGE (ZLIB) # Legacy find + ENDIF (NOT ZLIB_FOUND) ENDIF (NOT ZLIB_USE_EXTERNAL) IF (ZLIB_FOUND) SET (H5_HAVE_FILTER_DEFLATE 1) @@ -570,6 +573,7 @@ IF (HDF5_ENABLE_Z_LIB_SUPPORT) SET (H5_HAVE_LIBZ 1) SET (H5_ZLIB_HEADER "zlib.h") SET (ZLIB_INCLUDE_DIR_GEN ${ZLIB_INCLUDE_DIR}) + SET (ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR}) ELSE (ZLIB_FOUND) IF (HDF5_ALLOW_EXTERNAL_SUPPORT MATCHES "SVN" OR HDF5_ALLOW_EXTERNAL_SUPPORT MATCHES "TGZ") EXTERNAL_ZLIB_LIBRARY (${HDF5_ALLOW_EXTERNAL_SUPPORT} ${LIB_TYPE}) @@ -603,12 +607,16 @@ IF (HDF5_ENABLE_SZIP_SUPPORT) OPTION (HDF5_ENABLE_SZIP_ENCODING "Use SZip Encoding" OFF) IF (NOT SZIP_USE_EXTERNAL) FIND_PACKAGE (SZIP NAMES ${SZIP_PACKAGE_NAME}${HDF_PACKAGE_EXT}) + IF (NOT SZIP_FOUND) + FIND_PACKAGE (SZIP) # Legacy find + ENDIF (NOT SZIP_FOUND) ENDIF (NOT SZIP_USE_EXTERNAL) IF (SZIP_FOUND) SET (H5_HAVE_FILTER_SZIP 1) SET (H5_HAVE_SZLIB_H 1) SET (H5_HAVE_LIBSZ 1) SET (SZIP_INCLUDE_DIR_GEN ${SZIP_INCLUDE_DIR}) + SET (SZIP_INCLUDE_DIRS ${SZIP_INCLUDE_DIR}) ELSE (SZIP_FOUND) IF (HDF5_ALLOW_EXTERNAL_SUPPORT MATCHES "SVN" OR HDF5_ALLOW_EXTERNAL_SUPPORT MATCHES "TGZ") EXTERNAL_SZIP_LIBRARY (${HDF5_ALLOW_EXTERNAL_SUPPORT} ${LIB_TYPE} ${HDF5_ENABLE_SZIP_ENCODING}) diff --git a/hl/test/test_image.c b/hl/test/test_image.c index 3914a9f..4cef1b4 100644 --- a/hl/test/test_image.c +++ b/hl/test/test_image.c @@ -513,6 +513,7 @@ static int test_generate(void) FILE *f; const char *data_file = H5_get_srcdir_filename(DATA_FILE4); int i; + int retval = FAIL; /* create a file using default properties */ if ((fid=H5Fcreate(FILE3,H5F_ACC_TRUNC,H5P_DEFAULT,H5P_DEFAULT))<0) @@ -674,15 +675,17 @@ static int test_generate(void) if (H5Fclose(fid)<0) goto out; - return 0; + /* Indicate success */ + retval = 0; /* error zone, gracefully close */ out: + HDfree(data); H5E_BEGIN_TRY { H5Fclose(fid); } H5E_END_TRY; H5_FAILED(); - return FAIL; + return retval; } diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h index 2987c16..9efdc2d 100644 --- a/src/H5ACprivate.h +++ b/src/H5ACprivate.h @@ -325,6 +325,8 @@ H5_DLLVAR hid_t H5AC_ind_dxpl_id; #define H5AC__FLUSH_IGNORE_PROTECTED_FLAG H5C__FLUSH_IGNORE_PROTECTED_FLAG #define H5AC__FREE_FILE_SPACE_FLAG H5C__FREE_FILE_SPACE_FLAG #define H5AC__TAKE_OWNERSHIP_FLAG H5C__TAKE_OWNERSHIP_FLAG +#define H5AC__FLUSH_LAST_FLAG H5C__FLUSH_LAST_FLAG +#define H5AC__FLUSH_COLLECTIVELY_FLAG H5C__FLUSH_COLLECTIVELY_FLAG /* #defines of flags used to report entry status in the diff --git a/src/H5C.c b/src/H5C.c index c46817d..7005235 100644 --- a/src/H5C.c +++ b/src/H5C.c @@ -410,12 +410,6 @@ done: * Programmer: John Mainzer * 3/17/10 * - * Modifications: - * - * Heavily reworked to have each process flush a group of - * adjacent entries. - * JRM -- 4/15/10 - * *------------------------------------------------------------------------- */ #ifdef H5_HAVE_PARALLEL @@ -438,8 +432,13 @@ H5C_apply_candidate_list(H5F_t * f, int last_entry_to_flush; int entries_to_clear = 0; int entries_to_flush = 0; + int entries_to_flush_or_clear_last = 0; + int entries_to_flush_collectively = 0; int entries_cleared = 0; int entries_flushed = 0; + int entries_delayed = 0; + int entries_flushed_or_cleared_last = 0; + int entries_flushed_collectively = 0; int entries_examined = 0; int initial_list_len; int * candidate_assignment_table = NULL; @@ -447,6 +446,7 @@ H5C_apply_candidate_list(H5F_t * f, H5C_cache_entry_t * clear_ptr = NULL; H5C_cache_entry_t * entry_ptr = NULL; H5C_cache_entry_t * flush_ptr = NULL; + H5C_cache_entry_t * delayed_ptr = NULL; #if H5C_DO_SANITY_CHECKS haddr_t last_addr; #endif /* H5C_DO_SANITY_CHECKS */ @@ -608,12 +608,28 @@ H5C_apply_candidate_list(H5F_t * f, (int)(cache_ptr->LRU_list_len)); #endif /* H5C_APPLY_CANDIDATE_LIST__DEBUG */ + /* ====================================================================== * + * Now scan the LRU and PEL lists, flushing or clearing entries as + * needed. + * + * The flush_me_last and flush_me_collectively flags may dictate how or + * when some entries can be flushed, and should be addressed here. + * However, in their initial implementation, these flags only apply to the + * superblock, so there's only a relatively small change to this function + * to account for this one case where they come into play. If these flags + * are ever expanded upon, this function and the following flushing steps + * should be reworked to account for additional cases. + * ====================================================================== */ + entries_examined = 0; initial_list_len = cache_ptr->LRU_list_len; entry_ptr = cache_ptr->LRU_tail_ptr; + /* Examine each entry in the LRU list */ while((entry_ptr != NULL) && (entries_examined <= initial_list_len) && ((entries_cleared + entries_flushed) < num_candidates)) { + + /* If this process needs to clear this entry. */ if(entry_ptr->clear_on_unprotect) { entry_ptr->clear_on_unprotect = FALSE; clear_ptr = entry_ptr; @@ -621,7 +637,7 @@ H5C_apply_candidate_list(H5F_t * f, entries_cleared++; #if ( H5C_APPLY_CANDIDATE_LIST__DEBUG > 1 ) - HDfprintf(stdout, "%s:%d: clearing 0x%llx.\n", FUNC, mpi_rank, + HDfprintf(stdout, "%s:%d: clearing 0x%llx.\n", FUNC, mpi_rank, (long long)clear_ptr->addr); #endif /* H5C_APPLY_CANDIDATE_LIST__DEBUG */ @@ -634,14 +650,18 @@ H5C_apply_candidate_list(H5F_t * f, &first_flush, TRUE) < 0) HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't clear entry.") - } else if(entry_ptr->flush_immediately) { + } /* end if */ + + /* Else, if this process needs to flush this entry. */ + else if (entry_ptr->flush_immediately) { + entry_ptr->flush_immediately = FALSE; flush_ptr = entry_ptr; entry_ptr = entry_ptr->prev; entries_flushed++; #if ( H5C_APPLY_CANDIDATE_LIST__DEBUG > 1 ) - HDfprintf(stdout, "%s:%d: flushing 0x%llx.\n", FUNC, mpi_rank, + HDfprintf(stdout, "%s:%d: flushing 0x%llx.\n", FUNC, mpi_rank, (long long)flush_ptr->addr); #endif /* H5C_APPLY_CANDIDATE_LIST__DEBUG */ @@ -653,17 +673,20 @@ H5C_apply_candidate_list(H5F_t * f, H5C__NO_FLAGS_SET, &first_flush, TRUE) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't clear entry.") - } else { + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't flush entry.") + } /* end else-if */ + + /* Otherwise, no action to be taken on this entry. Grab the next. */ + else { entry_ptr = entry_ptr->prev; - } + } /* end else */ entries_examined++; } /* end while */ #if H5C_APPLY_CANDIDATE_LIST__DEBUG - HDfprintf(stdout, "%s:%d: entries examined/cleared/flushed = %d/%d/%d.\n", - FUNC, mpi_rank, entries_examined, + HDfprintf(stdout, "%s:%d: entries examined/cleared/flushed = %d/%d/%d.\n", + FUNC, mpi_rank, entries_examined, entries_cleared, entries_flushed); #endif /* H5C_APPLY_CANDIDATE_LIST__DEBUG */ @@ -672,69 +695,168 @@ H5C_apply_candidate_list(H5F_t * f, */ #if H5C_APPLY_CANDIDATE_LIST__DEBUG - HDfprintf(stdout, "%s:%d: scanning pinned entry list. len = %d\n", + HDfprintf(stdout, "%s:%d: scanning pinned entry list. len = %d\n", FUNC, mpi_rank, (int)(cache_ptr->pel_len)); #endif /* H5C_APPLY_CANDIDATE_LIST__DEBUG */ entry_ptr = cache_ptr->pel_head_ptr; while((entry_ptr != NULL) && - ((entries_cleared + entries_flushed) < num_candidates)) { - if(entry_ptr->clear_on_unprotect) { - entry_ptr->clear_on_unprotect = FALSE; - clear_ptr = entry_ptr; - entry_ptr = entry_ptr->next; - entries_cleared++; + ((entries_cleared + entries_flushed + entries_delayed) + < num_candidates)) { + + /* If entry is marked for flush or for clear */ + if((entry_ptr->clear_on_unprotect||entry_ptr->flush_immediately)) { + + /* If this entry needs to be flushed last */ + if (entry_ptr->flush_me_last) { + + /* At this time, only the superblock supports being + flushed last. Conveniently, it also happens to be the only + entry that supports being flushed collectively, as well. Also + conveniently, it's always pinned, so we only need to check + for it while scanning the PEL here. Finally, it's never + included in a candidate list that excludes other dirty + entries in a cache, so we can handle this relatively simple + case here. + + For now, this function asserts this and saves the entry + to flush it after scanning the rest of the PEL list. + + If there are ever more entries that either need to be + flushed last and/or flushed collectively, this whole routine + will need to be reworked to handle all additional cases. As + it is the simple case of a single pinned entry needing + flushed last and collectively is just a minor addition to + this routine, but signficantly buffing up the usage of + flush_me_last or flush_me_collectively will require a more + intense rework of this function and potentially the function + of candidate lists as a whole. */ + + HDassert(entry_ptr->flush_me_collectively); + entries_to_flush_or_clear_last++; + entries_to_flush_collectively++; + HDassert(entries_to_flush_or_clear_last == 1); + HDassert(entries_to_flush_collectively == 1); + + /* Delay the entry. It will be flushed later. */ + delayed_ptr = entry_ptr; + entries_delayed++; + HDassert(entries_delayed == 1); + + } /* end if */ + + /* Else, this process needs to clear this entry. */ + else if (entry_ptr->clear_on_unprotect) { + HDassert(!entry_ptr->flush_immediately); + entry_ptr->clear_on_unprotect = FALSE; + clear_ptr = entry_ptr; + entry_ptr = entry_ptr->next; + entries_cleared++; #if ( H5C_APPLY_CANDIDATE_LIST__DEBUG > 1 ) - HDfprintf(stdout, "%s:%d: clearing 0x%llx.\n", FUNC, mpi_rank, + HDfprintf(stdout, "%s:%d: clearing 0x%llx.\n", FUNC, mpi_rank, (long long)clear_ptr->addr); #endif /* H5C_APPLY_CANDIDATE_LIST__DEBUG */ - if(H5C_flush_single_entry(f, - primary_dxpl_id, - secondary_dxpl_id, - clear_ptr->type, - clear_ptr->addr, - H5C__FLUSH_CLEAR_ONLY_FLAG, - &first_flush, - TRUE) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't clear entry.") - } else if(entry_ptr->flush_immediately) { - entry_ptr->flush_immediately = FALSE; - flush_ptr = entry_ptr; - entry_ptr = entry_ptr->next; - entries_flushed++; + if(H5C_flush_single_entry(f, + primary_dxpl_id, + secondary_dxpl_id, + clear_ptr->type, + clear_ptr->addr, + H5C__FLUSH_CLEAR_ONLY_FLAG, + &first_flush, + TRUE) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't clear entry.") + } /* end else-if */ + + /* Else, if this process needs to independently flush this entry. */ + else if (entry_ptr->flush_immediately) { + entry_ptr->flush_immediately = FALSE; + flush_ptr = entry_ptr; + entry_ptr = entry_ptr->next; + entries_flushed++; #if ( H5C_APPLY_CANDIDATE_LIST__DEBUG > 1 ) - HDfprintf(stdout, "%s:%d: flushing 0x%llx.\n", FUNC, mpi_rank, + HDfprintf(stdout, "%s:%d: flushing 0x%llx.\n", FUNC, mpi_rank, (long long)flush_ptr->addr); #endif /* H5C_APPLY_CANDIDATE_LIST__DEBUG */ - if(H5C_flush_single_entry(f, - primary_dxpl_id, - secondary_dxpl_id, - flush_ptr->type, - flush_ptr->addr, - H5C__NO_FLAGS_SET, - &first_flush, - TRUE) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't clear entry.") - } else { + if(H5C_flush_single_entry(f, + primary_dxpl_id, + secondary_dxpl_id, + flush_ptr->type, + flush_ptr->addr, + H5C__NO_FLAGS_SET, + &first_flush, + TRUE) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't flush entry.") + } /* end else-if */ + } /* end if */ + + /* Otherwise, this entry is not marked for flush or clear. Grab the next. */ + else { entry_ptr = entry_ptr->next; - } + } /* end else */ + } /* end while */ #if H5C_APPLY_CANDIDATE_LIST__DEBUG - HDfprintf(stdout, - "%s:%d: pel entries examined/cleared/flushed = %d/%d/%d.\n", - FUNC, mpi_rank, entries_examined, + HDfprintf(stdout, + "%s:%d: pel entries examined/cleared/flushed = %d/%d/%d.\n", + FUNC, mpi_rank, entries_examined, entries_cleared, entries_flushed); HDfprintf(stdout, "%s:%d: done.\n", FUNC, mpi_rank); fsync(stdout); #endif /* H5C_APPLY_CANDIDATE_LIST__DEBUG */ - if((entries_flushed != entries_to_flush) || (entries_cleared != entries_to_clear)) + /* ====================================================================== * + * Now, handle all delayed entries. * + * * + * This can *only* be the superblock at this time, so it's relatively * + * easy to deal with. We're collectively flushing the entry saved from * + * above. This will need to be handled differently if there are ever more * + * than one entry needing this special treatment.) * + * ====================================================================== */ + + if (delayed_ptr) { + + if (delayed_ptr->clear_on_unprotect) { + entry_ptr->clear_on_unprotect = FALSE; + entries_cleared++; + } else if (delayed_ptr->flush_immediately) { + entry_ptr->flush_immediately = FALSE; + entries_flushed++; + } /* end if */ + + if(H5C_flush_single_entry(f, + primary_dxpl_id, + secondary_dxpl_id, + delayed_ptr->type, + delayed_ptr->addr, + H5C__NO_FLAGS_SET, + &first_flush, + TRUE) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, + "Can't flush entry collectively.") + + entries_flushed_collectively++; + entries_flushed_or_cleared_last++; + } /* end if */ + + /* ====================================================================== * + * Finished flushing everything. * + * ====================================================================== */ + + HDassert((entries_flushed == entries_to_flush)); + HDassert((entries_cleared == entries_to_clear)); + HDassert((entries_flushed_or_cleared_last == entries_to_flush_or_clear_last)); + HDassert((entries_flushed_collectively == entries_to_flush_collectively)); + + if((entries_flushed != entries_to_flush) || + (entries_cleared != entries_to_clear) || + (entries_flushed_or_cleared_last != entries_to_flush_or_clear_last) || + (entries_flushed_collectively != entries_to_flush_collectively)) HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "entry count mismatch.") done: @@ -920,7 +1042,8 @@ H5C_construct_candidate_list__min_clean(H5C_t * cache_ptr) entry_ptr = cache_ptr->dLRU_tail_ptr; while((nominated_entries_size < space_needed) && (nominated_entries_count < cache_ptr->slist_len) && - (entry_ptr != NULL)) { + (entry_ptr != NULL) && + (!entry_ptr->flush_me_last)) { haddr_t nominated_addr; HDassert( ! (entry_ptr->is_protected) ); @@ -1767,8 +1890,12 @@ H5C_flush_cache(H5F_t *f, hid_t primary_dxpl_id, hid_t secondary_dxpl_id, unsign HDassert( entry_ptr != NULL ); HDassert( entry_ptr->in_slist ); - if ( ( ! flush_marked_entries ) || - ( entry_ptr->flush_marker ) ) { + if ( ( ( ! flush_marked_entries ) || + ( entry_ptr->flush_marker ) ) && + ( ( ! entry_ptr->flush_me_last ) || + ( ( entry_ptr->flush_me_last ) && + ( cache_ptr->num_last_entries >= + cache_ptr->slist_len ) ) ) ) { if ( entry_ptr->is_protected ) { @@ -2520,6 +2647,10 @@ H5C_insert_entry(H5F_t * f, herr_t result; hbool_t first_flush = TRUE; hbool_t insert_pinned; + hbool_t flush_last; +#ifdef H5_HAVE_PARALLEL + hbool_t flush_collectively; +#endif hbool_t set_flush_marker; hbool_t write_permitted = TRUE; size_t empty_space; @@ -2558,8 +2689,12 @@ H5C_insert_entry(H5F_t * f, } #endif /* H5C_DO_EXTREME_SANITY_CHECKS */ - set_flush_marker = ( (flags & H5C__SET_FLUSH_MARKER_FLAG) != 0 ); - insert_pinned = ( (flags & H5C__PIN_ENTRY_FLAG) != 0 ); + set_flush_marker = ( (flags & H5C__SET_FLUSH_MARKER_FLAG) != 0 ); + insert_pinned = ( (flags & H5C__PIN_ENTRY_FLAG) != 0 ); + flush_last = ( (flags & H5C__FLUSH_LAST_FLAG) != 0 ); +#ifdef H5_HAVE_PARALLEL + flush_collectively = ( (flags & H5C__FLUSH_COLLECTIVELY_FLAG) != 0 ); +#endif entry_ptr = (H5C_cache_entry_t *)thing; @@ -2600,6 +2735,10 @@ H5C_insert_entry(H5F_t * f, entry_ptr->is_pinned = insert_pinned; entry_ptr->pinned_from_client = insert_pinned; + entry_ptr->flush_me_last = flush_last; +#ifdef H5_HAVE_PARALLEL + entry_ptr->flush_me_collectively = flush_collectively; +#endif /* newly inserted entries are assumed to be dirty */ entry_ptr->is_dirty = TRUE; @@ -7679,85 +7818,91 @@ H5C_flush_invalidate_cache(H5F_t * f, HDassert( entry_ptr != NULL ); HDassert( entry_ptr->in_slist ); -#if H5C_DO_SANITY_CHECKS - /* update actual_slist_len & actual_slist_size before - * the flush. Note that the entry will be removed - * from the slist after the flush, and thus may be - * resized by the flush callback. This is OK, as - * we will catch the size delta in - * cache_ptr->slist_size_increase. - * - * Note that we include pinned entries in this count, even - * though we will not actually flush them. - */ - actual_slist_len++; - actual_slist_size += entry_ptr->size; -#endif /* H5C_DO_SANITY_CHECKS */ + if ( ( ! entry_ptr->flush_me_last ) || + ( ( entry_ptr->flush_me_last ) && + ( cache_ptr->num_last_entries >= + cache_ptr->slist_len ) ) ) { + + #if H5C_DO_SANITY_CHECKS + /* update actual_slist_len & actual_slist_size before + * the flush. Note that the entry will be removed + * from the slist after the flush, and thus may be + * resized by the flush callback. This is OK, as + * we will catch the size delta in + * cache_ptr->slist_size_increase. + * + * Note that we include pinned entries in this count, even + * though we will not actually flush them. + */ + actual_slist_len++; + actual_slist_size += entry_ptr->size; + #endif /* H5C_DO_SANITY_CHECKS */ - if ( entry_ptr->is_protected ) { + if ( entry_ptr->is_protected ) { - /* we have major problems -- but lets flush - * everything we can before we flag an error. - */ - protected_entries++; + /* we have major problems -- but lets flush + * everything we can before we flag an error. + */ + protected_entries++; - } else if ( entry_ptr->is_pinned ) { + } else if ( entry_ptr->is_pinned ) { - /* Test to see if we are can flush the entry now. - * If we can, go ahead and flush, but don't tell - * H5C_flush_single_entry() to destroy the entry - * as pinned entries can't be evicted. - */ - if(entry_ptr->flush_dep_height == curr_flush_dep_height ) { - status = H5C_flush_single_entry(f, - primary_dxpl_id, - secondary_dxpl_id, - NULL, - entry_ptr->addr, - H5C__NO_FLAGS_SET, - &first_flush, - FALSE); - if ( status < 0 ) { + /* Test to see if we are can flush the entry now. + * If we can, go ahead and flush, but don't tell + * H5C_flush_single_entry() to destroy the entry + * as pinned entries can't be evicted. + */ + if(entry_ptr->flush_dep_height == curr_flush_dep_height ) { + status = H5C_flush_single_entry(f, + primary_dxpl_id, + secondary_dxpl_id, + NULL, + entry_ptr->addr, + H5C__NO_FLAGS_SET, + &first_flush, + FALSE); + if ( status < 0 ) { - /* This shouldn't happen -- if it does, we are toast - * so just scream and die. - */ + /* This shouldn't happen -- if it does, we are toast + * so just scream and die. + */ - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \ - "dirty pinned entry flush failed.") + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \ + "dirty pinned entry flush failed.") + } /* end if */ + flushed_during_dep_loop = TRUE; } /* end if */ - flushed_during_dep_loop = TRUE; + else if(entry_ptr->flush_dep_height < curr_flush_dep_height) + /* This shouldn't happen -- if it does, just scream and die. */ + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "dirty entry below current flush dep. height.") } /* end if */ - else if(entry_ptr->flush_dep_height < curr_flush_dep_height) - /* This shouldn't happen -- if it does, just scream and die. */ - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "dirty entry below current flush dep. height.") - } /* end if */ - else { - if(entry_ptr->flush_dep_height == curr_flush_dep_height ){ + else { + if(entry_ptr->flush_dep_height == curr_flush_dep_height ){ - status = H5C_flush_single_entry(f, - primary_dxpl_id, - secondary_dxpl_id, - NULL, - entry_ptr->addr, - (cooked_flags | H5C__FLUSH_INVALIDATE_FLAG), - &first_flush, - TRUE); - if ( status < 0 ) { + status = H5C_flush_single_entry(f, + primary_dxpl_id, + secondary_dxpl_id, + NULL, + entry_ptr->addr, + (cooked_flags | H5C__FLUSH_INVALIDATE_FLAG), + &first_flush, + TRUE); + if ( status < 0 ) { - /* This shouldn't happen -- if it does, we are toast so - * just scream and die. - */ + /* This shouldn't happen -- if it does, we are toast so + * just scream and die. + */ - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \ - "dirty entry flush destroy failed.") + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \ + "dirty entry flush destroy failed.") + } /* end if */ + flushed_during_dep_loop = TRUE; } /* end if */ - flushed_during_dep_loop = TRUE; - } /* end if */ - else if(entry_ptr->flush_dep_height < curr_flush_dep_height) - /* This shouldn't happen -- if it does, just scream and die. */ - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "dirty entry below current flush dep. height.") - } /* end else */ + else if(entry_ptr->flush_dep_height < curr_flush_dep_height) + /* This shouldn't happen -- if it does, just scream and die. */ + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "dirty entry below current flush dep. height.") + } /* end else */ + } /* end if */ } /* end while loop scanning skip list */ #if H5C_DO_SANITY_CHECKS @@ -7804,45 +7949,52 @@ H5C_flush_invalidate_cache(H5F_t * f, next_entry_ptr = entry_ptr->ht_next; HDassert ( ( next_entry_ptr == NULL ) || ( next_entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC ) ); - if ( entry_ptr->is_protected ) { - /* we have major problems -- but lets flush and destroy - * everything we can before we flag an error. - */ - protected_entries++; - - if ( ! entry_ptr->in_slist ) { + if ( ( ! entry_ptr->flush_me_last ) || + ( ( entry_ptr->flush_me_last ) && + ( cache_ptr->num_last_entries >= + cache_ptr->slist_len ) ) ) { - HDassert( !(entry_ptr->is_dirty) ); - } - } else if ( ! ( entry_ptr->is_pinned ) ) { + if ( entry_ptr->is_protected ) { - /* Test to see if we are can flush the entry now. - * If we can, go ahead and flush. - */ - if(entry_ptr->flush_dep_height == curr_flush_dep_height ){ - status = H5C_flush_single_entry(f, - primary_dxpl_id, - secondary_dxpl_id, - NULL, - entry_ptr->addr, - (cooked_flags | H5C__FLUSH_INVALIDATE_FLAG), - &first_flush, - TRUE); - if ( status < 0 ) { + /* we have major problems -- but lets flush and destroy + * everything we can before we flag an error. + */ + protected_entries++; - /* This shouldn't happen -- if it does, we are toast so - * just scream and die. - */ + if ( ! entry_ptr->in_slist ) { - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \ - "Entry flush destroy failed.") + HDassert( !(entry_ptr->is_dirty) ); } - flushed_during_dep_loop = TRUE; + } else if ( ! ( entry_ptr->is_pinned ) ) { + + /* Test to see if we are can flush the entry now. + * If we can, go ahead and flush. + */ + if(entry_ptr->flush_dep_height == curr_flush_dep_height ){ + status = H5C_flush_single_entry(f, + primary_dxpl_id, + secondary_dxpl_id, + NULL, + entry_ptr->addr, + (cooked_flags | H5C__FLUSH_INVALIDATE_FLAG), + &first_flush, + TRUE); + if ( status < 0 ) { + + /* This shouldn't happen -- if it does, we are toast so + * just scream and die. + */ + + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \ + "Entry flush destroy failed.") + } + flushed_during_dep_loop = TRUE; + } /* end if */ + else if(entry_ptr->flush_dep_height < curr_flush_dep_height) + /* This shouldn't happen -- if it does, just scream and die. */ + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "dirty entry below current flush dep. height.") } /* end if */ - else if(entry_ptr->flush_dep_height < curr_flush_dep_height) - /* This shouldn't happen -- if it does, just scream and die. */ - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "dirty entry below current flush dep. height.") } /* end if */ /* We can't do anything if the entry is pinned. The * hope is that the entry will be unpinned as the diff --git a/src/H5Cpkg.h b/src/H5Cpkg.h index 06eeb48..1d3bc60 100644 --- a/src/H5Cpkg.h +++ b/src/H5Cpkg.h @@ -282,6 +282,16 @@ * don't use this at present, I hope that this will allow * some optimizations when I get to it. * + * num_last_entries: The number of entries in the cache that can only be + * flushed after all other entries in the cache have + * been flushed. At this time, this will only ever be + * one entry (the superblock), and the code has been + * protected with HDasserts to enforce this. This restraint + * can certainly be relaxed in the future if the need for + * multiple entries being flushed last arises, though + * explicit tests for that case should be added when said + * HDasserts are removed. + * * With the addition of the fractal heap, the cache must now deal with * the case in which entries may be dirtied, moved, or have their sizes * changed during a flush. To allow sanity checks in this situation, the @@ -878,6 +888,7 @@ struct H5C_t int32_t slist_len; size_t slist_size; H5SL_t * slist_ptr; + int32_t num_last_entries; #if H5C_DO_SANITY_CHECKS int64_t slist_len_increase; int64_t slist_size_increase; @@ -1964,6 +1975,10 @@ if ( (cache_ptr)->index_size != \ } else { \ (cache_ptr)->clean_index_size += (entry_ptr)->size; \ } \ + if ((entry_ptr)->flush_me_last) { \ + (cache_ptr)->num_last_entries++; \ + HDassert((cache_ptr)->num_last_entries == 1); \ + } \ H5C__UPDATE_STATS_FOR_HT_INSERTION(cache_ptr) \ } @@ -1993,6 +2008,10 @@ if ( (cache_ptr)->index_size != \ } else { \ (cache_ptr)->clean_index_size -= (entry_ptr)->size; \ } \ + if ((entry_ptr)->flush_me_last) { \ + (cache_ptr)->num_last_entries--; \ + HDassert((cache_ptr)->num_last_entries == 0); \ + } \ H5C__UPDATE_STATS_FOR_HT_DELETION(cache_ptr) \ } diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h index 8eb7113..0de9c5b 100644 --- a/src/H5Cprivate.h +++ b/src/H5Cprivate.h @@ -387,6 +387,23 @@ typedef herr_t (*H5C_log_flush_func_t)(H5C_t * cache_ptr, * H5C__FLUSH_MARKED_ENTRIES_FLAG. The flag is reset when * the entry is flushed for whatever reason. * + * flush_me_last: Boolean flag indicating that this entry should not be + * flushed from the cache until all other entries without + * the flush_me_last flag set have been flushed. + * + * flush_me_collectively: Boolean flag indicating that this entry needs + * to be flushed collectively when in a parallel + * situation. + * + * Note: At this time, the flush_me_last and flush_me_collectively + * flags will only be applied to one entry, the superblock, + * and the code utilizing these flags is protected with HDasserts + * to enforce this. This restraint can certainly be relaxed in + * the future if the the need for multiple entries getting flushed + * last or collectively arises, though the code allowing for that + * will need to be expanded and tested appropriately if that + * functionality is desired. + * * clear_on_unprotect: Boolean flag used only in PHDF5. When H5C is used * to implement the metadata cache In the parallel case, only * the cache with mpi rank 0 is allowed to actually write to @@ -594,7 +611,7 @@ typedef struct H5C_cache_entry_t haddr_t addr; size_t size; const H5C_class_t * type; - haddr_t tag; + haddr_t tag; int globality; hbool_t is_dirty; hbool_t dirtied; @@ -604,13 +621,15 @@ typedef struct H5C_cache_entry_t hbool_t is_pinned; hbool_t in_slist; hbool_t flush_marker; + hbool_t flush_me_last; #ifdef H5_HAVE_PARALLEL + hbool_t flush_me_collectively; hbool_t clear_on_unprotect; - hbool_t flush_immediately; + hbool_t flush_immediately; #endif /* H5_HAVE_PARALLEL */ hbool_t flush_in_progress; hbool_t destroy_in_progress; - hbool_t free_file_space_on_destroy; + hbool_t free_file_space_on_destroy; /* fields supporting the 'flush dependency' feature: */ @@ -1059,6 +1078,8 @@ typedef struct H5C_auto_size_ctl_t #define H5C__READ_ONLY_FLAG 0x0200 #define H5C__FREE_FILE_SPACE_FLAG 0x0800 #define H5C__TAKE_OWNERSHIP_FLAG 0x1000 +#define H5C__FLUSH_LAST_FLAG 0x2000 +#define H5C__FLUSH_COLLECTIVELY_FLAG 0x4000 #ifdef H5_HAVE_PARALLEL H5_DLL herr_t H5C_apply_candidate_list(H5F_t * f, diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index 9e79f82..0471ccd 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -4448,7 +4448,9 @@ H5D__chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim) /* * Determine the chunks which need to be filled or removed */ - for(op_dim=0; op_dimlib_vers) eprint->cls.lib_vers = cls_ptr->lib_vers; - fprintf(stream, "%s-DIAG: Error detected in %s (%s) ", cls_ptr->cls_name, cls_ptr->lib_name, cls_ptr->lib_vers); + fprintf(stream, "%s-DIAG: Error detected in %s (%s) ", + (cls_ptr->cls_name ? cls_ptr->cls_name : "(null)"), + (cls_ptr->lib_name ? cls_ptr->lib_name : "(null)"), + (cls_ptr->lib_vers ? cls_ptr->lib_vers : "(null)")); /* try show the process or thread id in multiple processes cases*/ #ifdef H5_HAVE_PARALLEL @@ -387,7 +390,10 @@ H5E_walk2_cb(unsigned n, const H5E_error2_t *err_desc, void *client_data) if(cls_ptr->lib_vers) eprint->cls.lib_vers = cls_ptr->lib_vers; - fprintf(stream, "%s-DIAG: Error detected in %s (%s) ", cls_ptr->cls_name, cls_ptr->lib_name, cls_ptr->lib_vers); + fprintf(stream, "%s-DIAG: Error detected in %s (%s) ", + (cls_ptr->cls_name ? cls_ptr->cls_name : "(null)"), + (cls_ptr->lib_name ? cls_ptr->lib_name : "(null)"), + (cls_ptr->lib_vers ? cls_ptr->lib_vers : "(null)")); /* try show the process or thread id in multiple processes cases*/ #ifdef H5_HAVE_PARALLEL diff --git a/src/H5F.c b/src/H5F.c index b99afd6..d4371c5 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -1051,13 +1051,15 @@ H5F_dest(H5F_t *f, hid_t dxpl_id, hbool_t flush) * Only try to flush the file if it was opened with write access, and if * the caller requested a flush. */ - if((f->shared->flags & H5F_ACC_RDWR) && flush) + if((H5F_ACC_RDWR & H5F_INTENT(f)) && flush) if(H5F_flush(f, dxpl_id, TRUE) < 0) + /* Push error, but keep going*/ HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") /* Release the external file cache */ if(f->shared->efc) { if(H5F_efc_destroy(f->shared->efc) < 0) + /* Push error, but keep going*/ HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't destroy external file cache") f->shared->efc = NULL; } /* end if */ @@ -1075,6 +1077,14 @@ H5F_dest(H5F_t *f, hid_t dxpl_id, hbool_t flush) if(H5MF_close(f, dxpl_id) < 0) /* Push error, but keep going*/ HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file free space info") + + /* Flush the file again (if requested), as shutting down the + * free space manager may dirty some data structures again. + */ + if(flush) + if(H5F_flush(f, dxpl_id, TRUE) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") } /* end if */ /* Unpin the superblock, since we're about to destroy the cache */ diff --git a/src/H5FDcore.c b/src/H5FDcore.c index cc48e51..bb23d2d 100644 --- a/src/H5FDcore.c +++ b/src/H5FDcore.c @@ -430,8 +430,9 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "maxaddr overflow") HDassert(H5P_DEFAULT != fapl_id); if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list") - fa = (H5FD_core_fapl_t *)H5P_get_driver_info(plist); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list") + if(NULL == (fa = (H5FD_core_fapl_t *)H5P_get_driver_info(plist))) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, NULL, "bad VFL driver info") /* Build the open flags */ o_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY; @@ -446,6 +447,7 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, /* If the file image exists and this is an open, make sure the file doesn't exist */ HDassert(((file_image_info.buffer != NULL) && (file_image_info.size > 0)) || ((file_image_info.buffer == NULL) && (file_image_info.size == 0))); + HDmemset(&sb, 0, sizeof(sb)); if((file_image_info.buffer != NULL) && !(H5F_ACC_CREAT & flags)) { if(HDopen(name, o_flags, 0666) >= 0) HGOTO_ERROR(H5E_FILE, H5E_FILEEXISTS, NULL, "file already exists") @@ -465,7 +467,7 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, * store is off is when the backing_store flag is off and H5F_ACC_CREAT is * on. */ else if(fa->backing_store || !(H5F_ACC_CREAT & flags)) { - if(fa && (fd = HDopen(name, o_flags, 0666)) < 0) + if((fd = HDopen(name, o_flags, 0666)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file") if(HDfstat(fd, &sb) < 0) HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file") @@ -482,7 +484,7 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, * default value. But if the file access property list was zero then use * the default value instead. */ - file->increment = (fa && fa->increment>0) ? fa->increment : H5FD_CORE_INCREMENT; + file->increment = (fa->increment>0) ? fa->increment : H5FD_CORE_INCREMENT; /* If save data in backing store. */ file->backing_store = fa->backing_store; diff --git a/src/H5FDmpi.c b/src/H5FDmpi.c index 01c28e6..866a2cf 100644 --- a/src/H5FDmpi.c +++ b/src/H5FDmpi.c @@ -56,12 +56,15 @@ char H5FD_mpi_native_g[] = "native"; int H5FD_mpi_get_rank(const H5FD_t *file) { - const H5FD_class_mpi_t *cls=(const H5FD_class_mpi_t *)(file->cls); + const H5FD_class_mpi_t *cls; + int ret_value; FUNC_ENTER_NOAPI(FAIL) - assert(file && cls); + assert(file); + cls = (const H5FD_class_mpi_t *)(file->cls); + assert(cls); assert(cls->get_rank); /* All MPI drivers must implement this */ /* Dispatch to driver */ @@ -92,12 +95,14 @@ done: int H5FD_mpi_get_size(const H5FD_t *file) { - const H5FD_class_mpi_t *cls=(const H5FD_class_mpi_t *)(file->cls); + const H5FD_class_mpi_t *cls; int ret_value; FUNC_ENTER_NOAPI(FAIL) - assert(file && cls); + assert(file); + cls = (const H5FD_class_mpi_t *)(file->cls); + assert(cls); assert(cls->get_size); /* All MPI drivers must implement this */ /* Dispatch to driver */ @@ -128,12 +133,14 @@ done: MPI_Comm H5FD_mpi_get_comm(const H5FD_t *file) { - const H5FD_class_mpi_t *cls=(const H5FD_class_mpi_t *)(file->cls); + const H5FD_class_mpi_t *cls; MPI_Comm ret_value; FUNC_ENTER_NOAPI(MPI_COMM_NULL) - assert(file && cls); + assert(file); + cls = (const H5FD_class_mpi_t *)(file->cls); + assert(cls); assert(cls->get_comm); /* All MPI drivers must implement this */ /* Dispatch to driver */ diff --git a/src/H5FDmpiposix.c b/src/H5FDmpiposix.c index c91f176..ecf6e0f 100644 --- a/src/H5FDmpiposix.c +++ b/src/H5FDmpiposix.c @@ -89,12 +89,12 @@ typedef struct H5FD_mpiposix_t { MPI_Comm comm; /*communicator */ int mpi_rank; /* This process's rank */ int mpi_size; /* Total number of processes */ - haddr_t eof; /*end-of-file marker */ - haddr_t eoa; /*end-of-address marker */ - haddr_t last_eoa; /* Last known end-of-address marker */ - haddr_t pos; /* Current file I/O position */ - int op; /* Last file I/O operation */ - hsize_t naccess; /* Number of (write) accesses to file */ + haddr_t eof; /*end-of-file marker */ + haddr_t eoa; /*end-of-address marker */ + haddr_t last_eoa; /* Last known end-of-address marker */ + haddr_t pos; /* Current file I/O position */ + int op; /* Last file I/O operation */ + hsize_t naccess; /* Number of (write) accesses to file */ #ifdef H5_HAVE_GPFS size_t blksize; /* Block size of file system */ #endif @@ -233,13 +233,13 @@ static const H5FD_class_mpi_t H5FD_mpiposix_g = { H5FD_mpiposix_set_eoa, /*set_eoa */ H5FD_mpiposix_get_eof, /*get_eof */ H5FD_mpiposix_get_handle, /*get_handle */ - H5FD_mpiposix_read, /*read */ - H5FD_mpiposix_write, /*write */ + H5FD_mpiposix_read, /*read */ + H5FD_mpiposix_write, /*write */ NULL, /*flush */ - H5FD_mpiposix_truncate, /*truncate */ + H5FD_mpiposix_truncate, /*truncate */ NULL, /*lock */ NULL, /*unlock */ - H5FD_FLMAP_SINGLE /*fl_map */ + H5FD_FLMAP_SINGLE /*fl_map */ }, /* End of superclass information */ H5FD_mpiposix_mpi_rank, /*get_rank */ H5FD_mpiposix_mpi_size, /*get_size */ diff --git a/src/H5FS.c b/src/H5FS.c index fc1285f..7c09beb 100644 --- a/src/H5FS.c +++ b/src/H5FS.c @@ -284,6 +284,50 @@ HDfprintf(stderr, "%s: Deleting free space manager, fs_addr = %a\n", FUNC, fs_ad cache_udata.cls_init_udata = NULL; cache_udata.addr = fs_addr; +#ifdef H5FS_DEBUG +{ + unsigned fspace_status = 0; /* Free space section info's status in the metadata cache */ + + /* Sanity check */ + HDassert(H5F_addr_defined(fs_addr)); + + /* Check the free space section info's status in the metadata cache */ + if(H5AC_get_entry_status(f, fs_addr, &fspace_status) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "unable to check metadata cache status for free space section info") + + HDfprintf(stderr, "%s: fspace_status = %0x: ", FUNC, fspace_status); + if(fspace_status) { + hbool_t printed = FALSE; + + if(fspace_status & H5AC_ES__IN_CACHE) { + HDfprintf(stderr, "H5AC_ES__IN_CACHE"); + printed = TRUE; + } /* end if */ + if(fspace_status & H5AC_ES__IS_DIRTY) { + HDfprintf(stderr, "%sH5AC_ES__IS_DIRTY", (printed ? " | " : "")); + printed = TRUE; + } /* end if */ + if(fspace_status & H5AC_ES__IS_PROTECTED) { + HDfprintf(stderr, "%sH5AC_ES__IS_PROTECTED", (printed ? " | " : "")); + printed = TRUE; + } /* end if */ + if(fspace_status & H5AC_ES__IS_PINNED) { + HDfprintf(stderr, "%sH5AC_ES__IS_PINNED", (printed ? " | " : "")); + printed = TRUE; + } /* end if */ + if(fspace_status & H5AC_ES__IS_FLUSH_DEP_PARENT) { + HDfprintf(stderr, "%sH5AC_ES__IS_FLUSH_DEP_PARENT", (printed ? " | " : "")); + printed = TRUE; + } /* end if */ + if(fspace_status & H5AC_ES__IS_FLUSH_DEP_CHILD) { + HDfprintf(stderr, "%sH5AC_ES__IS_FLUSH_DEP_CHILD", (printed ? " | " : "")); + printed = TRUE; + } /* end if */ + } /* end if */ + HDfprintf(stderr, "\n"); +} +#endif /* H5FS_DEBUG */ + /* Protect the free space header */ if(NULL == (fspace = (H5FS_t *)H5AC_protect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, &cache_udata, H5AC_WRITE))) HGOTO_ERROR(H5E_FSPACE, H5E_CANTPROTECT, FAIL, "unable to protect free space header") @@ -324,9 +368,14 @@ HDfprintf(stderr, "%s: Done expunging free space section info from cache\n", FUN #endif /* H5FS_DEBUG */ } /* end if */ else { +#ifdef H5FS_DEBUG +HDfprintf(stderr, "%s: Deleting free space section info from file\n", FUNC); +#endif /* H5FS_DEBUG */ /* Release the space in the file */ - if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_addr, fspace->alloc_sect_size) < 0) - HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space sections") + if(!H5F_IS_TMP_ADDR(f, fspace->sect_addr)) { + if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_addr, fspace->alloc_sect_size) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space sections") + } /* end if */ } /* end else */ } /* end if */ @@ -387,8 +436,14 @@ HDfprintf(stderr, "%s: Real sections to store in file\n", FUNC); HDassert(fspace->sect_size > 0); /* Allocate space for the section info in file */ - if(HADDR_UNDEF == (fspace->sect_addr = H5MF_alloc(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_size))) - HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "file allocation failed for free space sections") + if(H5F_USE_TMP_SPACE(f)) { + if(HADDR_UNDEF == (fspace->sect_addr = H5MF_alloc_tmp(f, fspace->sect_size))) + HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "file allocation failed for free space sections") + } /* end if */ + else { + if(HADDR_UNDEF == (fspace->sect_addr = H5MF_alloc(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_size))) + HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "file allocation failed for free space sections") + } /* end if */ fspace->alloc_sect_size = (size_t)fspace->sect_size; /* Mark free space header as dirty */ @@ -430,19 +485,9 @@ HDfprintf(stderr, "%s: Section info allocated though\n", FUNC); HDfprintf(stderr, "%s: Section info is for file free space\n", FUNC); #endif /* H5FS_DEBUG */ /* Try to shrink the file or absorb the section info into a block aggregator */ - if((status = H5MF_try_shrink(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_addr, fspace->alloc_sect_size)) < 0) - HGOTO_ERROR(H5E_FSPACE, H5E_CANTMERGE, FAIL, "can't check for absorbing section info") - else if(status == FALSE) { - /* Section info can't "go away", but it's free. Allow - * header to record it - */ -#ifdef H5FS_DEBUG -HDfprintf(stderr, "%s: Section info can't 'go away', header will own it\n", FUNC); -#endif /* H5FS_DEBUG */ - } /* end if */ - else { + if(H5F_IS_TMP_ADDR(f, fspace->sect_addr)) { #ifdef H5FS_DEBUG -HDfprintf(stderr, "%s: Section info went 'go away'\n", FUNC); +HDfprintf(stderr, "%s: Section info in temp. address space went 'go away'\n", FUNC); #endif /* H5FS_DEBUG */ /* Reset section info in header */ fspace->sect_addr = HADDR_UNDEF; @@ -451,6 +496,30 @@ HDfprintf(stderr, "%s: Section info went 'go away'\n", FUNC); /* Mark free space header as dirty */ if(H5AC_mark_entry_dirty(fspace) < 0) HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty") + } /* end if */ + else { + if((status = H5MF_try_shrink(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_addr, fspace->alloc_sect_size)) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTMERGE, FAIL, "can't check for absorbing section info") + else if(status == FALSE) { + /* Section info can't "go away", but it's free. Allow + * header to record it + */ +#ifdef H5FS_DEBUG + HDfprintf(stderr, "%s: Section info can't 'go away', header will own it\n", FUNC); +#endif /* H5FS_DEBUG */ + } /* end if */ + else { +#ifdef H5FS_DEBUG + HDfprintf(stderr, "%s: Section info went 'go away'\n", FUNC); +#endif /* H5FS_DEBUG */ + /* Reset section info in header */ + fspace->sect_addr = HADDR_UNDEF; + fspace->alloc_sect_size = 0; + + /* Mark free space header as dirty */ + if(H5AC_mark_entry_dirty(fspace) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty") + } /* end else */ } /* end else */ } /* end if */ else { @@ -469,10 +538,12 @@ HDfprintf(stderr, "%s: Section info is NOT for file free space\n", FUNC); HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty") /* Free previous serialized sections disk space */ - if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, old_sect_addr, old_alloc_sect_size) < 0) - HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free free space sections") - } /* end if */ - } /* end else */ + if(!H5F_IS_TMP_ADDR(f, old_sect_addr)) { + if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, old_sect_addr, old_alloc_sect_size) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free free space sections") + } /* end if */ + } /* end else */ + } /* end if */ /* Destroy section info */ if(H5FS_sinfo_dest(fspace->sinfo) < 0) @@ -802,11 +873,11 @@ H5FS_alloc_sect(H5F_t *f, H5FS_t *fspace, hid_t dxpl_id) HDassert(fspace); if(!H5F_addr_defined(fspace->sect_addr) && fspace->sinfo && fspace->serial_sect_count > 0) { - /* Allocate space for section info from aggregator/vfd */ - /* (The original version called H5MF_alloc(), but that may cause sect_size to change again) */ - if(HADDR_UNDEF == (fspace->sect_addr = H5MF_aggr_vfd_alloc(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_size))) - HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "file allocation failed for section info") - + /* Allocate space for section info from aggregator/vfd (or temp. address space) */ + /* (The original version called H5MF_alloc(), but that may cause sect_size to change again) */ + /* (This routine is only called during file close operations, so don't allocate from temp. address space) */ + if(HADDR_UNDEF == (fspace->sect_addr = H5MF_aggr_vfd_alloc(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_size))) + HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "file allocation failed for section info") fspace->alloc_sect_size = fspace->sect_size; /* Mark free-space header as dirty */ @@ -882,8 +953,10 @@ H5FS_free(H5F_t *f, H5FS_t *fspace, hid_t dxpl_id) fspace->alloc_sect_size = 0; /* Free space for the free-space manager section info */ - if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, saved_addr, saved_size) < 0) - HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space sections") + if(!H5F_IS_TMP_ADDR(f, saved_addr)) { + if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, saved_addr, saved_size) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space sections") + } /* end if */ /* Mark free-space manager header as dirty */ if(H5FS_dirty(fspace) < 0) @@ -1120,7 +1193,7 @@ herr_t H5FS_assert(const H5FS_t *fspace) { FUNC_ENTER_NOAPI_NOINIT_NOERR -#ifndef QAK +#ifdef QAK HDfprintf(stderr, "%s: fspace->tot_sect_count = %Hu\n", "H5FS_assert", fspace->tot_sect_count); #endif /* QAK */ diff --git a/src/H5FScache.c b/src/H5FScache.c index d186404..e441398 100644 --- a/src/H5FScache.c +++ b/src/H5FScache.c @@ -306,7 +306,7 @@ H5FS_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5F if(fspace->sinfo->dirty) { if(fspace->serial_sect_count > 0) { /* Check if we need to allocate space for section info */ - if(!H5F_addr_defined(fspace->sect_addr)) { + if(H5F_IS_TMP_ADDR(f, fspace->sect_addr) || !H5F_addr_defined(fspace->sect_addr)) { /* Sanity check */ HDassert(fspace->sect_size > 0); @@ -884,6 +884,32 @@ H5FS_cache_sinfo_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H HDassert((size_t)(p - buf) == sinfo->fspace->sect_size); HDassert(sinfo->fspace->sect_size <= sinfo->fspace->alloc_sect_size); + /* Check for section info at temporary address */ + if(H5F_IS_TMP_ADDR(f, sinfo->fspace->sect_addr)) { + /* Sanity check */ + HDassert(sinfo->fspace->sect_size > 0); + HDassert(H5F_addr_eq(sinfo->fspace->sect_addr, addr)); + + /* Allocate space for the section info in file */ + if(HADDR_UNDEF == (addr = H5MF_alloc(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, sinfo->fspace->sect_size))) + HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "file allocation failed for free space sections") + sinfo->fspace->alloc_sect_size = (size_t)sinfo->fspace->sect_size; + + /* Sanity check */ + HDassert(!H5F_addr_eq(sinfo->fspace->sect_addr, addr)); + + /* Let the metadata cache know the section info moved */ + if(H5AC_move_entry(f, H5AC_FSPACE_SINFO, sinfo->fspace->sect_addr, addr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTMOVE, FAIL, "unable to move indirect block") + + /* Update the internal address for the section info */ + sinfo->fspace->sect_addr = addr; + + /* Mark free space header as dirty */ + if(H5AC_mark_entry_dirty(sinfo->fspace) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty") + } /* end if */ + /* Write buffer to disk */ if(H5F_block_write(f, H5FD_MEM_FSPACE_SINFO, sinfo->fspace->sect_addr, (size_t)sinfo->fspace->sect_size, dxpl_id, buf) < 0) HGOTO_ERROR(H5E_FSPACE, H5E_CANTFLUSH, FAIL, "unable to save free space sections to disk") @@ -936,8 +962,9 @@ H5FS_cache_sinfo_dest(H5F_t *f, H5FS_sinfo_t *sinfo) /* Release the space on disk */ /* (XXX: Nasty usage of internal DXPL value! -QAK) */ - if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, H5AC_dxpl_id, sinfo->cache_info.addr, (hsize_t)sinfo->fspace->alloc_sect_size) < 0) - HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free free space section info") + if(!H5F_IS_TMP_ADDR(f, sinfo->cache_info.addr)) + if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, H5AC_dxpl_id, sinfo->cache_info.addr, (hsize_t)sinfo->fspace->alloc_sect_size) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free free space section info") } /* end if */ /* Destroy free space info */ diff --git a/src/H5FSsection.c b/src/H5FSsection.c index 0f126c2..581d3dc 100644 --- a/src/H5FSsection.c +++ b/src/H5FSsection.c @@ -445,8 +445,10 @@ HDfprintf(stderr, "%s: Relinquishing section info ownership\n", FUNC); HDfprintf(stderr, "%s: Freeing section info on disk, old_sect_addr = %a, old_alloc_sect_size = %Hu\n", FUNC, old_sect_addr, old_alloc_sect_size); #endif /* H5FS_SINFO_DEBUG */ /* Release space for section info in file */ - if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, old_sect_addr, old_alloc_sect_size) < 0) - HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free free space sections") + if(!H5F_IS_TMP_ADDR(f, old_sect_addr)) { + if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, old_sect_addr, old_alloc_sect_size) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free free space sections") + } /* end if */ } /* end if */ } /* end if */ diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c index 8bf4405..8205392 100644 --- a/src/H5Fsuper.c +++ b/src/H5Fsuper.c @@ -516,7 +516,7 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to set EOA value for superblock") /* Insert superblock into cache, pinned */ - if(H5AC_insert_entry(f, dxpl_id, H5AC_SUPERBLOCK, (haddr_t)0, sblock, H5AC__PIN_ENTRY_FLAG) < 0) + if(H5AC_insert_entry(f, dxpl_id, H5AC_SUPERBLOCK, (haddr_t)0, sblock, H5AC__PIN_ENTRY_FLAG | H5AC__FLUSH_LAST_FLAG | H5AC__FLUSH_COLLECTIVELY_FLAG) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, "can't add superblock to cache") sblock_in_cache = TRUE; diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c index 29139d5..af4e886 100644 --- a/src/H5Fsuper_cache.c +++ b/src/H5Fsuper_cache.c @@ -153,6 +153,12 @@ H5F_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, void *_udata) if(NULL == (sblock = H5FL_CALLOC(H5F_super_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + /* The superblock must be flushed last (and collectively in parallel) */ + sblock->cache_info.flush_me_last = TRUE; +#ifdef H5_HAVE_PARALLEL + sblock->cache_info.flush_me_collectively = TRUE; +#endif + /* Read fixed-size portion of the superblock */ p = sbuf; H5_CHECK_OVERFLOW(fixed_size, size_t, haddr_t); @@ -644,6 +650,15 @@ H5F_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t UNUSED addr, HDassert(f); HDassert(H5F_addr_eq(addr, 0)); HDassert(sblock); + + /* Assert that the superblock is marked as being flushed last (and + collectively in parallel) */ + /* (We'll rely on the cache to make sure it actually *is* flushed + last (and collectively in parallel), but this check doesn't hurt) */ + HDassert(sblock->cache_info.flush_me_last); +#ifdef H5_HAVE_PARALLEL + HDassert(sblock->cache_info.flush_me_collectively); +#endif if(sblock->cache_info.is_dirty) { uint8_t buf[H5F_MAX_SUPERBLOCK_SIZE + H5F_MAX_DRVINFOBLOCK_SIZE]; /* Superblock & driver info blockencoding buffer */ @@ -683,10 +698,15 @@ H5F_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t UNUSED addr, *p++ = 0; /*reserved */ } /* end if */ + /* Encode the base address */ H5F_addr_encode(f, &p, sblock->base_addr); + + /* Encode the address of global free-space index */ H5F_addr_encode(f, &p, sblock->ext_addr); rel_eoa = H5FD_get_eoa(f->shared->lf, H5FD_MEM_SUPER); H5F_addr_encode(f, &p, (rel_eoa + sblock->base_addr)); + + /* Encode the driver informaton block address */ H5F_addr_encode(f, &p, sblock->driver_addr); /* Encode the root group object entry, including the cached stab info */ @@ -737,9 +757,12 @@ H5F_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t UNUSED addr, *p++ = (uint8_t)H5F_SIZEOF_SIZE(f); *p++ = sblock->status_flags; - /* Base, superblock extension & end of file addresses */ + /* Encode the base address */ H5F_addr_encode(f, &p, sblock->base_addr); + + /* Encode the address of the superblock extension */ H5F_addr_encode(f, &p, sblock->ext_addr); + rel_eoa = H5FD_get_eoa(f->shared->lf, H5FD_MEM_SUPER); H5F_addr_encode(f, &p, (rel_eoa + sblock->base_addr)); @@ -773,13 +796,18 @@ H5F_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t UNUSED addr, /* Check for newer version of superblock format & superblock extension */ if(sblock->super_vers >= HDF5_SUPERBLOCK_VERSION_2 && H5F_addr_defined(sblock->ext_addr)) { + H5O_loc_t ext_loc; /* "Object location" for superblock extension */ + + /* Open the superblock extension's object header */ + if(H5F_super_ext_open(f, sblock->ext_addr, &ext_loc) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "unable to open file's superblock extension") + /* Check for ignoring the driver info for this file */ if(!H5F_HAS_FEATURE(f, H5FD_FEAT_IGNORE_DRVRINFO)) { /* Check for driver info message */ H5_ASSIGN_OVERFLOW(driver_size, H5FD_sb_size(f->shared->lf), hsize_t, size_t); if(driver_size > 0) { H5O_drvinfo_t drvinfo; /* Driver info */ - H5O_loc_t ext_loc; /* "Object location" for superblock extension */ uint8_t dbuf[H5F_MAX_DRVINFOBLOCK_SIZE]; /* Driver info block encoding buffer */ /* Sanity check */ @@ -789,21 +817,19 @@ H5F_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t UNUSED addr, if(H5FD_sb_encode(f->shared->lf, drvinfo.name, dbuf) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to encode driver information") - /* Open the superblock extension's object header */ - if(H5F_super_ext_open(f, sblock->ext_addr, &ext_loc) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "unable to open file's superblock extension") - /* Write driver info information to the superblock extension */ drvinfo.len = driver_size; drvinfo.buf = dbuf; if(H5O_msg_write(&ext_loc, H5O_DRVINFO_ID, H5O_MSG_FLAG_DONTSHARE, H5O_UPDATE_TIME, &drvinfo, dxpl_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "unable to update driver info header message") - /* Close the superblock extension object header */ - if(H5F_super_ext_close(f, &ext_loc, dxpl_id, FALSE) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to close file's superblock extension") } /* end if */ + } /* end if */ + + /* Close the superblock extension object header */ + if(H5F_super_ext_close(f, &ext_loc, dxpl_id, FALSE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to close file's superblock extension") } /* end if */ /* Reset the dirty flag. */ diff --git a/src/H5HFsection.c b/src/H5HFsection.c index e9ea7e0..72ea100 100644 --- a/src/H5HFsection.c +++ b/src/H5HFsection.c @@ -2398,7 +2398,10 @@ H5HF_sect_indirect_init_rows(H5HF_hdr_t *hdr, hid_t dxpl_id, HDassert(sect->u.indirect.span_size > 0); /* Reset reference count for indirect section */ + /* (Also reset the direct & indirect row pointers */ sect->u.indirect.rc = 0; + sect->u.indirect.dir_rows = NULL; + sect->u.indirect.indir_ents = NULL; /* Set up direct block information, if necessary */ if(start_row < hdr->man_dtable.max_direct_rows) { @@ -2424,7 +2427,6 @@ H5HF_sect_indirect_init_rows(H5HF_hdr_t *hdr, hid_t dxpl_id, /* No rows of direct blocks covered, reset direct row information */ dir_nrows = 0; sect->u.indirect.dir_nrows = 0; - sect->u.indirect.dir_rows = NULL; } /* end else */ /* Set up indirect block information, if necessary */ @@ -2459,7 +2461,6 @@ H5HF_sect_indirect_init_rows(H5HF_hdr_t *hdr, hid_t dxpl_id, else { /* No indirect block entries covered, reset indirect row information */ sect->u.indirect.indir_nents = 0; - sect->u.indirect.indir_ents = NULL; } /* end else */ /* Set up initial row information */ @@ -2598,6 +2599,13 @@ H5HF_sect_indirect_init_rows(H5HF_hdr_t *hdr, hid_t dxpl_id, (sect->u.indirect.indir_nents + sect->u.indirect.dir_nrows)); done: + if(ret_value < 0) { + if(sect->u.indirect.indir_ents) + H5MM_xfree(sect->u.indirect.indir_ents); + if(sect->u.indirect.dir_rows) + H5MM_xfree(sect->u.indirect.dir_rows); + } /* end if */ + FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_sect_indirect_init_rows() */ diff --git a/src/H5HG.c b/src/H5HG.c index 0a97e47..7a90475 100644 --- a/src/H5HG.c +++ b/src/H5HG.c @@ -136,7 +136,7 @@ H5HG_create(H5F_t *f, hid_t dxpl_id, size_t size) { H5HG_heap_t *heap = NULL; uint8_t *p = NULL; - haddr_t addr; + haddr_t addr = HADDR_UNDEF; size_t n; haddr_t ret_value = HADDR_UNDEF; /* Return value */ diff --git a/src/H5MF.c b/src/H5MF.c index 5b4505f..e708ab8 100644 --- a/src/H5MF.c +++ b/src/H5MF.c @@ -245,6 +245,7 @@ H5MF_alloc_open(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type) */ HDassert(f); HDassert(f->shared); + HDassert(type != H5FD_MEM_NOLIST); HDassert(H5F_addr_defined(f->shared->fs_addr[type])); HDassert(f->shared->fs_state[type] == H5F_FS_STATE_CLOSED); @@ -292,6 +293,7 @@ H5MF_alloc_create(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type) */ HDassert(f); HDassert(f->shared); + HDassert(type != H5FD_MEM_NOLIST); HDassert(!H5F_addr_defined(f->shared->fs_addr[type])); HDassert(f->shared->fs_state[type] == H5F_FS_STATE_CLOSED); @@ -342,6 +344,7 @@ H5MF_alloc_start(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type) */ HDassert(f); HDassert(f->shared); + HDassert(type != H5FD_MEM_NOLIST); /* Check if the free space manager exists already */ if(H5F_addr_defined(f->shared->fs_addr[type])) { @@ -384,6 +387,7 @@ H5MF_alloc_close(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type) */ HDassert(f); HDassert(f->shared); + HDassert(type != H5FD_MEM_NOLIST); HDassert(f->shared->fs_man[type]); HDassert(f->shared->fs_state[type] != H5F_FS_STATE_CLOSED); diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c index 1d1aa90..ceb6563 100644 --- a/src/H5Ocopy.c +++ b/src/H5Ocopy.c @@ -1066,11 +1066,15 @@ H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, FUNC_ENTER_NOAPI_NOINIT + /* Sanity check */ HDassert(oloc_src); HDassert(oloc_src->file); HDassert(H5F_addr_defined(oloc_src->addr)); HDassert(oloc_dst->file); + /* Intialize copy info before errors can be thrown */ + HDmemset(&cpy_info, 0, sizeof(H5O_copy_t)); + /* Get the copy property list */ if(NULL == (ocpy_plist = (H5P_genplist_t *)H5I_object(ocpypl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") @@ -1088,7 +1092,6 @@ H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get callback info") /* Convert copy flags into copy struct */ - HDmemset(&cpy_info, 0, sizeof(H5O_copy_t)); if((cpy_option & H5O_COPY_SHALLOW_HIERARCHY_FLAG) > 0) { cpy_info.copy_shallow = TRUE; cpy_info.max_depth = 1; diff --git a/src/H5Otest.c b/src/H5Otest.c index b526b30..21e4ca8 100644 --- a/src/H5Otest.c +++ b/src/H5Otest.c @@ -520,7 +520,7 @@ H5O_expunge_chunks_test(const H5O_loc_t *loc, hid_t dxpl_id) /* Safety check */ nchunks = oh->nchunks; - HDassert(nchunks < NELMTS(chk_addr)); + HDassert(0 < nchunks && nchunks < NELMTS(chk_addr)); /* Iterate over all the chunks, saving the chunk addresses */ for(u = 0; u < oh->nchunks; u++) diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index f2af61b..9b5d1b0 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -2494,12 +2494,13 @@ done: herr_t H5P_file_image_info_copy(const char UNUSED *name, size_t UNUSED size, void *value) { - H5FD_file_image_info_t *info; /* Image info struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT if(value) { + H5FD_file_image_info_t *info; /* Image info struct */ + info = (H5FD_file_image_info_t *)value; /* verify file image field consistancy */ @@ -2533,16 +2534,17 @@ H5P_file_image_info_copy(const char UNUSED *name, size_t UNUSED size, void *valu else HDmemcpy(info->buffer, old_buffer, info->size); } /* end if */ - } /* end if */ - /* Copy udata if it exists */ - if(info->callbacks.udata) { - void *old_udata = info->callbacks.udata; + /* Copy udata if it exists */ + if(info->callbacks.udata) { + void *old_udata = info->callbacks.udata; + + if(NULL == info->callbacks.udata_copy) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "udata_copy not defined") - if(NULL == info->callbacks.udata_copy) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "udata_copy not defined") + info->callbacks.udata = info->callbacks.udata_copy(old_udata); + } /* end if */ - info->callbacks.udata = info->callbacks.udata_copy(old_udata); } /* end if */ done: @@ -2567,32 +2569,33 @@ done: herr_t H5P_file_image_info_close(const char UNUSED *name, size_t UNUSED size, void *value) { - H5FD_file_image_info_t info; /* Image info struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT if(value) { - info = *(H5FD_file_image_info_t *)value; + H5FD_file_image_info_t *info; /* Image info struct */ + + info = (H5FD_file_image_info_t *)value; - if(info.buffer != NULL && info.size > 0) { + if(info->buffer != NULL && info->size > 0) { /* Free buffer */ - if(info.callbacks.image_free) { - if(info.callbacks.image_free(info.buffer, H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE, - info.callbacks.udata) < 0) + if(info->callbacks.image_free) { + if(info->callbacks.image_free(info->buffer, H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE, + info->callbacks.udata) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "image_free callback failed") } /* end if */ else - H5MM_xfree(info.buffer); + H5MM_xfree(info->buffer); } /* end if */ - } /* end if */ - /* Free udata if it exists */ - if(info.callbacks.udata) { - if(NULL == info.callbacks.udata_free) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "udata_free not defined") - if(info.callbacks.udata_free(info.callbacks.udata) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "udata_free callback failed") + /* Free udata if it exists */ + if(info->callbacks.udata) { + if(NULL == info->callbacks.udata_free) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "udata_free not defined") + if(info->callbacks.udata_free(info->callbacks.udata) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "udata_free callback failed") + } /* end if */ } /* end if */ done: diff --git a/src/H5Shyper.c b/src/H5Shyper.c index d9b306d..d88ac35 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -2784,7 +2784,7 @@ H5S_hyper_offset(const H5S_t *space, hsize_t *offset) FUNC_ENTER_NOAPI(FAIL) - HDassert(space); + HDassert(space && space->extent.rank>0); HDassert(offset); /* Start at linear offset 0 */ diff --git a/src/H5Spoint.c b/src/H5Spoint.c index 817b2f2..b758a92 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -643,7 +643,7 @@ H5S_point_copy(H5S_t *dst, const H5S_t *src, hbool_t UNUSED share_selection) } /* end while */ done: - if(ret_value < 0) { + if(ret_value < 0 && dst->select.sel_info.pnt_lst) { /* Traverse the (incomplete?) dst list, freeing all memory */ curr = dst->select.sel_info.pnt_lst->head; while(curr) { diff --git a/src/H5Sselect.c b/src/H5Sselect.c index 91aed1e..9a993a5 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -67,7 +67,7 @@ H5S_select_offset(H5S_t *space, const hssize_t *offset) /* Check args */ HDassert(space); - HDassert(space->extent.rank); + HDassert(0 < space->extent.rank && space->extent.rank <= H5S_MAX_RANK); HDassert(offset); /* Copy the offset over */ diff --git a/src/H5Tarray.c b/src/H5Tarray.c index 9986631..c73b934 100644 --- a/src/H5Tarray.c +++ b/src/H5Tarray.c @@ -194,7 +194,8 @@ H5T__array_create(H5T_t *base, unsigned ndims, const hsize_t dim[/* ndims */]) ret_value->shared->type = H5T_ARRAY; /* Copy the base type of the array */ - ret_value->shared->parent = H5T_copy(base, H5T_COPY_ALL); + if(NULL == (ret_value->shared->parent = H5T_copy(base, H5T_COPY_ALL))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "unable to copy base datatype") /* Set the array parameters */ ret_value->shared->u.array.ndims = ndims; diff --git a/src/H5trace.c b/src/H5trace.c index b711f40..b559669 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -212,6 +212,7 @@ H5_trace(const double *returning, const char *func, const char *type, ...) if('[' == *type) { if('a' == type[1]) { asize_idx = (int)HDstrtol(type + 2, &rest, 10); + HDassert(0 <= asize_idx && asize_idx < (int) NELMTS(asize)); HDassert(']'==*rest); type = rest + 1; } else { diff --git a/test/accum.c b/test/accum.c index c5f6610..e4c1bd8 100644 --- a/test/accum.c +++ b/test/accum.c @@ -1793,15 +1793,17 @@ accum_printf(void) printf("=====================================================\n"); } else { printf("=====================================================\n"); - printf(" accumulator allocated size == %lu\n", (unsigned long)accum->alloc_size); - printf(" accumulated data size == %lu\n", (unsigned long)accum->size); - printf(" accumulator dirty? == %d\n", accum->dirty); + printf(" accumulator allocated size == %zu\n", accum->alloc_size); + printf(" accumulated data size == %zu\n", accum->size); + HDfprintf(stdout, " accumulator dirty? == %t\n", accum->dirty); printf("=====================================================\n"); - printf(" start of accumulated data, loc = %llu\n", accum->loc); - if (accum->dirty) printf(" start of dirty region, loc = %llu\n", accum->loc + accum->dirty_off); - if (accum->dirty) printf(" end of dirty region, loc = %llu\n", accum->loc + accum->dirty_off + accum->dirty_len); - printf(" end of accumulated data, loc = %llu\n", accum->loc + accum->size); - printf(" end of accumulator allocation, loc = %llu\n", accum->loc + accum->alloc_size); + HDfprintf(stdout, " start of accumulated data, loc = %a\n", accum->loc); + if(accum->dirty) { + HDfprintf(stdout, " start of dirty region, loc = %a\n", (haddr_t)(accum->loc + accum->dirty_off)); + HDfprintf(stdout, " end of dirty region, loc = %a\n", (haddr_t)(accum->loc + accum->dirty_off + accum->dirty_len)); + } /* end if */ + HDfprintf(stdout, " end of accumulated data, loc = %a\n", (haddr_t)(accum->loc + accum->size)); + HDfprintf(stdout, " end of accumulator allocation, loc = %a\n", (haddr_t)(accum->loc + accum->alloc_size)); printf("=====================================================\n"); } printf("\n\n"); diff --git a/test/cache.c b/test/cache.c index 0e6cb42..ba51a38 100644 --- a/test/cache.c +++ b/test/cache.c @@ -33532,6 +33532,7 @@ check_notify_cb(void) reset_entries(); file_ptr = setup_cache((size_t)(2 * 1024), (size_t)(1 * 1024)); + if ( !file_ptr ) CACHE_ERROR("setup_cache returned NULL") cache_ptr = file_ptr->shared->cache; base_addr = entries[entry_type]; @@ -33675,8 +33676,7 @@ check_notify_cb(void) } /* end for */ done: - if(file_ptr) - takedown_cache(file_ptr, FALSE, FALSE); + takedown_cache(file_ptr, FALSE, FALSE); if ( pass ) PASSED() diff --git a/test/cache_common.c b/test/cache_common.c index e6dd020..7b26714 100644 --- a/test/cache_common.c +++ b/test/cache_common.c @@ -2031,7 +2031,7 @@ verify_entry_status(H5C_t * cache_ptr, int num_entries, struct expected_entry_status expected[]) { - static char msg[128]; + static char msg[256]; int i; i = 0; diff --git a/test/cache_tagging.c b/test/cache_tagging.c index 9aef651..5eb1e84 100644 --- a/test/cache_tagging.c +++ b/test/cache_tagging.c @@ -740,7 +740,7 @@ check_group_creation_tags(hid_t fcpl, int type) hid_t fid = -1; /* File Identifier */ hid_t gid = -1; /* Group Identifier */ int verbose = FALSE; /* verbose file outout */ - haddr_t root_tag; /* Root Group Tag */ + haddr_t root_tag = HADDR_UNDEF; /* Root Group Tag */ haddr_t g_tag; /* Group Tag */ haddr_t sbe_tag; /* Sblock Extension Tag */ @@ -1249,7 +1249,7 @@ check_group_open_tags(hid_t fcpl, int type) hid_t fid = -1; /* File Identifier */ hid_t gid = -1; /* Group Identifier */ int verbose = FALSE; /* verbose file output */ - haddr_t root_tag; + haddr_t root_tag = HADDR_UNDEF; haddr_t sbe_tag; haddr_t g_tag; @@ -3056,7 +3056,7 @@ check_object_info_tags(hid_t fcpl, int type) hid_t fid = -1; /* File Identifier */ hid_t gid = -1; /* Group Identifier */ int verbose = FALSE; /* verbose file output */ - haddr_t root_tag; + haddr_t root_tag = HADDR_UNDEF; haddr_t sbe_tag; haddr_t g_tag; H5O_info_t oinfo; /* Object info struct */ @@ -3170,7 +3170,7 @@ check_object_copy_tags(hid_t fcpl, int type) hid_t fid = -1; /* File Identifier */ hid_t gid = -1; /* Group Identifier */ int verbose = FALSE; /* verbose file output */ - haddr_t root_tag; + haddr_t root_tag = HADDR_UNDEF; haddr_t sbe_tag; haddr_t g_tag; haddr_t copy_tag; diff --git a/test/dsets.c b/test/dsets.c index 88e41f7..70d610b 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -1085,8 +1085,8 @@ test_conv_buffer(hid_t fid) herr_t status = -1; int j, k, l; - CmpField *cf; - CmpFieldR *cfrR; + CmpField *cf = NULL; + CmpFieldR *cfrR = NULL; hid_t dataset = -1; /* dataset ID */ hid_t space = -1; /* data space ID */ @@ -1100,7 +1100,7 @@ test_conv_buffer(hid_t fid) TESTING("data type conversion buffer size"); - cf = (CmpField *)HDcalloc((size_t)1, sizeof(CmpField)); + if ((cf = (CmpField *)HDcalloc((size_t)1, sizeof(CmpField))) == 0) goto error; /* Populate the data members */ for(j = 0; j < DIM1; j++) @@ -1149,7 +1149,7 @@ test_conv_buffer(hid_t fid) if(H5Tinsert(ctype2, "C", HOFFSET(CmpFieldR, c), arr_type5) < 0) goto error; /* Read should succeed since library will set conversion buffer big enough */ - cfrR = (CmpFieldR *)HDcalloc((size_t)1, sizeof(CmpFieldR)); + if ((cfrR = (CmpFieldR *)HDcalloc((size_t)1, sizeof(CmpFieldR))) == 0) goto error; if(H5Dread(dataset, ctype2, H5S_ALL, H5S_ALL, H5P_DEFAULT, cfrR) < 0) goto error; /* Read should fail since conversion buffer isn't big enough */ @@ -1186,10 +1186,8 @@ test_conv_buffer(hid_t fid) if(H5Tclose(arr_type5) < 0) goto error; if(H5Dclose(dataset) < 0) goto error; - if(cf) - HDfree(cf); - if(cfrR) - HDfree(cfrR); + HDfree(cf); + HDfree(cfrR); puts(" PASSED"); return(0); diff --git a/test/dt_arith.c b/test/dt_arith.c index 0001755..096b83e 100644 --- a/test/dt_arith.c +++ b/test/dt_arith.c @@ -1105,9 +1105,9 @@ test_derived_flt(void) } fails_this_test = 0; - if(buf) free(buf); - if(saved_buf) free(saved_buf); - if(aligned) free(aligned); + free(buf); + free(saved_buf); + free(aligned); buf = NULL; saved_buf = NULL; aligned = NULL; diff --git a/test/dtypes.c b/test/dtypes.c index 3db9bf8..117a21a 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -1127,10 +1127,8 @@ test_compound_5(void) } /* Free memory buffers */ - if(buf) - HDfree(buf); - if(bkg) - HDfree(bkg); + HDfree(buf); + HDfree(bkg); return retval; } @@ -4698,11 +4696,12 @@ test_bitfield_funcs(void) { hid_t type=-1, ntype=-1, super=-1; int size; - char* tag; + char* tag=0; H5T_pad_t inpad; H5T_cset_t cset; H5T_str_t strpad; herr_t ret; + int retval=-1; TESTING("some type functions for bitfield"); @@ -4786,16 +4785,18 @@ test_bitfield_funcs(void) goto error; } /* end if */ - H5Tclose(type); - H5Tclose(ntype); - PASSED(); - reset_hdf5(); - return 0; + retval = 0; error: + + if (retval == -1) retval = 1; + + HDfree(tag); + H5Tclose(ntype); H5Tclose(type); + if (retval == 0) PASSED(); reset_hdf5(); - return 1; + return retval; } @@ -7049,11 +7050,13 @@ error: */ int test_utf_ascii_conv(void) { - hid_t fid; - hid_t did; - hid_t utf8_vtid, ascii_vtid; - hid_t utf8_tid, ascii_tid; - hid_t sid; + hid_t fid = -1; + hid_t did = -1; + hid_t utf8_vtid = -1; + hid_t ascii_vtid = -1; + hid_t utf8_tid = -1; + hid_t ascii_tid = -1; + hid_t sid = -1; const char *utf8_w = "foo!"; char *ascii_r = NULL; const char *ascii_w = "bar!"; diff --git a/test/file_image.c b/test/file_image.c index 73c901e..9d7a48c 100644 --- a/test/file_image.c +++ b/test/file_image.c @@ -86,15 +86,16 @@ typedef struct { static int test_properties(void) { - hid_t fapl_1; - hid_t fapl_2; - char *buffer; + hid_t fapl_1 = -1; + hid_t fapl_2 = -1; + char *buffer = 0; int count = 10; - void *temp; - char *temp2; + void *temp = 0; + char *temp2 = 0; int i; size_t size; size_t temp_size; + int retval = 1; TESTING("File image property list functions"); @@ -145,18 +146,21 @@ test_properties(void) VERIFY(temp2 != temp, "Retrieved buffer is the same as previously retrieved buffer"); VERIFY(0 == HDmemcmp(temp2, buffer, size),"Buffers contain different data"); + retval = 0; + +error: + /* Close everything */ - if(H5Pclose(fapl_1) < 0) FAIL_STACK_ERROR - if(H5Pclose(fapl_2) < 0) FAIL_STACK_ERROR + if(H5Pclose(fapl_1) < 0) retval = 1; + if(H5Pclose(fapl_2) < 0) retval = 1; HDfree(buffer); HDfree(temp); HDfree(temp2); - PASSED(); - return 0; + if(retval == 0) + PASSED(); -error: - return 1; + return retval; } /* end test_properties() */ /****************************************************************************** diff --git a/test/freespace.c b/test/freespace.c index 6960e6d..c0df4c8 100644 --- a/test/freespace.c +++ b/test/freespace.c @@ -1522,8 +1522,10 @@ test_fs_sect_merge(hid_t fapl) /* Free the section node(s) */ if(TEST_sect_free((H5FS_section_info_t *)sect_node1) < 0) TEST_ERROR + sect_node1 = NULL; if(TEST_sect_free((H5FS_section_info_t *)sect_node2) < 0) TEST_ERROR + sect_node2 = NULL; /* Close the free space manager */ if(H5FS_close(f, H5P_DATASET_XFER_DEFAULT, frsp) < 0) diff --git a/test/h5test.c b/test/h5test.c index 7faba81..ea30fad 100644 --- a/test/h5test.c +++ b/test/h5test.c @@ -735,6 +735,8 @@ h5_set_info_object(void) valp = envp = next = HDstrdup(envp); + if (!valp) return 0; + /* create an INFO object if not created yet */ if (h5_io_info_g == MPI_INFO_NULL) MPI_Info_create(&h5_io_info_g); @@ -761,6 +763,8 @@ h5_set_info_object(void) while (*namep && (*namep == ' ' || *namep == '\t')) namep++; + if (!*namep) continue; /* was all white space, so move to next k/v pair */ + /* eat up any ending white spaces */ endp = &namep[strlen(namep) - 1]; diff --git a/test/ntypes.c b/test/ntypes.c index 165d21b..0af3a3f 100644 --- a/test/ntypes.c +++ b/test/ntypes.c @@ -1776,6 +1776,7 @@ test_vl_dtype(hid_t file) } /* end for */ HDfree(tmp); + tmp = NULL; } /* end for */ } /* end for */ diff --git a/test/objcopy.c b/test/objcopy.c index 1c66097..0456899 100644 --- a/test/objcopy.c +++ b/test/objcopy.c @@ -10879,7 +10879,7 @@ test_copy_cdt_merge_all_suggs(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t did = -1; /* Dataset ID */ hid_t exp_did = -1; /* Dataset ID */ hid_t tid_short = -1; /* Datatype ID */ - hid_t exp_tid; /* Expected datatype ID */ + hid_t exp_tid = -1; /* Expected datatype ID */ hid_t ocpypl_id = -1; /* Object copy plist ID */ hsize_t dim1d[1]; /* Dataset dimensions */ char src_filename[NAME_BUF_SIZE]; diff --git a/test/tsohm.c b/test/tsohm.c index 62154b1..fddb552 100644 --- a/test/tsohm.c +++ b/test/tsohm.c @@ -2463,11 +2463,11 @@ static void test_sohm_size2(int close_reopen) * this happens because it's hard to predict exactly how much space this * will take. */ - if((mult_index_med.attrs2 - mult_index_med.attrs1) != - (list_index_med.attrs2 - list_index_med.attrs1)) + if((mult_index_med.attrs2 - mult_index_med.attrs1) > + (list_index_med.attrs2 - list_index_med.attrs1) * OVERHEAD_ALLOWED) VERIFY(0, 1, "h5_get_file_size"); - if((mult_index_btree.attrs2 - mult_index_btree.attrs1) != - (btree_index.attrs2 - btree_index.attrs1)) + if((mult_index_btree.attrs2 - mult_index_btree.attrs1) > + (btree_index.attrs2 - btree_index.attrs1) * OVERHEAD_ALLOWED) VERIFY(0, 1, "h5_get_file_size"); /* The final file size for both of the multiple index files should be diff --git a/test/tunicode.c b/test/tunicode.c index 3b949e9..0386352 100644 --- a/test/tunicode.c +++ b/test/tunicode.c @@ -161,6 +161,7 @@ void test_strpad(hid_t UNUSED fid, const char *string) /* Create a src_type that holds the UTF-8 string and its final NULL */ big_len = length + 1; /* +1 byte for final NULL */ + HDassert((2*big_len)<=sizeof(cmpbuf)); src_type = mkstr(big_len, H5T_STR_NULLTERM); CHECK(src_type, FAIL, "mkstr"); /* Create a dst_type that holds half of the UTF-8 string and a final @@ -224,6 +225,7 @@ void test_strpad(hid_t UNUSED fid, const char *string) /* Create a src_type that holds the UTF-8 string */ big_len = length; + HDassert((2*big_len)<=sizeof(cmpbuf)); src_type = mkstr(big_len, H5T_STR_NULLPAD); CHECK(src_type, FAIL, "mkstr"); /* Create a dst_type that holds half of the UTF-8 string */ diff --git a/testpar/t_dset.c b/testpar/t_dset.c index f20f126..9db1610 100644 --- a/testpar/t_dset.c +++ b/testpar/t_dset.c @@ -3106,8 +3106,12 @@ dataset_atomicity(void) dim0 = 64; dim1 = 32; filename = GetTestParameters(); + if (facc_type != FACC_MPIO) { + printf("Atomicity tests will not work without the MPIO VFD\n"); + return; + } if(VERBOSE_MED) - printf("Independent write test on file %s\n", filename); + printf("atomic writes to file %s\n", filename); /* set up MPI parameters */ MPI_Comm_size(MPI_COMM_WORLD,&mpi_size); diff --git a/testpar/testphdf5.c b/testpar/testphdf5.c index f27d09b..2837e71 100644 --- a/testpar/testphdf5.c +++ b/testpar/testphdf5.c @@ -513,16 +513,6 @@ int main(int argc, char **argv) AddTest((mpi_size < 2)? "-fiodc" : "fiodc", file_image_daisy_chain_test, NULL, "file image ops daisy chain", NULL); - /* Display testing information */ - TestInfo(argv[0]); - - /* setup file access property list */ - fapl = H5Pcreate (H5P_FILE_ACCESS); - H5Pset_fapl_mpio(fapl, MPI_COMM_WORLD, MPI_INFO_NULL); - - /* Parse command line arguments */ - TestParseCmdLine(argc, argv); - if((mpi_size < 2)&& MAINPROCESS ) { printf("Atomicity tests need at least 2 processes to participate\n"); printf("8 is more recommended.. Atomicity tests will be skipped \n"); @@ -535,6 +525,16 @@ int main(int argc, char **argv) "dataset atomic updates", PARATESTFILE); } + /* Display testing information */ + TestInfo(argv[0]); + + /* setup file access property list */ + fapl = H5Pcreate (H5P_FILE_ACCESS); + H5Pset_fapl_mpio(fapl, MPI_COMM_WORLD, MPI_INFO_NULL); + + /* Parse command line arguments */ + TestParseCmdLine(argc, argv); + if (facc_type == FACC_MPIPOSIX && MAINPROCESS){ printf("===================================\n" " Using MPIPOSIX driver\n" diff --git a/tools/h5dump/CMakeLists.txt b/tools/h5dump/CMakeLists.txt index cf442d4..1482327 100644 --- a/tools/h5dump/CMakeLists.txt +++ b/tools/h5dump/CMakeLists.txt @@ -781,14 +781,33 @@ IF (BUILD_TESTING) ENDMACRO (ADD_XML_H5_TEST file) # -------------------------------------------------------------------- - # Determine which filters are available + # See which filters are usable (and skip tests for filters we + # don't have). Do this by searching H5pubconf.h to see which + # filters are defined. # -------------------------------------------------------------------- - SET (USE_FILTER_SZIP H5_HAVE_FILTER_SZIP) - SET (USE_FILTER_DEFLATE H5_HAVE_FILTER_DEFLATE) - SET (USE_FILTER_SHUFFLE H5_HAVE_FILTER_SHUFFLE) - SET (USE_FILTER_FLETCHER32 H5_HAVE_FILTER_FLETCHER32) - SET (USE_FILTER_NBIT H5_HAVE_FILTER_NBIT) - SET (USE_FILTER_SCALEOFFSET H5_HAVE_FILTER_SCALEOFFSET) + IF (H5_HAVE_FILTER_DEFLATE) + SET (USE_FILTER_DEFLATE "true") + ENDIF (H5_HAVE_FILTER_DEFLATE) + + IF (H5_HAVE_FILTER_SZIP) + SET (USE_FILTER_SZIP "true") + ENDIF (H5_HAVE_FILTER_SZIP) + + IF (H5_HAVE_FILTER_SHUFFLE) + SET (USE_FILTER_SHUFFLE "true") + ENDIF (H5_HAVE_FILTER_SHUFFLE) + + IF (H5_HAVE_FILTER_FLETCHER32) + SET (USE_FILTER_FLETCHER32 "true") + ENDIF (H5_HAVE_FILTER_FLETCHER32) + + IF (H5_HAVE_FILTER_NBIT) + SET (USE_FILTER_NBIT "true") + ENDIF (H5_HAVE_FILTER_NBIT) + + IF (H5_HAVE_FILTER_SCALEOFFSET) + SET (USE_FILTER_SCALEOFFSET "true") + ENDIF (H5_HAVE_FILTER_SCALEOFFSET) ############################################################################## ############################################################################## diff --git a/tools/h5import/CMakeLists.txt b/tools/h5import/CMakeLists.txt index a655bf2..4e320a1 100644 --- a/tools/h5import/CMakeLists.txt +++ b/tools/h5import/CMakeLists.txt @@ -273,7 +273,9 @@ IF (BUILD_TESTING) # -------------------------------------------------------------------- # Determine if filter is available for h5diff # -------------------------------------------------------------------- - SET (USE_FILTER_DEFLATE H5_HAVE_FILTER_DEFLATE) + IF (H5_HAVE_FILTER_DEFLATE) + SET (USE_FILTER_DEFLATE "true") + ENDIF (H5_HAVE_FILTER_DEFLATE) ############################################################################## ############################################################################## diff --git a/tools/h5repack/h5repack_copy.c b/tools/h5repack/h5repack_copy.c index 957d3c8..cf55d7f 100644 --- a/tools/h5repack/h5repack_copy.c +++ b/tools/h5repack/h5repack_copy.c @@ -1541,7 +1541,7 @@ static void print_dataset_info(hid_t dcpl_id, printf(FORMAT_OBJ,"dset",objname ); else { - char str[255], temp[20]; + char str[255], temp[28]; HDstrcpy(str,"dset "); HDstrcat(str,strfilter); sprintf(temp," (%.3f:1)",ratio); diff --git a/tools/h5repack/h5repack_opttable.c b/tools/h5repack/h5repack_opttable.c index 4ec7fcf..00e4bea 100644 --- a/tools/h5repack/h5repack_opttable.c +++ b/tools/h5repack/h5repack_opttable.c @@ -388,7 +388,7 @@ pack_info_t* options_get_object( const char *path, pack_opttbl_t *table ) { unsigned int i; - const char tbl_path[MAX_NC_NAME]; + const char tbl_path[MAX_NC_NAME+1]; /* +1 for start with "/" case */ for ( i = 0; i < table->nelems; i++) diff --git a/tools/lib/h5diff.c b/tools/lib/h5diff.c index 48e82bb..f2eb3ab 100644 --- a/tools/lib/h5diff.c +++ b/tools/lib/h5diff.c @@ -1013,27 +1013,18 @@ hsize_t h5diff(const char *fname1, #ifdef H5_HAVE_PARALLEL if(g_Parallel) { - /* if both obj1 and obj2 are group */ - if (both_objs_grp) + if((HDstrlen(fname1) > MAX_FILENAME) || (HDstrlen(fname2) > MAX_FILENAME)) { - if((HDstrlen(fname1) > MAX_FILENAME) || (HDstrlen(fname2) > MAX_FILENAME)) - { - HDfprintf(stderr, "The parallel diff only supports path names up to %d characters\n", MAX_FILENAME); - MPI_Abort(MPI_COMM_WORLD, 0); - } /* end if */ + HDfprintf(stderr, "The parallel diff only supports path names up to %d characters\n", MAX_FILENAME); + MPI_Abort(MPI_COMM_WORLD, 0); + } /* end if */ - HDstrcpy(filenames[0], fname1); - HDstrcpy(filenames[1], fname2); + HDstrcpy(filenames[0], fname1); + HDstrcpy(filenames[1], fname2); - /* Alert the worker tasks that there's going to be work. */ - for(i = 1; i < g_nTasks; i++) - MPI_Send(filenames, (MAX_FILENAME * 2), MPI_CHAR, i, MPI_TAG_PARALLEL, MPI_COMM_WORLD); - } - else - { - /* Only single object diff, parallel workers won't be needed */ - phdiff_dismiss_workers(); - } + /* Alert the worker tasks that there's going to be work. */ + for(i = 1; i < g_nTasks; i++) + MPI_Send(filenames, (MAX_FILENAME * 2), MPI_CHAR, i, MPI_TAG_PARALLEL, MPI_COMM_WORLD); } /* end if */ #endif diff --git a/tools/misc/talign.c b/tools/misc/talign.c index 88ebaa6..b77d846 100644 --- a/tools/misc/talign.c +++ b/tools/misc/talign.c @@ -148,28 +148,31 @@ out: result = 1; mname = H5Tget_member_name(fix, 0); printf("%14s (%2d) %6s = %s\n", - mname, (int)H5Tget_member_offset(fix,0), + mname ? mname : "(null)", (int)H5Tget_member_offset(fix,0), string5, (char *)(data + H5Tget_member_offset(fix, 0))); - free(mname); + if(mname) + free(mname); fptr = (float *)(data + H5Tget_member_offset(fix, 1)); mname = H5Tget_member_name(fix, 1); printf("Data comparison:\n" "%14s (%2d) %6f = %f\n" " %6f = %f\n", - mname, (int)H5Tget_member_offset(fix,1), + mname ? mname : "(null)", (int)H5Tget_member_offset(fix,1), fok[0], fptr[0], fok[1], fptr[1]); - free(mname); + if(mname) + free(mname); fptr = (float *)(data + H5Tget_member_offset(fix, 2)); mname = H5Tget_member_name(fix, 2); printf("%14s (%2d) %6f = %f\n" " %6f = %6f\n", - mname, (int)H5Tget_member_offset(fix,2), + mname ? mname : "(null)", (int)H5Tget_member_offset(fix,2), fnok[0], fptr[0], fnok[1], fptr[1]); - free(mname); + if(mname) + free(mname); fptr = (float *)(data + H5Tget_member_offset(fix, 1)); printf("\n" -- cgit v0.12