summaryrefslogtreecommitdiffstats
path: root/src/H5C.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5C.c')
-rw-r--r--src/H5C.c1848
1 files changed, 757 insertions, 1091 deletions
diff --git a/src/H5C.c b/src/H5C.c
index 805b4f5..4adee6d 100644
--- a/src/H5C.c
+++ b/src/H5C.c
@@ -46,9 +46,9 @@
* - Change protect/unprotect to lock/unlock.
*
* - Flush entries in increasing address order in
- * H5C__make_space_in_cache().
+ * H5C_make_space_in_cache().
*
- * - Also in H5C__make_space_in_cache(), use high and low water marks
+ * - Also in H5C_make_space_in_cache(), use high and low water marks
* to reduce the number of I/O calls.
*
* - When flushing, attempt to combine contiguous entries to reduce
@@ -75,7 +75,7 @@
/****************/
#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 */
/***********/
@@ -155,17 +155,21 @@ static void * H5C_load_entry(H5F_t * f,
haddr_t addr,
void * udata);
+static herr_t H5C_make_space_in_cache(H5F_t * f,
+ hid_t dxpl_id,
+ size_t space_needed,
+ hbool_t write_permitted);
+
static herr_t H5C__mark_flush_dep_dirty(H5C_cache_entry_t * entry);
static herr_t H5C__mark_flush_dep_clean(H5C_cache_entry_t * entry);
-static herr_t H5C__serialize_ring(H5F_t *f, hid_t dxpl_id, H5C_ring_t ring);
-static herr_t H5C__serialize_single_entry(H5F_t *f, hid_t dxpl_id,
- H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr);
-
static herr_t H5C__verify_len_eoa(H5F_t *f, const H5C_class_t * type,
haddr_t addr, size_t *len, hbool_t actual);
+static herr_t H5C__generate_image(H5F_t *f, H5C_t * cache_ptr, H5C_cache_entry_t *entry_ptr,
+ hid_t dxpl_id);
+
#if H5C_DO_SLIST_SANITY_CHECKS
static hbool_t H5C_entry_in_skip_list(H5C_t * cache_ptr,
H5C_cache_entry_t *target_ptr);
@@ -239,7 +243,7 @@ H5C_t *
H5C_create(size_t max_cache_size,
size_t min_clean_size,
int max_type_id,
- const H5C_class_t * const * class_table_ptr,
+ const char * (* type_name_table_ptr),
H5C_write_permitted_func_t check_write_permitted,
hbool_t write_permitted,
H5C_log_flush_func_t log_flush,
@@ -257,21 +261,21 @@ H5C_create(size_t max_cache_size,
HDassert( max_type_id >= 0 );
HDassert( max_type_id < H5C__MAX_NUM_TYPE_IDS );
- HDassert( class_table_ptr );
+ HDassert( type_name_table_ptr );
for ( i = 0; i <= max_type_id; i++ ) {
- HDassert( (class_table_ptr)[i] );
- HDassert(HDstrlen((class_table_ptr)[i]->name) > 0);
+ HDassert( (type_name_table_ptr)[i] );
+ HDassert( HDstrlen(( type_name_table_ptr)[i]) > 0 );
} /* end for */
if(NULL == (cache_ptr = H5FL_CALLOC(H5C_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
if(NULL == (cache_ptr->slist_ptr = H5SL_create(H5SL_TYPE_HADDR, NULL)))
- HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, NULL, "can't create skip list")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, NULL, "can't create skip list.")
if(NULL == (cache_ptr->tag_list = H5SL_create(H5SL_TYPE_HADDR, NULL)))
- HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, NULL, "can't create skip list for tagged entry addresses")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, NULL, "can't create skip list for tagged entry addresses.")
/* If we get this far, we should succeed. Go ahead and initialize all
* the fields.
@@ -293,7 +297,7 @@ H5C_create(size_t max_cache_size,
cache_ptr->max_type_id = max_type_id;
- cache_ptr->class_table_ptr = class_table_ptr;
+ cache_ptr->type_name_table_ptr = type_name_table_ptr;
cache_ptr->max_cache_size = max_cache_size;
cache_ptr->min_clean_size = min_clean_size;
@@ -385,7 +389,6 @@ H5C_create(size_t max_cache_size,
cache_ptr->resize_enabled = FALSE;
cache_ptr->cache_full = FALSE;
cache_ptr->size_decreased = FALSE;
- cache_ptr->resize_in_progress = FALSE;
(cache_ptr->resize_ctl).version = H5C__CURR_AUTO_SIZE_CTL_VER;
(cache_ptr->resize_ctl).rpt_fcn = NULL;
@@ -431,52 +434,28 @@ H5C_create(size_t max_cache_size,
((cache_ptr->epoch_markers)[i]).magic =
H5C__H5C_CACHE_ENTRY_T_MAGIC;
((cache_ptr->epoch_markers)[i]).addr = (haddr_t)i;
- ((cache_ptr->epoch_markers)[i]).type = H5AC_EPOCH_MARKER;
+ ((cache_ptr->epoch_markers)[i]).type = &H5C__epoch_marker_class;
}
- /* Initialize cache image generation on file close related fields.
- * Initial value of image_ctl must match H5C__DEFAULT_CACHE_IMAGE_CTL
- * in H5Cprivate.h.
- */
- cache_ptr->image_ctl.version = H5C__CURR_CACHE_IMAGE_CTL_VER;
- cache_ptr->image_ctl.generate_image = FALSE;
- cache_ptr->image_ctl.save_resize_status = FALSE;
- cache_ptr->image_ctl.entry_ageout = -1;
- cache_ptr->image_ctl.flags = H5C_CI__ALL_FLAGS;
-
- cache_ptr->serialization_in_progress= FALSE;
- cache_ptr->load_image = FALSE;
- cache_ptr->image_loaded = FALSE;
- cache_ptr->delete_image = FALSE;
- cache_ptr->image_addr = HADDR_UNDEF;
- cache_ptr->image_len = 0;
- cache_ptr->image_data_len = 0;
-
cache_ptr->entries_loaded_counter = 0;
cache_ptr->entries_inserted_counter = 0;
cache_ptr->entries_relocated_counter = 0;
- cache_ptr->entry_fd_height_change_counter = 0;
-
- cache_ptr->num_entries_in_image = 0;
- cache_ptr->image_entries = NULL;
- cache_ptr->image_buffer = NULL;
/* initialize free space manager related fields: */
cache_ptr->rdfsm_settled = FALSE;
cache_ptr->mdfsm_settled = FALSE;
- if(H5C_reset_cache_hit_rate_stats(cache_ptr) < 0)
+ if ( H5C_reset_cache_hit_rate_stats(cache_ptr) != SUCCEED ) {
+
/* this should be impossible... */
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, NULL, "H5C_reset_cache_hit_rate_stats failed")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, NULL, \
+ "H5C_reset_cache_hit_rate_stats failed.")
+ }
H5C_stats__reset(cache_ptr);
cache_ptr->prefix[0] = '\0'; /* empty string */
-#ifndef NDEBUG
- cache_ptr->get_entry_ptr_from_addr_counter = 0;
-#endif /* NDEBUG */
-
/* Set return value */
ret_value = cache_ptr;
@@ -754,11 +733,6 @@ H5C_prep_for_file_close(H5F_t *f, hid_t dxpl_id)
/* Make certain there aren't any protected entries */
HDassert(cache_ptr->pl_len == 0);
- /* Prepare cache image */
- if(H5C__prep_image_for_file_close(f, dxpl_id) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, FAIL, "can't create cache image")
-
-
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C_prep_for_file_close() */
@@ -801,20 +775,10 @@ H5C_dest(H5F_t * f, hid_t dxpl_id)
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
HDassert(cache_ptr->close_warning_received);
-#if H5AC_DUMP_IMAGE_STATS_ON_CLOSE
- if(H5C_image_stats(cache_ptr, TRUE) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't display cache image stats")
-#endif /* H5AC_DUMP_IMAGE_STATS_ON_CLOSE */
-
/* Flush and invalidate all cache entries */
if(H5C_flush_invalidate_cache(f, dxpl_id, H5C__NO_FLAGS_SET) < 0 )
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache")
- /* Generate & write cache image if requested */
- if(cache_ptr->image_ctl.generate_image)
- if(H5C__generate_cache_image(f, dxpl_id, cache_ptr) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, FAIL, "Can't generate metadata cache image")
-
if(cache_ptr->slist_ptr != NULL) {
H5SL_close(cache_ptr->slist_ptr);
cache_ptr->slist_ptr = NULL;
@@ -826,12 +790,6 @@ H5C_dest(H5F_t * f, hid_t dxpl_id)
} /* end if */
#ifndef NDEBUG
-#if H5C_DO_SANITY_CHECKS
- if(cache_ptr->get_entry_ptr_from_addr_counter > 0)
- HDfprintf(stdout, "*** %ld calls to H5C_get_entry_ptr_from_add(). ***\n",
- cache_ptr->get_entry_ptr_from_addr_counter);
-#endif /* H5C_DO_SANITY_CHECKS */
-
cache_ptr->magic = 0;
#endif /* NDEBUG */
@@ -857,12 +815,14 @@ done:
herr_t
H5C_evict(H5F_t * f, hid_t dxpl_id)
{
+ H5C_t *cache_ptr = f->shared->cache;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
/* Sanity check */
- HDassert(f);
+ HDassert(cache_ptr);
+ HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
/* Flush and invalidate all cache entries except the pinned entries */
if(H5C_flush_invalidate_cache(f, dxpl_id, H5C__EVICT_ALLOW_LAST_PINS_FLAG) < 0 )
@@ -908,7 +868,7 @@ H5C_expunge_entry(H5F_t *f, hid_t dxpl_id, const H5C_class_t *type,
#if H5C_DO_EXTREME_SANITY_CHECKS
if(H5C_validate_lru_list(cache_ptr) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "LRU extreme sanity check failed on entry")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "LRU extreme sanity check failed on entry.\n")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
/* Look for entry in cache */
@@ -922,9 +882,9 @@ H5C_expunge_entry(H5F_t *f, hid_t dxpl_id, const H5C_class_t *type,
/* Check for entry being pinned or protected */
if(entry_ptr->is_protected)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTEXPUNGE, FAIL, "Target entry is protected")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTEXPUNGE, FAIL, "Target entry is protected.")
if(entry_ptr->is_pinned)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTEXPUNGE, FAIL, "Target entry is pinned")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTEXPUNGE, FAIL, "Target entry is pinned.")
#ifdef H5_HAVE_PARALLEL
if(entry_ptr->coll_access) {
entry_ptr->coll_access = FALSE;
@@ -949,7 +909,7 @@ H5C_expunge_entry(H5F_t *f, hid_t dxpl_id, const H5C_class_t *type,
done:
#if H5C_DO_EXTREME_SANITY_CHECKS
if(H5C_validate_lru_list(cache_ptr) < 0)
- HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "LRU extreme sanity check failed on exit")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "LRU extreme sanity check failed on exit.\n")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
FUNC_LEAVE_NOAPI(ret_value)
@@ -1008,12 +968,12 @@ H5C_flush_cache(H5F_t *f, hid_t dxpl_id, unsigned flags)
{
#if H5C_DO_SANITY_CHECKS
int i;
- uint32_t index_len = 0;
+ int32_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;
+ int32_t slist_len = 0;
#endif /* H5C_DO_SANITY_CHECKS */
H5C_ring_t ring;
H5C_t * cache_ptr;
@@ -1060,7 +1020,7 @@ H5C_flush_cache(H5F_t *f, hid_t dxpl_id, unsigned flags)
if((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
(H5C_validate_pinned_entry_list(cache_ptr) < 0) ||
(H5C_validate_lru_list(cache_ptr) < 0))
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on entry")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on entry.\n")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
ignore_protected = ( (flags & H5C__FLUSH_IGNORE_PROTECTED_FLAG) != 0 );
@@ -1072,7 +1032,7 @@ H5C_flush_cache(H5F_t *f, hid_t dxpl_id, unsigned flags)
if(destroy) {
if(H5C_flush_invalidate_cache(f, dxpl_id, flags) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "flush invalidate failed")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "flush invalidate failed.")
} /* end if */
else {
/* flush each ring, starting from the outermost ring and
@@ -1080,9 +1040,9 @@ H5C_flush_cache(H5F_t *f, hid_t dxpl_id, unsigned flags)
*/
ring = H5C_RING_USER;
while(ring < H5C_RING_NTYPES) {
-
- /* Only call the free space manager settle routines when close
- * warning has been received.
+ /* only call the free space manager settle routines when close
+ * warning has been received, and then only when the index is
+ * non-empty for that ring.
*/
if(cache_ptr->close_warning_received) {
switch(ring) {
@@ -1090,20 +1050,36 @@ H5C_flush_cache(H5F_t *f, hid_t dxpl_id, unsigned flags)
break;
case H5C_RING_RDFSM:
- /* Settle raw data FSM */
- if(!cache_ptr->rdfsm_settled)
- if(H5MF_settle_raw_data_fsm(f, dxpl_id, &cache_ptr->rdfsm_settled) < 0)
+ if(!cache_ptr->rdfsm_settled) {
+ hbool_t fsm_settled = FALSE; /* Whether the FSM was actually settled */
+
+ /* Settle raw data FSM */
+ if(H5MF_settle_raw_data_fsm(f, dxpl_id, &fsm_settled) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "RD FSM settle failed")
+
+ /* Only set the flag if the FSM was actually settled */
+ if(fsm_settled)
+ cache_ptr->rdfsm_settled = TRUE;
+ } /* end if */
break;
case H5C_RING_MDFSM:
- /* Settle metadata FSM */
- if(!cache_ptr->mdfsm_settled)
- if(H5MF_settle_meta_data_fsm(f, dxpl_id, &cache_ptr->mdfsm_settled) < 0)
+ if(!cache_ptr->mdfsm_settled) {
+ hbool_t fsm_settled = FALSE; /* Whether the FSM was actually settled */
+
+ /* Settle metadata FSM */
+ if(H5MF_settle_meta_data_fsm(f, dxpl_id, &fsm_settled) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "MD FSM settle failed")
+
+ /* Only set the flag if the FSM was actually settled */
+ if(fsm_settled)
+ cache_ptr->mdfsm_settled = TRUE;
+ } /* end if */
break;
case H5C_RING_SBE:
+ break;
+
case H5C_RING_SB:
break;
@@ -1114,7 +1090,7 @@ H5C_flush_cache(H5F_t *f, hid_t dxpl_id, unsigned flags)
} /* end if */
if(H5C_flush_ring(f, dxpl_id, ring, flags) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "flush ring failed")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "flush ring failed.")
ring++;
} /* end while */
} /* end else */
@@ -1155,6 +1131,7 @@ H5C_flush_to_min_clean(H5F_t * f,
hid_t dxpl_id)
{
H5C_t * cache_ptr;
+ herr_t result;
hbool_t write_permitted;
#if 0 /* modified code -- commented out for now */ /* JRM */
int i;
@@ -1176,19 +1153,36 @@ H5C_flush_to_min_clean(H5F_t * f,
HDassert( cache_ptr );
HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
- if(cache_ptr->check_write_permitted != NULL) {
- if((cache_ptr->check_write_permitted)(f, &write_permitted) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't get write_permitted")
- } /* end if */
- else
+ if ( cache_ptr->check_write_permitted != NULL ) {
+
+ result = (cache_ptr->check_write_permitted)(f, &write_permitted);
+
+ if ( result < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "Can't get write_permitted")
+ }
+ } else {
+
write_permitted = cache_ptr->write_permitted;
+ }
- if(!write_permitted)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "cache write is not permitted!?!")
+ if ( ! write_permitted ) {
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "cache write is not permitted!?!\n");
+ }
#if 1 /* original code */
- if(H5C__make_space_in_cache(f, dxpl_id, (size_t)0, write_permitted) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C__make_space_in_cache failed")
+ result = H5C_make_space_in_cache(f,
+ dxpl_id,
+ (size_t)0,
+ write_permitted);
+
+ if ( result < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "H5C_make_space_in_cache failed.")
+ }
#else /* modified code -- commented out for now */
if ( cache_ptr->max_cache_size > cache_ptr->index_size ) {
@@ -1226,8 +1220,12 @@ H5C_flush_to_min_clean(H5F_t * f,
*/
flushed_entries_list = (haddr_t *)H5MM_malloc(sizeof(haddr_t) *
(size_t)(cache_ptr->slist_len));
- if(flushed_entries_list == NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for flushed entries list")
+
+ if ( flushed_entries_list == NULL ) {
+
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, \
+ "memory allocation failed for flushed entries list")
+ }
/* Scan the dirty LRU list from tail forward and mark sufficient
* entries to free up the necessary space. Keep a list of the
@@ -1257,8 +1255,13 @@ H5C_flush_to_min_clean(H5F_t * f,
/* Flush the marked entries */
- if(H5C_flush_cache(f, primary_dxpl_id, secondary_dxpl_id, H5C__FLUSH_MARKED_ENTRIES_FLAG | H5C__FLUSH_IGNORE_PROTECTED_FLAG) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_flush_cache failed")
+ result = H5C_flush_cache(f, primary_dxpl_id, secondary_dxpl_id,
+ H5C__FLUSH_MARKED_ENTRIES_FLAG | H5C__FLUSH_IGNORE_PROTECTED_FLAG);
+
+ if ( result < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_flush_cache failed.")
+ }
/* Now touch up the LRU list so as to place the flushed entries in
* the order they they would be in if we had flushed them in the
@@ -1333,9 +1336,8 @@ H5C_insert_entry(H5F_t * f,
hbool_t set_flush_marker;
hbool_t write_permitted = TRUE;
size_t empty_space;
- H5C_cache_entry_t *entry_ptr = NULL;
+ H5C_cache_entry_t *entry_ptr;
H5C_cache_entry_t *test_entry_ptr;
- hbool_t entry_tagged = FALSE;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
@@ -1348,7 +1350,6 @@ H5C_insert_entry(H5F_t * f,
HDassert( cache_ptr );
HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
HDassert( type );
- HDassert( type->mem_type == cache_ptr->class_table_ptr[type->id]->mem_type );
HDassert( type->image_len );
HDassert( H5F_addr_defined(addr) );
HDassert( thing );
@@ -1356,10 +1357,14 @@ H5C_insert_entry(H5F_t * f,
#if H5C_DO_EXTREME_SANITY_CHECKS
/* no need to verify that entry is not already in the index as */
/* we already make that check below. */
- if((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C_validate_pinned_entry_list(cache_ptr) < 0) ||
- (H5C_validate_lru_list(cache_ptr) < 0))
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on entry")
+
+ if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "an extreme sanity check failed on entry.\n");
+ }
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
set_flush_marker = ( (flags & H5C__SET_FLUSH_MARKER_FLAG) != 0 );
@@ -1384,9 +1389,9 @@ H5C_insert_entry(H5F_t * f,
if(test_entry_ptr != NULL) {
if(test_entry_ptr == entry_ptr)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, "entry already in cache")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, "entry already in cache.")
else
- HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, "duplicate entry in cache")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, "duplicate entry in cache.")
} /* end if */
entry_ptr->magic = H5C__H5C_CACHE_ENTRY_T_MAGIC;
@@ -1453,33 +1458,16 @@ H5C_insert_entry(H5F_t * f,
entry_ptr->coll_prev = NULL;
#endif /* H5_HAVE_PARALLEL */
- /* initialize cache image related fields */
- entry_ptr->include_in_image = FALSE;
- entry_ptr->lru_rank = 0;
- entry_ptr->image_dirty = FALSE;
- entry_ptr->fd_parent_count = 0;
- entry_ptr->fd_parent_addrs = NULL;
- entry_ptr->fd_child_count = 0;
- entry_ptr->fd_dirty_child_count = 0;
- entry_ptr->image_fd_height = 0;
- entry_ptr->prefetched = FALSE;
- entry_ptr->prefetch_type_id = 0;
- entry_ptr->age = 0;
-#ifndef NDEBUG /* debugging field */
- entry_ptr->serialization_count = 0;
-#endif /* NDEBUG */
-
/* Apply tag to newly inserted entry */
if(H5C__tag_entry(cache_ptr, entry_ptr, dxpl_id) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "Cannot tag metadata entry")
- entry_tagged = TRUE;
H5C__RESET_CACHE_ENTRY_STATS(entry_ptr)
if(cache_ptr->flash_size_increase_possible &&
(entry_ptr->size > cache_ptr->flash_size_increase_threshold))
if(H5C__flash_increase_cache_size(cache_ptr, 0, entry_ptr->size) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, "H5C__flash_increase_cache_size failed")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, "H5C__flash_increase_cache_size failed.")
if(cache_ptr->index_size >= cache_ptr->max_cache_size)
empty_space = 0;
@@ -1509,7 +1497,7 @@ H5C_insert_entry(H5F_t * f,
/* Note that space_needed is just the amount of space that
* needed to insert the new entry without exceeding the cache
- * size limit. The subsequent call to H5C__make_space_in_cache()
+ * size limit. The subsequent call to H5C_make_space_in_cache()
* may evict the entries required to free more or less space
* depending on conditions. It MAY be less if the cache is
* currently undersized, or more if the cache is oversized.
@@ -1532,9 +1520,9 @@ H5C_insert_entry(H5F_t * f,
* no point in worrying about the third.
*/
- if(H5C__make_space_in_cache(f, dxpl_id, space_needed, write_permitted) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, "H5C__make_space_in_cache failed")
- } /* end if */
+ if(H5C_make_space_in_cache(f, dxpl_id, space_needed, write_permitted) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, "H5C_make_space_in_cache failed.")
+ }
H5C__INSERT_IN_INDEX(cache_ptr, entry_ptr, FAIL)
@@ -1545,10 +1533,10 @@ H5C_insert_entry(H5F_t * f,
H5C__UPDATE_RP_FOR_INSERTION(cache_ptr, entry_ptr, FAIL)
#if H5C_DO_EXTREME_SANITY_CHECKS
- if((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C_validate_pinned_entry_list(cache_ptr) < 0) ||
- (H5C_validate_lru_list(cache_ptr) < 0))
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed just before done")
+ if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_lru_list(cache_ptr) < 0 ) )
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed just before done.\n")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
/* If the entry's type has a 'notify' callback send a 'after insertion'
@@ -1600,16 +1588,12 @@ H5C_insert_entry(H5F_t * f,
done:
#if H5C_DO_EXTREME_SANITY_CHECKS
- if((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C_validate_pinned_entry_list(cache_ptr) < 0) ||
- (H5C_validate_lru_list(cache_ptr) < 0))
- HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on exit")
+ if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_lru_list(cache_ptr) < 0 ) )
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on exit.\n")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
- if(ret_value < 0 && entry_tagged)
- if(H5C__untag_entry(cache_ptr, entry_ptr) < 0)
- HDONE_ERROR(H5E_CACHE, H5E_CANTREMOVE, FAIL, "can't remove entry from tag list")
-
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C_insert_entry() */
@@ -1931,7 +1915,7 @@ H5C_move_entry(H5C_t * cache_ptr,
if((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
(H5C_validate_pinned_entry_list(cache_ptr) < 0) ||
(H5C_validate_lru_list(cache_ptr) < 0))
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on entry")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on entry.\n")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
H5C__SEARCH_INDEX(cache_ptr, old_addr, entry_ptr, FAIL)
@@ -2035,7 +2019,7 @@ done:
if((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
(H5C_validate_pinned_entry_list(cache_ptr) < 0) ||
(H5C_validate_lru_list(cache_ptr) < 0))
- HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on exit")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on exit.\n")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
FUNC_LEAVE_NOAPI(ret_value)
@@ -2076,14 +2060,17 @@ H5C_resize_entry(void *thing, size_t new_size)
/* Check for usage errors */
if(new_size <= 0)
- HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "New size is non-positive")
+ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "New size is non-positive.")
if(!(entry_ptr->is_pinned || entry_ptr->is_protected))
HGOTO_ERROR(H5E_CACHE, H5E_BADTYPE, FAIL, "Entry isn't pinned or protected??")
#if H5C_DO_EXTREME_SANITY_CHECKS
- if((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C_validate_pinned_entry_list(cache_ptr) < 0))
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on entry")
+ if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "an extreme sanity check failed on entry.\n");
+ }
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
/* update for change in entry size if necessary */
@@ -2180,10 +2167,14 @@ H5C_resize_entry(void *thing, size_t new_size)
} /* end if */
done:
+
#if H5C_DO_EXTREME_SANITY_CHECKS
- if((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C_validate_pinned_entry_list(cache_ptr) < 0))
- HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on exit")
+ if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "an extreme sanity check failed on exit.\n");
+ }
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
FUNC_LEAVE_NOAPI(ret_value)
@@ -2279,10 +2270,13 @@ H5C_pin_protected_entry(void *thing)
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
#if H5C_DO_EXTREME_SANITY_CHECKS
- if((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C_validate_pinned_entry_list(cache_ptr) < 0) ||
- (H5C_validate_lru_list(cache_ptr) < 0))
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on entry")
+ if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "an extreme sanity check failed on entry.\n");
+ }
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@@ -2295,11 +2289,15 @@ H5C_pin_protected_entry(void *thing)
HGOTO_ERROR(H5E_CACHE, H5E_CANTPIN, FAIL, "Can't pin entry by client")
done:
+
#if H5C_DO_EXTREME_SANITY_CHECKS
- if((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C_validate_pinned_entry_list(cache_ptr) < 0) ||
- (H5C_validate_lru_list(cache_ptr) < 0))
- HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on exit")
+ if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "an extreme sanity check failed on exit.\n");
+ }
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
FUNC_LEAVE_NOAPI(ret_value)
@@ -2326,6 +2324,32 @@ done:
*
* Programmer: John Mainzer - 6/2/04
*
+ * JRM -- 11/13/08
+ * Modified function to call H5C_make_space_in_cache() when
+ * the min_clean_size is violated, not just when there isn't
+ * enough space for and entry that has just been loaded.
+ *
+ * The purpose of this modification is to avoid "metadata
+ * blizzards" in the write only case. In such instances,
+ * the cache was allowed to fill with dirty metadata. When
+ * we finally needed to evict an entry to make space, we had
+ * to flush out a whole cache full of metadata -- which has
+ * interesting performance effects. We hope to avoid (or
+ * perhaps more accurately hide) this effect by maintaining
+ * the min_clean_size, which should force us to start flushing
+ * entries long before we actually have to evict something
+ * to make space.
+ *
+ * JRM -- 9/1/14
+ * Replace the old rw parameter with the flags parameter.
+ * This allows H5C_protect to accept flags other than
+ * H5C__READ_ONLY_FLAG.
+ *
+ * Added support for the H5C__FLUSH_LAST_FLAG.
+ * At present, this flag is only applied if the entry is
+ * not in cache, and is loaded into the cache as a result of
+ * this call.
+ *
*-------------------------------------------------------------------------
*/
void *
@@ -2364,22 +2388,16 @@ H5C_protect(H5F_t * f,
HDassert( cache_ptr );
HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
HDassert( type );
- HDassert( type->mem_type == cache_ptr->class_table_ptr[type->id]->mem_type );
HDassert( H5F_addr_defined(addr) );
#if H5C_DO_EXTREME_SANITY_CHECKS
- if((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C_validate_pinned_entry_list(cache_ptr) < 0) ||
- (H5C_validate_lru_list(cache_ptr) < 0))
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, NULL, "an extreme sanity check failed on entry")
-#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
+ if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
- /* Load the cache image, if requested */
- if(cache_ptr->load_image) {
- cache_ptr->load_image = FALSE;
- if(H5C__load_cache_image(f, dxpl_id) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "Can't load cache image")
- } /* end if */
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, NULL, "an extreme sanity check failed on entry.\n")
+ }
+#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
read_only = ( (flags & H5C__READ_ONLY_FLAG) != 0 );
flush_last = ( (flags & H5C__FLUSH_LAST_FLAG) != 0 );
@@ -2410,24 +2428,9 @@ H5C_protect(H5F_t * f,
/* first check to see if the target is in cache */
H5C__SEARCH_INDEX(cache_ptr, addr, entry_ptr, NULL)
- if(entry_ptr != NULL) {
+ if ( entry_ptr != NULL ) {
if(entry_ptr->ring != ring)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, NULL, "ring type mismatch occured for cache entry")
-
- HDassert(entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
-
- if(entry_ptr->prefetched) {
- /* This call removes the prefetched entry from the cache,
- * and replaces it with an entry deserialized from the
- * image of the prefetched entry.
- */
- if(H5C__deserialize_prefetched_entry(f, dxpl_id, cache_ptr, &entry_ptr, type, addr, udata) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "can't deserialize prefetched entry")
-
- HDassert(entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
- HDassert(!entry_ptr->prefetched);
- HDassert(entry_ptr->addr == addr);
- } /* end if */
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, NULL, "ring type mismatch occured for cache entry\n")
/* Check for trying to load the wrong type of entry from an address */
if(entry_ptr->type != type)
@@ -2520,8 +2523,6 @@ H5C_protect(H5F_t * f,
HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "can't load entry")
entry_ptr = (H5C_cache_entry_t *)thing;
- cache_ptr->entries_loaded_counter++;
-
entry_ptr->ring = ring;
#ifdef H5_HAVE_PARALLEL
if(H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI) && entry_ptr->coll_access)
@@ -2539,7 +2540,7 @@ H5C_protect(H5F_t * f,
( entry_ptr->size > cache_ptr->flash_size_increase_threshold ) ) {
if(H5C__flash_increase_cache_size(cache_ptr, 0, entry_ptr->size) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, "H5C__flash_increase_cache_size failed")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, "H5C__flash_increase_cache_size failed.")
}
if(cache_ptr->index_size >= cache_ptr->max_cache_size)
@@ -2548,7 +2549,7 @@ H5C_protect(H5F_t * f,
empty_space = cache_ptr->max_cache_size - cache_ptr->index_size;
/* try to free up if necceary and if evictions are permitted. Note
- * that if evictions are enabled, we will call H5C__make_space_in_cache()
+ * that if evictions are enabled, we will call H5C_make_space_in_cache()
* regardless if the min_free_space requirement is not met.
*/
if ( ( cache_ptr->evictions_enabled ) &&
@@ -2583,7 +2584,7 @@ H5C_protect(H5F_t * f,
/* Note that space_needed is just the amount of space that
* needed to insert the new entry without exceeding the cache
- * size limit. The subsequent call to H5C__make_space_in_cache()
+ * size limit. The subsequent call to H5C_make_space_in_cache()
* may evict the entries required to free more or less space
* depending on conditions. It MAY be less if the cache is
* currently undersized, or more if the cache is oversized.
@@ -2610,9 +2611,9 @@ H5C_protect(H5F_t * f,
* see no point in worrying about the fourth.
*/
- if(H5C__make_space_in_cache(f, dxpl_id, space_needed, write_permitted) < 0 )
- HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, "H5C__make_space_in_cache failed")
- } /* end if */
+ if(H5C_make_space_in_cache(f, dxpl_id, space_needed, write_permitted) < 0 )
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, "H5C_make_space_in_cache failed 1.")
+ }
/* Insert the entry in the hash table. It can't be dirty yet, so
* we don't even check to see if it should go in the skip list.
@@ -2647,34 +2648,44 @@ H5C_protect(H5F_t * f,
*/
H5C__UPDATE_RP_FOR_INSERTION(cache_ptr, entry_ptr, NULL)
+ /* Update entries loaded in cache counter */
+ cache_ptr->entries_loaded_counter++;
+
/* Record that the entry was loaded, to trigger a notify callback later */
/* (After the entry is fully added to the cache) */
was_loaded = TRUE;
- } /* end else */
+ }
- HDassert(entry_ptr->addr == addr);
- HDassert(entry_ptr->type == type);
+ HDassert( entry_ptr->addr == addr );
+ HDassert( entry_ptr->type == type );
+
+ if ( entry_ptr->is_protected ) {
+
+ if ( ( read_only ) && ( entry_ptr->is_read_only ) ) {
+
+ HDassert( entry_ptr->ro_ref_count > 0 );
- if(entry_ptr->is_protected) {
- if(read_only && entry_ptr->is_read_only) {
- HDassert(entry_ptr->ro_ref_count > 0);
(entry_ptr->ro_ref_count)++;
- } /* end if */
- else
- HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, "Target already protected & not read only?!?")
- } /* end if */
- else {
+
+ } else {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, \
+ "Target already protected & not read only?!?.")
+ }
+ } else {
+
H5C__UPDATE_RP_FOR_PROTECT(cache_ptr, entry_ptr, NULL)
entry_ptr->is_protected = TRUE;
if ( read_only ) {
+
entry_ptr->is_read_only = TRUE;
entry_ptr->ro_ref_count = 1;
- } /* end if */
+ }
entry_ptr->dirtied = FALSE;
- } /* end else */
+ }
H5C__UPDATE_CACHE_HIT_RATE_STATS(cache_ptr, hit)
@@ -2692,7 +2703,7 @@ H5C_protect(H5F_t * f,
if ( cache_ptr->check_write_permitted != NULL ) {
if((cache_ptr->check_write_permitted)(f, &write_permitted) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, "Can't get write_permitted")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, "Can't get write_permitted 2")
else
have_write_permitted = TRUE;
} else {
@@ -2704,14 +2715,16 @@ H5C_protect(H5F_t * f,
}
}
- if(cache_ptr->resize_enabled &&
- (cache_ptr->cache_accesses >= (cache_ptr->resize_ctl).epoch_length)) {
+ if ( ( cache_ptr->resize_enabled ) &&
+ ( cache_ptr->cache_accesses >=
+ (cache_ptr->resize_ctl).epoch_length ) ) {
if(H5C__auto_adjust_cache_size(f, dxpl_id, write_permitted) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, "Cache auto-resize failed")
- } /* end if */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, "Cache auto-resize failed.")
+ }
+
+ if ( cache_ptr->size_decreased ) {
- if(cache_ptr->size_decreased) {
cache_ptr->size_decreased = FALSE;
/* check to see if the cache is now oversized due to the cache
@@ -2719,7 +2732,7 @@ H5C_protect(H5F_t * f,
* bring the cache size down to the current maximum cache size.
*
* Also, if the min_clean_size requirement is not met, we
- * should also call H5C__make_space_in_cache() to bring us
+ * should also call H5C_make_space_in_cache() to bring us
* into complience.
*/
@@ -2736,10 +2749,10 @@ H5C_protect(H5F_t * f,
if(cache_ptr->index_size > cache_ptr->max_cache_size)
cache_ptr->cache_full = TRUE;
- if(H5C__make_space_in_cache(f, dxpl_id, (size_t)0, write_permitted) < 0 )
- HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, "H5C__make_space_in_cache failed")
+ if(H5C_make_space_in_cache(f, dxpl_id, (size_t)0, write_permitted) < 0 )
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, "H5C_make_space_in_cache failed 2.")
}
- } /* end if */
+ }
}
/* If we loaded the entry and the entry's type has a 'notify' callback, send
@@ -2776,10 +2789,10 @@ H5C_protect(H5F_t * f,
done:
#if H5C_DO_EXTREME_SANITY_CHECKS
- if((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C_validate_pinned_entry_list(cache_ptr) < 0) ||
- (H5C_validate_lru_list(cache_ptr) < 0))
- HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, NULL, "an extreme sanity check failed on exit")
+ if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_lru_list(cache_ptr) < 0 ) )
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, NULL, "an extreme sanity check failed on exit.\n")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
FUNC_LEAVE_NOAPI(ret_value)
@@ -2806,7 +2819,7 @@ H5C_reset_cache_hit_rate_stats(H5C_t * cache_ptr)
FUNC_ENTER_NOAPI(FAIL)
if((cache_ptr == NULL) || (cache_ptr->magic != H5C__H5C_T_MAGIC))
- HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "bad cache_ptr on entry")
+ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "bad cache_ptr on entry.")
cache_ptr->cache_hits = 0;
cache_ptr->cache_accesses = 0;
@@ -2846,27 +2859,27 @@ H5C_set_cache_auto_resize_config(H5C_t *cache_ptr,
FUNC_ENTER_NOAPI(FAIL)
if((cache_ptr == NULL) || (cache_ptr->magic != H5C__H5C_T_MAGIC))
- HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "bad cache_ptr on entry")
+ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "bad cache_ptr on entry.")
if(config_ptr == NULL)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "NULL config_ptr on entry")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "NULL config_ptr on entry.")
if(config_ptr->version != H5C__CURR_AUTO_SIZE_CTL_VER)
- HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "unknown config version")
+ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "unknown config version.")
/* check general configuration section of the config: */
if(H5C_validate_resize_config(config_ptr, H5C_RESIZE_CFG__VALIDATE_GENERAL) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "error in general configuration fields of new config")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "error in general configuration fields of new config.")
/* check size increase control fields of the config: */
if(H5C_validate_resize_config(config_ptr, H5C_RESIZE_CFG__VALIDATE_INCREMENT) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "error in the size increase control fields of new config")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "error in the size increase control fields of new config.")
/* check size decrease control fields of the config: */
if(H5C_validate_resize_config(config_ptr, H5C_RESIZE_CFG__VALIDATE_DECREMENT) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "error in the size decrease control fields of new config")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "error in the size decrease control fields of new config.")
/* check for conflicts between size increase and size decrease controls: */
if(H5C_validate_resize_config(config_ptr, H5C_RESIZE_CFG__VALIDATE_INTERACTIONS) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "conflicting threshold fields in new config")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "conflicting threshold fields in new config.")
/* will set the increase possible fields to FALSE later if needed */
cache_ptr->size_increase_possible = TRUE;
@@ -2886,7 +2899,7 @@ H5C_set_cache_auto_resize_config(H5C_t *cache_ptr,
break;
default: /* should be unreachable */
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Unknown incr_mode?!?!?")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Unknown incr_mode?!?!?.")
} /* end switch */
/* logically, this is were configuration for flash cache size increases
@@ -2920,7 +2933,7 @@ H5C_set_cache_auto_resize_config(H5C_t *cache_ptr,
break;
default: /* should be unreachable */
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Unknown decr_mode?!?!?")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Unknown decr_mode?!?!?.")
} /* end switch */
if(config_ptr->max_size == config_ptr->min_size) {
@@ -2976,18 +2989,18 @@ H5C_set_cache_auto_resize_config(H5C_t *cache_ptr,
if(H5C_reset_cache_hit_rate_stats(cache_ptr) < 0)
/* this should be impossible... */
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_reset_cache_hit_rate_stats failed")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_reset_cache_hit_rate_stats failed.")
/* remove excess epoch markers if any */
if((config_ptr->decr_mode == H5C_decr__age_out_with_threshold) ||
(config_ptr->decr_mode == H5C_decr__age_out)) {
if(cache_ptr->epoch_markers_active > cache_ptr->resize_ctl.epochs_before_eviction)
if(H5C__autoadjust__ageout__remove_excess_markers(cache_ptr) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't remove excess epoch markers")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't remove excess epoch markers.")
} /* end if */
else if(cache_ptr->epoch_markers_active > 0) {
if(H5C__autoadjust__ageout__remove_all_markers(cache_ptr) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "error removing all epoch markers")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "error removing all epoch markers.")
}
/* configure flash size increase facility. We wait until the
@@ -3011,7 +3024,7 @@ H5C_set_cache_auto_resize_config(H5C_t *cache_ptr,
break;
default: /* should be unreachable */
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Unknown flash_incr_mode?!?!?")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Unknown flash_incr_mode?!?!?.")
break;
} /* end switch */
} /* end if */
@@ -3042,7 +3055,7 @@ H5C_set_evictions_enabled(H5C_t *cache_ptr, hbool_t evictions_enabled)
FUNC_ENTER_NOAPI(FAIL)
if((cache_ptr == NULL) || (cache_ptr->magic != H5C__H5C_T_MAGIC))
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad cache_ptr on entry")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad cache_ptr on entry.")
/* There is no fundamental reason why we should not permit
* evictions to be disabled while automatic resize is enabled.
@@ -3053,7 +3066,7 @@ H5C_set_evictions_enabled(H5C_t *cache_ptr, hbool_t evictions_enabled)
if((evictions_enabled != TRUE) &&
((cache_ptr->resize_ctl.incr_mode != H5C_incr__off) ||
(cache_ptr->resize_ctl.decr_mode != H5C_decr__off)))
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't disable evictions when auto resize enabled")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't disable evictions when auto resize enabled.")
cache_ptr->evictions_enabled = evictions_enabled;
@@ -3148,10 +3161,13 @@ H5C_unpin_entry(void *_entry_ptr)
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
#if H5C_DO_EXTREME_SANITY_CHECKS
- if((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C_validate_pinned_entry_list(cache_ptr) < 0) ||
- (H5C_validate_lru_list(cache_ptr) < 0))
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on entry")
+ if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "an extreme sanity check failed on entry.\n");
+ }
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
@@ -3160,14 +3176,19 @@ H5C_unpin_entry(void *_entry_ptr)
HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, "Can't unpin entry from client")
done:
+
#if H5C_DO_EXTREME_SANITY_CHECKS
- if((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C_validate_pinned_entry_list(cache_ptr) < 0) ||
- (H5C_validate_lru_list(cache_ptr) < 0))
- HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on exit")
+ if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "an extreme sanity check failed on exit.\n");
+ }
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
FUNC_LEAVE_NOAPI(ret_value)
+
} /* H5C_unpin_entry() */
@@ -3254,10 +3275,13 @@ H5C_unprotect(H5F_t * f,
was_clean = ! ( entry_ptr->is_dirty );
#if H5C_DO_EXTREME_SANITY_CHECKS
- if((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C_validate_pinned_entry_list(cache_ptr) < 0) ||
- (H5C_validate_lru_list(cache_ptr) < 0))
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on entry")
+ if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "an extreme sanity check failed on entry.\n");
+ }
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
/* if the entry has multiple read only protects, just decrement
@@ -3414,9 +3438,9 @@ H5C_unprotect(H5F_t * f,
/* verify that the target entry is in the cache. */
H5C__SEARCH_INDEX(cache_ptr, addr, test_entry_ptr, FAIL)
if(test_entry_ptr == NULL)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "entry not in hash table?!?")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "entry not in hash table?!?.")
else if(test_entry_ptr != entry_ptr)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "hash table contains multiple entries for addr?!?")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "hash table contains multiple entries for addr?!?.")
/* Set the 'free file space' flag for the flush, if needed */
if(free_file_space)
@@ -3439,9 +3463,9 @@ H5C_unprotect(H5F_t * f,
/* verify that the target entry is in the cache. */
H5C__SEARCH_INDEX(cache_ptr, addr, test_entry_ptr, FAIL)
if(test_entry_ptr == NULL)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "entry not in hash table?!?")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "entry not in hash table?!?.")
else if(test_entry_ptr != entry_ptr)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "hash table contains multiple entries for addr?!?")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "hash table contains multiple entries for addr?!?.")
if(H5C__flush_single_entry(f, dxpl_id, entry_ptr, H5C__FLUSH_CLEAR_ONLY_FLAG | H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "Can't clear entry")
@@ -3452,14 +3476,19 @@ H5C_unprotect(H5F_t * f,
H5C__UPDATE_STATS_FOR_UNPROTECT(cache_ptr)
done:
+
#if H5C_DO_EXTREME_SANITY_CHECKS
- if((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C_validate_pinned_entry_list(cache_ptr) < 0) ||
- (H5C_validate_lru_list(cache_ptr) < 0)) {
- HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on exit")
+ if ( ( H5C_validate_protected_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_pinned_entry_list(cache_ptr) < 0 ) ||
+ ( H5C_validate_lru_list(cache_ptr) < 0 ) ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "an extreme sanity check failed on exit.\n");
+ }
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
FUNC_LEAVE_NOAPI(ret_value)
+
} /* H5C_unprotect() */
@@ -3467,20 +3496,23 @@ done:
*
* Function: H5C_unsettle_entry_ring
*
- * Purpose: Advise the metadata cache that the specified entry's free space
- * manager ring is no longer settled (if it was on entry).
+ * Purpose: Advise the metadata cache that the specified entry's metadata
+ * cache manager ring is no longer settled (if it was on entry).
*
- * If the target free space manager ring is already
+ * If the target metadata cache manager ring is already
* unsettled, do nothing, and return SUCCEED.
*
- * If the target free space manager ring is settled, and
+ * If the target metadata cache manager ring is settled, and
* we are not in the process of a file shutdown, mark
* the ring as unsettled, and return SUCCEED.
*
- * If the target free space manager is settled, and we
+ * If the target metadata cache manager is settled, and we
* 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.
+ *
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
@@ -3560,13 +3592,18 @@ H5C_validate_resize_config(H5C_auto_size_ctl_t * config_ptr,
FUNC_ENTER_NOAPI(FAIL)
- if(config_ptr == NULL)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "NULL config_ptr on entry")
+ if ( config_ptr == NULL ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "NULL config_ptr on entry.")
+ }
+
+ if ( config_ptr->version != H5C__CURR_AUTO_SIZE_CTL_VER ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Unknown config version.")
+ }
- if(config_ptr->version != H5C__CURR_AUTO_SIZE_CTL_VER)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Unknown config version")
- if((tests & H5C_RESIZE_CFG__VALIDATE_GENERAL) != 0) {
+ if ( (tests & H5C_RESIZE_CFG__VALIDATE_GENERAL) != 0 ) {
if(config_ptr->max_size > H5C__MAX_MAX_CACHE_SIZE)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "max_size too big")
@@ -3577,29 +3614,43 @@ H5C_validate_resize_config(H5C_auto_size_ctl_t * config_ptr,
if(config_ptr->min_size > config_ptr->max_size)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "min_size > max_size")
- if(config_ptr->set_initial_size &&
- ((config_ptr->initial_size < config_ptr->min_size) ||
- (config_ptr->initial_size > config_ptr->max_size)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "initial_size must be in the interval [min_size, max_size]")
+ if ( ( config_ptr->set_initial_size ) &&
+ ( ( config_ptr->initial_size < config_ptr->min_size ) ||
+ ( config_ptr->initial_size > config_ptr->max_size ) ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "initial_size must be in the interval [min_size, max_size]");
+ }
+
+ if ( ( config_ptr->min_clean_fraction < (double)0.0f ) ||
+ ( config_ptr->min_clean_fraction > (double)1.0f ) ) {
- if((config_ptr->min_clean_fraction < (double)0.0f) ||
- (config_ptr->min_clean_fraction > (double)1.0f))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "min_clean_fraction must be in the interval [0.0, 1.0]")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "min_clean_fraction must be in the interval [0.0, 1.0]");
+ }
+
+ if ( config_ptr->epoch_length < H5C__MIN_AR_EPOCH_LENGTH ) {
- if(config_ptr->epoch_length < H5C__MIN_AR_EPOCH_LENGTH)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "epoch_length too small")
+ }
+
+ if ( config_ptr->epoch_length > H5C__MAX_AR_EPOCH_LENGTH ) {
- if(config_ptr->epoch_length > H5C__MAX_AR_EPOCH_LENGTH)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "epoch_length too big")
+ }
} /* H5C_RESIZE_CFG__VALIDATE_GENERAL */
- if((tests & H5C_RESIZE_CFG__VALIDATE_INCREMENT) != 0) {
- if((config_ptr->incr_mode != H5C_incr__off) &&
- (config_ptr->incr_mode != H5C_incr__threshold))
+ if ( (tests & H5C_RESIZE_CFG__VALIDATE_INCREMENT) != 0 ) {
+
+ if ( ( config_ptr->incr_mode != H5C_incr__off ) &&
+ ( config_ptr->incr_mode != H5C_incr__threshold ) ) {
+
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Invalid incr_mode")
+ }
+
+ if ( config_ptr->incr_mode == H5C_incr__threshold ) {
- if(config_ptr->incr_mode == H5C_incr__threshold) {
if((config_ptr->lower_hr_threshold < (double)0.0f) ||
(config_ptr->lower_hr_threshold > (double)1.0f))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "lower_hr_threshold must be in the range [0.0, 1.0]")
@@ -3612,24 +3663,33 @@ H5C_validate_resize_config(H5C_auto_size_ctl_t * config_ptr,
*/
} /* H5C_incr__threshold */
- switch(config_ptr->flash_incr_mode) {
+ switch ( config_ptr->flash_incr_mode )
+ {
case H5C_flash_incr__off:
/* nothing to do here */
break;
case H5C_flash_incr__add_space:
- if((config_ptr->flash_multiple < (double)0.1f) ||
- (config_ptr->flash_multiple > (double)10.0f))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "flash_multiple must be in the range [0.1, 10.0]")
- if((config_ptr->flash_threshold < (double)0.1f) ||
- (config_ptr->flash_threshold > (double)1.0f))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "flash_threshold must be in the range [0.1, 1.0]")
+ if ( ( config_ptr->flash_multiple < (double)0.1f ) ||
+ ( config_ptr->flash_multiple > (double)10.0f ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "flash_multiple must be in the range [0.1, 10.0]");
+ }
+
+ if ( ( config_ptr->flash_threshold < (double)0.1f ) ||
+ ( config_ptr->flash_threshold > (double)1.0f ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "flash_threshold must be in the range [0.1, 1.0]");
+ }
break;
default:
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Invalid flash_incr_mode")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "Invalid flash_incr_mode");
break;
- } /* end switch */
+ }
} /* H5C_RESIZE_CFG__VALIDATE_INCREMENT */
@@ -3645,23 +3705,35 @@ H5C_validate_resize_config(H5C_auto_size_ctl_t * config_ptr,
}
if ( config_ptr->decr_mode == H5C_decr__threshold ) {
- if(config_ptr->upper_hr_threshold > (double)1.0f)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "upper_hr_threshold must be <= 1.0")
- if((config_ptr->decrement > (double)1.0f) ||
- (config_ptr->decrement < (double)0.0f))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "decrement must be in the interval [0.0, 1.0]")
+ if ( config_ptr->upper_hr_threshold > (double)1.0f ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "upper_hr_threshold must be <= 1.0");
+ }
+
+ if ( ( config_ptr->decrement > (double)1.0f ) ||
+ ( config_ptr->decrement < (double)0.0f ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "decrement must be in the interval [0.0, 1.0]");
+ }
/* no need to check max_decrement as it is a size_t
* and thus must be non-negative.
*/
} /* H5C_decr__threshold */
- if((config_ptr->decr_mode == H5C_decr__age_out) ||
- (config_ptr->decr_mode == H5C_decr__age_out_with_threshold)) {
+ if ( ( config_ptr->decr_mode == H5C_decr__age_out ) ||
+ ( config_ptr->decr_mode == H5C_decr__age_out_with_threshold )
+ ) {
+
+ if ( config_ptr->epochs_before_eviction < 1 ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "epochs_before_eviction must be positive");
+ }
- if(config_ptr->epochs_before_eviction < 1)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "epochs_before_eviction must be positive")
if(config_ptr->epochs_before_eviction > H5C__MAX_EPOCH_MARKERS)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "epochs_before_eviction too big")
@@ -3675,24 +3747,43 @@ H5C_validate_resize_config(H5C_auto_size_ctl_t * config_ptr,
*/
} /* H5C_decr__age_out || H5C_decr__age_out_with_threshold */
- if(config_ptr->decr_mode == H5C_decr__age_out_with_threshold) {
- if((config_ptr->upper_hr_threshold > (double)1.0f) ||
- (config_ptr->upper_hr_threshold < (double)0.0f))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "upper_hr_threshold must be in the interval [0.0, 1.0]")
+ if ( config_ptr->decr_mode == H5C_decr__age_out_with_threshold ) {
+
+ if ( ( config_ptr->upper_hr_threshold > (double)1.0f ) ||
+ ( config_ptr->upper_hr_threshold < (double)0.0f ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "upper_hr_threshold must be in the interval [0.0, 1.0]");
+ }
} /* H5C_decr__age_out_with_threshold */
+
} /* H5C_RESIZE_CFG__VALIDATE_DECREMENT */
if ( (tests & H5C_RESIZE_CFG__VALIDATE_INTERACTIONS) != 0 ) {
- if((config_ptr->incr_mode == H5C_incr__threshold)
- && ((config_ptr->decr_mode == H5C_decr__threshold) ||
- (config_ptr->decr_mode == H5C_decr__age_out_with_threshold))
- && (config_ptr->lower_hr_threshold >= config_ptr->upper_hr_threshold))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "conflicting threshold fields in config")
+
+ if ( ( config_ptr->incr_mode == H5C_incr__threshold )
+ &&
+ ( ( config_ptr->decr_mode == H5C_decr__threshold )
+ ||
+ ( config_ptr->decr_mode == H5C_decr__age_out_with_threshold )
+ )
+ &&
+ ( config_ptr->lower_hr_threshold
+ >=
+ config_ptr->upper_hr_threshold
+ )
+ ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "conflicting threshold fields in config.")
+ }
} /* H5C_RESIZE_CFG__VALIDATE_INTERACTIONS */
done:
+
FUNC_LEAVE_NOAPI(ret_value)
+
} /* H5C_validate_resize_config() */
@@ -3788,7 +3879,6 @@ H5C_create_flush_dependency(void * parent_thing, void * child_thing)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for flush dependency parent list")
child_entry->flush_dep_parent_nalloc *= 2;
} /* end else */
- cache_ptr->entry_fd_height_change_counter++;
} /* end if */
/* Add the dependency to the child's parent array */
@@ -3996,7 +4086,7 @@ H5C__auto_adjust_cache_size(H5F_t * f,
hbool_t write_permitted)
{
H5C_t * cache_ptr = f->shared->cache;
- hbool_t reentrant_call = FALSE;
+ herr_t result;
hbool_t inserted_epoch_marker = FALSE;
size_t new_max_cache_size = 0;
size_t old_max_cache_size = 0;
@@ -4016,33 +4106,29 @@ H5C__auto_adjust_cache_size(H5F_t * f,
HDassert( (double)0.0f <= (cache_ptr->resize_ctl).min_clean_fraction );
HDassert( (cache_ptr->resize_ctl).min_clean_fraction <= (double)100.0f );
- /* check to see if cache_ptr->resize_in_progress is TRUE. If it, this
- * is a re-entrant call via a client callback called in the resize
- * process. To avoid an infinite recursion, set reentrant_call to
- * TRUE, and goto done.
- */
- if(cache_ptr->resize_in_progress) {
- reentrant_call = TRUE;
- HGOTO_DONE(SUCCEED)
- } /* end if */
+ if ( !cache_ptr->resize_enabled ) {
- cache_ptr->resize_in_progress = TRUE;
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Auto cache resize disabled.")
+ }
- if(!cache_ptr->resize_enabled)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Auto cache resize disabled")
+ HDassert( ( (cache_ptr->resize_ctl).incr_mode != H5C_incr__off ) || \
+ ( (cache_ptr->resize_ctl).decr_mode != H5C_decr__off ) );
- HDassert(((cache_ptr->resize_ctl).incr_mode != H5C_incr__off) || \
- ((cache_ptr->resize_ctl).decr_mode != H5C_decr__off));
+ if ( H5C_get_cache_hit_rate(cache_ptr, &hit_rate) != SUCCEED ) {
- if(H5C_get_cache_hit_rate(cache_ptr, &hit_rate) != SUCCEED)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't get hit rate")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't get hit rate.")
+ }
HDassert( ( (double)0.0f <= hit_rate ) && ( hit_rate <= (double)1.0f ) );
- switch((cache_ptr->resize_ctl).incr_mode) {
+ switch ( (cache_ptr->resize_ctl).incr_mode )
+ {
case H5C_incr__off:
- if(cache_ptr->size_increase_possible)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "size_increase_possible but H5C_incr__off?!?!?")
+ if ( cache_ptr->size_increase_possible ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "size_increase_possible but H5C_incr__off?!?!?")
+ }
break;
case H5C_incr__threshold:
@@ -4092,7 +4178,7 @@ H5C__auto_adjust_cache_size(H5F_t * f,
break;
default:
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unknown incr_mode")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unknown incr_mode.")
}
/* If the decr_mode is either age out or age out with threshold, we
@@ -4119,10 +4205,17 @@ H5C__auto_adjust_cache_size(H5F_t * f,
)
) {
- if(H5C__autoadjust__ageout__insert_new_marker(cache_ptr) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't insert new epoch marker")
+ result = H5C__autoadjust__ageout__insert_new_marker(cache_ptr);
- inserted_epoch_marker = TRUE;
+ if ( result != SUCCEED ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "can't insert new epoch marker.")
+
+ } else {
+
+ inserted_epoch_marker = TRUE;
+ }
}
/* don't run the cache size decrease code unless the cache size
@@ -4182,18 +4275,32 @@ H5C__auto_adjust_cache_size(H5F_t * f,
case H5C_decr__age_out_with_threshold:
case H5C_decr__age_out:
- if(!inserted_epoch_marker) {
- if(!cache_ptr->size_decrease_possible)
+ if ( ! inserted_epoch_marker ) {
+
+ if ( ! cache_ptr->size_decrease_possible ) {
+
status = decrease_disabled;
- else {
- if(H5C__autoadjust__ageout(f, dxpl_id, hit_rate, &status, &new_max_cache_size, write_permitted) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "ageout code failed")
- } /* end else */
- } /* end if */
+
+ } else {
+
+ result = H5C__autoadjust__ageout(f,
+ dxpl_id,
+ hit_rate,
+ &status,
+ &new_max_cache_size,
+ write_permitted);
+
+ if ( result != SUCCEED ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "ageout code failed.")
+ }
+ }
+ }
break;
default:
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unknown incr_mode")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unknown incr_mode.")
}
}
@@ -4209,8 +4316,13 @@ H5C__auto_adjust_cache_size(H5F_t * f,
) {
/* move last epoch marker to the head of the LRU list */
- if(H5C__autoadjust__ageout__cycle_epoch_marker(cache_ptr) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "error cycling epoch marker")
+ result = H5C__autoadjust__ageout__cycle_epoch_marker(cache_ptr);
+
+ if ( result != SUCCEED ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "error cycling epoch marker.")
+ }
}
if ( ( status == increase ) || ( status == decrease ) ) {
@@ -4251,7 +4363,9 @@ H5C__auto_adjust_cache_size(H5F_t * f,
switch ( (cache_ptr->resize_ctl).flash_incr_mode )
{
case H5C_flash_incr__off:
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "flash_size_increase_possible but H5C_flash_incr__off?!")
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "flash_size_increase_possible but H5C_flash_incr__off?!")
break;
case H5C_flash_incr__add_space:
@@ -4262,13 +4376,15 @@ H5C__auto_adjust_cache_size(H5F_t * f,
break;
default: /* should be unreachable */
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Unknown flash_incr_mode?!?!?")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "Unknown flash_incr_mode?!?!?.")
break;
}
}
}
if ( (cache_ptr->resize_ctl).rpt_fcn != NULL ) {
+
(*((cache_ptr->resize_ctl).rpt_fcn))
(cache_ptr,
H5C__CURR_AUTO_RESIZE_RPT_FCN_VER,
@@ -4280,17 +4396,14 @@ H5C__auto_adjust_cache_size(H5F_t * f,
new_min_clean_size);
}
- if(H5C_reset_cache_hit_rate_stats(cache_ptr) < 0)
+ if ( H5C_reset_cache_hit_rate_stats(cache_ptr) != SUCCEED ) {
+
/* this should be impossible... */
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_reset_cache_hit_rate_stats failed")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "H5C_reset_cache_hit_rate_stats failed.")
+ }
done:
- /* Sanity checks */
- HDassert(cache_ptr->resize_in_progress);
- if(!reentrant_call)
- cache_ptr->resize_in_progress = FALSE;
- HDassert((!reentrant_call) || (cache_ptr->resize_in_progress));
-
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C__auto_adjust_cache_size() */
@@ -4323,6 +4436,7 @@ H5C__autoadjust__ageout(H5F_t * f,
hbool_t write_permitted)
{
H5C_t * cache_ptr = f->shared->cache;
+ herr_t result;
size_t test_size;
herr_t ret_value = SUCCEED; /* Return value */
@@ -4335,9 +4449,17 @@ H5C__autoadjust__ageout(H5F_t * f,
HDassert( ( new_max_cache_size_ptr ) && ( *new_max_cache_size_ptr == 0 ) );
/* remove excess epoch markers if any */
- if(cache_ptr->epoch_markers_active > (cache_ptr->resize_ctl).epochs_before_eviction)
- if(H5C__autoadjust__ageout__remove_excess_markers(cache_ptr) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't remove excess epoch markers")
+ if ( cache_ptr->epoch_markers_active >
+ (cache_ptr->resize_ctl).epochs_before_eviction ) {
+
+ result = H5C__autoadjust__ageout__remove_excess_markers(cache_ptr);
+
+ if ( result != SUCCEED ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "can't remove excess epoch markers.")
+ }
+ }
if ( ( (cache_ptr->resize_ctl).decr_mode == H5C_decr__age_out )
||
@@ -4353,7 +4475,7 @@ H5C__autoadjust__ageout(H5F_t * f,
/* evict aged out cache entries if appropriate... */
if(H5C__autoadjust__ageout__evict_aged_out_entries(f, dxpl_id, write_permitted) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "error flushing aged out entries")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "error flushing aged out entries.")
/* ... and then reduce cache size if appropriate */
if ( cache_ptr->index_size < cache_ptr->max_cache_size ) {
@@ -4435,8 +4557,11 @@ H5C__autoadjust__ageout__cycle_epoch_marker(H5C_t * cache_ptr)
HDassert( cache_ptr );
HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
- if(cache_ptr->epoch_markers_active <= 0)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "No active epoch markers on entry?!?!?")
+ if ( cache_ptr->epoch_markers_active <= 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "No active epoch markers on entry?!?!?.")
+ }
/* remove the last marker from both the ring buffer and the LRU list */
@@ -4448,10 +4573,15 @@ H5C__autoadjust__ageout__cycle_epoch_marker(H5C_t * cache_ptr)
cache_ptr->epoch_marker_ringbuf_size -= 1;
- if(cache_ptr->epoch_marker_ringbuf_size < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "ring buffer underflow")
- if((cache_ptr->epoch_marker_active)[i] != TRUE)
+ if ( cache_ptr->epoch_marker_ringbuf_size < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "ring buffer underflow.")
+ }
+
+ if ( (cache_ptr->epoch_marker_active)[i] != TRUE ) {
+
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unused marker in LRU?!?")
+ }
H5C__DLL_REMOVE((&((cache_ptr->epoch_markers)[i])), \
(cache_ptr)->LRU_head_ptr, \
@@ -4464,9 +4594,9 @@ H5C__autoadjust__ageout__cycle_epoch_marker(H5C_t * cache_ptr)
* the ring buffer.
*/
- HDassert(((cache_ptr->epoch_markers)[i]).addr == (haddr_t)i);
- HDassert(((cache_ptr->epoch_markers)[i]).next == NULL);
- HDassert(((cache_ptr->epoch_markers)[i]).prev == NULL);
+ HDassert( ((cache_ptr->epoch_markers)[i]).addr == (haddr_t)i );
+ HDassert( ((cache_ptr->epoch_markers)[i]).next == NULL );
+ HDassert( ((cache_ptr->epoch_markers)[i]).prev == NULL );
cache_ptr->epoch_marker_ringbuf_last =
(cache_ptr->epoch_marker_ringbuf_last + 1) %
@@ -4476,8 +4606,10 @@ H5C__autoadjust__ageout__cycle_epoch_marker(H5C_t * cache_ptr)
cache_ptr->epoch_marker_ringbuf_size += 1;
- if(cache_ptr->epoch_marker_ringbuf_size > H5C__MAX_EPOCH_MARKERS)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "ring buffer overflow")
+ if ( cache_ptr->epoch_marker_ringbuf_size > H5C__MAX_EPOCH_MARKERS ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "ring buffer overflow.")
+ }
H5C__DLL_PREPEND((&((cache_ptr->epoch_markers)[i])), \
(cache_ptr)->LRU_head_ptr, \
@@ -4539,6 +4671,19 @@ done:
*
* Programmer: John Mainzer, 11/22/04
*
+ * Changes: Modified function to detect deletions of entries
+ * during a scan of the LRU, and where appropriate,
+ * restart the scan to avoid proceeding with a next
+ * entry that is no longer in the cache.
+ *
+ * Note the absence of checks after flushes of clean
+ * entries. As a second entry can only be removed by
+ * by a call to the pre_serialize or serialize callback
+ * of the first, and as these callbacks will not be called
+ * on clean entries, no checks are needed.
+ *
+ * JRM -- 4/6/15
+ *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -4630,26 +4775,39 @@ H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t * f,
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush entry")
}
- if(prev_ptr != NULL) {
+ if ( prev_ptr != NULL ) {
+
if(corked) /* dirty corked entry is skipped */
entry_ptr = prev_ptr;
- else if(restart_scan || (prev_ptr->is_dirty != prev_is_dirty)
- || (prev_ptr->next != next_ptr)
- || (prev_ptr->is_protected)
- || (prev_ptr->is_pinned)) {
- /* Something has happened to the LRU -- start over
+
+ else if ( ( restart_scan )
+ ||
+ ( prev_ptr->is_dirty != prev_is_dirty )
+ ||
+ ( prev_ptr->next != next_ptr )
+ ||
+ ( prev_ptr->is_protected )
+ ||
+ ( prev_ptr->is_pinned ) ) {
+
+ /* something has happened to the LRU -- start over
* from the tail.
*/
restart_scan = FALSE;
entry_ptr = cache_ptr->LRU_tail_ptr;
H5C__UPDATE_STATS_FOR_LRU_SCAN_RESTART(cache_ptr)
- } /* end else-if */
- else
+
+ } else {
+
entry_ptr = prev_ptr;
- } /* end if */
- else
+
+ }
+ } else {
+
entry_ptr = NULL;
+
+ }
} /* end while */
/* for now at least, don't bother to maintain the minimum clean size,
@@ -4667,9 +4825,9 @@ H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t * f,
* entry).
*/
- } /* end if */
- else /* ! write_permitted */ {
- /* Since we are not allowed to write, all we can do is evict
+ } else /* ! write_permitted */ {
+
+ /* since we are not allowed to write, all we can do is evict
* any clean entries that we may encounter before we either
* hit the eviction size limit, or encounter the epoch marker.
*
@@ -4682,19 +4840,23 @@ H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t * f,
* performance implications, but it shouldn't cause any net
* slowdown.
*/
- HDassert(H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS);
+
+ HDassert( H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS );
+
entry_ptr = cache_ptr->LRU_tail_ptr;
- while(entry_ptr != NULL &&
- ((entry_ptr->type)->id != H5AC_EPOCH_MARKER_ID) &&
- (bytes_evicted < eviction_size_limit)) {
- HDassert(!(entry_ptr->is_protected));
+
+ while ( ( entry_ptr != NULL ) &&
+ ( (entry_ptr->type)->id != H5AC_EPOCH_MARKER_ID ) &&
+ ( bytes_evicted < eviction_size_limit ) )
+ {
+ HDassert( ! (entry_ptr->is_protected) );
prev_ptr = entry_ptr->prev;
- if(!(entry_ptr->is_dirty)) {
+ if ( ! (entry_ptr->is_dirty) ) {
if(H5C__flush_single_entry(f, dxpl_id, entry_ptr, H5C__FLUSH_INVALIDATE_FLAG | H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush clean entry")
- } /* end if */
+ }
/* just skip the entry if it is dirty, as we can't do
* anything with it now since we can't write.
*
@@ -4702,15 +4864,21 @@ H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t * f,
* and thus we needn't test to see if the LRU has been changed
* out from under us.
*/
+
entry_ptr = prev_ptr;
+
} /* end while */
- } /* end else */
+ }
+
+ if ( cache_ptr->index_size < cache_ptr->max_cache_size ) {
- if(cache_ptr->index_size < cache_ptr->max_cache_size)
cache_ptr->cache_full = FALSE;
+ }
done:
+
FUNC_LEAVE_NOAPI(ret_value)
+
} /* H5C__autoadjust__ageout__evict_aged_out_entries() */
@@ -4739,16 +4907,23 @@ H5C__autoadjust__ageout__insert_new_marker(H5C_t * cache_ptr)
HDassert( cache_ptr );
HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
- if(cache_ptr->epoch_markers_active >= (cache_ptr->resize_ctl).epochs_before_eviction)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Already have a full complement of markers")
+ if ( cache_ptr->epoch_markers_active >=
+ (cache_ptr->resize_ctl).epochs_before_eviction ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "Already have a full complement of markers.")
+ }
/* find an unused marker */
i = 0;
- while((cache_ptr->epoch_marker_active)[i] && i < H5C__MAX_EPOCH_MARKERS)
+ while ( ( (cache_ptr->epoch_marker_active)[i] ) &&
+ ( i < H5C__MAX_EPOCH_MARKERS ) )
+ {
i++;
+ }
if(i >= H5C__MAX_EPOCH_MARKERS)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't find unused marker")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't find unused marker.")
HDassert( ((cache_ptr->epoch_markers)[i]).addr == (haddr_t)i );
HDassert( ((cache_ptr->epoch_markers)[i]).next == NULL );
@@ -4766,7 +4941,7 @@ H5C__autoadjust__ageout__insert_new_marker(H5C_t * cache_ptr)
if ( cache_ptr->epoch_marker_ringbuf_size > H5C__MAX_EPOCH_MARKERS ) {
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "ring buffer overflow")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "ring buffer overflow.")
}
H5C__DLL_PREPEND((&((cache_ptr->epoch_markers)[i])), \
@@ -4825,11 +5000,15 @@ H5C__autoadjust__ageout__remove_all_markers(H5C_t * cache_ptr)
cache_ptr->epoch_marker_ringbuf_size -= 1;
- if(cache_ptr->epoch_marker_ringbuf_size < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "ring buffer underflow")
+ if ( cache_ptr->epoch_marker_ringbuf_size < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "ring buffer underflow.")
+ }
+
+ if ( (cache_ptr->epoch_marker_active)[i] != TRUE ) {
- if((cache_ptr->epoch_marker_active)[i] != TRUE)
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unused marker in LRU?!?")
+ }
/* remove the epoch marker from the LRU list */
H5C__DLL_REMOVE((&((cache_ptr->epoch_markers)[i])), \
@@ -4887,10 +5066,15 @@ H5C__autoadjust__ageout__remove_excess_markers(H5C_t * cache_ptr)
HDassert( cache_ptr );
HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
- if(cache_ptr->epoch_markers_active <= (cache_ptr->resize_ctl).epochs_before_eviction)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "no excess markers on entry")
+ if ( cache_ptr->epoch_markers_active <=
+ (cache_ptr->resize_ctl).epochs_before_eviction ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "no excess markers on entry.")
+ }
- while(cache_ptr->epoch_markers_active > (cache_ptr->resize_ctl).epochs_before_eviction) {
+ while ( cache_ptr->epoch_markers_active >
+ (cache_ptr->resize_ctl).epochs_before_eviction )
+ {
/* get the index of the last epoch marker in the LRU list
* and remove it from the ring buffer.
*/
@@ -4904,10 +5088,15 @@ H5C__autoadjust__ageout__remove_excess_markers(H5C_t * cache_ptr)
cache_ptr->epoch_marker_ringbuf_size -= 1;
- if(cache_ptr->epoch_marker_ringbuf_size < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "ring buffer underflow")
- if((cache_ptr->epoch_marker_active)[i] != TRUE)
+ if ( cache_ptr->epoch_marker_ringbuf_size < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "ring buffer underflow.")
+ }
+
+ if ( (cache_ptr->epoch_marker_active)[i] != TRUE ) {
+
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unused marker in LRU?!?")
+ }
/* remove the epoch marker from the LRU list */
H5C__DLL_REMOVE((&((cache_ptr->epoch_markers)[i])), \
@@ -4976,8 +5165,11 @@ H5C__flash_increase_cache_size(H5C_t * cache_ptr,
HDassert( new_entry_size > cache_ptr->flash_size_increase_threshold );
HDassert( old_entry_size < new_entry_size );
- if(old_entry_size >= new_entry_size)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "old_entry_size >= new_entry_size")
+ if ( old_entry_size >= new_entry_size ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "old_entry_size >= new_entry_size")
+ }
space_needed = new_entry_size - old_entry_size;
@@ -4990,7 +5182,8 @@ H5C__flash_increase_cache_size(H5C_t * cache_ptr,
switch ( (cache_ptr->resize_ctl).flash_incr_mode )
{
case H5C_flash_incr__off:
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "flash_size_increase_possible but H5C_flash_incr__off?!")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "flash_size_increase_possible but H5C_flash_incr__off?!")
break;
case H5C_flash_incr__add_space:
@@ -5010,7 +5203,8 @@ H5C__flash_increase_cache_size(H5C_t * cache_ptr,
break;
default: /* should be unreachable */
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Unknown flash_incr_mode?!?!?")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "Unknown flash_incr_mode?!?!?.")
break;
}
@@ -5039,7 +5233,8 @@ H5C__flash_increase_cache_size(H5C_t * cache_ptr,
switch ( (cache_ptr->resize_ctl).flash_incr_mode )
{
case H5C_flash_incr__off:
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "flash_size_increase_possible but H5C_flash_incr__off?!")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "flash_size_increase_possible but H5C_flash_incr__off?!")
break;
case H5C_flash_incr__add_space:
@@ -5050,7 +5245,8 @@ H5C__flash_increase_cache_size(H5C_t * cache_ptr,
break;
default: /* should be unreachable */
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Unknown flash_incr_mode?!?!?")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "Unknown flash_incr_mode?!?!?.")
break;
}
@@ -5064,8 +5260,10 @@ H5C__flash_increase_cache_size(H5C_t * cache_ptr,
/* get the hit rate for the reporting function. Should still
* be good as we havent reset the hit rate statistics.
*/
- if(H5C_get_cache_hit_rate(cache_ptr, &hit_rate) != SUCCEED)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't get hit rate")
+ if ( H5C_get_cache_hit_rate(cache_ptr, &hit_rate) != SUCCEED ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't get hit rate.")
+ }
(*((cache_ptr->resize_ctl).rpt_fcn))
(cache_ptr,
@@ -5078,9 +5276,12 @@ H5C__flash_increase_cache_size(H5C_t * cache_ptr,
new_min_clean_size);
}
- if(H5C_reset_cache_hit_rate_stats(cache_ptr) < 0)
+ if ( H5C_reset_cache_hit_rate_stats(cache_ptr) != SUCCEED ) {
+
/* this should be impossible... */
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_reset_cache_hit_rate_stats failed")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "H5C_reset_cache_hit_rate_stats failed.")
+ }
}
done:
@@ -5146,8 +5347,8 @@ H5C_flush_invalidate_cache(H5F_t *f, hid_t dxpl_id, unsigned flags)
#if H5C_DO_SANITY_CHECKS
{
int32_t i;
- uint32_t index_len = 0;
- uint32_t slist_len = 0;
+ int32_t index_len = 0;
+ int32_t slist_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;
@@ -5182,7 +5383,7 @@ H5C_flush_invalidate_cache(H5F_t *f, hid_t dxpl_id, unsigned flags)
/* remove ageout markers if present */
if(cache_ptr->epoch_markers_active > 0)
if(H5C__autoadjust__ageout__remove_all_markers(cache_ptr) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "error removing all epoch markers")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "error removing all epoch markers.")
/* flush invalidate each ring, starting from the outermost ring and
* working inward.
@@ -5190,7 +5391,7 @@ H5C_flush_invalidate_cache(H5F_t *f, hid_t dxpl_id, unsigned flags)
ring = H5C_RING_USER;
while(ring < H5C_RING_NTYPES) {
if(H5C_flush_invalidate_ring(f, dxpl_id, ring, flags) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "flush invalidate ring failed")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "flush invalidate ring failed.")
ring++;
} /* end while */
@@ -5278,7 +5479,7 @@ H5C_flush_invalidate_ring(H5F_t * f, hid_t dxpl_id, H5C_ring_t ring,
{
H5C_t *cache_ptr;
hbool_t restart_slist_scan;
- uint32_t protected_entries = 0;
+ int32_t protected_entries = 0;
int32_t i;
int32_t cur_ring_pel_len;
int32_t old_ring_pel_len;
@@ -5288,7 +5489,7 @@ H5C_flush_invalidate_ring(H5F_t * f, hid_t dxpl_id, H5C_ring_t ring,
H5C_cache_entry_t *entry_ptr = NULL;
H5C_cache_entry_t *next_entry_ptr = NULL;
#if H5C_DO_SANITY_CHECKS
- uint32_t initial_slist_len = 0;
+ int64_t initial_slist_len = 0;
size_t initial_slist_size = 0;
#endif /* H5C_DO_SANITY_CHECKS */
herr_t ret_value = SUCCEED;
@@ -5473,10 +5674,9 @@ H5C_flush_invalidate_ring(H5F_t * f, hid_t dxpl_id, H5C_ring_t ring,
* everything we can before we flag an error.
*/
protected_entries++;
- } /* end if */
- else if(entry_ptr->is_pinned) {
+ } else if(entry_ptr->is_pinned) {
if(H5C__flush_single_entry(f, dxpl_id, entry_ptr, H5C__DURING_FLUSH_FLAG) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "dirty pinned entry flush failed")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "dirty pinned entry flush failed.")
if(cache_ptr->slist_changed) {
/* The slist has been modified by something
@@ -5490,10 +5690,10 @@ H5C_flush_invalidate_ring(H5F_t * f, hid_t dxpl_id, H5C_ring_t ring,
cache_ptr->slist_changed = FALSE;
H5C__UPDATE_STATS_FOR_SLIST_SCAN_RESTART(cache_ptr);
} /* end if */
- } /* end else-if */
+ } /* end if */
else {
if(H5C__flush_single_entry(f, dxpl_id, entry_ptr, (cooked_flags | H5C__DURING_FLUSH_FLAG | H5C__FLUSH_INVALIDATE_FLAG | H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG)) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "dirty entry flush destroy failed")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "dirty entry flush destroy failed.")
if(cache_ptr->slist_changed) {
/* The slist has been modified by something
@@ -5522,8 +5722,8 @@ H5C_flush_invalidate_ring(H5F_t * f, hid_t dxpl_id, H5C_ring_t ring,
*/
if(node_ptr == NULL) {
- HDassert(cache_ptr->slist_len == (uint32_t)((int32_t)initial_slist_len + cache_ptr->slist_len_increase));
- HDassert(cache_ptr->slist_size == (size_t)((ssize_t)initial_slist_size + cache_ptr->slist_size_increase));
+ HDassert(cache_ptr->slist_len == (initial_slist_len + cache_ptr->slist_len_increase));
+ HDassert((int64_t)cache_ptr->slist_size == ((int64_t)initial_slist_size + cache_ptr->slist_size_increase));
} /* end if */
#endif /* H5C_DO_SANITY_CHECKS */
@@ -5597,7 +5797,7 @@ H5C_flush_invalidate_ring(H5F_t * f, hid_t dxpl_id, H5C_ring_t ring,
cache_ptr->entry_watched_for_removal = next_entry_ptr;
if(H5C__flush_single_entry(f, dxpl_id, entry_ptr, (cooked_flags | H5C__DURING_FLUSH_FLAG | H5C__FLUSH_INVALIDATE_FLAG | H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG)) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Entry flush destroy failed")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Entry flush destroy failed.")
/* Restart the index list scan if necessary. Must
* do this if the next entry is evicted, and also if
@@ -5678,9 +5878,9 @@ H5C_flush_invalidate_ring(H5F_t * f, hid_t dxpl_id, H5C_ring_t ring,
HDassert(protected_entries <= cache_ptr->pl_len);
if(protected_entries > 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Cache has protected entries")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Cache has protected entries.")
else if(cur_ring_pel_len > 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't unpin all pinned entries in ring")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't unpin all pinned entries in ring.")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -5720,12 +5920,12 @@ H5C_flush_ring(H5F_t *f, hid_t dxpl_id, H5C_ring_t ring, unsigned flags)
hbool_t ignore_protected;
hbool_t tried_to_flush_protected_entry = FALSE;
hbool_t restart_slist_scan;
- uint32_t protected_entries = 0;
+ int32_t protected_entries = 0;
H5SL_node_t * node_ptr = NULL;
H5C_cache_entry_t * entry_ptr = NULL;
H5C_cache_entry_t * next_entry_ptr = NULL;
#if H5C_DO_SANITY_CHECKS
- uint32_t initial_slist_len = 0;
+ int64_t initial_slist_len = 0;
size_t initial_slist_size = 0;
#endif /* H5C_DO_SANITY_CHECKS */
int i;
@@ -5744,7 +5944,7 @@ H5C_flush_ring(H5F_t *f, hid_t dxpl_id, H5C_ring_t ring, unsigned flags)
if((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
(H5C_validate_pinned_entry_list(cache_ptr) < 0) ||
(H5C_validate_lru_list(cache_ptr) < 0))
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on entry")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on entry.\n")
#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
ignore_protected = ( (flags & H5C__FLUSH_IGNORE_PROTECTED_FLAG) != 0 );
@@ -5908,7 +6108,7 @@ H5C_flush_ring(H5F_t *f, hid_t dxpl_id, H5C_ring_t ring, unsigned flags)
} /* end if */
else {
if(H5C__flush_single_entry(f, dxpl_id, entry_ptr, (flags | H5C__DURING_FLUSH_FLAG)) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush entry")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush entry.")
if(cache_ptr->slist_changed) {
/* The slist has been modified by something
@@ -5930,8 +6130,8 @@ H5C_flush_ring(H5F_t *f, hid_t dxpl_id, H5C_ring_t ring, unsigned flags)
#if H5C_DO_SANITY_CHECKS
/* Verify that the slist size and length are as expected. */
- HDassert((uint32_t)((int32_t)initial_slist_len + cache_ptr->slist_len_increase) == cache_ptr->slist_len);
- HDassert((size_t)((ssize_t)initial_slist_size + cache_ptr->slist_size_increase) == cache_ptr->slist_size);
+ HDassert((initial_slist_len + cache_ptr->slist_len_increase) == cache_ptr->slist_len);
+ HDassert((size_t)((int64_t)initial_slist_size + cache_ptr->slist_size_increase) == cache_ptr->slist_size);
#endif /* H5C_DO_SANITY_CHECKS */
} /* while */
@@ -5983,6 +6183,34 @@ done:
*
* Programmer: John Mainzer, 5/5/04
*
+ * Changes: Refactored function to remove the type_ptr parameter.
+ *
+ * JRM -- 8/7/14
+ *
+ * Added code to check for slist changes in pre_serialize and
+ * serialize calls, and set
+ * cache_ptr->slist_change_in_pre_serialize and
+ * cache_ptr->slist_change_in_serialize as appropriate.
+ *
+ * JRM -- 12/13/14
+ *
+ * Refactored function to delay all modifications of the
+ * metadata cache data structures until after any calls
+ * to the pre-serialize or serialize callbacks.
+ *
+ * Need to do this, as some pre-serialize or serialize
+ * calls result in calls to the metadata cache and
+ * modifications to its data structures. Thus, at the
+ * time of any such call, the target entry flags and
+ * the metadata cache must all be consistant.
+ *
+ * Also added the entry_size_change_ptr parameter, which
+ * allows the function to report back any change in the size
+ * of the entry during the flush. Such size changes may
+ * occur during the pre-serialize callback.
+ *
+ * JRM -- 12/24/14
+ *
*-------------------------------------------------------------------------
*/
herr_t
@@ -6000,8 +6228,6 @@ H5C__flush_single_entry(H5F_t *f, hid_t dxpl_id, H5C_cache_entry_t *entry_ptr,
hbool_t destroy_entry; /* internal flag */
hbool_t generate_image; /* internal flag */
hbool_t was_dirty;
- hbool_t suppress_image_entry_writes = FALSE;
- hbool_t suppress_image_entry_frees = FALSE;
haddr_t entry_addr = HADDR_UNDEF;
herr_t ret_value = SUCCEED; /* Return value */
@@ -6014,7 +6240,6 @@ H5C__flush_single_entry(H5F_t *f, hid_t dxpl_id, H5C_cache_entry_t *entry_ptr,
HDassert(entry_ptr);
HDassert(entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
HDassert(entry_ptr->ring != H5C_RING_UNDEFINED);
- HDassert(entry_ptr->type);
/* setup external flags from the flags parameter */
destroy = ((flags & H5C__FLUSH_INVALIDATE_FLAG) != 0);
@@ -6045,64 +6270,44 @@ H5C__flush_single_entry(H5F_t *f, hid_t dxpl_id, H5C_cache_entry_t *entry_ptr,
else
write_entry = FALSE;
- /* if we have received close warning, and we have been instructed to
- * generate a metadata cache image, and we have actually constructed
- * the entry images, set suppress_image_entry_frees to TRUE.
- *
- * Set suppress_image_entry_writes to TRUE if indicated by the
- * image_ctl flags.
- */
- if(cache_ptr->close_warning_received && cache_ptr->image_ctl.generate_image
- && cache_ptr->num_entries_in_image > 0 && cache_ptr->image_entries) {
- /* Sanity checks */
- HDassert(entry_ptr->image_up_to_date || !(entry_ptr->include_in_image));
- HDassert(entry_ptr->image_ptr || !(entry_ptr->include_in_image));
- HDassert((!clear_only) || !(entry_ptr->include_in_image));
- HDassert((!take_ownership) || !(entry_ptr->include_in_image));
- HDassert((!free_file_space) || !(entry_ptr->include_in_image));
-
- suppress_image_entry_frees = TRUE;
-
- if(cache_ptr->image_ctl.flags & H5C_CI__SUPRESS_ENTRY_WRITES)
- suppress_image_entry_writes = TRUE;
- } /* end if */
-
/* run initial sanity checks */
#if H5C_DO_SANITY_CHECKS
if(entry_ptr->in_slist) {
HDassert(entry_ptr->is_dirty);
if((entry_ptr->flush_marker) && (!entry_ptr->is_dirty))
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "entry in slist failed sanity checks")
- } /* end if */
- else {
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "entry in slist failed sanity checks.")
+ } else {
HDassert(!entry_ptr->is_dirty);
HDassert(!entry_ptr->flush_marker);
if((entry_ptr->is_dirty) || (entry_ptr->flush_marker))
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "entry failed sanity checks")
- } /* end else */
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "entry failed sanity checks.")
+ }
#endif /* H5C_DO_SANITY_CHECKS */
if(entry_ptr->is_protected) {
HDassert(!entry_ptr->is_protected);
/* Attempt to flush a protected entry -- scream and die. */
- HGOTO_ERROR(H5E_CACHE, H5E_PROTECT, FAIL, "Attempt to flush a protected entry")
+ HGOTO_ERROR(H5E_CACHE, H5E_PROTECT, FAIL, "Attempt to flush a protected entry.")
} /* end if */
- /* Set entry_ptr->flush_in_progress = TRUE and set
+ /* set entry_ptr->flush_in_progress = TRUE and set
* entry_ptr->flush_marker = FALSE
*
- * We will set flush_in_progress back to FALSE at the end if the
+ * in the parallel case, do some sanity checking in passing.
+ */
+ HDassert(entry_ptr->type);
+
+ was_dirty = entry_ptr->is_dirty; /* needed later for logging */
+
+ /* We will set flush_in_progress back to FALSE at the end if the
* entry still exists at that point.
*/
entry_ptr->flush_in_progress = TRUE;
entry_ptr->flush_marker = FALSE;
- /* Preserve current dirty state for later */
- was_dirty = entry_ptr->is_dirty;
-
/* The entry is dirty, and we are doing a flush, a flush destroy or have
* been requested to generate an image. In those cases, serialize the
* entry.
@@ -6119,9 +6324,6 @@ H5C__flush_single_entry(H5F_t *f, hid_t dxpl_id, H5C_cache_entry_t *entry_ptr,
} /* end if */
if(!(entry_ptr->image_up_to_date)) {
- /* Sanity check */
- HDassert(!entry_ptr->prefetched);
-
/* Generate the entry's image */
if(H5C__generate_image(f, cache_ptr, entry_ptr, dxpl_id) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, FAIL, "can't generate entry's image")
@@ -6142,17 +6344,7 @@ H5C__flush_single_entry(H5F_t *f, hid_t dxpl_id, H5C_cache_entry_t *entry_ptr,
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Write when writes are always forbidden!?!?!")
#endif /* H5C_DO_SANITY_CHECKS */
- /* Write the image to disk unless the write is suppressed.
- *
- * This happens if both suppress_image_entry_writes and
- * entry_ptr->include_in_image are TRUE, or if the
- * H5AC__CLASS_SKIP_WRITES is set in the entry's type. This
- * flag should only be used in test code
- */
- if((!suppress_image_entry_writes || !entry_ptr->include_in_image)
- && (((entry_ptr->type->flags) & H5C__CLASS_SKIP_WRITES) == 0)) {
- H5FD_mem_t mem_type = H5FD_MEM_DEFAULT;
-
+ if(((entry_ptr->type->flags) & H5C__CLASS_SKIP_WRITES) == 0) {
#ifdef H5_HAVE_PARALLEL
if(cache_ptr->coll_write_list) {
if(H5SL_insert(cache_ptr->coll_write_list, entry_ptr, &entry_ptr->addr) < 0)
@@ -6160,16 +6352,8 @@ H5C__flush_single_entry(H5F_t *f, hid_t dxpl_id, H5C_cache_entry_t *entry_ptr,
} /* end if */
else
#endif /* H5_HAVE_PARALLEL */
-
- if(entry_ptr->prefetched) {
- HDassert(entry_ptr->type->id == H5AC_PREFETCHED_ENTRY_ID);
- mem_type = cache_ptr->class_table_ptr[entry_ptr->prefetch_type_id]->mem_type;
- } /* end if */
- else
- mem_type = entry_ptr->type->mem_type;
-
- if(H5F_block_write(f, mem_type, entry_ptr->addr, entry_ptr->size, dxpl_id, entry_ptr->image_ptr) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't write image to file")
+ if(H5F_block_write(f, entry_ptr->type->mem_type, entry_ptr->addr, entry_ptr->size, dxpl_id, entry_ptr->image_ptr) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't write image to file.")
} /* end if */
/* if the entry has a notify callback, notify it that we have
@@ -6313,29 +6497,10 @@ H5C__flush_single_entry(H5F_t *f, hid_t dxpl_id, H5C_cache_entry_t *entry_ptr,
/* Sanity check */
HDassert(0 == entry_ptr->flush_dep_nparents);
- /* if both suppress_image_entry_frees and entry_ptr->include_in_image
- * are true, simply set entry_ptr->image_ptr to NULL, as we have
- * another pointer to the buffer in an instance of H5C_image_entry_t
- * in cache_ptr->image_entries.
- *
- * Otherwise, free the buffer if it exists.
- */
- if(suppress_image_entry_frees && entry_ptr->include_in_image)
- entry_ptr->image_ptr = NULL;
- else if(entry_ptr->image_ptr != NULL)
+ /* Start by freeing the buffer for the on disk image */
+ if(entry_ptr->image_ptr != NULL)
entry_ptr->image_ptr = H5MM_xfree(entry_ptr->image_ptr);
- /* If the entry is not a prefetched entry, verify that the flush
- * dependency parents addresses array has been transfered.
- *
- * If the entry is prefetched, the free_isr routine will dispose of
- * the flush dependency parents adresses array if necessary.
- */
- if(!entry_ptr->prefetched) {
- HDassert(0 == entry_ptr->fd_parent_count);
- HDassert(NULL == entry_ptr->fd_parent_addrs);
- } /* end if */
-
/* Check whether we should free the space in the file that
* the entry occupies
*/
@@ -6419,7 +6584,7 @@ H5C__flush_single_entry(H5F_t *f, hid_t dxpl_id, H5C_cache_entry_t *entry_ptr,
HDassert(entry_ptr->image_ptr == NULL);
if(entry_ptr->type->free_icr((void *)entry_ptr) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "free_icr callback failed")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "free_icr callback failed.")
} /* end if */
else {
HDassert(take_ownership);
@@ -6434,11 +6599,12 @@ H5C__flush_single_entry(H5F_t *f, hid_t dxpl_id, H5C_cache_entry_t *entry_ptr,
if(cache_ptr->log_flush)
if((cache_ptr->log_flush)(cache_ptr, entry_addr, was_dirty, flags) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "log_flush callback failed")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "log_flush callback failed.")
done:
HDassert( ( ret_value != SUCCEED ) || ( destroy_entry ) ||
( ! entry_ptr->flush_in_progress ) );
+
HDassert( ( ret_value != SUCCEED ) || ( destroy_entry ) ||
( take_ownership ) || ( ! entry_ptr->is_dirty ) );
@@ -6496,14 +6662,14 @@ H5C__verify_len_eoa(H5F_t *f, const H5C_class_t *type, haddr_t addr,
/* Check if the amount of data to read will be past the EOA */
if(H5F_addr_gt((addr + *len), eoa)) {
if(actual)
- HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "actual len exceeds EOA")
+ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "actual len exceeds EOA.")
else
/* Trim down the length of the metadata */
*len = (size_t)(eoa - addr);
} /* end if */
if(*len <= 0)
- HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "len not positive after adjustment for EOA")
+ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "len not positive after adjustment for EOA.")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -6583,7 +6749,7 @@ H5C_load_entry(H5F_t * f,
/* Allocate the buffer for reading the on-disk entry image */
if(NULL == (image = (uint8_t *)H5MM_malloc(len + H5C_IMAGE_EXTRA_SPACE)))
- HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, NULL, "memory allocation failed for on disk image buffer")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, NULL, "memory allocation failed for on disk image buffer.")
#if H5C_DO_MEMORY_SANITY_CHECKS
HDmemcpy(image + len, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE);
#endif /* H5C_DO_MEMORY_SANITY_CHECKS */
@@ -6660,7 +6826,7 @@ H5C_load_entry(H5F_t * f,
if(actual_len != len) {
/* Verify that the length isn't past the EOA for the file */
if(H5C__verify_len_eoa(f, type, addr, &actual_len, TRUE) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "actual_len exceeds EOA")
+ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "actual_len exceeds EOA.")
/* Expand buffer to new size */
if(NULL == (new_image = H5MM_realloc(image, actual_len + H5C_IMAGE_EXTRA_SPACE)))
@@ -6810,22 +6976,6 @@ H5C_load_entry(H5F_t * f,
entry->coll_prev = NULL;
#endif /* H5_HAVE_PARALLEL */
- /* initialize cache image related fields */
- entry->include_in_image = FALSE;
- entry->lru_rank = 0;
- entry->image_dirty = FALSE;
- entry->fd_parent_count = 0;
- entry->fd_parent_addrs = NULL;
- entry->fd_child_count = 0;
- entry->fd_dirty_child_count = 0;
- entry->image_fd_height = 0;
- entry->prefetched = FALSE;
- entry->prefetch_type_id = 0;
- entry->age = 0;
-#ifndef NDEBUG /* debugging field */
- entry->serialization_count = 0;
-#endif /* NDEBUG */
-
H5C__RESET_CACHE_ENTRY_STATS(entry);
ret_value = thing;
@@ -6846,7 +6996,7 @@ done:
/*-------------------------------------------------------------------------
*
- * Function: H5C__make_space_in_cache
+ * Function: H5C_make_space_in_cache
*
* Purpose: Attempt to evict cache entries until the index_size
* is at least needed_space below max_cache_size.
@@ -6877,19 +7027,53 @@ done:
*
* Programmer: John Mainzer, 5/14/04
*
+ * Changes: Modified function to skip over entries with the
+ * flush_in_progress flag set. If this is not done,
+ * an infinite recursion is possible if the cache is
+ * full, and the pre-serialize or serialize routine
+ * attempts to load another entry.
+ *
+ * This error was exposed by a re-factor of the
+ * H5C__flush_single_entry() routine. However, it was
+ * a potential bug from the moment that entries were
+ * allowed to load other entries on flush.
+ *
+ * In passing, note that the primary and secondary dxpls
+ * mentioned in the comment above have been replaced by
+ * a single dxpl at some point, and thus the discussion
+ * above is somewhat obsolete. Date of this change is
+ * unkown.
+ *
+ * JRM -- 12/26/14
+ *
+ * Modified function to detect deletions of entries
+ * during a scan of the LRU, and where appropriate,
+ * restart the scan to avoid proceeding with a next
+ * entry that is no longer in the cache.
+ *
+ * Note the absence of checks after flushes of clean
+ * entries. As a second entry can only be removed by
+ * by a call to the pre_serialize or serialize callback
+ * of the first, and as these callbacks will not be called
+ * on clean entries, no checks are needed.
+ *
+ * JRM -- 4/6/15
+ *
*-------------------------------------------------------------------------
*/
-herr_t
-H5C__make_space_in_cache(H5F_t *f, hid_t dxpl_id, size_t space_needed,
- hbool_t write_permitted)
+static herr_t
+H5C_make_space_in_cache(H5F_t * f,
+ hid_t dxpl_id,
+ size_t space_needed,
+ hbool_t write_permitted)
{
H5C_t * cache_ptr = f->shared->cache;
#if H5C_COLLECT_CACHE_STATS
int32_t clean_entries_skipped = 0;
int32_t total_entries_scanned = 0;
#endif /* H5C_COLLECT_CACHE_STATS */
- uint32_t entries_examined = 0;
- uint32_t initial_list_len;
+ int32_t entries_examined = 0;
+ int32_t initial_list_len;
size_t empty_space;
hbool_t prev_is_dirty = FALSE;
hbool_t didnt_flush_entry = FALSE;
@@ -6897,27 +7081,33 @@ H5C__make_space_in_cache(H5F_t *f, hid_t dxpl_id, size_t space_needed,
H5C_cache_entry_t * entry_ptr;
H5C_cache_entry_t * prev_ptr;
H5C_cache_entry_t * next_ptr;
- uint32_t num_corked_entries = 0;
+ int32_t num_corked_entries = 0;
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_PACKAGE
+ FUNC_ENTER_NOAPI_NOINIT
- /* Sanity checks */
- HDassert(f);
- HDassert(cache_ptr);
- HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
- HDassert(cache_ptr->index_size == (cache_ptr->clean_index_size + cache_ptr->dirty_index_size));
+ HDassert( f );
+ HDassert( cache_ptr );
+ HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
+ HDassert( cache_ptr->index_size ==
+ (cache_ptr->clean_index_size + cache_ptr->dirty_index_size) );
if ( write_permitted ) {
+
restart_scan = FALSE;
initial_list_len = cache_ptr->LRU_list_len;
entry_ptr = cache_ptr->LRU_tail_ptr;
- if(cache_ptr->index_size >= cache_ptr->max_cache_size)
+ if ( cache_ptr->index_size >= cache_ptr->max_cache_size ) {
+
empty_space = 0;
- else
+
+ } else {
+
empty_space = cache_ptr->max_cache_size - cache_ptr->index_size;
+ }
+
while ( ( ( (cache_ptr->index_size + space_needed)
>
cache_ptr->max_cache_size
@@ -7163,8 +7353,10 @@ H5C__make_space_in_cache(H5F_t *f, hid_t dxpl_id, size_t space_needed,
}
done:
+
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5C__make_space_in_cache() */
+
+} /* H5C_make_space_in_cache() */
/*-------------------------------------------------------------------------
@@ -7974,515 +8166,6 @@ H5C__assert_flush_dep_nocycle(const H5C_cache_entry_t * entry,
/*-------------------------------------------------------------------------
- * Function: H5C__serialize_cache
- *
- * Purpose: Serialize (i.e. construct an on disk image) for all entries
- * in the metadata cache including clean entries.
- *
- * Note that flush dependencies and "flush me last" flags
- * must be observed in the serialization process.
- *
- * Note also that entries may be loaded, flushed, evicted,
- * expunged, relocated, resized, or removed from the cache
- * during this process, just as these actions may occur during
- * a regular flush.
- *
- * However, we are given that the cache will contain no protected
- * entries on entry to this routine (although entries may be
- * briefly protected and then unprotected during the serialize
- * process).
- *
- * The objective of this routine is serialize all entries and
- * to force all entries into their actual locations on disk.
- *
- * The initial need for this routine is to settle all entries
- * in the cache prior to construction of the metadata cache
- * image so that the size of the cache image can be calculated.
- * However, I gather that other uses for the routine are
- * under consideration.
- *
- * Return: Non-negative on success/Negative on failure or if there was
- * a request to flush all items and something was protected.
- *
- * Programmer: John Mainzer
- * 7/22/15
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5C__serialize_cache(H5F_t *f, hid_t dxpl_id)
-{
-#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;
-#endif /* H5C_DO_SANITY_CHECKS */
- H5C_ring_t ring;
- H5C_t * cache_ptr;
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_PACKAGE
-
- /* Sanity checks */
- HDassert(f);
- HDassert(f->shared);
- cache_ptr = f->shared->cache;
- HDassert(cache_ptr);
- HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
- HDassert(cache_ptr->slist_ptr);
-
-#if H5C_DO_SANITY_CHECKS
- HDassert(cache_ptr->index_ring_len[H5C_RING_UNDEFINED] == 0);
- HDassert(cache_ptr->index_ring_size[H5C_RING_UNDEFINED] == (size_t)0);
- HDassert(cache_ptr->clean_index_ring_size[H5C_RING_UNDEFINED] == (size_t)0);
- HDassert(cache_ptr->dirty_index_ring_size[H5C_RING_UNDEFINED] == (size_t)0);
- HDassert(cache_ptr->slist_ring_len[H5C_RING_UNDEFINED] == 0);
- HDassert(cache_ptr->slist_ring_size[H5C_RING_UNDEFINED] == (size_t)0);
-
- for(i = H5C_RING_USER; i < H5C_RING_NTYPES; i++) {
- index_len += cache_ptr->index_ring_len[i];
- index_size += cache_ptr->index_ring_size[i];
- 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_size += cache_ptr->slist_ring_size[i];
- } /* end for */
-
- HDassert(cache_ptr->index_len == index_len);
- HDassert(cache_ptr->index_size == index_size);
- HDassert(cache_ptr->clean_index_size == clean_index_size);
- HDassert(cache_ptr->dirty_index_size == dirty_index_size);
- HDassert(cache_ptr->slist_len == slist_len);
- HDassert(cache_ptr->slist_size == slist_size);
-#endif /* H5C_DO_SANITY_CHECKS */
-
-#if H5C_DO_EXTREME_SANITY_CHECKS
- if((H5C_validate_protected_entry_list(cache_ptr) < 0) ||
- (H5C_validate_pinned_entry_list(cache_ptr) < 0) ||
- (H5C_validate_lru_list(cache_ptr) < 0))
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "an extreme sanity check failed on entry")
-#endif /* H5C_DO_EXTREME_SANITY_CHECKS */
-
-#ifndef NDEBUG
- /* if this is a debug build, set the serialization_count field of
- * each entry in the cache to zero before we start the serialization.
- * This allows us to detect the case in which any entry is serialized
- * more than once (a performance issues), and more importantly, the
- * case is which any flush depencency parent is serializes more than
- * once (a correctness issue).
- */
- {
- H5C_cache_entry_t * scan_ptr = NULL;
-
- scan_ptr = cache_ptr->il_head;
- while(scan_ptr != NULL) {
- HDassert(scan_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
- scan_ptr->serialization_count = 0;
- scan_ptr = scan_ptr->il_next;
- } /* end while */
- } /* end block */
-#endif /* NDEBUG */
-
- /* set cache_ptr->serialization_in_progress to TRUE, and back
- * to FALSE at the end of the function. Must maintain this flag
- * to support H5C_get_serialization_in_progress(), which is in
- * turn required to support sanity checking in some cache
- * clients.
- */
- HDassert(!cache_ptr->serialization_in_progress);
- cache_ptr->serialization_in_progress = TRUE;
-
- /* Serialize each ring, starting from the outermost ring and
- * working inward.
- */
- ring = H5C_RING_USER;
- while(ring < H5C_RING_NTYPES) {
- HDassert(cache_ptr->close_warning_received);
- switch(ring) {
- case H5C_RING_USER:
- break;
-
- case H5C_RING_RDFSM:
- /* Settle raw data FSM */
- if(!cache_ptr->rdfsm_settled)
- if(H5MF_settle_raw_data_fsm(f, dxpl_id, &cache_ptr->rdfsm_settled) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "RD FSM settle failed")
- break;
-
- case H5C_RING_MDFSM:
- /* Settle metadata FSM */
- if(!cache_ptr->mdfsm_settled)
- if(H5MF_settle_meta_data_fsm(f, dxpl_id, &cache_ptr->mdfsm_settled) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "MD FSM settle failed")
- break;
-
- case H5C_RING_SBE:
- case H5C_RING_SB:
- break;
-
- default:
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Unknown ring?!?!")
- break;
- } /* end switch */
-
- if(H5C__serialize_ring(f, dxpl_id, ring) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTSERIALIZE, FAIL, "serialize ring failed")
-
- ring++;
- } /* end while */
-
-#ifndef NDEBUG
- /* Verify that no entry has been serialized more than once.
- * FD parents with multiple serializations should have been caught
- * elsewhere, so no specific check for them here.
- */
- {
- H5C_cache_entry_t * scan_ptr = NULL;
-
- scan_ptr = cache_ptr->il_head;
- while(scan_ptr != NULL) {
- HDassert(scan_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
- HDassert(scan_ptr->serialization_count <= 1);
-
- scan_ptr = scan_ptr->il_next;
- } /* end while */
- } /* end block */
-#endif /* NDEBUG */
-
-done:
- cache_ptr->serialization_in_progress = FALSE;
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5C__serialize_cache() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5C__serialize_ring
- *
- * Purpose: Serialize the entries contained in the specified cache and
- * ring. All entries in rings outside the specified ring
- * must have been serialized on entry.
- *
- * If the cache contains protected entries in the specified
- * ring, the function will fail, as protected entries cannot
- * be serialized. However all unprotected entries in the
- * target ring should be serialized before the function
- * returns failure.
- *
- * If flush dependencies appear in the target ring, the
- * function makes repeated passes through the index list
- * serializing entries in flush dependency order.
- *
- * All entries outside the H5C_RING_SBE are marked for
- * inclusion in the cache image. Entries in H5C_RING_SBE
- * and below are marked for exclusion from the image.
- *
- * Return: Non-negative on success/Negative on failure or if there was
- * a request to flush all items and something was protected.
- *
- * Programmer: John Mainzer
- * 9/11/15
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5C__serialize_ring(H5F_t *f, hid_t dxpl_id, H5C_ring_t ring)
-{
- hbool_t done = FALSE;
- H5C_t * cache_ptr;
- H5C_cache_entry_t * entry_ptr;
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_STATIC
-
- /* Sanity checks */
- HDassert(f);
- HDassert(f->shared);
- cache_ptr = f->shared->cache;
- HDassert(cache_ptr);
- HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
- HDassert(ring > H5C_RING_UNDEFINED);
- HDassert(ring < H5C_RING_NTYPES);
-
- HDassert(cache_ptr->serialization_in_progress);
-
- /* The objective here is to serialize all entries in the cache ring
- * in flush dependency order.
- *
- * The basic algorithm is to scan the cache index list looking for
- * unserialized entries that are either not in a flush dependency
- * relationship, or which have no unserialized children. Any such
- * entry is serialized and its flush dependency parents (if any) are
- * informed -- allowing them to decrement their userialized child counts.
- *
- * However, this algorithm is complicated by the ability
- * of client serialization callbacks to perform operations on
- * on the cache which can result in the insertion, deletion,
- * relocation, resize, dirty, flush, eviction, or removal (via the
- * take ownership flag) of entries. Changes in the flush dependency
- * structure are also possible.
- *
- * On the other hand, the algorithm is simplified by the fact that
- * we are serializing, not flushing. Thus, as long as all entries
- * are serialized correctly, it doesn't matter if we have to go back
- * and serialize an entry a second time.
- *
- * These possible actions result in the following modfications to
- * tha basic algorithm:
- *
- * 1) In the event of an entry expunge, eviction or removal, we must
- * restart the scan as it is possible that the next entry in our
- * scan is no longer in the cache. Were we to examine this entry,
- * we would be accessing deallocated memory.
- *
- * 2) A resize, dirty, or insertion of an entry may result in the
- * the increment of a flush dependency parent's dirty and/or
- * unserialized child count. In the context of serializing the
- * the cache, this is a non-issue, as even if we have already
- * serialized the parent, it will be marked dirty and its image
- * marked out of date if appropriate when the child is serialized.
- *
- * However, this is a major issue for a flush, as were this to happen
- * in a flush, it would violate the invariant that the flush dependency
- * feature is intended to enforce. As the metadata cache has no
- * control over the behavior of cache clients, it has no way of
- * preventing this behaviour. However, it should detect it if at all
- * possible.
- *
- * Do this by maintaining a count of the number of times each entry is
- * serialized during a cache serialization. If any flush dependency
- * parent is serialized more than once, throw an assertion failure.
- *
- * 3) An entry relocation will typically change the location of the
- * entry in the index list. This shouldn't cause problems as we
- * will scan the index list until we make a complete pass without
- * finding anything to serialize -- making relocations of either
- * the current or next entries irrelevant.
- *
- * Note that since a relocation may result in our skipping part of
- * the index list, we must always do at least one more pass through
- * the index list after an entry relocation.
- *
- * 4) Changes in the flush dependency structure are possible on
- * entry insertion, load, expunge, evict, or remove. Destruction
- * of a flush dependency has no effect, as it can only relax the
- * flush dependencies. Creation of a flush dependency can create
- * an unserialized child of a flush dependency parent where all
- * flush dependency children were previously serialized. Should
- * this child dirty the flush dependency parent when it is serialized,
- * the parent will be re-serialized.
- *
- * Per the discussion of 2) above, this is a non issue for cache
- * serialization, and a major problem for cache flush. Using the
- * same detection mechanism, throw an assertion failure if this
- * condition appears.
- *
- * Observe that either eviction or removal of entries as a result of
- * a serialization is not a problem as long as the flush depencency
- * tree does not change beyond the removal of a leaf.
- */
- while(!done) {
- /* Reset the counters so that we can detect insertions, loads,
- * moves, and flush dependency height changes caused by the pre_serialize
- * and serialize callbacks.
- */
- cache_ptr->entries_loaded_counter = 0;
- cache_ptr->entries_inserted_counter = 0;
- cache_ptr->entries_relocated_counter = 0;
-
- done = TRUE; /* set to FALSE if any activity in inner loop */
- entry_ptr = cache_ptr->il_head;
- while(entry_ptr != NULL) {
- HDassert(entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
-
- /* Verify that either the entry is already serialized, or
- * that it is assigned to either the target or an inner
- * ring.
- */
- HDassert((entry_ptr->ring >= ring) || (entry_ptr->image_up_to_date));
-
- /* Skip flush me last entries or inner ring entries */
- if(!entry_ptr->flush_me_last && entry_ptr->ring == ring) {
-
- /* if we encounter an unserialized entry in the current
- * ring that is not marked flush me last, we are not done.
- */
- if(!entry_ptr->image_up_to_date)
- done = FALSE;
-
- /* Serialize the entry if its image is not up to date
- * and it has no unserialized flush dependency children.
- */
- if(!entry_ptr->image_up_to_date && entry_ptr->flush_dep_nunser_children == 0) {
- HDassert(entry_ptr->serialization_count == 0);
-
- /* Serialize the entry */
- if(H5C__serialize_single_entry(f, dxpl_id, cache_ptr, entry_ptr) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTSERIALIZE, FAIL, "entry serialization failed")
-
- HDassert(entry_ptr->flush_dep_nunser_children == 0);
- HDassert(entry_ptr->serialization_count == 0);
-
-#ifndef NDEBUG
- /* Increment serialization counter (to detect multiple serializations) */
- entry_ptr->serialization_count++;
-#endif /* NDEBUG */
- } /* end if */
- } /* end if */
-
- /* Check for the cache being perturbed during the entry serialize */
- if((cache_ptr->entries_loaded_counter > 0) ||
- (cache_ptr->entries_inserted_counter > 0) ||
- (cache_ptr->entries_relocated_counter > 0)) {
-
-#if H5C_COLLECT_CACHE_STATS
- H5C__UPDATE_STATS_FOR_INDEX_SCAN_RESTART(cache_ptr);
-#endif /* H5C_COLLECT_CACHE_STATS */
-
- /* Reset the counters */
- cache_ptr->entries_loaded_counter = 0;
- cache_ptr->entries_inserted_counter = 0;
- cache_ptr->entries_relocated_counter = 0;
-
- /* Restart scan */
- entry_ptr = cache_ptr->il_head;
- } /* end if */
- else
- /* Advance to next entry */
- entry_ptr = entry_ptr->il_next;
- } /* while ( entry_ptr != NULL ) */
- } /* while ( ! done ) */
-
-
- /* Reset the counters so that we can detect insertions, loads,
- * moves, and flush dependency height changes caused by the pre_serialize
- * and serialize callbacks.
- */
- cache_ptr->entries_loaded_counter = 0;
- cache_ptr->entries_inserted_counter = 0;
- cache_ptr->entries_relocated_counter = 0;
-
- /* At this point, all entries not marked "flush me last" and in
- * the current ring or outside it should be serialized and have up
- * to date images. Scan the index list again to serialize the
- * "flush me last" entries (if they are in the current ring) and to
- * verify that all other entries have up to date images.
- */
- entry_ptr = cache_ptr->il_head;
- while(entry_ptr != NULL) {
- HDassert(entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
- HDassert(entry_ptr->ring > H5C_RING_UNDEFINED);
- HDassert(entry_ptr->ring < H5C_RING_NTYPES);
- HDassert((entry_ptr->ring >= ring) || (entry_ptr->image_up_to_date));
-
- if(entry_ptr->ring == ring) {
- if(entry_ptr->flush_me_last) {
- if(!entry_ptr->image_up_to_date) {
- HDassert(entry_ptr->serialization_count == 0);
- HDassert(entry_ptr->flush_dep_nunser_children == 0);
-
- /* Serialize the entry */
- if(H5C__serialize_single_entry(f, dxpl_id, cache_ptr, entry_ptr) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTSERIALIZE, FAIL, "entry serialization failed")
-
- /* Check for the cache changing */
- if((cache_ptr->entries_loaded_counter > 0) ||
- (cache_ptr->entries_inserted_counter > 0) ||
- (cache_ptr->entries_relocated_counter > 0))
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "flush_me_last entry serialization triggered restart")
-
- HDassert(entry_ptr->flush_dep_nunser_children == 0);
- HDassert(entry_ptr->serialization_count == 0);
-#ifndef NDEBUG
- /* Increment serialization counter (to detect multiple serializations) */
- entry_ptr->serialization_count++;
-#endif /* NDEBUG */
- } /* end if */
- } /* end if */
- else {
- HDassert(entry_ptr->image_up_to_date);
- HDassert(entry_ptr->serialization_count <= 1);
- HDassert(entry_ptr->flush_dep_nunser_children == 0);
- } /* end else */
- } /* if ( entry_ptr->ring == ring ) */
-
- entry_ptr = entry_ptr->il_next;
- } /* while ( entry_ptr != NULL ) */
-
-done:
- HDassert(cache_ptr->serialization_in_progress);
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5C__serialize_ring() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5C__serialize_single_entry
- *
- * Purpose: Serialize the cache entry pointed to by the entry_ptr
- * parameter.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: John Mainzer, 7/24/15
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5C__serialize_single_entry(H5F_t *f, hid_t dxpl_id, H5C_t *cache_ptr,
- H5C_cache_entry_t *entry_ptr)
-{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_STATIC
-
- /* Sanity checks */
- HDassert(f);
- HDassert(cache_ptr);
- HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
- HDassert(entry_ptr);
- HDassert(entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
- HDassert(!entry_ptr->prefetched);
- HDassert(!entry_ptr->image_up_to_date);
- HDassert(entry_ptr->is_dirty);
- HDassert(!entry_ptr->is_protected);
- HDassert(!entry_ptr->flush_in_progress);
- HDassert(entry_ptr->type);
-
- /* Set entry_ptr->flush_in_progress to TRUE so the the target entry
- * will not be evicted out from under us. Must set it back to FALSE
- * when we are done.
- */
- entry_ptr->flush_in_progress = TRUE;
-
- /* Allocate buffer for the entry image if required. */
- if(NULL == entry_ptr->image_ptr) {
- HDassert(entry_ptr->size > 0);
- if(NULL == (entry_ptr->image_ptr = H5MM_malloc(entry_ptr->size + H5C_IMAGE_EXTRA_SPACE)) )
- HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "memory allocation failed for on disk image buffer")
-#if H5C_DO_MEMORY_SANITY_CHECKS
- HDmemcpy(((uint8_t *)entry_ptr->image_ptr) + image_size, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE);
-#endif /* H5C_DO_MEMORY_SANITY_CHECKS */
- } /* end if */
-
- /* Generate image for entry */
- if(H5C__generate_image(f, cache_ptr, entry_ptr, dxpl_id) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTSERIALIZE, FAIL, "Can't generate image for cache entry")
-
- /* Reset the flush_in progress flag */
- entry_ptr->flush_in_progress = FALSE;
-
-done:
- HDassert((ret_value != SUCCEED) || (!entry_ptr->flush_in_progress));
- HDassert((ret_value != SUCCEED) || (entry_ptr->image_up_to_date));
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5C__serialize_single_entry() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5C__generate_image
*
* Purpose: Serialize an entry and generate its image.
@@ -8503,7 +8186,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
+static herr_t
H5C__generate_image(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr,
hid_t dxpl_id)
{
@@ -8513,18 +8196,10 @@ H5C__generate_image(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr,
unsigned serialize_flags = H5C__SERIALIZE_NO_FLAGS_SET;
herr_t ret_value = SUCCEED;
- FUNC_ENTER_PACKAGE
+ FUNC_ENTER_STATIC
/* Sanity check */
- HDassert(f);
- HDassert(cache_ptr);
- HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
- HDassert(entry_ptr);
- HDassert(entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
HDassert(!entry_ptr->image_up_to_date);
- HDassert(entry_ptr->is_dirty);
- HDassert(!entry_ptr->is_protected);
- HDassert(entry_ptr->type);
/* make note of the entry's current address */
old_addr = entry_ptr->addr;
@@ -8538,7 +8213,8 @@ H5C__generate_image(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr,
/* Check for any flags set in the pre-serialize callback */
if(serialize_flags != H5C__SERIALIZE_NO_FLAGS_SET) {
/* Check for unexpected flags from serialize callback */
- if(serialize_flags & ~(H5C__SERIALIZE_RESIZED_FLAG | H5C__SERIALIZE_MOVED_FLAG))
+ if(serialize_flags & ~(H5C__SERIALIZE_RESIZED_FLAG |
+ H5C__SERIALIZE_MOVED_FLAG))
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unknown serialize flag(s)")
#ifdef H5_HAVE_PARALLEL
@@ -8569,15 +8245,12 @@ H5C__generate_image(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr,
* tests will be necessary.
*/
if(cache_ptr->aux_ptr != NULL)
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "resize/move in serialize occured in parallel case")
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "resize/move in serialize occured in parallel case.")
#endif
/* If required, resize the buffer and update the entry and the cache
* data structures */
if(serialize_flags & H5C__SERIALIZE_RESIZED_FLAG) {
- /* Sanity check */
- HDassert(new_len > 0);
-
/* Allocate a new image buffer */
if(NULL == (entry_ptr->image_ptr = H5MM_realloc(entry_ptr->image_ptr, new_len + H5C_IMAGE_EXTRA_SPACE)))
HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "memory allocation failed for on disk image buffer")
@@ -8588,8 +8261,9 @@ H5C__generate_image(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr,
/* Update statistics for resizing the entry */
H5C__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE(cache_ptr, entry_ptr, new_len);
- /* Update the hash table for the size change */
- H5C__UPDATE_INDEX_FOR_SIZE_CHANGE(cache_ptr, entry_ptr->size, new_len, entry_ptr, !(entry_ptr->is_dirty));
+ /* update the hash table for the size change */
+ H5C__UPDATE_INDEX_FOR_SIZE_CHANGE(cache_ptr, entry_ptr->size, \
+ new_len, entry_ptr, !(entry_ptr->is_dirty));
/* The entry can't be protected since we are in the process of
* flushing it. Thus we must update the replacement policy data
@@ -8602,11 +8276,10 @@ H5C__generate_image(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr,
* for the flush or flush destroy yet, the entry should
* be in the slist. Thus update it for the size change.
*/
- HDassert(entry_ptr->is_dirty);
HDassert(entry_ptr->in_slist);
H5C__UPDATE_SLIST_FOR_SIZE_CHANGE(cache_ptr, entry_ptr->size, new_len);
- /* Finally, update the entry for its new size */
+ /* finally, update the entry for its new size */
entry_ptr->size = new_len;
} /* end if */
@@ -8623,10 +8296,10 @@ H5C__generate_image(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr,
H5C__DELETE_FROM_INDEX(cache_ptr, entry_ptr, FAIL);
H5C__REMOVE_ENTRY_FROM_SLIST(cache_ptr, entry_ptr, FALSE);
- /* Update the entry for its new address */
+ /* update the entry for its new address */
entry_ptr->addr = new_addr;
- /* And then reinsert in the index and slist */
+ /* and then reinsert in the index and slist */
H5C__INSERT_IN_INDEX(cache_ptr, entry_ptr, FAIL);
H5C__INSERT_ENTRY_IN_SLIST(cache_ptr, entry_ptr, FAIL);
} /* end if */
@@ -8643,13 +8316,6 @@ H5C__generate_image(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr,
#endif /* H5C_DO_MEMORY_SANITY_CHECKS */
entry_ptr->image_up_to_date = TRUE;
- /* Propagate the fact that the entry is serialized up the
- * flush dependency chain if appropriate. Since the image must
- * have been out of date for this function to have been called
- * (see assertion on entry), no need to check that -- only check
- * for flush dependency parents.
- */
- HDassert(entry_ptr->flush_dep_nunser_children == 0);
if(entry_ptr->flush_dep_nparents > 0)
if(H5C__mark_flush_dep_serialized(entry_ptr) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTNOTIFY, FAIL, "Can't propagate serialization status to fd parents")