diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/H5ACpublic.h | 236 | ||||
-rw-r--r-- | src/H5Cdbg.c | 111 | ||||
-rw-r--r-- | src/H5Cimage.c | 73 | ||||
-rw-r--r-- | src/H5Cmpio.c | 102 | ||||
-rw-r--r-- | src/H5Cpkg.h | 21 | ||||
-rw-r--r-- | src/H5Cprivate.h | 5 | ||||
-rw-r--r-- | src/H5Ctag.c | 47 | ||||
-rw-r--r-- | src/H5Dchunk.c | 10 | ||||
-rw-r--r-- | src/H5Dearray.c | 15 | ||||
-rw-r--r-- | src/H5FDmpi.c | 39 | ||||
-rw-r--r-- | src/H5FDmpio.c | 37 | ||||
-rw-r--r-- | src/H5FDprivate.h | 2 | ||||
-rw-r--r-- | src/H5Fmpi.c | 26 | ||||
-rw-r--r-- | src/H5Fprivate.h | 1 | ||||
-rw-r--r-- | src/H5L.c | 6 | ||||
-rw-r--r-- | src/H5Oprivate.h | 1 | ||||
-rw-r--r-- | src/H5PL.c | 244 | ||||
-rw-r--r-- | src/H5PLpkg.h | 50 | ||||
-rw-r--r-- | src/H5PLpublic.h | 10 | ||||
-rw-r--r-- | src/H5Pfapl.c | 20 |
21 files changed, 716 insertions, 341 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9321bbd..e2acd30 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -520,6 +520,7 @@ set (H5PL_SOURCES set (H5PL_HDRS ${HDF5_SRC_DIR}/H5PLextern.h + ${HDF5_SRC_DIR}/H5PLpkg.h ${HDF5_SRC_DIR}/H5PLpublic.h ) IDE_GENERATED_PROPERTIES ("H5PL" "${H5PL_HDRS}" "${H5PL_SOURCES}" ) diff --git a/src/H5ACpublic.h b/src/H5ACpublic.h index 5fdb3f4..ca0e63f 100644 --- a/src/H5ACpublic.h +++ b/src/H5ACpublic.h @@ -70,65 +70,65 @@ extern "C" { * version number, or an error will be flagged. * * rpt_fcn_enabled: Boolean field used to enable and disable the default - * reporting function. This function is invoked every time the - * automatic cache resize code is run, and reports on its activities. + * reporting function. This function is invoked every time the + * automatic cache resize code is run, and reports on its activities. * - * This is a debugging function, and should normally be turned off. + * This is a debugging function, and should normally be turned off. * * open_trace_file: Boolean field indicating whether the trace_file_name - * field should be used to open a trace file for the cache. + * field should be used to open a trace file for the cache. * * *** DEPRECATED *** Use H5Fstart/stop logging functions instead * - * The trace file is a debuging feature that allow the capture of - * top level metadata cache requests for purposes of debugging and/or - * optimization. This field should normally be set to FALSE, as - * trace file collection imposes considerable overhead. + * The trace file is a debuging feature that allow the capture of + * top level metadata cache requests for purposes of debugging and/or + * optimization. This field should normally be set to FALSE, as + * trace file collection imposes considerable overhead. * - * This field should only be set to TRUE when the trace_file_name - * contains the full path of the desired trace file, and either - * there is no open trace file on the cache, or the close_trace_file - * field is also TRUE. + * This field should only be set to TRUE when the trace_file_name + * contains the full path of the desired trace file, and either + * there is no open trace file on the cache, or the close_trace_file + * field is also TRUE. * * close_trace_file: Boolean field indicating whether the current trace - * file (if any) should be closed. + * file (if any) should be closed. * * *** DEPRECATED *** Use H5Fstart/stop logging functions instead * - * See the above comments on the open_trace_file field. This field - * should be set to FALSE unless there is an open trace file on the - * cache that you wish to close. + * See the above comments on the open_trace_file field. This field + * should be set to FALSE unless there is an open trace file on the + * cache that you wish to close. * * trace_file_name: Full path of the trace file to be opened if the - * open_trace_file field is TRUE. + * open_trace_file field is TRUE. * * *** DEPRECATED *** Use H5Fstart/stop logging functions instead * - * In the parallel case, an ascii representation of the mpi rank of - * the process will be appended to the file name to yield a unique - * trace file name for each process. + * In the parallel case, an ascii representation of the mpi rank of + * the process will be appended to the file name to yield a unique + * trace file name for each process. * - * The length of the path must not exceed H5AC__MAX_TRACE_FILE_NAME_LEN - * characters. + * The length of the path must not exceed H5AC__MAX_TRACE_FILE_NAME_LEN + * characters. * * evictions_enabled: Boolean field used to either report the current - * evictions enabled status of the cache, or to set the cache's - * evictions enabled status. - * - * In general, the metadata cache should always be allowed to - * evict entries. However, in some cases it is advantageous to - * disable evictions briefly, and thereby postpone metadata - * writes. However, this must be done with care, as the cache - * can grow quickly. If you do this, re-enable evictions as - * soon as possible and monitor cache size. - * - * At present, evictions can only be disabled if automatic - * cache resizing is also disabled (that is, ( incr_mode == - * H5C_incr__off ) && ( decr_mode == H5C_decr__off )). There - * is no logical reason why this should be so, but it simplifies - * implementation and testing, and I can't think of any reason - * why it would be desireable. If you can think of one, I'll - * revisit the issue. + * evictions enabled status of the cache, or to set the cache's + * evictions enabled status. + * + * In general, the metadata cache should always be allowed to + * evict entries. However, in some cases it is advantageous to + * disable evictions briefly, and thereby postpone metadata + * writes. However, this must be done with care, as the cache + * can grow quickly. If you do this, re-enable evictions as + * soon as possible and monitor cache size. + * + * At present, evictions can only be disabled if automatic + * cache resizing is also disabled (that is, ( incr_mode == + * H5C_incr__off ) && ( decr_mode == H5C_decr__off )). There + * is no logical reason why this should be so, but it simplifies + * implementation and testing, and I can't think of any reason + * why it would be desireable. If you can think of one, I'll + * revisit the issue. * * set_initial_size: Boolean flag indicating whether the size of the * initial size of the cache is to be set to the value given in @@ -368,80 +368,80 @@ extern "C" { * * PHDF5 uses several strategies to prevent such inconsistencies in metadata, * all of which use the fact that the same stream of dirty metadata is seen - * by all processes for purposes of synchronization. This is done by + * by all processes for purposes of synchronization. This is done by * having each process count the number of bytes of dirty metadata generated, - * and then running a "sync point" whenever this count exceeds a user + * and then running a "sync point" whenever this count exceeds a user * specified threshold (see dirty_bytes_threshold below). * - * The current metadata write strategy is indicated by the + * The current metadata write strategy is indicated by the * metadata_write_strategy field. The possible values of this field, along * with the associated metadata write strategies are discussed below. * * dirty_bytes_threshold: Threshold of dirty byte creation used to - * synchronize updates between caches. (See above for outline and - * motivation.) + * synchronize updates between caches. (See above for outline and + * motivation.) * - * This value MUST be consistant across all processes accessing the - * file. This field is ignored unless HDF5 has been compiled for - * parallel. + * This value MUST be consistant across all processes accessing the + * file. This field is ignored unless HDF5 has been compiled for + * parallel. * * metadata_write_strategy: Integer field containing a code indicating the - * desired metadata write strategy. The valid values of this field - * are enumerated and discussed below: + * desired metadata write strategy. The valid values of this field + * are enumerated and discussed below: * * - * H5AC_METADATA_WRITE_STRATEGY__PROCESS_0_ONLY: + * H5AC_METADATA_WRITE_STRATEGY__PROCESS_0_ONLY: * - * When metadata_write_strategy is set to this value, only process - * zero is allowed to write dirty metadata to disk. All other - * processes must retain dirty metadata until they are informed at - * a sync point that the dirty metadata in question has been written - * to disk. + * When metadata_write_strategy is set to this value, only process + * zero is allowed to write dirty metadata to disk. All other + * processes must retain dirty metadata until they are informed at + * a sync point that the dirty metadata in question has been written + * to disk. * - * When the sync point is reached (or when there is a user generated - * flush), process zero flushes sufficient entries to bring it into - * complience with its min clean size (or flushes all dirty entries in - * the case of a user generated flush), broad casts the list of - * entries just cleaned to all the other processes, and then exits - * the sync point. + * When the sync point is reached (or when there is a user generated + * flush), process zero flushes sufficient entries to bring it into + * complience with its min clean size (or flushes all dirty entries in + * the case of a user generated flush), broad casts the list of + * entries just cleaned to all the other processes, and then exits + * the sync point. * - * Upon receipt of the broadcast, the other processes mark the indicated - * entries as clean, and leave the sync point as well. + * Upon receipt of the broadcast, the other processes mark the indicated + * entries as clean, and leave the sync point as well. * * - * H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED: + * H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED: * - * In the distributed metadata write strategy, process zero still makes - * the decisions as to what entries should be flushed, but the actual - * flushes are distributed across the processes in the computation to - * the extent possible. + * In the distributed metadata write strategy, process zero still makes + * the decisions as to what entries should be flushed, but the actual + * flushes are distributed across the processes in the computation to + * the extent possible. * - * In this strategy, when a sync point is triggered (either by dirty - * metadata creation or manual flush), all processes enter a barrier. + * In this strategy, when a sync point is triggered (either by dirty + * metadata creation or manual flush), all processes enter a barrier. * - * On the other side of the barrier, process 0 constructs an ordered - * list of the entries to be flushed, and then broadcasts this list - * to the caches in all the processes. + * On the other side of the barrier, process 0 constructs an ordered + * list of the entries to be flushed, and then broadcasts this list + * to the caches in all the processes. * - * All processes then scan the list of entries to be flushed, flushing - * some, and marking the rest as clean. The algorithm for this purpose - * ensures that each entry in the list is flushed exactly once, and - * all are marked clean in each cache. + * All processes then scan the list of entries to be flushed, flushing + * some, and marking the rest as clean. The algorithm for this purpose + * ensures that each entry in the list is flushed exactly once, and + * all are marked clean in each cache. * - * Note that in the case of a flush of the cache, no message passing - * is necessary, as all processes have the same list of dirty entries, - * and all of these entries must be flushed. Thus in this case it is - * sufficient for each process to sort its list of dirty entries after - * leaving the initial barrier, and use this list as if it had been - * received from process zero. + * Note that in the case of a flush of the cache, no message passing + * is necessary, as all processes have the same list of dirty entries, + * and all of these entries must be flushed. Thus in this case it is + * sufficient for each process to sort its list of dirty entries after + * leaving the initial barrier, and use this list as if it had been + * received from process zero. + * + * To avoid possible messages from the past/future, all caches must + * wait until all caches are done before leaving the sync point. * - * To avoid possible messages from the past/future, all caches must - * wait until all caches are done before leaving the sync point. - * ****************************************************************************/ -#define H5AC__CURR_CACHE_CONFIG_VERSION 1 -#define H5AC__MAX_TRACE_FILE_NAME_LEN 1024 +#define H5AC__CURR_CACHE_CONFIG_VERSION 1 +#define H5AC__MAX_TRACE_FILE_NAME_LEN 1024 #define H5AC_METADATA_WRITE_STRATEGY__PROCESS_0_ONLY 0 #define H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED 1 @@ -451,9 +451,9 @@ typedef struct H5AC_cache_config_t /* general configuration fields: */ int version; - hbool_t rpt_fcn_enabled; + hbool_t rpt_fcn_enabled; - hbool_t open_trace_file; + hbool_t open_trace_file; hbool_t close_trace_file; char trace_file_name[H5AC__MAX_TRACE_FILE_NAME_LEN + 1]; @@ -512,7 +512,7 @@ typedef struct H5AC_cache_config_t * * structure H5AC_cache_image_config_t * - * H5AC_cache_image_ctl_t is a public structure intended for use in public + * H5AC_cache_image_ctl_t is a public structure intended for use in public * APIs. At least in its initial incarnation, it is a copy of struct * H5C_cache_image_ctl_t. * @@ -526,47 +526,47 @@ typedef struct H5AC_cache_config_t * generate_image: Boolean flag indicating whether a cache image should * be created on file close. * - * save_resize_status: Boolean flag indicating whether the cache image - * should include the adaptive cache resize configuration and status. - * Note that this field is ignored at present. + * save_resize_status: Boolean flag indicating whether the cache image + * should include the adaptive cache resize configuration and status. + * Note that this field is ignored at present. * - * entry_ageout: Integer field indicating the maximum number of - * times a prefetched entry can appear in subsequent cache images. - * This field exists to allow the user to avoid the buildup of - * infrequently used entries in long sequences of cache images. + * entry_ageout: Integer field indicating the maximum number of + * times a prefetched entry can appear in subsequent cache images. + * This field exists to allow the user to avoid the buildup of + * infrequently used entries in long sequences of cache images. * - * The value of this field must lie in the range - * H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE (-1) to - * H5AC__CACHE_IMAGE__ENTRY_AGEOUT__MAX (100). + * The value of this field must lie in the range + * H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE (-1) to + * H5AC__CACHE_IMAGE__ENTRY_AGEOUT__MAX (100). * - * H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE means that no limit - * is imposed on number of times a prefeteched entry can appear - * in subsequent cache images. + * H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE means that no limit + * is imposed on number of times a prefeteched entry can appear + * in subsequent cache images. * - * A value of 0 prevents prefetched entries from being included - * in cache images. + * A value of 0 prevents prefetched entries from being included + * in cache images. * - * Positive integers restrict prefetched entries to the specified - * number of appearances. + * Positive integers restrict prefetched entries to the specified + * number of appearances. * - * Note that the number of subsequent cache images that a prefetched - * entry has appeared in is tracked in an 8 bit field. Thus, while - * H5AC__CACHE_IMAGE__ENTRY_AGEOUT__MAX can be increased from its - * current value, any value in excess of 255 will be the functional - * equivalent of H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE. + * Note that the number of subsequent cache images that a prefetched + * entry has appeared in is tracked in an 8 bit field. Thus, while + * H5AC__CACHE_IMAGE__ENTRY_AGEOUT__MAX can be increased from its + * current value, any value in excess of 255 will be the functional + * equivalent of H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE. * ****************************************************************************/ -#define H5AC__CURR_CACHE_IMAGE_CONFIG_VERSION 1 +#define H5AC__CURR_CACHE_IMAGE_CONFIG_VERSION 1 -#define H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE -1 -#define H5AC__CACHE_IMAGE__ENTRY_AGEOUT__MAX 100 +#define H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE -1 +#define H5AC__CACHE_IMAGE__ENTRY_AGEOUT__MAX 100 typedef struct H5AC_cache_image_config_t { - int32_t version; + int version; hbool_t generate_image; hbool_t save_resize_status; - int32_t entry_ageout; + int entry_ageout; } H5AC_cache_image_config_t; #ifdef __cplusplus diff --git a/src/H5Cdbg.c b/src/H5Cdbg.c index a955eaf..85f25b3 100644 --- a/src/H5Cdbg.c +++ b/src/H5Cdbg.c @@ -30,12 +30,16 @@ #include "H5Cmodule.h" /* This source code file is part of the H5C module */ +#define H5AC_FRIEND + + + /***********/ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ -#include "H5ACprivate.h" /* Metadata Cache */ +#include "H5ACpkg.h" /* Metadata Cache */ #include "H5Cpkg.h" /* Cache */ #include "H5Eprivate.h" /* Error Handling */ @@ -340,6 +344,107 @@ H5C_dump_cache_skip_list(H5C_t * cache_ptr, char * calling_fcn) /*------------------------------------------------------------------------- + * Function: H5C_dump_coll_write_list + * + * Purpose: Debugging routine that prints a summary of the contents of + * the collective write skip list used by the metadata cache + * in the parallel case to maintain a list of entries to write + * collectively at a sync point. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: John Mainzer + * 4/1/17 + * + *------------------------------------------------------------------------- + */ +#ifdef H5_HAVE_PARALLEL +#ifndef NDEBUG +herr_t +H5C_dump_coll_write_list(H5C_t * cache_ptr, char * calling_fcn) +{ + herr_t ret_value = SUCCEED; /* Return value */ + int i; + int list_len; + H5AC_aux_t * aux_ptr = NULL; + H5C_cache_entry_t * entry_ptr = NULL; + H5SL_node_t * node_ptr = NULL; + + FUNC_ENTER_NOAPI_NOERR + + HDassert(cache_ptr != NULL); + HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); + HDassert(cache_ptr->aux_ptr); + + aux_ptr = (H5AC_aux_t *)cache_ptr->aux_ptr; + + HDassert(aux_ptr->magic == H5AC__H5AC_AUX_T_MAGIC); + + HDassert(calling_fcn != NULL); + + list_len = (int)H5SL_count(cache_ptr->coll_write_list); + + HDfprintf(stdout, "\n\nDumping MDC coll write list from %d:%s.\n", + aux_ptr->mpi_rank, calling_fcn); + HDfprintf(stdout, " slist len = %u.\n", cache_ptr->slist_len); + + if ( list_len > 0 ) { + + /* scan the collective write list generating the desired output */ + HDfprintf(stdout, + "Num: Addr: Len: Prot/Pind: Dirty: Type:\n"); + + i = 0; + + node_ptr = H5SL_first(cache_ptr->coll_write_list); + + if ( node_ptr != NULL ) + + entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr); + + else + + entry_ptr = NULL; + + while ( entry_ptr != NULL ) { + + HDassert(entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC); + + HDfprintf(stdout, + "%s%d 0x%016llx %4lld %d/%d %d %s\n", + cache_ptr->prefix, i, + (long long)(entry_ptr->addr), + (long long)(entry_ptr->size), + (int)(entry_ptr->is_protected), + (int)(entry_ptr->is_pinned), + (int)(entry_ptr->is_dirty), + entry_ptr->type->name); + + node_ptr = H5SL_next(node_ptr); + + if ( node_ptr != NULL ) + + entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr); + + else + + entry_ptr = NULL; + + i++; + + } /* end while */ + } /* end if */ + + HDfprintf(stdout, "\n\n"); + + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5C_dump_coll_write_list() */ +#endif /* NDEBUG */ +#endif /* H5_HAVE_PARALLEL */ + + +/*------------------------------------------------------------------------- * Function: H5C_set_prefix * * Purpose: Set the values of the prefix field of H5C_t. This @@ -738,9 +843,10 @@ H5C_stats(H5C_t * cache_ptr, (long long)(cache_ptr->index_scan_restarts)); HDfprintf(stdout, - "%s cache image creations/loads/size = %d / %d / %Hu\n", + "%s cache image creations/reads/loads/size = %d / %d /%d / %Hu\n", cache_ptr->prefix, cache_ptr->images_created, + cache_ptr->images_read, cache_ptr->images_loaded, cache_ptr->last_image_size); @@ -993,6 +1099,7 @@ H5C_stats__reset(H5C_t H5_ATTR_UNUSED * cache_ptr) cache_ptr->index_scan_restarts = 0; cache_ptr->images_created = 0; + cache_ptr->images_read = 0; cache_ptr->images_loaded = 0; cache_ptr->last_image_size = (hsize_t)0; diff --git a/src/H5Cimage.c b/src/H5Cimage.c index fc58dac..d60ee05 100644 --- a/src/H5Cimage.c +++ b/src/H5Cimage.c @@ -122,7 +122,7 @@ static H5C_cache_entry_t *H5C__reconstruct_cache_entry(const H5F_t *f, H5C_t *cache_ptr, const uint8_t **buf); static herr_t H5C__write_cache_image_superblock_msg(H5F_t *f, hid_t dxpl_id, hbool_t create); -static herr_t H5C__read_cache_image(H5F_t * f, hid_t dxpl_id, const H5C_t *cache_ptr); +static herr_t H5C__read_cache_image(H5F_t * f, hid_t dxpl_id, H5C_t *cache_ptr); static herr_t H5C__write_cache_image(H5F_t *f, hid_t dxpl_id, const H5C_t *cache_ptr); static herr_t H5C__construct_cache_image_buffer(H5F_t *f, H5C_t *cache_ptr); static herr_t H5C__free_image_entries_array(H5C_t *cache_ptr); @@ -1035,7 +1035,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5C__read_cache_image(H5F_t *f, hid_t dxpl_id, const H5C_t *cache_ptr) +H5C__read_cache_image(H5F_t *f, hid_t dxpl_id, H5C_t *cache_ptr) { herr_t ret_value = SUCCEED; /* Return value */ @@ -1053,31 +1053,53 @@ H5C__read_cache_image(H5F_t *f, hid_t dxpl_id, const H5C_t *cache_ptr) H5AC_aux_t *aux_ptr = (H5AC_aux_t *)cache_ptr->aux_ptr; int mpi_result; - if((NULL == aux_ptr) || (aux_ptr->mpi_rank == 0)) { - HDassert((NULL == aux_ptr) || (aux_ptr->magic == H5AC__H5AC_AUX_T_MAGIC)); + if ( ( NULL == aux_ptr ) || ( aux_ptr->mpi_rank == 0 ) ) { + + HDassert((NULL == aux_ptr) || + (aux_ptr->magic == H5AC__H5AC_AUX_T_MAGIC)); #endif /* H5_HAVE_PARALLEL */ /* Read the buffer (if serial access, or rank 0 of parallel access) */ - if(H5F_block_read(f, H5FD_MEM_SUPER, cache_ptr->image_addr, cache_ptr->image_len, dxpl_id, cache_ptr->image_buffer) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_READERROR, FAIL, "Can't read metadata cache image block") + if ( H5F_block_read(f, H5FD_MEM_SUPER, cache_ptr->image_addr, + cache_ptr->image_len, dxpl_id, + cache_ptr->image_buffer) < 0) + + HGOTO_ERROR(H5E_CACHE, H5E_READERROR, FAIL, \ + "Can't read metadata cache image block") + + H5C__UPDATE_STATS_FOR_CACHE_IMAGE_READ(cache_ptr) #ifdef H5_HAVE_PARALLEL - if(aux_ptr) { + if ( aux_ptr ) { + /* Broadcast cache image */ - if(MPI_SUCCESS != (mpi_result = MPI_Bcast(cache_ptr->image_buffer, (int)cache_ptr->image_len, MPI_BYTE, 0, aux_ptr->mpi_comm))) + if ( MPI_SUCCESS != + (mpi_result = MPI_Bcast(cache_ptr->image_buffer, + (int)cache_ptr->image_len, MPI_BYTE, + 0, aux_ptr->mpi_comm)) ) + HMPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_result) + } /* end if */ } /* end if */ - else if(aux_ptr) { + else if ( aux_ptr ) { + /* Retrieve the contents of the metadata cache image from process 0 */ - if(MPI_SUCCESS != (mpi_result = MPI_Bcast(cache_ptr->image_buffer, (int)cache_ptr->image_len, MPI_BYTE, 0, aux_ptr->mpi_comm))) - HMPI_GOTO_ERROR(FAIL, "can't receive cache image MPI_Bcast", mpi_result) + if ( MPI_SUCCESS != + (mpi_result = MPI_Bcast(cache_ptr->image_buffer, + (int)cache_ptr->image_len, MPI_BYTE, + 0, aux_ptr->mpi_comm)) ) + + HMPI_GOTO_ERROR(FAIL, "can't receive cache image MPI_Bcast", \ + mpi_result) } /* end else-if */ } /* end block */ #endif /* H5_HAVE_PARALLEL */ done: + FUNC_LEAVE_NOAPI(ret_value) + } /* H5C__read_cache_image() */ @@ -3203,26 +3225,31 @@ H5C__reconstruct_cache_contents(H5F_t *f, hid_t dxpl_id, H5C_t *cache_ptr) i = -1; entry_ptr = cache_ptr->LRU_head_ptr; + while(entry_ptr != NULL) { - HDassert(entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC); + + HDassert(entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC); HDassert(entry_ptr->type != NULL); - if(entry_ptr->prefetched) { - HDassert(i <= entry_ptr->lru_rank); - HDassert((entry_ptr->lru_rank <= 2) || - (entry_ptr->lru_rank == i + 1) || - (entry_ptr->lru_rank == i + 2)); + if ( entry_ptr->prefetched ) { - if((entry_ptr->lru_rank <= 2) && (entry_ptr->lru_rank == i + 2)) - lru_rank_holes++; + HDassert(entry_ptr->lru_rank != 0); + HDassert((entry_ptr->lru_rank == -1) || + (entry_ptr->lru_rank > i)); - i = entry_ptr->lru_rank; - } /* end if */ + if ( ( entry_ptr->lru_rank > 1 ) && + ( entry_ptr->lru_rank > i + 1 ) ) + + lru_rank_holes += entry_ptr->lru_rank - (i + 1); + + i = entry_ptr->lru_rank; + + } /* end if */ - entry_ptr = entry_ptr->next; + entry_ptr = entry_ptr->next; } /* end while */ - /* Holes of size 1 appear in the LRU ranking due to epoch + /* Holes in the sequences of LRU ranks can appear due to epoch * markers. They are left in to allow re-insertion of the * epoch markers on reconstruction of the cache -- thus * the following sanity check will have to be revised when diff --git a/src/H5Cmpio.c b/src/H5Cmpio.c index 06ce714..0d1a3ff 100644 --- a/src/H5Cmpio.c +++ b/src/H5Cmpio.c @@ -950,12 +950,15 @@ H5C__collective_write(H5F_t *f, hid_t dxpl_id) /* Get original transfer mode */ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list") + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, \ + "not a data transfer property list") + if(H5P_get(plist, H5D_XFER_IO_XFER_MODE_NAME, &orig_xfer_mode) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI-I/O property") /* Get number of entries in collective write list */ count = (int)H5SL_count(cache_ptr->coll_write_list); + if(count > 0) { H5FD_mpio_xfer_t xfer_mode = H5FD_MPIO_COLLECTIVE; H5SL_node_t *node; @@ -964,21 +967,34 @@ H5C__collective_write(H5F_t *f, hid_t dxpl_id) int i; if(H5P_set(plist, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI-I/O property") + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, \ + "can't set MPI-I/O property") /* Allocate arrays */ - if(NULL == (length_array = (int *)H5MM_malloc((size_t)count * sizeof(int)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for collective write table length array") - if(NULL == (buf_array = (MPI_Aint *)H5MM_malloc((size_t)count * sizeof(MPI_Aint)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for collective buf table length array") - if(NULL == (offset_array = (MPI_Aint *)H5MM_malloc((size_t)count * sizeof(MPI_Aint)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for collective offset table length array") + if ( NULL == (length_array = + (int *)H5MM_malloc((size_t)count * sizeof(int))) ) + + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, \ + "memory allocation failed for collective write table length array") + + if ( NULL == (buf_array = + (MPI_Aint *)H5MM_malloc((size_t)count * sizeof(MPI_Aint))) ) + + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, \ + "memory allocation failed for collective buf table length array") + + if(NULL == (offset_array = + (MPI_Aint *)H5MM_malloc((size_t)count * sizeof(MPI_Aint))) ) + + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, \ + "memory allocation failed for collective offset table length array") /* Fill arrays */ node = H5SL_first(cache_ptr->coll_write_list); HDassert(node); if(NULL == (entry_ptr = (H5C_cache_entry_t *)H5SL_item(node))) - HGOTO_ERROR(H5E_CACHE, H5E_NOTFOUND, FAIL, "can't retrieve skip list item") + HGOTO_ERROR(H5E_CACHE, H5E_NOTFOUND, FAIL, \ + "can't retrieve skip list item") /* Set up initial array position & buffer base address */ length_array[0] = (int)entry_ptr->size; @@ -989,8 +1005,10 @@ H5C__collective_write(H5F_t *f, hid_t dxpl_id) node = H5SL_next(node); i = 1; while(node) { + if(NULL == (entry_ptr = (H5C_cache_entry_t *)H5SL_item(node))) - HGOTO_ERROR(H5E_CACHE, H5E_NOTFOUND, FAIL, "can't retrieve skip list item") + HGOTO_ERROR(H5E_CACHE, H5E_NOTFOUND, FAIL, \ + "can't retrieve skip list item") /* Set up array position */ length_array[i] = (int)entry_ptr->size; @@ -1003,48 +1021,85 @@ H5C__collective_write(H5F_t *f, hid_t dxpl_id) } /* end while */ /* Create memory MPI type */ - if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed(count, length_array, buf_array, MPI_BYTE, &btype))) + if(MPI_SUCCESS != (mpi_code = + MPI_Type_create_hindexed(count, length_array, + buf_array, MPI_BYTE, + &btype))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code) + btype_created = TRUE; + if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&btype))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code) /* Create file MPI type */ - if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed(count, length_array, offset_array, MPI_BYTE, &ftype))) + if(MPI_SUCCESS != (mpi_code = + MPI_Type_create_hindexed(count, length_array, + offset_array, MPI_BYTE, + &ftype))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code) + ftype_created = TRUE; + if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&ftype))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code) /* Pass buf type, file type to the file driver */ if(H5FD_mpi_setup_collective(dxpl_id, &btype, &ftype) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI-I/O properties") + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, \ + "can't set MPI-I/O properties") /* Write data */ - if(H5F_block_write(f, H5FD_MEM_DEFAULT, (haddr_t)0, (size_t)1, dxpl_id, base_buf) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to write entries collectively") + if(H5F_block_write(f, H5FD_MEM_DEFAULT, (haddr_t)0, + (size_t)1, dxpl_id, base_buf) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \ + "unable to write entries collectively") + } /* end if */ else { MPI_Status mpi_stat; - MPI_File mpi_fh_p; + MPI_File *mpi_fh_p; MPI_File mpi_fh; + MPI_Info *info_p; + MPI_Info info; if(H5F_get_mpi_handle(f, (MPI_File **)&mpi_fh_p) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get mpi file handle") + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, \ + "can't get mpi file handle") + mpi_fh = *(MPI_File*)mpi_fh_p; - /* just to match up with the 1st MPI_File_set_view from H5FD_mpio_write() */ - if(MPI_SUCCESS != (mpi_code = MPI_File_set_view(mpi_fh, (MPI_Offset)0, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL))) + if (H5F_get_mpi_info(f, &info_p) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, \ + "can't get mpi file info") + + info = *info_p; + + /* just to match up with the 1st MPI_File_set_view from + * H5FD_mpio_write() + */ + if(MPI_SUCCESS != (mpi_code = + MPI_File_set_view(mpi_fh, (MPI_Offset)0, MPI_BYTE, + MPI_BYTE, "native", + info))) HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code) /* just to match up with MPI_File_write_at_all from H5FD_mpio_write() */ HDmemset(&mpi_stat, 0, sizeof(MPI_Status)); - if(MPI_SUCCESS != (mpi_code = MPI_File_write_at_all(mpi_fh, (MPI_Offset)0, NULL, 0, MPI_BYTE, &mpi_stat))) + if(MPI_SUCCESS != (mpi_code = + MPI_File_write_at_all(mpi_fh, (MPI_Offset)0, + NULL, 0, MPI_BYTE, &mpi_stat))) HMPI_GOTO_ERROR(FAIL, "MPI_File_write_at_all failed", mpi_code) - /* just to match up with the 2nd MPI_File_set_view (reset) in H5FD_mpio_write() */ - if(MPI_SUCCESS != (mpi_code = MPI_File_set_view(mpi_fh, (MPI_Offset)0, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL))) + /* just to match up with the 2nd MPI_File_set_view (reset) in + * H5FD_mpio_write() + */ + if(MPI_SUCCESS != (mpi_code = + MPI_File_set_view(mpi_fh, (MPI_Offset)0, MPI_BYTE, + MPI_BYTE, "native", + info))) HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code) + } /* end else */ done: @@ -1063,7 +1118,8 @@ done: if(orig_xfer_mode != H5FD_MPIO_COLLECTIVE) { HDassert(plist); if(H5P_set(plist, H5D_XFER_IO_XFER_MODE_NAME, &orig_xfer_mode) < 0) - HDONE_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI-I/O property") + HDONE_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, \ + "can't set MPI-I/O property") } /* end if */ FUNC_LEAVE_NOAPI(ret_value); diff --git a/src/H5Cpkg.h b/src/H5Cpkg.h index 69e8145..90a84c4 100644 --- a/src/H5Cpkg.h +++ b/src/H5Cpkg.h @@ -686,6 +686,13 @@ if ( ( ( ( (head_ptr) == NULL ) || ( (tail_ptr) == NULL ) ) && \ (cache_ptr)->images_created++; \ } +#define H5C__UPDATE_STATS_FOR_CACHE_IMAGE_READ(cache_ptr) \ +{ \ + /* make sure image len is still good */ \ + HDassert((cache_ptr)->image_len > 0); \ + (cache_ptr)->images_read++; \ +} + #define H5C__UPDATE_STATS_FOR_CACHE_IMAGE_LOAD(cache_ptr) \ { \ /* make sure image len is still good */ \ @@ -931,6 +938,7 @@ if ( ( ( ( (head_ptr) == NULL ) || ( (tail_ptr) == NULL ) ) && \ #define H5C__UPDATE_STATS_FOR_LRU_SCAN_RESTART(cache_ptr) #define H5C__UPDATE_STATS_FOR_INDEX_SCAN_RESTART(cache_ptr) #define H5C__UPDATE_STATS_FOR_CACHE_IMAGE_CREATE(cache_ptr) +#define H5C__UPDATE_STATS_FOR_CACHE_IMAGE_READ(cache_ptr) #define H5C__UPDATE_STATS_FOR_CACHE_IMAGE_LOAD(cache_ptr) #define H5C__UPDATE_STATS_FOR_PREFETCH(cache_ptr, dirty) #define H5C__UPDATE_STATS_FOR_PREFETCH_HIT(cache_ptr) @@ -4549,6 +4557,18 @@ typedef struct H5C_tag_info_t { * Further, since cache images are only created at file * close, this field should only be set at that time. * + * images_read: Integer field containing the number of cache images + * read from file. Note that reading an image is different + * from loading it -- reading the image means just that, + * while loading the image refers to decoding it and loading + * it into the metadata cache. + * + * In the serial case, image_read should always equal + * images_loaded. However, in the parallel case, the + * image should only be read by process 0. All other + * processes should receive the cache image via a broadcast + * from process 0. + * * images_loaded: Integer field containing the number of cache images * loaded since the last time statistics were reset. * @@ -4864,6 +4884,7 @@ struct H5C_t { /* Fields for tracking cache image operations */ int32_t images_created; + int32_t images_read; int32_t images_loaded; hsize_t last_image_size; diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h index bdfb23e..5c5a666 100644 --- a/src/H5Cprivate.h +++ b/src/H5Cprivate.h @@ -2340,9 +2340,12 @@ H5_DLL herr_t H5C_dump_cache_LRU(H5C_t *cache_ptr, const char *cache_name); H5_DLL hbool_t H5C_get_serialization_in_progress(const H5C_t *cache_ptr); H5_DLL hbool_t H5C_cache_is_clean(const H5C_t *cache_ptr, H5C_ring_t inner_ring); H5_DLL herr_t H5C_dump_cache_skip_list(H5C_t *cache_ptr, char *calling_fcn); +#ifdef H5_HAVE_PARALLEL +H5_DLL herr_t H5C_dump_coll_write_list(H5C_t * cache_ptr, char * calling_fcn); +#endif /* H5_HAVE_PARALLEL */ H5_DLL herr_t H5C_get_entry_ptr_from_addr(H5C_t *cache_ptr, haddr_t addr, void **entry_ptr_ptr); -H5_DLL herr_t H5C_flush_dependency_exists(H5C_t *cache_ptr, haddr_t parent_addr, +H5_DLL herr_t H5C_flush_dependency_exists(H5C_t *cache_ptr, haddr_t parent_addr, haddr_t child_addr, hbool_t *fd_exists_ptr); H5_DLL herr_t H5C_verify_entry_type(H5C_t *cache_ptr, haddr_t addr, const H5C_class_t *expected_type, hbool_t *in_cache_ptr, diff --git a/src/H5Ctag.c b/src/H5Ctag.c index a9bcca1..0170ce9 100644 --- a/src/H5Ctag.c +++ b/src/H5Ctag.c @@ -58,8 +58,18 @@ typedef struct { H5F_t * f; /* File pointer for evicting entry */ hid_t dxpl_id; /* DXPL for evicting entry */ - hbool_t evicted_entries_last_pass; /* Flag to indicate that an entry was evicted when iterating over cache */ - hbool_t pinned_entries_need_evicted; /* Flag to indicate that a pinned entry was attempted to be evicted */ + hbool_t evicted_entries_last_pass; /* Flag to indicate that an entry + * was evicted when iterating over + * cache + */ + hbool_t pinned_entries_need_evicted;/* Flag to indicate that a pinned + * entry was attempted to be evicted + */ + hbool_t skipped_pf_dirty_entries; /* Flag indicating that one or more + * entries marked prefetched_dirty + * were encountered and not + * evicted. + */ } H5C_tag_iter_evict_ctx_t; /* Typedef for tagged entry iterator callback context - expunge tag type metadata */ @@ -470,7 +480,9 @@ H5C__evict_tagged_entries_cb(H5C_cache_entry_t *entry, void *_ctx) if(H5C__flush_single_entry(ctx->f, ctx->dxpl_id, entry, H5C__FLUSH_INVALIDATE_FLAG | H5C__FLUSH_CLEAR_ONLY_FLAG | H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, H5_ITER_ERROR, "Entry eviction failed.") ctx->evicted_entries_last_pass = TRUE; - } /* end else */ + } else { + ctx->skipped_pf_dirty_entries = TRUE; + } done: FUNC_LEAVE_NOAPI(ret_value) @@ -516,6 +528,7 @@ H5C_evict_tagged_entries(H5F_t * f, hid_t dxpl_id, haddr_t tag, hbool_t match_gl /* Reset pinned/evicted tracking flags */ ctx.pinned_entries_need_evicted = FALSE; ctx.evicted_entries_last_pass = FALSE; + ctx.skipped_pf_dirty_entries = FALSE; /* Iterate through entries in the cache */ if(H5C__iter_tagged_entries(cache, tag, match_global, H5C__evict_tagged_entries_cb, &ctx) < 0) @@ -524,8 +537,32 @@ H5C_evict_tagged_entries(H5F_t * f, hid_t dxpl_id, haddr_t tag, hbool_t match_gl /* Keep doing this until we have stopped evicted entries */ } while(TRUE == ctx.evicted_entries_last_pass); - /* Fail if we have finished evicting entries and pinned entries still need evicted */ - if(ctx.pinned_entries_need_evicted) + /* In most cases, fail if we have finished evicting entries and pinned + * entries still need evicted + * + * However, things can get strange if the file was opened R/O and + * the file contains a cache image and the cache image contains dirty + * entries. + * + * Since the file was opened read only, dirty entries in the cache + * image were marked as clean when they were inserted into the metadata + * cache. This is necessary, as if they are marked dirty, the metadata + * cache will attempt to write them on file close, which is frowned + * upon when the file is opened R/O. + * + * On the other hand, such entries (marked prefetched_dirty) must not + * be evicted, as should the cache be asked to re-load them, the cache + * will attempt to read them from the file, and at best load an outdated + * version. + * + * To avoid this, H5C__evict_tagged_entries_cb has been modified to + * skip such entries. However, by doing so, it may prevent pinned + * entries from becoming unpinned. + * + * Thus we must ignore ctx.pinned_entries_need_evicted if + * ctx.skipped_pf_dirty_entries is TRUE. + */ + if((!ctx.skipped_pf_dirty_entries) && (ctx.pinned_entries_need_evicted)) HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Pinned entries still need evicted?!") done: diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index 7a646af..63e692f 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -6060,9 +6060,9 @@ H5D__chunk_stats(const H5D_t *dset, hbool_t headers) #endif if (headers) { - if (rdcc->nhits>0 || rdcc->nmisses>0) { - miss_rate = 100.0 * rdcc->nmisses / - (rdcc->nhits + rdcc->nmisses); + if (rdcc->stats.nhits>0 || rdcc->stats.nmisses>0) { + miss_rate = 100.0 * rdcc->stats.nmisses / + (rdcc->stats.nhits + rdcc->stats.nmisses); } else { miss_rate = 0.0; } @@ -6073,8 +6073,8 @@ H5D__chunk_stats(const H5D_t *dset, hbool_t headers) } fprintf(H5DEBUG(AC), " %-18s %8u %8u %7s %8d+%-9ld\n", - "raw data chunks", rdcc->nhits, rdcc->nmisses, ascii, - rdcc->ninits, (long)(rdcc->nflushes)-(long)(rdcc->ninits)); + "raw data chunks", rdcc->stats.nhits, rdcc->stats.nmisses, ascii, + rdcc->stats.ninits, (long)(rdcc->stats.nflushes)-(long)(rdcc->stats.ninits)); } done: diff --git a/src/H5Dearray.c b/src/H5Dearray.c index e9dbd0d..240afb7 100644 --- a/src/H5Dearray.c +++ b/src/H5Dearray.c @@ -1137,7 +1137,7 @@ H5D__earray_idx_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *uda H5VM_swizzle_coords(hsize_t, swizzled_coords, idx_info->layout->u.earray.unlim_dim); /* Calculate the index of this chunk */ - idx = H5VM_chunk_index(ndims, swizzled_coords, idx_info->layout->u.earray.swizzled_dim, idx_info->layout->u.earray.swizzled_down_chunks); + idx = H5VM_chunk_index(ndims, swizzled_coords, idx_info->layout->u.earray.swizzled_dim, idx_info->layout->u.earray.swizzled_max_down_chunks); } /* end if */ else { /* Calculate the index of this chunk */ @@ -1202,7 +1202,8 @@ H5D__earray_idx_resize(H5O_layout_chunk_t *layout) /* "Swizzle" constant dimensions for this dataset */ if(layout->u.earray.unlim_dim > 0) { - hsize_t swizzled_chunks[H5O_LAYOUT_NDIMS]; /* Swizzled form of # of chunks in each dimension */ + hsize_t swizzled_chunks[H5O_LAYOUT_NDIMS]; /* Swizzled form of # of chunks in each dimension */ + hsize_t swizzled_max_chunks[H5O_LAYOUT_NDIMS]; /* Swizzled form of max # of chunks in each dimension */ /* Get the swizzled chunk dimensions */ HDmemcpy(layout->u.earray.swizzled_dim, layout->dim, (layout->ndims - 1) * sizeof(layout->dim[0])); @@ -1215,6 +1216,14 @@ H5D__earray_idx_resize(H5O_layout_chunk_t *layout) /* Get the swizzled "down" sizes for each dimension */ if(H5VM_array_down((layout->ndims - 1), swizzled_chunks, layout->u.earray.swizzled_down_chunks) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't compute swizzled 'down' chunk size value") + + /* Get the swizzled max number of chunks in each dimension */ + HDmemcpy(swizzled_max_chunks, layout->max_chunks, (layout->ndims - 1) * sizeof(swizzled_max_chunks[0])); + H5VM_swizzle_coords(hsize_t, swizzled_max_chunks, layout->u.earray.unlim_dim); + + /* Get the swizzled max "down" sizes for each dimension */ + if(H5VM_array_down((layout->ndims - 1), swizzled_max_chunks, layout->u.earray.swizzled_max_down_chunks) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't compute swizzled 'down' chunk size value") } /* end if */ done: @@ -1414,7 +1423,7 @@ H5D__earray_idx_remove(const H5D_chk_idx_info_t *idx_info, H5D_chunk_common_ud_t H5VM_swizzle_coords(hsize_t, swizzled_coords, idx_info->layout->u.earray.unlim_dim); /* Calculate the index of this chunk */ - idx = H5VM_chunk_index(ndims, swizzled_coords, idx_info->layout->u.earray.swizzled_dim, idx_info->layout->u.earray.swizzled_down_chunks); + idx = H5VM_chunk_index(ndims, swizzled_coords, idx_info->layout->u.earray.swizzled_dim, idx_info->layout->u.earray.swizzled_max_down_chunks); } /* end if */ else { /* Calculate the index of this chunk */ diff --git a/src/H5FDmpi.c b/src/H5FDmpi.c index fdc4eca..bf4e03a 100644 --- a/src/H5FDmpi.c +++ b/src/H5FDmpi.c @@ -148,6 +148,45 @@ done: /*------------------------------------------------------------------------- + * Function: H5FD_get_mpi_info + * + * Purpose: Retrieves the file's mpi info + * + * Return: Success: SUCCEED + * + * Failure: Negative + * + * Programmer: John Mainzer + * 4/4/17 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_get_mpi_info(H5FD_t *file, void** mpi_info) +{ + const H5FD_class_mpi_t *cls; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + HDassert(file); + cls = (const H5FD_class_mpi_t *)(file->cls); + HDassert(cls); + HDassert(cls->get_mpi_info); /* All MPI drivers must implement this */ + + /* Dispatch to driver */ + if ((ret_value=(cls->get_mpi_info)(file, mpi_info)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, MPI_COMM_NULL, \ + "driver get_mpi_info request failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD_get_mpi_info() */ + + +/*------------------------------------------------------------------------- * Function: H5FD_mpi_MPIOff_to_haddr * * Purpose: Convert an MPI_Offset value to haddr_t. diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index a3a404f..9417d46 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -95,6 +95,7 @@ static herr_t H5FD_mpio_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); static int H5FD_mpio_mpi_rank(const H5FD_t *_file); static int H5FD_mpio_mpi_size(const H5FD_t *_file); static MPI_Comm H5FD_mpio_communicator(const H5FD_t *_file); +static herr_t H5FD_mpio_get_info(H5FD_t *_file, void** mpi_info); /* The MPIO file driver information */ static const H5FD_class_mpi_t H5FD_mpio_g = { @@ -134,7 +135,8 @@ static const H5FD_class_mpi_t H5FD_mpio_g = { }, /* End of superclass information */ H5FD_mpio_mpi_rank, /*get_rank */ H5FD_mpio_mpi_size, /*get_size */ - H5FD_mpio_communicator /*get_comm */ + H5FD_mpio_communicator, /*get_comm */ + H5FD_mpio_get_info /*get_info */ }; #ifdef H5FDmpio_DEBUG @@ -1308,6 +1310,39 @@ done: /*------------------------------------------------------------------------- + * Function: H5FD_mpio_get_info + * + * Purpose: Returns the file info of MPIO file driver. + * + * Returns: Non-negative if succeed or negative if fails. + * + * Programmer: John Mainzer + * April 4, 2017 + * + * Modifications: + * + *------------------------------------------------------------------------- +*/ +static herr_t +H5FD_mpio_get_info(H5FD_t *_file, void** mpi_info) +{ + H5FD_mpio_t *file = (H5FD_mpio_t *)_file; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + if(!mpi_info) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mpi info not valid") + + *mpi_info = &(file->info); + +done: + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5FD_mpio_get_info() */ + + +/*------------------------------------------------------------------------- * Function: H5FD_mpio_read * * Purpose: Reads SIZE bytes of data from FILE beginning at address ADDR diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index c64ec30..fb7c43c 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -53,6 +53,7 @@ typedef struct H5FD_class_mpi_t { int (*get_rank)(const H5FD_t *file); /* Get the MPI rank of a process */ int (*get_size)(const H5FD_t *file); /* Get the MPI size of a communicator */ MPI_Comm (*get_comm)(const H5FD_t *file); /* Get the communicator for a file */ + herr_t (*get_mpi_info)(H5FD_t *file, void** mpi_info); /* get MPI_Info for a file */ } H5FD_class_mpi_t; #endif @@ -202,6 +203,7 @@ H5_DLL herr_t H5FD_get_mpio_atomicity(H5FD_t *file, hbool_t *flag); H5_DLL int H5FD_mpi_get_rank(const H5FD_t *file); H5_DLL int H5FD_mpi_get_size(const H5FD_t *file); H5_DLL MPI_Comm H5FD_mpi_get_comm(const H5FD_t *_file); +H5_DLL herr_t H5FD_get_mpi_info(H5FD_t *file, void** file_info); #endif /* H5_HAVE_PARALLEL */ #endif /* !_H5FDprivate_H */ diff --git a/src/H5Fmpi.c b/src/H5Fmpi.c index 5434aa5..60593a8 100644 --- a/src/H5Fmpi.c +++ b/src/H5Fmpi.c @@ -356,5 +356,31 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_mpi_retrieve_comm */ +/*------------------------------------------------------------------------- + * Function: H5F_get_mpi_info + * + * Purpose: Retrieves MPI File info. + * + * Return: Success: The size (positive) + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_get_mpi_info(const H5F_t *f, MPI_Info **f_info) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(f && f->shared); + + /* Dispatch to driver */ + if ((ret_value = H5FD_get_mpi_info(f->shared->lf, (void **)f_info)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get mpi file info") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_mpi_info() */ #endif /* H5_HAVE_PARALLEL */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 886063a..8ef353a 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -852,6 +852,7 @@ H5_DLL int H5F_mpi_get_rank(const H5F_t *f); H5_DLL MPI_Comm H5F_mpi_get_comm(const H5F_t *f); H5_DLL int H5F_mpi_get_size(const H5F_t *f); H5_DLL herr_t H5F_mpi_retrieve_comm(hid_t loc_id, hid_t acspl_id, MPI_Comm *mpi_comm); +H5_DLL herr_t H5F_get_mpi_info(const H5F_t *f, MPI_Info **f_info); #endif /* H5_HAVE_PARALLEL */ /* External file cache routines */ @@ -2351,9 +2351,11 @@ H5L_delete_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, if(name == NULL) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") - /* Check for removing '.' */ + /* Check for non-existent (NULL) link. + * Note that this can also occur when attempting to remove '.' + */ if(lnk == NULL) - HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "can't delete self") + HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "callback link pointer is NULL (specified link may be '.' or not exist)") /* Remove the link from the group */ if(H5G_obj_remove(grp_loc->oloc, grp_loc->path->full_path_r, name, udata->dxpl_id) < 0) diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index f0fbe72..0a4ed74 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -584,6 +584,7 @@ typedef struct H5O_layout_chunk_earray_t { unsigned unlim_dim; /* Rank of unlimited dimension for dataset */ uint32_t swizzled_dim[H5O_LAYOUT_NDIMS]; /* swizzled chunk dimensions */ hsize_t swizzled_down_chunks[H5O_LAYOUT_NDIMS]; /* swizzled "down" size of number of chunks in each dimension */ + hsize_t swizzled_max_down_chunks[H5O_LAYOUT_NDIMS]; /* swizzled max "down" size of number of chunks in each dimension */ } H5O_layout_chunk_earray_t; typedef struct H5O_layout_chunk_bt2_t { @@ -25,15 +25,33 @@ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5MMprivate.h" /* Memory management */ -#include "H5PLprivate.h" /* Plugin */ +#include "H5PLpkg.h" /* Plugin */ #include "H5Zprivate.h" /* Filter pipeline */ /****************/ /* Local Macros */ /****************/ - -#define H5PL_MAX_PATH_NUM 16 +#ifdef H5_HAVE_WIN32_API +#define H5PL_EXPAND_ENV_VAR { \ + long bufCharCount; \ + char *tempbuf; \ + if(NULL == (tempbuf = (char *)H5MM_malloc(H5PL_EXPAND_BUFFER_SIZE))) \ + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for expanded path") \ + if((bufCharCount = ExpandEnvironmentStringsA(dl_path, tempbuf, H5PL_EXPAND_BUFFER_SIZE)) > H5PL_EXPAND_BUFFER_SIZE) { \ + tempbuf = (char *)H5MM_xfree(tempbuf); \ + HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "expanded path is too long") \ + } \ + if(bufCharCount == 0) { \ + tempbuf = (char *)H5MM_xfree(tempbuf); \ + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "failed to expand path") \ + } \ + dl_path = (char *)H5MM_xfree(dl_path); \ + dl_path = tempbuf; \ + } +#else +#define H5PL_EXPAND_ENV_VAR +#endif /* H5_HAVE_WIN32_API */ /****************************/ /* Macros for supporting @@ -479,7 +497,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5PLappend(char* plugin_path) +H5PLappend(const char *plugin_path) { herr_t ret_value = SUCCEED; /* Return value */ char *dl_path = NULL; @@ -489,36 +507,15 @@ H5PLappend(char* plugin_path) HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "too many directories in path for table") if(NULL == plugin_path) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "no path provided") - dl_path = H5MM_strdup(plugin_path); - if(NULL == dl_path) - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path") -#ifdef H5_HAVE_WIN32_API - else { /* Expand windows env var*/ - long bufCharCount; - char *tempbuf; - if(NULL == (tempbuf = (char *)H5MM_malloc(H5PL_EXPAND_BUFFER_SIZE))) - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for expanded path") - if((bufCharCount = ExpandEnvironmentStrings(dl_path, tempbuf, H5PL_EXPAND_BUFFER_SIZE)) > H5PL_EXPAND_BUFFER_SIZE) { - tempbuf = (char *)H5MM_xfree(tempbuf); - HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "expanded path is too long") - } - if(bufCharCount == 0) { - tempbuf = (char *)H5MM_xfree(tempbuf); - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "failed to expand path") - } - dl_path = (char *)H5MM_xfree(dl_path); - dl_path = H5MM_strdup(tempbuf); - tempbuf = (char *)H5MM_xfree(tempbuf); - } -#endif /* H5_HAVE_WIN32_API */ - if(NULL == (H5PL_path_table_g[H5PL_num_paths_g] = H5MM_strdup(dl_path))) + if(NULL == (dl_path = H5MM_strdup(plugin_path))) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path") + + H5PL_EXPAND_ENV_VAR + + H5PL_path_table_g[H5PL_num_paths_g] = dl_path; H5PL_num_paths_g++; done: - if(dl_path) - dl_path = (char *)H5MM_xfree(dl_path); - FUNC_LEAVE_API(ret_value) } /* end H5PLappend() */ @@ -533,7 +530,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5PLprepend(char* plugin_path) +H5PLprepend(const char *plugin_path) { herr_t ret_value = SUCCEED; /* Return value */ char *dl_path = NULL; @@ -544,44 +541,23 @@ H5PLprepend(char* plugin_path) HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "too many directories in path for table") if(NULL == plugin_path) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "no path provided") - dl_path = H5MM_strdup(plugin_path); - if(NULL == dl_path) + if(NULL == (dl_path = H5MM_strdup(plugin_path))) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path") -#ifdef H5_HAVE_WIN32_API - else { /* Expand windows env var*/ - long bufCharCount; - char *tempbuf; - if (NULL == (tempbuf = (char *)H5MM_malloc(H5PL_EXPAND_BUFFER_SIZE))) - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for expanded path") - if ((bufCharCount = ExpandEnvironmentStrings(dl_path, tempbuf, H5PL_EXPAND_BUFFER_SIZE)) > H5PL_EXPAND_BUFFER_SIZE) { - tempbuf = (char *)H5MM_xfree(tempbuf); - HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "expanded path is too long") - } - if (bufCharCount == 0) { - tempbuf = (char *)H5MM_xfree(tempbuf); - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "failed to expand path") - } - dl_path = (char *)H5MM_xfree(dl_path); - dl_path = H5MM_strdup(tempbuf); - tempbuf = (char *)H5MM_xfree(tempbuf); - } -#endif /* H5_HAVE_WIN32_API */ + + H5PL_EXPAND_ENV_VAR + for (plindex = (unsigned int)H5PL_num_paths_g; plindex > 0; plindex--) H5PL_path_table_g[plindex] = H5PL_path_table_g[plindex - 1]; - if (NULL == (H5PL_path_table_g[0] = H5MM_strdup(dl_path))) - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path") + H5PL_path_table_g[0] = dl_path; H5PL_num_paths_g++; done: - if (dl_path) - dl_path = (char *)H5MM_xfree(dl_path); - FUNC_LEAVE_API(ret_value) } /* end H5PLprepend() */ /*------------------------------------------------------------------------- - * Function: H5PLput + * Function: H5PLreplace * * Purpose: Replace the path at the specified index. * @@ -590,7 +566,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5PLput(char* plugin_path, unsigned int index) +H5PLreplace(const char *plugin_path, unsigned int index) { herr_t ret_value = SUCCEED; /* Return value */ char *dl_path = NULL; @@ -598,39 +574,20 @@ H5PLput(char* plugin_path, unsigned int index) FUNC_ENTER_API(FAIL) if(NULL == plugin_path) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "no path provided") - dl_path = H5MM_strdup(plugin_path); - if(NULL == dl_path) + if(index >= H5PL_MAX_PATH_NUM) + HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "index path out of bounds for table") + if(NULL == (dl_path = H5MM_strdup(plugin_path))) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path") -#ifdef H5_HAVE_WIN32_API - else { /* Expand windows env var*/ - long bufCharCount; - char *tempbuf; - if(NULL == (tempbuf = (char *)H5MM_malloc(H5PL_EXPAND_BUFFER_SIZE))) - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for expanded path") - if((bufCharCount = ExpandEnvironmentStrings(dl_path, tempbuf, H5PL_EXPAND_BUFFER_SIZE)) > H5PL_EXPAND_BUFFER_SIZE) { - tempbuf = (char *)H5MM_xfree(tempbuf); - HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "expanded path is too long") - } - if(bufCharCount == 0) { - tempbuf = (char *)H5MM_xfree(tempbuf); - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "failed to expand path") - } - dl_path = (char *)H5MM_xfree(dl_path); - dl_path = H5MM_strdup(tempbuf); - tempbuf = (char *)H5MM_xfree(tempbuf); - } -#endif /* H5_HAVE_WIN32_API */ + + H5PL_EXPAND_ENV_VAR + if(H5PL_path_table_g[index]) H5PL_path_table_g[index] = (char *)H5MM_xfree(H5PL_path_table_g[index]); - if(NULL == (H5PL_path_table_g[index] = H5MM_strdup(dl_path))) - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path") + H5PL_path_table_g[index] = dl_path; done: - if(dl_path) - dl_path = (char *)H5MM_xfree(dl_path); - FUNC_LEAVE_API(ret_value) -} /* end H5PLput() */ +} /* end H5PLreplace() */ /*------------------------------------------------------------------------- @@ -643,7 +600,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5PLinsert(char* plugin_path, unsigned int index) +H5PLinsert(const char *plugin_path, unsigned int index) { herr_t ret_value = SUCCEED; /* Return value */ char *dl_path = NULL; @@ -654,38 +611,19 @@ H5PLinsert(char* plugin_path, unsigned int index) HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "too many directories in path for table") if(NULL == plugin_path) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "no path provided") - dl_path = H5MM_strdup(plugin_path); - if(NULL == dl_path) + if(index >= H5PL_MAX_PATH_NUM) + HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "index path out of bounds for table") + if(NULL == (dl_path = H5MM_strdup(plugin_path))) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path") -#ifdef H5_HAVE_WIN32_API - else { /* Expand windows env var*/ - long bufCharCount; - char *tempbuf; - if(NULL == (tempbuf = (char *)H5MM_malloc(H5PL_EXPAND_BUFFER_SIZE))) - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for expanded path") - if((bufCharCount = ExpandEnvironmentStrings(dl_path, tempbuf, H5PL_EXPAND_BUFFER_SIZE)) > H5PL_EXPAND_BUFFER_SIZE) { - tempbuf = (char *)H5MM_xfree(tempbuf); - HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "expanded path is too long") - } - if(bufCharCount == 0) { - tempbuf = (char *)H5MM_xfree(tempbuf); - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "failed to expand path") - } - dl_path = (char *)H5MM_xfree(dl_path); - dl_path = H5MM_strdup(tempbuf); - tempbuf = (char *)H5MM_xfree(tempbuf); - } -#endif /* H5_HAVE_WIN32_API */ + + H5PL_EXPAND_ENV_VAR + for(plindex = (unsigned int)H5PL_num_paths_g; plindex > index; plindex--) H5PL_path_table_g[plindex] = H5PL_path_table_g[plindex - 1]; - if(NULL == (H5PL_path_table_g[index] = H5MM_strdup(dl_path))) - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path") + H5PL_path_table_g[index] = dl_path; H5PL_num_paths_g++; done: - if(dl_path) - dl_path = (char *)H5MM_xfree(dl_path); - FUNC_LEAVE_API(ret_value) } /* end H5PLinsert() */ @@ -703,25 +641,24 @@ herr_t H5PLremove(unsigned int index) { herr_t ret_value = SUCCEED; /* Return value */ - char *dl_path = NULL; unsigned int plindex; FUNC_ENTER_API(FAIL) + H5TRACE1("e", "Iu", index); if(H5PL_num_paths_g == 0) HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "no directories in table") - if(NULL == (dl_path = H5PL_path_table_g[index])) + if(index >= H5PL_MAX_PATH_NUM) + HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "index path out of bounds for table") + if(NULL == H5PL_path_table_g[index]) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "no directory path at index") + H5PL_path_table_g[index] = (char *)H5MM_xfree(H5PL_path_table_g[index]); + + H5PL_num_paths_g--; for(plindex = index; plindex < (unsigned int)H5PL_num_paths_g; plindex++) H5PL_path_table_g[plindex] = H5PL_path_table_g[plindex + 1]; - if(H5PL_path_table_g[plindex]) - dl_path = (char *)H5MM_xfree(dl_path); - H5PL_num_paths_g--; H5PL_path_table_g[H5PL_num_paths_g] = NULL; done: - if(dl_path) - dl_path = (char *)H5MM_xfree(dl_path); - FUNC_LEAVE_API(ret_value) } /* end H5PLremove() */ @@ -731,20 +668,43 @@ done: * * Purpose: Query the plugin path at the specified index. * - * Return: Non-NULL on success/NULL on failure + * Return: Success: The length of path. + * + * If `pathname' is non-NULL then write up to `size' bytes into that + * buffer and always return the length of the pathname. + * Otherwise `size' is ignored and the function does not store the pathname, + * just returning the number of characters required to store the pathname. + * If an error occurs then the buffer pointed to by `pathname' (NULL or non-NULL) + * is unchanged and the function returns a negative value. + * If a zero is returned for the name's length, then there is no pathname + * associated with the index. * *------------------------------------------------------------------------- */ -const char* -H5PLget(unsigned int index) +ssize_t +H5PLget(unsigned int index, char *pathname/*out*/, size_t size) { - char* ret_value = NULL; /* Return value */ + ssize_t ret_value = 0; /* Return value */ + ssize_t len = 0; /* Length of pathname */ + char *dl_path = NULL; - FUNC_ENTER_API(NULL) + FUNC_ENTER_API(FAIL) + H5TRACE3("Zs", "Iuxz", index, pathname, size); if(H5PL_num_paths_g == 0) - HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, NULL, "no directories in table") - if(NULL == (ret_value = H5PL_path_table_g[index])) - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, NULL, "no directory path at index") + HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "no directories in table") + if(index >= H5PL_MAX_PATH_NUM) + HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "index path out of bounds for table") + if(NULL == (dl_path = H5PL_path_table_g[index])) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "no directory path at index") + len = HDstrlen(dl_path); + if(pathname) { + HDstrncpy(pathname, dl_path, MIN((size_t)(len + 1), size)); + if((size_t)len >= size) + pathname[size - 1] = '\0'; + } /* end if */ + + /* Set return value */ + ret_value = len; done: FUNC_LEAVE_API(ret_value) @@ -794,31 +754,13 @@ H5PL__init_path_table(void) */ origin_dl_path = HDgetenv("HDF5_PLUGIN_PATH"); if(NULL == origin_dl_path) - dl_path = H5PL__env_strdup(H5PL_DEFAULT_PATH); + dl_path = H5MM_strdup(H5PL_DEFAULT_PATH); else - dl_path = H5PL__env_strdup(origin_dl_path); + dl_path = H5MM_strdup(origin_dl_path); if(NULL == dl_path) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path") -#ifdef H5_HAVE_WIN32_API - else { /* Expand windows env var*/ - long bufCharCount; - char *tempbuf; - if(NULL == (tempbuf = (char *)H5MM_malloc(H5PL_EXPAND_BUFFER_SIZE))) - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for expanded path") - if((bufCharCount = ExpandEnvironmentStrings(dl_path, tempbuf, H5PL_EXPAND_BUFFER_SIZE)) > H5PL_EXPAND_BUFFER_SIZE) { - tempbuf = (char *)H5MM_xfree(tempbuf); - HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "expanded path is too long") - } - if(bufCharCount == 0) { - tempbuf = (char *)H5MM_xfree(tempbuf); - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "failed to expand path") - } - dl_path = (char *)H5MM_xfree(dl_path); - dl_path = H5MM_strdup(tempbuf); - tempbuf = (char *)H5MM_xfree(tempbuf); - } -#endif /* H5_HAVE_WIN32_API */ + H5PL_EXPAND_ENV_VAR /* Put paths in the path table. They are separated by ":" */ dir = HDstrtok(dl_path, H5PL_PATH_SEPARATOR); @@ -826,7 +768,7 @@ H5PL__init_path_table(void) /* Check for too many directories in path */ if(H5PL_num_paths_g == H5PL_MAX_PATH_NUM) HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "too many directories in path for table") - if(NULL == (H5PL_path_table_g[H5PL_num_paths_g] = H5MM_strdup(dir))) + if(NULL == (H5PL_path_table_g[H5PL_num_paths_g] = H5PL__env_strdup(dir))) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path") H5PL_num_paths_g++; dir = HDstrtok(NULL, H5PL_PATH_SEPARATOR); diff --git a/src/H5PLpkg.h b/src/H5PLpkg.h new file mode 100644 index 0000000..5cf3096 --- /dev/null +++ b/src/H5PLpkg.h @@ -0,0 +1,50 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#if !(defined H5PL_FRIEND || defined H5PL_MODULE) +#error "Do not include this file outside the H5PL package!" +#endif + +#ifndef _H5PLpkg_H +#define _H5PLpkg_H + +/* Include private header file */ +#include "H5PLprivate.h" /* Filter functions */ + +/* Other private headers needed by this file */ + +/**************************/ +/* Package Private Macros */ +/**************************/ + +#define H5PL_MAX_PATH_NUM 16 + + +/****************************/ +/* Package Private Typedefs */ +/****************************/ + + +/*****************************/ +/* Package Private Variables */ +/*****************************/ + + +/******************************/ +/* Package Private Prototypes */ +/******************************/ + +#endif /* _H5PLpkg_H */ + diff --git a/src/H5PLpublic.h b/src/H5PLpublic.h index f3fe497..5e4dcae 100644 --- a/src/H5PLpublic.h +++ b/src/H5PLpublic.h @@ -44,12 +44,12 @@ extern "C" { /* plugin state */ H5_DLL herr_t H5PLset_loading_state(unsigned int plugin_type); H5_DLL herr_t H5PLget_loading_state(unsigned int* plugin_type/*out*/); -H5_DLL herr_t H5PLappend(char* plugin_path); -H5_DLL herr_t H5PLprepend(char* plugin_path); -H5_DLL herr_t H5PLput(char* plugin_path, unsigned int index); -H5_DLL herr_t H5PLinsert(char* plugin_path, unsigned int index); +H5_DLL herr_t H5PLappend(const char* plugin_path); +H5_DLL herr_t H5PLprepend(const char* plugin_path); +H5_DLL herr_t H5PLreplace(const char* plugin_path, unsigned int index); +H5_DLL herr_t H5PLinsert(const char* plugin_path, unsigned int index); H5_DLL herr_t H5PLremove(unsigned int index); -H5_DLL const char* H5PLget(unsigned int index); +H5_DLL ssize_t H5PLget(unsigned int index, char *pathname/*out*/, size_t size); H5_DLL unsigned int H5PLsize(void); #ifdef __cplusplus diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index 7865fdf..e47a4b0 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -4381,7 +4381,19 @@ H5P_facc_mdc_log_location_close(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_ *------------------------------------------------------------------------- */ herr_t -H5Pset_evict_on_close(hid_t fapl_id, hbool_t evict_on_close) +H5Pset_evict_on_close( +#if defined(H5_HAVE_PARALLEL) && !defined(H5_DEBUG_BUILD) + hid_t H5_ATTR_UNUSED fapl_id, +#else + hid_t fapl_id, +#endif /* H5_HAVE_PARALLEL and !H5_DEBUG_BUILD */ + +#ifdef H5_HAVE_PARALLEL + hbool_t H5_ATTR_UNUSED evict_on_close +#else + hbool_t evict_on_close +#endif /* H5_HAVE_PARALLEL */ +) { H5P_genplist_t *plist; /* property list pointer */ herr_t ret_value = SUCCEED; /* return value */ @@ -4397,9 +4409,13 @@ H5Pset_evict_on_close(hid_t fapl_id, hbool_t evict_on_close) if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - /* Set values */ +#ifndef H5_HAVE_PARALLEL + /* Set value */ if(H5P_set(plist, H5F_ACS_EVICT_ON_CLOSE_FLAG_NAME, &evict_on_close) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set evict on close property") +#else + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "evict on close is currently not supported in parallel HDF5") +#endif /* H5_HAVE_PARALLEL */ done: FUNC_LEAVE_API(ret_value) |