summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAllen Byrne <byrn@hdfgroup.org>2017-04-21 15:41:50 (GMT)
committerAllen Byrne <byrn@hdfgroup.org>2017-04-21 15:41:50 (GMT)
commitaeb1500897862ab8e0c500bd0a6986d229c4e5f2 (patch)
tree422757fe6b1a946a69c3d47b1a6ba4c8fc7dafba /src
parentae1144f8826dcecc68ec923bb7261f2a8153735c (diff)
parent3968c5c3bf16dc23a0a2ff1fa8d6c64dd2f8d32a (diff)
downloadhdf5-aeb1500897862ab8e0c500bd0a6986d229c4e5f2.zip
hdf5-aeb1500897862ab8e0c500bd0a6986d229c4e5f2.tar.gz
hdf5-aeb1500897862ab8e0c500bd0a6986d229c4e5f2.tar.bz2
Merge remote-tracking branch 'origin/develop' into
bugfix/HDFFV-9655-plugin-path-relative
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/H5ACpublic.h236
-rw-r--r--src/H5Cdbg.c111
-rw-r--r--src/H5Cimage.c73
-rw-r--r--src/H5Cmpio.c102
-rw-r--r--src/H5Cpkg.h21
-rw-r--r--src/H5Cprivate.h5
-rw-r--r--src/H5Ctag.c47
-rw-r--r--src/H5Dchunk.c10
-rw-r--r--src/H5Dearray.c15
-rw-r--r--src/H5FDmpi.c39
-rw-r--r--src/H5FDmpio.c37
-rw-r--r--src/H5FDprivate.h2
-rw-r--r--src/H5Fmpi.c26
-rw-r--r--src/H5Fprivate.h1
-rw-r--r--src/H5L.c6
-rw-r--r--src/H5Oprivate.h1
-rw-r--r--src/H5PL.c244
-rw-r--r--src/H5PLpkg.h50
-rw-r--r--src/H5PLpublic.h10
-rw-r--r--src/H5Pfapl.c20
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 */
diff --git a/src/H5L.c b/src/H5L.c
index b5c6240..ecdf8a2 100644
--- a/src/H5L.c
+++ b/src/H5L.c
@@ -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 {
diff --git a/src/H5PL.c b/src/H5PL.c
index 0cdbc93..bca680e 100644
--- a/src/H5PL.c
+++ b/src/H5PL.c
@@ -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)