diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2017-03-12 09:57:19 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2017-03-12 09:57:19 (GMT) |
commit | c4a36e0bb3b56e0c8397876be1c66fedb2f57d83 (patch) | |
tree | bafeb848fb17a45a11a75abbbc50778b52347e59 /src | |
parent | 36f06cab798cd45261988e2618018e0763f5e2fd (diff) | |
download | hdf5-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.
Diffstat (limited to 'src')
-rw-r--r-- | src/H5AC.c | 9 | ||||
-rw-r--r-- | src/H5ACdbg.c | 2 | ||||
-rw-r--r-- | src/H5ACprivate.h | 2 | ||||
-rw-r--r-- | src/H5C.c | 42 | ||||
-rw-r--r-- | src/H5Cdbg.c | 106 | ||||
-rw-r--r-- | src/H5Cimage.c | 2 | ||||
-rw-r--r-- | src/H5Cpkg.h | 12 | ||||
-rw-r--r-- | src/H5Cprivate.h | 58 | ||||
-rw-r--r-- | src/H5Ctag.c | 2 |
9 files changed, 204 insertions, 31 deletions
@@ -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, @@ -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.") |