summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@lbl.gov>2016-11-25 22:07:23 (GMT)
committerQuincey Koziol <koziol@lbl.gov>2016-11-25 22:07:23 (GMT)
commit1071d8bf73bc9f069b9d939d882aa27e2334f94a (patch)
treeab2ad7c29fc31a6385a622226ac98b973be1ad7a
parentfff898558e3c828070abe81b4147bd959ed37ccb (diff)
downloadhdf5-1071d8bf73bc9f069b9d939d882aa27e2334f94a.zip
hdf5-1071d8bf73bc9f069b9d939d882aa27e2334f94a.tar.gz
hdf5-1071d8bf73bc9f069b9d939d882aa27e2334f94a.tar.bz2
Add a flag for H5C__flush_single_entry() to allow the parallel code to request
that images for entries be generated, even when not writing the entry from an MPI rank.
-rw-r--r--src/H5C.c58
-rw-r--r--src/H5Cmpio.c42
-rw-r--r--src/H5Cprivate.h2
3 files changed, 65 insertions, 37 deletions
diff --git a/src/H5C.c b/src/H5C.c
index 147489b..31f887d 100644
--- a/src/H5C.c
+++ b/src/H5C.c
@@ -5739,6 +5739,7 @@ H5C__flush_single_entry(const H5F_t *f, hid_t dxpl_id, H5C_cache_entry_t *entry_
hbool_t during_flush; /* external flag */
hbool_t write_entry; /* internal flag */
hbool_t destroy_entry; /* internal flag */
+ hbool_t generate_image; /* internal flag */
hbool_t was_dirty;
haddr_t entry_addr = HADDR_UNDEF;
herr_t ret_value = SUCCEED; /* Return value */
@@ -5759,6 +5760,7 @@ H5C__flush_single_entry(const H5F_t *f, hid_t dxpl_id, H5C_cache_entry_t *entry_
take_ownership = ((flags & H5C__TAKE_OWNERSHIP_FLAG) != 0);
del_from_slist_on_destroy = ((flags & H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG) != 0);
during_flush = ((flags & H5C__DURING_FLUSH_FLAG) != 0);
+ generate_image = ((flags & H5C__GENERATE_IMAGE_FLAG) != 0);
/* Set the flag for destroying the entry, based on the 'take ownership'
* and 'destroy' flags
@@ -5818,29 +5820,13 @@ H5C__flush_single_entry(const H5F_t *f, hid_t dxpl_id, H5C_cache_entry_t *entry_
entry_ptr->flush_in_progress = TRUE;
entry_ptr->flush_marker = FALSE;
- /* serialize the entry if necessary, and then write it to disk. */
- if(write_entry) {
-
- /* The entry is dirty, and we are doing either a flush,
- * or a flush destroy. In either case, serialize the
- * entry and write it to disk.
- *
- * Note that this may cause the entry to be re-sized and/or
- * moved in the cache.
- *
- * As we will not update the metadata cache's data structures
- * until we we finish the write, we must touch up these
- * data structures for size and location changes even if we
- * are about to delete the entry from the cache (i.e. on a
- * flush destroy).
- */
+ /* The entry is dirty, and we are doing a flush, a flush destroy or have
+ * been requested to generate an image. In those cases, serialize the
+ * entry.
+ */
+ if(write_entry || generate_image) {
HDassert(entry_ptr->is_dirty);
-#if H5C_DO_SANITY_CHECKS
- if(cache_ptr->check_write_permitted && !(cache_ptr->write_permitted))
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Write when writes are always forbidden!?!?!")
-#endif /* H5C_DO_SANITY_CHECKS */
-
if(NULL == entry_ptr->image_ptr) {
if(NULL == (entry_ptr->image_ptr = H5MM_malloc(entry_ptr->size + H5C_IMAGE_EXTRA_SPACE)))
HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "memory allocation failed for on disk image buffer")
@@ -5854,13 +5840,22 @@ H5C__flush_single_entry(const H5F_t *f, hid_t dxpl_id, H5C_cache_entry_t *entry_
if(H5C__generate_image(f, cache_ptr, entry_ptr, dxpl_id) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, FAIL, "can't generate entry's image")
} /* end if ( ! (entry_ptr->image_up_to_date) ) */
+ } /* end if */
+
+ /* Finally, write the image to disk.
+ *
+ * Note that if the H5AC__CLASS_SKIP_WRITES flag is set in the
+ * in the entry's type, we silently skip the write. This
+ * flag should only be used in test code.
+ */
+ if(write_entry) {
+ HDassert(entry_ptr->is_dirty);
+
+#if H5C_DO_SANITY_CHECKS
+ if(cache_ptr->check_write_permitted && !(cache_ptr->write_permitted))
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Write when writes are always forbidden!?!?!")
+#endif /* H5C_DO_SANITY_CHECKS */
- /* Finally, write the image to disk.
- *
- * Note that if the H5AC__CLASS_SKIP_WRITES flag is set in the
- * in the entry's type, we silently skip the write. This
- * flag should only be used in test code.
- */
if(((entry_ptr->type->flags) & H5C__CLASS_SKIP_WRITES) == 0) {
#ifdef H5_HAVE_PARALLEL
if(collective_write_list) {
@@ -7600,6 +7595,15 @@ H5C__assert_flush_dep_nocycle(const H5C_cache_entry_t * entry,
*
* Purpose: Serialize an entry and generate its image.
*
+ * Note: This may cause the entry to be re-sized and/or moved in
+ * the cache.
+ *
+ * As we will not update the metadata cache's data structures
+ * until we we finish the write, we must touch up these
+ * data structures for size and location changes even if we
+ * are about to delete the entry from the cache (i.e. on a
+ * flush destroy).
+ *
* Return: Non-negative on success/Negative on failure
*
* Programmer: Mohamad Chaarawi
diff --git a/src/H5Cmpio.c b/src/H5Cmpio.c
index 8a28f88..72de4d0 100644
--- a/src/H5Cmpio.c
+++ b/src/H5Cmpio.c
@@ -454,13 +454,37 @@ H5C_apply_candidate_list(H5F_t * f,
(long long)clear_ptr->addr);
#endif /* H5C_APPLY_CANDIDATE_LIST__DEBUG */
- /* No need to check for the next entry in the scan being
- * removed from the cache, as this call to H5C__flush_single_entry()
- * will not call either the pre_serialize or serialize callbacks.
+ /* reset entries_removed_counter and
+ * last_entry_removed_ptr prior to the call to
+ * H5C__flush_single_entry() so that we can spot
+ * unexpected removals of entries from the cache,
+ * and set the restart_scan flag if proceeding
+ * would be likely to cause us to scan an entry
+ * that is no longer in the cache.
+ *
+ * Note that as of this writing (April 2015) this
+ * case cannot occur in the parallel case. However
+ * Quincey is making noises about changing this, hence
+ * the insertion of this test.
+ *
+ * Note also that there is no test code to verify
+ * that this code actually works (although similar code
+ * in the serial version exists and is tested).
+ *
+ * Implementing a test will likely require implementing
+ * flush op like facilities in the parallel tests. At
+ * a guess this will not be terribly painful, but it
+ * will take a bit of time.
*/
+ cache_ptr->entries_removed_counter = 0;
+ cache_ptr->last_entry_removed_ptr = NULL;
- if(H5C__flush_single_entry(f, dxpl_id, clear_ptr, H5C__FLUSH_CLEAR_ONLY_FLAG | H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG, NULL) < 0)
+ if(H5C__flush_single_entry(f, dxpl_id, clear_ptr, H5C__FLUSH_CLEAR_ONLY_FLAG | H5C__GENERATE_IMAGE_FLAG | H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG, NULL) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't clear entry.")
+
+ if((cache_ptr->entries_removed_counter > 1) ||
+ (cache_ptr->last_entry_removed_ptr == entry_ptr))
+ restart_scan = TRUE;
} /* end if */
/* Else, if this process needs to flush this entry. */
@@ -508,11 +532,9 @@ H5C_apply_candidate_list(H5F_t * f,
if(H5C__flush_single_entry(f, dxpl_id, flush_ptr, H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG, collective_write_list) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush entry.")
- if ( ( cache_ptr->entries_removed_counter > 1 ) ||
- ( cache_ptr->last_entry_removed_ptr == entry_ptr ) )
-
+ if((cache_ptr->entries_removed_counter > 1) ||
+ (cache_ptr->last_entry_removed_ptr == entry_ptr))
restart_scan = TRUE;
-
} /* end else-if */
/* Otherwise, no action to be taken on this entry. Grab the next. */
@@ -663,7 +685,7 @@ H5C_apply_candidate_list(H5F_t * f,
(long long)clear_ptr->addr);
#endif /* H5C_APPLY_CANDIDATE_LIST__DEBUG */
- if(H5C__flush_single_entry(f, dxpl_id, clear_ptr, H5C__FLUSH_CLEAR_ONLY_FLAG | H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG, NULL) < 0)
+ if(H5C__flush_single_entry(f, dxpl_id, clear_ptr, H5C__FLUSH_CLEAR_ONLY_FLAG | H5C__GENERATE_IMAGE_FLAG | H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG, NULL) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't clear entry.")
} /* end else-if */
@@ -714,7 +736,7 @@ H5C_apply_candidate_list(H5F_t * f,
if (delayed_ptr) {
if (delayed_ptr->clear_on_unprotect) {
- if(H5C__flush_single_entry(f, dxpl_id, delayed_ptr, H5C__FLUSH_CLEAR_ONLY_FLAG, NULL) < 0)
+ if(H5C__flush_single_entry(f, dxpl_id, delayed_ptr, H5C__FLUSH_CLEAR_ONLY_FLAG | H5C__GENERATE_IMAGE_FLAG, NULL) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush entry.")
entry_ptr->clear_on_unprotect = FALSE;
diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h
index c03e2e7..923083f 100644
--- a/src/H5Cprivate.h
+++ b/src/H5Cprivate.h
@@ -183,6 +183,7 @@
* H5C__FLUSH_MARKED_ENTRIES_FLAG
* H5C__TAKE_OWNERSHIP_FLAG
* H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG
+ * H5C__GENERATE_IMAGE_FLAG
*/
#define H5C__NO_FLAGS_SET 0x00000
#define H5C__SET_FLUSH_MARKER_FLAG 0x00001
@@ -202,6 +203,7 @@
#define H5C__EVICT_ALLOW_LAST_PINS_FLAG 0x04000
#define H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG 0x08000
#define H5C__DURING_FLUSH_FLAG 0x10000 /* Set when the entire cache is being flushed */
+#define H5C__GENERATE_IMAGE_FLAG 0x20000 /* Set during parallel I/O */
/* Debugging/sanity checking/statistics settings */
#ifndef NDEBUG