summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2017-03-12 09:57:19 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2017-03-12 09:57:19 (GMT)
commitc4a36e0bb3b56e0c8397876be1c66fedb2f57d83 (patch)
treebafeb848fb17a45a11a75abbbc50778b52347e59
parent36f06cab798cd45261988e2618018e0763f5e2fd (diff)
downloadhdf5-c4a36e0bb3b56e0c8397876be1c66fedb2f57d83.zip
hdf5-c4a36e0bb3b56e0c8397876be1c66fedb2f57d83.tar.gz
hdf5-c4a36e0bb3b56e0c8397876be1c66fedb2f57d83.tar.bz2
Minor cleanups and bring over "prefetched dirty" fixes for entries loaded from
a cache image.
-rw-r--r--src/H5AC.c9
-rw-r--r--src/H5ACdbg.c2
-rw-r--r--src/H5ACprivate.h2
-rw-r--r--src/H5C.c42
-rw-r--r--src/H5Cdbg.c106
-rw-r--r--src/H5Cimage.c2
-rw-r--r--src/H5Cpkg.h12
-rw-r--r--src/H5Cprivate.h58
-rw-r--r--src/H5Ctag.c2
-rw-r--r--test/cache.c5
-rw-r--r--test/cache_tagging.c58
-rw-r--r--test/evict_on_close.c1
12 files changed, 265 insertions, 34 deletions
diff --git a/src/H5AC.c b/src/H5AC.c
index ee68a6f..2fb7992 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -501,7 +501,7 @@ H5AC_create(const H5F_t *f, H5AC_cache_config_t *config_ptr, H5AC_cache_image_co
/* Turn on metadata cache logging, if being used */
if(H5F_USE_MDC_LOGGING(f)) {
if(H5C_set_up_logging(f->shared->cache, H5F_MDC_LOG_LOCATION(f), H5F_START_MDC_LOG_ON_ACCESS(f)) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "mdc logging setup failed")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTINIT, FAIL, "mdc logging setup failed")
/* Write the log header regardless of current logging status */
if(H5AC__write_create_cache_log_msg(f->shared->cache) < 0)
@@ -510,9 +510,9 @@ H5AC_create(const H5F_t *f, H5AC_cache_config_t *config_ptr, H5AC_cache_image_co
/* Set the cache parameters */
if(H5AC_set_cache_auto_resize_config(f->shared->cache, config_ptr) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "auto resize configuration failed")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTSET, FAIL, "auto resize configuration failed")
- /* don't need to get the current H5C image config here since the
+ /* Don't need to get the current H5C image config here since the
* cache has just been created, and thus f->shared->cache->image_ctl
* must still set to its initial value (H5C__DEFAULT_CACHE_IMAGE_CTL).
* Note that this not true as soon as control returns to the application
@@ -522,9 +522,8 @@ H5AC_create(const H5F_t *f, H5AC_cache_config_t *config_ptr, H5AC_cache_image_co
int_ci_config.generate_image = image_config_ptr->generate_image;
int_ci_config.save_resize_status = image_config_ptr->save_resize_status;
int_ci_config.entry_ageout = image_config_ptr->entry_ageout;
-
if(H5C_set_cache_image_config(f, f->shared->cache, &int_ci_config) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "auto resize configuration failed")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTSET, FAIL, "auto resize configuration failed")
done:
#ifdef H5_HAVE_PARALLEL
diff --git a/src/H5ACdbg.c b/src/H5ACdbg.c
index 8ca5102..6073288 100644
--- a/src/H5ACdbg.c
+++ b/src/H5ACdbg.c
@@ -101,6 +101,7 @@ H5AC_stats(const H5F_t *f)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5AC_stats() */
+#ifndef NDEBUG
/*-------------------------------------------------------------------------
* Function: H5AC_dump_cache
@@ -133,6 +134,7 @@ H5AC_dump_cache(const H5F_t *f)
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_dump_cache() */
+#endif /* NDEBUG */
/*-------------------------------------------------------------------------
diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h
index 1fe6456..1dc8270 100644
--- a/src/H5ACprivate.h
+++ b/src/H5ACprivate.h
@@ -482,8 +482,8 @@ H5_DLL herr_t H5AC_add_candidate(H5AC_t * cache_ptr, haddr_t addr);
/* Debugging functions */
H5_DLL herr_t H5AC_stats(const H5F_t *f);
-H5_DLL herr_t H5AC_dump_cache(const H5F_t *f);
#ifndef NDEBUG
+H5_DLL herr_t H5AC_dump_cache(const H5F_t *f);
H5_DLL herr_t H5AC_get_entry_ptr_from_addr(const H5F_t *f, haddr_t addr,
void **entry_ptr_ptr);
H5_DLL herr_t H5AC_flush_dependency_exists(H5F_t *f, haddr_t parent_addr,
diff --git a/src/H5C.c b/src/H5C.c
index cdf01b3..0eb9d9b 100644
--- a/src/H5C.c
+++ b/src/H5C.c
@@ -1459,6 +1459,7 @@ H5C_insert_entry(H5F_t * f,
entry_ptr->prefetched = FALSE;
entry_ptr->prefetch_type_id = 0;
entry_ptr->age = 0;
+ entry_ptr->prefetched_dirty = FALSE;
#ifndef NDEBUG /* debugging field */
entry_ptr->serialization_count = 0;
#endif /* NDEBUG */
@@ -4584,7 +4585,7 @@ H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t * f,
( (entry_ptr->type)->id != H5AC_EPOCH_MARKER_ID ) &&
( bytes_evicted < eviction_size_limit ) )
{
- hbool_t corked = FALSE;
+ hbool_t skipping_entry = FALSE;
HDassert(entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
HDassert( ! (entry_ptr->is_protected) );
@@ -4598,9 +4599,11 @@ H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t * f,
prev_is_dirty = prev_ptr->is_dirty;
if(entry_ptr->is_dirty ) {
+ HDassert(!entry_ptr->prefetched_dirty);
+
/* dirty corked entry is skipped */
if(entry_ptr->tag_info && entry_ptr->tag_info->corked)
- corked = TRUE;
+ skipping_entry = TRUE;
else {
/* reset entries_removed_counter and
* last_entry_removed_ptr prior to the call to
@@ -4620,16 +4623,22 @@ H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t * f,
restart_scan = TRUE;
} /* end else */
} /* end if */
- else {
+ else if(!entry_ptr->prefetched_dirty) {
bytes_evicted += entry_ptr->size;
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 entry")
- }
+ } /* end else-if */
+ else {
+ HDassert(!entry_ptr->is_dirty);
+ HDassert(entry_ptr->prefetched_dirty);
+
+ skipping_entry = TRUE;
+ } /* end else */
if(prev_ptr != NULL) {
- if(corked) /* dirty corked entry is skipped */
+ if(skipping_entry)
entry_ptr = prev_ptr;
else if(restart_scan || (prev_ptr->is_dirty != prev_is_dirty)
|| (prev_ptr->next != next_ptr)
@@ -4689,10 +4698,10 @@ H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t * f,
prev_ptr = entry_ptr->prev;
- if(!(entry_ptr->is_dirty)) {
+ if(!(entry_ptr->is_dirty) && !(entry_ptr->prefetched_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.
*
@@ -6827,6 +6836,7 @@ H5C_load_entry(H5F_t * f,
entry->prefetched = FALSE;
entry->prefetch_type_id = 0;
entry->age = 0;
+ entry->prefetched_dirty = FALSE;
#ifndef NDEBUG /* debugging field */
entry->serialization_count = 0;
#endif /* NDEBUG */
@@ -6888,6 +6898,7 @@ H5C__make_space_in_cache(H5F_t *f, hid_t dxpl_id, size_t space_needed,
H5C_t * cache_ptr = f->shared->cache;
#if H5C_COLLECT_CACHE_STATS
int32_t clean_entries_skipped = 0;
+ int32_t dirty_pf_entries_skipped = 0;
int32_t total_entries_scanned = 0;
#endif /* H5C_COLLECT_CACHE_STATS */
uint32_t entries_examined = 0;
@@ -6956,7 +6967,8 @@ H5C__make_space_in_cache(H5F_t *f, hid_t dxpl_id, size_t space_needed,
didnt_flush_entry = TRUE;
} else if ( ( (entry_ptr->type)->id != H5AC_EPOCH_MARKER_ID ) &&
- ( ! entry_ptr->flush_in_progress ) ) {
+ ( ! entry_ptr->flush_in_progress ) &&
+ ( ! entry_ptr->prefetched_dirty ) ) {
didnt_flush_entry = FALSE;
@@ -7015,10 +7027,16 @@ H5C__make_space_in_cache(H5F_t *f, hid_t dxpl_id, size_t space_needed,
} else {
- /* Skip epoch markers and entries that are in the process
- * of being flushed.
+ /* Skip epoch markers, entries that are in the process
+ * of being flushed, and entries marked as prefetched_dirty
+ * (occurs in the R/O case only).
*/
didnt_flush_entry = TRUE;
+
+#if H5C_COLLECT_CACHE_STATS
+ if(entry_ptr->prefetched_dirty)
+ dirty_pf_entries_skipped++;
+#endif /* H5C_COLLECT_CACHE_STATS */
}
if ( prev_ptr != NULL ) {
@@ -7083,6 +7101,7 @@ H5C__make_space_in_cache(H5F_t *f, hid_t dxpl_id, size_t space_needed,
cache_ptr->calls_to_msic++;
cache_ptr->total_entries_skipped_in_msic += clean_entries_skipped;
+ cache_ptr->total_dirty_pf_entries_skipped_in_msic += dirty_pf_entries_skipped;
cache_ptr->total_entries_scanned_in_msic += total_entries_scanned;
if ( clean_entries_skipped > cache_ptr->max_entries_skipped_in_msic ) {
@@ -7090,6 +7109,9 @@ H5C__make_space_in_cache(H5F_t *f, hid_t dxpl_id, size_t space_needed,
cache_ptr->max_entries_skipped_in_msic = clean_entries_skipped;
}
+ if(dirty_pf_entries_skipped > cache_ptr->max_dirty_pf_entries_skipped_in_msic)
+ cache_ptr->max_dirty_pf_entries_skipped_in_msic = dirty_pf_entries_skipped;
+
if ( total_entries_scanned > cache_ptr->max_entries_scanned_in_msic ) {
cache_ptr->max_entries_scanned_in_msic = total_entries_scanned;
diff --git a/src/H5Cdbg.c b/src/H5Cdbg.c
index eb5f123..a955eaf 100644
--- a/src/H5Cdbg.c
+++ b/src/H5Cdbg.c
@@ -70,6 +70,7 @@
/*******************/
+#ifndef NDEBUG
/*-------------------------------------------------------------------------
* Function: H5C_dump_cache
@@ -175,6 +176,85 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5C_dump_cache() */
+#endif /* NDEBUG */
+
+#ifndef NDEBUG
+
+/*-------------------------------------------------------------------------
+ * Function: H5C_dump_cache_LRU
+ *
+ * Purpose: Print a summary of the contents of the metadata cache
+ * LRU for debugging purposes.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: John Mainzer
+ * 10/10/10
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5C_dump_cache_LRU(H5C_t *cache_ptr, const char *cache_name)
+{
+ H5C_cache_entry_t * entry_ptr;
+ int i = 0;
+
+ FUNC_ENTER_NOAPI_NOERR
+
+ /* Sanity check */
+ HDassert(cache_ptr != NULL);
+ HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
+ HDassert(cache_name != NULL );
+
+ HDfprintf(stdout, "\n\nDump of metadata cache LRU \"%s\"\n", cache_name);
+ HDfprintf(stdout, "LRU len = %d, LRU size = %d\n",
+ cache_ptr->LRU_list_len, (int)(cache_ptr->LRU_list_size));
+ HDfprintf(stdout, "index_size = %d, max_cache_size = %d, delta = %d\n\n",
+ (int)(cache_ptr->index_size), (int)(cache_ptr->max_cache_size),
+ (int)(cache_ptr->max_cache_size) - (int)(cache_ptr->index_size));
+
+ /* Print header */
+ HDfprintf(stdout, "Entry ");
+ HDfprintf(stdout, "| Address ");
+ HDfprintf(stdout, "| Tag ");
+ HDfprintf(stdout, "| Size ");
+ HDfprintf(stdout, "| Ring ");
+ HDfprintf(stdout, "| Type ");
+ HDfprintf(stdout, "| Dirty");
+ HDfprintf(stdout, "\n");
+
+ HDfprintf(stdout, "----------------------------------------------------------------------------------------------------------------\n");
+
+ entry_ptr = cache_ptr->LRU_head_ptr;
+ while(entry_ptr != NULL) {
+ HDassert(entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
+
+ /* Print entry */
+ HDfprintf(stdout, "%s%5d ", cache_ptr->prefix, i);
+ HDfprintf(stdout, " 0x%16llx ", (long long)(entry_ptr->addr));
+
+ if(NULL == entry_ptr->tag_info)
+ HDfprintf(stdout, " %16s ", "N/A");
+ else
+ HDfprintf(stdout, " 0x%16llx ",
+ (long long)(entry_ptr->tag_info->tag));
+
+ HDfprintf(stdout, " %5lld ", (long long)(entry_ptr->size));
+ HDfprintf(stdout, " %d ", (int)(entry_ptr->ring));
+ HDfprintf(stdout, " %2d %-32s ", (int)(entry_ptr->type->id),
+ (entry_ptr->type->name));
+ HDfprintf(stdout, " %d", (int)(entry_ptr->is_dirty));
+ HDfprintf(stdout, "\n");
+
+ i++;
+ entry_ptr = entry_ptr->next;
+ } /* end while */
+
+ HDfprintf(stdout, "----------------------------------------------------------------------------------------------------------------\n");
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5C_dump_cache_LRU() */
+#endif /* NDEBUG */
/*-------------------------------------------------------------------------
@@ -385,6 +465,7 @@ H5C_stats(H5C_t * cache_ptr,
double average_successful_search_depth = 0.0f;
double average_failed_search_depth = 0.0f;
double average_entries_skipped_per_calls_to_msic = 0.0f;
+ double average_dirty_pf_entries_skipped_per_call_to_msic = 0.0f;
double average_entries_scanned_per_calls_to_msic = 0.0f;
#endif /* H5C_COLLECT_CACHE_STATS */
herr_t ret_value = SUCCEED; /* Return value */
@@ -620,6 +701,17 @@ H5C_stats(H5C_t * cache_ptr,
(long)(cache_ptr->max_entries_skipped_in_msic));
if(cache_ptr->calls_to_msic > 0)
+ average_dirty_pf_entries_skipped_per_call_to_msic =
+ (((double)(cache_ptr->total_dirty_pf_entries_skipped_in_msic)) /
+ ((double)(cache_ptr->calls_to_msic)));
+
+ HDfprintf(stdout,
+ "%s MSIC: Average/max dirty pf entries skipped = %lf / %ld\n",
+ cache_ptr->prefix,
+ average_dirty_pf_entries_skipped_per_call_to_msic,
+ (long)(cache_ptr->max_dirty_pf_entries_skipped_in_msic));
+
+ if(cache_ptr->calls_to_msic > 0)
average_entries_scanned_per_calls_to_msic =
(((double)(cache_ptr->total_entries_scanned_in_msic)) /
((double)(cache_ptr->calls_to_msic)));
@@ -887,12 +979,14 @@ H5C_stats__reset(H5C_t H5_ATTR_UNUSED * cache_ptr)
cache_ptr->max_pel_len = 0;
cache_ptr->max_pel_size = (size_t)0;
- cache_ptr->calls_to_msic = 0;
- cache_ptr->total_entries_skipped_in_msic = 0;
- cache_ptr->total_entries_scanned_in_msic = 0;
- cache_ptr->max_entries_skipped_in_msic = 0;
- cache_ptr->max_entries_scanned_in_msic = 0;
- cache_ptr->entries_scanned_to_make_space = 0;
+ cache_ptr->calls_to_msic = 0;
+ cache_ptr->total_entries_skipped_in_msic = 0;
+ cache_ptr->total_dirty_pf_entries_skipped_in_msic = 0;
+ cache_ptr->total_entries_scanned_in_msic = 0;
+ cache_ptr->max_entries_skipped_in_msic = 0;
+ cache_ptr->max_dirty_pf_entries_skipped_in_msic = 0;
+ cache_ptr->max_entries_scanned_in_msic = 0;
+ cache_ptr->entries_scanned_to_make_space = 0;
cache_ptr->slist_scan_restarts = 0;
cache_ptr->LRU_scan_restarts = 0;
diff --git a/src/H5Cimage.c b/src/H5Cimage.c
index dcaf968..3a21137 100644
--- a/src/H5Cimage.c
+++ b/src/H5Cimage.c
@@ -636,6 +636,7 @@ H5C__deserialize_prefetched_entry(H5F_t *f, hid_t dxpl_id, H5C_t *cache_ptr,
ds_entry_ptr->prefetched = FALSE;
ds_entry_ptr->prefetch_type_id = 0;
ds_entry_ptr->age = 0;
+ ds_entry_ptr->prefetched_dirty = pf_entry_ptr->prefetched_dirty;
#ifndef NDEBUG /* debugging field */
ds_entry_ptr->serialization_count = 0;
#endif /* NDEBUG */
@@ -3317,6 +3318,7 @@ H5C__reconstruct_cache_entry(const H5F_t *f, H5C_t *cache_ptr,
pf_entry_ptr->image_up_to_date = TRUE;
pf_entry_ptr->type = H5AC_PREFETCHED_ENTRY;
pf_entry_ptr->prefetched = TRUE;
+ pf_entry_ptr->prefetched_dirty = is_dirty && (!file_is_rw);
/* Sanity checks */
HDassert(pf_entry_ptr->size > 0 && pf_entry_ptr->size < H5C_MAX_ENTRY_SIZE);
diff --git a/src/H5Cpkg.h b/src/H5Cpkg.h
index 5b923e9..3ea5144 100644
--- a/src/H5Cpkg.h
+++ b/src/H5Cpkg.h
@@ -4500,12 +4500,22 @@ typedef struct H5C_tag_info_t {
* total_entries_skipped_in_msic: Number of clean entries skipped while
* enforcing the min_clean_fraction in H5C__make_space_in_cache().
*
+ * total_dirty_pf_entries_skipped_in_msic: Number of dirty prefetched entries
+ * skipped in H5C__make_space_in_cache(). Note that this can
+ * only occur when a file is opened R/O with a cache image
+ * containing dirty entries.
+ *
* total_entries_scanned_in_msic: Number of clean entries skipped while
* enforcing the min_clean_fraction in H5C__make_space_in_cache().
*
* max_entries_skipped_in_msic: Maximum number of clean entries skipped
* in any one call to H5C__make_space_in_cache().
*
+ * max_dirty_pf_entries_skipped_in_msic: Maximum number of dirty prefetched
+ * entries skipped in any one call to H5C__make_space_in_cache().
+ * Note that this can only occur when the file is opened
+ * R/O with a cache image containing dirty entries.
+ *
* max_entries_scanned_in_msic: Maximum number of entries scanned over
* in any one call to H5C__make_space_in_cache().
*
@@ -4822,8 +4832,10 @@ struct H5C_t {
/* Fields for tracking 'make space in cache' (msic) operations */
int64_t calls_to_msic;
int64_t total_entries_skipped_in_msic;
+ int64_t total_dirty_pf_entries_skipped_in_msic;
int64_t total_entries_scanned_in_msic;
int32_t max_entries_skipped_in_msic;
+ int32_t max_dirty_pf_entries_skipped_in_msic;
int32_t max_entries_scanned_in_msic;
int64_t entries_scanned_to_make_space;
diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h
index 28eacf2..3408839 100644
--- a/src/H5Cprivate.h
+++ b/src/H5Cprivate.h
@@ -1066,9 +1066,9 @@ typedef int H5C_ring_t;
*
* is_read_only: Boolean flag that is only meaningful if is_protected is
* TRUE. In this circumstance, it indicates whether the
- * entry has been protected read only, or read/write.
+ * entry has been protected read-only, or read/write.
*
- * If the entry has been protected read only (i.e. is_protected
+ * If the entry has been protected read-only (i.e. is_protected
* and is_read_only are both TRUE), we allow the entry to be
* protected more than once.
*
@@ -1078,7 +1078,7 @@ typedef int H5C_ring_t;
* the entry is actually unprotected.
*
* ro_ref_count: Integer field used to maintain a count of the number of
- * outstanding read only protects on this entry. This field
+ * outstanding read-only protects on this entry. This field
* must be zero whenever either is_protected or is_read_only
* are TRUE.
*
@@ -1458,13 +1458,13 @@ typedef int H5C_ring_t;
* the load of a cache image block, although other scenarios
* are contemplated for the use of this feature. Note that
* unlike the usual prefetch situation, this means that a
- * pre fetched entry can be dirty, and/or can be a party to
+ * prefetched entry can be dirty, and/or can be a party to
* flush dependency relationship(s). This complicates matters
* somewhat.
*
- * The essential feature of a pre-fetched entry is that it
+ * The essential feature of a prefetched entry is that it
* consists only of a buffer containing the on disk image of
- * the entry. Thus it must be deserialized before it can
+ * the entry. Thus it must be deserialized before it can
* be passed back to the library on a protect call. This
* task is handled by H5C_deserialized_prefetched_entry().
* In essence, this routine calls the deserialize callback
@@ -1475,7 +1475,7 @@ typedef int H5C_ring_t;
*
* Further, if the prefetched entry is a flush dependency parent,
* all its flush dependency children (which must also be
- * pre-fetched entries), must be tranfered to the new cache
+ * prefetched entries), must be tranfered to the new cache
* entry returned by the deserailization callback.
*
* Finally, if the prefetched entry is a flush dependency child,
@@ -1511,6 +1511,46 @@ typedef int H5C_ring_t;
*
* This field must be zero if prefetched is FALSE.
*
+ * prefetched_dirty: Boolean field that must be set to FALSE unless the
+ * following conditions hold:
+ *
+ * 1) The file has been opened R/O.
+ *
+ * 2) The entry is either a prefetched entry, or was
+ * re-constructed from a prefetched entry.
+ *
+ * 3) The base prefetched entry was marked dirty.
+ *
+ * This field exists to solve the following problem with
+ * files containing cache images that are opened R/O.
+ *
+ * If the cache image contains a dirty entry, that entry
+ * must be marked clean when it is inserted into the cache
+ * in the read-only case, as otherwise the metadata cache
+ * will attempt to flush it on file close -- which is poor
+ * form in the read-only case.
+ *
+ * However, since the entry is marked clean, it is possible
+ * that the metadata cache will evict it if the size of the
+ * metadata in the file exceeds the size of the metadata cache,
+ * and the application visits much of this data.
+ *
+ * If this happens, and the metadata cache is then asked for
+ * this entry, it will attempt to read it from file, and will
+ * obtain either obsolete or invalid data depending on whether
+ * the entry has ever been written to it assigned location in
+ * the file.
+ *
+ * With this background, the purpose of this field should be
+ * obvious -- when set, it allows the eviction candidate
+ * selection code to skip over the entry, thus avoiding the
+ * issue.
+ *
+ * Since the issue only arises in the R/O case, there is
+ * no possible interaction with SWMR. There are also
+ * potential interactions with Evict On Close -- at present,
+ * we deal with this by disabling EOC in the R/O case.
+ *
* serialization_count: Integer field used to maintain a count of the
* number of times each entry is serialized during cache
* serialization. While no entry should be serialized more than
@@ -1627,6 +1667,7 @@ typedef struct H5C_cache_entry_t {
hbool_t prefetched;
int prefetch_type_id;
int32_t age;
+ hbool_t prefetched_dirty;
#ifndef NDEBUG /* debugging field */
int serialization_count;
@@ -2259,7 +2300,6 @@ H5_DLL herr_t H5C_set_trace_file_ptr(H5C_t *cache_ptr, FILE *trace_file_ptr);
H5_DLL herr_t H5C_stats(H5C_t *cache_ptr, const char *cache_name,
hbool_t display_detailed_stats);
H5_DLL void H5C_stats__reset(H5C_t *cache_ptr);
-H5_DLL herr_t H5C_dump_cache(H5C_t *cache_ptr, const char *cache_name);
H5_DLL herr_t H5C_unpin_entry(void *thing);
H5_DLL herr_t H5C_destroy_flush_dependency(void *parent_thing, void *child_thing);
H5_DLL herr_t H5C_unprotect(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *thing,
@@ -2289,6 +2329,8 @@ H5_DLL herr_t H5C_mark_entries_as_clean(H5F_t *f, hid_t dxpl_id, unsigned ce_arr
#endif /* H5_HAVE_PARALLEL */
#ifndef NDEBUG /* debugging functions */
+H5_DLL herr_t H5C_dump_cache(H5C_t *cache_ptr, const char *cache_name);
+H5_DLL herr_t H5C_dump_cache_LRU(H5C_t *cache_ptr, const char *cache_name);
H5_DLL hbool_t H5C_get_serialization_in_progress(const H5C_t *cache_ptr);
H5_DLL hbool_t H5C_cache_is_clean(const H5C_t *cache_ptr, H5C_ring_t inner_ring);
H5_DLL herr_t H5C_dump_cache_skip_list(H5C_t *cache_ptr, char *calling_fcn);
diff --git a/src/H5Ctag.c b/src/H5Ctag.c
index 157a838..a9bcca1 100644
--- a/src/H5Ctag.c
+++ b/src/H5Ctag.c
@@ -465,7 +465,7 @@ H5C__evict_tagged_entries_cb(H5C_cache_entry_t *entry, void *_ctx)
entry and we'll loop back around again (as evicting other
entries will hopefully unpin this entry) */
ctx->pinned_entries_need_evicted = TRUE;
- else {
+ else if(!entry->prefetched_dirty) {
/* Evict the Entry */
if(H5C__flush_single_entry(ctx->f, ctx->dxpl_id, entry, H5C__FLUSH_INVALIDATE_FLAG | H5C__FLUSH_CLEAR_ONLY_FLAG | H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, H5_ITER_ERROR, "Entry eviction failed.")
diff --git a/test/cache.c b/test/cache.c
index 87b1272..ee4bff5 100644
--- a/test/cache.c
+++ b/test/cache.c
@@ -9825,7 +9825,6 @@ check_flush_cache__flush_op_eviction_test(H5F_t * file_ptr)
}
}
-
if(pass) {
/* Now load a large entry. This should result in the eviction
@@ -10550,7 +10549,9 @@ check_flush_cache__flush_op_eviction_test(H5F_t * file_ptr)
expected[i].is_dirty = TRUE;
}
- /* update MET 0 to set its in cache flag, and reset the its destroyed flag */
+ /* update MET 0 to set its in cache flag, and reset
+ * its destroyed flag
+ */
expected[10].in_cache = TRUE;
/* pass through non variable entries will flush VET 8, and evict VET 9.
diff --git a/test/cache_tagging.c b/test/cache_tagging.c
index 02ce19b..8901468 100644
--- a/test/cache_tagging.c
+++ b/test/cache_tagging.c
@@ -53,13 +53,16 @@
/* ===================== */
/* Helper Functions */
+#ifndef NDEBUG
static int dump_cache(hid_t fid);
+#endif /* NDEBUG */ /* end debugging functions */
static int verify_no_unknown_tags(hid_t fid);
static int mark_all_entries_investigated(hid_t fid);
static int reset_all_entries_investigated(hid_t fid);
static int verify_tag(hid_t fid, int id, haddr_t tag);
static int get_object_header_tag(hid_t loc_id, haddr_t *tag);
static int get_sbe_tag(hid_t fid, haddr_t *tag);
+
/* Tests */
static unsigned check_file_creation_tags(hid_t fcpl_id, int type);
static unsigned check_file_open_tags(hid_t fcpl, int type);
@@ -71,7 +74,6 @@ static unsigned check_attribute_rename_tags(hid_t fcpl, int type);
static unsigned check_dataset_creation_tags(hid_t fcpl, int type);
static unsigned check_dataset_creation_earlyalloc_tags(hid_t fcpl, int type);
static unsigned check_link_removal_tags(hid_t fcpl, int type);
-
static unsigned check_group_creation_tags(void);
static unsigned check_multi_group_creation_tags(void);
static unsigned check_group_open_tags(void);
@@ -95,6 +97,7 @@ static unsigned check_invalid_tag_application(void);
/* ================ */
+#ifndef NDEBUG
/*-------------------------------------------------------------------------
* Function: dump_cache()
@@ -128,6 +131,7 @@ static int dump_cache(hid_t fid)
error:
return -1;
} /* dump_cache */
+#endif /* NDEBUG */ /* end debugging functions */
/*-------------------------------------------------------------------------
@@ -445,8 +449,10 @@ check_file_creation_tags(hid_t fcpl_id, int type)
/* Create a test file with provided fcpl_t */
if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, H5P_DEFAULT)) < 0 ) TEST_ERROR;
+#ifndef NDEBUG
/* if verbose, print cache index to screen before verification . */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* verify there is a superblock entry with superblock tag */
if ( verify_tag(fid, H5AC_SUPERBLOCK_ID, H5AC__SUPERBLOCK_TAG) < 0 ) TEST_ERROR;
@@ -551,8 +557,10 @@ check_file_open_tags(hid_t fcpl, int type)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen before verification . */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* verify there is a superblock entry with superblock tag. */
if ( verify_tag(fid, H5AC_SUPERBLOCK_ID, H5AC__SUPERBLOCK_TAG) < 0 ) TEST_ERROR;
@@ -653,8 +661,10 @@ check_group_creation_tags(void)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* Verify root group's tagged metadata */
if ( verify_tag(fid, H5AC_OHDR_ID, root_tag) < 0 ) TEST_ERROR;
@@ -756,8 +766,10 @@ check_multi_group_creation_tags(void)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* Verify there is an object header for each group */
for (i = 0; i < MULTIGROUPS; i++) {
@@ -888,8 +900,10 @@ check_link_iteration_tags(void)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* Verify root group's tagged metadata */
if ( verify_tag(fid, H5AC_OHDR_ID, root_tag) < 0 ) TEST_ERROR;
@@ -1005,8 +1019,10 @@ check_dense_attribute_tags(void)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* Verify free space header and section info */
if ( verify_tag(fid, H5AC_FSPACE_SINFO_ID, d_tag) < 0 ) TEST_ERROR;
@@ -1061,8 +1077,10 @@ check_dense_attribute_tags(void)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* verify object header belonging to dataset */
if ( verify_tag(fid, H5AC_OHDR_ID, d_tag) < 0 ) TEST_ERROR;
@@ -1169,8 +1187,10 @@ check_group_open_tags(void)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* Verify root group metadata */
if ( verify_tag(fid, H5AC_OHDR_ID, root_tag) < 0 ) TEST_ERROR;
@@ -1273,8 +1293,10 @@ check_attribute_creation_tags(hid_t fcpl, int type)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* verify object header belonging to group */
if ( verify_tag(fid, H5AC_OHDR_ID, g_tag) < 0 ) TEST_ERROR;
@@ -1407,8 +1429,10 @@ check_attribute_open_tags(hid_t fcpl, int type)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* verify object header belonging to group */
if ( verify_tag(fid, H5AC_OHDR_ID, g_tag) < 0 ) TEST_ERROR;
@@ -1550,8 +1574,10 @@ check_attribute_rename_tags(hid_t fcpl, int type)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* Verify root group metadata */
if ( verify_tag(fid, H5AC_OHDR_ID, root_tag) < 0 ) TEST_ERROR;
@@ -1712,8 +1738,10 @@ check_attribute_delete_tags(hid_t fcpl, int type)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* verify object header belonging to group */
if ( verify_tag(fid, H5AC_OHDR_ID, g_tag) < 0 ) TEST_ERROR;
@@ -1834,8 +1862,10 @@ check_dataset_creation_tags(hid_t fcpl, int type)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* Verify root group metadata */
if ( verify_tag(fid, H5AC_OHDR_ID, root_tag) < 0 ) TEST_ERROR;
@@ -1959,8 +1989,10 @@ check_dataset_creation_earlyalloc_tags(hid_t fcpl, int type)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* Verify root group metadata */
if ( verify_tag(fid, H5AC_OHDR_ID, root_tag) < 0 ) TEST_ERROR;
@@ -2097,8 +2129,10 @@ check_dataset_open_tags(void)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* Verify root group metadata */
if ( verify_tag(fid, H5AC_OHDR_ID, root_tag) < 0 ) TEST_ERROR;
@@ -2228,8 +2262,10 @@ check_dataset_write_tags(void)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* Verify 10 b-tree nodes belonging to dataset */
for (i=0; i<10; i++)
@@ -2351,8 +2387,10 @@ check_attribute_write_tags(hid_t fcpl, int type)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* Verify object header of group */
if ( verify_tag(fid, H5AC_OHDR_ID, g_tag) < 0 ) TEST_ERROR;
@@ -2506,8 +2544,10 @@ check_dataset_read_tags(void)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* Verify 19 b-tree nodes belonging to dataset */
for (i=0; i<19; i++)
@@ -2636,8 +2676,10 @@ check_dataset_size_retrieval(void)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* Verify 19 b-tree nodes belonging to dataset */
for (i=0; i<19; i++)
@@ -2769,8 +2811,10 @@ check_dataset_extend_tags(void)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* Verify root group metadata */
if ( verify_tag(fid, H5AC_OHDR_ID, d_tag) < 0 ) TEST_ERROR;
@@ -2866,8 +2910,10 @@ check_object_info_tags(void)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* Verify root group's tagged metadata */
if ( verify_tag(fid, H5AC_OHDR_ID, root_tag) < 0 ) TEST_ERROR;
@@ -2972,8 +3018,10 @@ check_object_copy_tags(void)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* Verify root group's tagged metadata */
if ( verify_tag(fid, H5AC_OHDR_ID, root_tag) < 0 ) TEST_ERROR;
@@ -3122,8 +3170,10 @@ check_link_removal_tags(hid_t fcpl, int type)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* Verify root group's tagged metadata */
if ( verify_tag(fid, H5AC_OHDR_ID, root_tag) < 0 ) TEST_ERROR;
@@ -3271,8 +3321,10 @@ check_link_getname_tags(void)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* Verify root group's tagged metadata */
if ( verify_tag(fid, H5AC_OHDR_ID, root_tag) < 0 ) TEST_ERROR;
@@ -3371,8 +3423,10 @@ check_external_link_creation_tags(void)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* Verify root group metadata */
if ( verify_tag(fid, H5AC_OHDR_ID, root_tag) < 0 ) TEST_ERROR;
@@ -3478,8 +3532,10 @@ check_external_link_open_tags(void)
/* Verification of Metadata Tag Values */
/* =================================== */
+#ifndef NDEBUG
/* if verbose, print cache index to screen for visual verification */
if ( verbose ) dump_cache(fid);
+#endif /* NDEBUG */ /* end debugging functions */
/* verify tag value of first file's root group */
if ( verify_tag(fid, H5AC_OHDR_ID, root_tag) < 0 ) TEST_ERROR;
diff --git a/test/evict_on_close.c b/test/evict_on_close.c
index 3986d5a..b00c1e4 100644
--- a/test/evict_on_close.c
+++ b/test/evict_on_close.c
@@ -40,6 +40,7 @@
#include "H5Ipkg.h"
/* Uncomment to manually inspect cache states */
+/* (Requires debug build of the library) */
/* #define EOC_MANUAL_INSPECTION */
const char *FILENAMES[] = {