summaryrefslogtreecommitdiffstats
path: root/src/H5Ocache.c
diff options
context:
space:
mode:
authorJohn Mainzer <mainzer@hdfgroup.org>2010-10-17 15:13:24 (GMT)
committerJohn Mainzer <mainzer@hdfgroup.org>2010-10-17 15:13:24 (GMT)
commitf527b1a512ea4b571e22e9efee054d4781afcbc0 (patch)
tree7d68e54480e6012bd4df777baf650a544e32cead /src/H5Ocache.c
parentc002883bcc008a4274433ed8e8275669c09dcfe6 (diff)
downloadhdf5-f527b1a512ea4b571e22e9efee054d4781afcbc0.zip
hdf5-f527b1a512ea4b571e22e9efee054d4781afcbc0.tar.gz
hdf5-f527b1a512ea4b571e22e9efee054d4781afcbc0.tar.bz2
[svn-r19622] Port of fix for the round robin parallel flush bug caused by the failure
of the H5Ocache.c code to update its image of the on disk representation of the object header on a call to the clear callback. This wasn't an issue as long as all flushes of the object header were made from the same process, but if an object header is modified, and then flushed on one process and cleared on the rest, the changes were not be reflected in the images of the on disk representation on all processes where the object header was cleared rather than flushed. If one of these processes did the next flush, the changes were lost in the on disk representation. Fixed this by causing all dirty messages and to be written to the copy of the on disk image maintained by the object header code on both flush and clear. Also added associated test code in t_mdset.c. Also checking in some cache debug code developed while chasing this bug. Commit tested and tested (parallel) on phoenix.
Diffstat (limited to 'src/H5Ocache.c')
-rw-r--r--src/H5Ocache.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/H5Ocache.c b/src/H5Ocache.c
index 9e909a6..e64262b 100644
--- a/src/H5Ocache.c
+++ b/src/H5Ocache.c
@@ -560,6 +560,21 @@ done:
* koziol@ncsa.uiuc.edu
* Mar 20 2003
*
+ * Changes: In the parallel case, there is the possibility that the
+ * the object header may be flushed by different processes
+ * over the life of the computation. Thus we must ensure
+ * that the chunk images are up to date before we mark the
+ * messages clean -- as otherwise we may overwrite valid
+ * data with a blank section of a chunk image.
+ *
+ * To deal with this, I have added code to call
+ * H5O_chunk_serialize() for all chunks before we
+ * mark all messages as clean if we are not destroying the
+ * object. Do this in the parallel case only, as the problem
+ * can only occur in this context.
+ *
+ * JRM -- 10/12/10
+ *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -573,6 +588,30 @@ H5O_clear(H5F_t *f, H5O_t *oh, hbool_t destroy)
/* check args */
HDassert(oh);
+#ifdef H5_HAVE_PARALLEL
+ if ( ( oh->cache_info.is_dirty ) && ( ! destroy ) ) {
+
+ size_t i;
+
+ /* scan through all chunks associated with the object header,
+ * and cause them to update their images for all entries currently
+ * marked dirty. Must do this in the parallel case, as it is possible
+ * that this processor may clear this object header several times
+ * before flushing it -- thus causing undefined sections of the image
+ * to be written to disk overwriting valid data.
+ */
+
+ for ( i = 0; i < oh->nchunks; i++ ) {
+
+ if ( H5O_chunk_serialize(f, oh, i) < 0 ) {
+
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTSERIALIZE, FAIL,
+ "unable to serialize object header chunk")
+ }
+ }
+ }
+#endif /* H5_HAVE_PARALLEL */
+
/* Mark messages as clean */
for(u = 0; u < oh->nmesgs; u++)
oh->mesg[u].dirty = FALSE;
@@ -830,6 +869,30 @@ done:
* koziol@hdfgroup.org
* July 12, 2008
*
+ * Changes: In the parallel case, there is the possibility that the
+ * the object header chunk may be flushed by different
+ * processes over the life of the computation. Thus we must
+ * ensure that the chunk image is up to date before we mark its
+ * messages clean -- as otherwise we may overwrite valid
+ * data with a blank section of a chunk image.
+ *
+ * To deal with this, I have added code to call
+ * H5O_chunk_serialize() for this chunk before we
+ * mark all messages as clean if we are not destroying the
+ * chunk.
+ *
+ * Do this in the parallel case only, as the problem
+ * can only occur in this context.
+ *
+ * Note that at present at least, it seems that this fix
+ * is not necessary, as we don't seem to be able to
+ * generate a dirty chunk without creating a dirty object
+ * header. However, the object header code will be changing
+ * a lot in the near future, so I'll leave this fix in
+ * for now, unless Quincey requests otherwise.
+ *
+ * JRM -- 10/12/10
+ *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -843,6 +906,17 @@ H5O_cache_chk_clear(H5F_t *f, H5O_chunk_proxy_t *chk_proxy, hbool_t destroy)
/* check args */
HDassert(chk_proxy);
+#ifdef H5_HAVE_PARALLEL
+ if ( ( chk_proxy->oh->cache_info.is_dirty ) && ( ! destroy ) ) {
+
+ if ( H5O_chunk_serialize(f, chk_proxy->oh, chk_proxy->chunkno) < 0 ) {
+
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTSERIALIZE, FAIL,
+ "unable to serialize object header chunk")
+ }
+ }
+#endif /* H5_HAVE_PARALLEL */
+
/* Mark messages in chunk as clean */
for(u = 0; u < chk_proxy->oh->nmesgs; u++)
if(chk_proxy->oh->mesg[u].chunkno == chk_proxy->chunkno)