[svn-r25321] Reworked and enhanced extreme sanity check in H5C.c, fixing an

uninitialized variable bug in passing.

Added the H5C_get_entry_ptr_from_addr() and H5C_verify_entry_type()
in H5C.c, along with their pass through functions in H5AC.c.  Note
that H5C_get_entry_ptr_from_addr() is quite slimey, and should be
avoided if possible.

Updated fractal heap to use flush ordering to force children
in the hdr / iblock / dblock tree to be flushed prior to parents.
This is part of a port of the fractal heap to the V3 cache, although
I gather that it will also be useful for SWMR.

Added sanity checking code to the fractal heap to verify that direct 
blocks are flushed before their parent indirect blocks, child indirect
block are flushed prior to their parent indirect blocks, and that the
root iblock or dblock is flushed prior to the header

Tested on:

        Jam: Serial and parallel
        Phoenix (Debian): serial, debug and production
        amazon (MacOS): serial
This commit is contained in:
John Mainzer 2014-06-18 13:18:36 -05:00
parent 471aedb1e8
commit 12ee3deb82
9 changed files with 1938 additions and 90 deletions

View File

@ -2590,6 +2590,137 @@ done:
} /* H5AC_add_candidate() */
#endif /* H5_HAVE_PARALLEL */
/*************************************************************************/
/*************************** Debugging Functions: ************************/
/*************************************************************************/
/*-------------------------------------------------------------------------
*
* Function: H5AC_get_entry_ptr_from_addr()
*
* Purpose: Debugging function that attempts to look up an entry in the
* cache by its file address, and if found, returns a pointer
* to the entry in *entry_ptr_ptr. If the entry is not in the
* cache, *entry_ptr_ptr is set to NULL.
*
* WARNING: This call should be used only in debugging
* routines, and it should be avoided when
* possible.
*
* Further, if we ever multi-thread the cache,
* this routine will have to be either discarded
* or heavily re-worked.
*
* Finally, keep in mind that the entry whose
* pointer is obtained in this fashion may not
* be in a stable state.
*
* Note that this function is only defined if NDEBUG
* is not defined.
*
* As heavy use of this function is almost certainly a
* bad idea, the metadata cache tracks the number of
* successful calls to this function, and (if
* H5C_DO_SANITY_CHECKS is defined) displays any
* non-zero count on cache shutdown.
*
* This function is just a wrapper that calls the H5C
* version of the function.
*
* Return: FAIL if error is detected, SUCCEED otherwise.
*
* Programmer: John Mainzer, 5/30/14
*
* Changes:
*
* None.
*
*-------------------------------------------------------------------------
*/
#ifndef NDEBUG
herr_t
H5AC_get_entry_ptr_from_addr(const H5F_t *f,
haddr_t addr,
void ** entry_ptr_ptr)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
if ( H5C_get_entry_ptr_from_addr(f, addr, entry_ptr_ptr) < 0 )
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"H5C_get_entry_ptr_from_addr() failed.")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_get_entry_ptr_from_addr() */
#endif /* NDEBUG */
/*-------------------------------------------------------------------------
*
* Function: H5AC_verify_entry_type()
*
* Purpose: Debugging function that attempts to look up an entry in the
* cache by its file address, and if found, test to see if its
* type field contains the expected value.
*
* If the specified entry is in cache, *in_cache_ptr is set
* to TRUE, and *type_ok_ptr is set to TRUE or FALSE
* depending on whether the entries type field matches the
* expected_type parameter
*
* If the target entry is not in cache, *in_cache_ptr is
* set to FALSE, and *type_ok_ptr is undefined.
*
* Note that this function is only defined if NDEBUG
* is not defined.
*
* This function is just a wrapper that calls the H5C
* version of the function.
*
* Return: FAIL if error is detected, SUCCEED otherwise.
*
* Programmer: John Mainzer, 5/30/14
*
* Changes:
*
* None.
*
*-------------------------------------------------------------------------
*/
#ifndef NDEBUG
herr_t
H5AC_verify_entry_type(const H5F_t *f,
haddr_t addr,
const H5AC_class_t * expected_type,
hbool_t * in_cache_ptr,
hbool_t * type_ok_ptr)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
if ( H5C_verify_entry_type(f, addr, (const H5C_class_t *)expected_type,
in_cache_ptr, type_ok_ptr) < 0 )
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"H5C_verify_entry_type() failed.")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_verify_entry_type() */
#endif /* NDEBUG */
/*************************************************************************/
/**************************** Private Functions: *************************/

View File

@ -416,5 +416,17 @@ H5_DLL herr_t H5AC_ignore_tags(H5F_t * f);
H5_DLL herr_t H5AC_add_candidate(H5AC_t * cache_ptr, haddr_t addr);
#endif /* H5_HAVE_PARALLEL */
#ifndef NDEBUG /* debugging functions */
H5_DLL herr_t H5AC_get_entry_ptr_from_addr(const H5F_t *f, haddr_t addr,
void ** entry_ptr_ptr);
H5_DLL herr_t H5AC_verify_entry_type(const H5F_t * f, haddr_t addr,
const H5AC_class_t * expected_type,
hbool_t * in_cache_ptr,
hbool_t * type_ok_ptr);
#endif /* NDEBUG */ /* end debugging functions */
#endif /* !_H5ACprivate_H */

700
src/H5C.c
View File

@ -186,8 +186,8 @@ static herr_t H5C_verify_tag(int id, haddr_t tag);
#if H5C_DO_EXTREME_SANITY_CHECKS
static herr_t H5C_validate_lru_list(H5C_t * cache_ptr);
static herr_t H5C_verify_not_in_index(H5C_t * cache_ptr,
H5C_cache_entry_t * entry_ptr);
static herr_t H5C_validate_pinned_entry_list(H5C_t * cache_ptr);
static herr_t H5C_validate_protected_entry_list(H5C_t * cache_ptr);
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@ -1285,6 +1285,10 @@ H5C_create(size_t max_cache_size,
cache_ptr->prefix[0] = '\0'; /* empty string */
#ifndef NDEBUG
cache_ptr->get_entry_ptr_from_addr_counter = 0;
#endif /* NDEBUG */
/* Set return value */
ret_value = cache_ptr;
@ -1543,6 +1547,23 @@ H5C_dest(H5F_t * f,
cache_ptr->slist_ptr = NULL;
} /* end if */
/* Only display count of number of calls to H5C_get_entry_ptr_from_add()
* if NDEBUG is undefined, and H5C_DO_SANITY_CHECKS is defined. Need
* this as the print statement will upset windows, and we frequently
* run debug builds there.
*
* Note that the count is still kept whenever NDEBUG is undefined, and
* is reasonably accessible via debugger.
*/
#ifndef NDEBUG
#if H5C_DO_SANITY_CHECKS
if ( cache_ptr->get_entry_ptr_from_addr_counter > 0 )
HDfprintf(stdout,
"*** %ld calls to H5C_get_entry_ptr_from_add(). ***\n",
cache_ptr->get_entry_ptr_from_addr_counter);
#endif /* H5C_DO_SANITY_CHECKS */
#endif /* NDEBUG */
cache_ptr->magic = 0;
cache_ptr = H5FL_FREE(H5C_t, cache_ptr);
@ -1599,7 +1620,7 @@ H5C_expunge_entry(H5F_t * f,
if ( H5C_validate_lru_list(cache_ptr) < 0 ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"LRU sanity check failed.\n");
"LRU extreme sanity check failed on entry.\n");
}
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@ -1654,7 +1675,7 @@ done:
if ( H5C_validate_lru_list(cache_ptr) < 0 ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"LRU sanity check failed.\n");
"LRU extreme sanity check failed on exit.\n");
}
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@ -1719,6 +1740,16 @@ H5C_flush_cache(H5F_t *f, hid_t primary_dxpl_id, hid_t secondary_dxpl_id, unsign
HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
HDassert( cache_ptr->slist_ptr );
#if H5C_DO_EXTREME_SANITY_CHECKS
if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"an extreme sanity check failed on entry.\n");
}
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
ignore_protected = ( (flags & H5C__FLUSH_IGNORE_PROTECTED_FLAG) != 0 );
destroy = ( (flags & H5C__FLUSH_INVALIDATE_FLAG) != 0 );
@ -2006,7 +2037,8 @@ end_of_inner_loop:
HDassert( (initial_slist_len + cache_ptr->slist_len_increase -
flushed_entries_count) == cache_ptr->slist_len );
HDassert( (initial_slist_size + cache_ptr->slist_size_increase -
HDassert( (initial_slist_size +
(size_t)(cache_ptr->slist_size_increase) -
flushed_entries_size) == cache_ptr->slist_size );
#endif /* H5C_DO_SANITY_CHECKS */
@ -2682,17 +2714,15 @@ H5C_insert_entry(H5F_t * f,
HDassert( thing );
#if H5C_DO_EXTREME_SANITY_CHECKS
if ( H5C_verify_not_in_index(cache_ptr, (H5C_cache_entry_t *)thing) < 0 ) {
/* no need to verify that entry is not already in the index as */
/* we already make that check below. */
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "thing already in index.\n");
}
#endif /* H5C_DO_SANITY_CHECKS */
if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
#if H5C_DO_EXTREME_SANITY_CHECKS
if ( H5C_validate_lru_list(cache_ptr) < 0 ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"LRU sanity check failed.\n");
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"an extreme sanity check failed on entry.\n");
}
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@ -2742,6 +2772,7 @@ H5C_insert_entry(H5F_t * f,
entry_ptr->is_pinned = insert_pinned;
entry_ptr->pinned_from_client = insert_pinned;
entry_ptr->pinned_from_cache = FALSE;
entry_ptr->flush_me_last = flush_last;
#ifdef H5_HAVE_PARALLEL
entry_ptr->flush_me_collectively = flush_collectively;
@ -2911,10 +2942,12 @@ H5C_insert_entry(H5F_t * f,
H5C__UPDATE_RP_FOR_INSERTION(cache_ptr, entry_ptr, FAIL)
#if H5C_DO_EXTREME_SANITY_CHECKS
if ( H5C_validate_lru_list(cache_ptr) < 0 ) {
if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"LRU sanity check failed.\n");
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"an extreme sanity check failed just before done.\n");
}
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@ -2930,10 +2963,12 @@ H5C_insert_entry(H5F_t * f,
done:
#if H5C_DO_EXTREME_SANITY_CHECKS
if ( H5C_validate_lru_list(cache_ptr) < 0 ) {
if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"LRU sanity check failed.\n");
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"an extreme sanity check failed on exit.\n");
}
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@ -3010,12 +3045,13 @@ H5C_mark_entries_as_clean(H5F_t * f,
HDassert( ce_array_ptr != NULL );
#if H5C_DO_EXTREME_SANITY_CHECKS
if ( H5C_validate_lru_list(cache_ptr) < 0 ) {
if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
HDassert(0);
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"LRU sanity check failed.\n");
}
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"an extreme sanity check failed on entry.\n");
}
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
for ( i = 0; i < ce_array_len; i++ )
@ -3042,11 +3078,12 @@ H5C_mark_entries_as_clean(H5F_t * f,
}
#if H5C_DO_EXTREME_SANITY_CHECKS
if ( H5C_validate_lru_list(cache_ptr) < 0 ) {
if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
HDassert(0);
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"LRU sanity check failed.\n");
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"an extreme sanity check failed in for loop.\n");
}
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
#endif /* H5C_DO_SANITY_CHECKS */
@ -3220,12 +3257,13 @@ H5C_mark_entries_as_clean(H5F_t * f,
done:
#if H5C_DO_EXTREME_SANITY_CHECKS
if ( H5C_validate_lru_list(cache_ptr) < 0 ) {
if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
HDassert(0);
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"LRU sanity check failed.\n");
}
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"an extreme sanity check failed on exit.\n");
}
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
FUNC_LEAVE_NOAPI(ret_value)
@ -3359,11 +3397,13 @@ H5C_move_entry(H5C_t * cache_ptr,
HDassert( H5F_addr_ne(old_addr, new_addr) );
#if H5C_DO_EXTREME_SANITY_CHECKS
if ( H5C_validate_lru_list(cache_ptr) < 0 ) {
if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"LRU sanity check failed.\n");
}
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"an extreme sanity check failed on entry.\n");
}
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
H5C__SEARCH_INDEX(cache_ptr, old_addr, entry_ptr, FAIL)
@ -3463,10 +3503,11 @@ H5C_move_entry(H5C_t * cache_ptr,
* the sanity checks.
*/
HDassert( cache_ptr->slist_len_increase > 1 );
HDassert( cache_ptr->slist_size_increase > entry_ptr->size );
HDassert( cache_ptr->slist_size_increase >
(int64_t)(entry_ptr->size) );
cache_ptr->slist_len_increase -= 1;
cache_ptr->slist_size_increase -= entry_ptr->size;
cache_ptr->slist_size_increase -= (int64_t)(entry_ptr->size);
}
#endif /* H5C_DO_SANITY_CHECKS */
@ -3480,11 +3521,13 @@ H5C_move_entry(H5C_t * cache_ptr,
done:
#if H5C_DO_EXTREME_SANITY_CHECKS
if ( H5C_validate_lru_list(cache_ptr) < 0 ) {
if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"LRU sanity check failed.\n");
}
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"an extreme sanity check failed on exit.\n");
}
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
FUNC_LEAVE_NOAPI(ret_value)
@ -3530,6 +3573,15 @@ H5C_resize_entry(void *thing, size_t new_size)
if(!(entry_ptr->is_pinned || entry_ptr->is_protected))
HGOTO_ERROR(H5E_CACHE, H5E_BADTYPE, FAIL, "Entry isn't pinned or protected??")
#if H5C_DO_EXTREME_SANITY_CHECKS
if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"an extreme sanity check failed on entry.\n");
}
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
/* update for change in entry size if necessary */
if ( entry_ptr->size != new_size ) {
hbool_t was_clean;
@ -3594,6 +3646,16 @@ H5C_resize_entry(void *thing, size_t new_size)
} /* end if */
done:
#if H5C_DO_EXTREME_SANITY_CHECKS
if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"an extreme sanity check failed on exit.\n");
}
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C_resize_entry() */
@ -3608,6 +3670,9 @@ done:
* Programmer: Quincey Koziol
* 3/26/09
*
* Changes: Added sanity checks to clarify the circumstances under
* which an entry can be pinned. JRM -- 4/27/14
*
*-------------------------------------------------------------------------
*/
#ifndef NDEBUG
@ -3627,6 +3692,7 @@ H5C_pin_entry_from_client(H5C_t UNUSED * cache_ptr,
/* Sanity checks */
HDassert( cache_ptr );
HDassert( entry_ptr );
HDassert( entry_ptr->is_protected );
/* Check if the entry is already pinned */
if(entry_ptr->is_pinned) {
@ -3644,7 +3710,9 @@ H5C_pin_entry_from_client(H5C_t UNUSED * cache_ptr,
entry_ptr->pinned_from_client = TRUE;
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C_pin_entry_from_client() */
@ -3659,6 +3727,9 @@ done:
* Programmer: John Mainzer
* 4/26/06
*
* Changes: Added extreme sanity checks on entry and exit.
* JRM -- 4/26/14
*
*-------------------------------------------------------------------------
*/
herr_t
@ -3677,6 +3748,17 @@ H5C_pin_protected_entry(void *thing)
HDassert(cache_ptr);
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
#if H5C_DO_EXTREME_SANITY_CHECKS
if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"an extreme sanity check failed on entry.\n");
}
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
/* Only protected entries can be pinned */
if(!entry_ptr->is_protected)
HGOTO_ERROR(H5E_CACHE, H5E_CANTPIN, FAIL, "Entry isn't protected")
@ -3686,6 +3768,17 @@ H5C_pin_protected_entry(void *thing)
HGOTO_ERROR(H5E_CACHE, H5E_CANTPIN, FAIL, "Can't pin entry by client")
done:
#if H5C_DO_EXTREME_SANITY_CHECKS
if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"an extreme sanity check failed on exit.\n");
}
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C_pin_protected_entry() */
@ -3779,11 +3872,12 @@ H5C_protect(H5F_t * f,
HDassert( H5F_addr_defined(addr) );
#if H5C_DO_EXTREME_SANITY_CHECKS
if ( H5C_validate_lru_list(cache_ptr) < 0 ) {
if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
HDassert(0);
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, NULL, \
"LRU sanity check failed.\n");
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"an extreme sanity check failed on entry.\n");
}
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@ -4138,11 +4232,13 @@ H5C_protect(H5F_t * f,
done:
#if H5C_DO_EXTREME_SANITY_CHECKS
if ( H5C_validate_lru_list(cache_ptr) < 0 ) {
if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, NULL, \
"LRU sanity check failed.\n");
}
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"an extreme sanity check failed on exit.\n");
}
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
FUNC_LEAVE_NOAPI(ret_value)
@ -5353,7 +5449,9 @@ H5C_unpin_entry_from_client(H5C_t * cache_ptr,
entry_ptr->pinned_from_client = FALSE;
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C_unpin_entry_from_client() */
@ -5368,6 +5466,9 @@ done:
* Programmer: John Mainzer
* 3/22/06
*
* Changes: Added extreme sanity checks on entry and exit.
JRM -- 4/26/14
*
*-------------------------------------------------------------------------
*/
herr_t
@ -5385,12 +5486,35 @@ H5C_unpin_entry(void *_entry_ptr)
HDassert(cache_ptr);
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
#if H5C_DO_EXTREME_SANITY_CHECKS
if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"an extreme sanity check failed on entry.\n");
}
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
/* Unpin the entry */
if(H5C_unpin_entry_from_client(cache_ptr, entry_ptr, TRUE) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, "Can't unpin entry from client")
done:
#if H5C_DO_EXTREME_SANITY_CHECKS
if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"an extreme sanity check failed on exit.\n");
}
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C_unpin_entry() */
@ -5495,14 +5619,15 @@ H5C_unprotect(H5F_t * f,
was_clean = ! ( entry_ptr->is_dirty );
#if H5C_DO_EXTREME_SANITY_CHECKS
if ( H5C_validate_lru_list(cache_ptr) < 0 ) {
if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"LRU sanity check failed.\n");
}
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"an extreme sanity check failed on entry.\n");
}
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
/* if the entry has multiple read only protects, just decrement
* the ro_ref_counter. Don't actually unprotect until the ref count
* drops to zero.
@ -5735,11 +5860,13 @@ H5C_unprotect(H5F_t * f,
done:
#if H5C_DO_EXTREME_SANITY_CHECKS
if ( H5C_validate_lru_list(cache_ptr) < 0 ) {
if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"LRU sanity check failed.\n");
}
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"an extreme sanity check failed on exit.\n");
}
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
FUNC_LEAVE_NOAPI(ret_value)
@ -7958,7 +8085,8 @@ H5C_flush_invalidate_cache(H5F_t * f,
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) );
(initial_slist_size +
(size_t)(cache_ptr->slist_size_increase)) );
}
#endif /* H5C_DO_SANITY_CHECKS */
@ -8590,6 +8718,8 @@ H5C_flush_single_entry(H5F_t * f,
}
done:
HDassert( ( destroy ) ||
( ( entry_ptr ) && ( ! entry_ptr->flush_in_progress ) ) );
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C_flush_single_entry() */
@ -9083,6 +9213,11 @@ done:
*
* Programmer: John Mainzer, 7/14/05
*
* Changes:
*
* Added code to verify that the LRU contains no pinned
* entries. JRM -- 4/25/14
*
*-------------------------------------------------------------------------
*/
#if H5C_DO_EXTREME_SANITY_CHECKS
@ -9162,6 +9297,13 @@ H5C_validate_lru_list(H5C_t * cache_ptr)
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 6 failed")
}
if ( ( entry_ptr->is_pinned ) ||
( entry_ptr->pinned_from_client ) ||
( entry_ptr->pinned_from_cache ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 7 failed")
}
len++;
size += entry_ptr->size;
entry_ptr = entry_ptr->next;
@ -9170,7 +9312,7 @@ H5C_validate_lru_list(H5C_t * cache_ptr)
if ( ( cache_ptr->LRU_list_len != len ) ||
( cache_ptr->LRU_list_size != size ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 7 failed")
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 8 failed")
}
done:
@ -9189,11 +9331,10 @@ done:
/*-------------------------------------------------------------------------
*
* Function: H5C_verify_not_in_index
* Function: H5C_validate_pinned_entry_list
*
* Purpose: Debugging function that scans the hash table to verify
* that the specified instance of H5C_cache_entry_t is not
* present.
* Purpose: Debugging function that scans the pinned entry list for
* errors.
*
* If an error is detected, the function generates a
* diagnostic and returns FAIL. If no error is detected,
@ -9201,42 +9342,111 @@ done:
*
* Return: FAIL if error is detected, SUCCEED otherwise.
*
* Programmer: John Mainzer, 7/14/05
* Programmer: John Mainzer, 4/25/14
*
* Changes:
*
* None.
*
*-------------------------------------------------------------------------
*/
#if H5C_DO_EXTREME_SANITY_CHECKS
static herr_t
H5C_verify_not_in_index(H5C_t * cache_ptr,
H5C_cache_entry_t * entry_ptr)
H5C_validate_pinned_entry_list(H5C_t * cache_ptr)
{
herr_t ret_value = SUCCEED; /* Return value */
int32_t i;
int32_t depth;
H5C_cache_entry_t * scan_ptr = NULL;
int32_t len = 0;
size_t size = 0;
H5C_cache_entry_t * entry_ptr = NULL;
FUNC_ENTER_NOAPI_NOINIT
HDassert( cache_ptr != NULL );
HDassert( cache_ptr );
HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
HDassert( entry_ptr != NULL );
for ( i = 0; i < H5C__HASH_TABLE_LEN; i++ )
if ( ( ( cache_ptr->pel_head_ptr == NULL )
||
( cache_ptr->pel_tail_ptr == NULL )
)
&&
( cache_ptr->pel_head_ptr != cache_ptr->pel_tail_ptr )
) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 1 failed")
}
if ( ( cache_ptr->pel_len < 0 ) || ( cache_ptr->pel_size < 0 ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 2 failed")
}
if ( ( cache_ptr->pel_len == 1 )
&&
( ( cache_ptr->pel_head_ptr != cache_ptr->pel_tail_ptr )
||
( cache_ptr->pel_head_ptr == NULL )
||
( cache_ptr->pel_head_ptr->size != cache_ptr->pel_size )
)
) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 3 failed")
}
if ( ( cache_ptr->pel_len >= 1 )
&&
( ( cache_ptr->pel_head_ptr == NULL )
||
( cache_ptr->pel_head_ptr->prev != NULL )
||
( cache_ptr->pel_tail_ptr == NULL )
||
( cache_ptr->pel_tail_ptr->next != NULL )
)
) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 4 failed")
}
entry_ptr = cache_ptr->pel_head_ptr;
while ( entry_ptr != NULL )
{
depth = 0;
scan_ptr = cache_ptr->index[i];
while ( scan_ptr != NULL )
{
if ( scan_ptr == entry_ptr ) {
if ( ( entry_ptr != cache_ptr->pel_head_ptr ) &&
( ( entry_ptr->prev == NULL ) ||
( entry_ptr->prev->next != entry_ptr ) ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"Entry already in index.")
}
depth++;
scan_ptr = scan_ptr->ht_next;
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 5 failed")
}
if ( ( entry_ptr != cache_ptr->pel_tail_ptr ) &&
( ( entry_ptr->next == NULL ) ||
( entry_ptr->next->prev != entry_ptr ) ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 6 failed")
}
if ( ! entry_ptr->is_pinned ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 7 failed")
}
if ( ! ( ( entry_ptr->pinned_from_client ) ||
( entry_ptr->pinned_from_cache ) ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 8 failed")
}
len++;
size += entry_ptr->size;
entry_ptr = entry_ptr->next;
}
if ( ( cache_ptr->pel_len != len ) ||
( cache_ptr->pel_size != size ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 9 failed")
}
done:
@ -9248,10 +9458,326 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C_verify_not_in_index() */
} /* H5C_validate_pinned_entry_list() */
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
/*-------------------------------------------------------------------------
*
* Function: H5C_validate_protected_entry_list
*
* Purpose: Debugging function that scans the protected entry list for
* errors.
*
* If an error is detected, the function generates a
* diagnostic and returns FAIL. If no error is detected,
* the function returns SUCCEED.
*
* Return: FAIL if error is detected, SUCCEED otherwise.
*
* Programmer: John Mainzer, 4/25/14
*
* Changes:
*
* None.
*
*-------------------------------------------------------------------------
*/
#if H5C_DO_EXTREME_SANITY_CHECKS
static herr_t
H5C_validate_protected_entry_list(H5C_t * cache_ptr)
{
herr_t ret_value = SUCCEED; /* Return value */
int32_t len = 0;
size_t size = 0;
H5C_cache_entry_t * entry_ptr = NULL;
FUNC_ENTER_NOAPI_NOINIT
HDassert( cache_ptr );
HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
if ( ( ( cache_ptr->pl_head_ptr == NULL )
||
( cache_ptr->pl_tail_ptr == NULL )
)
&&
( cache_ptr->pl_head_ptr != cache_ptr->pl_tail_ptr )
) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 1 failed")
}
if ( ( cache_ptr->pl_len < 0 ) || ( cache_ptr->pl_size < 0 ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 2 failed")
}
if ( ( cache_ptr->pl_len == 1 )
&&
( ( cache_ptr->pl_head_ptr != cache_ptr->pl_tail_ptr )
||
( cache_ptr->pl_head_ptr == NULL )
||
( cache_ptr->pl_head_ptr->size != cache_ptr->pl_size )
)
) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 3 failed")
}
if ( ( cache_ptr->pl_len >= 1 )
&&
( ( cache_ptr->pl_head_ptr == NULL )
||
( cache_ptr->pl_head_ptr->prev != NULL )
||
( cache_ptr->pl_tail_ptr == NULL )
||
( cache_ptr->pl_tail_ptr->next != NULL )
)
) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 4 failed")
}
entry_ptr = cache_ptr->pl_head_ptr;
while ( entry_ptr != NULL )
{
if ( ( entry_ptr != cache_ptr->pl_head_ptr ) &&
( ( entry_ptr->prev == NULL ) ||
( entry_ptr->prev->next != entry_ptr ) ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 5 failed")
}
if ( ( entry_ptr != cache_ptr->pl_tail_ptr ) &&
( ( entry_ptr->next == NULL ) ||
( entry_ptr->next->prev != entry_ptr ) ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 6 failed")
}
if ( ! entry_ptr->is_protected ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 7 failed")
}
if ( ( entry_ptr->is_read_only ) &&
( entry_ptr->ro_ref_count <= 0 ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 8 failed")
}
len++;
size += entry_ptr->size;
entry_ptr = entry_ptr->next;
}
if ( ( cache_ptr->pl_len != len ) ||
( cache_ptr->pl_size != size ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Check 9 failed")
}
done:
if ( ret_value != SUCCEED ) {
HDassert(0);
}
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C_validate_protected_entry_list() */
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
/*-------------------------------------------------------------------------
*
* Function: H5C_get_entry_ptr_from_addr()
*
* Purpose: Debugging function that attempts to look up an entry in the
* cache by its file address, and if found, returns a pointer
* to the entry in *entry_ptr_ptr. If the entry is not in the
* cache, *entry_ptr_ptr is set to NULL.
*
* WARNING: This call should be used only in debugging
* routines, and it should be avoided when
* possible.
*
* Further, if we ever multi-thread the cache,
* this routine will have to be either discarded
* or heavily re-worked.
*
* Finally, keep in mind that the entry whose
* pointer is obtained in this fashion may not
* be in a stable state.
*
* Note that this function is only defined if NDEBUG
* is not defined.
*
* As heavy use of this function is almost certainly a
* bad idea, the metadata cache tracks the number of
* successful calls to this function, and (if
* H5C_DO_SANITY_CHECKS is defined) displays any
* non-zero count on cache shutdown.
*
* Return: FAIL if error is detected, SUCCEED otherwise.
*
* Programmer: John Mainzer, 5/30/14
*
* Changes:
*
* None.
*
*-------------------------------------------------------------------------
*/
#ifndef NDEBUG
herr_t
H5C_get_entry_ptr_from_addr(const H5F_t *f,
haddr_t addr,
void ** entry_ptr_ptr)
{
H5C_t * cache_ptr;
H5C_cache_entry_t * entry_ptr = NULL;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
HDassert( f );
HDassert( f->shared );
cache_ptr = f->shared->cache;
HDassert( cache_ptr != NULL );
HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
HDassert( H5F_addr_defined(addr) );
HDassert( entry_ptr_ptr != NULL );
/* this test duplicates two of the above asserts, but we need an
* invocation of HGOTO_ERROR to keep the compiler happy.
*/
if ( ( cache_ptr == NULL ) || ( cache_ptr->magic != H5C__H5C_T_MAGIC ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad cache_ptr on entry.")
}
H5C__SEARCH_INDEX(cache_ptr, addr, entry_ptr, FAIL)
if ( entry_ptr == NULL ) {
/* the entry doesn't exist in the cache -- report this
* and quit.
*/
*entry_ptr_ptr = NULL;
} else {
*entry_ptr_ptr = entry_ptr;
/* increment call counter */
(cache_ptr->get_entry_ptr_from_addr_counter)++;
}
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C_get_entry_ptr_from_addr() */
#endif /* NDEBUG */
/*-------------------------------------------------------------------------
*
* Function: H5C_verify_entry_type()
*
* Purpose: Debugging function that attempts to look up an entry in the
* cache by its file address, and if found, test to see if its
* type field contains the expted value.
*
* If the specified entry is in cache, *in_cache_ptr is set
* to TRUE, and *type_ok_ptr is set to TRUE or FALSE
* depending on whether the entries type field matches the
* expected_type parameter
*
* If the target entry is not in cache, *in_cache_ptr is
* set to FALSE, and *type_ok_ptr is undefined.
*
* Note that this function is only defined if NDEBUG
* is not defined.
*
* Return: FAIL if error is detected, SUCCEED otherwise.
*
* Programmer: John Mainzer, 5/30/14
*
* Changes:
*
* None.
*
*-------------------------------------------------------------------------
*/
#ifndef NDEBUG
herr_t
H5C_verify_entry_type(const H5F_t *f,
haddr_t addr,
const H5C_class_t * expected_type,
hbool_t * in_cache_ptr,
hbool_t * type_ok_ptr)
{
H5C_t * cache_ptr;
H5C_cache_entry_t * entry_ptr = NULL;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
HDassert( f );
HDassert( f->shared );
cache_ptr = f->shared->cache;
HDassert( cache_ptr != NULL );
HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
HDassert( H5F_addr_defined(addr) );
HDassert( in_cache_ptr != NULL );
HDassert( type_ok_ptr != NULL );
/* this test duplicates two of the above asserts, but we need an
* invocation of HGOTO_ERROR to keep the compiler happy.
*/
if ( ( cache_ptr == NULL ) || ( cache_ptr->magic != H5C__H5C_T_MAGIC ) ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad cache_ptr on entry.")
}
H5C__SEARCH_INDEX(cache_ptr, addr, entry_ptr, FAIL)
if ( entry_ptr == NULL ) {
/* the entry doesn't exist in the cache -- report this
* and quit.
*/
*in_cache_ptr = FALSE;
} else {
*in_cache_ptr = TRUE;
*type_ok_ptr = (expected_type == entry_ptr->type);
}
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C_verify_entry_type() */
#endif /* NDEBUG */
/*-------------------------------------------------------------------------
*

View File

@ -846,6 +846,11 @@
* field is intended to allow marking of output of with
* the processes mpi rank.
*
* get_entry_ptr_from_addr_counter: Counter used to track the number of
* times the H5C_get_entry_ptr_from_addr() function has been
* called successfully. This field is only defined when
* NDEBUG is not #defined.
*
****************************************************************************/
#define H5C__HASH_TABLE_LEN (64 * 1024) /* must be a power of 2 */
@ -1007,6 +1012,12 @@ struct H5C_t
#endif /* H5C_COLLECT_CACHE_STATS */
char prefix[H5C__PREFIX_LEN];
#ifndef NDEBUG
int64_t get_entry_ptr_from_addr_counter;
#endif /* NDEBUG */
};
@ -2198,7 +2209,7 @@ if ( (cache_ptr)->index_size != \
(cache_ptr)->slist_len++; \
(cache_ptr)->slist_size += (entry_ptr)->size; \
(cache_ptr)->slist_len_increase++; \
(cache_ptr)->slist_size_increase += (entry_ptr)->size; \
(cache_ptr)->slist_size_increase += (int64_t)((entry_ptr)->size); \
\
HDassert( (cache_ptr)->slist_len > 0 ); \
HDassert( (cache_ptr)->slist_size > 0 ); \

View File

@ -1223,5 +1223,17 @@ H5_DLL herr_t H5C_ignore_tags(H5C_t * cache_ptr);
H5_DLL void H5C_retag_copied_metadata(H5C_t * cache_ptr, haddr_t metadata_tag);
#ifndef NDEBUG /* debugging functions */
H5_DLL herr_t H5C_get_entry_ptr_from_addr(const H5F_t *f, haddr_t addr,
void ** entry_ptr_ptr);
H5_DLL herr_t H5C_verify_entry_type(const H5F_t * f, haddr_t addr,
const H5C_class_t * expected_type,
hbool_t * in_cache_ptr,
hbool_t * type_ok_ptr);
#endif /* NDEBUG */
#endif /* !_H5Cprivate_H */

File diff suppressed because it is too large Load Diff

View File

@ -161,6 +161,7 @@ HDmemset(dblock->blk, 0, dblock->size);
/* Attach to parent indirect block, if there is one */
dblock->parent = par_iblock;
dblock->fd_parent = par_iblock;
if(dblock->parent)
if(H5HF_man_iblock_attach(dblock->parent, par_entry, dblock_addr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTATTACH, FAIL, "can't attach direct block to parent indirect block")

View File

@ -438,7 +438,20 @@ H5HF_man_iblock_root_create(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t min_dblock_si
/* Attach direct block to new root indirect block */
dblock->parent = iblock;
dblock->fd_parent = iblock;
dblock->par_entry = 0;
/* destroy flush dependency between direct block and header */
if(H5AC_destroy_flush_dependency(dblock->hdr, dblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNDEPEND, FAIL, \
"unable to destroy flush dependency")
/* create flush dependency between direct block and new root indirect block */
if(H5AC_create_flush_dependency(dblock->parent, dblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDEPEND, FAIL, \
"unable to create flush dependency")
if(H5HF_man_iblock_attach(iblock, 0, hdr->man_dtable.table_addr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTATTACH, FAIL, "can't attach root direct block to parent indirect block")
@ -884,6 +897,19 @@ H5HF_man_iblock_root_revert(H5HF_indirect_t *root_iblock, hid_t dxpl_id)
dblock->parent = NULL;
dblock->par_entry = 0;
/* destroy flush dependency between old root iblock and new root direct block*/
if(H5AC_destroy_flush_dependency(dblock->fd_parent, dblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNDEPEND, FAIL, \
"unable to destroy flush dependency")
/* create flush dependency between header and new root direct block */
if(H5AC_create_flush_dependency(dblock->hdr, dblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDEPEND, FAIL, \
"unable to create flush dependency")
dblock->fd_parent = NULL;
/* Point root at direct block */
hdr->man_dtable.curr_root_rows = 0;
hdr->man_dtable.table_addr = dblock_addr;
@ -1078,6 +1104,12 @@ H5HF_man_iblock_create(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_indirect_t *par_iblo
/* Attach to parent indirect block, if there is one */
iblock->parent = par_iblock;
iblock->fd_parent = par_iblock; /* this copy of the parent pointer is */
/* needed by the notify callback so */
/* that it can take down flush */
/* dependencies on eviction even if */
/* the parent pointer has been nulled */
/* out. JRM -- 5/18/14 */
iblock->par_entry = par_entry;
if(iblock->parent) {
/* Attach new block to parent */

View File

@ -384,6 +384,13 @@ struct H5HF_indirect_t {
size_t rc; /* Reference count of objects using this block */
H5HF_hdr_t *hdr; /* Shared heap header info */
struct H5HF_indirect_t *parent; /* Shared parent indirect block info */
struct H5HF_indirect_t
*fd_parent; /* Saved copy of the parent pointer -- this */
/* necessary as the parent field is sometimes */
/* nulled out before the eviction notify call */
/* is made from the metadata cache. Since */
/* this call cancels flush dependencies, it */
/* needs this information. */
unsigned par_entry; /* Entry in parent's table */
haddr_t addr; /* Address of this indirect block on disk */
size_t size; /* Size of indirect block on disk */
@ -407,6 +414,12 @@ typedef struct H5HF_direct_t {
/* Internal heap information */
H5HF_hdr_t *hdr; /* Shared heap header info */
H5HF_indirect_t *parent; /* Shared parent indirect block info */
H5HF_indirect_t *fd_parent; /* Saved copy of the parent pointer -- this */
/* necessary as the parent field is sometimes */
/* nulled out before the eviction notify call */
/* is made from the metadata cache. Since */
/* this call cancels flush dependencies, it */
/* needs this information. */
unsigned par_entry; /* Entry in parent's table */
size_t size; /* Size of direct block */
hsize_t file_size; /* Size of direct block in file (only valid when block's space is being freed) */