mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-03-13 16:47:58 +08:00
When flushing, the metadata cache attempts to flush entries in increasing
address order. To facilitate this, the metadata cache needs a list of of dirty entries in increasing address order. This is implemented via a skip list of all dirty entries in the cache. To date this skip list has been maintained at all times. However, profiling indicates that we can avoid significant overhead by constructing the skip list of dirty entries just before a flush, taking it down afterwareds, and not maintaining it during normal operation. This commit implements this optimization for both serial and parallel. Tested serial and parallel, debug and production on charis and jelly.
This commit is contained in:
parent
50f404c887
commit
33f35183cb
483
src/H5AC.c
483
src/H5AC.c
@ -136,14 +136,14 @@ static const H5AC_class_t *const H5AC_class_s[] = {
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5AC_init
|
||||
* Function: H5AC_init
|
||||
*
|
||||
* Purpose: Initialize the interface from some other layer.
|
||||
* Purpose: Initialize the interface from some other layer.
|
||||
*
|
||||
* Return: Success: non-negative
|
||||
* Failure: negative
|
||||
* Return: Success: non-negative
|
||||
* Failure: negative
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Programmer: Quincey Koziol
|
||||
* Saturday, January 18, 2003
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
@ -162,13 +162,13 @@ done:
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function H5AC__init_package
|
||||
* Function: H5AC__init_package
|
||||
*
|
||||
* Purpose: Initialize interface-specific information
|
||||
* Purpose: Initialize interface-specific information
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Programmer: Quincey Koziol
|
||||
* Thursday, July 18, 2002
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
@ -198,15 +198,15 @@ H5AC__init_package(void)
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5AC_term_package
|
||||
* Function: H5AC_term_package
|
||||
*
|
||||
* Purpose: Terminate this interface.
|
||||
* Purpose: Terminate this interface.
|
||||
*
|
||||
* Return: Success: Positive if anything was done that might
|
||||
* affect other interfaces; zero otherwise.
|
||||
* Failure: Negative.
|
||||
* Return: Success: Positive if anything was done that might
|
||||
* affect other interfaces; zero otherwise.
|
||||
* Failure: Negative.
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Programmer: Quincey Koziol
|
||||
* Thursday, July 18, 2002
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
@ -284,7 +284,7 @@ herr_t
|
||||
H5AC_create(const H5F_t *f, H5AC_cache_config_t *config_ptr, H5AC_cache_image_config_t * image_config_ptr)
|
||||
{
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
char prefix[H5C__PREFIX_LEN] = "";
|
||||
char prefix[H5C__PREFIX_LEN] = "";
|
||||
H5AC_aux_t * aux_ptr = NULL;
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
struct H5C_cache_image_ctl_t int_ci_config = H5C__DEFAULT_CACHE_IMAGE_CTL;
|
||||
@ -309,9 +309,9 @@ H5AC_create(const H5F_t *f, H5AC_cache_config_t *config_ptr, H5AC_cache_image_co
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
if(H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI)) {
|
||||
MPI_Comm mpi_comm;
|
||||
int mpi_rank;
|
||||
int mpi_size;
|
||||
MPI_Comm mpi_comm;
|
||||
int mpi_rank;
|
||||
int mpi_size;
|
||||
|
||||
if(MPI_COMM_NULL == (mpi_comm = H5F_mpi_get_comm(f)))
|
||||
HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI communicator")
|
||||
@ -400,7 +400,7 @@ H5AC_create(const H5F_t *f, H5AC_cache_config_t *config_ptr, H5AC_cache_image_co
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
|
||||
if(NULL == f->shared->cache)
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "memory allocation failed")
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "memory allocation failed")
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
if(aux_ptr != NULL)
|
||||
@ -472,6 +472,14 @@ done:
|
||||
* matzke@llnl.gov
|
||||
* 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
|
||||
@ -497,58 +505,115 @@ H5AC_dest(H5F_t *f)
|
||||
#endif /* H5AC_DUMP_STATS_ON_CLOSE */
|
||||
|
||||
/* 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")
|
||||
if(log_enabled && curr_logging)
|
||||
if(log_enabled && curr_logging) {
|
||||
|
||||
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 */
|
||||
if(log_enabled)
|
||||
if(log_enabled) {
|
||||
|
||||
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
|
||||
|
||||
/* destroying the cache, so clear all collective entries */
|
||||
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);
|
||||
if(aux_ptr)
|
||||
|
||||
if(aux_ptr) {
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(aux_ptr->magic == H5AC__H5AC_AUX_T_MAGIC);
|
||||
|
||||
|
||||
/* If the file was opened R/W, attempt to flush all entries
|
||||
* from rank 0 & Bcast clean list to other ranks.
|
||||
*
|
||||
* Must not flush in the R/O case, as this will trigger the
|
||||
* free space manager settle routines.
|
||||
*/
|
||||
if(H5F_ACC_RDWR & H5F_INTENT(f))
|
||||
if(H5AC__flush_entries(f) < 0)
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush")
|
||||
/* If the file was opened R/W, attempt to flush all entries
|
||||
* from rank 0 & Bcast clean list to other ranks.
|
||||
*
|
||||
* Must not flush in the R/O case, as this will trigger the
|
||||
* free space manager settle routines.
|
||||
*
|
||||
* Must also enable the skip list before the call to
|
||||
* H5AC__flush_entries() and disable it afterwards, as the
|
||||
* 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 */
|
||||
|
||||
/* Destroy the cache */
|
||||
if(H5C_dest(f) < 0)
|
||||
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "can't destroy cache")
|
||||
|
||||
f->shared->cache = NULL;
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
|
||||
if(aux_ptr != NULL) {
|
||||
|
||||
if(aux_ptr->d_slist_ptr != NULL) {
|
||||
|
||||
HDassert(H5SL_count(aux_ptr->d_slist_ptr) == 0);
|
||||
H5SL_close(aux_ptr->d_slist_ptr);
|
||||
|
||||
} /* end if */
|
||||
|
||||
if(aux_ptr->c_slist_ptr != NULL) {
|
||||
|
||||
HDassert(H5SL_count(aux_ptr->c_slist_ptr) == 0);
|
||||
H5SL_close(aux_ptr->c_slist_ptr);
|
||||
|
||||
} /* end if */
|
||||
|
||||
if(aux_ptr->candidate_slist_ptr != NULL) {
|
||||
|
||||
HDassert(H5SL_count(aux_ptr->candidate_slist_ptr) == 0);
|
||||
H5SL_close(aux_ptr->candidate_slist_ptr);
|
||||
|
||||
} /* end if */
|
||||
|
||||
aux_ptr->magic = 0;
|
||||
aux_ptr = H5FL_FREE(H5AC_aux_t, aux_ptr);
|
||||
|
||||
} /* end if */
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
|
||||
@ -561,12 +626,12 @@ done:
|
||||
* Function: H5AC_evict
|
||||
*
|
||||
* Purpose: Evict all entries except the pinned entries
|
||||
* in the cache.
|
||||
* in the cache.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Vailin Choi
|
||||
* Dec 2013
|
||||
* Dec 2013
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -600,9 +665,9 @@ done:
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5AC_expunge_entry
|
||||
*
|
||||
* Purpose: Expunge the target entry from the cache without writing it
|
||||
* to disk even if it is dirty. The entry must not be either
|
||||
* pinned or protected.
|
||||
* Purpose: Expunge the target entry from the cache without writing it
|
||||
* to disk even if it is dirty. The entry must not be either
|
||||
* pinned or protected.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
@ -643,13 +708,13 @@ done:
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5AC_flush
|
||||
*
|
||||
* Purpose: Flush (and possibly destroy) the metadata cache associated
|
||||
* with the specified file.
|
||||
* Purpose: Flush (and possibly destroy) the metadata cache associated
|
||||
* with the specified file.
|
||||
*
|
||||
* If the cache contains protected entries, the function will
|
||||
* fail, as protected entries cannot be flushed. However
|
||||
* all unprotected entries should be flushed before the
|
||||
* function returns failure.
|
||||
* If the cache contains protected entries, the function will
|
||||
* fail, as protected entries cannot be flushed. However
|
||||
* all unprotected entries should be flushed before the
|
||||
* function returns failure.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure if there was a
|
||||
* request to flush all items and something was protected.
|
||||
@ -701,15 +766,15 @@ done:
|
||||
* Function: H5AC_get_entry_status
|
||||
*
|
||||
* Purpose: Given a file address, determine whether the metadata
|
||||
* cache contains an entry at that location. If it does,
|
||||
* also determine whether the entry is dirty, protected,
|
||||
* pinned, etc. and return that information to the caller
|
||||
* in *status.
|
||||
* cache contains an entry at that location. If it does,
|
||||
* also determine whether the entry is dirty, protected,
|
||||
* pinned, etc. and return that information to the caller
|
||||
* in *status.
|
||||
*
|
||||
* If the specified entry doesn't exist, set *status_ptr
|
||||
* to zero.
|
||||
* If the specified entry doesn't exist, set *status_ptr
|
||||
* to zero.
|
||||
*
|
||||
* On error, the value of *status is undefined.
|
||||
* On error, the value of *status is undefined.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
@ -721,14 +786,14 @@ done:
|
||||
herr_t
|
||||
H5AC_get_entry_status(const H5F_t *f, haddr_t addr, unsigned *status)
|
||||
{
|
||||
hbool_t in_cache; /* Entry @ addr is in the cache */
|
||||
hbool_t is_dirty; /* Entry @ addr is in the cache and dirty */
|
||||
hbool_t is_protected; /* Entry @ addr is in the cache and protected */
|
||||
hbool_t is_pinned; /* Entry @ addr is in the cache and pinned */
|
||||
hbool_t is_corked;
|
||||
hbool_t is_flush_dep_child; /* Entry @ addr is in the cache and is a flush dependency child */
|
||||
hbool_t is_flush_dep_parent; /* Entry @ addr is in the cache and is a flush dependency parent */
|
||||
hbool_t image_is_up_to_date; /* Entry @ addr is in the cache and has an up to date image */
|
||||
hbool_t in_cache; /* Entry @ addr is in the cache */
|
||||
hbool_t is_dirty; /* Entry @ addr is in the cache and dirty */
|
||||
hbool_t is_protected; /* Entry @ addr is in the cache and protected */
|
||||
hbool_t is_pinned; /* Entry @ addr is in the cache and pinned */
|
||||
hbool_t is_corked;
|
||||
hbool_t is_flush_dep_child; /* Entry @ addr is in the cache and is a flush dependency child */
|
||||
hbool_t is_flush_dep_parent; /* Entry @ addr is in the cache and is a flush dependency parent */
|
||||
hbool_t image_is_up_to_date; /* Entry @ addr is in the cache and has an up to date image */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
@ -741,21 +806,21 @@ H5AC_get_entry_status(const H5F_t *f, haddr_t addr, unsigned *status)
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_get_entry_status() failed")
|
||||
|
||||
if(in_cache) {
|
||||
*status |= H5AC_ES__IN_CACHE;
|
||||
if(is_dirty)
|
||||
*status |= H5AC_ES__IS_DIRTY;
|
||||
if(is_protected)
|
||||
*status |= H5AC_ES__IS_PROTECTED;
|
||||
if(is_pinned)
|
||||
*status |= H5AC_ES__IS_PINNED;
|
||||
if(is_corked)
|
||||
*status |= H5AC_ES__IS_CORKED;
|
||||
if(is_flush_dep_parent)
|
||||
*status |= H5AC_ES__IS_FLUSH_DEP_PARENT;
|
||||
if(is_flush_dep_child)
|
||||
*status |= H5AC_ES__IS_FLUSH_DEP_CHILD;
|
||||
if(image_is_up_to_date)
|
||||
*status |= H5AC_ES__IMAGE_IS_UP_TO_DATE;
|
||||
*status |= H5AC_ES__IN_CACHE;
|
||||
if(is_dirty)
|
||||
*status |= H5AC_ES__IS_DIRTY;
|
||||
if(is_protected)
|
||||
*status |= H5AC_ES__IS_PROTECTED;
|
||||
if(is_pinned)
|
||||
*status |= H5AC_ES__IS_PINNED;
|
||||
if(is_corked)
|
||||
*status |= H5AC_ES__IS_CORKED;
|
||||
if(is_flush_dep_parent)
|
||||
*status |= H5AC_ES__IS_FLUSH_DEP_PARENT;
|
||||
if(is_flush_dep_child)
|
||||
*status |= H5AC_ES__IS_FLUSH_DEP_CHILD;
|
||||
if(image_is_up_to_date)
|
||||
*status |= H5AC_ES__IMAGE_IS_UP_TO_DATE;
|
||||
} /* end if */
|
||||
else
|
||||
*status = 0;
|
||||
@ -875,8 +940,8 @@ done:
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5AC_mark_entry_dirty
|
||||
*
|
||||
* Purpose: Mark a pinned or protected entry as dirty. The target
|
||||
* entry MUST be either pinned, protected, or both.
|
||||
* Purpose: Mark a pinned or protected entry as dirty. The target
|
||||
* entry MUST be either pinned, protected, or both.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
@ -929,8 +994,8 @@ done:
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5AC_mark_entry_clean
|
||||
*
|
||||
* Purpose: Mark a pinned entry as clean. The target
|
||||
* entry MUST be pinned.
|
||||
* Purpose: Mark a pinned entry as clean. The target
|
||||
* entry MUST be pinned.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
@ -982,8 +1047,8 @@ done:
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5AC_mark_entry_unserialized
|
||||
*
|
||||
* Purpose: Mark a pinned or protected entry as unserialized. The target
|
||||
* entry MUST be either pinned, protected, or both.
|
||||
* Purpose: Mark a pinned or protected entry as unserialized. The target
|
||||
* entry MUST be either pinned, protected, or both.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
@ -1024,8 +1089,8 @@ done:
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5AC_mark_entry_serialized
|
||||
*
|
||||
* Purpose: Mark a pinned entry as serialized. The target
|
||||
* entry MUST be pinned.
|
||||
* Purpose: Mark a pinned entry as serialized. The target
|
||||
* entry MUST be pinned.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
@ -1124,7 +1189,7 @@ done:
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5AC_pin_protected_entry()
|
||||
*
|
||||
* Purpose: Pin a protected cache entry. The entry must be protected
|
||||
* Purpose: Pin a protected cache entry. The entry must be protected
|
||||
* at the time of call, and must be unpinned.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
@ -1203,9 +1268,112 @@ 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()
|
||||
*
|
||||
* Purpose: Create a flush dependency between two entries in the metadata
|
||||
* Purpose: Create a flush dependency between two entries in the metadata
|
||||
* cache.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
@ -1250,16 +1418,16 @@ done:
|
||||
* Function: H5AC_protect
|
||||
*
|
||||
* Purpose: If the target entry is not in the cache, load it. If
|
||||
* necessary, attempt to evict one or more entries to keep
|
||||
* the cache within its maximum size.
|
||||
* necessary, attempt to evict one or more entries to keep
|
||||
* the cache within its maximum size.
|
||||
*
|
||||
* Mark the target entry as protected, and return its address
|
||||
* to the caller. The caller must call H5AC_unprotect() when
|
||||
* finished with the entry.
|
||||
* Mark the target entry as protected, and return its address
|
||||
* to the caller. The caller must call H5AC_unprotect() when
|
||||
* finished with the entry.
|
||||
*
|
||||
* While it is protected, the entry may not be either evicted
|
||||
* or flushed -- nor may it be accessed by another call to
|
||||
* H5AC_protect. Any attempt to do so will result in a failure.
|
||||
* While it is protected, the entry may not be either evicted
|
||||
* or flushed -- nor may it be accessed by another call to
|
||||
* H5AC_protect. Any attempt to do so will result in a failure.
|
||||
*
|
||||
* Return: Success: Ptr to the object.
|
||||
* Failure: NULL
|
||||
@ -1301,7 +1469,7 @@ H5AC_protect(H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *udata,
|
||||
|
||||
/* Check for invalid access request */
|
||||
if((0 == (H5F_INTENT(f) & H5F_ACC_RDWR)) && (0 == (flags & H5C__READ_ONLY_FLAG)))
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "no write intent on file")
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "no write intent on file")
|
||||
|
||||
#if H5AC_DO_TAGGING_SANITY_CHECKS
|
||||
if(!H5C_get_ignore_tags(f->shared->cache) && H5AC__verify_tag(type) < 0)
|
||||
@ -1331,7 +1499,7 @@ done:
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5AC_resize_entry
|
||||
*
|
||||
* Purpose: Resize a pinned or protected entry.
|
||||
* Purpose: Resize a pinned or protected entry.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
@ -1384,8 +1552,8 @@ done:
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5AC_unpin_entry()
|
||||
*
|
||||
* Purpose: Unpin a cache entry. The entry must be unprotected at
|
||||
* the time of call, and must be pinned.
|
||||
* Purpose: Unpin a cache entry. The entry must be unprotected at
|
||||
* the time of call, and must be pinned.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
@ -1427,7 +1595,7 @@ done:
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5AC_destroy_flush_dependency()
|
||||
*
|
||||
* Purpose: Destroy a flush dependency between two entries.
|
||||
* Purpose: Destroy a flush dependency between two entries.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
@ -1470,27 +1638,27 @@ done:
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5AC_unprotect
|
||||
*
|
||||
* Purpose: Undo an H5AC_protect() call -- specifically, mark the
|
||||
* entry as unprotected, remove it from the protected list,
|
||||
* and give it back to the replacement policy.
|
||||
* Purpose: Undo an H5AC_protect() call -- specifically, mark the
|
||||
* entry as unprotected, remove it from the protected list,
|
||||
* and give it back to the replacement policy.
|
||||
*
|
||||
* The TYPE and ADDR arguments must be the same as those in
|
||||
* the corresponding call to H5AC_protect() and the THING
|
||||
* argument must be the value returned by that call to
|
||||
* H5AC_protect().
|
||||
* The TYPE and ADDR arguments must be the same as those in
|
||||
* the corresponding call to H5AC_protect() and the THING
|
||||
* argument must be the value returned by that call to
|
||||
* H5AC_protect().
|
||||
*
|
||||
* If the deleted flag is TRUE, simply remove the target entry
|
||||
* from the cache, clear it, and free it without writing it to
|
||||
* disk.
|
||||
* If the deleted flag is TRUE, simply remove the target entry
|
||||
* from the cache, clear it, and free it without writing it to
|
||||
* disk.
|
||||
*
|
||||
* This version of the function is a complete re-write to
|
||||
* use the new metadata cache. While there isn't all that
|
||||
* much difference between the old and new Purpose sections,
|
||||
* the original version is given below.
|
||||
* This version of the function is a complete re-write to
|
||||
* use the new metadata cache. While there isn't all that
|
||||
* much difference between the old and new Purpose sections,
|
||||
* the original version is given below.
|
||||
*
|
||||
* Original purpose section:
|
||||
* Original purpose section:
|
||||
*
|
||||
* This function should be called to undo the effect of
|
||||
* This function should be called to undo the effect of
|
||||
* H5AC_protect(). The TYPE and ADDR arguments should be the
|
||||
* same as the corresponding call to H5AC_protect() and the
|
||||
* THING argument should be the value returned by H5AC_protect().
|
||||
@ -1509,8 +1677,8 @@ herr_t
|
||||
H5AC_unprotect(H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing,
|
||||
unsigned flags)
|
||||
{
|
||||
hbool_t dirtied;
|
||||
hbool_t deleted;
|
||||
hbool_t dirtied;
|
||||
hbool_t deleted;
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
H5AC_aux_t * aux_ptr = NULL;
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
@ -1531,14 +1699,14 @@ H5AC_unprotect(H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing,
|
||||
HDassert( ((H5AC_info_t *)thing)->type == type );
|
||||
|
||||
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);
|
||||
|
||||
/* Check if the size changed out from underneath us, if we're not deleting
|
||||
* the entry.
|
||||
*/
|
||||
if(dirtied && !deleted) {
|
||||
size_t curr_size = 0;
|
||||
size_t curr_size = 0;
|
||||
|
||||
if((type->image_len)(thing, &curr_size) < 0)
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTGETSIZE, FAIL, "Can't get size of thing")
|
||||
@ -1625,7 +1793,7 @@ H5AC_get_cache_auto_resize_config(const H5AC_t *cache_ptr,
|
||||
if(internal_config.rpt_fcn == NULL)
|
||||
config_ptr->rpt_fcn_enabled = FALSE;
|
||||
else
|
||||
config_ptr->rpt_fcn_enabled = TRUE;
|
||||
config_ptr->rpt_fcn_enabled = TRUE;
|
||||
config_ptr->open_trace_file = FALSE;
|
||||
config_ptr->close_trace_file = FALSE;
|
||||
config_ptr->trace_file_name[0] = '\0';
|
||||
@ -1658,12 +1826,12 @@ H5AC_get_cache_auto_resize_config(const H5AC_t *cache_ptr,
|
||||
|
||||
if(NULL != (aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(cache_ptr))) {
|
||||
config_ptr->dirty_bytes_threshold = aux_ptr->dirty_bytes_threshold;
|
||||
config_ptr->metadata_write_strategy = aux_ptr->metadata_write_strategy;
|
||||
config_ptr->metadata_write_strategy = aux_ptr->metadata_write_strategy;
|
||||
} /* end if */
|
||||
else {
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
config_ptr->dirty_bytes_threshold = H5AC__DEFAULT_DIRTY_BYTES_THRESHOLD;
|
||||
config_ptr->metadata_write_strategy = H5AC__DEFAULT_METADATA_WRITE_STRATEGY;
|
||||
config_ptr->metadata_write_strategy = H5AC__DEFAULT_METADATA_WRITE_STRATEGY;
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
} /* end else */
|
||||
}
|
||||
@ -1800,7 +1968,7 @@ herr_t
|
||||
H5AC_set_cache_auto_resize_config(H5AC_t *cache_ptr, H5AC_cache_config_t *config_ptr)
|
||||
{
|
||||
H5C_auto_size_ctl_t internal_config;
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
|
||||
@ -1880,16 +2048,16 @@ done:
|
||||
* Function: H5AC_validate_config()
|
||||
*
|
||||
* Purpose: Run a sanity check on the contents of the supplied
|
||||
* instance of H5AC_cache_config_t.
|
||||
* instance of H5AC_cache_config_t.
|
||||
*
|
||||
* Do nothing and return SUCCEED if no errors are detected,
|
||||
* and flag an error and return FAIL otherwise.
|
||||
*
|
||||
* At present, this function operates by packing the data
|
||||
* from the instance of H5AC_cache_config_t into an instance
|
||||
* of H5C_auto_size_ctl_t, and then calling
|
||||
* H5C_validate_resize_config(). As H5AC_cache_config_t and
|
||||
* H5C_auto_size_ctl_t diverge, we may have to change this.
|
||||
* At present, this function operates by packing the data
|
||||
* from the instance of H5AC_cache_config_t into an instance
|
||||
* of H5C_auto_size_ctl_t, and then calling
|
||||
* H5C_validate_resize_config(). As H5AC_cache_config_t and
|
||||
* H5C_auto_size_ctl_t diverge, we may have to change this.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
@ -1914,7 +2082,7 @@ H5AC_validate_config(H5AC_cache_config_t *config_ptr)
|
||||
|
||||
/* don't bother to test trace_file_name unless open_trace_file is TRUE */
|
||||
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
|
||||
* open the file, so we will content ourselves with a couple of
|
||||
@ -1957,17 +2125,17 @@ done:
|
||||
* Function: H5AC_validate_cache_image_config()
|
||||
*
|
||||
* Purpose: Run a sanity check on the contents of the supplied
|
||||
* instance of H5AC_cache_image_config_t.
|
||||
* instance of H5AC_cache_image_config_t.
|
||||
*
|
||||
* Do nothing and return SUCCEED if no errors are detected,
|
||||
* and flag an error and return FAIL otherwise.
|
||||
*
|
||||
* At present, this function operates by packing the data
|
||||
* from the instance of H5AC_cache_image_config_t into an
|
||||
* instance of H5C_cache_image_ctl_t, and then calling
|
||||
* H5C_validate_cache_image_config(). If and when
|
||||
* At present, this function operates by packing the data
|
||||
* from the instance of H5AC_cache_image_config_t into an
|
||||
* instance of H5C_cache_image_ctl_t, and then calling
|
||||
* H5C_validate_cache_image_config(). If and when
|
||||
* H5AC_cache_image_config_t and H5C_cache_image_ctl_t
|
||||
* diverge, we may have to change this.
|
||||
* diverge, we may have to change this.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
@ -2013,13 +2181,13 @@ done:
|
||||
* Function: H5AC__check_if_write_permitted
|
||||
*
|
||||
* Purpose: Determine if a write is permitted under the current
|
||||
* circumstances, and set *write_permitted_ptr accordingly.
|
||||
* As a general rule it is, but when we are running in parallel
|
||||
* mode with collective I/O, we must ensure that a read cannot
|
||||
* cause a write.
|
||||
* circumstances, and set *write_permitted_ptr accordingly.
|
||||
* As a general rule it is, but when we are running in parallel
|
||||
* mode with collective I/O, we must ensure that a read cannot
|
||||
* cause a write.
|
||||
*
|
||||
* In the event of failure, the value of *write_permitted_ptr
|
||||
* is undefined.
|
||||
* In the event of failure, the value of *write_permitted_ptr
|
||||
* is undefined.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure.
|
||||
*
|
||||
@ -2035,9 +2203,9 @@ H5_ATTR_UNUSED
|
||||
*f, hbool_t *write_permitted_ptr)
|
||||
{
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
H5AC_aux_t * aux_ptr = NULL;
|
||||
H5AC_aux_t * aux_ptr = NULL;
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
hbool_t write_permitted = TRUE;
|
||||
hbool_t write_permitted = TRUE;
|
||||
|
||||
FUNC_ENTER_STATIC_NOERR
|
||||
|
||||
@ -2051,9 +2219,9 @@ H5_ATTR_UNUSED
|
||||
HDassert(aux_ptr->magic == H5AC__H5AC_AUX_T_MAGIC);
|
||||
|
||||
if((aux_ptr->mpi_rank == 0) || (aux_ptr->metadata_write_strategy == H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED))
|
||||
write_permitted = aux_ptr->write_permitted;
|
||||
write_permitted = aux_ptr->write_permitted;
|
||||
else
|
||||
write_permitted = FALSE;
|
||||
write_permitted = FALSE;
|
||||
} /* end if */
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
|
||||
@ -2067,12 +2235,12 @@ H5_ATTR_UNUSED
|
||||
* Function: H5AC__ext_config_2_int_config()
|
||||
*
|
||||
* Purpose: Utility function to translate an instance of
|
||||
* H5AC_cache_config_t to an instance of H5C_auto_size_ctl_t.
|
||||
* H5AC_cache_config_t to an instance of H5C_auto_size_ctl_t.
|
||||
*
|
||||
* Places translation in *int_conf_ptr and returns SUCCEED
|
||||
* if successful. Returns FAIL on failure.
|
||||
* Places translation in *int_conf_ptr and returns SUCCEED
|
||||
* if successful. Returns FAIL on failure.
|
||||
*
|
||||
* Does only minimal sanity checking.
|
||||
* Does only minimal sanity checking.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
@ -2453,7 +2621,7 @@ done:
|
||||
* Purpose: Given a file address, retrieve the ring for an entry at that
|
||||
* address.
|
||||
*
|
||||
* On error, the value of *ring is not modified.
|
||||
* On error, the value of *ring is not modified.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
@ -2531,11 +2699,11 @@ H5AC_set_ring(H5AC_ring_t ring, H5AC_ring_t *orig_ring)
|
||||
* are in the process of a file shutdown, post an error
|
||||
* message, and return FAIL.
|
||||
*
|
||||
* Note that this function simply passes the call on to
|
||||
* the metadata cache proper, and returns the result.
|
||||
* Note that this function simply passes the call on to
|
||||
* the metadata cache proper, and returns the result.
|
||||
*
|
||||
* Return: Success: Non-negative
|
||||
* Failure: Negative
|
||||
* Return: Success: Non-negative
|
||||
* Failure: Negative
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* September 17, 2016
|
||||
@ -2608,7 +2776,7 @@ done:
|
||||
* Function: H5AC_remove_entry()
|
||||
*
|
||||
* Purpose: Remove an entry from the cache. Must be not protected, pinned,
|
||||
* dirty, involved in flush dependencies, etc.
|
||||
* dirty, involved in flush dependencies, etc.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
@ -2669,4 +2837,3 @@ H5AC_get_mdc_image_info(H5AC_t *cache_ptr, haddr_t *image_addr, hsize_t *image_l
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* H5AC_get_mdc_image_info() */
|
||||
|
||||
|
@ -791,7 +791,7 @@ H5AC__log_dirtied_entry(const H5AC_info_t *entry_ptr)
|
||||
else {
|
||||
aux_ptr->dirty_bytes += entry_ptr->size;
|
||||
#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;
|
||||
#endif /* H5AC_DEBUG_DIRTY_BYTES_CREATION */
|
||||
} /* end else */
|
||||
@ -989,7 +989,7 @@ H5AC__log_inserted_entry(const H5AC_info_t *entry_ptr)
|
||||
aux_ptr->dirty_bytes += entry_ptr->size;
|
||||
|
||||
#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;
|
||||
#endif /* H5AC_DEBUG_DIRTY_BYTES_CREATION */
|
||||
|
||||
@ -1875,6 +1875,8 @@ done:
|
||||
* Programmer: John Mainzer
|
||||
* April 28, 2010
|
||||
*
|
||||
* Changes: None.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
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);
|
||||
HDassert(aux_ptr != NULL);
|
||||
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
|
||||
* 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,
|
||||
* it's possible to skip this barrier (on the second flush of the cache).
|
||||
*/
|
||||
if(!H5CX_get_mpi_file_flushing())
|
||||
if(MPI_SUCCESS != (mpi_result = MPI_Barrier(aux_ptr->mpi_comm)))
|
||||
if ( ! H5CX_get_mpi_file_flushing() ) {
|
||||
|
||||
if ( MPI_SUCCESS != (mpi_result = MPI_Barrier(aux_ptr->mpi_comm)) )
|
||||
|
||||
HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_result)
|
||||
}
|
||||
|
||||
/* Flush data to disk, from rank 0 process */
|
||||
if(aux_ptr->mpi_rank == 0) {
|
||||
@ -1921,23 +1927,30 @@ H5AC__rsp__p0_only__flush(H5F_t *f)
|
||||
aux_ptr->write_permitted = FALSE;
|
||||
|
||||
/* Check for error on the write operation */
|
||||
if(result < 0)
|
||||
if ( result < 0 )
|
||||
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush.")
|
||||
|
||||
/* this code exists primarily for the test bed -- it allows us to
|
||||
* enforce POSIX semantics on the server that pretends to be a
|
||||
* file system in our parallel tests.
|
||||
*/
|
||||
if(aux_ptr->write_done)
|
||||
if ( aux_ptr->write_done ) {
|
||||
|
||||
(aux_ptr->write_done)();
|
||||
}
|
||||
} /* end if */
|
||||
|
||||
/* Propagate cleaned entries to other ranks. */
|
||||
if(H5AC__propagate_flushed_and_still_clean_entries_list(f) < 0)
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't propagate clean entries list.")
|
||||
if ( H5AC__propagate_flushed_and_still_clean_entries_list(f) < 0 )
|
||||
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
|
||||
"Can't propagate clean entries list.")
|
||||
|
||||
done:
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
|
||||
} /* H5AC__rsp__p0_only__flush() */
|
||||
|
||||
|
||||
@ -2104,16 +2117,22 @@ H5AC__run_sync_point(H5F_t *f, int sync_point_op)
|
||||
|
||||
/* Sanity checks */
|
||||
HDassert(f != NULL);
|
||||
|
||||
cache_ptr = f->shared->cache;
|
||||
|
||||
HDassert(cache_ptr != NULL);
|
||||
|
||||
aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(cache_ptr);
|
||||
|
||||
HDassert(aux_ptr != NULL);
|
||||
HDassert(aux_ptr->magic == H5AC__H5AC_AUX_T_MAGIC);
|
||||
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
|
||||
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->dirty_bytes_propagations,
|
||||
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 */
|
||||
|
||||
done:
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* H5AC__run_sync_point() */
|
||||
|
||||
|
@ -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);
|
||||
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_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 void * H5AC_protect(H5F_t *f, const H5AC_class_t *type, haddr_t addr,
|
||||
void *udata, unsigned flags);
|
||||
|
47
src/H5Cdbg.c
47
src/H5Cdbg.c
@ -260,6 +260,7 @@ H5C_dump_cache_LRU(H5C_t *cache_ptr, const char *cache_name)
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* Function: H5C_dump_cache_skip_list
|
||||
*
|
||||
* Purpose: Debugging routine that prints a summary of the contents of
|
||||
@ -271,6 +272,12 @@ H5C_dump_cache_LRU(H5C_t *cache_ptr, const char *cache_name)
|
||||
* Programmer: John Mainzer
|
||||
* 11/15/14
|
||||
*
|
||||
* Changes: Updated function for the slist_enabled field in H6C_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
|
||||
@ -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(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 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 we get this far, all entries in the cache are listed in the
|
||||
* 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");
|
||||
|
||||
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 );
|
||||
|
||||
HDfprintf(stdout,
|
||||
@ -323,19 +342,27 @@ H5C_dump_cache_skip_list(H5C_t * cache_ptr, char * calling_fcn)
|
||||
node_ptr, H5SL_item(node_ptr));
|
||||
|
||||
/* increment node_ptr before we delete its target */
|
||||
|
||||
node_ptr = H5SL_next(node_ptr);
|
||||
if(node_ptr != NULL)
|
||||
|
||||
if ( node_ptr != NULL ) {
|
||||
|
||||
entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr);
|
||||
else
|
||||
|
||||
} else {
|
||||
|
||||
entry_ptr = NULL;
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
} /* end while */
|
||||
} /* end if */
|
||||
|
||||
HDfprintf(stdout, "\n\n");
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
|
||||
} /* H5C_dump_cache_skip_list() */
|
||||
#endif /* NDEBUG */
|
||||
|
||||
|
@ -461,6 +461,10 @@ done:
|
||||
*
|
||||
* Programmer: John Mainzer, 8/10/15
|
||||
*
|
||||
* Changes: Updated sanity checks for possibility that the slist
|
||||
* is disabled.
|
||||
* JRM -- 5/17/20
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
@ -700,9 +704,14 @@ H5C__deserialize_prefetched_entry(H5F_t *f, H5C_t *cache_ptr,
|
||||
* and H5C__FLUSH_CLEAR_ONLY_FLAG flags set.
|
||||
*/
|
||||
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;
|
||||
|
||||
} /* end if */
|
||||
|
||||
if(H5C__flush_single_entry(f, pf_entry_ptr, flush_flags) < 0)
|
||||
|
391
src/H5Cmpio.c
391
src/H5Cmpio.c
@ -18,7 +18,7 @@
|
||||
* Quincey Koziol
|
||||
*
|
||||
* Purpose: Functions in this file implement support for parallel I/O for
|
||||
* generic cache code.
|
||||
* generic cache code.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -28,20 +28,20 @@
|
||||
/****************/
|
||||
|
||||
#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 */
|
||||
|
||||
|
||||
/***********/
|
||||
/* Headers */
|
||||
/***********/
|
||||
#include "H5private.h" /* Generic Functions */
|
||||
#include "H5private.h" /* Generic Functions */
|
||||
#include "H5ACprivate.h" /* Metadata cache */
|
||||
#include "H5Cpkg.h" /* Cache */
|
||||
#include "H5Cpkg.h" /* Cache */
|
||||
#include "H5CXprivate.h" /* API Contexts */
|
||||
#include "H5Eprivate.h" /* Error handling */
|
||||
#include "H5Fpkg.h" /* Files */
|
||||
#include "H5FDprivate.h" /* File drivers */
|
||||
#include "H5MMprivate.h" /* Memory management */
|
||||
#include "H5Eprivate.h" /* Error handling */
|
||||
#include "H5Fpkg.h" /* Files */
|
||||
#include "H5FDprivate.h" /* File drivers */
|
||||
#include "H5MMprivate.h" /* Memory management */
|
||||
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
@ -87,74 +87,74 @@ static herr_t H5C__flush_candidates_in_ring(H5F_t *f, H5C_ring_t ring,
|
||||
*
|
||||
* Purpose: Apply the supplied candidate list.
|
||||
*
|
||||
* We used to do this by simply having each process write
|
||||
* every mpi_size-th entry in the candidate list, starting
|
||||
* at index mpi_rank, and mark all the others clean.
|
||||
* We used to do this by simply having each process write
|
||||
* every mpi_size-th entry in the candidate list, starting
|
||||
* at index mpi_rank, and mark all the others clean.
|
||||
*
|
||||
* However, this can cause unnecessary contention in a file
|
||||
* system by increasing the number of processes writing to
|
||||
* adjacent locations in the HDF5 file.
|
||||
* However, this can cause unnecessary contention in a file
|
||||
* system by increasing the number of processes writing to
|
||||
* adjacent locations in the HDF5 file.
|
||||
*
|
||||
* To attempt to minimize this, we now arange matters such
|
||||
* that each process writes n adjacent entries in the
|
||||
* candidate list, and marks all others clean. We must do
|
||||
* this in such a fashion as to guarantee that each entry
|
||||
* on the candidate list is written by exactly one process,
|
||||
* and marked clean by all others.
|
||||
* To attempt to minimize this, we now arange matters such
|
||||
* that each process writes n adjacent entries in the
|
||||
* candidate list, and marks all others clean. We must do
|
||||
* this in such a fashion as to guarantee that each entry
|
||||
* on the candidate list is written by exactly one process,
|
||||
* and marked clean by all others.
|
||||
*
|
||||
* To do this, first construct a table mapping mpi_rank
|
||||
* to the index of the first entry in the candidate list to
|
||||
* be written by the process of that mpi_rank, and then use
|
||||
* the table to control which entries are written and which
|
||||
* are marked as clean as a function of the mpi_rank.
|
||||
* To do this, first construct a table mapping mpi_rank
|
||||
* to the index of the first entry in the candidate list to
|
||||
* be written by the process of that mpi_rank, and then use
|
||||
* the table to control which entries are written and which
|
||||
* are marked as clean as a function of the mpi_rank.
|
||||
*
|
||||
* Note that the table must be identical on all processes, as
|
||||
* all see the same candidate list, mpi_size, and mpi_rank --
|
||||
* the inputs used to construct the table.
|
||||
* Note that the table must be identical on all processes, as
|
||||
* all see the same candidate list, mpi_size, and mpi_rank --
|
||||
* the inputs used to construct the table.
|
||||
*
|
||||
* 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,
|
||||
* and call this array candidate_assignment_table.
|
||||
* Now allocate an array of integers of length mpi_size + 1,
|
||||
* and call this array candidate_assignment_table.
|
||||
*
|
||||
* Conceptually, if the number of candidates is a multiple
|
||||
* of the mpi_size, we simply pass through the candidate list
|
||||
* and assign n entries to each process to flush, with the
|
||||
* index of the first entry to flush in the location in
|
||||
* the candidate_assignment_table indicated by the mpi_rank
|
||||
* of the process.
|
||||
* Conceptually, if the number of candidates is a multiple
|
||||
* of the mpi_size, we simply pass through the candidate list
|
||||
* and assign n entries to each process to flush, with the
|
||||
* index of the first entry to flush in the location in
|
||||
* the candidate_assignment_table indicated by the mpi_rank
|
||||
* of the process.
|
||||
*
|
||||
* In the more common case in which the candidate list isn't
|
||||
* isn't a multiple of the mpi_size, we pretend it is, and
|
||||
* give num_candidates % mpi_size processes one extra entry
|
||||
* each to make things work out.
|
||||
* In the more common case in which the candidate list isn't
|
||||
* isn't a multiple of the mpi_size, we pretend it is, and
|
||||
* give num_candidates % mpi_size processes one extra entry
|
||||
* each to make things work out.
|
||||
*
|
||||
* Once the table is constructed, we determine the first and
|
||||
* last entry this process is to flush as follows:
|
||||
* Once the table is constructed, we determine the first and
|
||||
* 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 =
|
||||
* candidate_assignment_table[mpi_rank + 1] - 1;
|
||||
* last_entry_to_flush =
|
||||
* candidate_assignment_table[mpi_rank + 1] - 1;
|
||||
*
|
||||
* With these values determined, we simply scan through the
|
||||
* candidate list, marking all entries in the range
|
||||
* [first_entry_to_flush, last_entry_to_flush] for flush,
|
||||
* and all others to be cleaned.
|
||||
* With these values determined, we simply scan through the
|
||||
* candidate list, marking all entries in the range
|
||||
* [first_entry_to_flush, last_entry_to_flush] for flush,
|
||||
* and all others to be cleaned.
|
||||
*
|
||||
* Finally, we scan the LRU from tail to head, flushing
|
||||
* or marking clean the candidate entries as indicated.
|
||||
* If necessary, we scan the pinned list as well.
|
||||
* Finally, we scan the LRU from tail to head, flushing
|
||||
* or marking clean the candidate entries as indicated.
|
||||
* If necessary, we scan the pinned list as well.
|
||||
*
|
||||
* Note that this function will fail if any protected or
|
||||
* clean entries appear on the candidate list.
|
||||
* Note that this function will fail if any protected or
|
||||
* clean entries appear on the candidate list.
|
||||
*
|
||||
* This function is used in managing sync points, and
|
||||
* shouldn't be used elsewhere.
|
||||
* This function is used in managing sync points, and
|
||||
* shouldn't be used elsewhere.
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
@ -163,6 +163,10 @@ static herr_t H5C__flush_candidates_in_ring(H5F_t *f, H5C_ring_t ring,
|
||||
* Programmer: John Mainzer
|
||||
* 3/17/10
|
||||
*
|
||||
* Changes: Updated sanity checks to allow for the possibility that
|
||||
* the slist is disabled.
|
||||
* JRM -- 8/3/20
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
@ -183,14 +187,17 @@ H5C_apply_candidate_list(H5F_t * f,
|
||||
unsigned * candidate_assignment_table = NULL;
|
||||
unsigned entries_to_flush[H5C_RING_NTYPES];
|
||||
unsigned entries_to_clear[H5C_RING_NTYPES];
|
||||
haddr_t addr;
|
||||
H5C_cache_entry_t * entry_ptr = NULL;
|
||||
haddr_t addr;
|
||||
H5C_cache_entry_t * entry_ptr = NULL;
|
||||
|
||||
#if H5C_DO_SANITY_CHECKS
|
||||
haddr_t last_addr;
|
||||
haddr_t last_addr;
|
||||
#endif /* H5C_DO_SANITY_CHECKS */
|
||||
|
||||
#if H5C_APPLY_CANDIDATE_LIST__DEBUG
|
||||
char tbl_buf[1024];
|
||||
char tbl_buf[1024];
|
||||
#endif /* H5C_APPLY_CANDIDATE_LIST__DEBUG */
|
||||
|
||||
unsigned u; /* Local index variable */
|
||||
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->magic == H5C__H5C_T_MAGIC);
|
||||
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(0 <= mpi_rank);
|
||||
HDassert(mpi_rank < mpi_size);
|
||||
@ -410,13 +418,14 @@ done:
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* Function: H5C_construct_candidate_list__clean_cache
|
||||
*
|
||||
* Purpose: Construct the list of entries that should be flushed to
|
||||
* clean all entries in the cache.
|
||||
* clean all entries in the cache.
|
||||
*
|
||||
* This function is used in managing sync points, and
|
||||
* shouldn't be used elsewhere.
|
||||
* This function is used in managing sync points, and
|
||||
* shouldn't be used elsewhere.
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
@ -425,6 +434,16 @@ done:
|
||||
* Programmer: John Mainzer
|
||||
* 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
|
||||
@ -438,60 +457,82 @@ H5C_construct_candidate_list__clean_cache(H5C_t * cache_ptr)
|
||||
HDassert( cache_ptr != NULL );
|
||||
HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
|
||||
|
||||
/* As a sanity check, set space needed to the size of the skip list.
|
||||
* This should be the sum total of the sizes of all the dirty entries
|
||||
* in the metadata cache.
|
||||
/* As a sanity check, set space needed to the dirty_index_size. This
|
||||
* should be the sum total of the sizes of all the dirty entries in
|
||||
* 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
|
||||
* point, it is possible that some dirty entries may reside on the
|
||||
* 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) );
|
||||
HDassert( cache_ptr->slist_len <=
|
||||
(cache_ptr->dLRU_list_len + cache_ptr->pel_len) );
|
||||
HDassert( ( ! cache_ptr->slist_enabled ) ||
|
||||
( cache_ptr->slist_len <=
|
||||
(cache_ptr->dLRU_list_len + cache_ptr->pel_len) ) );
|
||||
|
||||
|
||||
if(space_needed > 0) { /* we have work to do */
|
||||
|
||||
H5C_cache_entry_t *entry_ptr;
|
||||
unsigned nominated_entries_count = 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
|
||||
* entries to free up the necessary space.
|
||||
*/
|
||||
entry_ptr = cache_ptr->dLRU_tail_ptr;
|
||||
while((nominated_entries_size < space_needed) &&
|
||||
(nominated_entries_count < cache_ptr->slist_len) &&
|
||||
(entry_ptr != NULL)) {
|
||||
|
||||
while ( ( nominated_entries_size < space_needed ) &&
|
||||
( ( ! cache_ptr->slist_enabled ) ||
|
||||
( nominated_entries_count < cache_ptr->slist_len ) ) &&
|
||||
( entry_ptr != NULL ) ) {
|
||||
|
||||
HDassert( ! (entry_ptr->is_protected) );
|
||||
HDassert( ! (entry_ptr->is_read_only) );
|
||||
HDassert( entry_ptr->ro_ref_count == 0 );
|
||||
HDassert( entry_ptr->is_dirty );
|
||||
HDassert( entry_ptr->in_slist );
|
||||
HDassert( ( ! cache_ptr->slist_enabled ) ||
|
||||
( entry_ptr->in_slist ) );
|
||||
|
||||
nominated_addr = entry_ptr->addr;
|
||||
|
||||
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_count++;
|
||||
entry_ptr = entry_ptr->aux_prev;
|
||||
|
||||
} /* end while */
|
||||
|
||||
HDassert( entry_ptr == NULL );
|
||||
|
||||
/* it is possible that there are some dirty entries on the
|
||||
* protected entry list as well -- scan it too if necessary
|
||||
*/
|
||||
entry_ptr = cache_ptr->pel_head_ptr;
|
||||
while((nominated_entries_size < space_needed) &&
|
||||
(nominated_entries_count < cache_ptr->slist_len) &&
|
||||
(entry_ptr != NULL)) {
|
||||
|
||||
while ( ( nominated_entries_size < space_needed ) &&
|
||||
( ( ! cache_ptr->slist_enabled ) ||
|
||||
( nominated_entries_count < cache_ptr->slist_len ) ) &&
|
||||
( entry_ptr != NULL ) ) {
|
||||
|
||||
if(entry_ptr->is_dirty) {
|
||||
|
||||
HDassert( ! (entry_ptr->is_protected) );
|
||||
HDassert( ! (entry_ptr->is_read_only) );
|
||||
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 );
|
||||
|
||||
nominated_addr = entry_ptr->addr;
|
||||
|
||||
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_count++;
|
||||
|
||||
} /* end if */
|
||||
|
||||
entry_ptr = entry_ptr->next;
|
||||
|
||||
} /* 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 );
|
||||
|
||||
} /* end if */
|
||||
|
||||
done:
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
|
||||
} /* H5C_construct_candidate_list__clean_cache() */
|
||||
|
||||
|
||||
@ -522,10 +572,10 @@ done:
|
||||
* Function: H5C_construct_candidate_list__min_clean
|
||||
*
|
||||
* Purpose: Construct the list of entries that should be flushed to
|
||||
* get the cache back within its min clean constraints.
|
||||
* get the cache back within its min clean constraints.
|
||||
*
|
||||
* This function is used in managing sync points, and
|
||||
* shouldn't be used elsewhere.
|
||||
* This function is used in managing sync points, and
|
||||
* shouldn't be used elsewhere.
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
@ -534,6 +584,12 @@ done:
|
||||
* Programmer: John Mainzer
|
||||
* 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
|
||||
@ -551,54 +607,77 @@ H5C_construct_candidate_list__min_clean(H5C_t * cache_ptr)
|
||||
* 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) +
|
||||
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;
|
||||
else
|
||||
|
||||
} else {
|
||||
|
||||
space_needed = cache_ptr->min_clean_size -
|
||||
((cache_ptr->max_cache_size - cache_ptr->index_size) +
|
||||
cache_ptr->cLRU_list_size);
|
||||
}
|
||||
} /* end if */
|
||||
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;
|
||||
else
|
||||
|
||||
} else {
|
||||
|
||||
space_needed = cache_ptr->min_clean_size -
|
||||
cache_ptr->cLRU_list_size;
|
||||
}
|
||||
} /* end else */
|
||||
|
||||
if(space_needed > 0) { /* we have work to do */
|
||||
|
||||
H5C_cache_entry_t *entry_ptr;
|
||||
unsigned nominated_entries_count = 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
|
||||
* entries to free up the necessary space.
|
||||
*/
|
||||
entry_ptr = cache_ptr->dLRU_tail_ptr;
|
||||
while((nominated_entries_size < space_needed) &&
|
||||
(nominated_entries_count < cache_ptr->slist_len) &&
|
||||
(entry_ptr != NULL) &&
|
||||
(!entry_ptr->flush_me_last)) {
|
||||
haddr_t nominated_addr;
|
||||
|
||||
while ( ( nominated_entries_size < space_needed ) &&
|
||||
( ( ! cache_ptr->slist_enabled ) ||
|
||||
( nominated_entries_count < cache_ptr->slist_len ) ) &&
|
||||
( entry_ptr != NULL ) &&
|
||||
( ! entry_ptr->flush_me_last ) ) {
|
||||
|
||||
haddr_t nominated_addr;
|
||||
|
||||
HDassert( ! (entry_ptr->is_protected) );
|
||||
HDassert( ! (entry_ptr->is_read_only) );
|
||||
HDassert( entry_ptr->ro_ref_count == 0 );
|
||||
HDassert( entry_ptr->is_dirty );
|
||||
HDassert( entry_ptr->in_slist );
|
||||
HDassert( ( ! cache_ptr->slist_enabled ) ||
|
||||
( entry_ptr->in_slist ) );
|
||||
|
||||
nominated_addr = entry_ptr->addr;
|
||||
|
||||
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_count++;
|
||||
entry_ptr = entry_ptr->aux_prev;
|
||||
|
||||
} /* 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 );
|
||||
} /* end if */
|
||||
|
||||
@ -612,24 +691,24 @@ done:
|
||||
* Function: H5C_mark_entries_as_clean
|
||||
*
|
||||
* Purpose: When the H5C code is used to implement the metadata caches
|
||||
* in PHDF5, only the cache with MPI_rank 0 is allowed to
|
||||
* actually write entries to disk -- all other caches must
|
||||
* retain dirty entries until they are advised that the
|
||||
* entries are clean.
|
||||
* in PHDF5, only the cache with MPI_rank 0 is allowed to
|
||||
* actually write entries to disk -- all other caches must
|
||||
* retain dirty entries until they are advised that the
|
||||
* entries are clean.
|
||||
*
|
||||
* This function exists to allow the H5C code to receive these
|
||||
* notifications.
|
||||
* This function exists to allow the H5C code to receive these
|
||||
* notifications.
|
||||
*
|
||||
* The function receives a list of entry base addresses
|
||||
* which must refer to dirty entries in the cache. If any
|
||||
* of the entries are either clean or don't exist, the
|
||||
* function flags an error.
|
||||
* The function receives a list of entry base addresses
|
||||
* which must refer to dirty entries in the cache. If any
|
||||
* of the entries are either clean or don't exist, the
|
||||
* function flags an error.
|
||||
*
|
||||
* The function scans the list of entries and flushes all
|
||||
* those that are currently unprotected with the
|
||||
* H5C__FLUSH_CLEAR_ONLY_FLAG. Those that are currently
|
||||
* protected are flagged for clearing when they are
|
||||
* unprotected.
|
||||
* The function scans the list of entries and flushes all
|
||||
* those that are currently unprotected with the
|
||||
* H5C__FLUSH_CLEAR_ONLY_FLAG. Those that are currently
|
||||
* protected are flagged for clearing when they are
|
||||
* unprotected.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
@ -644,22 +723,22 @@ H5C_mark_entries_as_clean(H5F_t * f,
|
||||
haddr_t * ce_array_ptr)
|
||||
{
|
||||
H5C_t * cache_ptr;
|
||||
unsigned entries_cleared;
|
||||
unsigned entries_cleared;
|
||||
unsigned pinned_entries_cleared;
|
||||
hbool_t progress;
|
||||
unsigned entries_examined;
|
||||
unsigned initial_list_len;
|
||||
haddr_t addr;
|
||||
unsigned pinned_entries_marked = 0;
|
||||
unsigned entries_examined;
|
||||
unsigned initial_list_len;
|
||||
haddr_t addr;
|
||||
unsigned pinned_entries_marked = 0;
|
||||
#if H5C_DO_SANITY_CHECKS
|
||||
unsigned protected_entries_marked = 0;
|
||||
unsigned other_entries_marked = 0;
|
||||
haddr_t last_addr;
|
||||
unsigned protected_entries_marked = 0;
|
||||
unsigned other_entries_marked = 0;
|
||||
haddr_t last_addr;
|
||||
#endif /* H5C_DO_SANITY_CHECKS */
|
||||
H5C_cache_entry_t * clear_ptr = NULL;
|
||||
H5C_cache_entry_t * entry_ptr = NULL;
|
||||
H5C_cache_entry_t * clear_ptr = NULL;
|
||||
H5C_cache_entry_t * entry_ptr = NULL;
|
||||
unsigned u;
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
|
||||
@ -706,7 +785,7 @@ H5C_mark_entries_as_clean(H5F_t * f,
|
||||
|
||||
if(entry_ptr == NULL) {
|
||||
#if H5C_DO_SANITY_CHECKS
|
||||
HDfprintf(stdout,
|
||||
HDfprintf(stdout,
|
||||
"H5C_mark_entries_as_clean: entry[%u] = %a not in cache.\n",
|
||||
u,
|
||||
addr);
|
||||
@ -715,7 +794,7 @@ H5C_mark_entries_as_clean(H5F_t * f,
|
||||
} /* end if */
|
||||
else if(!entry_ptr->is_dirty) {
|
||||
#if H5C_DO_SANITY_CHECKS
|
||||
HDfprintf(stdout,
|
||||
HDfprintf(stdout,
|
||||
"H5C_mark_entries_as_clean: entry %a is not dirty!?!\n",
|
||||
addr);
|
||||
#endif /* H5C_DO_SANITY_CHECKS */
|
||||
@ -735,13 +814,13 @@ H5C_mark_entries_as_clean(H5F_t * f,
|
||||
} /* end if */
|
||||
|
||||
entry_ptr->clear_on_unprotect = TRUE;
|
||||
if(entry_ptr->is_pinned)
|
||||
pinned_entries_marked++;
|
||||
if(entry_ptr->is_pinned)
|
||||
pinned_entries_marked++;
|
||||
#if H5C_DO_SANITY_CHECKS
|
||||
else if(entry_ptr->is_protected)
|
||||
protected_entries_marked++;
|
||||
else
|
||||
other_entries_marked++;
|
||||
else if(entry_ptr->is_protected)
|
||||
protected_entries_marked++;
|
||||
else
|
||||
other_entries_marked++;
|
||||
#endif /* H5C_DO_SANITY_CHECKS */
|
||||
}
|
||||
}
|
||||
@ -769,7 +848,7 @@ H5C_mark_entries_as_clean(H5F_t * f,
|
||||
* of the pre_serialize / serialize routines, this may
|
||||
* cease to be the case -- requiring a review of this
|
||||
* point.
|
||||
* JRM -- 4/7/15
|
||||
* JRM -- 4/7/15
|
||||
*/
|
||||
entries_cleared = 0;
|
||||
entries_examined = 0;
|
||||
@ -873,9 +952,9 @@ done:
|
||||
herr_t
|
||||
H5C_clear_coll_entries(H5C_t *cache_ptr, hbool_t partial)
|
||||
{
|
||||
uint32_t clear_cnt;
|
||||
H5C_cache_entry_t * entry_ptr = NULL;
|
||||
herr_t ret_value = SUCCEED;
|
||||
uint32_t clear_cnt;
|
||||
H5C_cache_entry_t * entry_ptr = NULL;
|
||||
herr_t ret_value = SUCCEED;
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT
|
||||
|
||||
@ -1084,7 +1163,7 @@ done:
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5C__flush_candidate_entries
|
||||
*
|
||||
* Purpose: Flush or clear (as indicated) the candidate entries that
|
||||
* Purpose: Flush or clear (as indicated) the candidate entries that
|
||||
* have been marked in the metadata cache. In so doing,
|
||||
* observe rings and flush dependencies.
|
||||
*
|
||||
@ -1113,9 +1192,9 @@ done:
|
||||
* Return: Non-negative on success/Negative on failure.
|
||||
*
|
||||
* Programmer: John Mainzer
|
||||
* 2/10/17
|
||||
* 2/10/17
|
||||
*
|
||||
* Changes: None.
|
||||
* Changes: None.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -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])
|
||||
{
|
||||
#if H5C_DO_SANITY_CHECKS
|
||||
int i;
|
||||
uint32_t index_len = 0;
|
||||
size_t index_size = (size_t)0;
|
||||
size_t clean_index_size = (size_t)0;
|
||||
size_t dirty_index_size = (size_t)0;
|
||||
size_t slist_size = (size_t)0;
|
||||
uint32_t slist_len = 0;
|
||||
int i;
|
||||
uint32_t index_len = 0;
|
||||
size_t index_size = (size_t)0;
|
||||
size_t clean_index_size = (size_t)0;
|
||||
size_t dirty_index_size = (size_t)0;
|
||||
size_t slist_size = (size_t)0;
|
||||
uint32_t slist_len = 0;
|
||||
#endif /* H5C_DO_SANITY_CHECKS */
|
||||
H5C_ring_t ring;
|
||||
H5C_ring_t ring;
|
||||
H5C_t * cache_ptr;
|
||||
herr_t ret_value = SUCCEED;
|
||||
herr_t ret_value = SUCCEED;
|
||||
|
||||
FUNC_ENTER_STATIC
|
||||
|
||||
@ -1164,7 +1243,7 @@ H5C__flush_candidate_entries(H5F_t *f, unsigned entries_to_flush[H5C_RING_NTYPES
|
||||
clean_index_size += cache_ptr->clean_index_ring_size[i];
|
||||
dirty_index_size += cache_ptr->dirty_index_ring_size[i];
|
||||
|
||||
slist_len += cache_ptr->slist_ring_len[i];
|
||||
slist_len += cache_ptr->slist_ring_len[i];
|
||||
slist_size += cache_ptr->slist_ring_size[i];
|
||||
} /* end for */
|
||||
|
||||
@ -1206,7 +1285,7 @@ done:
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5C__flush_candidates_in_ring
|
||||
*
|
||||
* Purpose: Flush or clear (as indicated) the candidate entries
|
||||
* Purpose: Flush or clear (as indicated) the candidate entries
|
||||
* contained in the specified cache and ring. All candidate
|
||||
* entries in rings outside the specified ring must have been
|
||||
* flushed (or cleared) on entry.
|
||||
@ -1235,7 +1314,7 @@ done:
|
||||
* Return: Non-negative on success/Negative on failure.
|
||||
*
|
||||
* Programmer: John Mainzer
|
||||
* 2/10/17
|
||||
* 2/10/17
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
471
src/H5Cpkg.h
471
src/H5Cpkg.h
@ -47,13 +47,22 @@
|
||||
/* Number of epoch markers active */
|
||||
#define H5C__MAX_EPOCH_MARKERS 10
|
||||
|
||||
|
||||
/* Cache configuration settings */
|
||||
#define H5C__HASH_TABLE_LEN (64 * 1024) /* must be a power of 2 */
|
||||
#define H5C__H5C_T_MAGIC 0x005CAC0E
|
||||
|
||||
|
||||
/* Initial allocated size of the "flush_dep_parent" array */
|
||||
#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
|
||||
@ -1568,49 +1577,82 @@ if ( ( (cache_ptr)->index_size != \
|
||||
* Added code to maintain the cache_ptr->slist_ring_len
|
||||
* 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
|
||||
|
||||
#define ENTRY_IN_SLIST(cache_ptr, entry_ptr) \
|
||||
H5C_entry_in_skip_list((cache_ptr), (entry_ptr))
|
||||
|
||||
#else /* H5C_DO_SLIST_SANITY_CHECKS */
|
||||
|
||||
#define ENTRY_IN_SLIST(cache_ptr, entry_ptr) FALSE
|
||||
|
||||
#endif /* H5C_DO_SLIST_SANITY_CHECKS */
|
||||
|
||||
|
||||
#if H5C_DO_SANITY_CHECKS
|
||||
|
||||
#define H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr, fail_val) \
|
||||
{ \
|
||||
HDassert( (cache_ptr) ); \
|
||||
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) \
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, (fail_val), "can't insert entry in skip list") \
|
||||
if ( (cache_ptr)->slist_enabled ) { \
|
||||
\
|
||||
(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( (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 ); \
|
||||
\
|
||||
HDassert( (cache_ptr)->slist_len > 0 ); \
|
||||
HDassert( (cache_ptr)->slist_size > 0 ); \
|
||||
if ( H5SL_insert((cache_ptr)->slist_ptr, entry_ptr, \
|
||||
&((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 */
|
||||
|
||||
#else /* H5C_DO_SANITY_CHECKS */
|
||||
@ -1619,31 +1661,42 @@ if ( ( (cache_ptr)->index_size != \
|
||||
{ \
|
||||
HDassert( (cache_ptr) ); \
|
||||
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) \
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, (fail_val), "can't insert entry in skip list") \
|
||||
if ( (cache_ptr)->slist_enabled ) { \
|
||||
\
|
||||
(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( (entry_ptr) ); \
|
||||
HDassert( (entry_ptr)->size > 0 ); \
|
||||
HDassert( ! ENTRY_IN_SLIST((cache_ptr), (entry_ptr)) ); \
|
||||
HDassert( H5F_addr_defined((entry_ptr)->addr) ); \
|
||||
HDassert( !((entry_ptr)->in_slist) ); \
|
||||
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 ); \
|
||||
HDassert( (cache_ptr)->slist_size > 0 ); \
|
||||
if ( H5SL_insert((cache_ptr)->slist_ptr, entry_ptr, \
|
||||
&((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 */
|
||||
|
||||
#endif /* H5C_DO_SANITY_CHECKS */
|
||||
@ -1661,80 +1714,129 @@ if ( ( (cache_ptr)->index_size != \
|
||||
*
|
||||
* 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
|
||||
#define H5C__REMOVE_ENTRY_FROM_SLIST(cache_ptr, entry_ptr, during_flush) \
|
||||
{ \
|
||||
HDassert( (cache_ptr) ); \
|
||||
HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \
|
||||
HDassert( (entry_ptr) ); \
|
||||
HDassert( !((entry_ptr)->is_read_only) ); \
|
||||
HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \
|
||||
HDassert( (entry_ptr)->size > 0 ); \
|
||||
HDassert( (entry_ptr)->in_slist ); \
|
||||
HDassert( (cache_ptr)->slist_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_remove((cache_ptr)->slist_ptr, &(entry_ptr)->addr) \
|
||||
!= (entry_ptr) ) \
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "can't delete entry from skip list") \
|
||||
\
|
||||
HDassert( (cache_ptr)->slist_len > 0 ); \
|
||||
if(!(during_flush)) \
|
||||
(cache_ptr)->slist_changed = TRUE; \
|
||||
(cache_ptr)->slist_len--; \
|
||||
HDassert( (cache_ptr)->slist_size >= (entry_ptr)->size ); \
|
||||
(cache_ptr)->slist_size -= (entry_ptr)->size; \
|
||||
((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; \
|
||||
(cache_ptr)->slist_len_increase--; \
|
||||
(cache_ptr)->slist_size_increase -= (int64_t)((entry_ptr)->size); \
|
||||
(entry_ptr)->in_slist = FALSE; \
|
||||
#define H5C__REMOVE_ENTRY_FROM_SLIST(cache_ptr, entry_ptr, during_flush) \
|
||||
{ \
|
||||
HDassert( (cache_ptr) ); \
|
||||
HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \
|
||||
\
|
||||
if ( (cache_ptr)->slist_enabled ) { \
|
||||
\
|
||||
HDassert( (entry_ptr) ); \
|
||||
HDassert( !((entry_ptr)->is_read_only) ); \
|
||||
HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \
|
||||
HDassert( (entry_ptr)->size > 0 ); \
|
||||
HDassert( (entry_ptr)->in_slist ); \
|
||||
HDassert( (cache_ptr)->slist_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 ); \
|
||||
HDassert( (cache_ptr)->slist_size >= (entry_ptr)->size ); \
|
||||
\
|
||||
if ( H5SL_remove((cache_ptr)->slist_ptr, &(entry_ptr)->addr) \
|
||||
!= (entry_ptr) ) \
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, \
|
||||
"can't delete entry from skip list") \
|
||||
\
|
||||
HDassert( (cache_ptr)->slist_len > 0 ); \
|
||||
if(!(during_flush)) \
|
||||
(cache_ptr)->slist_changed = TRUE; \
|
||||
(cache_ptr)->slist_len--; \
|
||||
HDassert( (cache_ptr)->slist_size >= (entry_ptr)->size ); \
|
||||
(cache_ptr)->slist_size -= (entry_ptr)->size; \
|
||||
((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;\
|
||||
(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 */
|
||||
|
||||
#else /* H5C_DO_SANITY_CHECKS */
|
||||
|
||||
#define H5C__REMOVE_ENTRY_FROM_SLIST(cache_ptr, entry_ptr, during_flush) \
|
||||
{ \
|
||||
HDassert( (cache_ptr) ); \
|
||||
HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \
|
||||
HDassert( (entry_ptr) ); \
|
||||
HDassert( !((entry_ptr)->is_read_only) ); \
|
||||
HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \
|
||||
HDassert( (entry_ptr)->in_slist ); \
|
||||
HDassert( (cache_ptr)->slist_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_remove((cache_ptr)->slist_ptr, &(entry_ptr)->addr) \
|
||||
!= (entry_ptr) ) \
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "can't delete entry from skip list") \
|
||||
\
|
||||
HDassert( (cache_ptr)->slist_len > 0 ); \
|
||||
if(!(during_flush)) \
|
||||
(cache_ptr)->slist_changed = TRUE; \
|
||||
(cache_ptr)->slist_len--; \
|
||||
HDassert( (cache_ptr)->slist_size >= (entry_ptr)->size ); \
|
||||
(cache_ptr)->slist_size -= (entry_ptr)->size; \
|
||||
((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; \
|
||||
#define H5C__REMOVE_ENTRY_FROM_SLIST(cache_ptr, entry_ptr, during_flush) \
|
||||
{ \
|
||||
HDassert( (cache_ptr) ); \
|
||||
HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \
|
||||
\
|
||||
if ( (cache_ptr)->slist_enabled ) { \
|
||||
\
|
||||
HDassert( (entry_ptr) ); \
|
||||
HDassert( !((entry_ptr)->is_read_only) ); \
|
||||
HDassert( ((entry_ptr)->ro_ref_count) == 0 ); \
|
||||
HDassert( (entry_ptr)->in_slist ); \
|
||||
HDassert( (cache_ptr)->slist_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_remove((cache_ptr)->slist_ptr, &(entry_ptr)->addr) \
|
||||
!= (entry_ptr) ) \
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, \
|
||||
"can't delete entry from skip list") \
|
||||
\
|
||||
HDassert( (cache_ptr)->slist_len > 0 ); \
|
||||
if(!(during_flush)) \
|
||||
(cache_ptr)->slist_changed = TRUE; \
|
||||
(cache_ptr)->slist_len--; \
|
||||
HDassert( (cache_ptr)->slist_size >= (entry_ptr)->size ); \
|
||||
(cache_ptr)->slist_size -= (entry_ptr)->size; \
|
||||
((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 */
|
||||
|
||||
#endif /* H5C_DO_SANITY_CHECKS */
|
||||
|
||||
|
||||
@ -1770,6 +1872,12 @@ if ( ( (cache_ptr)->index_size != \
|
||||
* Added code to maintain the cache_ptr->slist_ring_len
|
||||
* 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)->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); \
|
||||
(cache_ptr)->slist_size += (new_size); \
|
||||
if ( (cache_ptr)->slist_enabled ) { \
|
||||
\
|
||||
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( (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_increase -= (int64_t)(old_size); \
|
||||
(cache_ptr)->slist_size_increase += (int64_t)(new_size); \
|
||||
(cache_ptr)->slist_size -= (old_size); \
|
||||
(cache_ptr)->slist_size += (new_size); \
|
||||
\
|
||||
HDassert( (new_size) <= (cache_ptr)->slist_size ); \
|
||||
HDassert( ( (cache_ptr)->slist_len > 1 ) || \
|
||||
( (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); \
|
||||
\
|
||||
(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 */
|
||||
|
||||
#else /* H5C_DO_SANITY_CHECKS */
|
||||
@ -1813,29 +1932,39 @@ if ( ( (cache_ptr)->index_size != \
|
||||
{ \
|
||||
HDassert( (cache_ptr) ); \
|
||||
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); \
|
||||
(cache_ptr)->slist_size += (new_size); \
|
||||
if ( (cache_ptr)->slist_enabled ) { \
|
||||
\
|
||||
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( (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 ); \
|
||||
\
|
||||
HDassert( (new_size) <= (cache_ptr)->slist_size ); \
|
||||
HDassert( ( (cache_ptr)->slist_len > 1 ) || \
|
||||
( (cache_ptr)->slist_size == (new_size) ) ); \
|
||||
(cache_ptr)->slist_size -= (old_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 */
|
||||
|
||||
#endif /* H5C_DO_SANITY_CHECKS */
|
||||
@ -3726,7 +3855,8 @@ typedef struct H5C_tag_info_t {
|
||||
* which contains the 'next' entry for an iteration. Removing
|
||||
* this entry must trigger a rescan of the iteration, so each
|
||||
* 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")
|
||||
*
|
||||
*
|
||||
@ -3740,6 +3870,36 @@ typedef struct H5C_tag_info_t {
|
||||
* are flushed. (this has been changed -- dirty entries are now removed from
|
||||
* 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
|
||||
* the slist has changed since the last time this flag was
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
struct H5C_t {
|
||||
uint32_t magic;
|
||||
hbool_t flush_in_progress;
|
||||
@ -4664,7 +4825,7 @@ struct H5C_t {
|
||||
hbool_t evictions_enabled;
|
||||
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;
|
||||
size_t index_size;
|
||||
uint32_t index_ring_len[H5C_RING_NTYPES];
|
||||
@ -4685,6 +4846,7 @@ struct H5C_t {
|
||||
H5C_cache_entry_t * entry_watched_for_removal;
|
||||
|
||||
/* Fields for maintaining list of in-order entries, for flushing */
|
||||
hbool_t slist_enabled;
|
||||
hbool_t slist_changed;
|
||||
uint32_t slist_len;
|
||||
size_t slist_size;
|
||||
@ -4882,7 +5044,8 @@ struct H5C_t {
|
||||
#ifndef NDEBUG
|
||||
int64_t get_entry_ptr_from_addr_counter;
|
||||
#endif /* NDEBUG */
|
||||
};
|
||||
|
||||
}; /* H5C_t */
|
||||
|
||||
/* Define typedef for tagged cache entry iteration callbacks */
|
||||
typedef int (*H5C_tag_iter_cb_t)(H5C_cache_entry_t *entry, void *ctx);
|
||||
|
@ -2288,7 +2288,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_image_config(const H5F_t *f, H5C_t *cache_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_stats(H5C_t *cache_ptr, const char *cache_name,
|
||||
hbool_t display_detailed_stats);
|
||||
|
10
src/H5Fint.c
10
src/H5Fint.c
@ -1914,6 +1914,11 @@ H5F__flush_phase2(H5F_t *f, hbool_t closing)
|
||||
/* Sanity check arguments */
|
||||
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 */
|
||||
if(H5AC_flush(f) < 0)
|
||||
/* Push error, but keep going*/
|
||||
@ -1946,6 +1951,11 @@ H5F__flush_phase2(H5F_t *f, hbool_t closing)
|
||||
H5CX_set_mpi_file_flushing(FALSE);
|
||||
#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 */
|
||||
if(H5F__accum_flush(f->shared) < 0)
|
||||
/* Push error, but keep going*/
|
||||
|
2081
test/cache.c
2081
test/cache.c
File diff suppressed because it is too large
Load Diff
@ -3111,12 +3111,25 @@ expunge_entry(H5F_t * file_ptr,
|
||||
* Function: flush_cache()
|
||||
*
|
||||
* Purpose: Flush the specified cache, destroying all entries if
|
||||
requested. If requested, dump stats first.
|
||||
* requested. If requested, dump stats first.
|
||||
*
|
||||
* Return: void
|
||||
*
|
||||
* 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;
|
||||
|
||||
if(destroy_entries)
|
||||
result = H5C_flush_cache(file_ptr, H5C__FLUSH_INVALIDATE_FLAG);
|
||||
if ( destroy_entries ) {
|
||||
|
||||
else
|
||||
result = H5C_flush_cache(file_ptr, H5C__NO_FLAGS_SET);
|
||||
H5C_FLUSH_CACHE(file_ptr, H5C__FLUSH_INVALIDATE_FLAG, \
|
||||
"error in H5C_flush_cache().")
|
||||
|
||||
if(dump_stats)
|
||||
H5C_stats(cache_ptr, "test cache", dump_detailed_stats);
|
||||
} else {
|
||||
|
||||
if(result < 0) {
|
||||
pass = FALSE;
|
||||
failure_mssg = "error in H5C_flush_cache().";
|
||||
H5C_FLUSH_CACHE(file_ptr, H5C__NO_FLAGS_SET, \
|
||||
"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,
|
||||
"%s: unexpected il/is/cis/dis = %lld/%lld/%lld/%lld.\n",
|
||||
FUNC,
|
||||
@ -3961,14 +3979,19 @@ unprotect_entry(H5F_t * file_ptr,
|
||||
* Function: row_major_scan_forward()
|
||||
*
|
||||
* Purpose: Do a sequence of inserts, protects, unprotects, moves,
|
||||
* destroys while scanning through the set of entries. If
|
||||
* pass is false on entry, do nothing.
|
||||
* destroys while scanning through the set of entries. If
|
||||
* pass is false on entry, do nothing.
|
||||
*
|
||||
* Return: void
|
||||
*
|
||||
* Programmer: John Mainzer
|
||||
* 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
|
||||
@ -3983,7 +4006,7 @@ row_major_scan_forward(H5F_t * file_ptr,
|
||||
hbool_t do_moves,
|
||||
hbool_t move_to_main_addr,
|
||||
hbool_t do_destroys,
|
||||
hbool_t do_mult_ro_protects,
|
||||
hbool_t do_mult_ro_protects,
|
||||
int dirty_destroys,
|
||||
int dirty_unprotects)
|
||||
{
|
||||
@ -4022,7 +4045,10 @@ row_major_scan_forward(H5F_t * file_ptr,
|
||||
HDfprintf(stdout, "1(i, %d, %d) ", type, tmp_idx);
|
||||
|
||||
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 */
|
||||
|
||||
tmp_idx--;
|
||||
@ -4033,7 +4059,10 @@ row_major_scan_forward(H5F_t * file_ptr,
|
||||
HDfprintf(stdout, "2(p, %d, %d) ", 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 */
|
||||
|
||||
tmp_idx--;
|
||||
@ -4044,7 +4073,10 @@ row_major_scan_forward(H5F_t * file_ptr,
|
||||
HDfprintf(stdout, "3(u, %d, %d) ", type, tmp_idx);
|
||||
|
||||
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 */
|
||||
|
||||
/* (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);
|
||||
|
||||
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 */
|
||||
|
||||
tmp_idx--;
|
||||
@ -4066,7 +4101,10 @@ row_major_scan_forward(H5F_t * file_ptr,
|
||||
HDfprintf(stdout, "5(p, %d, %d) ", 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 */
|
||||
|
||||
tmp_idx -= 2;
|
||||
@ -4077,7 +4115,10 @@ row_major_scan_forward(H5F_t * file_ptr,
|
||||
HDfprintf(stdout, "6(u, %d, %d) ", type, tmp_idx);
|
||||
|
||||
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 */
|
||||
|
||||
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);
|
||||
|
||||
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 */
|
||||
|
||||
tmp_idx--;
|
||||
@ -4100,7 +4144,10 @@ row_major_scan_forward(H5F_t * file_ptr,
|
||||
HDfprintf(stdout, "8(p-ro, %d, %d) ", 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 */
|
||||
|
||||
tmp_idx--;
|
||||
@ -4111,7 +4158,10 @@ row_major_scan_forward(H5F_t * file_ptr,
|
||||
HDfprintf(stdout, "9(p-ro, %d, %d) ", 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 */
|
||||
|
||||
/* (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);
|
||||
|
||||
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 */
|
||||
|
||||
tmp_idx--;
|
||||
@ -4133,7 +4186,10 @@ row_major_scan_forward(H5F_t * file_ptr,
|
||||
HDfprintf(stdout, "11(u-ro, %d, %d) ", type, tmp_idx);
|
||||
|
||||
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 */
|
||||
|
||||
tmp_idx--;
|
||||
@ -4144,7 +4200,10 @@ row_major_scan_forward(H5F_t * file_ptr,
|
||||
HDfprintf(stdout, "12(u-ro, %d, %d) ", type, tmp_idx);
|
||||
|
||||
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 */
|
||||
} /* 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);
|
||||
|
||||
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 */
|
||||
|
||||
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);
|
||||
|
||||
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 */
|
||||
|
||||
tmp_idx--;
|
||||
@ -4175,7 +4240,10 @@ row_major_scan_forward(H5F_t * file_ptr,
|
||||
HDfprintf(stdout, "15(p, %d, %d) ", 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 */
|
||||
|
||||
if(do_destroys) {
|
||||
@ -4187,7 +4255,10 @@ row_major_scan_forward(H5F_t * file_ptr,
|
||||
HDfprintf(stdout, "16(u, %d, %d) ", type, tmp_idx);
|
||||
|
||||
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;
|
||||
|
||||
case 1:
|
||||
@ -4196,14 +4267,20 @@ row_major_scan_forward(H5F_t * file_ptr,
|
||||
HDfprintf(stdout, "17(u, %d, %d) ", type, tmp_idx);
|
||||
|
||||
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 */
|
||||
else {
|
||||
if(verbose)
|
||||
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));
|
||||
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 */
|
||||
break;
|
||||
|
||||
@ -4212,7 +4289,10 @@ row_major_scan_forward(H5F_t * file_ptr,
|
||||
HDfprintf(stdout, "19(u-del, %d, %d) ", type, tmp_idx);
|
||||
|
||||
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;
|
||||
|
||||
case 3:
|
||||
@ -4221,14 +4301,20 @@ row_major_scan_forward(H5F_t * file_ptr,
|
||||
HDfprintf(stdout, "20(u-del, %d, %d) ", type, tmp_idx);
|
||||
|
||||
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 */
|
||||
else {
|
||||
if(verbose)
|
||||
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);
|
||||
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 */
|
||||
break;
|
||||
|
||||
@ -4245,7 +4331,10 @@ row_major_scan_forward(H5F_t * file_ptr,
|
||||
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));
|
||||
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 elsef */
|
||||
|
||||
|
@ -134,6 +134,65 @@
|
||||
(NOTIFY_ENTRY_SIZE * NUM_NOTIFY_ENTRIES))
|
||||
#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
|
||||
* directly pinned by a single entry.
|
||||
*/
|
||||
|
@ -348,11 +348,20 @@ evict_entries(hid_t fid)
|
||||
/* Mark all entries investigated */
|
||||
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 */
|
||||
/* This function will likely return failure since the root group
|
||||
* is still protected. Thus, don't check its return value. */
|
||||
/* This function will likely return failure since the root group
|
||||
* is still protected. Thus, don't check its return value.
|
||||
*/
|
||||
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;
|
||||
|
||||
error:
|
||||
|
24
test/ohdr.c
24
test/ohdr.c
@ -126,8 +126,12 @@ test_cont(char *filename, hid_t fapl)
|
||||
FAIL_STACK_ERROR
|
||||
if(1 != H5O_link(&oh_locB, 1))
|
||||
FAIL_STACK_ERROR
|
||||
if(H5AC_prep_for_file_flush(f) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
if(H5AC_flush(f) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
if(H5AC_secure_from_file_flush(f) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
if(H5O__expunge_chunks_test(&oh_locA) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
|
||||
@ -1681,8 +1685,12 @@ main(void)
|
||||
FAIL_STACK_ERROR
|
||||
if(1 != H5O_link(&oh_loc, 1))
|
||||
FAIL_STACK_ERROR
|
||||
if(H5AC_prep_for_file_flush(f) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
if(H5AC_flush(f) < 0)
|
||||
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)
|
||||
FAIL_STACK_ERROR
|
||||
if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro))
|
||||
@ -1698,8 +1706,12 @@ main(void)
|
||||
time_new = 33333333;
|
||||
if(H5O_msg_write(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
if(H5AC_prep_for_file_flush(f) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
if(H5AC_flush(f) < 0)
|
||||
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)
|
||||
FAIL_STACK_ERROR
|
||||
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)
|
||||
FAIL_STACK_ERROR
|
||||
} /* end for */
|
||||
if(H5AC_prep_for_file_flush(f) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
if(H5AC_flush(f) < 0)
|
||||
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)
|
||||
FAIL_STACK_ERROR
|
||||
|
||||
@ -1772,8 +1788,12 @@ main(void)
|
||||
time_new = (i + 1) * 1000 + 10;
|
||||
if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
if(H5AC_prep_for_file_flush(f) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
if(H5AC_flush(f) < 0)
|
||||
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)
|
||||
FAIL_STACK_ERROR
|
||||
} /* end for */
|
||||
@ -1802,8 +1822,12 @@ main(void)
|
||||
time_new = 22222222;
|
||||
if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, H5O_MSG_FLAG_CONSTANT, 0, &time_new) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
if(H5AC_prep_for_file_flush(f) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
if(H5AC_flush(f) < 0)
|
||||
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)
|
||||
FAIL_STACK_ERROR
|
||||
if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro))
|
||||
|
Loading…
x
Reference in New Issue
Block a user