Merge branch 'develop' into develop_minor

This commit is contained in:
Dana Robinson 2020-08-17 09:00:42 -07:00
commit d53c9be189
17 changed files with 3637 additions and 1844 deletions

View File

@ -1594,19 +1594,19 @@ case "X-$withval" in
AM_CPPFLAGS="$AM_CPPFLAGS -I$szlib_inc" AM_CPPFLAGS="$AM_CPPFLAGS -I$szlib_inc"
fi fi
AC_CHECK_HEADERS([szlib.h],
[HAVE_SZLIB_H="yes"],
[CPPFLAGS="$saved_CPPFLAGS"; AM_CPPFLAGS="$saved_AM_CPPFLAGS"] [unset HAVE_SZLIB])
if test -n "$szlib_lib"; then if test -n "$szlib_lib"; then
LDFLAGS="$LDFLAGS -L$szlib_lib" LDFLAGS="$LDFLAGS -L$szlib_lib"
AM_LDFLAGS="$AM_LDFLAGS -L$szlib_lib" AM_LDFLAGS="$AM_LDFLAGS -L$szlib_lib"
fi fi
if test "x$HAVE_SZLIB" = "xyes" -a "x$HAVE_SZLIB_H" = "xyes"; then if test "x$HAVE_SZLIB" = "xyes"; then
AC_CHECK_LIB([sz], [SZ_BufftoBuffCompress],, AC_CHECK_LIB([sz], [SZ_BufftoBuffCompress],,
[CPPFLAGS="$saved_CPPFLAGS"; AM_CPPFLAGS="$saved_AM_CPPFLAGS"; LDFLAGS="$saved_LDFLAGS"; AM_LDFLAGS="$saved_AM_LDFLAGS"; unset HAVE_SZLIB]) [CPPFLAGS="$saved_CPPFLAGS"; AM_CPPFLAGS="$saved_AM_CPPFLAGS"; LDFLAGS="$saved_LDFLAGS"; AM_LDFLAGS="$saved_AM_LDFLAGS"; unset HAVE_SZLIB])
if test -z "$HAVE_SZLIB"; then if test -n "$HAVE_SZLIB"; then
AC_CHECK_HEADERS([szlib.h],
[HAVE_SZLIB_H="yes"],
[CPPFLAGS="$saved_CPPFLAGS"; AM_CPPFLAGS="$saved_AM_CPPFLAGS"] [unset HAVE_SZLIB])
else
AC_MSG_RESULT([Using SZ_BufftoBuffCompress from libsz in $szlib_lib failed. Szip not enabled.]) AC_MSG_RESULT([Using SZ_BufftoBuffCompress from libsz in $szlib_lib failed. Szip not enabled.])
fi fi
fi fi

View File

@ -140,8 +140,8 @@ static const H5AC_class_t *const H5AC_class_s[] = {
* *
* Purpose: Initialize the interface from some other layer. * Purpose: Initialize the interface from some other layer.
* *
* Return: Success: non-negative * Return: Success: non-negative
* Failure: negative * Failure: negative
* *
* Programmer: Quincey Koziol * Programmer: Quincey Koziol
* Saturday, January 18, 2003 * Saturday, January 18, 2003
@ -162,7 +162,7 @@ done:
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
* Function H5AC__init_package * Function: H5AC__init_package
* *
* Purpose: Initialize interface-specific information * Purpose: Initialize interface-specific information
* *
@ -202,9 +202,9 @@ H5AC__init_package(void)
* *
* Purpose: Terminate this interface. * Purpose: Terminate this interface.
* *
* Return: Success: Positive if anything was done that might * Return: Success: Positive if anything was done that might
* affect other interfaces; zero otherwise. * affect other interfaces; zero otherwise.
* Failure: Negative. * Failure: Negative.
* *
* Programmer: Quincey Koziol * Programmer: Quincey Koziol
* Thursday, July 18, 2002 * Thursday, July 18, 2002
@ -281,7 +281,7 @@ herr_t
H5AC_create(const H5F_t *f, H5AC_cache_config_t *config_ptr, H5AC_cache_image_config_t * image_config_ptr) H5AC_create(const H5F_t *f, H5AC_cache_config_t *config_ptr, H5AC_cache_image_config_t * image_config_ptr)
{ {
#ifdef H5_HAVE_PARALLEL #ifdef H5_HAVE_PARALLEL
char prefix[H5C__PREFIX_LEN] = ""; char prefix[H5C__PREFIX_LEN] = "";
H5AC_aux_t * aux_ptr = NULL; H5AC_aux_t * aux_ptr = NULL;
#endif /* H5_HAVE_PARALLEL */ #endif /* H5_HAVE_PARALLEL */
struct H5C_cache_image_ctl_t int_ci_config = H5C__DEFAULT_CACHE_IMAGE_CTL; struct H5C_cache_image_ctl_t int_ci_config = H5C__DEFAULT_CACHE_IMAGE_CTL;
@ -468,6 +468,14 @@ done:
* Programmer: Robb Matzke * Programmer: Robb Matzke
* Jul 9 1997 * Jul 9 1997
* *
* Changes:
*
* In the parallel case, added code to setup the MDC slist
* before the call to H5AC__flush_entries() and take it down
* afterwards.
*
* JRM -- 7/29/20
*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
herr_t herr_t
@ -493,58 +501,115 @@ H5AC_dest(H5F_t *f)
#endif /* H5AC_DUMP_STATS_ON_CLOSE */ #endif /* H5AC_DUMP_STATS_ON_CLOSE */
/* Check if log messages are being emitted */ /* Check if log messages are being emitted */
if(H5C_get_logging_status(f->shared->cache, &log_enabled, &curr_logging) < 0) if(H5C_get_logging_status(f->shared->cache,
&log_enabled, &curr_logging) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to get logging status") HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to get logging status")
if(log_enabled && curr_logging) if(log_enabled && curr_logging) {
if(H5C_log_write_destroy_cache_msg(f->shared->cache) < 0) if(H5C_log_write_destroy_cache_msg(f->shared->cache) < 0)
HDONE_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
HDONE_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, \
"unable to emit log message")
}
/* Tear down logging */ /* Tear down logging */
if(log_enabled) if(log_enabled) {
if(H5C_log_tear_down(f->shared->cache) < 0) if(H5C_log_tear_down(f->shared->cache) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "mdc logging tear-down failed")
HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, \
"mdc logging tear-down failed")
}
#ifdef H5_HAVE_PARALLEL #ifdef H5_HAVE_PARALLEL
/* destroying the cache, so clear all collective entries */ /* destroying the cache, so clear all collective entries */
if(H5C_clear_coll_entries(f->shared->cache, FALSE) < 0) if(H5C_clear_coll_entries(f->shared->cache, FALSE) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, FAIL, "H5C_clear_coll_entries() failed")
HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, FAIL, \
"H5C_clear_coll_entries() failed")
aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(f->shared->cache); aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(f->shared->cache);
if(aux_ptr)
if(aux_ptr) {
/* Sanity check */ /* Sanity check */
HDassert(aux_ptr->magic == H5AC__H5AC_AUX_T_MAGIC); HDassert(aux_ptr->magic == H5AC__H5AC_AUX_T_MAGIC);
/* If the file was opened R/W, attempt to flush all entries /* If the file was opened R/W, attempt to flush all entries
* from rank 0 & Bcast clean list to other ranks. * from rank 0 & Bcast clean list to other ranks.
* *
* Must not flush in the R/O case, as this will trigger the * Must not flush in the R/O case, as this will trigger the
* free space manager settle routines. * free space manager settle routines.
*/ *
if(H5F_ACC_RDWR & H5F_INTENT(f)) * Must also enable the skip list before the call to
if(H5AC__flush_entries(f) < 0) * H5AC__flush_entries() and disable it afterwards, as the
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush") * skip list will be disabled after the previous flush.
*
* Note that H5C_dest() does slist setup and take down as well.
* Unfortunately, we can't do the setup and take down just once,
* as H5C_dest() is called directly in the test code.
*
* Fortunately, the cache should be clean or close to it at this
* point, so the overhead should be minimal.
*/
if(H5F_ACC_RDWR & H5F_INTENT(f)) {
/* enable and load the slist */
if ( H5C_set_slist_enabled(f->shared->cache, TRUE, FALSE) < 0 )
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"set slist enabled failed")
if(H5AC__flush_entries(f) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush")
/* disable the slist -- should be empty */
if ( H5C_set_slist_enabled(f->shared->cache, FALSE, FALSE) < 0 )
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "disable slist failed")
}
}
#endif /* H5_HAVE_PARALLEL */ #endif /* H5_HAVE_PARALLEL */
/* Destroy the cache */ /* Destroy the cache */
if(H5C_dest(f) < 0) if(H5C_dest(f) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "can't destroy cache") HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "can't destroy cache")
f->shared->cache = NULL; f->shared->cache = NULL;
#ifdef H5_HAVE_PARALLEL #ifdef H5_HAVE_PARALLEL
if(aux_ptr != NULL) { if(aux_ptr != NULL) {
if(aux_ptr->d_slist_ptr != NULL) { if(aux_ptr->d_slist_ptr != NULL) {
HDassert(H5SL_count(aux_ptr->d_slist_ptr) == 0); HDassert(H5SL_count(aux_ptr->d_slist_ptr) == 0);
H5SL_close(aux_ptr->d_slist_ptr); H5SL_close(aux_ptr->d_slist_ptr);
} /* end if */ } /* end if */
if(aux_ptr->c_slist_ptr != NULL) { if(aux_ptr->c_slist_ptr != NULL) {
HDassert(H5SL_count(aux_ptr->c_slist_ptr) == 0); HDassert(H5SL_count(aux_ptr->c_slist_ptr) == 0);
H5SL_close(aux_ptr->c_slist_ptr); H5SL_close(aux_ptr->c_slist_ptr);
} /* end if */ } /* end if */
if(aux_ptr->candidate_slist_ptr != NULL) { if(aux_ptr->candidate_slist_ptr != NULL) {
HDassert(H5SL_count(aux_ptr->candidate_slist_ptr) == 0); HDassert(H5SL_count(aux_ptr->candidate_slist_ptr) == 0);
H5SL_close(aux_ptr->candidate_slist_ptr); H5SL_close(aux_ptr->candidate_slist_ptr);
} /* end if */ } /* end if */
aux_ptr->magic = 0; aux_ptr->magic = 0;
aux_ptr = H5FL_FREE(H5AC_aux_t, aux_ptr); aux_ptr = H5FL_FREE(H5AC_aux_t, aux_ptr);
} /* end if */ } /* end if */
#endif /* H5_HAVE_PARALLEL */ #endif /* H5_HAVE_PARALLEL */
@ -736,20 +801,20 @@ H5AC_get_entry_status(const H5F_t *f, haddr_t addr, unsigned *status)
if(in_cache) { if(in_cache) {
*status |= H5AC_ES__IN_CACHE; *status |= H5AC_ES__IN_CACHE;
if(is_dirty) if(is_dirty)
*status |= H5AC_ES__IS_DIRTY; *status |= H5AC_ES__IS_DIRTY;
if(is_protected) if(is_protected)
*status |= H5AC_ES__IS_PROTECTED; *status |= H5AC_ES__IS_PROTECTED;
if(is_pinned) if(is_pinned)
*status |= H5AC_ES__IS_PINNED; *status |= H5AC_ES__IS_PINNED;
if(is_corked) if(is_corked)
*status |= H5AC_ES__IS_CORKED; *status |= H5AC_ES__IS_CORKED;
if(is_flush_dep_parent) if(is_flush_dep_parent)
*status |= H5AC_ES__IS_FLUSH_DEP_PARENT; *status |= H5AC_ES__IS_FLUSH_DEP_PARENT;
if(is_flush_dep_child) if(is_flush_dep_child)
*status |= H5AC_ES__IS_FLUSH_DEP_CHILD; *status |= H5AC_ES__IS_FLUSH_DEP_CHILD;
if(image_is_up_to_date) if(image_is_up_to_date)
*status |= H5AC_ES__IMAGE_IS_UP_TO_DATE; *status |= H5AC_ES__IMAGE_IS_UP_TO_DATE;
} /* end if */ } /* end if */
else else
*status = 0; *status = 0;
@ -1200,6 +1265,109 @@ done:
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
*
* Function: H5AC_prep_for_file_flush
*
* Purpose: This function should be called just prior to the first
* call to H5AC_flush() during a file flush.
*
* Its purpose is to handly any setup required prior to
* metadata cache flush.
*
* Initially, this means setting up the slist prior to the
* flush. We do this in a seperate call because
* H5F__flush_phase2() make repeated calls to H5AC_flush().
* Handling this detail in separate calls allows us to avoid
* the overhead of setting up and taking down the skip list
* repeatedly.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: John Mainzer
* 5/5/20
*
* Changes: None.
*
*-------------------------------------------------------------------------
*/
herr_t
H5AC_prep_for_file_flush(H5F_t *f)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
/* Sanity checks */
HDassert(f);
HDassert(f->shared);
HDassert(f->shared->cache);
if ( H5C_set_slist_enabled(f->shared->cache, TRUE, FALSE) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "slist enabled failed")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_prep_for_file_flush() */
/*-------------------------------------------------------------------------
*
* Function: H5AC_secure_from_file_flush
*
* Purpose: This function should be called just after the last
* call to H5AC_flush() during a file flush.
*
* Its purpose is to perform any necessary cleanup after the
* metadata cache flush.
*
* The objective of the call is to allow the metadata cache
* to do any necessary necessary cleanup work after a cache
* flush.
*
* Initially, this means taking down the slist after the
* flush. We do this in a seperate call because
* H5F__flush_phase2() make repeated calls to H5AC_flush().
* Handling this detail in separate calls allows us to avoid
* the overhead of setting up and taking down the skip list
* repeatedly.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: John Mainzer
* 5/5/20
*
* Changes: None.
*
*-------------------------------------------------------------------------
*/
herr_t
H5AC_secure_from_file_flush(H5F_t *f)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
/* Sanity checks */
HDassert(f);
HDassert(f->shared);
HDassert(f->shared->cache);
if ( H5C_set_slist_enabled(f->shared->cache, FALSE, FALSE) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "slist enabled failed")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_secure_from_file_flush() */
/*-------------------------------------------------------------------------
*
* Function: H5AC_create_flush_dependency() * Function: H5AC_create_flush_dependency()
* *
* Purpose: Create a flush dependency between two entries in the metadata * Purpose: Create a flush dependency between two entries in the metadata
@ -1508,8 +1676,8 @@ herr_t
H5AC_unprotect(H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing, H5AC_unprotect(H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing,
unsigned flags) unsigned flags)
{ {
hbool_t dirtied; hbool_t dirtied;
hbool_t deleted; hbool_t deleted;
#ifdef H5_HAVE_PARALLEL #ifdef H5_HAVE_PARALLEL
H5AC_aux_t * aux_ptr = NULL; H5AC_aux_t * aux_ptr = NULL;
#endif /* H5_HAVE_PARALLEL */ #endif /* H5_HAVE_PARALLEL */
@ -1530,14 +1698,14 @@ H5AC_unprotect(H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing,
HDassert(((H5AC_info_t *)thing)->type == type); HDassert(((H5AC_info_t *)thing)->type == type);
dirtied = (hbool_t)(((flags & H5AC__DIRTIED_FLAG) == H5AC__DIRTIED_FLAG) || dirtied = (hbool_t)(((flags & H5AC__DIRTIED_FLAG) == H5AC__DIRTIED_FLAG) ||
(((H5AC_info_t *)thing)->dirtied)); (((H5AC_info_t *)thing)->dirtied));
deleted = (hbool_t)((flags & H5C__DELETED_FLAG) == H5C__DELETED_FLAG); deleted = (hbool_t)((flags & H5C__DELETED_FLAG) == H5C__DELETED_FLAG);
/* Check if the size changed out from underneath us, if we're not deleting /* Check if the size changed out from underneath us, if we're not deleting
* the entry. * the entry.
*/ */
if(dirtied && !deleted) { if(dirtied && !deleted) {
size_t curr_size = 0; size_t curr_size = 0;
if((type->image_len)(thing, &curr_size) < 0) if((type->image_len)(thing, &curr_size) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTGETSIZE, FAIL, "Can't get size of thing") HGOTO_ERROR(H5E_CACHE, H5E_CANTGETSIZE, FAIL, "Can't get size of thing")
@ -1624,7 +1792,7 @@ H5AC_get_cache_auto_resize_config(const H5AC_t *cache_ptr,
if(internal_config.rpt_fcn == NULL) if(internal_config.rpt_fcn == NULL)
config_ptr->rpt_fcn_enabled = FALSE; config_ptr->rpt_fcn_enabled = FALSE;
else else
config_ptr->rpt_fcn_enabled = TRUE; config_ptr->rpt_fcn_enabled = TRUE;
config_ptr->open_trace_file = FALSE; config_ptr->open_trace_file = FALSE;
config_ptr->close_trace_file = FALSE; config_ptr->close_trace_file = FALSE;
config_ptr->trace_file_name[0] = '\0'; config_ptr->trace_file_name[0] = '\0';
@ -1913,7 +2081,7 @@ H5AC_validate_config(H5AC_cache_config_t *config_ptr)
/* don't bother to test trace_file_name unless open_trace_file is TRUE */ /* don't bother to test trace_file_name unless open_trace_file is TRUE */
if(config_ptr->open_trace_file) { if(config_ptr->open_trace_file) {
size_t name_len; size_t name_len;
/* Can't really test the trace_file_name field without trying to /* Can't really test the trace_file_name field without trying to
* open the file, so we will content ourselves with a couple of * open the file, so we will content ourselves with a couple of
@ -2034,9 +2202,9 @@ H5_ATTR_UNUSED
*f, hbool_t *write_permitted_ptr) *f, hbool_t *write_permitted_ptr)
{ {
#ifdef H5_HAVE_PARALLEL #ifdef H5_HAVE_PARALLEL
H5AC_aux_t * aux_ptr = NULL; H5AC_aux_t * aux_ptr = NULL;
#endif /* H5_HAVE_PARALLEL */ #endif /* H5_HAVE_PARALLEL */
hbool_t write_permitted = TRUE; hbool_t write_permitted = TRUE;
FUNC_ENTER_STATIC_NOERR FUNC_ENTER_STATIC_NOERR
@ -2533,8 +2701,8 @@ H5AC_set_ring(H5AC_ring_t ring, H5AC_ring_t *orig_ring)
* Note that this function simply passes the call on to * Note that this function simply passes the call on to
* the metadata cache proper, and returns the result. * the metadata cache proper, and returns the result.
* *
* Return: Success: Non-negative * Return: Success: Non-negative
* Failure: Negative * Failure: Negative
* *
* Programmer: Quincey Koziol * Programmer: Quincey Koziol
* September 17, 2016 * September 17, 2016
@ -2669,4 +2837,3 @@ H5AC_get_mdc_image_info(H5AC_t *cache_ptr, haddr_t *image_addr, hsize_t *image_l
done: done:
FUNC_LEAVE_NOAPI(ret_value) FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_get_mdc_image_info() */ } /* H5AC_get_mdc_image_info() */

View File

@ -791,7 +791,7 @@ H5AC__log_dirtied_entry(const H5AC_info_t *entry_ptr)
else { else {
aux_ptr->dirty_bytes += entry_ptr->size; aux_ptr->dirty_bytes += entry_ptr->size;
#if H5AC_DEBUG_DIRTY_BYTES_CREATION #if H5AC_DEBUG_DIRTY_BYTES_CREATION
aux_ptr->unprotect_dirty_bytes += entry_size; aux_ptr->unprotect_dirty_bytes += entry_ptr->size;
aux_ptr->unprotect_dirty_bytes_updates += 1; aux_ptr->unprotect_dirty_bytes_updates += 1;
#endif /* H5AC_DEBUG_DIRTY_BYTES_CREATION */ #endif /* H5AC_DEBUG_DIRTY_BYTES_CREATION */
} /* end else */ } /* end else */
@ -989,7 +989,7 @@ H5AC__log_inserted_entry(const H5AC_info_t *entry_ptr)
aux_ptr->dirty_bytes += entry_ptr->size; aux_ptr->dirty_bytes += entry_ptr->size;
#if H5AC_DEBUG_DIRTY_BYTES_CREATION #if H5AC_DEBUG_DIRTY_BYTES_CREATION
aux_ptr->insert_dirty_bytes += size; aux_ptr->insert_dirty_bytes += entry_ptr->size;
aux_ptr->insert_dirty_bytes_updates += 1; aux_ptr->insert_dirty_bytes_updates += 1;
#endif /* H5AC_DEBUG_DIRTY_BYTES_CREATION */ #endif /* H5AC_DEBUG_DIRTY_BYTES_CREATION */
@ -1875,6 +1875,8 @@ done:
* Programmer: John Mainzer * Programmer: John Mainzer
* April 28, 2010 * April 28, 2010
* *
* Changes: None.
*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
static herr_t static herr_t
@ -1894,7 +1896,8 @@ H5AC__rsp__p0_only__flush(H5F_t *f)
aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(cache_ptr); aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(cache_ptr);
HDassert(aux_ptr != NULL); HDassert(aux_ptr != NULL);
HDassert(aux_ptr->magic == H5AC__H5AC_AUX_T_MAGIC); HDassert(aux_ptr->magic == H5AC__H5AC_AUX_T_MAGIC);
HDassert(aux_ptr->metadata_write_strategy == H5AC_METADATA_WRITE_STRATEGY__PROCESS_0_ONLY); HDassert(aux_ptr->metadata_write_strategy == \
H5AC_METADATA_WRITE_STRATEGY__PROCESS_0_ONLY);
/* To prevent "messages from the future" we must /* To prevent "messages from the future" we must
* synchronize all processes before we start the flush. * synchronize all processes before we start the flush.
@ -1903,9 +1906,12 @@ H5AC__rsp__p0_only__flush(H5F_t *f)
* However, when flushing from within the close operation from a file, * However, when flushing from within the close operation from a file,
* it's possible to skip this barrier (on the second flush of the cache). * it's possible to skip this barrier (on the second flush of the cache).
*/ */
if(!H5CX_get_mpi_file_flushing()) if ( ! H5CX_get_mpi_file_flushing() ) {
if(MPI_SUCCESS != (mpi_result = MPI_Barrier(aux_ptr->mpi_comm)))
if ( MPI_SUCCESS != (mpi_result = MPI_Barrier(aux_ptr->mpi_comm)) )
HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_result) HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_result)
}
/* Flush data to disk, from rank 0 process */ /* Flush data to disk, from rank 0 process */
if(aux_ptr->mpi_rank == 0) { if(aux_ptr->mpi_rank == 0) {
@ -1921,23 +1927,30 @@ H5AC__rsp__p0_only__flush(H5F_t *f)
aux_ptr->write_permitted = FALSE; aux_ptr->write_permitted = FALSE;
/* Check for error on the write operation */ /* Check for error on the write operation */
if(result < 0) if ( result < 0 )
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush.") HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush.")
/* this code exists primarily for the test bed -- it allows us to /* this code exists primarily for the test bed -- it allows us to
* enforce POSIX semantics on the server that pretends to be a * enforce POSIX semantics on the server that pretends to be a
* file system in our parallel tests. * file system in our parallel tests.
*/ */
if(aux_ptr->write_done) if ( aux_ptr->write_done ) {
(aux_ptr->write_done)(); (aux_ptr->write_done)();
}
} /* end if */ } /* end if */
/* Propagate cleaned entries to other ranks. */ /* Propagate cleaned entries to other ranks. */
if(H5AC__propagate_flushed_and_still_clean_entries_list(f) < 0) if ( H5AC__propagate_flushed_and_still_clean_entries_list(f) < 0 )
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't propagate clean entries list.")
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
"Can't propagate clean entries list.")
done: done:
FUNC_LEAVE_NOAPI(ret_value) FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC__rsp__p0_only__flush() */ } /* H5AC__rsp__p0_only__flush() */
@ -2104,16 +2117,22 @@ H5AC__run_sync_point(H5F_t *f, int sync_point_op)
/* Sanity checks */ /* Sanity checks */
HDassert(f != NULL); HDassert(f != NULL);
cache_ptr = f->shared->cache; cache_ptr = f->shared->cache;
HDassert(cache_ptr != NULL); HDassert(cache_ptr != NULL);
aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(cache_ptr); aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(cache_ptr);
HDassert(aux_ptr != NULL); HDassert(aux_ptr != NULL);
HDassert(aux_ptr->magic == H5AC__H5AC_AUX_T_MAGIC); HDassert(aux_ptr->magic == H5AC__H5AC_AUX_T_MAGIC);
HDassert((sync_point_op == H5AC_SYNC_POINT_OP__FLUSH_TO_MIN_CLEAN) || HDassert((sync_point_op == H5AC_SYNC_POINT_OP__FLUSH_TO_MIN_CLEAN) ||
(sync_point_op == H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED)); (sync_point_op == H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED));
#if H5AC_DEBUG_DIRTY_BYTES_CREATION #if H5AC_DEBUG_DIRTY_BYTES_CREATION
HDfprintf(stdout, "%d:H5AC_propagate...:%u: (u/uu/i/iu/r/ru) = %zu/%u/%zu/%u/%zu/%u\n", HDfprintf(stdout,
"%d:H5AC_propagate...:%u: (u/uu/i/iu/r/ru) = %zu/%u/%zu/%u/%zu/%u\n",
aux_ptr->mpi_rank, aux_ptr->mpi_rank,
aux_ptr->dirty_bytes_propagations, aux_ptr->dirty_bytes_propagations,
aux_ptr->unprotect_dirty_bytes, aux_ptr->unprotect_dirty_bytes,
@ -2188,6 +2207,7 @@ HDfprintf(stdout, "%d:H5AC_propagate...:%u: (u/uu/i/iu/r/ru) = %zu/%u/%zu/%u/%zu
#endif /* H5AC_DEBUG_DIRTY_BYTES_CREATION */ #endif /* H5AC_DEBUG_DIRTY_BYTES_CREATION */
done: done:
FUNC_LEAVE_NOAPI(ret_value) FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC__run_sync_point() */ } /* H5AC__run_sync_point() */

View File

@ -387,6 +387,8 @@ H5_DLL herr_t H5AC_insert_entry(H5F_t *f, const H5AC_class_t *type,
haddr_t addr, void *thing, unsigned int flags); haddr_t addr, void *thing, unsigned int flags);
H5_DLL herr_t H5AC_pin_protected_entry(void *thing); H5_DLL herr_t H5AC_pin_protected_entry(void *thing);
H5_DLL herr_t H5AC_prep_for_file_close(H5F_t *f); H5_DLL herr_t H5AC_prep_for_file_close(H5F_t *f);
H5_DLL herr_t H5AC_prep_for_file_flush(H5F_t *f);
H5_DLL herr_t H5AC_secure_from_file_flush(H5F_t *f);
H5_DLL herr_t H5AC_create_flush_dependency(void *parent_thing, void *child_thing); H5_DLL herr_t H5AC_create_flush_dependency(void *parent_thing, void *child_thing);
H5_DLL void * H5AC_protect(H5F_t *f, const H5AC_class_t *type, haddr_t addr, H5_DLL void * H5AC_protect(H5F_t *f, const H5AC_class_t *type, haddr_t addr,
void *udata, unsigned flags); void *udata, unsigned flags);

1877
src/H5C.c

File diff suppressed because it is too large Load Diff

View File

@ -260,17 +260,24 @@ H5C_dump_cache_LRU(H5C_t *cache_ptr, const char *cache_name)
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
*
* Function: H5C_dump_cache_skip_list * Function: H5C_dump_cache_skip_list
* *
* Purpose: Debugging routine that prints a summary of the contents of * Purpose: Debugging routine that prints a summary of the contents of
* the skip list used by the metadata cache metadata cache to * the skip list used by the metadata cache metadata cache to
* maintain an address sorted list of dirty entries. * maintain an address sorted list of dirty entries.
* *
* Return: Non-negative on success/Negative on failure * Return: Non-negative on success/Negative on failure
* *
* Programmer: John Mainzer * Programmer: John Mainzer
* 11/15/14 * 11/15/14
* *
* Changes: Updated function for the slist_enabled field in H5C_t.
* Recall that to minimize slist overhead, the slist is
* empty and not maintained if cache_ptr->slist_enabled is
* false.
* JRM -- 5/6/20
*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#ifndef NDEBUG #ifndef NDEBUG
@ -288,11 +295,16 @@ H5C_dump_cache_skip_list(H5C_t * cache_ptr, char * calling_fcn)
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
HDassert(calling_fcn != NULL); HDassert(calling_fcn != NULL);
HDfprintf(stdout, "\n\nDumping metadata cache skip list from %s.\n", calling_fcn); HDfprintf(stdout, "\n\nDumping metadata cache skip list from %s.\n",
calling_fcn);
HDfprintf(stdout, " slist enabled = %d.\n",
(int)(cache_ptr->slist_enabled));
HDfprintf(stdout, " slist len = %u.\n", cache_ptr->slist_len); HDfprintf(stdout, " slist len = %u.\n", cache_ptr->slist_len);
HDfprintf(stdout, " slist size = %lld.\n", (long long)(cache_ptr->slist_size)); HDfprintf(stdout, " slist size = %lld.\n",
(long long)(cache_ptr->slist_size));
if(cache_ptr->slist_len > 0) { if(cache_ptr->slist_len > 0) {
/* If we get this far, all entries in the cache are listed in the /* If we get this far, all entries in the cache are listed in the
* skip list -- scan the skip list generating the desired output. * skip list -- scan the skip list generating the desired output.
*/ */
@ -300,13 +312,20 @@ H5C_dump_cache_skip_list(H5C_t * cache_ptr, char * calling_fcn)
"Num: Addr: Len: Prot/Pind: Dirty: Type:\n"); "Num: Addr: Len: Prot/Pind: Dirty: Type:\n");
i = 0; i = 0;
node_ptr = H5SL_first(cache_ptr->slist_ptr);
if(node_ptr != NULL)
entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr);
else
entry_ptr = NULL;
while(entry_ptr != NULL) { node_ptr = H5SL_first(cache_ptr->slist_ptr);
if ( node_ptr != NULL ) {
entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr);
} else {
entry_ptr = NULL;
}
while ( entry_ptr != NULL ) {
HDassert( entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC ); HDassert( entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC );
HDfprintf(stdout, HDfprintf(stdout,
@ -323,19 +342,27 @@ H5C_dump_cache_skip_list(H5C_t * cache_ptr, char * calling_fcn)
node_ptr, H5SL_item(node_ptr)); node_ptr, H5SL_item(node_ptr));
/* increment node_ptr before we delete its target */ /* increment node_ptr before we delete its target */
node_ptr = H5SL_next(node_ptr); node_ptr = H5SL_next(node_ptr);
if(node_ptr != NULL)
if ( node_ptr != NULL ) {
entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr); entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr);
else
} else {
entry_ptr = NULL; entry_ptr = NULL;
}
i++; i++;
} /* end while */ } /* end while */
} /* end if */ } /* end if */
HDfprintf(stdout, "\n\n"); HDfprintf(stdout, "\n\n");
FUNC_LEAVE_NOAPI(ret_value) FUNC_LEAVE_NOAPI(ret_value)
} /* H5C_dump_cache_skip_list() */ } /* H5C_dump_cache_skip_list() */
#endif /* NDEBUG */ #endif /* NDEBUG */

View File

@ -431,36 +431,40 @@ done:
* Function: H5C__deserialize_prefetched_entry() * Function: H5C__deserialize_prefetched_entry()
* *
* Purpose: Deserialize the supplied prefetched entry entry, and return * Purpose: Deserialize the supplied prefetched entry entry, and return
* a pointer to the deserialized entry in *entry_ptr_ptr. * a pointer to the deserialized entry in *entry_ptr_ptr.
* If successful, remove the prefetched entry from the cache, * If successful, remove the prefetched entry from the cache,
* and free it. Insert the deserialized entry into the cache. * and free it. Insert the deserialized entry into the cache.
* *
* Note that the on disk image of the entry is not freed -- * Note that the on disk image of the entry is not freed --
* a pointer to it is stored in the deserialized entries' * a pointer to it is stored in the deserialized entries'
* image_ptr field, and its image_up_to_date field is set to * image_ptr field, and its image_up_to_date field is set to
* TRUE unless the entry is dirtied by the deserialize call. * TRUE unless the entry is dirtied by the deserialize call.
* *
* If the prefetched entry is a flush dependency child, * If the prefetched entry is a flush dependency child,
* destroy that flush dependency prior to calling the * destroy that flush dependency prior to calling the
* deserialize callback. If appropriate, the flush dependency * deserialize callback. If appropriate, the flush dependency
* relationship will be recreated by the cache client. * relationship will be recreated by the cache client.
* *
* If the prefetched entry is a flush dependency parent, * If the prefetched entry is a flush dependency parent,
* destroy the flush dependency relationship with all its * destroy the flush dependency relationship with all its
* children. As all these children must be prefetched entries, * children. As all these children must be prefetched entries,
* recreate these flush dependency relationships with * recreate these flush dependency relationships with
* deserialized entry after it is inserted in the cache. * deserialized entry after it is inserted in the cache.
* *
* Since deserializing a prefetched entry is semantically * Since deserializing a prefetched entry is semantically
* equivalent to a load, issue an entry loaded nofification * equivalent to a load, issue an entry loaded nofification
* if the notify callback is defined. * if the notify callback is defined.
* *
* Return: SUCCEED on success, and FAIL on failure. * Return: SUCCEED on success, and FAIL on failure.
* *
* Note that *entry_ptr_ptr is undefined on failure. * Note that *entry_ptr_ptr is undefined on failure.
* *
* Programmer: John Mainzer, 8/10/15 * Programmer: John Mainzer, 8/10/15
* *
* Changes: Updated sanity checks for possibility that the slist
* is disabled.
* JRM -- 5/17/20
*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
herr_t herr_t
@ -468,11 +472,11 @@ H5C__deserialize_prefetched_entry(H5F_t *f, H5C_t *cache_ptr,
H5C_cache_entry_t **entry_ptr_ptr, const H5C_class_t *type, H5C_cache_entry_t **entry_ptr_ptr, const H5C_class_t *type,
haddr_t addr, void *udata) haddr_t addr, void *udata)
{ {
hbool_t dirty = FALSE; /* Flag indicating whether thing was hbool_t dirty = FALSE; /* Flag indicating whether thing was
* dirtied during deserialize * dirtied during deserialize
*/ */
size_t len; /* Size of image in file */ size_t len; /* Size of image in file */
void * thing = NULL; /* Pointer to thing loaded */ void * thing = NULL; /* Pointer to thing loaded */
H5C_cache_entry_t * pf_entry_ptr; /* pointer to the prefetched entry */ H5C_cache_entry_t * pf_entry_ptr; /* pointer to the prefetched entry */
/* supplied in *entry_ptr_ptr. */ /* supplied in *entry_ptr_ptr. */
H5C_cache_entry_t * ds_entry_ptr; /* Alias for thing loaded, as cache H5C_cache_entry_t * ds_entry_ptr; /* Alias for thing loaded, as cache
@ -484,8 +488,8 @@ H5C__deserialize_prefetched_entry(H5F_t *f, H5C_t *cache_ptr,
/* the prefetched entry, or NULL if */ /* the prefetched entry, or NULL if */
/* that array does not exist. */ /* that array does not exist. */
unsigned flush_flags = (H5C__FLUSH_INVALIDATE_FLAG | unsigned flush_flags = (H5C__FLUSH_INVALIDATE_FLAG |
H5C__FLUSH_CLEAR_ONLY_FLAG); H5C__FLUSH_CLEAR_ONLY_FLAG);
int i; int i;
herr_t ret_value = SUCCEED; /* Return value */ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE FUNC_ENTER_PACKAGE
@ -604,73 +608,73 @@ H5C__deserialize_prefetched_entry(H5F_t *f, H5C_t *cache_ptr,
HDassert( ( dirty == FALSE ) || ( type->id == 5 || type->id == 6) ); HDassert( ( dirty == FALSE ) || ( type->id == 5 || type->id == 6) );
ds_entry_ptr->magic = H5C__H5C_CACHE_ENTRY_T_MAGIC; ds_entry_ptr->magic = H5C__H5C_CACHE_ENTRY_T_MAGIC;
ds_entry_ptr->cache_ptr = f->shared->cache; ds_entry_ptr->cache_ptr = f->shared->cache;
ds_entry_ptr->addr = addr; ds_entry_ptr->addr = addr;
ds_entry_ptr->size = len; ds_entry_ptr->size = len;
HDassert(ds_entry_ptr->size < H5C_MAX_ENTRY_SIZE); HDassert(ds_entry_ptr->size < H5C_MAX_ENTRY_SIZE);
ds_entry_ptr->image_ptr = pf_entry_ptr->image_ptr; ds_entry_ptr->image_ptr = pf_entry_ptr->image_ptr;
ds_entry_ptr->image_up_to_date = !dirty; ds_entry_ptr->image_up_to_date = !dirty;
ds_entry_ptr->type = type; ds_entry_ptr->type = type;
ds_entry_ptr->is_dirty = dirty | pf_entry_ptr->is_dirty; ds_entry_ptr->is_dirty = dirty | pf_entry_ptr->is_dirty;
ds_entry_ptr->dirtied = FALSE; ds_entry_ptr->dirtied = FALSE;
ds_entry_ptr->is_protected = FALSE; ds_entry_ptr->is_protected = FALSE;
ds_entry_ptr->is_read_only = FALSE; ds_entry_ptr->is_read_only = FALSE;
ds_entry_ptr->ro_ref_count = 0; ds_entry_ptr->ro_ref_count = 0;
ds_entry_ptr->is_pinned = FALSE; ds_entry_ptr->is_pinned = FALSE;
ds_entry_ptr->in_slist = FALSE; ds_entry_ptr->in_slist = FALSE;
ds_entry_ptr->flush_marker = FALSE; ds_entry_ptr->flush_marker = FALSE;
#ifdef H5_HAVE_PARALLEL #ifdef H5_HAVE_PARALLEL
ds_entry_ptr->clear_on_unprotect = FALSE; ds_entry_ptr->clear_on_unprotect = FALSE;
ds_entry_ptr->flush_immediately = FALSE; ds_entry_ptr->flush_immediately = FALSE;
ds_entry_ptr->coll_access = FALSE; ds_entry_ptr->coll_access = FALSE;
#endif /* H5_HAVE_PARALLEL */ #endif /* H5_HAVE_PARALLEL */
ds_entry_ptr->flush_in_progress = FALSE; ds_entry_ptr->flush_in_progress = FALSE;
ds_entry_ptr->destroy_in_progress = FALSE; ds_entry_ptr->destroy_in_progress = FALSE;
ds_entry_ptr->ring = pf_entry_ptr->ring; ds_entry_ptr->ring = pf_entry_ptr->ring;
/* Initialize flush dependency height fields */ /* Initialize flush dependency height fields */
ds_entry_ptr->flush_dep_parent = NULL; ds_entry_ptr->flush_dep_parent = NULL;
ds_entry_ptr->flush_dep_nparents = 0; ds_entry_ptr->flush_dep_nparents = 0;
ds_entry_ptr->flush_dep_parent_nalloc = 0; ds_entry_ptr->flush_dep_parent_nalloc = 0;
ds_entry_ptr->flush_dep_nchildren = 0; ds_entry_ptr->flush_dep_nchildren = 0;
ds_entry_ptr->flush_dep_ndirty_children = 0; ds_entry_ptr->flush_dep_ndirty_children = 0;
ds_entry_ptr->flush_dep_nunser_children = 0; ds_entry_ptr->flush_dep_nunser_children = 0;
/* Initialize fields supporting the hash table: */ /* Initialize fields supporting the hash table: */
ds_entry_ptr->ht_next = NULL; ds_entry_ptr->ht_next = NULL;
ds_entry_ptr->ht_prev = NULL; ds_entry_ptr->ht_prev = NULL;
ds_entry_ptr->il_next = NULL; ds_entry_ptr->il_next = NULL;
ds_entry_ptr->il_prev = NULL; ds_entry_ptr->il_prev = NULL;
/* Initialize fields supporting replacement policies: */ /* Initialize fields supporting replacement policies: */
ds_entry_ptr->next = NULL; ds_entry_ptr->next = NULL;
ds_entry_ptr->prev = NULL; ds_entry_ptr->prev = NULL;
#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS #if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS
ds_entry_ptr->aux_next = NULL; ds_entry_ptr->aux_next = NULL;
ds_entry_ptr->aux_prev = NULL; ds_entry_ptr->aux_prev = NULL;
#endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */ #endif /* H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS */
#ifdef H5_HAVE_PARALLEL #ifdef H5_HAVE_PARALLEL
pf_entry_ptr->coll_next = NULL; pf_entry_ptr->coll_next = NULL;
pf_entry_ptr->coll_prev = NULL; pf_entry_ptr->coll_prev = NULL;
#endif /* H5_HAVE_PARALLEL */ #endif /* H5_HAVE_PARALLEL */
/* Initialize cache image related fields */ /* Initialize cache image related fields */
ds_entry_ptr->include_in_image = FALSE; ds_entry_ptr->include_in_image = FALSE;
ds_entry_ptr->lru_rank = 0; ds_entry_ptr->lru_rank = 0;
ds_entry_ptr->image_dirty = FALSE; ds_entry_ptr->image_dirty = FALSE;
ds_entry_ptr->fd_parent_count = 0; ds_entry_ptr->fd_parent_count = 0;
ds_entry_ptr->fd_parent_addrs = NULL; ds_entry_ptr->fd_parent_addrs = NULL;
ds_entry_ptr->fd_child_count = pf_entry_ptr->fd_child_count; ds_entry_ptr->fd_child_count = pf_entry_ptr->fd_child_count;
ds_entry_ptr->fd_dirty_child_count = 0; ds_entry_ptr->fd_dirty_child_count = 0;
ds_entry_ptr->image_fd_height = 0; ds_entry_ptr->image_fd_height = 0;
ds_entry_ptr->prefetched = FALSE; ds_entry_ptr->prefetched = FALSE;
ds_entry_ptr->prefetch_type_id = 0; ds_entry_ptr->prefetch_type_id = 0;
ds_entry_ptr->age = 0; ds_entry_ptr->age = 0;
ds_entry_ptr->prefetched_dirty = pf_entry_ptr->prefetched_dirty; ds_entry_ptr->prefetched_dirty = pf_entry_ptr->prefetched_dirty;
#ifndef NDEBUG /* debugging field */ #ifndef NDEBUG /* debugging field */
ds_entry_ptr->serialization_count = 0; ds_entry_ptr->serialization_count = 0;
#endif /* NDEBUG */ #endif /* NDEBUG */
H5C__RESET_CACHE_ENTRY_STATS(ds_entry_ptr); H5C__RESET_CACHE_ENTRY_STATS(ds_entry_ptr);
@ -694,15 +698,20 @@ H5C__deserialize_prefetched_entry(H5F_t *f, H5C_t *cache_ptr,
* *
* 1) Set pf_entry_ptr->image_ptr to NULL. Since we have already * 1) Set pf_entry_ptr->image_ptr to NULL. Since we have already
* transferred the buffer containing the image to *ds_entry_ptr, * transferred the buffer containing the image to *ds_entry_ptr,
* this is not a memory leak. * this is not a memory leak.
* *
* 2) Call H5C__flush_single_entry() with the H5C__FLUSH_INVALIDATE_FLAG * 2) Call H5C__flush_single_entry() with the H5C__FLUSH_INVALIDATE_FLAG
* and H5C__FLUSH_CLEAR_ONLY_FLAG flags set. * and H5C__FLUSH_CLEAR_ONLY_FLAG flags set.
*/ */
pf_entry_ptr->image_ptr = NULL; pf_entry_ptr->image_ptr = NULL;
if(pf_entry_ptr->is_dirty) {
HDassert(pf_entry_ptr->in_slist); if ( pf_entry_ptr->is_dirty ) {
HDassert(((cache_ptr->slist_enabled) && (pf_entry_ptr->in_slist)) || \
((!cache_ptr->slist_enabled) && (!pf_entry_ptr->in_slist)));
flush_flags |= H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG; flush_flags |= H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG;
} /* end if */ } /* end if */
if(H5C__flush_single_entry(f, pf_entry_ptr, flush_flags) < 0) if(H5C__flush_single_entry(f, pf_entry_ptr, flush_flags) < 0)

View File

@ -18,7 +18,7 @@
* Quincey Koziol * Quincey Koziol
* *
* Purpose: Functions in this file implement support for parallel I/O for * Purpose: Functions in this file implement support for parallel I/O for
* generic cache code. * generic cache code.
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -28,7 +28,7 @@
/****************/ /****************/
#include "H5Cmodule.h" /* This source code file is part of the H5C module */ #include "H5Cmodule.h" /* This source code file is part of the H5C module */
#define H5F_FRIEND /*suppress error about including H5Fpkg */ #define H5F_FRIEND /*suppress error about including H5Fpkg */
/***********/ /***********/
@ -114,9 +114,9 @@ static herr_t H5C__flush_candidates_in_ring(H5F_t *f, H5C_ring_t ring,
* *
* We construct the table as follows. Let: * We construct the table as follows. Let:
* *
* n = num_candidates / mpi_size; * n = num_candidates / mpi_size;
* *
* m = num_candidates % mpi_size; * m = num_candidates % mpi_size;
* *
* Now allocate an array of integers of length mpi_size + 1, * Now allocate an array of integers of length mpi_size + 1,
* and call this array candidate_assignment_table. * and call this array candidate_assignment_table.
@ -136,10 +136,10 @@ static herr_t H5C__flush_candidates_in_ring(H5F_t *f, H5C_ring_t ring,
* Once the table is constructed, we determine the first and * Once the table is constructed, we determine the first and
* last entry this process is to flush as follows: * last entry this process is to flush as follows:
* *
* first_entry_to_flush = candidate_assignment_table[mpi_rank] * first_entry_to_flush = candidate_assignment_table[mpi_rank]
* *
* last_entry_to_flush = * last_entry_to_flush =
* candidate_assignment_table[mpi_rank + 1] - 1; * candidate_assignment_table[mpi_rank + 1] - 1;
* *
* With these values determined, we simply scan through the * With these values determined, we simply scan through the
* candidate list, marking all entries in the range * candidate list, marking all entries in the range
@ -163,6 +163,10 @@ static herr_t H5C__flush_candidates_in_ring(H5F_t *f, H5C_ring_t ring,
* Programmer: John Mainzer * Programmer: John Mainzer
* 3/17/10 * 3/17/10
* *
* Changes: Updated sanity checks to allow for the possibility that
* the slist is disabled.
* JRM -- 8/3/20
*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
herr_t herr_t
@ -185,12 +189,15 @@ H5C_apply_candidate_list(H5F_t * f,
unsigned entries_to_clear[H5C_RING_NTYPES]; unsigned entries_to_clear[H5C_RING_NTYPES];
haddr_t addr; haddr_t addr;
H5C_cache_entry_t * entry_ptr = NULL; H5C_cache_entry_t * entry_ptr = NULL;
#if H5C_DO_SANITY_CHECKS #if H5C_DO_SANITY_CHECKS
haddr_t last_addr; haddr_t last_addr;
#endif /* H5C_DO_SANITY_CHECKS */ #endif /* H5C_DO_SANITY_CHECKS */
#if H5C_APPLY_CANDIDATE_LIST__DEBUG #if H5C_APPLY_CANDIDATE_LIST__DEBUG
char tbl_buf[1024]; char tbl_buf[1024];
#endif /* H5C_APPLY_CANDIDATE_LIST__DEBUG */ #endif /* H5C_APPLY_CANDIDATE_LIST__DEBUG */
unsigned u; /* Local index variable */ unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */ herr_t ret_value = SUCCEED; /* Return value */
@ -200,7 +207,8 @@ H5C_apply_candidate_list(H5F_t * f,
HDassert(cache_ptr != NULL); HDassert(cache_ptr != NULL);
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
HDassert(num_candidates > 0); HDassert(num_candidates > 0);
HDassert(num_candidates <= cache_ptr->slist_len); HDassert( ( ! cache_ptr->slist_enabled ) ||
( num_candidates <= cache_ptr->slist_len ));
HDassert(candidates_list_ptr != NULL); HDassert(candidates_list_ptr != NULL);
HDassert(0 <= mpi_rank); HDassert(0 <= mpi_rank);
HDassert(mpi_rank < mpi_size); HDassert(mpi_rank < mpi_size);
@ -410,6 +418,7 @@ done:
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
*
* Function: H5C_construct_candidate_list__clean_cache * Function: H5C_construct_candidate_list__clean_cache
* *
* Purpose: Construct the list of entries that should be flushed to * Purpose: Construct the list of entries that should be flushed to
@ -425,6 +434,16 @@ done:
* Programmer: John Mainzer * Programmer: John Mainzer
* 3/17/10 * 3/17/10
* *
* Changes: With the slist optimization, the slist is not maintained
* unless a flush is in progress. Thus we can not longer use
* cache_ptr->slist_size to determine the total size of
* the entries we must insert in the candidate list.
*
* To address this, we now use cache_ptr->dirty_index_size
* instead.
*
* JRM -- 7/27/20
*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
herr_t herr_t
@ -438,60 +457,82 @@ H5C_construct_candidate_list__clean_cache(H5C_t * cache_ptr)
HDassert( cache_ptr != NULL ); HDassert( cache_ptr != NULL );
HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC ); HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
/* As a sanity check, set space needed to the size of the skip list. /* As a sanity check, set space needed to the dirty_index_size. This
* This should be the sum total of the sizes of all the dirty entries * should be the sum total of the sizes of all the dirty entries
* in the metadata cache. * in the metadata cache. Note that if the slist is enabled,
* cache_ptr->slist_size should equal cache_ptr->dirty_index_size.
*/ */
space_needed = cache_ptr->slist_size; space_needed = cache_ptr->dirty_index_size;
HDassert( ( ! cache_ptr->slist_enabled ) ||
( space_needed == cache_ptr->slist_size ) );
/* Recall that while we shouldn't have any protected entries at this /* Recall that while we shouldn't have any protected entries at this
* point, it is possible that some dirty entries may reside on the * point, it is possible that some dirty entries may reside on the
* pinned list at this point. * pinned list at this point.
*/ */
HDassert( cache_ptr->slist_size <= HDassert( cache_ptr->dirty_index_size <=
(cache_ptr->dLRU_list_size + cache_ptr->pel_size) ); (cache_ptr->dLRU_list_size + cache_ptr->pel_size) );
HDassert( cache_ptr->slist_len <= HDassert( ( ! cache_ptr->slist_enabled ) ||
(cache_ptr->dLRU_list_len + cache_ptr->pel_len) ); ( cache_ptr->slist_len <=
(cache_ptr->dLRU_list_len + cache_ptr->pel_len) ) );
if(space_needed > 0) { /* we have work to do */ if(space_needed > 0) { /* we have work to do */
H5C_cache_entry_t *entry_ptr; H5C_cache_entry_t *entry_ptr;
unsigned nominated_entries_count = 0; unsigned nominated_entries_count = 0;
size_t nominated_entries_size = 0; size_t nominated_entries_size = 0;
haddr_t nominated_addr; haddr_t nominated_addr;
HDassert( cache_ptr->slist_len > 0 ); HDassert( ( ! cache_ptr->slist_enabled ) ||
( cache_ptr->slist_len > 0 ) );
/* Scan the dirty LRU list from tail forward and nominate sufficient /* Scan the dirty LRU list from tail forward and nominate sufficient
* entries to free up the necessary space. * entries to free up the necessary space.
*/ */
entry_ptr = cache_ptr->dLRU_tail_ptr; entry_ptr = cache_ptr->dLRU_tail_ptr;
while((nominated_entries_size < space_needed) &&
(nominated_entries_count < cache_ptr->slist_len) && while ( ( nominated_entries_size < space_needed ) &&
(entry_ptr != NULL)) { ( ( ! cache_ptr->slist_enabled ) ||
( nominated_entries_count < cache_ptr->slist_len ) ) &&
( entry_ptr != NULL ) ) {
HDassert( ! (entry_ptr->is_protected) ); HDassert( ! (entry_ptr->is_protected) );
HDassert( ! (entry_ptr->is_read_only) ); HDassert( ! (entry_ptr->is_read_only) );
HDassert( entry_ptr->ro_ref_count == 0 ); HDassert( entry_ptr->ro_ref_count == 0 );
HDassert( entry_ptr->is_dirty ); HDassert( entry_ptr->is_dirty );
HDassert( entry_ptr->in_slist ); HDassert( ( ! cache_ptr->slist_enabled ) ||
( entry_ptr->in_slist ) );
nominated_addr = entry_ptr->addr; nominated_addr = entry_ptr->addr;
if(H5AC_add_candidate((H5AC_t *)cache_ptr, nominated_addr) < 0) if(H5AC_add_candidate((H5AC_t *)cache_ptr, nominated_addr) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_add_candidate() failed")
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"H5AC_add_candidate() failed")
nominated_entries_size += entry_ptr->size; nominated_entries_size += entry_ptr->size;
nominated_entries_count++; nominated_entries_count++;
entry_ptr = entry_ptr->aux_prev; entry_ptr = entry_ptr->aux_prev;
} /* end while */ } /* end while */
HDassert( entry_ptr == NULL ); HDassert( entry_ptr == NULL );
/* it is possible that there are some dirty entries on the /* it is possible that there are some dirty entries on the
* protected entry list as well -- scan it too if necessary * protected entry list as well -- scan it too if necessary
*/ */
entry_ptr = cache_ptr->pel_head_ptr; entry_ptr = cache_ptr->pel_head_ptr;
while((nominated_entries_size < space_needed) &&
(nominated_entries_count < cache_ptr->slist_len) && while ( ( nominated_entries_size < space_needed ) &&
(entry_ptr != NULL)) { ( ( ! cache_ptr->slist_enabled ) ||
( nominated_entries_count < cache_ptr->slist_len ) ) &&
( entry_ptr != NULL ) ) {
if(entry_ptr->is_dirty) { if(entry_ptr->is_dirty) {
HDassert( ! (entry_ptr->is_protected) ); HDassert( ! (entry_ptr->is_protected) );
HDassert( ! (entry_ptr->is_read_only) ); HDassert( ! (entry_ptr->is_read_only) );
HDassert( entry_ptr->ro_ref_count == 0 ); HDassert( entry_ptr->ro_ref_count == 0 );
@ -499,22 +540,31 @@ H5C_construct_candidate_list__clean_cache(H5C_t * cache_ptr)
HDassert( entry_ptr->in_slist ); HDassert( entry_ptr->in_slist );
nominated_addr = entry_ptr->addr; nominated_addr = entry_ptr->addr;
if(H5AC_add_candidate((H5AC_t *)cache_ptr, nominated_addr) < 0) if(H5AC_add_candidate((H5AC_t *)cache_ptr, nominated_addr) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_add_candidate() failed")
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"H5AC_add_candidate() failed")
nominated_entries_size += entry_ptr->size; nominated_entries_size += entry_ptr->size;
nominated_entries_count++; nominated_entries_count++;
} /* end if */ } /* end if */
entry_ptr = entry_ptr->next; entry_ptr = entry_ptr->next;
} /* end while */ } /* end while */
HDassert( nominated_entries_count == cache_ptr->slist_len ); HDassert( ( ! cache_ptr->slist_enabled ) ||
( nominated_entries_count == cache_ptr->slist_len ) );
HDassert( nominated_entries_size == space_needed ); HDassert( nominated_entries_size == space_needed );
} /* end if */ } /* end if */
done: done:
FUNC_LEAVE_NOAPI(ret_value) FUNC_LEAVE_NOAPI(ret_value)
} /* H5C_construct_candidate_list__clean_cache() */ } /* H5C_construct_candidate_list__clean_cache() */
@ -534,6 +584,12 @@ done:
* Programmer: John Mainzer * Programmer: John Mainzer
* 3/17/10 * 3/17/10
* *
* Changes: With the slist optimization, the slist is not maintained
* unless a flush is in progress. Updated sanity checks to
* reflect this.
*
* JRM -- 7/27/20
*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
herr_t herr_t
@ -551,54 +607,77 @@ H5C_construct_candidate_list__min_clean(H5C_t * cache_ptr)
* cache back within its min clean constraints. * cache back within its min clean constraints.
*/ */
if(cache_ptr->max_cache_size > cache_ptr->index_size) { if(cache_ptr->max_cache_size > cache_ptr->index_size) {
if(((cache_ptr->max_cache_size - cache_ptr->index_size) +
cache_ptr->cLRU_list_size) >= cache_ptr->min_clean_size) if ( ( (cache_ptr->max_cache_size - cache_ptr->index_size) +
cache_ptr->cLRU_list_size) >= cache_ptr->min_clean_size ) {
space_needed = 0; space_needed = 0;
else
} else {
space_needed = cache_ptr->min_clean_size - space_needed = cache_ptr->min_clean_size -
((cache_ptr->max_cache_size - cache_ptr->index_size) + ((cache_ptr->max_cache_size - cache_ptr->index_size) +
cache_ptr->cLRU_list_size); cache_ptr->cLRU_list_size);
}
} /* end if */ } /* end if */
else { else {
if(cache_ptr->min_clean_size <= cache_ptr->cLRU_list_size)
if(cache_ptr->min_clean_size <= cache_ptr->cLRU_list_size) {
space_needed = 0; space_needed = 0;
else
} else {
space_needed = cache_ptr->min_clean_size - space_needed = cache_ptr->min_clean_size -
cache_ptr->cLRU_list_size; cache_ptr->cLRU_list_size;
}
} /* end else */ } /* end else */
if(space_needed > 0) { /* we have work to do */ if(space_needed > 0) { /* we have work to do */
H5C_cache_entry_t *entry_ptr; H5C_cache_entry_t *entry_ptr;
unsigned nominated_entries_count = 0; unsigned nominated_entries_count = 0;
size_t nominated_entries_size = 0; size_t nominated_entries_size = 0;
HDassert( cache_ptr->slist_len > 0 ); HDassert( ( ! cache_ptr->slist_enabled ) ||
( cache_ptr->slist_len > 0 ) );
/* Scan the dirty LRU list from tail forward and nominate sufficient /* Scan the dirty LRU list from tail forward and nominate sufficient
* entries to free up the necessary space. * entries to free up the necessary space.
*/ */
entry_ptr = cache_ptr->dLRU_tail_ptr; entry_ptr = cache_ptr->dLRU_tail_ptr;
while((nominated_entries_size < space_needed) &&
(nominated_entries_count < cache_ptr->slist_len) && while ( ( nominated_entries_size < space_needed ) &&
(entry_ptr != NULL) && ( ( ! cache_ptr->slist_enabled ) ||
(!entry_ptr->flush_me_last)) { ( nominated_entries_count < cache_ptr->slist_len ) ) &&
haddr_t nominated_addr; ( entry_ptr != NULL ) &&
( ! entry_ptr->flush_me_last ) ) {
haddr_t nominated_addr;
HDassert( ! (entry_ptr->is_protected) ); HDassert( ! (entry_ptr->is_protected) );
HDassert( ! (entry_ptr->is_read_only) ); HDassert( ! (entry_ptr->is_read_only) );
HDassert( entry_ptr->ro_ref_count == 0 ); HDassert( entry_ptr->ro_ref_count == 0 );
HDassert( entry_ptr->is_dirty ); HDassert( entry_ptr->is_dirty );
HDassert( entry_ptr->in_slist ); HDassert( ( ! cache_ptr->slist_enabled ) ||
( entry_ptr->in_slist ) );
nominated_addr = entry_ptr->addr; nominated_addr = entry_ptr->addr;
if(H5AC_add_candidate((H5AC_t *)cache_ptr, nominated_addr) < 0) if(H5AC_add_candidate((H5AC_t *)cache_ptr, nominated_addr) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_add_candidate() failed")
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
"H5AC_add_candidate() failed")
nominated_entries_size += entry_ptr->size; nominated_entries_size += entry_ptr->size;
nominated_entries_count++; nominated_entries_count++;
entry_ptr = entry_ptr->aux_prev; entry_ptr = entry_ptr->aux_prev;
} /* end while */ } /* end while */
HDassert( nominated_entries_count <= cache_ptr->slist_len );
HDassert( ( ! cache_ptr->slist_enabled ) ||
( nominated_entries_count <= cache_ptr->slist_len ) );
HDassert( nominated_entries_size <= cache_ptr->dirty_index_size );
HDassert( nominated_entries_size >= space_needed ); HDassert( nominated_entries_size >= space_needed );
} /* end if */ } /* end if */
@ -769,7 +848,7 @@ H5C_mark_entries_as_clean(H5F_t * f,
* of the pre_serialize / serialize routines, this may * of the pre_serialize / serialize routines, this may
* cease to be the case -- requiring a review of this * cease to be the case -- requiring a review of this
* point. * point.
* JRM -- 4/7/15 * JRM -- 4/7/15
*/ */
entries_cleared = 0; entries_cleared = 0;
entries_examined = 0; entries_examined = 0;
@ -873,9 +952,9 @@ done:
herr_t herr_t
H5C_clear_coll_entries(H5C_t *cache_ptr, hbool_t partial) H5C_clear_coll_entries(H5C_t *cache_ptr, hbool_t partial)
{ {
uint32_t clear_cnt; uint32_t clear_cnt;
H5C_cache_entry_t * entry_ptr = NULL; H5C_cache_entry_t * entry_ptr = NULL;
herr_t ret_value = SUCCEED; herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT FUNC_ENTER_NOAPI_NOINIT
@ -1124,17 +1203,17 @@ H5C__flush_candidate_entries(H5F_t *f, unsigned entries_to_flush[H5C_RING_NTYPES
unsigned entries_to_clear[H5C_RING_NTYPES]) unsigned entries_to_clear[H5C_RING_NTYPES])
{ {
#if H5C_DO_SANITY_CHECKS #if H5C_DO_SANITY_CHECKS
int i; int i;
uint32_t index_len = 0; uint32_t index_len = 0;
size_t index_size = (size_t)0; size_t index_size = (size_t)0;
size_t clean_index_size = (size_t)0; size_t clean_index_size = (size_t)0;
size_t dirty_index_size = (size_t)0; size_t dirty_index_size = (size_t)0;
size_t slist_size = (size_t)0; size_t slist_size = (size_t)0;
uint32_t slist_len = 0; uint32_t slist_len = 0;
#endif /* H5C_DO_SANITY_CHECKS */ #endif /* H5C_DO_SANITY_CHECKS */
H5C_ring_t ring; H5C_ring_t ring;
H5C_t * cache_ptr; H5C_t * cache_ptr;
herr_t ret_value = SUCCEED; herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC FUNC_ENTER_STATIC

View File

@ -47,13 +47,22 @@
/* Number of epoch markers active */ /* Number of epoch markers active */
#define H5C__MAX_EPOCH_MARKERS 10 #define H5C__MAX_EPOCH_MARKERS 10
/* Cache configuration settings */ /* Cache configuration settings */
#define H5C__HASH_TABLE_LEN (64 * 1024) /* must be a power of 2 */ #define H5C__HASH_TABLE_LEN (64 * 1024) /* must be a power of 2 */
#define H5C__H5C_T_MAGIC 0x005CAC0E #define H5C__H5C_T_MAGIC 0x005CAC0E
/* Initial allocated size of the "flush_dep_parent" array */ /* Initial allocated size of the "flush_dep_parent" array */
#define H5C_FLUSH_DEP_PARENT_INIT 8 #define H5C_FLUSH_DEP_PARENT_INIT 8
/* Set to TRUE to enable the slist optimization. If this field is TRUE,
* the slist is disabled whenever a flush is not in progress.
*/
#define H5C__SLIST_OPT_ENABLED TRUE
/**************************************************************************** /****************************************************************************
* *
* We maintain doubly linked lists of instances of H5C_cache_entry_t for a * We maintain doubly linked lists of instances of H5C_cache_entry_t for a
@ -1568,49 +1577,82 @@ if ( ( (cache_ptr)->index_size != \
* Added code to maintain the cache_ptr->slist_ring_len * Added code to maintain the cache_ptr->slist_ring_len
* and cache_ptr->slist_ring_size arrays. * and cache_ptr->slist_ring_size arrays.
* *
* JRM -- 4/29/20
* Reworked macro to support the slist_enabled field
* of H5C_t. If slist_enabled == TRUE, the macro
* functions as before. Otherwise, the macro is a no-op,
* and the slist must be empty.
*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
/* NOTE: The H5C__INSERT_ENTRY_IN_SLIST() macro is set up so that
*
* H5C_DO_SANITY_CHECKS
*
* and
*
* H5C_DO_SLIST_SANITY_CHECKS
*
* can be selected independantly. This is easy to miss as the
* two #defines are easy to confuse.
*/
#if H5C_DO_SLIST_SANITY_CHECKS #if H5C_DO_SLIST_SANITY_CHECKS
#define ENTRY_IN_SLIST(cache_ptr, entry_ptr) \ #define ENTRY_IN_SLIST(cache_ptr, entry_ptr) \
H5C_entry_in_skip_list((cache_ptr), (entry_ptr)) H5C_entry_in_skip_list((cache_ptr), (entry_ptr))
#else /* H5C_DO_SLIST_SANITY_CHECKS */ #else /* H5C_DO_SLIST_SANITY_CHECKS */
#define ENTRY_IN_SLIST(cache_ptr, entry_ptr) FALSE #define ENTRY_IN_SLIST(cache_ptr, entry_ptr) FALSE
#endif /* H5C_DO_SLIST_SANITY_CHECKS */ #endif /* H5C_DO_SLIST_SANITY_CHECKS */
#if H5C_DO_SANITY_CHECKS #if H5C_DO_SANITY_CHECKS
#define H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr, fail_val) \ #define H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr, fail_val) \
{ \ { \
HDassert( (cache_ptr) ); \ HDassert( (cache_ptr) ); \
HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \
HDassert( (entry_ptr) ); \
HDassert( (entry_ptr)->size > 0 ); \
HDassert( H5F_addr_defined((entry_ptr)->addr) ); \
HDassert( !((entry_ptr)->in_slist) ); \
HDassert( !ENTRY_IN_SLIST((cache_ptr), (entry_ptr)) ); \
HDassert( (entry_ptr)->ring > H5C_RING_UNDEFINED ); \
HDassert( (entry_ptr)->ring < H5C_RING_NTYPES ); \
HDassert( (cache_ptr)->slist_ring_len[(entry_ptr)->ring] <= \
(cache_ptr)->slist_len ); \
HDassert( (cache_ptr)->slist_ring_size[(entry_ptr)->ring] <= \
(cache_ptr)->slist_size ); \
\ \
if(H5SL_insert((cache_ptr)->slist_ptr, entry_ptr, &(entry_ptr)->addr) < 0) \ if ( (cache_ptr)->slist_enabled ) { \
HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, (fail_val), "can't insert entry in skip list") \
\ \
(entry_ptr)->in_slist = TRUE; \ HDassert( (entry_ptr) ); \
(cache_ptr)->slist_changed = TRUE; \ HDassert( (entry_ptr)->size > 0 ); \
(cache_ptr)->slist_len++; \ HDassert( H5F_addr_defined((entry_ptr)->addr) ); \
(cache_ptr)->slist_size += (entry_ptr)->size; \ HDassert( !((entry_ptr)->in_slist) ); \
((cache_ptr)->slist_ring_len[(entry_ptr)->ring])++; \ HDassert( ! ENTRY_IN_SLIST((cache_ptr), (entry_ptr)) ); \
((cache_ptr)->slist_ring_size[(entry_ptr)->ring]) += (entry_ptr)->size; \ HDassert( (entry_ptr)->ring > H5C_RING_UNDEFINED ); \
(cache_ptr)->slist_len_increase++; \ HDassert( (entry_ptr)->ring < H5C_RING_NTYPES ); \
(cache_ptr)->slist_size_increase += (int64_t)((entry_ptr)->size); \ HDassert( (cache_ptr)->slist_ring_len[(entry_ptr)->ring] <= \
(cache_ptr)->slist_len ); \
HDassert( (cache_ptr)->slist_ring_size[(entry_ptr)->ring] <= \
(cache_ptr)->slist_size ); \
\ \
HDassert( (cache_ptr)->slist_len > 0 ); \ if ( H5SL_insert((cache_ptr)->slist_ptr, entry_ptr, \
HDassert( (cache_ptr)->slist_size > 0 ); \ &((entry_ptr)->addr)) < 0) \
HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, (fail_val), \
"can't insert entry in skip list") \
\ \
(entry_ptr)->in_slist = TRUE; \
(cache_ptr)->slist_changed = TRUE; \
(cache_ptr)->slist_len++; \
(cache_ptr)->slist_size += (entry_ptr)->size; \
((cache_ptr)->slist_ring_len[(entry_ptr)->ring])++; \
((cache_ptr)->slist_ring_size[(entry_ptr)->ring]) += (entry_ptr)->size;\
(cache_ptr)->slist_len_increase++; \
(cache_ptr)->slist_size_increase += (int64_t)((entry_ptr)->size); \
\
HDassert( (cache_ptr)->slist_len > 0 ); \
HDassert( (cache_ptr)->slist_size > 0 ); \
\
} else { /* slist disabled */ \
\
HDassert( (cache_ptr)->slist_len == 0 ); \
HDassert( (cache_ptr)->slist_size == 0 ); \
} \
} /* H5C__INSERT_ENTRY_IN_SLIST */ } /* H5C__INSERT_ENTRY_IN_SLIST */
#else /* H5C_DO_SANITY_CHECKS */ #else /* H5C_DO_SANITY_CHECKS */
@ -1619,31 +1661,42 @@ if ( ( (cache_ptr)->index_size != \
{ \ { \
HDassert( (cache_ptr) ); \ HDassert( (cache_ptr) ); \
HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \
HDassert( (entry_ptr) ); \
HDassert( (entry_ptr)->size > 0 ); \
HDassert( H5F_addr_defined((entry_ptr)->addr) ); \
HDassert( !((entry_ptr)->in_slist) ); \
HDassert( !ENTRY_IN_SLIST((cache_ptr), (entry_ptr)) ); \
HDassert( (entry_ptr)->ring > H5C_RING_UNDEFINED ); \
HDassert( (entry_ptr)->ring < H5C_RING_NTYPES ); \
HDassert( (cache_ptr)->slist_ring_len[(entry_ptr)->ring] <= \
(cache_ptr)->slist_len ); \
HDassert( (cache_ptr)->slist_ring_size[(entry_ptr)->ring] <= \
(cache_ptr)->slist_size ); \
\ \
if(H5SL_insert((cache_ptr)->slist_ptr, entry_ptr, &(entry_ptr)->addr) < 0) \ if ( (cache_ptr)->slist_enabled ) { \
HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, (fail_val), "can't insert entry in skip list") \
\ \
(entry_ptr)->in_slist = TRUE; \ HDassert( (entry_ptr) ); \
(cache_ptr)->slist_changed = TRUE; \ HDassert( (entry_ptr)->size > 0 ); \
(cache_ptr)->slist_len++; \ HDassert( ! ENTRY_IN_SLIST((cache_ptr), (entry_ptr)) ); \
(cache_ptr)->slist_size += (entry_ptr)->size; \ HDassert( H5F_addr_defined((entry_ptr)->addr) ); \
((cache_ptr)->slist_ring_len[(entry_ptr)->ring])++; \ HDassert( !((entry_ptr)->in_slist) ); \
((cache_ptr)->slist_ring_size[(entry_ptr)->ring]) += (entry_ptr)->size; \ HDassert( (entry_ptr)->ring > H5C_RING_UNDEFINED ); \
HDassert( (entry_ptr)->ring < H5C_RING_NTYPES ); \
HDassert( (cache_ptr)->slist_ring_len[(entry_ptr)->ring] <= \
(cache_ptr)->slist_len ); \
HDassert( (cache_ptr)->slist_ring_size[(entry_ptr)->ring] <= \
(cache_ptr)->slist_size ); \
HDassert( (cache_ptr)->slist_ptr ); \
\ \
HDassert( (cache_ptr)->slist_len > 0 ); \ if ( H5SL_insert((cache_ptr)->slist_ptr, entry_ptr, \
HDassert( (cache_ptr)->slist_size > 0 ); \ &((entry_ptr)->addr)) < 0) \
HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, (fail_val), \
"can't insert entry in skip list") \
\ \
(entry_ptr)->in_slist = TRUE; \
(cache_ptr)->slist_changed = TRUE; \
(cache_ptr)->slist_len++; \
(cache_ptr)->slist_size += (entry_ptr)->size; \
((cache_ptr)->slist_ring_len[(entry_ptr)->ring])++; \
((cache_ptr)->slist_ring_size[(entry_ptr)->ring]) += (entry_ptr)->size;\
\
HDassert( (cache_ptr)->slist_len > 0 ); \
HDassert( (cache_ptr)->slist_size > 0 ); \
\
} else { /* slist disabled */ \
\
HDassert( (cache_ptr)->slist_len == 0 ); \
HDassert( (cache_ptr)->slist_size == 0 ); \
} \
} /* H5C__INSERT_ENTRY_IN_SLIST */ } /* H5C__INSERT_ENTRY_IN_SLIST */
#endif /* H5C_DO_SANITY_CHECKS */ #endif /* H5C_DO_SANITY_CHECKS */
@ -1654,87 +1707,136 @@ if ( ( (cache_ptr)->index_size != \
* Function: H5C__REMOVE_ENTRY_FROM_SLIST * Function: H5C__REMOVE_ENTRY_FROM_SLIST
* *
* Purpose: Remove the specified instance of H5C_cache_entry_t from the * Purpose: Remove the specified instance of H5C_cache_entry_t from the
* index skip list in the specified instance of H5C_t. Update * index skip list in the specified instance of H5C_t. Update
* the associated length and size fields. * the associated length and size fields.
* *
* Return: N/A * Return: N/A
* *
* Programmer: John Mainzer, 5/10/04 * Programmer: John Mainzer, 5/10/04
* *
* Modifications:
*
* JRM -- 7/21/04
* Updated function for the addition of the hash table.
*
* JRM - 7/27/04
* Converted from the function H5C_remove_entry_from_tree()
* to the macro H5C__REMOVE_ENTRY_FROM_TREE in the hopes of
* wringing a little more performance out of the cache.
*
* QAK -- 11/27/04
* Switched over to using skip list routines.
*
* JRM -- 3/28/07
* Updated sanity checks for the new is_read_only and
* ro_ref_count fields in H5C_cache_entry_t.
*
* JRM -- 12/13/14
* Added code to set cache_ptr->slist_changed to TRUE
* when an entry is removed from the slist.
*
* JRM -- 4/29/20
* Reworked macro to support the slist_enabled field
* of H5C_t. If slist_enabled == TRUE, the macro
* functions as before. Otherwise, the macro is a no-op,
* and the slist must be empty.
*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#if H5C_DO_SANITY_CHECKS #if H5C_DO_SANITY_CHECKS
#define H5C__REMOVE_ENTRY_FROM_SLIST(cache_ptr, entry_ptr, during_flush) \ #define H5C__REMOVE_ENTRY_FROM_SLIST(cache_ptr, entry_ptr, during_flush) \
{ \ { \
HDassert( (cache_ptr) ); \ HDassert( (cache_ptr) ); \
HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \
HDassert( (entry_ptr) ); \ \
HDassert( !((entry_ptr)->is_read_only) ); \ if ( (cache_ptr)->slist_enabled ) { \
HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ \
HDassert( (entry_ptr)->size > 0 ); \ HDassert( (entry_ptr) ); \
HDassert( (entry_ptr)->in_slist ); \ HDassert( !((entry_ptr)->is_read_only) ); \
HDassert( (cache_ptr)->slist_ptr ); \ HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \
HDassert( (entry_ptr)->ring > H5C_RING_UNDEFINED ); \ HDassert( (entry_ptr)->size > 0 ); \
HDassert( (entry_ptr)->ring < H5C_RING_NTYPES ); \ HDassert( (entry_ptr)->in_slist ); \
HDassert( (cache_ptr)->slist_ring_len[(entry_ptr)->ring] <= \ HDassert( (cache_ptr)->slist_ptr ); \
(cache_ptr)->slist_len ); \ HDassert( (entry_ptr)->ring > H5C_RING_UNDEFINED ); \
HDassert( (cache_ptr)->slist_ring_size[(entry_ptr)->ring] <= \ HDassert( (entry_ptr)->ring < H5C_RING_NTYPES ); \
(cache_ptr)->slist_size ); \ HDassert( (cache_ptr)->slist_ring_len[(entry_ptr)->ring] <= \
\ (cache_ptr)->slist_len ); \
if ( H5SL_remove((cache_ptr)->slist_ptr, &(entry_ptr)->addr) \ HDassert( (cache_ptr)->slist_ring_size[(entry_ptr)->ring] <= \
!= (entry_ptr) ) \ (cache_ptr)->slist_size ); \
HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "can't delete entry from skip list") \ HDassert( (cache_ptr)->slist_size >= (entry_ptr)->size ); \
\ \
HDassert( (cache_ptr)->slist_len > 0 ); \ if ( H5SL_remove((cache_ptr)->slist_ptr, &(entry_ptr)->addr) \
if(!(during_flush)) \ != (entry_ptr) ) \
(cache_ptr)->slist_changed = TRUE; \ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, \
(cache_ptr)->slist_len--; \ "can't delete entry from skip list") \
HDassert( (cache_ptr)->slist_size >= (entry_ptr)->size ); \ \
(cache_ptr)->slist_size -= (entry_ptr)->size; \ HDassert( (cache_ptr)->slist_len > 0 ); \
((cache_ptr)->slist_ring_len[(entry_ptr)->ring])--; \ if(!(during_flush)) \
HDassert( (cache_ptr)->slist_ring_size[(entry_ptr->ring)] >= \ (cache_ptr)->slist_changed = TRUE; \
(entry_ptr)->size ); \ (cache_ptr)->slist_len--; \
((cache_ptr)->slist_ring_size[(entry_ptr)->ring]) -= (entry_ptr)->size; \ HDassert( (cache_ptr)->slist_size >= (entry_ptr)->size ); \
(cache_ptr)->slist_len_increase--; \ (cache_ptr)->slist_size -= (entry_ptr)->size; \
(cache_ptr)->slist_size_increase -= (int64_t)((entry_ptr)->size); \ ((cache_ptr)->slist_ring_len[(entry_ptr)->ring])--; \
(entry_ptr)->in_slist = FALSE; \ HDassert( (cache_ptr)->slist_ring_size[(entry_ptr->ring)] >= \
(entry_ptr)->size ); \
((cache_ptr)->slist_ring_size[(entry_ptr)->ring]) -= (entry_ptr)->size;\
(cache_ptr)->slist_len_increase--; \
(cache_ptr)->slist_size_increase -= (int64_t)((entry_ptr)->size); \
(entry_ptr)->in_slist = FALSE; \
\
} else { /* slist disabled */ \
\
HDassert( (cache_ptr)->slist_len == 0 ); \
HDassert( (cache_ptr)->slist_size == 0 ); \
} \
} /* H5C__REMOVE_ENTRY_FROM_SLIST */ } /* H5C__REMOVE_ENTRY_FROM_SLIST */
#else /* H5C_DO_SANITY_CHECKS */ #else /* H5C_DO_SANITY_CHECKS */
#define H5C__REMOVE_ENTRY_FROM_SLIST(cache_ptr, entry_ptr, during_flush) \ #define H5C__REMOVE_ENTRY_FROM_SLIST(cache_ptr, entry_ptr, during_flush) \
{ \ { \
HDassert( (cache_ptr) ); \ HDassert( (cache_ptr) ); \
HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \
HDassert( (entry_ptr) ); \ \
HDassert( !((entry_ptr)->is_read_only) ); \ if ( (cache_ptr)->slist_enabled ) { \
HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \ \
HDassert( (entry_ptr)->in_slist ); \ HDassert( (entry_ptr) ); \
HDassert( (cache_ptr)->slist_ptr ); \ HDassert( !((entry_ptr)->is_read_only) ); \
HDassert( (entry_ptr)->ring > H5C_RING_UNDEFINED ); \ HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \
HDassert( (entry_ptr)->ring < H5C_RING_NTYPES ); \ HDassert( (entry_ptr)->in_slist ); \
HDassert( (cache_ptr)->slist_ring_len[(entry_ptr)->ring] <= \ HDassert( (cache_ptr)->slist_ptr ); \
(cache_ptr)->slist_len ); \ HDassert( (entry_ptr)->ring > H5C_RING_UNDEFINED ); \
HDassert( (cache_ptr)->slist_ring_size[(entry_ptr)->ring] <= \ HDassert( (entry_ptr)->ring < H5C_RING_NTYPES ); \
(cache_ptr)->slist_size ); \ HDassert( (cache_ptr)->slist_ring_len[(entry_ptr)->ring] <= \
\ (cache_ptr)->slist_len ); \
if ( H5SL_remove((cache_ptr)->slist_ptr, &(entry_ptr)->addr) \ HDassert( (cache_ptr)->slist_ring_size[(entry_ptr)->ring] <= \
!= (entry_ptr) ) \ (cache_ptr)->slist_size ); \
HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "can't delete entry from skip list") \ \
\ if ( H5SL_remove((cache_ptr)->slist_ptr, &(entry_ptr)->addr) \
HDassert( (cache_ptr)->slist_len > 0 ); \ != (entry_ptr) ) \
if(!(during_flush)) \ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, \
(cache_ptr)->slist_changed = TRUE; \ "can't delete entry from skip list") \
(cache_ptr)->slist_len--; \ \
HDassert( (cache_ptr)->slist_size >= (entry_ptr)->size ); \ HDassert( (cache_ptr)->slist_len > 0 ); \
(cache_ptr)->slist_size -= (entry_ptr)->size; \ if(!(during_flush)) \
((cache_ptr)->slist_ring_len[(entry_ptr)->ring])--; \ (cache_ptr)->slist_changed = TRUE; \
HDassert( (cache_ptr)->slist_ring_size[(entry_ptr->ring)] >= \ (cache_ptr)->slist_len--; \
(entry_ptr)->size ); \ HDassert( (cache_ptr)->slist_size >= (entry_ptr)->size ); \
((cache_ptr)->slist_ring_size[(entry_ptr)->ring]) -= (entry_ptr)->size; \ (cache_ptr)->slist_size -= (entry_ptr)->size; \
(entry_ptr)->in_slist = FALSE; \ ((cache_ptr)->slist_ring_len[(entry_ptr)->ring])--; \
HDassert( (cache_ptr)->slist_ring_size[(entry_ptr->ring)] >= \
(entry_ptr)->size ); \
((cache_ptr)->slist_ring_size[(entry_ptr)->ring]) -= (entry_ptr)->size;\
(entry_ptr)->in_slist = FALSE; \
\
} else { /* slist disabled */ \
\
HDassert( (cache_ptr)->slist_len == 0 ); \
HDassert( (cache_ptr)->slist_size == 0 ); \
} \
} /* H5C__REMOVE_ENTRY_FROM_SLIST */ } /* H5C__REMOVE_ENTRY_FROM_SLIST */
#endif /* H5C_DO_SANITY_CHECKS */ #endif /* H5C_DO_SANITY_CHECKS */
@ -1743,7 +1845,7 @@ if ( ( (cache_ptr)->index_size != \
* Function: H5C__UPDATE_SLIST_FOR_SIZE_CHANGE * Function: H5C__UPDATE_SLIST_FOR_SIZE_CHANGE
* *
* Purpose: Update cache_ptr->slist_size for a change in the size of * Purpose: Update cache_ptr->slist_size for a change in the size of
* and entry in the slist. * and entry in the slist.
* *
* Return: N/A * Return: N/A
* *
@ -1751,24 +1853,30 @@ if ( ( (cache_ptr)->index_size != \
* *
* Modifications: * Modifications:
* *
* JRM -- 8/27/06 * JRM -- 8/27/06
* Added the H5C_DO_SANITY_CHECKS version of the macro. * Added the H5C_DO_SANITY_CHECKS version of the macro.
* *
* This version maintains the slist_size_increase field * This version maintains the slist_size_increase field
* that are used in sanity checks in the flush routines. * that are used in sanity checks in the flush routines.
* *
* All this is needed as the fractal heap needs to be * All this is needed as the fractal heap needs to be
* able to dirty, resize and/or move entries during the * able to dirty, resize and/or move entries during the
* flush. * flush.
* *
* JRM -- 12/13/14 * JRM -- 12/13/14
* Note that we do not set cache_ptr->slist_changed to TRUE * Note that we do not set cache_ptr->slist_changed to TRUE
* in this case, as the structure of the slist is not * in this case, as the structure of the slist is not
* modified. * modified.
* *
* JRM -- 9/1/15 * JRM -- 9/1/15
* Added code to maintain the cache_ptr->slist_ring_len * Added code to maintain the cache_ptr->slist_ring_len
* and cache_ptr->slist_ring_size arrays. * and cache_ptr->slist_ring_size arrays.
*
* JRM -- 4/29/20
* Reworked macro to support the slist_enabled field
* of H5C_t. If slist_enabled == TRUE, the macro
* functions as before. Otherwise, the macro is a no-op,
* and the slist must be empty.
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1779,32 +1887,43 @@ if ( ( (cache_ptr)->index_size != \
{ \ { \
HDassert( (cache_ptr) ); \ HDassert( (cache_ptr) ); \
HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \
HDassert( (old_size) > 0 ); \
HDassert( (new_size) > 0 ); \
HDassert( (old_size) <= (cache_ptr)->slist_size ); \
HDassert( (cache_ptr)->slist_len > 0 ); \
HDassert( ((cache_ptr)->slist_len > 1) || \
( (cache_ptr)->slist_size == (old_size) ) ); \
HDassert( (entry_ptr)->ring > H5C_RING_UNDEFINED ); \
HDassert( (entry_ptr)->ring < H5C_RING_NTYPES ); \
HDassert( (cache_ptr)->slist_ring_len[(entry_ptr)->ring] <= \
(cache_ptr)->slist_len ); \
HDassert( (cache_ptr)->slist_ring_size[(entry_ptr)->ring] <= \
(cache_ptr)->slist_size ); \
\ \
(cache_ptr)->slist_size -= (old_size); \ if ( (cache_ptr)->slist_enabled ) { \
(cache_ptr)->slist_size += (new_size); \
\ \
HDassert( (cache_ptr)->slist_ring_size[(entry_ptr->ring)] >=(old_size) ); \ HDassert( (old_size) > 0 ); \
((cache_ptr)->slist_ring_size[(entry_ptr)->ring]) -= (old_size); \ HDassert( (new_size) > 0 ); \
((cache_ptr)->slist_ring_size[(entry_ptr)->ring]) += (new_size); \ HDassert( (old_size) <= (cache_ptr)->slist_size ); \
HDassert( (cache_ptr)->slist_len > 0 ); \
HDassert( ((cache_ptr)->slist_len > 1) || \
( (cache_ptr)->slist_size == (old_size) ) ); \
HDassert( (entry_ptr)->ring > H5C_RING_UNDEFINED ); \
HDassert( (entry_ptr)->ring < H5C_RING_NTYPES ); \
HDassert( (cache_ptr)->slist_ring_len[(entry_ptr)->ring] <= \
(cache_ptr)->slist_len ); \
HDassert( (cache_ptr)->slist_ring_size[(entry_ptr)->ring] <= \
(cache_ptr)->slist_size ); \
\ \
(cache_ptr)->slist_size_increase -= (int64_t)(old_size); \ (cache_ptr)->slist_size -= (old_size); \
(cache_ptr)->slist_size_increase += (int64_t)(new_size); \ (cache_ptr)->slist_size += (new_size); \
\ \
HDassert( (new_size) <= (cache_ptr)->slist_size ); \ HDassert( (cache_ptr)->slist_ring_size[(entry_ptr->ring)] \
HDassert( ( (cache_ptr)->slist_len > 1 ) || \ >= (old_size) ); \
( (cache_ptr)->slist_size == (new_size) ) ); \ \
((cache_ptr)->slist_ring_size[(entry_ptr)->ring]) -= (old_size); \
((cache_ptr)->slist_ring_size[(entry_ptr)->ring]) += (new_size); \
\
(cache_ptr)->slist_size_increase -= (int64_t)(old_size); \
(cache_ptr)->slist_size_increase += (int64_t)(new_size); \
\
HDassert( (new_size) <= (cache_ptr)->slist_size ); \
HDassert( ( (cache_ptr)->slist_len > 1 ) || \
( (cache_ptr)->slist_size == (new_size) ) ); \
\
} else { /* slist disabled */ \
\
HDassert( (cache_ptr)->slist_len == 0 ); \
HDassert( (cache_ptr)->slist_size == 0 ); \
} \
} /* H5C__UPDATE_SLIST_FOR_SIZE_CHANGE */ } /* H5C__UPDATE_SLIST_FOR_SIZE_CHANGE */
#else /* H5C_DO_SANITY_CHECKS */ #else /* H5C_DO_SANITY_CHECKS */
@ -1813,29 +1932,39 @@ if ( ( (cache_ptr)->index_size != \
{ \ { \
HDassert( (cache_ptr) ); \ HDassert( (cache_ptr) ); \
HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \
HDassert( (old_size) > 0 ); \
HDassert( (new_size) > 0 ); \
HDassert( (old_size) <= (cache_ptr)->slist_size ); \
HDassert( (cache_ptr)->slist_len > 0 ); \
HDassert( ((cache_ptr)->slist_len > 1) || \
( (cache_ptr)->slist_size == (old_size) ) ); \
HDassert( (entry_ptr)->ring > H5C_RING_UNDEFINED ); \
HDassert( (entry_ptr)->ring < H5C_RING_NTYPES ); \
HDassert( (cache_ptr)->slist_ring_len[(entry_ptr)->ring] <= \
(cache_ptr)->slist_len ); \
HDassert( (cache_ptr)->slist_ring_size[(entry_ptr)->ring] <= \
(cache_ptr)->slist_size ); \
\ \
(cache_ptr)->slist_size -= (old_size); \ if ( (cache_ptr)->slist_enabled ) { \
(cache_ptr)->slist_size += (new_size); \
\ \
HDassert( (cache_ptr)->slist_ring_size[(entry_ptr->ring)] >=(old_size) ); \ HDassert( (old_size) > 0 ); \
((cache_ptr)->slist_ring_size[(entry_ptr)->ring]) -= (old_size); \ HDassert( (new_size) > 0 ); \
((cache_ptr)->slist_ring_size[(entry_ptr)->ring]) += (new_size); \ HDassert( (old_size) <= (cache_ptr)->slist_size ); \
HDassert( (cache_ptr)->slist_len > 0 ); \
HDassert( ((cache_ptr)->slist_len > 1) || \
( (cache_ptr)->slist_size == (old_size) ) ); \
HDassert( (entry_ptr)->ring > H5C_RING_UNDEFINED ); \
HDassert( (entry_ptr)->ring < H5C_RING_NTYPES ); \
HDassert( (cache_ptr)->slist_ring_len[(entry_ptr)->ring] <= \
(cache_ptr)->slist_len ); \
HDassert( (cache_ptr)->slist_ring_size[(entry_ptr)->ring] <= \
(cache_ptr)->slist_size ); \
\ \
HDassert( (new_size) <= (cache_ptr)->slist_size ); \ (cache_ptr)->slist_size -= (old_size); \
HDassert( ( (cache_ptr)->slist_len > 1 ) || \ (cache_ptr)->slist_size += (new_size); \
( (cache_ptr)->slist_size == (new_size) ) ); \ \
HDassert( (cache_ptr)->slist_ring_size[(entry_ptr->ring)] >= \
(old_size) ); \
((cache_ptr)->slist_ring_size[(entry_ptr)->ring]) -= (old_size); \
((cache_ptr)->slist_ring_size[(entry_ptr)->ring]) += (new_size); \
\
HDassert( (new_size) <= (cache_ptr)->slist_size ); \
HDassert( ( (cache_ptr)->slist_len > 1 ) || \
( (cache_ptr)->slist_size == (new_size) ) ); \
\
} else { /* slist disabled */ \
\
HDassert( (cache_ptr)->slist_len == 0 ); \
HDassert( (cache_ptr)->slist_size == 0 ); \
} \
} /* H5C__UPDATE_SLIST_FOR_SIZE_CHANGE */ } /* H5C__UPDATE_SLIST_FOR_SIZE_CHANGE */
#endif /* H5C_DO_SANITY_CHECKS */ #endif /* H5C_DO_SANITY_CHECKS */
@ -3723,10 +3852,11 @@ typedef struct H5C_tag_info_t {
* one. * one.
* *
* entry_watched_for_removal: Pointer to an instance of H5C_cache_entry_t * entry_watched_for_removal: Pointer to an instance of H5C_cache_entry_t
* which contains the 'next' entry for an iteration. Removing * which contains the 'next' entry for an iteration. Removing
* this entry must trigger a rescan of the iteration, so each * this entry must trigger a rescan of the iteration, so each
* entry removed from the cache is compared against this pointer * entry removed from the cache is compared against this pointer
* and the pointer is reset to NULL if the watched entry is removed. * and the pointer is reset to NULL if the watched entry is
* removed.
* (This functions similarly to a "dead man's switch") * (This functions similarly to a "dead man's switch")
* *
* *
@ -3740,6 +3870,36 @@ typedef struct H5C_tag_info_t {
* are flushed. (this has been changed -- dirty entries are now removed from * are flushed. (this has been changed -- dirty entries are now removed from
* the skip list as they are flushed. JRM - 10/25/05) * the skip list as they are flushed. JRM - 10/25/05)
* *
* Update 4/21/20:
*
* Profiling indicates that the cost of maintaining the skip list is
* significant. As it is only used on flush and close, maintaining it
* only when needed is an obvious optimization.
*
* To do this, we add a flag to control maintenanace of the skip list.
* This flag is initially set to FALSE, which disables all operations
* on the skip list.
*
* At the beginning of either flush or close, we scan the index list,
* insert all dirtly entries in the skip list, and enable operations
* on skip list by setting above control flag to true.
*
* At the end of a complete flush, we verify that the skip list is empty,
* and set the control flag back to false, so as to avoid skip list
* maintenance overhead until the next flush or close.
*
* In the case of a partial flush (i.e. flush marked entries), we remove
* all remaining entries from the skip list, and then set the control flag
* back to false -- again avoiding skip list maintenance overhead until
* the next flush or close.
*
* slist_enabled: Boolean flag used to control operation of the skip
* list. If this filed is FALSE, operations on the
* slist are no-ops, and the slist must be empty. If
* it is TRUE, operations on the slist proceed as usual,
* and all dirty entries in the metadata cache must be
* listed in the slist.
*
* slist_changed: Boolean flag used to indicate whether the contents of * slist_changed: Boolean flag used to indicate whether the contents of
* the slist has changed since the last time this flag was * the slist has changed since the last time this flag was
* reset. This is used in the cache flush code to detect * reset. This is used in the cache flush code to detect
@ -4649,6 +4809,7 @@ typedef struct H5C_tag_info_t {
* NDEBUG is not #defined. * NDEBUG is not #defined.
* *
****************************************************************************/ ****************************************************************************/
struct H5C_t { struct H5C_t {
uint32_t magic; uint32_t magic;
hbool_t flush_in_progress; hbool_t flush_in_progress;
@ -4664,7 +4825,7 @@ struct H5C_t {
hbool_t evictions_enabled; hbool_t evictions_enabled;
hbool_t close_warning_received; hbool_t close_warning_received;
/* Fields for maintaining [hash table] index of entries */ /* Fields for maintaining the [hash table] index of entries */
uint32_t index_len; uint32_t index_len;
size_t index_size; size_t index_size;
uint32_t index_ring_len[H5C_RING_NTYPES]; uint32_t index_ring_len[H5C_RING_NTYPES];
@ -4685,6 +4846,7 @@ struct H5C_t {
H5C_cache_entry_t * entry_watched_for_removal; H5C_cache_entry_t * entry_watched_for_removal;
/* Fields for maintaining list of in-order entries, for flushing */ /* Fields for maintaining list of in-order entries, for flushing */
hbool_t slist_enabled;
hbool_t slist_changed; hbool_t slist_changed;
uint32_t slist_len; uint32_t slist_len;
size_t slist_size; size_t slist_size;
@ -4882,7 +5044,8 @@ struct H5C_t {
#ifndef NDEBUG #ifndef NDEBUG
int64_t get_entry_ptr_from_addr_counter; int64_t get_entry_ptr_from_addr_counter;
#endif /* NDEBUG */ #endif /* NDEBUG */
};
}; /* H5C_t */
/* Define typedef for tagged cache entry iteration callbacks */ /* Define typedef for tagged cache entry iteration callbacks */
typedef int (*H5C_tag_iter_cb_t)(H5C_cache_entry_t *entry, void *ctx); typedef int (*H5C_tag_iter_cb_t)(H5C_cache_entry_t *entry, void *ctx);

View File

@ -2285,7 +2285,10 @@ H5_DLL herr_t H5C_resize_entry(void *thing, size_t new_size);
H5_DLL herr_t H5C_set_cache_auto_resize_config(H5C_t *cache_ptr, H5C_auto_size_ctl_t *config_ptr); H5_DLL herr_t H5C_set_cache_auto_resize_config(H5C_t *cache_ptr, H5C_auto_size_ctl_t *config_ptr);
H5_DLL herr_t H5C_set_cache_image_config(const H5F_t *f, H5C_t *cache_ptr, H5_DLL herr_t H5C_set_cache_image_config(const H5F_t *f, H5C_t *cache_ptr,
H5C_cache_image_ctl_t *config_ptr); H5C_cache_image_ctl_t *config_ptr);
H5_DLL herr_t H5C_set_evictions_enabled(H5C_t *cache_ptr, hbool_t evictions_enabled); H5_DLL herr_t H5C_set_evictions_enabled(H5C_t *cache_ptr,
hbool_t evictions_enabled);
H5_DLL herr_t H5C_set_slist_enabled(H5C_t *cache_ptr, hbool_t slist_enabled,
hbool_t clear_slist);
H5_DLL herr_t H5C_set_prefix(H5C_t *cache_ptr, char *prefix); H5_DLL herr_t H5C_set_prefix(H5C_t *cache_ptr, char *prefix);
H5_DLL herr_t H5C_stats(H5C_t *cache_ptr, const char *cache_name, H5_DLL herr_t H5C_stats(H5C_t *cache_ptr, const char *cache_name,
hbool_t display_detailed_stats); hbool_t display_detailed_stats);

View File

@ -2144,6 +2144,11 @@ H5F__flush_phase2(H5F_t *f, hbool_t closing)
/* Sanity check arguments */ /* Sanity check arguments */
HDassert(f); HDassert(f);
/* Inform the metadata cache that we are about to flush */
if(H5AC_prep_for_file_flush(f) < 0)
/* Push error, but keep going*/
HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "prep for MDC flush failed")
/* Flush the entire metadata cache */ /* Flush the entire metadata cache */
if(H5AC_flush(f) < 0) if(H5AC_flush(f) < 0)
/* Push error, but keep going*/ /* Push error, but keep going*/
@ -2176,6 +2181,11 @@ H5F__flush_phase2(H5F_t *f, hbool_t closing)
H5CX_set_mpi_file_flushing(FALSE); H5CX_set_mpi_file_flushing(FALSE);
#endif /* H5_HAVE_PARALLEL */ #endif /* H5_HAVE_PARALLEL */
/* Inform the metadata cache that we are done with the flush */
if(H5AC_secure_from_file_flush(f) < 0)
/* Push error, but keep going*/
HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "secure from MDC flush failed")
/* Flush out the metadata accumulator */ /* Flush out the metadata accumulator */
if(H5F__accum_flush(f->shared) < 0) if(H5F__accum_flush(f->shared) < 0)
/* Push error, but keep going*/ /* Push error, but keep going*/

File diff suppressed because it is too large Load Diff

View File

@ -3111,12 +3111,25 @@ expunge_entry(H5F_t * file_ptr,
* Function: flush_cache() * Function: flush_cache()
* *
* Purpose: Flush the specified cache, destroying all entries if * Purpose: Flush the specified cache, destroying all entries if
requested. If requested, dump stats first. * requested. If requested, dump stats first.
* *
* Return: void * Return: void
* *
* Programmer: John Mainzer * Programmer: John Mainzer
* 6/23/04 * 6/23/04
*
* Changes: Added code to setup and take down the skip list before
* and after calls to H5C_flush_cache(). Do this via calls
* to the H5C_FLUSH_CACHE macro.
*
* This is necessary, as H5C_flush() is called repeatedly
* during file flush. If we setup and took down the
* skip list on H5C_flush_cache(), we would find ourselves
* doing this repeatedly -- which is contrary to the
* objective of the exercise (avoiding as many skip list
* operations as possible).
*
* JRM -- 5/14/20
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -3139,25 +3152,30 @@ flush_cache(H5F_t * file_ptr,
cache_ptr = file_ptr->shared->cache; cache_ptr = file_ptr->shared->cache;
if(destroy_entries) if ( destroy_entries ) {
result = H5C_flush_cache(file_ptr, H5C__FLUSH_INVALIDATE_FLAG);
else H5C_FLUSH_CACHE(file_ptr, H5C__FLUSH_INVALIDATE_FLAG, \
result = H5C_flush_cache(file_ptr, H5C__NO_FLAGS_SET); "error in H5C_flush_cache().")
if(dump_stats) } else {
H5C_stats(cache_ptr, "test cache", dump_detailed_stats);
if(result < 0) { H5C_FLUSH_CACHE(file_ptr, H5C__NO_FLAGS_SET, \
pass = FALSE; "error in H5C_flush_cache().")
failure_mssg = "error in H5C_flush_cache().";
} }
else if((destroy_entries) && ((cache_ptr->index_len != 0)
|| (cache_ptr->index_size != 0)
|| (cache_ptr->clean_index_size != 0)
|| (cache_ptr->dirty_index_size != 0))) {
if(verbose) { if ( dump_stats ) {
H5C_stats(cache_ptr, "test cache", dump_detailed_stats);
}
if ( ( pass ) && ( destroy_entries ) &&
( ( cache_ptr->index_len != 0 ) ||
( cache_ptr->index_size != 0 ) ||
( cache_ptr->clean_index_size != 0 ) ||
( cache_ptr->dirty_index_size != 0 ) ) ) {
if ( verbose ) {
HDfprintf(stdout, HDfprintf(stdout,
"%s: unexpected il/is/cis/dis = %lld/%lld/%lld/%lld.\n", "%s: unexpected il/is/cis/dis = %lld/%lld/%lld/%lld.\n",
FUNC, FUNC,
@ -3961,14 +3979,19 @@ unprotect_entry(H5F_t * file_ptr,
* Function: row_major_scan_forward() * Function: row_major_scan_forward()
* *
* Purpose: Do a sequence of inserts, protects, unprotects, moves, * Purpose: Do a sequence of inserts, protects, unprotects, moves,
* destroys while scanning through the set of entries. If * destroys while scanning through the set of entries. If
* pass is false on entry, do nothing. * pass is false on entry, do nothing.
* *
* Return: void * Return: void
* *
* Programmer: John Mainzer * Programmer: John Mainzer
* 6/12/04 * 6/12/04
* *
* Changes: Updated slist size == dirty index size checks to
* bypass the test if cache_ptr->slist_enabled is FALSE.
*
* JRM -- 5/8/20
*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
void void
@ -3983,7 +4006,7 @@ row_major_scan_forward(H5F_t * file_ptr,
hbool_t do_moves, hbool_t do_moves,
hbool_t move_to_main_addr, hbool_t move_to_main_addr,
hbool_t do_destroys, hbool_t do_destroys,
hbool_t do_mult_ro_protects, hbool_t do_mult_ro_protects,
int dirty_destroys, int dirty_destroys,
int dirty_unprotects) int dirty_unprotects)
{ {
@ -4022,7 +4045,10 @@ row_major_scan_forward(H5F_t * file_ptr,
HDfprintf(stdout, "1(i, %d, %d) ", type, tmp_idx); HDfprintf(stdout, "1(i, %d, %d) ", type, tmp_idx);
insert_entry(file_ptr, type, tmp_idx, H5C__NO_FLAGS_SET); insert_entry(file_ptr, type, tmp_idx, H5C__NO_FLAGS_SET);
HDassert(cache_ptr->slist_size == cache_ptr->dirty_index_size);
HDassert( ( ! cache_ptr->slist_enabled ) || \
( cache_ptr->slist_size == \
cache_ptr->dirty_index_size ) );
} /* end if */ } /* end if */
tmp_idx--; tmp_idx--;
@ -4033,7 +4059,10 @@ row_major_scan_forward(H5F_t * file_ptr,
HDfprintf(stdout, "2(p, %d, %d) ", type, tmp_idx); HDfprintf(stdout, "2(p, %d, %d) ", type, tmp_idx);
protect_entry(file_ptr, type, tmp_idx); protect_entry(file_ptr, type, tmp_idx);
HDassert(cache_ptr->slist_size == cache_ptr->dirty_index_size);
HDassert( ( ! cache_ptr->slist_enabled ) || \
( cache_ptr->slist_size == \
cache_ptr->dirty_index_size ) );
} /* end if */ } /* end if */
tmp_idx--; tmp_idx--;
@ -4044,7 +4073,10 @@ row_major_scan_forward(H5F_t * file_ptr,
HDfprintf(stdout, "3(u, %d, %d) ", type, tmp_idx); HDfprintf(stdout, "3(u, %d, %d) ", type, tmp_idx);
unprotect_entry(file_ptr, type, tmp_idx, H5C__NO_FLAGS_SET); unprotect_entry(file_ptr, type, tmp_idx, H5C__NO_FLAGS_SET);
HDassert(cache_ptr->slist_size == cache_ptr->dirty_index_size);
HDassert( ( ! cache_ptr->slist_enabled ) || \
( cache_ptr->slist_size == \
cache_ptr->dirty_index_size ) );
} /* end if */ } /* end if */
/* (don't decrement tmp_idx) */ /* (don't decrement tmp_idx) */
@ -4055,7 +4087,10 @@ row_major_scan_forward(H5F_t * file_ptr,
HDfprintf(stdout, "4(r, %d, %d, %d) ", type, tmp_idx, (int)move_to_main_addr); HDfprintf(stdout, "4(r, %d, %d, %d) ", type, tmp_idx, (int)move_to_main_addr);
move_entry(cache_ptr, type, tmp_idx, move_to_main_addr); move_entry(cache_ptr, type, tmp_idx, move_to_main_addr);
HDassert(cache_ptr->slist_size == cache_ptr->dirty_index_size);
HDassert( ( ! cache_ptr->slist_enabled ) || \
( cache_ptr->slist_size == \
cache_ptr->dirty_index_size ) );
} /* end if */ } /* end if */
tmp_idx--; tmp_idx--;
@ -4066,7 +4101,10 @@ row_major_scan_forward(H5F_t * file_ptr,
HDfprintf(stdout, "5(p, %d, %d) ", type, tmp_idx); HDfprintf(stdout, "5(p, %d, %d) ", type, tmp_idx);
protect_entry(file_ptr, type, tmp_idx); protect_entry(file_ptr, type, tmp_idx);
HDassert(cache_ptr->slist_size == cache_ptr->dirty_index_size);
HDassert( ( ! cache_ptr->slist_enabled ) || \
( cache_ptr->slist_size == \
cache_ptr->dirty_index_size ) );
} /* end if */ } /* end if */
tmp_idx -= 2; tmp_idx -= 2;
@ -4077,7 +4115,10 @@ row_major_scan_forward(H5F_t * file_ptr,
HDfprintf(stdout, "6(u, %d, %d) ", type, tmp_idx); HDfprintf(stdout, "6(u, %d, %d) ", type, tmp_idx);
unprotect_entry(file_ptr, type, tmp_idx, H5C__NO_FLAGS_SET); unprotect_entry(file_ptr, type, tmp_idx, H5C__NO_FLAGS_SET);
HDassert(cache_ptr->slist_size == cache_ptr->dirty_index_size);
HDassert( ( ! cache_ptr->slist_enabled ) || \
( cache_ptr->slist_size == \
cache_ptr->dirty_index_size ) );
} /* end if */ } /* end if */
if(do_mult_ro_protects) { if(do_mult_ro_protects) {
@ -4089,7 +4130,10 @@ row_major_scan_forward(H5F_t * file_ptr,
HDfprintf(stdout, "7(p-ro, %d, %d) ", type, tmp_idx); HDfprintf(stdout, "7(p-ro, %d, %d) ", type, tmp_idx);
protect_entry_ro(file_ptr, type, tmp_idx); protect_entry_ro(file_ptr, type, tmp_idx);
HDassert(cache_ptr->slist_size == cache_ptr->dirty_index_size);
HDassert( ( ! cache_ptr->slist_enabled ) || \
( cache_ptr->slist_size == \
cache_ptr->dirty_index_size ) );
} /* end if */ } /* end if */
tmp_idx--; tmp_idx--;
@ -4100,7 +4144,10 @@ row_major_scan_forward(H5F_t * file_ptr,
HDfprintf(stdout, "8(p-ro, %d, %d) ", type, tmp_idx); HDfprintf(stdout, "8(p-ro, %d, %d) ", type, tmp_idx);
protect_entry_ro(file_ptr, type, tmp_idx); protect_entry_ro(file_ptr, type, tmp_idx);
HDassert(cache_ptr->slist_size == cache_ptr->dirty_index_size);
HDassert( ( ! cache_ptr->slist_enabled ) || \
( cache_ptr->slist_size == \
cache_ptr->dirty_index_size ) );
} /* end if */ } /* end if */
tmp_idx--; tmp_idx--;
@ -4111,7 +4158,10 @@ row_major_scan_forward(H5F_t * file_ptr,
HDfprintf(stdout, "9(p-ro, %d, %d) ", type, tmp_idx); HDfprintf(stdout, "9(p-ro, %d, %d) ", type, tmp_idx);
protect_entry_ro(file_ptr, type, tmp_idx); protect_entry_ro(file_ptr, type, tmp_idx);
HDassert(cache_ptr->slist_size == cache_ptr->dirty_index_size);
HDassert( ( ! cache_ptr->slist_enabled ) || \
( cache_ptr->slist_size == \
cache_ptr->dirty_index_size ) );
} /* end if */ } /* end if */
/* (don't decrement tmp_idx) */ /* (don't decrement tmp_idx) */
@ -4122,7 +4172,10 @@ row_major_scan_forward(H5F_t * file_ptr,
HDfprintf(stdout, "10(u-ro, %d, %d) ", type, tmp_idx); HDfprintf(stdout, "10(u-ro, %d, %d) ", type, tmp_idx);
unprotect_entry(file_ptr, type, tmp_idx, H5C__NO_FLAGS_SET); unprotect_entry(file_ptr, type, tmp_idx, H5C__NO_FLAGS_SET);
HDassert(cache_ptr->slist_size == cache_ptr->dirty_index_size);
HDassert( ( ! cache_ptr->slist_enabled ) || \
( cache_ptr->slist_size == \
cache_ptr->dirty_index_size ) );
} /* end if */ } /* end if */
tmp_idx--; tmp_idx--;
@ -4133,7 +4186,10 @@ row_major_scan_forward(H5F_t * file_ptr,
HDfprintf(stdout, "11(u-ro, %d, %d) ", type, tmp_idx); HDfprintf(stdout, "11(u-ro, %d, %d) ", type, tmp_idx);
unprotect_entry(file_ptr, type, tmp_idx, H5C__NO_FLAGS_SET); unprotect_entry(file_ptr, type, tmp_idx, H5C__NO_FLAGS_SET);
HDassert(cache_ptr->slist_size == cache_ptr->dirty_index_size);
HDassert( ( ! cache_ptr->slist_enabled ) || \
( cache_ptr->slist_size == \
cache_ptr->dirty_index_size ) );
} /* end if */ } /* end if */
tmp_idx--; tmp_idx--;
@ -4144,7 +4200,10 @@ row_major_scan_forward(H5F_t * file_ptr,
HDfprintf(stdout, "12(u-ro, %d, %d) ", type, tmp_idx); HDfprintf(stdout, "12(u-ro, %d, %d) ", type, tmp_idx);
unprotect_entry(file_ptr, type, tmp_idx, H5C__NO_FLAGS_SET); unprotect_entry(file_ptr, type, tmp_idx, H5C__NO_FLAGS_SET);
HDassert(cache_ptr->slist_size == cache_ptr->dirty_index_size);
HDassert( ( ! cache_ptr->slist_enabled ) || \
( cache_ptr->slist_size == \
cache_ptr->dirty_index_size ) );
} /* end if */ } /* end if */
} /* if ( do_mult_ro_protects ) */ } /* if ( do_mult_ro_protects ) */
@ -4153,7 +4212,10 @@ row_major_scan_forward(H5F_t * file_ptr,
HDfprintf(stdout, "13(p, %d, %d) ", type, idx); HDfprintf(stdout, "13(p, %d, %d) ", type, idx);
protect_entry(file_ptr, type, idx); protect_entry(file_ptr, type, idx);
HDassert(cache_ptr->slist_size == cache_ptr->dirty_index_size);
HDassert( ( ! cache_ptr->slist_enabled ) || \
( cache_ptr->slist_size == \
cache_ptr->dirty_index_size ) );
} /* end if */ } /* end if */
tmp_idx = idx - lag + 2; tmp_idx = idx - lag + 2;
@ -4164,7 +4226,10 @@ row_major_scan_forward(H5F_t * file_ptr,
HDfprintf(stdout, "14(u, %d, %d) ", type, tmp_idx); HDfprintf(stdout, "14(u, %d, %d) ", type, tmp_idx);
unprotect_entry(file_ptr, type, tmp_idx, H5C__NO_FLAGS_SET); unprotect_entry(file_ptr, type, tmp_idx, H5C__NO_FLAGS_SET);
HDassert(cache_ptr->slist_size == cache_ptr->dirty_index_size);
HDassert( ( ! cache_ptr->slist_enabled ) || \
( cache_ptr->slist_size == \
cache_ptr->dirty_index_size ) );
} /* end if */ } /* end if */
tmp_idx--; tmp_idx--;
@ -4175,7 +4240,10 @@ row_major_scan_forward(H5F_t * file_ptr,
HDfprintf(stdout, "15(p, %d, %d) ", type, tmp_idx); HDfprintf(stdout, "15(p, %d, %d) ", type, tmp_idx);
protect_entry(file_ptr, type, tmp_idx); protect_entry(file_ptr, type, tmp_idx);
HDassert(cache_ptr->slist_size == cache_ptr->dirty_index_size);
HDassert( ( ! cache_ptr->slist_enabled ) || \
( cache_ptr->slist_size == \
cache_ptr->dirty_index_size ) );
} /* end if */ } /* end if */
if(do_destroys) { if(do_destroys) {
@ -4187,7 +4255,10 @@ row_major_scan_forward(H5F_t * file_ptr,
HDfprintf(stdout, "16(u, %d, %d) ", type, tmp_idx); HDfprintf(stdout, "16(u, %d, %d) ", type, tmp_idx);
unprotect_entry(file_ptr, type, tmp_idx, H5C__NO_FLAGS_SET); unprotect_entry(file_ptr, type, tmp_idx, H5C__NO_FLAGS_SET);
HDassert(cache_ptr->slist_size == cache_ptr->dirty_index_size);
HDassert( ( ! cache_ptr->slist_enabled ) || \
( cache_ptr->slist_size == \
cache_ptr->dirty_index_size ) );
break; break;
case 1: case 1:
@ -4196,14 +4267,20 @@ row_major_scan_forward(H5F_t * file_ptr,
HDfprintf(stdout, "17(u, %d, %d) ", type, tmp_idx); HDfprintf(stdout, "17(u, %d, %d) ", type, tmp_idx);
unprotect_entry(file_ptr, type, tmp_idx, H5C__NO_FLAGS_SET); unprotect_entry(file_ptr, type, tmp_idx, H5C__NO_FLAGS_SET);
HDassert(cache_ptr->slist_size == cache_ptr->dirty_index_size);
HDassert( ( ! cache_ptr->slist_enabled ) || \
( cache_ptr->slist_size == \
cache_ptr->dirty_index_size ) );
} /* end if */ } /* end if */
else { else {
if(verbose) if(verbose)
HDfprintf(stdout, "18(u, %d, %d) ", type, tmp_idx); HDfprintf(stdout, "18(u, %d, %d) ", type, tmp_idx);
unprotect_entry(file_ptr, type, tmp_idx, (dirty_unprotects ? H5C__DIRTIED_FLAG : H5C__NO_FLAGS_SET)); unprotect_entry(file_ptr, type, tmp_idx, (dirty_unprotects ? H5C__DIRTIED_FLAG : H5C__NO_FLAGS_SET));
HDassert(cache_ptr->slist_size == cache_ptr->dirty_index_size);
HDassert( ( ! cache_ptr->slist_enabled ) || \
( cache_ptr->slist_size == \
cache_ptr->dirty_index_size ) );
} /* end else */ } /* end else */
break; break;
@ -4212,7 +4289,10 @@ row_major_scan_forward(H5F_t * file_ptr,
HDfprintf(stdout, "19(u-del, %d, %d) ", type, tmp_idx); HDfprintf(stdout, "19(u-del, %d, %d) ", type, tmp_idx);
unprotect_entry(file_ptr, type, tmp_idx, H5C__DELETED_FLAG); unprotect_entry(file_ptr, type, tmp_idx, H5C__DELETED_FLAG);
HDassert(cache_ptr->slist_size == cache_ptr->dirty_index_size);
HDassert( ( ! cache_ptr->slist_enabled ) || \
( cache_ptr->slist_size == \
cache_ptr->dirty_index_size ) );
break; break;
case 3: case 3:
@ -4221,14 +4301,20 @@ row_major_scan_forward(H5F_t * file_ptr,
HDfprintf(stdout, "20(u-del, %d, %d) ", type, tmp_idx); HDfprintf(stdout, "20(u-del, %d, %d) ", type, tmp_idx);
unprotect_entry(file_ptr, type, tmp_idx, H5C__DELETED_FLAG); unprotect_entry(file_ptr, type, tmp_idx, H5C__DELETED_FLAG);
HDassert(cache_ptr->slist_size == cache_ptr->dirty_index_size);
HDassert( ( ! cache_ptr->slist_enabled ) || \
( cache_ptr->slist_size == \
cache_ptr->dirty_index_size ) );
} /* end if */ } /* end if */
else { else {
if(verbose) if(verbose)
HDfprintf(stdout, "21(u-del, %d, %d) ", type, tmp_idx); HDfprintf(stdout, "21(u-del, %d, %d) ", type, tmp_idx);
unprotect_entry(file_ptr, type, tmp_idx, (dirty_destroys ? H5C__DIRTIED_FLAG : H5C__NO_FLAGS_SET) | H5C__DELETED_FLAG); unprotect_entry(file_ptr, type, tmp_idx, (dirty_destroys ? H5C__DIRTIED_FLAG : H5C__NO_FLAGS_SET) | H5C__DELETED_FLAG);
HDassert(cache_ptr->slist_size == cache_ptr->dirty_index_size);
HDassert( ( ! cache_ptr->slist_enabled ) || \
( cache_ptr->slist_size == \
cache_ptr->dirty_index_size ) );
} /* end else */ } /* end else */
break; break;
@ -4245,7 +4331,10 @@ row_major_scan_forward(H5F_t * file_ptr,
HDfprintf(stdout, "22(u, %d, %d) ", type, tmp_idx); HDfprintf(stdout, "22(u, %d, %d) ", type, tmp_idx);
unprotect_entry(file_ptr, type, tmp_idx, (dirty_unprotects ? H5C__DIRTIED_FLAG : H5C__NO_FLAGS_SET)); unprotect_entry(file_ptr, type, tmp_idx, (dirty_unprotects ? H5C__DIRTIED_FLAG : H5C__NO_FLAGS_SET));
HDassert(cache_ptr->slist_size == cache_ptr->dirty_index_size);
HDassert( ( ! cache_ptr->slist_enabled ) || \
( cache_ptr->slist_size == \
cache_ptr->dirty_index_size ) );
} /* end if */ } /* end if */
} /* end elsef */ } /* end elsef */

View File

@ -134,6 +134,65 @@
(NOTIFY_ENTRY_SIZE * NUM_NOTIFY_ENTRIES)) (NOTIFY_ENTRY_SIZE * NUM_NOTIFY_ENTRIES))
#define ADDR_SPACE_SIZE (haddr_t)(MAX_ADDR - BASE_ADDR) #define ADDR_SPACE_SIZE (haddr_t)(MAX_ADDR - BASE_ADDR)
/***********************************************************************
*
* Macro: H5C_FLUSH_CACHE
*
* Purpose: Wrap a call to H5C_flush_cache() in calls to
* H5C_set_slist_enabled() to setup and take down the slist.
*
* This is necessary, as H5C_flush_cache() needs the
* slist to be active. Further, since it is called
* repeatedly during file flush, it would be inefficient
* for it to setup the slist on entry, and take it down
* on exit.
*
* Note that the slist need not be empty if the flags
* indicate a partial flush (i.e.
* H5C__FLUSH_MARKED_ENTRIES_FLAG). Compute clear_slist
* and pass it into H5C_set_slist_enabled as appropriate.
*
* On error, set pass to FALSE, and set failure_mssg
* to the supplied error message.
*
* Return: N/A
*
* Programmer: John Mainzer
* 5/14/20
*
* Changes: None.
*
***********************************************************************/
#define H5C_FLUSH_CACHE(file, flags, fail_mssg) \
{ \
hbool_t clear_slist; \
herr_t rslt; \
\
clear_slist = ( (flags & H5C__FLUSH_MARKED_ENTRIES_FLAG) != 0 ); \
\
rslt = H5C_set_slist_enabled((file)->shared->cache, TRUE, FALSE); \
\
if ( rslt >= 0 ) { \
\
rslt = H5C_flush_cache((file), (flags)); \
} \
\
if ( rslt >= 0 ) { \
\
rslt = H5C_set_slist_enabled((file)->shared->cache, FALSE, \
clear_slist); \
} \
\
if( rslt < 0 ) { \
\
pass = FALSE; \
failure_mssg = (fail_mssg); \
} \
} /* H5C_FLUSH_CACHE */
#define MAX_PINS 8 /* Maximum number of entries that can be #define MAX_PINS 8 /* Maximum number of entries that can be
* directly pinned by a single entry. * directly pinned by a single entry.
*/ */

View File

@ -348,11 +348,20 @@ evict_entries(hid_t fid)
/* Mark all entries investigated */ /* Mark all entries investigated */
mark_all_entries_investigated(fid); mark_all_entries_investigated(fid);
/* setup the skip list prior to calling H5C_flush_cache() */
if ( H5C_set_slist_enabled(f->shared->cache, TRUE, FALSE) < 0 )
TEST_ERROR;
/* Evict all we can from the cache to examine full tag creation tree */ /* Evict all we can from the cache to examine full tag creation tree */
/* This function will likely return failure since the root group /* This function will likely return failure since the root group
* is still protected. Thus, don't check its return value. */ * is still protected. Thus, don't check its return value.
*/
H5C_flush_cache(f, H5C__FLUSH_INVALIDATE_FLAG); H5C_flush_cache(f, H5C__FLUSH_INVALIDATE_FLAG);
/* shutdown the slist -- allow it to be non-empty */
if ( H5C_set_slist_enabled(f->shared->cache, FALSE, TRUE) < 0 )
TEST_ERROR;
return 0; return 0;
error: error:

View File

@ -126,8 +126,12 @@ test_cont(char *filename, hid_t fapl)
FAIL_STACK_ERROR FAIL_STACK_ERROR
if(1 != H5O_link(&oh_locB, 1)) if(1 != H5O_link(&oh_locB, 1))
FAIL_STACK_ERROR FAIL_STACK_ERROR
if(H5AC_prep_for_file_flush(f) < 0)
FAIL_STACK_ERROR
if(H5AC_flush(f) < 0) if(H5AC_flush(f) < 0)
FAIL_STACK_ERROR FAIL_STACK_ERROR
if(H5AC_secure_from_file_flush(f) < 0)
FAIL_STACK_ERROR
if(H5O__expunge_chunks_test(&oh_locA) < 0) if(H5O__expunge_chunks_test(&oh_locA) < 0)
FAIL_STACK_ERROR FAIL_STACK_ERROR
@ -1681,8 +1685,12 @@ main(void)
FAIL_STACK_ERROR FAIL_STACK_ERROR
if(1 != H5O_link(&oh_loc, 1)) if(1 != H5O_link(&oh_loc, 1))
FAIL_STACK_ERROR FAIL_STACK_ERROR
if(H5AC_prep_for_file_flush(f) < 0)
FAIL_STACK_ERROR
if(H5AC_flush(f) < 0) if(H5AC_flush(f) < 0)
FAIL_STACK_ERROR FAIL_STACK_ERROR
if(H5AC_secure_from_file_flush(f) < 0)
FAIL_STACK_ERROR
if(H5AC_expunge_entry(f, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0) if(H5AC_expunge_entry(f, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0)
FAIL_STACK_ERROR FAIL_STACK_ERROR
if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro)) if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro))
@ -1698,8 +1706,12 @@ main(void)
time_new = 33333333; time_new = 33333333;
if(H5O_msg_write(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new) < 0) if(H5O_msg_write(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new) < 0)
FAIL_STACK_ERROR FAIL_STACK_ERROR
if(H5AC_prep_for_file_flush(f) < 0)
FAIL_STACK_ERROR
if(H5AC_flush(f) < 0) if(H5AC_flush(f) < 0)
FAIL_STACK_ERROR FAIL_STACK_ERROR
if(H5AC_secure_from_file_flush(f) < 0)
FAIL_STACK_ERROR
if(H5AC_expunge_entry(f, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0) if(H5AC_expunge_entry(f, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0)
FAIL_STACK_ERROR FAIL_STACK_ERROR
if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro)) if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro))
@ -1729,8 +1741,12 @@ main(void)
if(H5O_msg_create(&oh_loc, H5O_MTIME_ID, 0, 0, &time_new) < 0) if(H5O_msg_create(&oh_loc, H5O_MTIME_ID, 0, 0, &time_new) < 0)
FAIL_STACK_ERROR FAIL_STACK_ERROR
} /* end for */ } /* end for */
if(H5AC_prep_for_file_flush(f) < 0)
FAIL_STACK_ERROR
if(H5AC_flush(f) < 0) if(H5AC_flush(f) < 0)
FAIL_STACK_ERROR FAIL_STACK_ERROR
if(H5AC_secure_from_file_flush(f) < 0)
FAIL_STACK_ERROR
if(H5AC_expunge_entry(f, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0) if(H5AC_expunge_entry(f, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0)
FAIL_STACK_ERROR FAIL_STACK_ERROR
@ -1772,8 +1788,12 @@ main(void)
time_new = (i + 1) * 1000 + 10; time_new = (i + 1) * 1000 + 10;
if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new) < 0) if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new) < 0)
FAIL_STACK_ERROR FAIL_STACK_ERROR
if(H5AC_prep_for_file_flush(f) < 0)
FAIL_STACK_ERROR
if(H5AC_flush(f) < 0) if(H5AC_flush(f) < 0)
FAIL_STACK_ERROR FAIL_STACK_ERROR
if(H5AC_secure_from_file_flush(f) < 0)
FAIL_STACK_ERROR
if(H5AC_expunge_entry(f, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0) if(H5AC_expunge_entry(f, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0)
FAIL_STACK_ERROR FAIL_STACK_ERROR
} /* end for */ } /* end for */
@ -1802,8 +1822,12 @@ main(void)
time_new = 22222222; time_new = 22222222;
if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, H5O_MSG_FLAG_CONSTANT, 0, &time_new) < 0) if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, H5O_MSG_FLAG_CONSTANT, 0, &time_new) < 0)
FAIL_STACK_ERROR FAIL_STACK_ERROR
if(H5AC_prep_for_file_flush(f) < 0)
FAIL_STACK_ERROR
if(H5AC_flush(f) < 0) if(H5AC_flush(f) < 0)
FAIL_STACK_ERROR FAIL_STACK_ERROR
if(H5AC_secure_from_file_flush(f) < 0)
FAIL_STACK_ERROR
if(H5AC_expunge_entry(f, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0) if(H5AC_expunge_entry(f, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0)
FAIL_STACK_ERROR FAIL_STACK_ERROR
if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro)) if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro))

View File

@ -13,10 +13,10 @@ add_executable (mirror_server ${mirror_server_SOURCES})
target_include_directories (mirror_server PRIVATE "${HDF5_UITLS_DIR};${HDF5_SRC_DIR};${HDF5_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") target_include_directories (mirror_server PRIVATE "${HDF5_UITLS_DIR};${HDF5_SRC_DIR};${HDF5_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>")
if (NOT BUILD_SHARED_LIBS) if (NOT BUILD_SHARED_LIBS)
TARGET_C_PROPERTIES (mirror_server STATIC) TARGET_C_PROPERTIES (mirror_server STATIC)
target_link_libraries (mirror_server PRIVATE ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET}) target_link_libraries (mirror_server PRIVATE ${HDF5_LIB_TARGET})
else () else ()
TARGET_C_PROPERTIES (mirror_server SHARED) TARGET_C_PROPERTIES (mirror_server SHARED)
target_link_libraries (mirror_server PRIVATE ${HDF5_TOOLS_LIBSH_TARGET} ${HDF5_LIBSH_TARGET}) target_link_libraries (mirror_server PRIVATE ${HDF5_LIBSH_TARGET})
endif () endif ()
set_target_properties (mirror_server PROPERTIES FOLDER utils) set_target_properties (mirror_server PROPERTIES FOLDER utils)
set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};mirror_server") set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};mirror_server")
@ -31,10 +31,10 @@ add_executable (mirror_server_stop ${mirror_server_stop_SOURCES})
target_include_directories (mirror_server_stop PRIVATE "${HDF5_UITLS_DIR};${HDF5_SRC_DIR};${HDF5_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") target_include_directories (mirror_server_stop PRIVATE "${HDF5_UITLS_DIR};${HDF5_SRC_DIR};${HDF5_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>")
if (NOT BUILD_SHARED_LIBS) if (NOT BUILD_SHARED_LIBS)
TARGET_C_PROPERTIES (mirror_server_stop STATIC) TARGET_C_PROPERTIES (mirror_server_stop STATIC)
target_link_libraries (mirror_server_stop PRIVATE ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET}) target_link_libraries (mirror_server_stop PRIVATE ${HDF5_LIB_TARGET})
else () else ()
TARGET_C_PROPERTIES (mirror_server_stop SHARED) TARGET_C_PROPERTIES (mirror_server_stop SHARED)
target_link_libraries (mirror_server_stop PRIVATE ${HDF5_TOOLS_LIBSH_TARGET} ${HDF5_LIBSH_TARGET}) target_link_libraries (mirror_server_stop PRIVATE ${HDF5_LIBSH_TARGET})
endif () endif ()
set_target_properties (mirror_server_stop PROPERTIES FOLDER utils) set_target_properties (mirror_server_stop PROPERTIES FOLDER utils)
set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};mirror_server_stop") set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};mirror_server_stop")