summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2009-03-24 19:23:11 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2009-03-24 19:23:11 (GMT)
commit53e4b5b90b3f5cb9dc7fbe47e6787a5280b2fa04 (patch)
tree825d37444aa8c0f3bab4442c3f1b0068c7ac2924 /src
parent65dc3358db37b04cc64b65b88065cbaf48e63a8b (diff)
downloadhdf5-53e4b5b90b3f5cb9dc7fbe47e6787a5280b2fa04.zip
hdf5-53e4b5b90b3f5cb9dc7fbe47e6787a5280b2fa04.tar.gz
hdf5-53e4b5b90b3f5cb9dc7fbe47e6787a5280b2fa04.tar.bz2
[svn-r16601] Description:
Bring r16536:16600 from trunk back into revise_chunks branch Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (jam) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (smirom) w/Intel compilers w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in production mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode Mac OS X/32 10.5.6 (amazon) in debug mode Mac OS X/32 10.5.6 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode
Diffstat (limited to 'src')
-rw-r--r--src/H5AC.c4
-rw-r--r--src/H5Aint.c2
-rw-r--r--src/H5B.c44
-rw-r--r--src/H5Bprivate.h4
-rw-r--r--src/H5C.c1384
-rw-r--r--src/H5Cprivate.h22
-rw-r--r--src/H5D.c3
-rw-r--r--src/H5Dio.c10
-rw-r--r--src/H5Dmpio.c29
-rw-r--r--src/H5Edefin.h2
-rw-r--r--src/H5Einit.h10
-rw-r--r--src/H5Epubgen.h4
-rw-r--r--src/H5Eterm.h4
-rw-r--r--src/H5F.c3
-rw-r--r--src/H5FDdirect.c5
-rw-r--r--src/H5FDmpio.c2
-rw-r--r--src/H5FDmpiposix.c2
-rw-r--r--src/H5FDstdio.c2
-rw-r--r--src/H5FDwindows.c2
-rw-r--r--src/H5FLprivate.h16
-rw-r--r--src/H5Fdbg.c35
-rw-r--r--src/H5Fpkg.h3
-rw-r--r--src/H5Fsuper.c3
-rw-r--r--src/H5G.c18
-rw-r--r--src/H5Gdense.c3
-rw-r--r--src/H5Gloc.c12
-rw-r--r--src/H5Gname.c2
-rw-r--r--src/H5Gnode.c4
-rw-r--r--src/H5Gobj.c40
-rw-r--r--src/H5Gpkg.h8
-rw-r--r--src/H5Gprivate.h3
-rw-r--r--src/H5Gstab.c75
-rw-r--r--src/H5HFbtree2.c9
-rw-r--r--src/H5HFhuge.c14
-rw-r--r--src/H5HFsection.c17
-rw-r--r--src/H5HGdbg.c2
-rw-r--r--src/H5Oainfo.c4
-rw-r--r--src/H5Odtype.c63
-rw-r--r--src/H5Omessage.c2
-rw-r--r--src/H5Oprivate.h1
-rw-r--r--src/H5RC.c16
-rw-r--r--src/H5RS.c106
-rw-r--r--src/H5ST.c169
-rw-r--r--src/H5Smpio.c336
-rw-r--r--src/H5Z.c14
-rw-r--r--src/H5err.txt2
-rw-r--r--src/H5private.h5
-rw-r--r--src/H5public.h4
-rw-r--r--src/Makefile.in8
49 files changed, 1570 insertions, 962 deletions
diff --git a/src/H5AC.c b/src/H5AC.c
index 950615a..ccdd493 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -2288,10 +2288,10 @@ H5AC_unprotect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr,
{
herr_t result;
herr_t ret_value=SUCCEED; /* Return value */
- hbool_t size_changed = FALSE;
hbool_t dirtied;
size_t new_size = 0;
#ifdef H5_HAVE_PARALLEL
+ hbool_t size_changed = FALSE;
H5AC_aux_t * aux_ptr = NULL;
#endif /* H5_HAVE_PARALLEL */
#if H5AC__TRACE_FILE_ENABLED
@@ -2345,7 +2345,9 @@ H5AC_unprotect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr,
if ( ((H5AC_info_t *)thing)->size != new_size ) {
+#ifdef H5_HAVE_PARALLEL
size_changed = TRUE;
+#endif /* H5_HAVE_PARALLEL */
flags = flags | H5AC__SIZE_CHANGED_FLAG;
#if H5AC__TRACE_FILE_ENABLED
trace_flags = flags;
diff --git a/src/H5Aint.c b/src/H5Aint.c
index c7013a2..2ac17fa 100644
--- a/src/H5Aint.c
+++ b/src/H5Aint.c
@@ -716,7 +716,7 @@ H5A_get_ainfo(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_ainfo_t *ainfo)
/* Retrieve # of records in "name" B-tree */
/* (should be same # of records in all indices) */
if(H5B2_get_nrec(f, dxpl_id, H5A_BT2_NAME, ainfo->name_bt2_addr, &ainfo->nattrs) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, NULL, "can't retrieve # of records in index")
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve # of records in index")
} /* end if */
else
/* Retrieve # of attributes from object header */
diff --git a/src/H5B.c b/src/H5B.c
index d5ac87a..254183f 100644
--- a/src/H5B.c
+++ b/src/H5B.c
@@ -2057,3 +2057,47 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B_get_info() */
+#ifndef H5_STRICT_FORMAT_CHECKS
+
+/*-------------------------------------------------------------------------
+ * Function: H5B_valid
+ *
+ * Purpose: Attempt to load a b-tree node.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * March 17, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5B_valid(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr)
+{
+ H5B_t *bt; /* The btree */
+ htri_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5B_valid, FAIL)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(type);
+
+ if(!H5F_addr_defined(addr))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "address is undefined")
+
+ /* Protect the node */
+ if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree node")
+
+ /* Release the node */
+ if(H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree node")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5B_valid() */
+#endif /* H5_STRICT_FORMAT_CHECKS */
+
diff --git a/src/H5Bprivate.h b/src/H5Bprivate.h
index 93c2d80..2ec2c22 100644
--- a/src/H5Bprivate.h
+++ b/src/H5Bprivate.h
@@ -168,5 +168,9 @@ H5_DLL H5B_shared_t *H5B_shared_new(const H5F_t *f, const H5B_class_t *type,
H5_DLL herr_t H5B_shared_free(void *_shared);
H5_DLL herr_t H5B_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream,
int indent, int fwidth, const H5B_class_t *type, void *udata);
+#ifndef H5_STRICT_FORMAT_CHECKS
+H5_DLL htri_t H5B_valid(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type,
+ haddr_t addr);
+#endif /* H5_STRICT_FORMAT_CHECKS */
#endif /* _H5Bprivate_H */
diff --git a/src/H5C.c b/src/H5C.c
index 7d2d4ea..27b98d0 100644
--- a/src/H5C.c
+++ b/src/H5C.c
@@ -3147,6 +3147,10 @@ H5C_create(size_t max_cache_size,
cache_ptr->epoch_marker_ringbuf_last = 0;
cache_ptr->epoch_marker_ringbuf_size = 0;
+ /* Initialize all epoch marker entries' fields to zero/FALSE/NULL */
+ HDmemset(cache_ptr->epoch_markers, 0, sizeof(cache_ptr->epoch_markers));
+
+ /* Set non-zero/FALSE/NULL fields for epoch markers */
for ( i = 0; i < H5C__MAX_EPOCH_MARKERS; i++ )
{
(cache_ptr->epoch_marker_active)[i] = FALSE;
@@ -3155,27 +3159,7 @@ H5C_create(size_t max_cache_size,
H5C__H5C_CACHE_ENTRY_T_MAGIC;
#endif /* NDEBUG */
((cache_ptr->epoch_markers)[i]).addr = (haddr_t)i;
- ((cache_ptr->epoch_markers)[i]).size = (size_t)0;
((cache_ptr->epoch_markers)[i]).type = &epoch_marker_class;
- ((cache_ptr->epoch_markers)[i]).is_dirty = FALSE;
- ((cache_ptr->epoch_markers)[i]).dirtied = FALSE;
- ((cache_ptr->epoch_markers)[i]).is_protected = FALSE;
- ((cache_ptr->epoch_markers)[i]).is_read_only = FALSE;
- ((cache_ptr->epoch_markers)[i]).ro_ref_count = 0;
- ((cache_ptr->epoch_markers)[i]).is_pinned = FALSE;
- ((cache_ptr->epoch_markers)[i]).in_slist = FALSE;
- ((cache_ptr->epoch_markers)[i]).ht_next = NULL;
- ((cache_ptr->epoch_markers)[i]).ht_prev = NULL;
- ((cache_ptr->epoch_markers)[i]).next = NULL;
- ((cache_ptr->epoch_markers)[i]).prev = NULL;
- ((cache_ptr->epoch_markers)[i]).aux_next = NULL;
- ((cache_ptr->epoch_markers)[i]).aux_prev = NULL;
-#if H5C_COLLECT_CACHE_ENTRY_STATS
- ((cache_ptr->epoch_markers)[i]).accesses = 0;
- ((cache_ptr->epoch_markers)[i]).clears = 0;
- ((cache_ptr->epoch_markers)[i]).flushes = 0;
- ((cache_ptr->epoch_markers)[i]).pins = 0;
-#endif /* H5C_COLLECT_CACHE_ENTRY_STATS */
}
if ( H5C_reset_cache_hit_rate_stats(cache_ptr) != SUCCEED ) {
@@ -3824,222 +3808,244 @@ H5C_flush_cache(H5F_t * f,
( protected_entries == 0 ) &&
( flushed_entries_last_pass ) )
{
- flushed_entries_last_pass = FALSE;
- node_ptr = H5SL_first(cache_ptr->slist_ptr);
+ unsigned curr_flush_dep_height = 0;
+ unsigned flush_dep_passes = 0;
- if ( node_ptr != NULL ) {
+ flushed_entries_last_pass = FALSE;
- next_entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr);
+ /* Loop over all flush dependency heights of entries */
+ while((curr_flush_dep_height <= H5C__NUM_FLUSH_DEP_HEIGHTS) &&
+ (cache_ptr->slist_len != 0) &&
+ (flush_dep_passes < H5C__MAX_PASSES_ON_FLUSH) )
+ {
+ hbool_t flushed_during_dep_loop = FALSE;
- if ( next_entry_ptr == NULL ) {
+ /* Start at beginning of skip list each time */
+ node_ptr = H5SL_first(cache_ptr->slist_ptr);
+ HDassert( node_ptr != NULL );
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "next_entry_ptr == NULL 1 ?!?!");
- }
-#ifndef NDEBUG
- HDassert( next_entry_ptr->magic ==
- H5C__H5C_CACHE_ENTRY_T_MAGIC );
-#endif /* NDEBUG */
- HDassert( next_entry_ptr->is_dirty );
+ /* Get cache entry for this node */
+ next_entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr);
+ if ( NULL == next_entry_ptr )
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "next_entry_ptr == NULL ?!?!")
+ HDassert( next_entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC );
+ HDassert( next_entry_ptr->is_dirty );
HDassert( next_entry_ptr->in_slist );
- } else {
-
- next_entry_ptr = NULL;
-
- }
-
- HDassert( node_ptr != NULL );
-
#if H5C_DO_SANITY_CHECKS
- /* For sanity checking, try to verify that the skip list has
- * the expected size and number of entries at the end of each
- * internal while loop (see below).
- *
- * Doing this get a bit tricky, as depending on flags, we may
- * or may not flush all the entries in the slist.
- *
- * To make things more entertaining, with the advent of the
- * fractal heap, the entry flush callback can cause entries
- * to be dirtied, resized, and/or renamed.
- *
- * To deal with this, we first make note of the initial
- * skip list length and size:
- */
- initial_slist_len = cache_ptr->slist_len;
- initial_slist_size = cache_ptr->slist_size;
+ /* For sanity checking, try to verify that the skip list has
+ * the expected size and number of entries at the end of each
+ * internal while loop (see below).
+ *
+ * Doing this get a bit tricky, as depending on flags, we may
+ * or may not flush all the entries in the slist.
+ *
+ * To make things more entertaining, with the advent of the
+ * fractal heap, the entry flush callback can cause entries
+ * to be dirtied, resized, and/or renamed.
+ *
+ * To deal with this, we first make note of the initial
+ * skip list length and size:
+ */
+ initial_slist_len = cache_ptr->slist_len;
+ initial_slist_size = cache_ptr->slist_size;
- /* We then zero counters that we use to track the number
- * and total size of entries flushed:
- */
- flushed_entries_count = 0;
- flushed_entries_size = 0;
-
- /* As mentioned above, there is the possibility that
- * entries will be dirtied, resized, and/or flushed during
- * our pass through the skip list. To capture the number
- * of entries added, and the skip list size delta,
- * zero the slist_len_increase and slist_size_increase of
- * the cache's instance of H5C_t. These fields will be
- * updated elsewhere to account for slist insertions and/or
- * dirty entry size changes.
- */
- cache_ptr->slist_len_increase = 0;
- cache_ptr->slist_size_increase = 0;
+ /* We then zero counters that we use to track the number
+ * and total size of entries flushed:
+ */
+ flushed_entries_count = 0;
+ flushed_entries_size = 0;
+
+ /* As mentioned above, there is the possibility that
+ * entries will be dirtied, resized, and/or flushed during
+ * our pass through the skip list. To capture the number
+ * of entries added, and the skip list size delta,
+ * zero the slist_len_increase and slist_size_increase of
+ * the cache's instance of H5C_t. These fields will be
+ * updated elsewhere to account for slist insertions and/or
+ * dirty entry size changes.
+ */
+ cache_ptr->slist_len_increase = 0;
+ cache_ptr->slist_size_increase = 0;
- /* at the end of the loop, use these values to compute the
- * expected slist length and size and compare this with the
- * value recorded in the cache's instance of H5C_t.
- */
+ /* at the end of the loop, use these values to compute the
+ * expected slist length and size and compare this with the
+ * value recorded in the cache's instance of H5C_t.
+ */
#endif /* H5C_DO_SANITY_CHECKS */
- while ( node_ptr != NULL )
- {
- entry_ptr = next_entry_ptr;
-
- /* With the advent of the fractal heap, it is possible
- * that the flush callback will dirty and/or resize
- * other entries in the cache. In particular, while
- * Quincey has promised me that this will never happen,
- * it is possible that the flush callback for an
- * entry may protect an entry that is not in the cache,
- * perhaps causing the cache to flush and possibly
- * evict the entry associated with node_ptr to make
- * space for the new entry.
- *
- * Thus we do a bit of extra sanity checking on entry_ptr,
- * and break out of this scan of the skip list if we
- * detect minor problems. We have a bit of leaway on the
- * number of passes though the skip list, so this shouldn't
- * be an issue in the flush in and of itself, as it should
- * be all but impossible for this to happen more than once
- * in any flush.
- *
- * Observe that that breaking out of the scan early
- * shouldn't break the sanity checks just after the end
- * of this while loop.
- *
- * If an entry has merely been marked clean and removed from
- * the s-list, we simply break out of the scan.
- *
- * If the entry has been evicted, we flag an error and
- * exit.
- */
+ while ( node_ptr != NULL )
+ {
+ entry_ptr = next_entry_ptr;
+
+ /* With the advent of the fractal heap, it is possible
+ * that the flush callback will dirty and/or resize
+ * other entries in the cache. In particular, while
+ * Quincey has promised me that this will never happen,
+ * it is possible that the flush callback for an
+ * entry may protect an entry that is not in the cache,
+ * perhaps causing the cache to flush and possibly
+ * evict the entry associated with node_ptr to make
+ * space for the new entry.
+ *
+ * Thus we do a bit of extra sanity checking on entry_ptr,
+ * and break out of this scan of the skip list if we
+ * detect minor problems. We have a bit of leaway on the
+ * number of passes though the skip list, so this shouldn't
+ * be an issue in the flush in and of itself, as it should
+ * be all but impossible for this to happen more than once
+ * in any flush.
+ *
+ * Observe that that breaking out of the scan early
+ * shouldn't break the sanity checks just after the end
+ * of this while loop.
+ *
+ * If an entry has merely been marked clean and removed from
+ * the s-list, we simply break out of the scan.
+ *
+ * If the entry has been evicted, we flag an error and
+ * exit.
+ */
#ifndef NDEBUG
- if ( entry_ptr->magic != H5C__H5C_CACHE_ENTRY_T_MAGIC ) {
+ if ( entry_ptr->magic != H5C__H5C_CACHE_ENTRY_T_MAGIC ) {
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "entry_ptr->magic invalid ?!?!");
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "entry_ptr->magic invalid ?!?!");
- } else
+ } else
#endif /* NDEBUG */
- if ( ( ! entry_ptr->is_dirty ) ||
- ( ! entry_ptr->in_slist ) ) {
+ if ( ( ! entry_ptr->is_dirty ) ||
+ ( ! entry_ptr->in_slist ) ) {
- /* the s-list has been modified out from under us.
- * set node_ptr to NULL and break out of the loop.
- */
- node_ptr = NULL;
- break;
- }
+ /* the s-list has been modified out from under us.
+ * set node_ptr to NULL and break out of the inner loop.
+ */
+ node_ptr = NULL;
+ goto end_of_inner_loop;;
+ }
- /* increment node pointer now, before we delete its target
- * from the slist.
- */
- node_ptr = H5SL_next(node_ptr);
+ /* increment node pointer now, before we delete its target
+ * from the slist.
+ */
+ node_ptr = H5SL_next(node_ptr);
- if ( node_ptr != NULL ) {
- next_entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr);
+ if ( node_ptr != NULL ) {
+ next_entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr);
- if ( next_entry_ptr == NULL ) {
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "next_entry_ptr == NULL 2 ?!?!");
+ if ( next_entry_ptr == NULL ) {
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "next_entry_ptr == NULL 2 ?!?!");
+ }
+ HDassert( next_entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC );
+ HDassert( next_entry_ptr->is_dirty );
+ HDassert( next_entry_ptr->in_slist );
+ } else {
+ next_entry_ptr = NULL;
}
-#ifndef NDEBUG
- HDassert( next_entry_ptr->magic ==
- H5C__H5C_CACHE_ENTRY_T_MAGIC );
-#endif /* NDEBUG */
- HDassert( next_entry_ptr->is_dirty );
- HDassert( next_entry_ptr->in_slist );
- } else {
- next_entry_ptr = NULL;
- }
- HDassert( entry_ptr != NULL );
- HDassert( entry_ptr->in_slist );
+ HDassert( entry_ptr != NULL );
+ HDassert( entry_ptr->in_slist );
- if ( ( ! flush_marked_entries ) ||
- ( entry_ptr->flush_marker ) ) {
+ if ( ( ! flush_marked_entries ) ||
+ ( entry_ptr->flush_marker ) ) {
- if ( entry_ptr->is_protected ) {
+ if ( entry_ptr->is_protected ) {
- /* we probably have major problems -- but lets flush
- * everything we can before we decide whether to flag
- * an error.
- */
- tried_to_flush_protected_entry = TRUE;
- protected_entries++;
-
- } else if ( entry_ptr->is_pinned ) {
- /* Test to see if we are can flush the entry now.
- * If we can, go ahead and flush. Note that we
- * aren't trying to do a destroy here, so that
- * is not an issue.
- */
- if ( TRUE ) { /* When we get to multithreaded cache,
- * we will need either locking code,
- * and/or a test to see if the entry
- * is in flushable condition here.
- */
+ /* we probably have major problems -- but lets flush
+ * everything we can before we decide whether to flag
+ * an error.
+ */
+ tried_to_flush_protected_entry = TRUE;
+ protected_entries++;
+
+ } else if ( entry_ptr->is_pinned ) {
+ /* Test to see if we are can flush the entry now.
+ * If we can, go ahead and flush. Note that we
+ * aren't trying to do a destroy here, so that
+ * is not an issue.
+ */
+ if(entry_ptr->flush_dep_height == curr_flush_dep_height ) {
#if H5C_DO_SANITY_CHECKS
- flushed_entries_count++;
- flushed_entries_size += entry_ptr->size;
+ flushed_entries_count++;
+ flushed_entries_size += entry_ptr->size;
#endif /* H5C_DO_SANITY_CHECKS */
- status = H5C_flush_single_entry(f,
- primary_dxpl_id,
- secondary_dxpl_id,
- cache_ptr,
- NULL,
- entry_ptr->addr,
- flags,
- &first_flush,
- FALSE);
- if ( status < 0 ) {
-
- /* This shouldn't happen -- if it does, we are
- * toast so just scream and die.
- */
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
- "dirty pinned entry flush failed.")
- }
- flushed_entries_last_pass = TRUE;
- }
- } else {
+ status = H5C_flush_single_entry(f,
+ primary_dxpl_id,
+ secondary_dxpl_id,
+ cache_ptr,
+ NULL,
+ entry_ptr->addr,
+ flags,
+ &first_flush,
+ FALSE);
+ if ( status < 0 ) {
+
+ /* This shouldn't happen -- if it does, we are
+ * toast so just scream and die.
+ */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
+ "dirty pinned entry flush failed.")
+ }
+ flushed_during_dep_loop = TRUE;
+ } /* end if */
+ else if(entry_ptr->flush_dep_height < curr_flush_dep_height)
+ /* This shouldn't happen -- if it does, just scream and die. */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "dirty entry below current flush dep. height.")
+ } else {
+ /* Test to see if we are can flush the entry now.
+ * If we can, go ahead and flush. Note that we
+ * aren't trying to do a destroy here, so that
+ * is not an issue.
+ */
+ if(entry_ptr->flush_dep_height == curr_flush_dep_height ){
#if H5C_DO_SANITY_CHECKS
- flushed_entries_count++;
- flushed_entries_size += entry_ptr->size;
+ flushed_entries_count++;
+ flushed_entries_size += entry_ptr->size;
#endif /* H5C_DO_SANITY_CHECKS */
- status = H5C_flush_single_entry(f,
- primary_dxpl_id,
- secondary_dxpl_id,
- cache_ptr,
- NULL,
- entry_ptr->addr,
- flags,
- &first_flush,
- FALSE);
- if ( status < 0 ) {
+ status = H5C_flush_single_entry(f,
+ primary_dxpl_id,
+ secondary_dxpl_id,
+ cache_ptr,
+ NULL,
+ entry_ptr->addr,
+ flags,
+ &first_flush,
+ FALSE);
+ if ( status < 0 ) {
+
+ /* This shouldn't happen -- if it does, we are
+ * toast so just scream and die.
+ */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
+ "Can't flush entry.")
+ }
+ flushed_during_dep_loop = TRUE;
+ } /* end if */
+ else if(entry_ptr->flush_dep_height < curr_flush_dep_height)
+ /* This shouldn't happen -- if it does, just scream and die. */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "dirty entry below current flush dep. height.")
+ } /* end else */
+ } /* end if */
+ } /* while ( node_ptr != NULL ) */
+
+ /* Check for incrementing flush dependency height */
+ if(flushed_during_dep_loop) {
+ /* If we flushed an entry at this flush dependency height
+ * start over at the bottom level of the flush dependencies
+ */
+ curr_flush_dep_height = 0;
- /* This shouldn't happen -- if it does, we are
- * toast so just scream and die.
- */
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
- "Can't flush entry.")
- }
- flushed_entries_last_pass = TRUE;
- }
- }
- } /* while ( node_ptr != NULL ) */
+ /* Make certain we don't get stuck in an infinite loop */
+ flush_dep_passes++;
+
+ /* Set flag for outer loop */
+ flushed_entries_last_pass = TRUE;
+ } /* end if */
+ else
+ curr_flush_dep_height++;
+
+ } /* while ( curr_flush_dep_height <= H5C__NUM_FLUSH_DEP_HEIGHTS) */
+end_of_inner_loop:
#if H5C_DO_SANITY_CHECKS
/* Verify that the slist size and length are as expected. */
@@ -4802,9 +4808,7 @@ H5C_insert_entry(H5F_t * f,
void * thing,
unsigned int flags)
{
- /* const char * fcn_name = "H5C_insert_entry()"; */
herr_t result;
- herr_t ret_value = SUCCEED; /* Return value */
hbool_t first_flush = TRUE;
hbool_t insert_pinned;
hbool_t set_flush_marker;
@@ -4812,6 +4816,8 @@ H5C_insert_entry(H5F_t * f,
size_t empty_space;
H5C_cache_entry_t * entry_ptr;
H5C_cache_entry_t * test_entry_ptr;
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5C_insert_entry, FAIL)
@@ -4900,6 +4906,12 @@ H5C_insert_entry(H5F_t * f,
entry_ptr->destroy_in_progress = FALSE;
entry_ptr->free_file_space_on_destroy = FALSE;
+ /* Initialize flush dependency height fields */
+ entry_ptr->flush_dep_parent = NULL;
+ for(u = 0; u < H5C__NUM_FLUSH_DEP_HEIGHTS; u++)
+ entry_ptr->child_flush_dep_height_rc[u] = 0;
+ entry_ptr->flush_dep_height = 0;
+
entry_ptr->ht_next = NULL;
entry_ptr->ht_prev = NULL;
@@ -7661,20 +7673,14 @@ H5C_stats__reset(H5C_t UNUSED * cache_ptr)
/*-------------------------------------------------------------------------
* Function: H5C_unpin_entry()
*
- * Purpose: Unpin a cache entry. The entry must be unprotected at
- * the time of call, and must be pinned.
+ * Purpose: Unpin a cache entry. The entry can be either protected or
+ * unprotected at the time of call, but must be pinned.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: John Mainzer
* 3/22/06
*
- * Modifications:
- *
- * JRM -- 4/26/06
- * Modified routine to allow it to operate on protected
- * entries.
- *
*-------------------------------------------------------------------------
*/
herr_t
@@ -8490,6 +8496,342 @@ done:
} /* H5C_validate_resize_config() */
+/*-------------------------------------------------------------------------
+ * Function: H5C_adjust_flush_dependency_rc()
+ *
+ * Purpose: "Atomicly" adjust flush dependency ref. counts for an entry,
+ * as a result of a flush dependency child's height changing.
+ *
+ * Note: Entry will remain in flush dependency relationship with its
+ * child entry (i.e. it's not going to get unpinned as a result
+ * of this change), but change could trickle upward, if this
+ * entry's height changes and it has a flush dependency parent.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * 3/05/09
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+H5C_adjust_flush_dependency_rc(H5C_cache_entry_t * cache_entry,
+ unsigned old_child_height, unsigned new_child_height)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5C_adjust_flush_dependency_rc)
+
+ /* Sanity checks */
+ HDassert(cache_entry);
+ HDassert(cache_entry->is_pinned);
+ HDassert(cache_entry->flush_dep_height > 0);
+ HDassert(cache_entry->flush_dep_height < H5C__NUM_FLUSH_DEP_HEIGHTS);
+ HDassert(cache_entry->child_flush_dep_height_rc[old_child_height] > 0);
+ HDassert(old_child_height < H5C__NUM_FLUSH_DEP_HEIGHTS);
+ HDassert(old_child_height != new_child_height);
+ HDassert(new_child_height < H5C__NUM_FLUSH_DEP_HEIGHTS);
+
+ /* Adjust ref. counts for entry's flush dependency children heights */
+ cache_entry->child_flush_dep_height_rc[new_child_height]++;
+ cache_entry->child_flush_dep_height_rc[old_child_height]--;
+
+ /* Check for flush dependency height of entry increasing */
+ if((new_child_height + 1) > cache_entry->flush_dep_height) {
+
+ /* Check if entry has _its_ own parent flush dependency entry */
+ if(NULL != cache_entry->flush_dep_parent) {
+ /* Adjust flush dependency ref. counts on entry's parent */
+ H5C_adjust_flush_dependency_rc(cache_entry->flush_dep_parent, cache_entry->flush_dep_height, new_child_height + 1);
+ } /* end if */
+
+ /* Set new flush dependency height of entry */
+ cache_entry->flush_dep_height = new_child_height + 1;
+ } /* end if */
+ else {
+ /* Check for child's flush dep. height decreasing and ref. count of
+ * old child height going to zero, it could mean the parent's
+ * flush dependency height dropped.
+ */
+ if((new_child_height < old_child_height)
+ && ((old_child_height + 1) == cache_entry->flush_dep_height)
+ && (0 == cache_entry->child_flush_dep_height_rc[old_child_height])) {
+ int i; /* Local index variable */
+
+ /* Re-scan child flush dependency height ref. counts to determine
+ * this entry's height.
+ */
+#ifndef NDEBUG
+ for(i = (H5C__NUM_FLUSH_DEP_HEIGHTS - 1); i > (int)new_child_height; i--)
+ HDassert(0 == cache_entry->child_flush_dep_height_rc[i]);
+#endif /* NDEBUG */
+ for(i = (int)new_child_height; i >= 0; i--)
+ /* Check for child flush dependencies of this height */
+ if(cache_entry->child_flush_dep_height_rc[i] > 0)
+ break;
+
+ /* Sanity checks */
+ HDassert((unsigned)(i + 1) < cache_entry->flush_dep_height);
+
+ /* Check if entry has _its_ own parent flush dependency entry */
+ if(NULL != cache_entry->flush_dep_parent) {
+ /* Adjust flush dependency ref. counts on entry's parent */
+ H5C_adjust_flush_dependency_rc(cache_entry->flush_dep_parent, cache_entry->flush_dep_height, (unsigned)(i + 1));
+ } /* end if */
+
+ /* Set new flush dependency height of entry */
+ cache_entry->flush_dep_height = (unsigned)(i + 1);
+ } /* end if */
+ } /* end else */
+
+
+ /* Post-conditions, for successful operation */
+ HDassert(cache_entry->is_pinned);
+ HDassert(cache_entry->flush_dep_height > 0);
+ HDassert(cache_entry->flush_dep_height <= H5C__NUM_FLUSH_DEP_HEIGHTS);
+ HDassert(cache_entry->child_flush_dep_height_rc[new_child_height] > 0);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* H5C_adjust_flush_dependency_rc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5C_create_flush_dependency()
+ *
+ * Purpose: Initiates a parent<->child entry flush dependency. The parent
+ * entry must be protected at the time of call, and must have all
+ * dependencies removed before the cache can shut down.
+ *
+ * Note: Flush dependencies in the cache indicate that a child entry
+ * must be flushed to the file before its parent. (This is
+ * currently used to implement Single-Writer/Multiple-Reader (SWMR)
+ * I/O access for data structures in the file).
+ *
+ * Each child entry can have only one parent entry, but parent
+ * entries can have >1 child entries. The flush dependency
+ * height of a parent entry is one greater than the max. flush
+ * dependency height of its children.
+ *
+ * Creating a flush dependency between two entries will also pin
+ * the parent entry. (The parent entry must _not_ be pinned
+ * through some other mechanism)
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * 3/05/09
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef NDEBUG
+herr_t
+H5C_create_flush_dependency(H5C_t * cache_ptr, void * parent_thing,
+ void * child_thing)
+#else
+herr_t
+H5C_create_flush_dependency(H5C_t UNUSED * cache_ptr, void * parent_thing,
+ void * child_thing)
+#endif
+{
+ H5C_cache_entry_t * parent_entry = (H5C_cache_entry_t *)parent_thing; /* Ptr to parent thing's entry */
+ H5C_cache_entry_t * child_entry = (H5C_cache_entry_t *)child_thing; /* Ptr to child thing's entry */
+#ifndef NDEBUG
+ unsigned prev_flush_dep_height = parent_entry->flush_dep_height; /* Previous flush height for parent entry */
+#endif /* NDEBUG */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5C_create_flush_dependency, FAIL)
+
+ /* Sanity checks */
+ HDassert(cache_ptr);
+ HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
+ HDassert(parent_entry);
+ HDassert(parent_entry->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
+ HDassert(parent_entry->flush_dep_height <= H5C__NUM_FLUSH_DEP_HEIGHTS);
+ HDassert(H5F_addr_defined(parent_entry->addr));
+ HDassert(child_entry);
+ HDassert(child_entry->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
+ HDassert(H5F_addr_defined(child_entry->addr));
+ HDassert(child_entry->flush_dep_height <= H5C__NUM_FLUSH_DEP_HEIGHTS);
+
+ /* More sanity checks */
+ if(child_entry == parent_entry)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTDEPEND, FAIL, "Child entry flush dependency parent can't be itself")
+ if(!parent_entry->is_protected)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTDEPEND, FAIL, "Parent entry isn't protected")
+ if(NULL != child_entry->flush_dep_parent)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTDEPEND, FAIL, "Child entry already has flush dependency parent")
+ {
+ H5C_cache_entry_t *tmp_entry = parent_entry; /* Temporary cache entry in flush dependency chain */
+ unsigned tmp_flush_height = 0; /* Different in heights of parent entry */
+
+ /* Find the top entry in the flush dependency list */
+ while(NULL != tmp_entry->flush_dep_parent) {
+ tmp_flush_height++;
+ tmp_entry = tmp_entry->flush_dep_parent;
+ } /* end while */
+
+ /* Check if we will make the dependency chain too long */
+ if((tmp_flush_height + child_entry->flush_dep_height + 1)
+ > H5C__NUM_FLUSH_DEP_HEIGHTS)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTDEPEND, FAIL, "Combined flush dependency height too large")
+ }
+
+ /* Check for parent already pinned */
+ if(parent_entry->is_pinned) {
+ /* Verify that the parent entry was pinned through a flush dependency relationship */
+ if(0 == parent_entry->flush_dep_height)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTDEPEND, FAIL, "Parent entry wasn't pinned through flush dependency")
+ } /* end if */
+ else {
+ /* Sanity check */
+ HDassert(parent_entry->flush_dep_height == 0);
+
+ /* Pin the parent entry */
+ parent_entry->is_pinned = TRUE;
+ H5C__UPDATE_STATS_FOR_PIN(cache_ptr, parent_entry)
+ } /* end else */
+
+ /* Increment ref. count for parent's flush dependency children heights */
+ parent_entry->child_flush_dep_height_rc[child_entry->flush_dep_height]++;
+
+ /* Check for increasing parent flush dependency height */
+ if((child_entry->flush_dep_height + 1) > parent_entry->flush_dep_height) {
+
+ /* Check if parent entry has _its_ own parent flush dependency entry */
+ if(NULL != parent_entry->flush_dep_parent) {
+ /* Adjust flush dependency ref. counts on parent entry's parent */
+ H5C_adjust_flush_dependency_rc(parent_entry->flush_dep_parent, parent_entry->flush_dep_height, (child_entry->flush_dep_height + 1));
+ } /* end if */
+
+ /* Increase flush dependency height of parent entry */
+ parent_entry->flush_dep_height = child_entry->flush_dep_height + 1;
+ } /* end if */
+
+ /* Set parent for child entry */
+ child_entry->flush_dep_parent = parent_entry;
+
+
+ /* Post-conditions, for successful operation */
+ HDassert(parent_entry->is_pinned);
+ HDassert(parent_entry->flush_dep_height > 0);
+ HDassert(parent_entry->flush_dep_height < H5C__NUM_FLUSH_DEP_HEIGHTS);
+ HDassert(prev_flush_dep_height <= parent_entry->flush_dep_height);
+ HDassert(parent_entry->child_flush_dep_height_rc[child_entry->flush_dep_height] > 0);
+ HDassert(NULL != child_entry->flush_dep_parent);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5C_create_flush_dependency() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5C_destroy_flush_dependency()
+ *
+ * Purpose: Terminates a parent<-> child entry flush dependency. The
+ * parent entry must be pinned and have a positive flush
+ * dependency height (which could go to zero as a result of
+ * this operation).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * 3/05/09
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5C_destroy_flush_dependency(H5C_t * cache_ptr, void *parent_thing,
+ void * child_thing)
+{
+ H5C_cache_entry_t * parent_entry = (H5C_cache_entry_t *)parent_thing; /* Ptr to parent entry */
+ H5C_cache_entry_t * child_entry = (H5C_cache_entry_t *)child_thing; /* Ptr to child entry */
+#ifndef NDEBUG
+ unsigned prev_flush_dep_height = parent_entry->flush_dep_height; /* Previous flush height for parent entry */
+#endif /* NDEBUG */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5C_destroy_flush_dependency, FAIL)
+
+ /* Sanity checks */
+ HDassert(cache_ptr);
+ HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
+ HDassert(parent_entry);
+ HDassert(parent_entry->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
+ HDassert(H5F_addr_defined(parent_entry->addr));
+ HDassert(parent_entry->flush_dep_height <= H5C__NUM_FLUSH_DEP_HEIGHTS);
+ HDassert(child_entry);
+ HDassert(child_entry->flush_dep_parent != child_entry);
+ HDassert(child_entry->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
+ HDassert(H5F_addr_defined(child_entry->addr));
+
+ /* Usage checks */
+ if(!parent_entry->is_pinned)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTUNDEPEND, FAIL, "Parent entry isn't pinned")
+ if(0 == parent_entry->flush_dep_height)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTUNDEPEND, FAIL, "Parent entry isn't a flush dependency parent")
+ if(NULL == child_entry->flush_dep_parent)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTUNDEPEND, FAIL, "Child entry doesn't have a flush dependency parent")
+ if(0 == parent_entry->child_flush_dep_height_rc[child_entry->flush_dep_height])
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTUNDEPEND, FAIL, "Parent entry flush dependency ref. count has no child entries of this height")
+ if(child_entry->flush_dep_parent != parent_entry)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTUNDEPEND, FAIL, "Parent entry isn't flush dependency parent for child entry")
+
+ /* Decrement the ref. count for flush dependency height of children for parent entry */
+ parent_entry->child_flush_dep_height_rc[child_entry->flush_dep_height]--;
+
+ /* Check for flush dependency ref. count at this height going to zero and
+ * parent entry flush dependency height dropping
+ */
+ if(((child_entry->flush_dep_height + 1) == parent_entry->flush_dep_height) &&
+ 0 == parent_entry->child_flush_dep_height_rc[child_entry->flush_dep_height]) {
+ int i; /* Local index variable */
+
+ /* Reverse scan for new flush dependency height of parent */
+#ifndef NDEBUG
+ for(i = (H5C__NUM_FLUSH_DEP_HEIGHTS - 1); i > (int)child_entry->flush_dep_height; i--)
+ HDassert(0 == parent_entry->child_flush_dep_height_rc[i]);
+#endif /* NDEBUG */
+ for(i = (int)child_entry->flush_dep_height; i >= 0; i--)
+ /* Check for child flush dependencies of this height */
+ if(parent_entry->child_flush_dep_height_rc[i] > 0)
+ break;
+
+ /* Sanity check */
+ HDassert((unsigned)(i + 1) < parent_entry->flush_dep_height);
+
+ /* Check if parent entry is a child in another flush dependency relationship */
+ if(NULL != parent_entry->flush_dep_parent) {
+ /* Change flush dependency ref. counts of parent's parent */
+ H5C_adjust_flush_dependency_rc(parent_entry->flush_dep_parent, parent_entry->flush_dep_height, (unsigned)(i + 1));
+ } /* end if */
+
+ /* Increase flush dependency height of parent entry */
+ parent_entry->flush_dep_height = (unsigned)(i + 1);
+
+ /* Check for height of parent dropping to zero (i.e. no longer a
+ * parent of _any_ child flush dependencies).
+ */
+ if(0 == parent_entry->flush_dep_height) {
+ if(!parent_entry->is_protected)
+ H5C__UPDATE_RP_FOR_UNPIN(cache_ptr, parent_entry, FAIL)
+
+ /* Unpin parent entry */
+ parent_entry->is_pinned = FALSE;
+ H5C__UPDATE_STATS_FOR_UNPIN(cache_ptr, parent_entry)
+ } /* end if */
+ } /* end if */
+
+ /* Reset parent of child entry */
+ child_entry->flush_dep_parent = NULL;
+
+ /* Post-conditions, for successful operation */
+ HDassert(prev_flush_dep_height >= parent_entry->flush_dep_height);
+ HDassert(NULL == child_entry->flush_dep_parent);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5C_destroy_flush_dependency() */
+
+
/*************************************************************************/
/**************************** Private Functions: *************************/
/*************************************************************************/
@@ -9874,8 +10216,6 @@ H5C_flush_invalidate_cache(H5F_t * f,
herr_t ret_value = SUCCEED;
hbool_t done = FALSE;
hbool_t first_flush = TRUE;
- hbool_t first_pass = TRUE;
- hbool_t have_pinned_entries;
int32_t protected_entries = 0;
int32_t i;
int32_t cur_pel_len;
@@ -9952,347 +10292,376 @@ H5C_flush_invalidate_cache(H5F_t * f,
while ( ! done )
{
- first_pass = FALSE;
+ unsigned curr_flush_dep_height = 0;
+ unsigned flush_dep_passes = 0;
- have_pinned_entries = ( cur_pel_len > 0 );
+ /* Loop over all flush dependency heights of entries */
+ while((curr_flush_dep_height <= H5C__NUM_FLUSH_DEP_HEIGHTS) &&
+ (cache_ptr->index_len > 0 ) &&
+ (flush_dep_passes < H5C__MAX_PASSES_ON_FLUSH) )
+ {
+ hbool_t flushed_during_dep_loop = FALSE;
- /* first, try to flush-destroy any dirty entries. Do this by
- * making a scan through the slist. Note that new dirty entries
- * may be created by the flush call backs. Thus it is possible
- * that the slist will not be empty after we finish the scan.
- */
+ /* first, try to flush-destroy any dirty entries. Do this by
+ * making a scan through the slist. Note that new dirty entries
+ * may be created by the flush call backs. Thus it is possible
+ * that the slist will not be empty after we finish the scan.
+ */
- if ( cache_ptr->slist_len == 0 ) {
+ if ( cache_ptr->slist_len == 0 ) {
- node_ptr = NULL;
- HDassert( cache_ptr->slist_size == 0 );
+ node_ptr = NULL;
+ HDassert( cache_ptr->slist_size == 0 );
- } else {
+ } else {
- node_ptr = H5SL_first(cache_ptr->slist_ptr);
+ node_ptr = H5SL_first(cache_ptr->slist_ptr);
- if ( node_ptr == NULL ) {
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "slist_len != 0 && node_ptr == NULL");
- }
+ if ( node_ptr == NULL ) {
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "slist_len != 0 && node_ptr == NULL");
+ }
- next_entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr);
+ next_entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr);
- if ( next_entry_ptr == NULL ) {
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "next_entry_ptr == NULL 1 ?!?!");
- }
-#ifndef NDEBUG
- HDassert( next_entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC );
-#endif /* NDEBUG */
- HDassert( next_entry_ptr->is_dirty );
- HDassert( next_entry_ptr->in_slist );
+ if ( next_entry_ptr == NULL ) {
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "next_entry_ptr == NULL 1 ?!?!");
+ }
+ HDassert( next_entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC );
+ HDassert( next_entry_ptr->is_dirty );
+ HDassert( next_entry_ptr->in_slist );
- }
+ }
#if H5C_DO_SANITY_CHECKS
- /* Depending on circumstances, H5C_flush_single_entry() will
- * remove dirty entries from the slist as it flushes them.
- * Thus for sanity checks we must make note of the initial
- * slist length and size before we do any flushes.
- */
- initial_slist_len = cache_ptr->slist_len;
- initial_slist_size = cache_ptr->slist_size;
-
- /* There is also the possibility that entries will be
- * dirtied, resized, and/or renamed as the result of
- * calls to the flush callbacks. We use the slist_len_increase
- * and slist_size_increase increase fields in struct H5C_t
- * to track these changes for purpose of sanity checking.
- * To this end, we must zero these fields before we start
- * the pass through the slist.
- */
- cache_ptr->slist_len_increase = 0;
- cache_ptr->slist_size_increase = 0;
+ /* Depending on circumstances, H5C_flush_single_entry() will
+ * remove dirty entries from the slist as it flushes them.
+ * Thus for sanity checks we must make note of the initial
+ * slist length and size before we do any flushes.
+ */
+ initial_slist_len = cache_ptr->slist_len;
+ initial_slist_size = cache_ptr->slist_size;
- /* Finally, reset the actual_slist_len and actual_slist_size
- * fields to zero, as these fields are used to accumulate
- * the slist lenght and size that we see as we scan through
- * the slist.
- */
- actual_slist_len = 0;
- actual_slist_size = 0;
-#endif /* H5C_DO_SANITY_CHECKS */
+ /* There is also the possibility that entries will be
+ * dirtied, resized, and/or renamed as the result of
+ * calls to the flush callbacks. We use the slist_len_increase
+ * and slist_size_increase increase fields in struct H5C_t
+ * to track these changes for purpose of sanity checking.
+ * To this end, we must zero these fields before we start
+ * the pass through the slist.
+ */
+ cache_ptr->slist_len_increase = 0;
+ cache_ptr->slist_size_increase = 0;
- while ( node_ptr != NULL )
- {
- entry_ptr = next_entry_ptr;
-
- /* With the advent of the fractal heap, it is possible
- * that the flush callback will dirty and/or resize
- * other entries in the cache. In particular, while
- * Quincey has promised me that this will never happen,
- * it is possible that the flush callback for an
- * entry may protect an entry that is not in the cache,
- * perhaps causing the cache to flush and possibly
- * evict the entry associated with node_ptr to make
- * space for the new entry.
- *
- * Thus we do a bit of extra sanity checking on entry_ptr,
- * and break out of this scan of the skip list if we
- * detect major problems. We have a bit of leaway on the
- * number of passes though the skip list, so this shouldn't
- * be an issue in the flush in and of itself, as it should
- * be all but impossible for this to happen more than once
- * in any flush.
- *
- * Observe that that breaking out of the scan early
- * shouldn't break the sanity checks just after the end
- * of this while loop.
- *
- * If an entry has merely been marked clean and removed from
- * the s-list, we simply break out of the scan.
- *
- * If the entry has been evicted, we flag an error and
- * exit.
+ /* Finally, reset the actual_slist_len and actual_slist_size
+ * fields to zero, as these fields are used to accumulate
+ * the slist lenght and size that we see as we scan through
+ * the slist.
*/
+ actual_slist_len = 0;
+ actual_slist_size = 0;
+#endif /* H5C_DO_SANITY_CHECKS */
+
+ while ( node_ptr != NULL )
+ {
+ entry_ptr = next_entry_ptr;
+
+ /* With the advent of the fractal heap, it is possible
+ * that the flush callback will dirty and/or resize
+ * other entries in the cache. In particular, while
+ * Quincey has promised me that this will never happen,
+ * it is possible that the flush callback for an
+ * entry may protect an entry that is not in the cache,
+ * perhaps causing the cache to flush and possibly
+ * evict the entry associated with node_ptr to make
+ * space for the new entry.
+ *
+ * Thus we do a bit of extra sanity checking on entry_ptr,
+ * and break out of this scan of the skip list if we
+ * detect major problems. We have a bit of leaway on the
+ * number of passes though the skip list, so this shouldn't
+ * be an issue in the flush in and of itself, as it should
+ * be all but impossible for this to happen more than once
+ * in any flush.
+ *
+ * Observe that that breaking out of the scan early
+ * shouldn't break the sanity checks just after the end
+ * of this while loop.
+ *
+ * If an entry has merely been marked clean and removed from
+ * the s-list, we simply break out of the scan.
+ *
+ * If the entry has been evicted, we flag an error and
+ * exit.
+ */
#ifndef NDEBUG
- if ( entry_ptr->magic != H5C__H5C_CACHE_ENTRY_T_MAGIC ) {
+ if ( entry_ptr->magic != H5C__H5C_CACHE_ENTRY_T_MAGIC ) {
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "entry_ptr->magic is invalid ?!?!");
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "entry_ptr->magic is invalid ?!?!");
- } else
+ } else
#endif /* NDEBUG */
- if ( ( ! entry_ptr->is_dirty ) ||
- ( ! entry_ptr->in_slist ) ) {
+ if ( ( ! entry_ptr->is_dirty ) ||
+ ( ! entry_ptr->in_slist ) ) {
- /* the s-list has been modified out from under us.
- * break out of the loop.
- */
- break;
- }
+ /* the s-list has been modified out from under us.
+ * break out of the loop.
+ */
+ goto end_of_inner_loop;;
+ }
- /* increment node pointer now, before we delete its target
- * from the slist.
- */
+ /* increment node pointer now, before we delete its target
+ * from the slist.
+ */
- node_ptr = H5SL_next(node_ptr);
- if ( node_ptr != NULL ) {
+ node_ptr = H5SL_next(node_ptr);
+ if ( node_ptr != NULL ) {
- next_entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr);
+ next_entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr);
- if ( next_entry_ptr == NULL ) {
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "next_entry_ptr == NULL 2 ?!?!");
- }
-#ifndef NDEBUG
- HDassert( next_entry_ptr->magic ==
- H5C__H5C_CACHE_ENTRY_T_MAGIC );
-#endif /* NDEBUG */
- HDassert( next_entry_ptr->is_dirty );
- HDassert( next_entry_ptr->in_slist );
+ if ( next_entry_ptr == NULL ) {
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "next_entry_ptr == NULL 2 ?!?!");
+ }
+ HDassert( next_entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC );
+ HDassert( next_entry_ptr->is_dirty );
+ HDassert( next_entry_ptr->in_slist );
- } else {
+ } else {
- next_entry_ptr = NULL;
- }
+ next_entry_ptr = NULL;
+ }
- /* Note that we now remove nodes from the slist as we flush
- * the associated entries, instead of leaving them there
- * until we are done, and then destroying all nodes in
- * the slist.
- *
- * While this optimization used to be easy, with the possibility
- * of new entries being added to the slist in the midst of the
- * flush, we must keep the slist in cannonical form at all
- * times.
- */
+ /* Note that we now remove nodes from the slist as we flush
+ * the associated entries, instead of leaving them there
+ * until we are done, and then destroying all nodes in
+ * the slist.
+ *
+ * While this optimization used to be easy, with the possibility
+ * of new entries being added to the slist in the midst of the
+ * flush, we must keep the slist in cannonical form at all
+ * times.
+ */
- HDassert( entry_ptr != NULL );
- HDassert( entry_ptr->in_slist );
+ HDassert( entry_ptr != NULL );
+ HDassert( entry_ptr->in_slist );
#if H5C_DO_SANITY_CHECKS
- /* update actual_slist_len & actual_slist_size before
- * the flush. Note that the entry will be removed
- * from the slist after the flush, and thus may be
- * resized by the flush callback. This is OK, as
- * we will catch the size delta in
- * cache_ptr->slist_size_increase.
- *
- * Note that we include pinned entries in this count, even
- * though we will not actually flush them.
- */
- actual_slist_len++;
- actual_slist_size += entry_ptr->size;
+ /* update actual_slist_len & actual_slist_size before
+ * the flush. Note that the entry will be removed
+ * from the slist after the flush, and thus may be
+ * resized by the flush callback. This is OK, as
+ * we will catch the size delta in
+ * cache_ptr->slist_size_increase.
+ *
+ * Note that we include pinned entries in this count, even
+ * though we will not actually flush them.
+ */
+ actual_slist_len++;
+ actual_slist_size += entry_ptr->size;
#endif /* H5C_DO_SANITY_CHECKS */
- if ( entry_ptr->is_protected ) {
-
- /* we have major problems -- but lets flush
- * everything we can before we flag an error.
- */
- protected_entries++;
+ if ( entry_ptr->is_protected ) {
- } else if ( entry_ptr->is_pinned ) {
+ /* we have major problems -- but lets flush
+ * everything we can before we flag an error.
+ */
+ protected_entries++;
- /* Test to see if we are can flush the entry now.
- * If we can, go ahead and flush, but don't tell
- * H5C_flush_single_entry() to destroy the entry
- * as pinned entries can't be evicted.
- */
- if ( TRUE ) { /* When we get to multithreaded cache,
- * we will need either locking code, and/or
- * a test to see if the entry is in flushable
- * condition here.
- */
+ } else if ( entry_ptr->is_pinned ) {
- status = H5C_flush_single_entry(f,
- primary_dxpl_id,
- secondary_dxpl_id,
- cache_ptr,
- NULL,
- entry_ptr->addr,
- H5C__NO_FLAGS_SET,
- &first_flush,
- FALSE);
- if ( status < 0 ) {
+ /* Test to see if we are can flush the entry now.
+ * If we can, go ahead and flush, but don't tell
+ * H5C_flush_single_entry() to destroy the entry
+ * as pinned entries can't be evicted.
+ */
+ if(entry_ptr->flush_dep_height == curr_flush_dep_height ) {
+ status = H5C_flush_single_entry(f,
+ primary_dxpl_id,
+ secondary_dxpl_id,
+ cache_ptr,
+ NULL,
+ entry_ptr->addr,
+ H5C__NO_FLAGS_SET,
+ &first_flush,
+ FALSE);
+ if ( status < 0 ) {
- /* This shouldn't happen -- if it does, we are toast
- * so just scream and die.
- */
+ /* This shouldn't happen -- if it does, we are toast
+ * so just scream and die.
+ */
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
- "dirty pinned entry flush failed.")
- }
- }
- } else {
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
+ "dirty pinned entry flush failed.")
+ } /* end if */
+ flushed_during_dep_loop = TRUE;
+ } /* end if */
+ else if(entry_ptr->flush_dep_height < curr_flush_dep_height)
+ /* This shouldn't happen -- if it does, just scream and die. */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "dirty entry below current flush dep. height.")
+ } /* end if */
+ else {
+ if(entry_ptr->flush_dep_height == curr_flush_dep_height ){
- status = H5C_flush_single_entry(f,
- primary_dxpl_id,
- secondary_dxpl_id,
- cache_ptr,
- NULL,
- entry_ptr->addr,
- (cooked_flags |
- H5C__FLUSH_INVALIDATE_FLAG),
- &first_flush,
- TRUE);
- if ( status < 0 ) {
+ status = H5C_flush_single_entry(f,
+ primary_dxpl_id,
+ secondary_dxpl_id,
+ cache_ptr,
+ NULL,
+ entry_ptr->addr,
+ (cooked_flags |
+ H5C__FLUSH_INVALIDATE_FLAG),
+ &first_flush,
+ TRUE);
+ if ( status < 0 ) {
- /* This shouldn't happen -- if it does, we are toast so
- * just scream and die.
- */
+ /* This shouldn't happen -- if it does, we are toast so
+ * just scream and die.
+ */
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
- "dirty entry flush destroy failed.")
- }
- }
- } /* end while loop scanning skip list */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
+ "dirty entry flush destroy failed.")
+ } /* end if */
+ flushed_during_dep_loop = TRUE;
+ } /* end if */
+ else if(entry_ptr->flush_dep_height < curr_flush_dep_height)
+ /* This shouldn't happen -- if it does, just scream and die. */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "dirty entry below current flush dep. height.")
+ } /* end else */
+ } /* end while loop scanning skip list */
#if H5C_DO_SANITY_CHECKS
- /* It is possible that entries were added to the slist during
- * the scan, either before or after scan pointer. The following
- * asserts take this into account.
- *
- * Don't bother with the sanity checks if node_ptr != NULL, as
- * in this case we broke out of the loop because it got changed
- * out from under us.
- */
+ /* It is possible that entries were added to the slist during
+ * the scan, either before or after scan pointer. The following
+ * asserts take this into account.
+ *
+ * Don't bother with the sanity checks if node_ptr != NULL, as
+ * in this case we broke out of the loop because it got changed
+ * out from under us.
+ */
- if ( node_ptr == NULL ) {
+ if ( node_ptr == NULL ) {
- HDassert( (actual_slist_len + cache_ptr->slist_len) ==
- (initial_slist_len + cache_ptr->slist_len_increase) );
- HDassert( (actual_slist_size + cache_ptr->slist_size) ==
- (initial_slist_size + cache_ptr->slist_size_increase) );
- }
+ HDassert( (actual_slist_len + cache_ptr->slist_len) ==
+ (initial_slist_len + cache_ptr->slist_len_increase) );
+ HDassert( (actual_slist_size + cache_ptr->slist_size) ==
+ (initial_slist_size + cache_ptr->slist_size_increase) );
+ }
#endif /* H5C_DO_SANITY_CHECKS */
- /* Since we are doing a destroy, we must make a pass through
- * the hash table and try to flush - destroy all entries that
- * remain.
- *
- * It used to be that all entries remaining in the cache at
- * this point had to be clean, but with the fractal heap mods
- * this may not be the case. If so, we will flush entries out
- * of increasing address order.
- *
- * Writes to disk are possible here.
- */
- for ( i = 0; i < H5C__HASH_TABLE_LEN; i++ )
- {
- next_entry_ptr = cache_ptr->index[i];
-
- while ( next_entry_ptr != NULL )
+ /* Since we are doing a destroy, we must make a pass through
+ * the hash table and try to flush - destroy all entries that
+ * remain.
+ *
+ * It used to be that all entries remaining in the cache at
+ * this point had to be clean, but with the fractal heap mods
+ * this may not be the case. If so, we will flush entries out
+ * of increasing address order.
+ *
+ * Writes to disk are possible here.
+ */
+ for ( i = 0; i < H5C__HASH_TABLE_LEN; i++ )
{
- entry_ptr = next_entry_ptr;
+ next_entry_ptr = cache_ptr->index[i];
- next_entry_ptr = entry_ptr->ht_next;
-#ifndef NDEBUG
- HDassert ( ( next_entry_ptr == NULL ) ||
- ( next_entry_ptr->magic ==
- H5C__H5C_CACHE_ENTRY_T_MAGIC ) );
-#endif /* NDEBUG */
- if ( entry_ptr->is_protected ) {
+ while ( next_entry_ptr != NULL )
+ {
+ entry_ptr = next_entry_ptr;
- /* we have major problems -- but lets flush and destroy
- * everything we can before we flag an error.
- */
- protected_entries++;
+ next_entry_ptr = entry_ptr->ht_next;
+ HDassert ( ( next_entry_ptr == NULL ) ||
+ ( next_entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC ) );
+ if ( entry_ptr->is_protected ) {
- if ( ! entry_ptr->in_slist ) {
+ /* we have major problems -- but lets flush and destroy
+ * everything we can before we flag an error.
+ */
+ protected_entries++;
- HDassert( !(entry_ptr->is_dirty) );
- }
- } else if ( ! ( entry_ptr->is_pinned ) ) {
+ if ( ! entry_ptr->in_slist ) {
- status = H5C_flush_single_entry(f,
- primary_dxpl_id,
- secondary_dxpl_id,
- cache_ptr,
- NULL,
- entry_ptr->addr,
- (cooked_flags |
- H5C__FLUSH_INVALIDATE_FLAG),
- &first_flush,
- TRUE);
- if ( status < 0 ) {
+ HDassert( !(entry_ptr->is_dirty) );
+ }
+ } else if ( ! ( entry_ptr->is_pinned ) ) {
- /* This shouldn't happen -- if it does, we are toast so
- * just scream and die.
+ /* Test to see if we are can flush the entry now.
+ * If we can, go ahead and flush.
*/
+ if(entry_ptr->flush_dep_height == curr_flush_dep_height ){
+ status = H5C_flush_single_entry(f,
+ primary_dxpl_id,
+ secondary_dxpl_id,
+ cache_ptr,
+ NULL,
+ entry_ptr->addr,
+ (cooked_flags |
+ H5C__FLUSH_INVALIDATE_FLAG),
+ &first_flush,
+ TRUE);
+ if ( status < 0 ) {
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
- "Entry flush destroy failed.")
- }
- }
- /* We can't do anything if the entry is pinned. The
- * hope is that the entry will be unpinned as the
- * result of destroys of entries that reference it.
- *
- * We detect this by noting the change in the number
- * of pinned entries from pass to pass. If it stops
- * shrinking before it hits zero, we scream and die.
- */
- /* if the flush function on the entry we last evicted
- * loaded an entry into cache (as Quincey has promised me
- * it never will), and if the cache was full, it is
- * possible that *next_entry_ptr was flushed or evicted.
- *
- * Test to see if this happened here. Note that if this
- * test is triggred, we are accessing a deallocated piece
- * of dynamically allocated memory, so we just scream and
- * die.
- */
-#ifndef NDEBUG
- if ( ( next_entry_ptr != NULL ) &&
- ( next_entry_ptr->magic !=
- H5C__H5C_CACHE_ENTRY_T_MAGIC ) ) {
+ /* This shouldn't happen -- if it does, we are toast so
+ * just scream and die.
+ */
- /* Something horrible has happened to
- * *next_entry_ptr -- scream and die.
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
+ "Entry flush destroy failed.")
+ }
+ flushed_during_dep_loop = TRUE;
+ } /* end if */
+ else if(entry_ptr->flush_dep_height < curr_flush_dep_height)
+ /* This shouldn't happen -- if it does, just scream and die. */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "dirty entry below current flush dep. height.")
+ } /* end if */
+ /* We can't do anything if the entry is pinned. The
+ * hope is that the entry will be unpinned as the
+ * result of destroys of entries that reference it.
+ *
+ * We detect this by noting the change in the number
+ * of pinned entries from pass to pass. If it stops
+ * shrinking before it hits zero, we scream and die.
*/
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "next_entry_ptr->magic is invalid?!?!?.")
- }
+ /* if the flush function on the entry we last evicted
+ * loaded an entry into cache (as Quincey has promised me
+ * it never will), and if the cache was full, it is
+ * possible that *next_entry_ptr was flushed or evicted.
+ *
+ * Test to see if this happened here. Note that if this
+ * test is triggred, we are accessing a deallocated piece
+ * of dynamically allocated memory, so we just scream and
+ * die.
+ */
+#ifndef NDEBUG
+ if ( ( next_entry_ptr != NULL ) &&
+ ( next_entry_ptr->magic !=
+ H5C__H5C_CACHE_ENTRY_T_MAGIC ) ) {
+
+ /* Something horrible has happened to
+ * *next_entry_ptr -- scream and die.
+ */
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "next_entry_ptr->magic is invalid?!?!?.")
+ }
#endif /* NDEBUG */
- } /* end while loop scanning hash table bin */
- } /* end for loop scanning hash table */
+ } /* end while loop scanning hash table bin */
+ } /* end for loop scanning hash table */
+
+ /* Check for incrementing flush dependency height */
+ if(flushed_during_dep_loop) {
+ /* If we flushed an entry at this flush dependency height
+ * start over at the bottom level of the flush dependencies
+ */
+ curr_flush_dep_height = 0;
+
+ /* Make certain we don't get stuck in an infinite loop */
+ flush_dep_passes++;
+ } /* end if */
+ else
+ curr_flush_dep_height++;
+
+ } /* end while loop over flush dependency heights */
+end_of_inner_loop:
old_pel_len = cur_pel_len;
cur_pel_len = cache_ptr->pel_len;
@@ -11029,8 +11398,9 @@ H5C_load_entry(H5F_t * f,
#endif /* NDEBUG */
{
void * thing = NULL;
- void * ret_value = NULL;
H5C_cache_entry_t * entry_ptr = NULL;
+ unsigned u; /* Local index variable */
+ void * ret_value = NULL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5C_load_entry)
@@ -11097,6 +11467,12 @@ H5C_load_entry(H5F_t * f,
HDassert( entry_ptr->size < H5C_MAX_ENTRY_SIZE );
+ /* Initialize flush dependency height fields */
+ entry_ptr->flush_dep_parent = NULL;
+ for(u = 0; u < H5C__NUM_FLUSH_DEP_HEIGHTS; u++)
+ entry_ptr->child_flush_dep_height_rc[u] = 0;
+ entry_ptr->flush_dep_height = 0;
+
entry_ptr->ht_next = NULL;
entry_ptr->ht_prev = NULL;
diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h
index 4ce321c..855c861 100644
--- a/src/H5Cprivate.h
+++ b/src/H5Cprivate.h
@@ -32,7 +32,7 @@
#include "H5Cpublic.h" /*public prototypes */
-/* Pivate headers needed by this header */
+/* Private headers needed by this header */
#include "H5private.h" /* Generic Functions */
#include "H5Fprivate.h" /* File access */
@@ -183,6 +183,14 @@ typedef herr_t (*H5C_log_flush_func_t)(H5C_t * cache_ptr,
#define H5C__DEFAULT_MAX_CACHE_SIZE ((size_t)(4 * 1024 * 1024))
#define H5C__DEFAULT_MIN_CLEAN_SIZE ((size_t)(2 * 1024 * 1024))
+/* Maximum height of flush dependency relationships between entries. This is
+ * currently tuned to the extensible array (H5EA) data structure, which only
+ * requires 4 levels of dependency (i.e. heights 0-4).
+ */
+
+#define H5C__NUM_FLUSH_DEP_HEIGHTS 4
+
+
/****************************************************************************
*
@@ -496,6 +504,12 @@ typedef struct H5C_cache_entry_t
hbool_t destroy_in_progress;
hbool_t free_file_space_on_destroy;
+ /* fields supporting the 'flush dependency height': */
+
+ struct H5C_cache_entry_t * flush_dep_parent;
+ uint64_t child_flush_dep_height_rc[H5C__NUM_FLUSH_DEP_HEIGHTS];
+ unsigned flush_dep_height;
+
/* fields supporting the hash table: */
struct H5C_cache_entry_t * ht_next;
@@ -1040,6 +1054,9 @@ H5_DLL herr_t H5C_rename_entry(H5C_t * cache_ptr,
H5_DLL herr_t H5C_pin_protected_entry(H5C_t * cache_ptr,
void * thing);
+H5_DLL herr_t H5C_create_flush_dependency(H5C_t *cache_ptr, void *parent_thing,
+ void *child_thing);
+
H5_DLL void * H5C_protect(H5F_t * f,
hid_t primary_dxpl_id,
hid_t secondary_dxpl_id,
@@ -1079,6 +1096,9 @@ H5_DLL void H5C_stats__reset(H5C_t * cache_ptr);
H5_DLL herr_t H5C_unpin_entry(H5C_t * cache_ptr, void * thing);
+H5_DLL herr_t H5C_destroy_flush_dependency(H5C_t *cache_ptr, void *parent_thing,
+ void *child_thing);
+
H5_DLL herr_t H5C_unprotect(H5F_t * f,
hid_t primary_dxpl_id,
hid_t secondary_dxpl_id,
diff --git a/src/H5D.c b/src/H5D.c
index 4dad2aa..bb5e772 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -368,14 +368,13 @@ done:
herr_t
H5Dclose(hid_t dset_id)
{
- H5D_t *dset; /* Dataset object to release */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Dclose, FAIL)
H5TRACE1("e", "i", dset_id);
/* Check args */
- if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
+ if(NULL == H5I_object_verify(dset_id, H5I_DATASET))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
/*
diff --git a/src/H5Dio.c b/src/H5Dio.c
index c1d57fd..cc75981 100644
--- a/src/H5Dio.c
+++ b/src/H5Dio.c
@@ -66,8 +66,7 @@ static herr_t H5D_typeinfo_init(const H5D_t *dset, const H5D_dxpl_cache_t *dxpl_
H5D_type_info_t *type_info);
#ifdef H5_HAVE_PARALLEL
static herr_t H5D_ioinfo_adjust(H5D_io_info_t *io_info, const H5D_t *dset,
- const H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id,
- const H5S_t *file_space, const H5S_t *mem_space,
+ hid_t dxpl_id, const H5S_t *file_space, const H5S_t *mem_space,
const H5D_type_info_t *type_info, const H5D_chunk_map_t *fm);
static herr_t H5D_ioinfo_term(H5D_io_info_t *io_info);
#endif /* H5_HAVE_PARALLEL */
@@ -396,7 +395,7 @@ H5D_read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
#ifdef H5_HAVE_PARALLEL
/* Adjust I/O info for any parallel I/O */
- if(H5D_ioinfo_adjust(&io_info, dataset, dxpl_cache, dxpl_id, file_space, mem_space, &type_info, &fm) < 0)
+ if(H5D_ioinfo_adjust(&io_info, dataset, dxpl_id, file_space, mem_space, &type_info, &fm) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to adjust I/O info for parallel I/O")
#endif /*H5_HAVE_PARALLEL*/
@@ -570,7 +569,7 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
#ifdef H5_HAVE_PARALLEL
/* Adjust I/O info for any parallel I/O */
- if(H5D_ioinfo_adjust(&io_info, dataset, dxpl_cache, dxpl_id, file_space, mem_space, &type_info, &fm) < 0)
+ if(H5D_ioinfo_adjust(&io_info, dataset, dxpl_id, file_space, mem_space, &type_info, &fm) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to adjust I/O info for parallel I/O")
#endif /*H5_HAVE_PARALLEL*/
@@ -845,8 +844,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_ioinfo_adjust(H5D_io_info_t *io_info, const H5D_t *dset,
- const H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id,
+H5D_ioinfo_adjust(H5D_io_info_t *io_info, const H5D_t *dset, hid_t dxpl_id,
const H5S_t *file_space, const H5S_t *mem_space,
const H5D_type_info_t *type_info, const H5D_chunk_map_t *fm)
{
diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c
index e4dd8b5..6693348 100644
--- a/src/H5Dmpio.c
+++ b/src/H5Dmpio.c
@@ -117,8 +117,10 @@ static herr_t H5D_inter_collective_io(H5D_io_info_t *io_info,
static herr_t H5D_final_collective_io(H5D_io_info_t *io_info,
const H5D_type_info_t *type_info, size_t nelmts, MPI_Datatype *mpi_file_type,
MPI_Datatype *mpi_buf_type);
+#ifdef H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS
static herr_t H5D_sort_chunk(H5D_io_info_t *io_info, const H5D_chunk_map_t *fm,
H5D_chunk_addr_info_t chunk_addr_info_array[], int many_chunk_opt);
+#endif /* H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS */
static herr_t H5D_obtain_mpio_mode(H5D_io_info_t *io_info, H5D_chunk_map_t *fm,
H5P_genplist_t *dx_plist, uint8_t assign_io_mode[], haddr_t chunk_addr[]);
static herr_t H5D_ioinfo_xfer_mode(H5D_io_info_t *io_info, H5P_genplist_t *dx_plist,
@@ -1074,7 +1076,6 @@ static herr_t
H5D_multi_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
H5D_chunk_map_t *fm, H5P_genplist_t *dx_plist)
{
- H5D_t *dataset = io_info->dset;/* Local pointer to dataset info */
H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */
H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
H5D_io_info_t cpt_io_info; /* Compact I/O info object */
@@ -1347,7 +1348,6 @@ static herr_t
H5D_multi_chunk_collective_io_no_opt(H5D_io_info_t *io_info,
const H5D_type_info_t *type_info, H5D_chunk_map_t *fm, H5P_genplist_t *dx_plist)
{
- H5D_t *dataset = io_info->dset;/* Local pointer to dataset info */
H5SL_node_t *chunk_node; /* Current node in chunk skip list */
H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */
H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
@@ -1366,7 +1366,7 @@ if(H5DEBUG(D)) {
int mpi_rank;
mpi_rank = H5F_mpi_get_rank(io_info->dset->oloc.file);
- HDfprintf(H5DEBUG(D), "coming to multi_chunk_collective_io_no_opt\n");
+ HDfprintf(H5DEBUG(D), "Rank %d: coming to multi_chunk_collective_io_no_opt\n", mpi_rank);
}
#endif
@@ -1614,7 +1614,6 @@ static herr_t
H5D_final_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
size_t mpi_buf_count, MPI_Datatype *mpi_file_type, MPI_Datatype *mpi_buf_type)
{
- int mpi_code; /* MPI return code */
hbool_t plist_is_setup = FALSE; /* Whether the dxpl has been customized */
herr_t ret_value = SUCCEED;
@@ -1626,13 +1625,11 @@ H5D_final_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info
plist_is_setup = TRUE;
if(io_info->op_type == H5D_IO_OP_WRITE) {
- if((io_info->io_ops.single_write)(io_info, type_info,
- (hsize_t)mpi_buf_count, NULL, NULL) < 0)
+ if((io_info->io_ops.single_write)(io_info, type_info, (hsize_t)mpi_buf_count, NULL, NULL) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "optimized write failed")
} /* end if */
else {
- if((io_info->io_ops.single_read)(io_info, type_info,
- (hsize_t)mpi_buf_count, NULL, NULL) < 0)
+ if((io_info->io_ops.single_read)(io_info, type_info, (hsize_t)mpi_buf_count, NULL, NULL) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "optimized read failed")
} /* end else */
@@ -1649,6 +1646,7 @@ if(H5DEBUG(D))
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_final_collective_io */
+#ifdef H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS
/*-------------------------------------------------------------------------
* Function: H5D_sort_chunk
@@ -1790,6 +1788,7 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_sort_chunk() */
+#endif /* H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS */
/*-------------------------------------------------------------------------
@@ -1833,17 +1832,19 @@ H5D_obtain_mpio_mode(H5D_io_info_t* io_info, H5D_chunk_map_t *fm,
H5P_genplist_t *dx_plist, uint8_t assign_io_mode[], haddr_t chunk_addr[])
{
int total_chunks;
- unsigned percent_nproc_per_chunk,threshold_nproc_per_chunk;
+ unsigned percent_nproc_per_chunk, threshold_nproc_per_chunk;
+#if defined(H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS) && defined(H5_MPI_SPECIAL_COLLECTIVE_IO_WORKS)
H5FD_mpio_chunk_opt_t chunk_opt_mode;
- uint8_t* io_mode_info=NULL;
- uint8_t* recv_io_mode_info=NULL;
- uint8_t* mergebuf=NULL;
+#endif
+ uint8_t* io_mode_info = NULL;
+ uint8_t* recv_io_mode_info = NULL;
+ uint8_t* mergebuf = NULL;
uint8_t* tempbuf;
H5SL_node_t* chunk_node;
H5D_chunk_info_t* chunk_info;
- int mpi_size,mpi_rank;
+ int mpi_size, mpi_rank;
MPI_Comm comm;
- int ic,root;
+ int ic, root;
int mpi_code;
int mem_cleanup = 0;
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
diff --git a/src/H5Edefin.h b/src/H5Edefin.h
index 612fcb1..b31b31b 100644
--- a/src/H5Edefin.h
+++ b/src/H5Edefin.h
@@ -164,6 +164,8 @@ hid_t H5E_CANTMARKDIRTY_g = FAIL; /* Unable to mark a pinned entry as dirt
hid_t H5E_CANTDIRTY_g = FAIL; /* Unable to mark metadata as dirty */
hid_t H5E_CANTEXPUNGE_g = FAIL; /* Unable to expunge a metadata cache entry */
hid_t H5E_CANTRESIZE_g = FAIL; /* Unable to resize a metadata cache entry */
+hid_t H5E_CANTDEPEND_g = FAIL; /* Unable to create a flush dependency */
+hid_t H5E_CANTUNDEPEND_g = FAIL; /* Unable to destroy a flush dependency */
/* Link related errors */
hid_t H5E_TRAVERSE_g = FAIL; /* Link traversal failure */
diff --git a/src/H5Einit.h b/src/H5Einit.h
index 20e156c..204644f 100644
--- a/src/H5Einit.h
+++ b/src/H5Einit.h
@@ -622,6 +622,16 @@ if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to resize a metadata cache entr
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
if((H5E_CANTRESIZE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_CANTDEPEND_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to create a flush dependency"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_CANTDEPEND_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_CANTUNDEPEND_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to destroy a flush dependency"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_CANTUNDEPEND_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* Link related errors */
assert(H5E_TRAVERSE_g==(-1));
diff --git a/src/H5Epubgen.h b/src/H5Epubgen.h
index 4e981dc..736349a 100644
--- a/src/H5Epubgen.h
+++ b/src/H5Epubgen.h
@@ -266,6 +266,8 @@ H5_DLLVAR hid_t H5E_NOIDS_g; /* Out of IDs for group */
#define H5E_CANTDIRTY (H5OPEN H5E_CANTDIRTY_g)
#define H5E_CANTEXPUNGE (H5OPEN H5E_CANTEXPUNGE_g)
#define H5E_CANTRESIZE (H5OPEN H5E_CANTRESIZE_g)
+#define H5E_CANTDEPEND (H5OPEN H5E_CANTDEPEND_g)
+#define H5E_CANTUNDEPEND (H5OPEN H5E_CANTUNDEPEND_g)
H5_DLLVAR hid_t H5E_CANTFLUSH_g; /* Unable to flush data from cache */
H5_DLLVAR hid_t H5E_CANTSERIALIZE_g; /* Unable to serialize data from cache */
H5_DLLVAR hid_t H5E_CANTLOAD_g; /* Unable to load metadata into cache */
@@ -282,6 +284,8 @@ H5_DLLVAR hid_t H5E_CANTMARKDIRTY_g; /* Unable to mark a pinned entry as dirty *
H5_DLLVAR hid_t H5E_CANTDIRTY_g; /* Unable to mark metadata as dirty */
H5_DLLVAR hid_t H5E_CANTEXPUNGE_g; /* Unable to expunge a metadata cache entry */
H5_DLLVAR hid_t H5E_CANTRESIZE_g; /* Unable to resize a metadata cache entry */
+H5_DLLVAR hid_t H5E_CANTDEPEND_g; /* Unable to create a flush dependency */
+H5_DLLVAR hid_t H5E_CANTUNDEPEND_g; /* Unable to destroy a flush dependency */
/* Link related errors */
#define H5E_TRAVERSE (H5OPEN H5E_TRAVERSE_g)
diff --git a/src/H5Eterm.h b/src/H5Eterm.h
index 7595e7f..8936dc0 100644
--- a/src/H5Eterm.h
+++ b/src/H5Eterm.h
@@ -165,7 +165,9 @@ H5E_CANTUNPIN_g=
H5E_CANTMARKDIRTY_g=
H5E_CANTDIRTY_g=
H5E_CANTEXPUNGE_g=
-H5E_CANTRESIZE_g=
+H5E_CANTRESIZE_g=
+H5E_CANTDEPEND_g=
+H5E_CANTUNDEPEND_g=
/* Link related errors */
H5E_TRAVERSE_g=
diff --git a/src/H5F.c b/src/H5F.c
index 7b9ce79..e7b4cd3 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -1115,6 +1115,9 @@ H5F_dest(H5F_t *f, hid_t dxpl_id)
f->shared->mtab.child = (H5F_mount_t *)H5MM_xfree(f->shared->mtab.child);
f->shared->mtab.nalloc = 0;
+ /* Free root group symbol table entry, if any */
+ f->shared->root_ent = H5MM_xfree(f->shared->root_ent);
+
/* Destroy shared file struct */
f->shared = (H5F_file_t *)H5FL_FREE(H5F_file_t, f->shared);
diff --git a/src/H5FDdirect.c b/src/H5FDdirect.c
index 61eb318..fff31f3 100644
--- a/src/H5FDdirect.c
+++ b/src/H5FDdirect.c
@@ -1081,7 +1081,8 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h
hbool_t _must_align = TRUE;
herr_t ret_value=SUCCEED; /* Return value */
size_t alloc_size;
- void *copy_buf, *p1, *p3;
+ void *copy_buf, *p1;
+ const void *p3;
size_t _boundary;
size_t _fbsize;
size_t _cbsize;
@@ -1187,7 +1188,7 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h
HDmemcpy(p1, p3, copy_size);
}else if(size >= _cbsize && copy_size > (alloc_size-(size_t)(copy_addr%_fbsize))) {
HDmemcpy(p1, p3, (alloc_size - (size_t)(copy_addr % _fbsize)));
- p3 = (unsigned char*)p3 + (alloc_size - (size_t)(copy_addr % _fbsize));
+ p3 = (const unsigned char *)p3 + (alloc_size - (size_t)(copy_addr % _fbsize));
}
/*look for the aligned position for writing the data*/
diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c
index 57da069..5e5349d 100644
--- a/src/H5FDmpio.c
+++ b/src/H5FDmpio.c
@@ -1913,7 +1913,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5FD_mpio_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t closing)
+H5FD_mpio_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing)
{
H5FD_mpio_t *file = (H5FD_mpio_t*)_file;
herr_t ret_value = SUCCEED;
diff --git a/src/H5FDmpiposix.c b/src/H5FDmpiposix.c
index 245fc3e..ff5b118 100644
--- a/src/H5FDmpiposix.c
+++ b/src/H5FDmpiposix.c
@@ -1215,7 +1215,9 @@ H5FD_mpiposix_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr,
size_t size, const void *buf)
{
H5FD_mpiposix_t *file = (H5FD_mpiposix_t*)_file;
+#if 0 /* JRM */
int mpi_code; /* MPI return code */
+#endif /* JRM */
ssize_t nbytes; /* Number of bytes written each I/O call */
H5P_genplist_t *plist; /* Property list pointer */
herr_t ret_value=SUCCEED; /* Return value */
diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c
index 59e5b1e..0ae09a6 100644
--- a/src/H5FDstdio.c
+++ b/src/H5FDstdio.c
@@ -563,7 +563,9 @@ H5FD_stdio_alloc(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxp
{
H5FD_stdio_t *file = (H5FD_stdio_t*)_file;
haddr_t addr;
+#ifndef H5_HAVE_FSEEKO
static const char *func = "H5FD_stdio_alloc"; /* Function Name for error reporting */
+#endif
haddr_t ret_value; /* Return value */
/* Shut compiler up */
diff --git a/src/H5FDwindows.c b/src/H5FDwindows.c
index ef26fec..37228d7 100644
--- a/src/H5FDwindows.c
+++ b/src/H5FDwindows.c
@@ -1008,7 +1008,7 @@ done:
*/
/* ARGSUSED */
static herr_t
-H5FD_windows_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t closing)
+H5FD_windows_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing)
{
H5FD_windows_t *file = (H5FD_windows_t*)_file;
#ifndef WINDOWS_USE_STDIO
diff --git a/src/H5FLprivate.h b/src/H5FLprivate.h
index 446c852..a799dc4 100644
--- a/src/H5FLprivate.h
+++ b/src/H5FLprivate.h
@@ -118,7 +118,7 @@ typedef struct H5FL_reg_head_t {
#define H5FL_DEFINE(t) H5_DLL H5FL_DEFINE_COMMON(t)
/* Reference a free list for type 't' defined in another file */
-#define H5FL_EXTERN(t) extern H5_DLL H5FL_reg_head_t H5FL_REG_NAME(t)
+#define H5FL_EXTERN(t) H5_DLLVAR H5FL_reg_head_t H5FL_REG_NAME(t)
/* Declare a static free list to manage objects of type 't' */
#define H5FL_DEFINE_STATIC(t) static H5FL_DEFINE_COMMON(t)
@@ -142,7 +142,7 @@ typedef struct H5FL_reg_head_t {
#define H5FL_DEFINE_COMMON(t) int UNUSED H5FL_REG_NAME(t)
#define H5FL_DEFINE(t) H5_DLL H5FL_DEFINE_COMMON(t)
-#define H5FL_EXTERN(t) extern H5_DLL H5FL_DEFINE_COMMON(t)
+#define H5FL_EXTERN(t) H5_DLLVAR H5FL_DEFINE_COMMON(t)
#define H5FL_DEFINE_STATIC(t) static H5FL_DEFINE_COMMON(t)
#define H5FL_MALLOC(t) (t *)H5MM_malloc(sizeof(t))
#define H5FL_CALLOC(t) (t *)H5MM_calloc(sizeof(t))
@@ -187,7 +187,7 @@ typedef struct H5FL_blk_head_t {
#define H5FL_BLK_DEFINE(t) H5_DLL H5FL_BLK_DEFINE_COMMON(t)
/* Reference a free list for type 't' defined in another file */
-#define H5FL_BLK_EXTERN(t) extern H5_DLL H5FL_blk_head_t H5FL_BLK_NAME(t)
+#define H5FL_BLK_EXTERN(t) H5_DLLVAR H5FL_blk_head_t H5FL_BLK_NAME(t)
/* Declare a static free list to manage objects of type 't' */
#define H5FL_BLK_DEFINE_STATIC(t) static H5FL_BLK_DEFINE_COMMON(t)
@@ -212,7 +212,7 @@ typedef struct H5FL_blk_head_t {
#define H5FL_BLK_DEFINE_COMMON(t) int UNUSED H5FL_BLK_NAME(t)
#define H5FL_BLK_DEFINE(t) H5_DLL H5FL_BLK_DEFINE_COMMON(t)
-#define H5FL_BLK_EXTERN(t) extern H5_DLL H5FL_BLK_DEFINE_COMMON(t)
+#define H5FL_BLK_EXTERN(t) H5_DLLVAR H5FL_BLK_DEFINE_COMMON(t)
#define H5FL_BLK_DEFINE_STATIC(t) static H5FL_BLK_DEFINE_COMMON(t)
#define H5FL_BLK_MALLOC(t,size) (uint8_t *)H5MM_malloc(size)
#define H5FL_BLK_CALLOC(t,size) (uint8_t *)H5MM_calloc(size)
@@ -263,7 +263,7 @@ typedef struct H5FL_arr_head_t {
#define H5FL_BARR_DEFINE(b,t,m) H5_DLL H5FL_ARR_DEFINE_COMMON(sizeof(b),t,m)
/* Reference a free list for arrays of type 't' defined in another file */
-#define H5FL_ARR_EXTERN(t) extern H5_DLL H5FL_arr_head_t H5FL_ARR_NAME(t)
+#define H5FL_ARR_EXTERN(t) H5_DLLVAR H5FL_arr_head_t H5FL_ARR_NAME(t)
/* Declare a static free list to manage arrays of type 't' */
#define H5FL_ARR_DEFINE_STATIC(t,m) static H5FL_ARR_DEFINE_COMMON(0,t,m)
@@ -289,7 +289,7 @@ typedef struct H5FL_arr_head_t {
#define H5FL_ARR_DEFINE(t,m) H5_DLL H5FL_ARR_DEFINE_COMMON(t,m) = 0
#define H5FL_BARR_DEFINE(b,t,m) H5_DLL H5FL_ARR_DEFINE_COMMON(t,m) = sizeof(b)
-#define H5FL_ARR_EXTERN(t) extern H5_DLL H5FL_ARR_DEFINE_COMMON(t,m)
+#define H5FL_ARR_EXTERN(t) H5_DLLVAR H5FL_ARR_DEFINE_COMMON(t,m)
#define H5FL_ARR_DEFINE_STATIC(t,m) static H5FL_ARR_DEFINE_COMMON(t,m) = 0
#define H5FL_BARR_DEFINE_STATIC(b,t,m) static H5FL_ARR_DEFINE_COMMON(t,m) = sizeof(b)
#define H5FL_ARR_MALLOC(t,elem) H5MM_malloc(H5FL_ARR_NAME(t) + ((elem)*sizeof(t)))
@@ -319,7 +319,7 @@ typedef struct H5FL_seq_head_t {
#define H5FL_SEQ_DEFINE(t) H5_DLL H5FL_SEQ_DEFINE_COMMON(t)
/* Reference a free list for sequences of type 't' defined in another file */
-#define H5FL_SEQ_EXTERN(t) extern H5_DLL H5FL_seq_head_t H5FL_SEQ_NAME(t)
+#define H5FL_SEQ_EXTERN(t) H5_DLLVAR H5FL_seq_head_t H5FL_SEQ_NAME(t)
/* Declare a static free list to manage sequences of type 't' */
#define H5FL_SEQ_DEFINE_STATIC(t) static H5FL_SEQ_DEFINE_COMMON(t)
@@ -341,7 +341,7 @@ typedef struct H5FL_seq_head_t {
#define H5FL_SEQ_DEFINE_COMMON(t) int UNUSED H5FL_SEQ_NAME(t)
#define H5FL_SEQ_DEFINE(t) H5_DLL H5FL_SEQ_DEFINE_COMMON(t)
-#define H5FL_SEQ_EXTERN(t) extern H5_DLL H5FL_SEQ_DEFINE_COMMON(t)
+#define H5FL_SEQ_EXTERN(t) H5_DLLVAR H5FL_SEQ_DEFINE_COMMON(t)
#define H5FL_SEQ_DEFINE_STATIC(t) static H5FL_SEQ_DEFINE_COMMON(t)
#define H5FL_SEQ_MALLOC(t,elem) (t *)H5MM_malloc((elem)*sizeof(t))
#define H5FL_SEQ_CALLOC(t,elem) (t *)H5MM_calloc((elem)*sizeof(t))
diff --git a/src/H5Fdbg.c b/src/H5Fdbg.c
index e05c32a..a4577c9 100644
--- a/src/H5Fdbg.c
+++ b/src/H5Fdbg.c
@@ -123,21 +123,26 @@ H5F_debug(H5F_t *f, FILE *stream, int indent, int fwidth)
"Root group symbol table entry:",
f->shared->root_grp ? "" : "(none)");
if(f->shared->root_grp) {
- H5O_loc_t *root_oloc; /* Root object location */
- H5G_entry_t root_ent; /* Constructed root symbol table entry */
-
- /* Reset the root group entry */
- H5G_ent_reset(&root_ent);
-
- /* Build up a simulated root group symbol table entry */
- root_oloc = H5G_oloc(f->shared->root_grp);
- HDassert(root_oloc);
- root_ent.type = H5G_NOTHING_CACHED;
- root_ent.header = root_oloc->addr;
- root_ent.file = f;
-
- /* Display root group symbol table entry info */
- H5G_ent_debug(f, &root_ent, stream, indent + 3, MAX(0, fwidth - 3), NULL);
+ if(f->shared->root_ent) /* Use real root group symbol table entry */
+ H5G_ent_debug(f, f->shared->root_ent, stream, indent + 3,
+ MAX(0, fwidth - 3), NULL);
+ else {
+ H5O_loc_t *root_oloc; /* Root object location */
+ H5G_entry_t root_ent; /* Constructed root symbol table entry */
+
+ /* Reset the root group entry */
+ H5G_ent_reset(&root_ent);
+
+ /* Build up a simulated root group symbol table entry */
+ root_oloc = H5G_oloc(f->shared->root_grp);
+ HDassert(root_oloc);
+ root_ent.type = H5G_NOTHING_CACHED;
+ root_ent.header = root_oloc->addr;
+ root_ent.file = f;
+
+ /* Display root group symbol table entry info */
+ H5G_ent_debug(f, &root_ent, stream, indent + 3, MAX(0, fwidth - 3), NULL);
+ }
} /* end if */
done:
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index cc74a80..4080705 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -158,6 +158,7 @@ typedef struct H5F_file_t {
int ncwfs; /* Num entries on cwfs list */
struct H5HG_heap_t **cwfs; /* Global heap cache */
struct H5G_t *root_grp; /* Open root group */
+ H5G_entry_t *root_ent; /* Root group symbol table entry */
H5FO_t *open_objs; /* Open objects in file */
H5RC_t *grp_btree_shared; /* Ref-counted group B-tree node info */
@@ -193,7 +194,7 @@ struct H5F_t {
H5FO_t *obj_count; /* # of time each object is opened through top file structure */
hid_t file_id; /* ID of this file */
hbool_t closing; /* File is in the process of being closed */
- struct H5F_t *parent; /* Parent file that this file is mounted to */
+ struct H5F_t *parent; /* Parent file that this file is mounted to */
unsigned nmounts; /* Number of children mounted to this file */
};
diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c
index 3c914bd..70e0954 100644
--- a/src/H5Fsuper.c
+++ b/src/H5Fsuper.c
@@ -383,7 +383,8 @@ H5F_super_read(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc)
H5F_addr_decode(f, (const uint8_t **)&p, &shared->extension_addr/*out*/);
H5F_addr_decode(f, (const uint8_t **)&p, &stored_eoa/*out*/);
H5F_addr_decode(f, (const uint8_t **)&p, &shared->driver_addr/*out*/);
- if(H5G_obj_ent_decode(f, (const uint8_t **)&p, root_loc->oloc/*out*/) < 0)
+ if(H5G_obj_ent_decode(f, (const uint8_t **)&p, root_loc->oloc/*out*/,
+ &shared->root_ent/*out*/) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read root symbol entry")
/*
diff --git a/src/H5G.c b/src/H5G.c
index 6a7e505..042ce90 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -896,6 +896,24 @@ H5G_mkroot(H5F_t *f, hid_t dxpl_id, H5G_loc_t *loc)
*/
if(H5O_open(loc->oloc) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open root group")
+
+#ifndef H5_STRICT_FORMAT_CHECKS
+ /* If symbol table information is cached, check if we should replace the
+ * symbol table message with the cached symbol table information */
+ if((H5F_INTENT(f) & H5F_ACC_RDWR) && f->shared->root_ent
+ && (f->shared->root_ent->type == H5G_CACHED_STAB)) {
+ H5O_stab_t cached_stab;
+
+ /* Retrieve the cached symbol table information */
+ cached_stab.btree_addr = f->shared->root_ent->cache.stab.btree_addr;
+ cached_stab.heap_addr = f->shared->root_ent->cache.stab.heap_addr;
+
+ /* Check if the symbol table message is valid, and replace with the
+ * cached symbol table if necessary */
+ if(H5G_stab_valid(loc->oloc, dxpl_id, &cached_stab) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to verify symbol table")
+ } /* end if */
+#endif /* H5_STRICT_FORMAT_CHECKS */
} /* end else */
/* Create the path names for the root group's entry */
diff --git a/src/H5Gdense.c b/src/H5Gdense.c
index 6cc15b8..322b31b 100644
--- a/src/H5Gdense.c
+++ b/src/H5Gdense.c
@@ -988,9 +988,10 @@ H5G_dense_iterate(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
/* Check on iteration order */
if(order == H5_ITER_NATIVE) {
- HDassert(H5F_addr_defined(bt2_addr));
H5G_bt2_ud_it_t udata; /* User data for iterator callback */
+ HDassert(H5F_addr_defined(bt2_addr));
+
/* Open the fractal heap */
if(NULL == (fheap = H5HF_open(f, dxpl_id, linfo->fheap_addr)))
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
diff --git a/src/H5Gloc.c b/src/H5Gloc.c
index 908c9a3..b6a3a17 100644
--- a/src/H5Gloc.c
+++ b/src/H5Gloc.c
@@ -727,6 +727,7 @@ H5G_loc_set_comment_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name,
{
H5G_loc_sc_t *udata = (H5G_loc_sc_t *)_udata; /* User data passed in */
H5O_name_t comment; /* Object header "comment" message */
+ htri_t exists; /* Whether a "comment" message already exists */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5G_loc_set_comment_cb)
@@ -735,9 +736,14 @@ H5G_loc_set_comment_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name,
if(obj_loc == NULL)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist")
+ /* Check for existing comment message */
+ if((exists = H5O_msg_exists(obj_loc->oloc, H5O_NAME_ID, udata->dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read object header")
+
/* Remove the previous comment message if any */
- if(H5O_msg_remove(obj_loc->oloc, H5O_NAME_ID, 0, TRUE, udata->dxpl_id) < 0)
- H5E_clear_stack(NULL);
+ if(exists)
+ if(H5O_msg_remove(obj_loc->oloc, H5O_NAME_ID, 0, TRUE, udata->dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete existing comment object header message")
/* Add the new message */
if(udata->comment && *udata->comment) {
@@ -830,7 +836,7 @@ H5G_loc_get_comment_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name,
} else {
if(udata->comment && udata->bufsize)
HDstrncpy(udata->comment, comment.s, udata->bufsize);
- udata->comment_size = HDstrlen(comment.s);
+ udata->comment_size = (ssize_t)HDstrlen(comment.s);
H5O_msg_reset(H5O_NAME_ID, &comment);
} /* end else */
diff --git a/src/H5Gname.c b/src/H5Gname.c
index 205f2a2..581b649 100644
--- a/src/H5Gname.c
+++ b/src/H5Gname.c
@@ -578,7 +578,6 @@ H5G_name_move_path(H5RS_str_t **path_r_ptr, const char *full_suffix, const char
if(full_suffix_len < path_len) {
const char *dst_suffix; /* Destination suffix that changes */
const char *src_suffix; /* Source suffix that changes */
- const char *path_prefix; /* Prefix for path */
size_t path_prefix_len; /* Length of path prefix */
const char *path_prefix2; /* 2nd prefix for path */
size_t path_prefix2_len; /* Length of 2nd path prefix */
@@ -589,7 +588,6 @@ H5G_name_move_path(H5RS_str_t **path_r_ptr, const char *full_suffix, const char
/* Compute path prefix before full suffix*/
- path_prefix = path;
path_prefix_len = path_len - full_suffix_len;
/* Determine the common prefix for src & dst paths */
diff --git a/src/H5Gnode.c b/src/H5Gnode.c
index 6b16544..fe381fd 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -815,7 +815,7 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
/* Get a pointer to the name of the link */
if(NULL == (lnk.name = (char *)H5HL_offset_into(f, udata->common.heap, sn->entry[idx].name_off)))
- HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get link name")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5B_INS_ERROR, "unable to get link name")
/* Set up rest of link structure */
lnk.corder_valid = FALSE;
@@ -833,7 +833,7 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
/* Replace any object names */
if(H5G_link_name_replace(f, dxpl_id, udata->grp_full_path_r, &lnk) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get object type")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5B_INS_ERROR, "unable to get object type")
/* Decrement the ref. count for hard links */
if(lnk.type == H5L_TYPE_HARD) {
diff --git a/src/H5Gobj.c b/src/H5Gobj.c
index 3220b67..2eb1924 100644
--- a/src/H5Gobj.c
+++ b/src/H5Gobj.c
@@ -237,31 +237,49 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5G_obj_ent_decode(H5F_t *f, const uint8_t **pp, H5O_loc_t *oloc)
+H5G_obj_ent_decode(H5F_t *f, const uint8_t **pp, H5O_loc_t *oloc, H5G_entry_t **entp)
{
const uint8_t *p_ret = *pp;
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5G_obj_ent_decode)
+ FUNC_ENTER_NOAPI(H5G_obj_ent_decode, FAIL)
/* check arguments */
HDassert(f);
HDassert(pp);
HDassert(oloc);
- /* Set file pointer for root object location */
- oloc->file = f;
+ if(entp) {
+ /* If entp is not NULL we allocate space for the symbol table entry and
+ * decode the entire entry. */
+ if(!(*entp)) /* Only allocate space if *entp is NULL */
+ if(NULL == (*entp = (H5G_entry_t *) H5MM_calloc(sizeof(H5G_entry_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate space for symbol table entry")
+ if(H5G_ent_decode_vec(f, pp, *entp, 1) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode symbol table entry")
+
+ /* Set oloc to the correct values */
+ oloc->file = (*entp)->file;
+ oloc->addr = (*entp)->header;
+ } else {
+ /* Set file pointer for root object location */
+ oloc->file = f;
+
+ /* decode header */
+ *pp += H5F_SIZEOF_SIZE(f); /* Skip over local heap address */
+ H5F_addr_decode(f, pp, &(oloc->addr));
+ *pp += 4; /* Skip over "cache type" */
+ *pp += 4; /* Reserved */
+ }
+
+ /* Common oloc settings */
oloc->holding_file = FALSE;
- /* decode header */
- *pp += H5F_SIZEOF_SIZE(f); /* Skip over local heap address */
- H5F_addr_decode(f, pp, &(oloc->addr));
- *pp += 4; /* Skip over "cache type" */
- *pp += 4; /* Reserved */
-
/* Set decode pointer */
*pp = p_ret + H5G_SIZEOF_ENTRY(f);
- FUNC_LEAVE_NOAPI(SUCCEED)
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_obj_ent_decode() */
diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h
index 31e5713..38c7628 100644
--- a/src/H5Gpkg.h
+++ b/src/H5Gpkg.h
@@ -100,14 +100,14 @@ typedef union H5G_cache_t {
* also appears in the object header to which this symbol table entry
* points.
*/
-typedef struct H5G_entry_t {
+struct H5G_entry_t {
hbool_t dirty; /*entry out-of-date? */
H5G_cache_type_t type; /*type of information cached */
H5G_cache_t cache; /*cached data from object header */
size_t name_off; /*offset of name within name heap */
haddr_t header; /*file address of object header */
H5F_t *file; /*file to which this obj hdr belongs */
-} H5G_entry_t;
+};
/*
* A symbol table node is a collection of symbol table entries. It can
@@ -402,6 +402,10 @@ H5_DLL herr_t H5G_stab_lookup(H5O_loc_t *grp_oloc, const char *name,
H5O_link_t *lnk, hid_t dxpl_id);
H5_DLL herr_t H5G_stab_lookup_by_idx(H5O_loc_t *grp_oloc, H5_iter_order_t order,
hsize_t n, H5O_link_t *lnk, hid_t dxpl_id);
+#ifndef H5_STRICT_FORMAT_CHECKS
+H5_DLL herr_t H5G_stab_valid(H5O_loc_t *grp_oloc, hid_t dxpl_id,
+ H5O_stab_t *alt_stab);
+#endif /* H5_STRICT_FORMAT_CHECKS */
#ifndef H5_NO_DEPRECATED_SYMBOLS
H5_DLL H5G_obj_t H5G_stab_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx,
hid_t dxpl_id);
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index 591be6b..b1db96f 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -145,6 +145,7 @@ typedef struct {
typedef struct H5G_t H5G_t;
typedef struct H5G_shared_t H5G_shared_t;
+typedef struct H5G_entry_t H5G_entry_t;
/*
* Library prototypes... These are the ones that other packages routinely
@@ -181,7 +182,7 @@ H5_DLL herr_t H5G_node_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream
* These functions operate on group object locations.
*/
H5_DLL herr_t H5G_obj_ent_decode(H5F_t *f, const uint8_t **pp,
- struct H5O_loc_t *oloc);
+ struct H5O_loc_t *oloc, H5G_entry_t **entp);
H5_DLL herr_t H5G_obj_ent_encode(const H5F_t *f, uint8_t **pp,
const struct H5O_loc_t *oloc);
diff --git a/src/H5Gstab.c b/src/H5Gstab.c
index f79d78b..c2df8e7 100644
--- a/src/H5Gstab.c
+++ b/src/H5Gstab.c
@@ -982,6 +982,81 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_stab_lookup_by_idx() */
+#ifndef H5_STRICT_FORMAT_CHECKS
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_stab_valid
+ *
+ * Purpose: Verify that a group's symbol table message is valid. If
+ * provided, the addresses in alt_stab will be tried if the
+ * addresses in the group's stab message are invalid, and
+ * the stab message will be updated if necessary.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * nfortne2@hdfgroup.org
+ * Mar 17, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_stab_valid(H5O_loc_t *grp_oloc, hid_t dxpl_id, H5O_stab_t *alt_stab)
+{
+ H5O_stab_t stab; /* Current symbol table */
+ H5HL_t *heap = NULL; /* Pointer to local heap */
+ hbool_t changed = FALSE; /* Whether stab has been modified */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_stab_valid, FAIL)
+
+ /* Read the symbol table message */
+ H5O_msg_read(grp_oloc, H5O_STAB_ID, &stab, dxpl_id);
+
+ /* Check if the symbol table message's b-tree address is valid */
+ if(H5B_valid(grp_oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr) < 0) {
+ /* Address is invalid, try the b-tree address in the alternate symbol
+ * table message */
+ if(!alt_stab || H5B_valid(grp_oloc->file, dxpl_id, H5B_SNODE, alt_stab->btree_addr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "unable to locate b-tree")
+ else {
+ /* The alternate symbol table's b-tree address is valid. Adjust the
+ * symbol table message in the group. */
+ stab.btree_addr = alt_stab->btree_addr;
+ changed = TRUE;
+ } /* end else */
+ } /* end if */
+
+ /* Check if the symbol table message's heap address is valid */
+ if(NULL == (heap = H5HL_protect(grp_oloc->file, dxpl_id, stab.heap_addr, H5AC_READ))) {
+ /* Address is invalid, try the heap address in the alternate symbol
+ * table message */
+ if(!alt_stab || NULL == (heap = H5HL_protect(grp_oloc->file, dxpl_id, alt_stab->heap_addr, H5AC_READ)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "unable to locate heap")
+ else {
+ /* The alternate symbol table's heap address is valid. Adjust the
+ * symbol table message in the group. */
+ stab.heap_addr = alt_stab->heap_addr;
+ changed = TRUE;
+ } /* end else */
+ } /* end if */
+
+ /* Update the symbol table message and clear errors if necessary */
+ if(changed) {
+ H5E_clear_stack(NULL);
+ if(H5O_msg_write(grp_oloc, H5O_STAB_ID, 0, H5O_UPDATE_TIME | H5O_UPDATE_FORCE, &stab, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to correct symbol table message")
+ } /* end if */
+
+done:
+ /* Release resources */
+ if(heap && H5HL_unprotect(grp_oloc->file, dxpl_id, heap, stab.heap_addr) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_stab_valid */
+#endif /* H5_STRICT_FORMAT_CHECKS */
+
#ifndef H5_NO_DEPRECATED_SYMBOLS
/*-------------------------------------------------------------------------
diff --git a/src/H5HFbtree2.c b/src/H5HFbtree2.c
index eabb740..b750822 100644
--- a/src/H5HFbtree2.c
+++ b/src/H5HFbtree2.c
@@ -59,15 +59,6 @@
/* Local Prototypes */
/********************/
-/* v2 B-tree function callbacks */
-herr_t H5HF_huge_bt2_indir_found(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_indir_remove(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_filt_indir_found(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_filt_indir_remove(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_dir_remove(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_filt_dir_found(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_filt_dir_remove(const void *nrecord, void *op_data);
-
/* v2 B-tree driver callbacks */
static herr_t H5HF_huge_btree2_indir_store(void *native, const void *udata);
static herr_t H5HF_huge_btree2_indir_retrieve(void *udata, const void *native);
diff --git a/src/H5HFhuge.c b/src/H5HFhuge.c
index db9f7a1..60c6c9f 100644
--- a/src/H5HFhuge.c
+++ b/src/H5HFhuge.c
@@ -69,13 +69,13 @@
static herr_t H5HF_huge_bt2_create(H5HF_hdr_t *hdr, hid_t dxpl_id);
/* v2 B-tree function callbacks (in H5HFbtree2.c) */
-herr_t H5HF_huge_bt2_indir_found(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_indir_remove(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_filt_indir_found(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_filt_indir_remove(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_dir_remove(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_filt_dir_found(const void *nrecord, void *op_data);
-herr_t H5HF_huge_bt2_filt_dir_remove(const void *nrecord, void *op_data);
+H5_DLL herr_t H5HF_huge_bt2_indir_found(const void *nrecord, void *op_data);
+H5_DLL herr_t H5HF_huge_bt2_indir_remove(const void *nrecord, void *op_data);
+H5_DLL herr_t H5HF_huge_bt2_filt_indir_found(const void *nrecord, void *op_data);
+H5_DLL herr_t H5HF_huge_bt2_filt_indir_remove(const void *nrecord, void *op_data);
+H5_DLL herr_t H5HF_huge_bt2_dir_remove(const void *nrecord, void *op_data);
+H5_DLL herr_t H5HF_huge_bt2_filt_dir_found(const void *nrecord, void *op_data);
+H5_DLL herr_t H5HF_huge_bt2_filt_dir_remove(const void *nrecord, void *op_data);
/* Local 'huge' object support routines */
static hsize_t H5HF_huge_new_id(H5HF_hdr_t *hdr);
diff --git a/src/H5HFsection.c b/src/H5HFsection.c
index 81b353f..91031be 100644
--- a/src/H5HFsection.c
+++ b/src/H5HFsection.c
@@ -3105,7 +3105,6 @@ H5HF_sect_indirect_reduce_row(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_
unsigned start_col; /* Start column in indirect block */
unsigned end_entry; /* Entry for last block covered */
unsigned end_row; /* End row in indirect block */
- unsigned end_col; /* End column in indirect block */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_indirect_reduce_row)
@@ -3132,7 +3131,6 @@ HDfprintf(stderr, "%s: row_start_entry = %u, row_end_entry = %u\n", FUNC, row_st
start_entry = (start_row * hdr->man_dtable.cparam.width) + start_col;
end_entry = (start_entry + sect->u.indirect.num_entries) - 1;
end_row = end_entry / hdr->man_dtable.cparam.width;
- end_col = end_entry % hdr->man_dtable.cparam.width;
/* Additional sanity check */
HDassert(sect->u.indirect.span_size > 0);
@@ -3144,7 +3142,7 @@ HDfprintf(stderr, "%s: row_start_entry = %u, row_end_entry = %u\n", FUNC, row_st
HDfprintf(stderr, "%s: sect->sect_info = {%a, %Hu, %u, %s}\n", FUNC, sect->sect_info.addr, sect->sect_info.size, sect->sect_info.type, (sect->sect_info.state == H5FS_SECT_LIVE ? "H5FS_SECT_LIVE" : "H5FS_SECT_SERIALIZED"));
HDfprintf(stderr, "%s: sect->u.indirect.parent = %p, sect->u.indirect.par_entry = %u\n", FUNC, sect->u.indirect.parent, sect->u.indirect.par_entry);
HDfprintf(stderr, "%s: start_entry = %u, start_row = %u, start_col = %u\n", FUNC, start_entry, start_row, start_col);
-HDfprintf(stderr, "%s: end_entry = %u, end_row = %u, end_col = %u\n", FUNC, end_entry, end_row, end_col);
+HDfprintf(stderr, "%s: end_entry = %u, end_row = %u\n", FUNC, end_entry, end_row);
#endif /* QAK */
/* Check if we should allocate from end of indirect section */
@@ -3400,7 +3398,6 @@ H5HF_sect_indirect_reduce(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *s
unsigned start_col; /* Start column in indirect block */
unsigned end_entry; /* Entry for last block covered */
unsigned end_row; /* End row in indirect block */
- unsigned end_col; /* End column in indirect block */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_indirect_reduce)
@@ -3422,12 +3419,11 @@ HDfprintf(stderr, "%s: child_entry = %u\n", FUNC, child_entry);
start_entry = (start_row * hdr->man_dtable.cparam.width) + start_col;
end_entry = (start_entry + sect->u.indirect.num_entries) - 1;
end_row = end_entry / hdr->man_dtable.cparam.width;
- end_col = end_entry % hdr->man_dtable.cparam.width;
#ifdef QAK
HDfprintf(stderr, "%s: sect->sect_info = {%a, %Hu, %u, %s}\n", FUNC, sect->sect_info.addr, sect->sect_info.size, sect->sect_info.type, (sect->sect_info.state == H5FS_SECT_LIVE ? "H5FS_SECT_LIVE" : "H5FS_SECT_SERIALIZED"));
HDfprintf(stderr, "%s: sect->u.indirect.parent = %p, sect->u.indirect.par_entry = %u\n", FUNC, sect->u.indirect.parent, sect->u.indirect.par_entry);
HDfprintf(stderr, "%s: start_entry = %u, start_row = %u, start_col = %u\n", FUNC, start_entry, start_row, start_col);
-HDfprintf(stderr, "%s: end_entry = %u, end_row = %u, end_col = %u\n", FUNC, end_entry, end_row, end_col);
+HDfprintf(stderr, "%s: end_entry = %u, end_row = %u\n", FUNC, end_entry, end_row);
#endif /* QAK */
/* Check how to adjust section for allocated entry */
@@ -3780,9 +3776,7 @@ H5HF_sect_indirect_merge_row(H5HF_hdr_t *hdr, hid_t dxpl_id,
unsigned start_row1, start_col1; /* Starting row & column for section #1 */
unsigned end_entry1; /* End entry for section #1 */
unsigned end_row1; /* Ending row for section #1 */
- unsigned start_entry2; /* Start entry for section #2 */
- unsigned start_row2, start_col2; /* Starting row & column for section #2 */
- unsigned end_entry2; /* End entry for section #2 */
+ unsigned start_row2; /* Starting row for section #2 */
hbool_t merged_rows; /* Flag to indicate that rows was merged together */
unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -3831,12 +3825,9 @@ HDfprintf(stderr, "%s: sect1->u.indirect.num_entries = %u\n", FUNC, sect1->u.ind
HDfprintf(stderr, "%s: end_row1 = %u, end_entry1 = %u\n", FUNC, end_row1, end_entry1);
#endif /* QAK */
start_row2 = sect2->u.indirect.row;
- start_col2 = sect2->u.indirect.col;
- start_entry2 = (start_row2 * hdr->man_dtable.cparam.width) + start_col2;
- end_entry2 = (start_entry2 + sect2->u.indirect.num_entries) - 1;
#ifdef QAK
HDfprintf(stderr, "%s: sect2->u.indirect.dir_nrows = %u\n", FUNC, sect2->u.indirect.dir_nrows);
-HDfprintf(stderr, "%s: start_row2 = %u, start_col2 = %u, start_entry2 = %u\n", FUNC, start_row2, start_col2, start_entry2);
+HDfprintf(stderr, "%s: start_row2 = %u\n", FUNC, start_row2);
HDfprintf(stderr, "%s: sect2->u.indirect.num_entries = %u\n", FUNC, sect2->u.indirect.num_entries);
#endif /* QAK */
diff --git a/src/H5HGdbg.c b/src/H5HGdbg.c
index 43c1ed0..7030da5 100644
--- a/src/H5HGdbg.c
+++ b/src/H5HGdbg.c
@@ -113,7 +113,7 @@ H5HG_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
(unsigned long)H5HG_ALIGN(h->obj[u].size));
p = h->obj[u].begin + H5HG_SIZEOF_OBJHDR (f);
for (j=0; j<h->obj[u].size; j+=16) {
- fprintf (stream, "%*s%04d: ", indent+6, "", j);
+ fprintf (stream, "%*s%04u: ", indent+6, "", j);
for (k=0; k<16; k++) {
if (8==k) fprintf (stream, " ");
if (j+k<h->obj[u].size) {
diff --git a/src/H5Oainfo.c b/src/H5Oainfo.c
index 667f28c..e61d899 100644
--- a/src/H5Oainfo.c
+++ b/src/H5Oainfo.c
@@ -403,7 +403,7 @@ H5O_ainfo_pre_copy_file(H5F_t UNUSED *file_src, const void UNUSED *native_src,
*/
static void *
H5O_ainfo_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst,
- hbool_t *recompute_size, H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id)
+ hbool_t *recompute_size, H5O_copy_t *cpy_info, void UNUSED *udata, hid_t dxpl_id)
{
H5O_ainfo_t *ainfo_src = (H5O_ainfo_t *)mesg_src;
H5O_ainfo_t *ainfo_dst = NULL;
@@ -467,7 +467,7 @@ static herr_t
H5O_ainfo_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src,
H5O_loc_t *dst_oloc, void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info)
{
- H5O_ainfo_t *ainfo_src = (const H5O_ainfo_t *)mesg_src;
+ const H5O_ainfo_t *ainfo_src = (const H5O_ainfo_t *)mesg_src;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_ainfo_post_copy_file)
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index 24e443c..fe8c627 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -115,20 +115,23 @@ const H5O_msg_class_t H5O_MSG_DTYPE[1] = {{
*
* Purpose: Decodes a datatype
*
- * Return: Non-negative on success/Negative on failure
+ * Return: TRUE if we can upgrade the parent type's version even
+ * with strict format checks
+ * FALSE if we cannot
+ * Negative on failure
*
* Programmer: Robb Matzke
* Monday, December 8, 1997
*
*-------------------------------------------------------------------------
*/
-static herr_t
+static htri_t
H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **pp, H5T_t *dt)
{
unsigned flags, version;
unsigned i;
size_t z;
- herr_t ret_value = SUCCEED; /* Return value */
+ htri_t ret_value = FALSE; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_dtype_decode_helper)
@@ -254,6 +257,7 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p
unsigned offset_nbytes; /* Size needed to encode member offsets */
size_t max_memb_pos = 0; /* Maximum member covered, so far */
unsigned max_version = 0; /* Maximum member version */
+ hbool_t upgrade_to = 0; /* Version number we can "soft" upgrade to */
unsigned j;
/* Compute the # of bytes required to store a member offset */
@@ -271,6 +275,7 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
for(i = 0; i < dt->shared->u.compnd.nmembs; i++) {
unsigned ndims = 0; /* Number of dimensions of the array field */
+ htri_t can_upgrade; /* Whether we can upgrade this type's version */
hsize_t dim[H5O_LAYOUT_NDIMS]; /* Dimensions of the array */
H5T_t *array_dt; /* Temporary pointer to the array datatype */
H5T_t *temp_type; /* Temporary pointer to the field's datatype */
@@ -318,16 +323,20 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Decode the field's datatype information */
- if(H5O_dtype_decode_helper(f, ioflags, pp, temp_type) < 0) {
+ if((can_upgrade = H5O_dtype_decode_helper(f, ioflags, pp, temp_type)) < 0) {
for(j = 0; j <= i; j++)
H5MM_xfree(dt->shared->u.compnd.memb[j].name);
H5MM_xfree(dt->shared->u.compnd.memb);
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode member type")
} /* end if */
- /* Keep track of the maximum member version found */
- if(temp_type->shared->version > max_version)
- max_version = temp_type->shared->version;
+ /* Upgrade the version if we can and it is necessary */
+ if(can_upgrade && temp_type->shared->version > version) {
+ upgrade_to = temp_type->shared->version;
+
+ /* Pass "can_upgrade" flag down to parent type */
+ ret_value = TRUE;
+ } /* end if */
/* Go create the array datatype now, for older versions of the datatype message */
if(version == H5O_DTYPE_VERSION_1) {
@@ -346,9 +355,26 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p
/* Make the array type the type that is set for the field */
temp_type = array_dt;
+
+ /* Reset array version if NOCHANGE is specified (i.e. h5debug) */
+ if(*ioflags & H5O_DECODEIO_NOCHANGE)
+ temp_type->shared->version = H5O_DTYPE_VERSION_1;
+ else {
+ /* Otherwise upgrade the compound version */
+ if(upgrade_to < temp_type->shared->version)
+ upgrade_to = temp_type->shared->version;
+
+ /* Set the return value to indicate that we should freely
+ * upgrade parent types */
+ ret_value = TRUE;
+ } /* end else */
} /* end if */
} /* end if */
+ /* Keep track of the maximum member version found */
+ if(temp_type->shared->version > max_version)
+ max_version = temp_type->shared->version;
+
/*
* Set the "force conversion" flag if VL datatype fields exist in this
* type or any component types
@@ -397,6 +423,17 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p
dt->shared->u.compnd.packed = FALSE;
} /* end if */
} /* end for */
+
+ /* Upgrade the compound if requested */
+ if(version < upgrade_to) {
+ version = upgrade_to;
+ if(H5T_upgrade_version(dt, upgrade_to) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't upgrade compound encoding version")
+ /* We won't mark the message dirty since there were no
+ * errors in the file, simply type versions that we will no
+ * longer encode. */
+ } /* end if */
+
/* Check that no member of this compound has a version greater
* than the compound itself. */
H5O_DTYPE_CHECK_VERSION(dt, version, max_version, ioflags, "compound", FAIL)
@@ -1580,11 +1617,11 @@ H5O_dtype_debug(H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream,
"Version:", dt->shared->version);
if (H5T_COMPOUND == dt->shared->type) {
- fprintf(stream, "%*s%-*s %d\n", indent, "", fwidth,
+ fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"Number of members:",
dt->shared->u.compnd.nmembs);
for(i = 0; i < dt->shared->u.compnd.nmembs; i++) {
- sprintf(buf, "Member %d:", i);
+ sprintf(buf, "Member %u:", i);
fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
buf,
dt->shared->u.compnd.memb[i].name);
@@ -1597,11 +1634,11 @@ H5O_dtype_debug(H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream,
} else if(H5T_ENUM == dt->shared->type) {
fprintf(stream, "%*s%s\n", indent, "", "Base type:");
H5O_dtype_debug(f, dxpl_id, dt->shared->parent, stream, indent+3, MAX(0, fwidth-3));
- fprintf(stream, "%*s%-*s %d\n", indent, "", fwidth,
+ fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"Number of members:",
dt->shared->u.enumer.nmembs);
for(i = 0; i < dt->shared->u.enumer.nmembs; i++) {
- sprintf(buf, "Member %d:", i);
+ sprintf(buf, "Member %u:", i);
fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
buf,
dt->shared->u.enumer.name[i]);
@@ -1678,7 +1715,7 @@ H5O_dtype_debug(H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream,
s = "disk";
break;
default:
- sprintf(buf, "H5T_LOC_%d", dt->shared->u.vlen.loc);
+ sprintf(buf, "H5T_LOC_%d", (int)dt->shared->u.vlen.loc);
s = buf;
break;
} /* end switch */
@@ -1723,7 +1760,7 @@ H5O_dtype_debug(H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream,
s);
} /* end if */
} else if(H5T_ARRAY == dt->shared->type) {
- fprintf(stream, "%*s%-*s %d\n", indent, "", fwidth,
+ fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"Rank:",
dt->shared->u.array.ndims);
fprintf(stream, "%*s%-*s {", indent, "", fwidth, "Dim Size:");
diff --git a/src/H5Omessage.c b/src/H5Omessage.c
index 286240c..4a9ecb5 100644
--- a/src/H5Omessage.c
+++ b/src/H5Omessage.c
@@ -393,7 +393,7 @@ H5O_msg_write_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_msg_class_t *ty
HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "message type not found")
/* Check for modifying a constant message */
- if(idx_msg->flags & H5O_MSG_FLAG_CONSTANT)
+ if(!(update_flags & H5O_UPDATE_FORCE) && (idx_msg->flags & H5O_MSG_FLAG_CONSTANT))
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to modify constant message")
/* This message is shared, but it's being modified. */
else if((idx_msg->flags & H5O_MSG_FLAG_SHARED) || (idx_msg->flags & H5O_MSG_FLAG_SHAREABLE)) {
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index c623b73..c2116bb 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -79,6 +79,7 @@ typedef struct H5O_t H5O_t;
/* Flags for updating messages */
#define H5O_UPDATE_TIME 0x01u
+#define H5O_UPDATE_FORCE 0x02u /* Force updating the message */
/* Hash value constants */
#define H5O_HASH_SIZE 32
diff --git a/src/H5RC.c b/src/H5RC.c
index 49e26a8..d9f62c3 100644
--- a/src/H5RC.c
+++ b/src/H5RC.c
@@ -55,25 +55,25 @@ H5FL_DEFINE_STATIC(H5RC_t);
H5RC_t *
H5RC_create(void *o, H5RC_free_func_t free_func)
{
- H5RC_t *ret_value=NULL; /* Return value */
+ H5RC_t *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5RC_create,NULL);
+ FUNC_ENTER_NOAPI(H5RC_create, NULL)
/* Sanity check */
HDassert(o);
HDassert(free_func);
/* Allocate ref-counted string structure */
- if((ret_value=H5FL_MALLOC(H5RC_t))==NULL)
- HGOTO_ERROR(H5E_RS,H5E_NOSPACE,NULL,"memory allocation failed");
+ if(NULL == (ret_value = H5FL_MALLOC(H5RC_t)))
+ HGOTO_ERROR(H5E_RS,H5E_NOSPACE,NULL,"memory allocation failed")
/* Set the internal fields */
- ret_value->o=o;
- ret_value->n=1;
- ret_value->free_func=free_func;
+ ret_value->o = o;
+ ret_value->n = 1;
+ ret_value->free_func = free_func;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5RC_create() */
diff --git a/src/H5RS.c b/src/H5RS.c
index 0142c1f..6456ac8 100644
--- a/src/H5RS.c
+++ b/src/H5RS.c
@@ -63,7 +63,7 @@ H5RS_xstrdup(const char *s)
{
char *ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5RS_xstrdup)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5RS_xstrdup)
if(s) {
ret_value = (char *)H5FL_BLK_MALLOC(str_buf, HDstrlen(s) + 1);
@@ -99,21 +99,21 @@ H5RS_xstrdup(const char *s)
H5RS_str_t *
H5RS_create(const char *s)
{
- H5RS_str_t *ret_value=NULL; /* Return value */
+ H5RS_str_t *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5RS_create,NULL);
+ FUNC_ENTER_NOAPI(H5RS_create, NULL)
/* Allocate ref-counted string structure */
- if((ret_value=H5FL_MALLOC(H5RS_str_t))==NULL)
- HGOTO_ERROR(H5E_RS,H5E_NOSPACE,NULL,"memory allocation failed");
+ if(NULL == (ret_value = H5FL_MALLOC(H5RS_str_t)))
+ HGOTO_ERROR(H5E_RS, H5E_NOSPACE, NULL, "memory allocation failed")
/* Set the internal fields */
- ret_value->s=H5RS_xstrdup(s);
- ret_value->wrapped=0;
- ret_value->n=1;
+ ret_value->s = H5RS_xstrdup(s);
+ ret_value->wrapped = 0;
+ ret_value->n = 1;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5RS_create() */
@@ -139,21 +139,21 @@ done:
H5RS_str_t *
H5RS_wrap(const char *s)
{
- H5RS_str_t *ret_value=NULL; /* Return value */
+ H5RS_str_t *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5RS_wrap,NULL);
+ FUNC_ENTER_NOAPI(H5RS_wrap, NULL)
/* Allocate ref-counted string structure */
- if((ret_value=H5FL_MALLOC(H5RS_str_t))==NULL)
- HGOTO_ERROR(H5E_RS,H5E_NOSPACE,NULL,"memory allocation failed");
+ if(NULL == (ret_value = H5FL_MALLOC(H5RS_str_t)))
+ HGOTO_ERROR(H5E_RS, H5E_NOSPACE, NULL, "memory allocation failed")
/* Set the internal fields */
- ret_value->s=(char*)s; /* (Cast away const OK - QAK) */
- ret_value->wrapped=1;
- ret_value->n=1;
+ ret_value->s = (char*)s; /* (Cast away const OK - QAK) */
+ ret_value->wrapped = 1;
+ ret_value->n = 1;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5RS_wrap() */
@@ -181,21 +181,21 @@ done:
H5RS_str_t *
H5RS_own(char *s)
{
- H5RS_str_t *ret_value=NULL; /* Return value */
+ H5RS_str_t *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5RS_own,NULL);
+ FUNC_ENTER_NOAPI(H5RS_own, NULL)
/* Allocate ref-counted string structure */
- if((ret_value=H5FL_MALLOC(H5RS_str_t))==NULL)
- HGOTO_ERROR(H5E_RS,H5E_NOSPACE,NULL,"memory allocation failed");
+ if(NULL == (ret_value = H5FL_MALLOC(H5RS_str_t)))
+ HGOTO_ERROR(H5E_RS, H5E_NOSPACE, NULL, "memory allocation failed")
/* Set the internal fields */
- ret_value->s=s;
- ret_value->wrapped=0;
- ret_value->n=1;
+ ret_value->s = s;
+ ret_value->wrapped = 0;
+ ret_value->n = 1;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5RS_own() */
@@ -259,25 +259,25 @@ H5RS_decr(H5RS_str_t *rs)
herr_t
H5RS_incr(H5RS_str_t *rs)
{
- FUNC_ENTER_NOAPI_NOFUNC(H5RS_incr);
+ FUNC_ENTER_NOAPI_NOFUNC(H5RS_incr)
/* Sanity check */
- assert(rs);
- assert(rs->n > 0);
+ HDassert(rs);
+ HDassert(rs->n > 0);
/* If the ref-counted string started life as a wrapper around an existing
* string, duplicate the string now, so that the wrapped string can go out
* scope appropriately.
*/
if(rs->wrapped) {
- rs->s=H5RS_xstrdup(rs->s);
- rs->wrapped=0;
+ rs->s = H5RS_xstrdup(rs->s);
+ rs->wrapped = 0;
} /* end if */
/* Increment reference count for string */
rs->n++;
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5RS_incr() */
@@ -303,14 +303,14 @@ H5RS_incr(H5RS_str_t *rs)
H5RS_str_t *
H5RS_dup(H5RS_str_t *ret_value)
{
- FUNC_ENTER_NOAPI_NOFUNC(H5RS_dup);
+ FUNC_ENTER_NOAPI_NOFUNC(H5RS_dup)
/* Check for valid reference counted string */
- if(ret_value!=NULL)
+ if(ret_value != NULL)
/* Increment reference count for string */
ret_value->n++;
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5RS_dup() */
@@ -335,7 +335,7 @@ H5RS_dup(H5RS_str_t *ret_value)
H5RS_str_t *
H5RS_dup_str(const char *s)
{
- char *new_str = NULL; /* Duplicate of string */
+ char *new_str; /* Duplicate of string */
size_t path_len; /* Length of the path */
H5RS_str_t *ret_value;
@@ -387,15 +387,15 @@ int
H5RS_cmp(const H5RS_str_t *rs1, const H5RS_str_t *rs2)
{
/* Can't return invalid value from this function */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5RS_cmp);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5RS_cmp)
/* Sanity check */
- assert(rs1);
- assert(rs1->s);
- assert(rs2);
- assert(rs2->s);
+ HDassert(rs1);
+ HDassert(rs1->s);
+ HDassert(rs2);
+ HDassert(rs2->s);
- FUNC_LEAVE_NOAPI(HDstrcmp(rs1->s,rs2->s));
+ FUNC_LEAVE_NOAPI(HDstrcmp(rs1->s, rs2->s))
} /* end H5RS_cmp() */
@@ -420,13 +420,13 @@ H5RS_cmp(const H5RS_str_t *rs1, const H5RS_str_t *rs2)
ssize_t
H5RS_len(const H5RS_str_t *rs)
{
- FUNC_ENTER_NOAPI_NOFUNC(H5RS_len);
+ FUNC_ENTER_NOAPI_NOFUNC(H5RS_len)
/* Sanity check */
- assert(rs);
- assert(rs->s);
+ HDassert(rs);
+ HDassert(rs->s);
- FUNC_LEAVE_NOAPI((ssize_t)HDstrlen(rs->s));
+ FUNC_LEAVE_NOAPI((ssize_t)HDstrlen(rs->s))
} /* end H5RS_len() */
@@ -454,13 +454,13 @@ H5RS_len(const H5RS_str_t *rs)
char *
H5RS_get_str(const H5RS_str_t *rs)
{
- FUNC_ENTER_NOAPI_NOFUNC(H5RS_get_str);
+ FUNC_ENTER_NOAPI_NOFUNC(H5RS_get_str)
/* Sanity check */
- assert(rs);
- assert(rs->s);
+ HDassert(rs);
+ HDassert(rs->s);
- FUNC_LEAVE_NOAPI(rs->s);
+ FUNC_LEAVE_NOAPI(rs->s)
} /* end H5RS_get_str() */
@@ -486,12 +486,12 @@ H5RS_get_str(const H5RS_str_t *rs)
unsigned
H5RS_get_count(const H5RS_str_t *rs)
{
- FUNC_ENTER_NOAPI_NOFUNC(H5RS_get_count);
+ FUNC_ENTER_NOAPI_NOFUNC(H5RS_get_count)
/* Sanity check */
- assert(rs);
- assert(rs->n>0);
+ HDassert(rs);
+ HDassert(rs->n > 0);
- FUNC_LEAVE_NOAPI(rs->n);
+ FUNC_LEAVE_NOAPI(rs->n)
} /* end H5RS_get_count() */
diff --git a/src/H5ST.c b/src/H5ST.c
index 7dee73f..6d14115 100644
--- a/src/H5ST.c
+++ b/src/H5ST.c
@@ -50,19 +50,19 @@ H5FL_DEFINE_STATIC(H5ST_tree_t);
H5ST_tree_t *
H5ST_create(void)
{
- H5ST_tree_t *ret_value=NULL; /* Return value */
+ H5ST_tree_t *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5ST_create,NULL);
+ FUNC_ENTER_NOAPI(H5ST_create, NULL)
/* Allocate wrapper for TST */
- if((ret_value=H5FL_MALLOC(H5ST_tree_t))==NULL)
- HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,NULL,"memory allocation failed");
+ if(NULL == (ret_value = H5FL_MALLOC(H5ST_tree_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Set the internal fields */
- ret_value->root=NULL;
+ ret_value->root = NULL;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5ST_create() */
@@ -178,16 +178,16 @@ H5ST_insert(H5ST_tree_t *tree, const char *s, void *obj)
p = &tree->root;
while((pp = *p)) {
/* If this node matches the character in the key, then drop down to the lower tree */
- if ((d = *s - pp->splitchar) == 0) {
- if (*s++ == 0)
- HGOTO_ERROR(H5E_TST,H5E_EXISTS,FAIL,"key already in tree");
+ if(0 == (d = *s - pp->splitchar)) {
+ if(*s++ == 0)
+ HGOTO_ERROR(H5E_TST, H5E_EXISTS, FAIL, "key already in tree")
up=pp;
p = &(pp->eqkid);
} /* end if */
else {
/* Walk through the current tree, searching for the matching character */
- parent=pp;
- if (d < 0)
+ parent = pp;
+ if(d < 0)
p = &(pp->lokid);
else
p = &(pp->hikid);
@@ -196,8 +196,8 @@ H5ST_insert(H5ST_tree_t *tree, const char *s, void *obj)
/* Finish walking through the key string, adding nodes until the end */
for (;;) {
- if((*p = H5FL_MALLOC(H5ST_node_t))==NULL)
- HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed");
+ if(NULL == (*p = H5FL_MALLOC(H5ST_node_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
pp = *p;
pp->splitchar = *s;
pp->up = up;
@@ -205,19 +205,19 @@ H5ST_insert(H5ST_tree_t *tree, const char *s, void *obj)
pp->lokid = pp->eqkid = pp->hikid = NULL;
/* If this is the end of the key string, break out */
- if (*s++ == 0) {
- pp->eqkid = (H5ST_ptr_t) obj;
+ if(*s++ == 0) {
+ pp->eqkid = (H5ST_ptr_t)obj;
break;
} /* end if */
/* Continue to next character */
- parent=NULL;
- up=pp;
+ parent = NULL;
+ up = pp;
p = &(pp->eqkid);
} /* end for */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5ST_insert() */
@@ -247,7 +247,7 @@ H5ST_search(H5ST_tree_t *tree, const char *s)
H5ST_ptr_t p; /* Temporary pointer to TST node */
htri_t ret_value=FALSE; /* Return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5ST_search);
+ FUNC_ENTER_NOAPI_NOFUNC(H5ST_search)
p = tree->root;
while (p) {
@@ -262,7 +262,7 @@ H5ST_search(H5ST_tree_t *tree, const char *s)
} /* end while */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5ST_search() */
@@ -289,9 +289,9 @@ done:
static H5ST_ptr_t
H5ST_find_internal(H5ST_ptr_t p, const char *s)
{
- H5ST_ptr_t ret_value=NULL; /* Return value */
+ H5ST_ptr_t ret_value = NULL; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5ST_find_internal);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5ST_find_internal)
while (p) {
if (*s < p->splitchar)
@@ -305,7 +305,7 @@ H5ST_find_internal(H5ST_ptr_t p, const char *s)
} /* end while */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5ST_find_internal() */
@@ -332,15 +332,15 @@ done:
H5ST_ptr_t
H5ST_find(H5ST_tree_t *tree, const char *s)
{
- H5ST_ptr_t ret_value=NULL; /* Return value */
+ H5ST_ptr_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5ST_find,NULL);
+ FUNC_ENTER_NOAPI(H5ST_find, NULL)
- if((ret_value=H5ST_find_internal(tree->root,s))==NULL)
- HGOTO_ERROR(H5E_TST,H5E_NOTFOUND,NULL,"key not found in TST");
+ if(NULL == (ret_value = H5ST_find_internal(tree->root, s)))
+ HGOTO_ERROR(H5E_TST, H5E_NOTFOUND, NULL, "key not found in TST")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5ST_find() */
@@ -369,17 +369,17 @@ H5ST_locate(H5ST_tree_t *tree, const char *s)
H5ST_ptr_t node; /* Pointer to node located */
void *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5ST_locate,NULL);
+ FUNC_ENTER_NOAPI(H5ST_locate, NULL)
/* Locate the node to remove */
- if((node=H5ST_find_internal(tree->root,s))==NULL)
- HGOTO_ERROR(H5E_TST,H5E_NOTFOUND,NULL,"key not found in TST");
+ if(NULL == (node = H5ST_find_internal(tree->root, s)))
+ HGOTO_ERROR(H5E_TST, H5E_NOTFOUND, NULL, "key not found in TST")
/* Get the pointer to the object to return */
- ret_value=node->eqkid;
+ ret_value = node->eqkid;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5ST_locate() */
@@ -404,28 +404,28 @@ done:
static H5ST_ptr_t
H5ST_findfirst_internal(H5ST_ptr_t p)
{
- H5ST_ptr_t ret_value=NULL; /* Return value */
+ H5ST_ptr_t ret_value = NULL; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5ST_findfirst_internal);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5ST_findfirst_internal)
while(p) {
/* Find least node in current tree */
while(p->lokid)
- p=p->lokid;
+ p = p->lokid;
/* Is least node '\0'? */
- if(p->splitchar=='\0') {
+ if(p->splitchar == '\0') {
/* Return it */
HGOTO_DONE(p);
} /* end if */
else {
/* Go down to next level of tree */
- p=p->eqkid;
+ p = p->eqkid;
} /* end else */
} /* end while */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5ST_findfirst_internal() */
@@ -452,13 +452,13 @@ H5ST_findfirst(H5ST_tree_t *tree)
{
H5ST_ptr_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5ST_findfirst,NULL);
+ FUNC_ENTER_NOAPI(H5ST_findfirst, NULL)
- if((ret_value=H5ST_findfirst_internal(tree->root))==NULL)
+ if(NULL == (ret_value = H5ST_findfirst_internal(tree->root)))
HGOTO_ERROR(H5E_TST,H5E_NOTFOUND,NULL,"no nodes in TST");
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5ST_findfirst() */
@@ -483,40 +483,40 @@ done:
static H5ST_ptr_t
H5ST_getnext(H5ST_ptr_t p)
{
- H5ST_ptr_t ret_value=NULL; /* Return value */
+ H5ST_ptr_t ret_value = NULL; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5ST_getnext);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5ST_getnext)
/* If the node to continue from has higher-valued nodes attached */
if(p->hikid) {
/* Go to first higher-valued node */
- p=p->hikid;
+ p = p->hikid;
/* Find least node from here */
while(p->lokid)
- p=p->lokid;
+ p = p->lokid;
HGOTO_DONE(p);
} /* end if */
else {
H5ST_ptr_t q; /* Temporary TST node pointer */
/* Go up one level in current tree */
- q=p->parent;
- if(q==NULL)
+ q = p->parent;
+ if(q == NULL)
HGOTO_DONE(NULL);
/* While the previous node was the higher-valued node, keep backing up the tree */
- while(q->hikid==p) {
- p=q;
- q=p->parent;
- if(q==NULL)
+ while(q->hikid == p) {
+ p = q;
+ q = p->parent;
+ if(NULL == q)
HGOTO_DONE(NULL);
} /* end while */
HGOTO_DONE(q);
} /* end else */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5ST_getnext() */
@@ -542,22 +542,22 @@ H5ST_ptr_t
H5ST_findnext(H5ST_ptr_t p)
{
H5ST_ptr_t q; /* Temporary pointer to TST node */
- H5ST_ptr_t ret_value=NULL; /* Return value */
+ H5ST_ptr_t ret_value = NULL; /* Return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5ST_findnext);
+ FUNC_ENTER_NOAPI_NOFUNC(H5ST_findnext)
/* Find the next node at the current level, or go back up the tree */
do {
- q=H5ST_getnext(p);
+ q = H5ST_getnext(p);
if(q) {
HGOTO_DONE(H5ST_findfirst_internal(q->eqkid));
} /* end if */
else
- p=p->up;
+ p = p->up;
} while(p);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5ST_findnext() */
@@ -661,15 +661,15 @@ H5ST_delete_internal(H5ST_ptr_t *root, H5ST_ptr_t p)
herr_t
H5ST_delete(H5ST_tree_t *tree, H5ST_ptr_t p)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5ST_delete,FAIL);
+ FUNC_ENTER_NOAPI(H5ST_delete, FAIL)
- if(H5ST_delete_internal(&tree->root,p)<0)
- HGOTO_ERROR(H5E_TST,H5E_CANTDELETE,FAIL,"can't delete node from TST");
+ if(H5ST_delete_internal(&tree->root, p) < 0)
+ HGOTO_ERROR(H5E_TST, H5E_CANTDELETE, FAIL, "can't delete node from TST")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5ST_delete() */
@@ -698,21 +698,21 @@ H5ST_remove(H5ST_tree_t *tree, const char *s)
H5ST_ptr_t node; /* Pointer to node to remove */
void *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5ST_remove,NULL);
+ FUNC_ENTER_NOAPI(H5ST_remove, NULL)
/* Locate the node to remove */
- if((node=H5ST_find_internal(tree->root,s))==NULL)
- HGOTO_ERROR(H5E_TST,H5E_NOTFOUND,NULL,"key not found in TST");
+ if(NULL == (node = H5ST_find_internal(tree->root, s)))
+ HGOTO_ERROR(H5E_TST, H5E_NOTFOUND, NULL, "key not found in TST")
/* Get the pointer to the object to return */
- ret_value=node->eqkid;
+ ret_value = node->eqkid;
/* Remove the node from the TST */
- if(H5ST_delete_internal(&tree->root,node)<0)
- HGOTO_ERROR(H5E_TST,H5E_CANTDELETE,NULL,"can't delete node from TST");
+ if(H5ST_delete_internal(&tree->root, node) < 0)
+ HGOTO_ERROR(H5E_TST, H5E_CANTDELETE, NULL, "can't delete node from TST")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5ST_remove() */
#ifdef H5ST_DEBUG
@@ -738,26 +738,26 @@ done:
herr_t
H5ST_dump_internal(H5ST_ptr_t p)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5ST_dump_internal);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5ST_dump_internal)
- if (p) {
- printf("p=%p\n",p);
- printf("\tp->up=%p\n",p->up);
- printf("\tp->parent=%p\n",p->parent);
- printf("\tp->lokid=%p\n",p->lokid);
- printf("\tp->hikid=%p\n",p->hikid);
- printf("\tp->eqkid=%p\n",p->eqkid);
- printf("\tp->splitchar=%c\n",p->splitchar);
+ if(p) {
+ printf("p=%p\n", p);
+ printf("\tp->up=%p\n", p->up);
+ printf("\tp->parent=%p\n", p->parent);
+ printf("\tp->lokid=%p\n", p->lokid);
+ printf("\tp->hikid=%p\n", p->hikid);
+ printf("\tp->eqkid=%p\n", p->eqkid);
+ printf("\tp->splitchar=%c\n", p->splitchar);
H5ST_dump_internal(p->lokid);
- if (p->splitchar)
+ if(p->splitchar)
H5ST_dump_internal(p->eqkid);
else
- printf("%s\n", (char *) p->eqkid);
+ printf("%s\n", (char *)p->eqkid);
H5ST_dump_internal(p->hikid);
} /* end if */
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5ST_dump_internal() */
@@ -782,11 +782,12 @@ H5ST_dump_internal(H5ST_ptr_t p)
herr_t
H5ST_dump(H5ST_tree_t *tree)
{
- FUNC_ENTER_NOAPI_NOFUNC(H5ST_dump,NULL);
+ FUNC_ENTER_NOAPI_NOFUNC(H5ST_dump, NULL)
/* Dump the tree */
H5ST_dump_internal(tree->root);
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5ST_dump() */
#endif /* H5ST_DEBUG */
+
diff --git a/src/H5Smpio.c b/src/H5Smpio.c
index 1f69706..72d61e6 100644
--- a/src/H5Smpio.c
+++ b/src/H5Smpio.c
@@ -107,17 +107,17 @@ H5S_mpio_all_type( const H5S_t *space, size_t elmt_size,
hsize_t nelmts; /*total number of elmts */
herr_t ret_value = SUCCEED;
- FUNC_ENTER_NOAPI_NOINIT(H5S_mpio_all_type);
+ FUNC_ENTER_NOAPI_NOINIT(H5S_mpio_all_type)
/* Check args */
- assert (space);
+ HDassert(space);
/* Just treat the entire extent as a block of bytes */
- if((snelmts = H5S_GET_EXTENT_NPOINTS(space))<0)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "src dataspace has invalid selection")
- H5_ASSIGN_OVERFLOW(nelmts,snelmts,hssize_t,hsize_t);
+ if((snelmts = H5S_GET_EXTENT_NPOINTS(space)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "src dataspace has invalid selection")
+ H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, hsize_t);
- total_bytes = (hsize_t)elmt_size*nelmts;
+ total_bytes = (hsize_t)elmt_size * nelmts;
/* fill in the return values */
*new_type = MPI_BYTE;
@@ -126,7 +126,7 @@ H5S_mpio_all_type( const H5S_t *space, size_t elmt_size,
*is_derived_type = FALSE;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_mpio_all_type() */
@@ -210,7 +210,7 @@ H5S_mpio_hyper_type( const H5S_t *space, size_t elmt_size,
hbool_t *is_derived_type )
{
H5S_sel_iter_t sel_iter; /* Selection iteration info */
- hbool_t sel_iter_init=0; /* Selection iteration info has been initialized */
+ hbool_t sel_iter_init = FALSE; /* Selection iteration info has been initialized */
struct dim { /* less hassle than malloc/free & ilk */
hssize_t start;
@@ -234,27 +234,27 @@ H5S_mpio_hyper_type( const H5S_t *space, size_t elmt_size,
FUNC_ENTER_NOAPI_NOINIT(H5S_mpio_hyper_type);
/* Check args */
- assert (space);
- assert(sizeof(MPI_Aint) >= sizeof(elmt_size));
- if (0==elmt_size)
+ HDassert(space);
+ HDassert(sizeof(MPI_Aint) >= sizeof(elmt_size));
+ if(0 == elmt_size)
goto empty;
/* Initialize selection iterator */
- if (H5S_select_iter_init(&sel_iter, space, elmt_size)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
- sel_iter_init=1; /* Selection iteration info has been initialized */
+ if(H5S_select_iter_init(&sel_iter, space, elmt_size) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
+ sel_iter_init = 1; /* Selection iteration info has been initialized */
/* Abbreviate args */
- diminfo=sel_iter.u.hyp.diminfo;
- assert (diminfo);
+ diminfo = sel_iter.u.hyp.diminfo;
+ HDassert(diminfo);
/* make a local copy of the dimension info so we can operate with them */
/* Check if this is a "flattened" regular hyperslab selection */
if(sel_iter.u.hyp.iter_rank!=0 && sel_iter.u.hyp.iter_rank<space->extent.rank) {
/* Flattened selection */
- rank=sel_iter.u.hyp.iter_rank;
- assert (rank >= 0 && rank<=H5S_MAX_RANK); /* within array bounds */
+ rank = sel_iter.u.hyp.iter_rank;
+ HDassert(rank >= 0 && rank <= H5S_MAX_RANK); /* within array bounds */
if (0==rank)
goto empty;
#ifdef H5S_DEBUG
@@ -288,7 +288,7 @@ H5S_mpio_hyper_type( const H5S_t *space, size_t elmt_size,
else {
/* Non-flattened selection */
rank = space->extent.rank;
- assert (rank >= 0 && rank<=H5S_MAX_RANK); /* within array bounds */
+ HDassert(rank >= 0 && rank<=H5S_MAX_RANK); /* within array bounds */
if (0==rank)
goto empty;
#ifdef H5S_DEBUG
@@ -509,47 +509,39 @@ H5S_mpio_span_hyper_type( const H5S_t *space,
MPI_Datatype *new_type,/* out: */
size_t *count,
hsize_t *extra_offset,
- hbool_t *is_derived_type ){
-
- MPI_Datatype span_type;
- H5S_hyper_span_t *ospan;
- H5S_hyper_span_info_t *odown;
- hsize_t *size;
- int rank;
- int mpi_code;
- herr_t ret_value = SUCCEED;
- MPI_Aint extent,lb;
-
-
- FUNC_ENTER_NOAPI_NOINIT(H5S_mpio_span_hyper_type);
-
- /* Check args */
- assert (space);
+ hbool_t *is_derived_type )
+{
- /* assert(sizeof(MPI_Aint) >= sizeof(elmt_size)); not sure the reason*/
+ MPI_Datatype span_type;
+ H5S_hyper_span_t *ospan;
+ H5S_hyper_span_info_t *odown;
+ hsize_t *size;
+ int mpi_code;
+ herr_t ret_value = SUCCEED;
+ FUNC_ENTER_NOAPI_NOINIT(H5S_mpio_span_hyper_type)
- rank = space->extent.rank;
+ /* Check args */
+ HDassert(space);
- /* size = HDcalloc((size_t)rank,sizeof(hsize_t)); */
- if (0==elmt_size)
+ if(0 == elmt_size)
goto empty;
size = space->extent.size;
- if(size == 0)
+ if(0 == size)
goto empty;
odown = space->select.sel_info.hslab->span_lst;
- if(odown == NULL)
- goto empty;
+ if(NULL == odown)
+ goto empty;
ospan = odown->head;
- if(ospan == NULL)
- goto empty;
+ if(NULL == ospan)
+ goto empty;
/* obtain derived data type */
- if(FAIL == H5S_obtain_datatype(space->extent.size,ospan,&span_type,elmt_size,rank))
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't obtain MPI derived data type");
+ if(FAIL == H5S_obtain_datatype(space->extent.size, ospan, &span_type, elmt_size, space->extent.rank))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't obtain MPI derived data type")
- if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(&span_type)))
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&span_type)))
HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code);
*new_type = span_type;
@@ -558,7 +550,7 @@ H5S_mpio_span_hyper_type( const H5S_t *space,
*extra_offset = 0;
*is_derived_type = TRUE;
- HGOTO_DONE(SUCCEED);
+ HGOTO_DONE(SUCCEED)
empty:
/* special case: empty hyperslab */
@@ -568,8 +560,8 @@ empty:
*is_derived_type = FALSE;
done:
- FUNC_LEAVE_NOAPI(ret_value);
- }
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_mpio_span_hyper_type() */
/*-------------------------------------------------------------------------
@@ -585,173 +577,162 @@ done:
* Programmer: kyang
*
*/
-static herr_t H5S_obtain_datatype(const hsize_t size[],
+static herr_t
+H5S_obtain_datatype(const hsize_t size[],
H5S_hyper_span_t* span,
MPI_Datatype *span_type,
size_t elmt_size,
int dimindex)
{
-
- int innercount,outercount;
- MPI_Datatype bas_type;
- MPI_Datatype temp_type;
- MPI_Datatype tempinner_type;
- MPI_Datatype *inner_type;
- int *blocklen;
- MPI_Aint *disp;
- MPI_Aint stride;
- MPI_Aint extent,lb;
- H5S_hyper_span_info_t *down;
- H5S_hyper_span_t *tspan;
- int mpi_code;
- herr_t ret_value = SUCCEED;
-
+ int innercount, outercount;
+ MPI_Datatype bas_type;
+ MPI_Datatype temp_type;
+ MPI_Datatype tempinner_type;
+ MPI_Datatype *inner_type;
+ int *blocklen;
+ MPI_Aint *disp;
+ MPI_Aint stride;
+ H5S_hyper_span_info_t *down;
+ H5S_hyper_span_t *tspan;
#ifdef H5_HAVE_MPI2
- MPI_Aint sizeaint,sizedtype;
+ MPI_Aint sizeaint, sizedtype;
#endif /* H5_HAVE_MPI2 */
- hsize_t total_lowd,total_lowd1;
- int i;
- int ret;
-
- FUNC_ENTER_NOAPI_NOINIT(H5S_obtain_datatype);
- assert(span);
-
- inner_type = NULL;
- down = NULL;
- tspan = NULL;
- down = span->down;
- tspan = span;
-
- outercount = 0;
-
-/* obtain the number of span tree for this dimension */
- while(tspan) {
- tspan = tspan->next;
- outercount ++;
- }
-
- if(outercount == 0) {
- span_type = NULL;
- return 0;
- }
+ hsize_t total_lowd, total_lowd1;
+ int i;
+ int mpi_code;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5S_obtain_datatype)
+
+ HDassert(span);
+
+ inner_type = NULL;
+ down = NULL;
+ tspan = NULL;
+ down = span->down;
+ tspan = span;
+
+ /* obtain the number of span tree for this dimension */
+ outercount = 0;
+ while(tspan) {
+ tspan = tspan->next;
+ outercount++;
+ } /* end while */
+ if(outercount == 0)
+ HGOTO_DONE(SUCCEED)
/* MPI2 hasn't been widely acccepted, adding H5_HAVE_MPI2 for the future use */
#ifdef H5_HAVE_MPI2
- MPI_Type_extent(MPI_Aint,&sizeaint);
- MPI_Type_extent(MPI_Datatype,&sizedtype);
+ MPI_Type_extent(MPI_Aint, &sizeaint);
+ MPI_Type_extent(MPI_Datatype, &sizedtype);
- blocklen = (int *)HDcalloc((size_t)outercount,sizeof(int));
- disp = (MPI_Aint *)HDcalloc((size_t)outercount,sizeaint);
- inner_type = (MPI_Datatype *)HDcalloc((size_t)outercount,sizedtype);
+ blocklen = (int *)HDcalloc((size_t)outercount, sizeof(int));
+ disp = (MPI_Aint *)HDcalloc((size_t)outercount, sizeaint);
+ inner_type = (MPI_Datatype *)HDcalloc((size_t)outercount, sizedtype);
#else
- blocklen = (int *)HDcalloc((size_t)outercount,sizeof(int));
- disp = (MPI_Aint *)HDcalloc((size_t)outercount,sizeof(MPI_Aint));
- inner_type = (MPI_Datatype *)HDcalloc((size_t)outercount,sizeof(MPI_Datatype));
+ blocklen = (int *)HDcalloc((size_t)outercount, sizeof(int));
+ disp = (MPI_Aint *)HDcalloc((size_t)outercount, sizeof(MPI_Aint));
+ inner_type = (MPI_Datatype *)HDcalloc((size_t)outercount, sizeof(MPI_Datatype));
#endif
- tspan = span;
- outercount = 0;
+ tspan = span;
+ outercount = 0;
- /* if this is the fastest changing dimension, it is the base case for derived datatype. */
- if(down == NULL){
+ /* if this is the fastest changing dimension, it is the base case for derived datatype. */
+ if(down == NULL){
- assert(dimindex <= 1);
- if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)elmt_size, MPI_BYTE,&bas_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code);
+ HDassert(dimindex <= 1);
- if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&bas_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code);
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)elmt_size, MPI_BYTE,&bas_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code);
- while(tspan){
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&bas_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code);
- disp[outercount] = (MPI_Aint)elmt_size * tspan->low;
- blocklen[outercount] = tspan->nelem;
- tspan = tspan->next;
- outercount ++;
- }
+ while(tspan) {
+ disp[outercount] = (MPI_Aint)elmt_size * tspan->low;
+ blocklen[outercount] = tspan->nelem;
+ tspan = tspan->next;
+ outercount++;
+ } /* end while */
- if(MPI_SUCCESS != (mpi_code = MPI_Type_hindexed(outercount,blocklen,
- disp,bas_type,span_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_hindexed failed", mpi_code);
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_hindexed(outercount, blocklen, disp, bas_type, span_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_hindexed failed", mpi_code);
+ } /* end if */
+ else {/* dimindex is the rank of the dimension */
- }
- else {/* dimindex is the rank of the dimension */
+ HDassert(dimindex > 1);
- assert(dimindex >1);
- /* Calculate the total bytes of the lower dimension */
- total_lowd = 1; /* one dimension down */
- total_lowd1 = 1; /* two dimensions down */
+ /* Calculate the total bytes of the lower dimension */
+ total_lowd = 1; /* one dimension down */
+ total_lowd1 = 1; /* two dimensions down */
- for ( i = dimindex-1; i > 0; i--)
- total_lowd = total_lowd * size[i];
+ for ( i = dimindex-1; i > 0; i--)
+ total_lowd = total_lowd * size[i];
- for ( i = dimindex-1; i > 1; i--)
- total_lowd1 = total_lowd1 * size[i];
+ for ( i = dimindex-1; i > 1; i--)
+ total_lowd1 = total_lowd1 * size[i];
- while(tspan){
+ while(tspan) {
- /* Displacement should be in byte and should have dimension information */
- /* First using MPI Type vector to build derived data type for this span only */
- /* Need to calculate the disp in byte for this dimension. */
- /* Calculate the total bytes of the lower dimension */
+ /* Displacement should be in byte and should have dimension information */
+ /* First using MPI Type vector to build derived data type for this span only */
+ /* Need to calculate the disp in byte for this dimension. */
+ /* Calculate the total bytes of the lower dimension */
- disp[outercount] = tspan->low*total_lowd*elmt_size;
- blocklen[outercount] = 1;
+ disp[outercount] = tspan->low*total_lowd*elmt_size;
+ blocklen[outercount] = 1;
- /* generating inner derived datatype by using MPI_Type_hvector */
- if(FAIL == H5S_obtain_datatype(size,tspan->down->head,&temp_type,elmt_size,dimindex-1))
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't obtain MPI derived data type");
+ /* generating inner derived datatype by using MPI_Type_hvector */
+ if(FAIL == H5S_obtain_datatype(size,tspan->down->head,&temp_type,elmt_size,dimindex-1))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't obtain MPI derived data type")
- if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&temp_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code);
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&temp_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code);
- /* building the inner vector datatype */
- stride = total_lowd*elmt_size;
- innercount = tspan->nelem;
+ /* building the inner vector datatype */
+ stride = total_lowd*elmt_size;
+ innercount = tspan->nelem;
- if(MPI_SUCCESS != (mpi_code = MPI_Type_hvector(innercount,1,stride,temp_type,&tempinner_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_hvector failed", mpi_code);
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_hvector(innercount,1,stride,temp_type,&tempinner_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_hvector failed", mpi_code);
- if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&tempinner_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code);
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&tempinner_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code);
- if(MPI_SUCCESS != (mpi_code =MPI_Type_free(&temp_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed",mpi_code);
- inner_type[outercount] = tempinner_type;
- outercount ++;
- tspan = tspan->next;
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_free(&temp_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed", mpi_code);
- }
+ inner_type[outercount] = tempinner_type;
+ outercount ++;
+ tspan = tspan->next;
+ } /* end while */
- /* building the whole vector datatype */
- if(MPI_SUCCESS != (mpi_code =
- MPI_Type_struct(outercount,blocklen,disp,inner_type,span_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_struct failed", mpi_code);
-
- }
+ /* building the whole vector datatype */
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_struct(outercount, blocklen, disp, inner_type, span_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_struct failed", mpi_code);
+ } /* end else */
- if(inner_type != NULL){
- if(down != NULL) {
- for(i=0;i<outercount;i++)
- if(MPI_SUCCESS != (mpi_code = MPI_Type_free(&inner_type[i])))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed",mpi_code);
- }
- }
+ if(inner_type != NULL && down != NULL) {
+ for(i = 0; i < outercount; i++)
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_free(&inner_type[i])))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed", mpi_code);
+ } /* end if */
- if(inner_type != NULL)
- HDfree(inner_type);
- if(blocklen != NULL)
- HDfree(blocklen);
- if(disp != NULL)
- HDfree(disp);
+ if(inner_type != NULL)
+ HDfree(inner_type);
+ if(blocklen != NULL)
+ HDfree(blocklen);
+ if(disp != NULL)
+ HDfree(disp);
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_obtain_datatype() */
@@ -791,7 +772,7 @@ H5S_mpio_space_type( const H5S_t *space, size_t elmt_size,
FUNC_ENTER_NOAPI_NOINIT(H5S_mpio_space_type);
/* Check args */
- assert (space);
+ HDassert(space);
/* Creat MPI type based on the kind of selection */
switch (H5S_GET_EXTENT_TYPE(space)) {
@@ -830,13 +811,13 @@ H5S_mpio_space_type( const H5S_t *space, size_t elmt_size,
break;
default:
- assert("unknown selection type" && 0);
+ HDassert("unknown selection type" && 0);
break;
} /* end switch */
break;
default:
- assert("unknown data space type" && 0);
+ HDassert("unknown data space type" && 0);
break;
}
@@ -845,3 +826,4 @@ done:
}
#endif /* H5_HAVE_PARALLEL */
+
diff --git a/src/H5Z.c b/src/H5Z.c
index 6ca352f..4df6abd 100644
--- a/src/H5Z.c
+++ b/src/H5Z.c
@@ -271,17 +271,17 @@ done:
herr_t
H5Z_register (const H5Z_class_t *cls)
{
- size_t i;
- herr_t ret_value=SUCCEED; /* Return value */
+ size_t i;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5Z_register, FAIL)
- assert (cls);
- assert (cls->id>=0 && cls->id<=H5Z_FILTER_MAX);
+ HDassert(cls);
+ HDassert(cls->id >= 0 && cls->id <= H5Z_FILTER_MAX);
/* Is the filter already registered? */
- for (i=0; i<H5Z_table_used_g; i++)
- if (H5Z_table_g[i].id==cls->id)
+ for(i = 0; i < H5Z_table_used_g; i++)
+ if(H5Z_table_g[i].id == cls->id)
break;
/* Filter not already registered */
@@ -572,7 +572,7 @@ H5Z_prelude_callback(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_ty
break;
default:
- assert("invalid prelude type" && 0);
+ HDassert("invalid prelude type" && 0);
} /* end switch */
} /* end else */
} /* end for */
diff --git a/src/H5err.txt b/src/H5err.txt
index 7f110b8..64e9729 100644
--- a/src/H5err.txt
+++ b/src/H5err.txt
@@ -169,6 +169,8 @@ MINOR, CACHE, H5E_CANTMARKDIRTY, Unable to mark a pinned entry as dirty
MINOR, CACHE, H5E_CANTDIRTY, Unable to mark metadata as dirty
MINOR, CACHE, H5E_CANTEXPUNGE, Unable to expunge a metadata cache entry
MINOR, CACHE, H5E_CANTRESIZE, Unable to resize a metadata cache entry
+MINOR, CACHE, H5E_CANTDEPEND, Unable to create a flush dependency
+MINOR, CACHE, H5E_CANTUNDEPEND, Unable to destroy a flush dependency
# B-tree related errors
MINOR, BTREE, H5E_NOTFOUND, Object not found
diff --git a/src/H5private.h b/src/H5private.h
index ea55a61..695b015 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -1898,6 +1898,11 @@ static herr_t H5_INTERFACE_INIT_FUNC(void);
} /*end scope from beginning of FUNC_ENTER*/
+/* Macro for "stringizing" an integer in the C preprocessor (use H5_TOSTRING) */
+/* (use H5_TOSTRING, H5_STRINGIZE is just part of the implementation) */
+#define H5_STRINGIZE(x) #x
+#define H5_TOSTRING(x) H5_STRINGIZE(x)
+
/* Macro for "glueing" together items, for re-scanning macros */
#define H5_GLUE(x,y) x##y
#define H5_GLUE3(x,y,z) x##y##z
diff --git a/src/H5public.h b/src/H5public.h
index e0a9049..ab471b9 100644
--- a/src/H5public.h
+++ b/src/H5public.h
@@ -71,10 +71,10 @@ extern "C" {
/* Version numbers */
#define H5_VERS_MAJOR 1 /* For major interface/format changes */
#define H5_VERS_MINOR 9 /* For minor interface/format changes */
-#define H5_VERS_RELEASE 34 /* For tweaks, bug-fixes, or development */
+#define H5_VERS_RELEASE 36 /* For tweaks, bug-fixes, or development */
#define H5_VERS_SUBRELEASE "" /* For pre-releases like snap0 */
/* Empty string for real releases. */
-#define H5_VERS_INFO "HDF5 library version: 1.9.34" /* Full version string */
+#define H5_VERS_INFO "HDF5 library version: 1.9.36" /* Full version string */
#define H5check() H5check_version(H5_VERS_MAJOR,H5_VERS_MINOR, \
H5_VERS_RELEASE)
diff --git a/src/Makefile.in b/src/Makefile.in
index e49d68b..5433176 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -328,6 +328,8 @@ build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
+
+# Install directories that automake doesn't know about
docdir = $(exec_prefix)/doc
dvidir = @dvidir@
enable_shared = @enable_shared@
@@ -339,9 +341,7 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
-
-# Install directories that automake doesn't know about
-includedir = $(exec_prefix)/include
+includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
@@ -409,7 +409,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog
# Add libtool shared library version numbers to the HDF5 library
# See libtool versioning documentation online.
LT_VERS_INTERFACE = 6
-LT_VERS_REVISION = 24
+LT_VERS_REVISION = 26
LT_VERS_AGE = 0
H5detect_CFLAGS = -g