#include "H5Cmodule.h"
#include "H5private.h"
#include "H5ACprivate.h"
#include "H5Cpkg.h"
#include "H5Eprivate.h"
#ifndef NDEBUG
herr_t
H5C_dump_cache(H5C_t * cache_ptr, const char * cache_name)
{
H5C_cache_entry_t * entry_ptr;
H5SL_t * slist_ptr = NULL;
int i;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert(cache_ptr != NULL);
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
HDassert(cache_name != NULL );
if(NULL == (slist_ptr = H5SL_create(H5SL_TYPE_HADDR, NULL)))
HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, FAIL, "can't create skip list")
for(i = 0; i < H5C__HASH_TABLE_LEN; i++) {
entry_ptr = cache_ptr->index[i];
while(entry_ptr != NULL) {
HDassert(entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
if(H5SL_insert(slist_ptr, entry_ptr, &(entry_ptr->addr)) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "can't insert entry in skip list")
entry_ptr = entry_ptr->ht_next;
}
}
HDfprintf(stdout, "\n\nDump of metadata cache \"%s\"\n", cache_name);
HDfprintf(stdout, "Entry ");
HDfprintf(stdout, "| Address ");
HDfprintf(stdout, "| Tag ");
HDfprintf(stdout, "| Size ");
HDfprintf(stdout, "| Ring ");
HDfprintf(stdout, "| Type ");
HDfprintf(stdout, "| Prot/Pin/Dirty");
HDfprintf(stdout, "\n");
HDfprintf(stdout, "----------------------------------------------------------------------------------------------------------------\n");
i = 0;
entry_ptr = (H5C_cache_entry_t *)H5SL_remove_first(slist_ptr);
while(entry_ptr != NULL) {
HDassert(entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
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_protected));
HDfprintf(stdout, " %d", (int)(entry_ptr->is_pinned));
HDfprintf(stdout, " %d", (int)(entry_ptr->is_dirty));
HDfprintf(stdout, "\n");
entry_ptr = (H5C_cache_entry_t *)H5SL_remove_first(slist_ptr);
i++;
}
HDfprintf(stdout, "\n\n");
HDassert(H5SL_count(slist_ptr) == 0);
done:
if(slist_ptr)
H5SL_close(slist_ptr);
FUNC_LEAVE_NOAPI(ret_value)
}
#endif
#ifndef NDEBUG
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
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));
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);
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;
}
HDfprintf(stdout, "----------------------------------------------------------------------------------------------------------------\n");
FUNC_LEAVE_NOAPI(SUCCEED)
}
#endif
#ifndef NDEBUG
herr_t
H5C_dump_cache_skip_list(H5C_t * cache_ptr, char * calling_fcn)
{
herr_t ret_value = SUCCEED;
int i;
H5C_cache_entry_t * entry_ptr = NULL;
H5SL_node_t * node_ptr = NULL;
FUNC_ENTER_NOAPI_NOERR
HDassert(cache_ptr != NULL);
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
HDassert(calling_fcn != NULL);
HDfprintf(stdout, "\n\nDumping metadata cache skip list from %s.\n",
calling_fcn);
HDfprintf(stdout, " slist enabled = %d.\n",
(int)(cache_ptr->slist_enabled));
HDfprintf(stdout, " slist len = %u.\n", cache_ptr->slist_len);
HDfprintf(stdout, " slist size = %lld.\n",
(long long)(cache_ptr->slist_size));
if(cache_ptr->slist_len > 0) {
HDfprintf(stdout,
"Num: Addr: Len: Prot/Pind: Dirty: Type:\n");
i = 0;
node_ptr = H5SL_first(cache_ptr->slist_ptr);
if ( node_ptr != NULL ) {
entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr);
} else {
entry_ptr = NULL;
}
while ( entry_ptr != NULL ) {
HDassert( entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC );
HDfprintf(stdout,
"%s%d 0x%016llx %4lld %d/%d %d %s\n",
cache_ptr->prefix, i,
(long long)(entry_ptr->addr),
(long long)(entry_ptr->size),
(int)(entry_ptr->is_protected),
(int)(entry_ptr->is_pinned),
(int)(entry_ptr->is_dirty),
entry_ptr->type->name);
HDfprintf(stdout, " node_ptr = %p, item = %p\n",
node_ptr, H5SL_item(node_ptr));
node_ptr = H5SL_next(node_ptr);
if ( node_ptr != NULL ) {
entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr);
} else {
entry_ptr = NULL;
}
i++;
}
}
HDfprintf(stdout, "\n\n");
FUNC_LEAVE_NOAPI(ret_value)
}
#endif
herr_t
H5C_set_prefix(H5C_t * cache_ptr, char * prefix)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
if((cache_ptr == NULL) || (cache_ptr->magic != H5C__H5C_T_MAGIC) ||
(prefix == NULL) || (HDstrlen(prefix) >= H5C__PREFIX_LEN))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad param(s) on entry")
HDstrncpy(&(cache_ptr->prefix[0]), prefix, (size_t)(H5C__PREFIX_LEN));
cache_ptr->prefix[H5C__PREFIX_LEN - 1] = '\0';
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5C_stats(H5C_t * cache_ptr,
const char * cache_name,
hbool_t
#if !H5C_COLLECT_CACHE_STATS
H5_ATTR_UNUSED
#endif
display_detailed_stats)
{
#if H5C_COLLECT_CACHE_STATS
int i;
int64_t total_hits = 0;
int64_t total_misses = 0;
int64_t total_write_protects = 0;
int64_t total_read_protects = 0;
int64_t max_read_protects = 0;
int64_t total_insertions = 0;
int64_t total_pinned_insertions = 0;
int64_t total_clears = 0;
int64_t total_flushes = 0;
int64_t total_evictions = 0;
int64_t total_take_ownerships = 0;
int64_t total_moves = 0;
int64_t total_entry_flush_moves = 0;
int64_t total_cache_flush_moves = 0;
int64_t total_size_increases = 0;
int64_t total_size_decreases = 0;
int64_t total_entry_flush_size_changes = 0;
int64_t total_cache_flush_size_changes = 0;
int64_t total_pins = 0;
int64_t total_unpins = 0;
int64_t total_dirty_pins = 0;
int64_t total_pinned_flushes = 0;
int64_t total_pinned_clears = 0;
int32_t aggregate_max_accesses = 0;
int32_t aggregate_min_accesses = 1000000;
int32_t aggregate_max_clears = 0;
int32_t aggregate_max_flushes = 0;
size_t aggregate_max_size = 0;
int32_t aggregate_max_pins = 0;
double hit_rate;
double prefetch_use_rate;
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
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC );
if((NULL == cache_ptr) || (cache_ptr->magic != H5C__H5C_T_MAGIC) ||
(NULL == cache_name))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad cache_ptr or cache_name")
#if H5C_COLLECT_CACHE_STATS
for(i = 0; i <= cache_ptr->max_type_id; i++ ) {
total_hits += cache_ptr->hits[i];
total_misses += cache_ptr->misses[i];
total_write_protects += cache_ptr->write_protects[i];
total_read_protects += cache_ptr->read_protects[i];
if(max_read_protects < cache_ptr->max_read_protects[i])
max_read_protects = cache_ptr->max_read_protects[i];
total_insertions += cache_ptr->insertions[i];
total_pinned_insertions += cache_ptr->pinned_insertions[i];
total_clears += cache_ptr->clears[i];
total_flushes += cache_ptr->flushes[i];
total_evictions += cache_ptr->evictions[i];
total_take_ownerships += cache_ptr->take_ownerships[i];
total_moves += cache_ptr->moves[i];
total_entry_flush_moves += cache_ptr->entry_flush_moves[i];
total_cache_flush_moves += cache_ptr->cache_flush_moves[i];
total_size_increases += cache_ptr->size_increases[i];
total_size_decreases += cache_ptr->size_decreases[i];
total_entry_flush_size_changes
+= cache_ptr->entry_flush_size_changes[i];
total_cache_flush_size_changes
+= cache_ptr->cache_flush_size_changes[i];
total_pins += cache_ptr->pins[i];
total_unpins += cache_ptr->unpins[i];
total_dirty_pins += cache_ptr->dirty_pins[i];
total_pinned_flushes += cache_ptr->pinned_flushes[i];
total_pinned_clears += cache_ptr->pinned_clears[i];
#if H5C_COLLECT_CACHE_ENTRY_STATS
if(aggregate_max_accesses < cache_ptr->max_accesses[i])
aggregate_max_accesses = cache_ptr->max_accesses[i];
if(aggregate_min_accesses > aggregate_max_accesses)
aggregate_min_accesses = aggregate_max_accesses;
if(aggregate_min_accesses > cache_ptr->min_accesses[i])
aggregate_min_accesses = cache_ptr->min_accesses[i];
if(aggregate_max_clears < cache_ptr->max_clears[i])
aggregate_max_clears = cache_ptr->max_clears[i];
if(aggregate_max_flushes < cache_ptr->max_flushes[i])
aggregate_max_flushes = cache_ptr->max_flushes[i];
if(aggregate_max_size < cache_ptr->max_size[i])
aggregate_max_size = cache_ptr->max_size[i];
if(aggregate_max_pins < cache_ptr->max_pins[i])
aggregate_max_pins = cache_ptr->max_pins[i];
#endif
}
if((total_hits > 0) || (total_misses > 0))
hit_rate = (double)100.0f * ((double)(total_hits)) /
((double)(total_hits + total_misses));
else
hit_rate = 0.0f;
if(cache_ptr->successful_ht_searches > 0)
average_successful_search_depth =
((double)(cache_ptr->total_successful_ht_search_depth)) /
((double)(cache_ptr->successful_ht_searches));
if(cache_ptr->failed_ht_searches > 0)
average_failed_search_depth =
((double)(cache_ptr->total_failed_ht_search_depth)) /
((double)(cache_ptr->failed_ht_searches));
HDfprintf(stdout, "\n%sH5C: cache statistics for %s\n",
cache_ptr->prefix, cache_name);
HDfprintf(stdout, "\n");
HDfprintf(stdout,
"%s hash table insertion / deletions = %ld / %ld\n",
cache_ptr->prefix,
(long)(cache_ptr->total_ht_insertions),
(long)(cache_ptr->total_ht_deletions));
HDfprintf(stdout,
"%s HT successful / failed searches = %ld / %ld\n",
cache_ptr->prefix,
(long)(cache_ptr->successful_ht_searches),
(long)(cache_ptr->failed_ht_searches));
HDfprintf(stdout,
"%s Av. HT suc / failed search depth = %f / %f\n",
cache_ptr->prefix,
average_successful_search_depth,
average_failed_search_depth);
HDfprintf(stdout,
"%s current (max) index size / length = %ld (%ld) / %lu (%lu)\n",
cache_ptr->prefix,
(long)(cache_ptr->index_size),
(long)(cache_ptr->max_index_size),
(unsigned long)(cache_ptr->index_len),
(unsigned long)(cache_ptr->max_index_len));
HDfprintf(stdout,
"%s current (max) clean/dirty idx size = %ld (%ld) / %ld (%ld)\n",
cache_ptr->prefix,
(long)(cache_ptr->clean_index_size),
(long)(cache_ptr->max_clean_index_size),
(long)(cache_ptr->dirty_index_size),
(long)(cache_ptr->max_dirty_index_size));
HDfprintf(stdout,
"%s current (max) slist size / length = %ld (%ld) / %lu (%lu)\n",
cache_ptr->prefix,
(long)(cache_ptr->slist_size),
(long)(cache_ptr->max_slist_size),
(unsigned long)(cache_ptr->slist_len),
(unsigned long)(cache_ptr->max_slist_len));
HDfprintf(stdout,
"%s current (max) PL size / length = %ld (%ld) / %lu (%lu)\n",
cache_ptr->prefix,
(long)(cache_ptr->pl_size),
(long)(cache_ptr->max_pl_size),
(unsigned long)(cache_ptr->pl_len),
(unsigned long)(cache_ptr->max_pl_len));
HDfprintf(stdout,
"%s current (max) PEL size / length = %ld (%ld) / %lu (%lu)\n",
cache_ptr->prefix,
(long)(cache_ptr->pel_size),
(long)(cache_ptr->max_pel_size),
(unsigned long)(cache_ptr->pel_len),
(unsigned long)(cache_ptr->max_pel_len));
HDfprintf(stdout,
"%s current LRU list size / length = %ld / %lu\n",
cache_ptr->prefix,
(long)(cache_ptr->LRU_list_size),
(unsigned long)(cache_ptr->LRU_list_len));
#if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS
HDfprintf(stdout,
"%s current clean LRU size / length = %ld / %lu\n",
cache_ptr->prefix,
(long)(cache_ptr->cLRU_list_size),
(unsigned long)(cache_ptr->cLRU_list_len));
HDfprintf(stdout,
"%s current dirty LRU size / length = %ld / %lu\n",
cache_ptr->prefix,
(long)(cache_ptr->dLRU_list_size),
(unsigned long)(cache_ptr->dLRU_list_len));
#endif
HDfprintf(stdout,
"%s Total hits / misses / hit_rate = %ld / %ld / %f\n",
cache_ptr->prefix,
(long)total_hits,
(long)total_misses,
hit_rate);
HDfprintf(stdout,
"%s Total write / read (max) protects = %ld / %ld (%ld)\n",
cache_ptr->prefix,
(long)total_write_protects,
(long)total_read_protects,
(long)max_read_protects);
HDfprintf(stdout,
"%s Total clears / flushes = %ld / %ld\n",
cache_ptr->prefix,
(long)total_clears,
(long)total_flushes);
HDfprintf(stdout,
"%s Total evictions / take ownerships = %ld / %ld\n",
cache_ptr->prefix,
(long)total_evictions,
(long)total_take_ownerships);
HDfprintf(stdout,
"%s Total insertions(pinned) / moves = %ld(%ld) / %ld\n",
cache_ptr->prefix,
(long)total_insertions,
(long)total_pinned_insertions,
(long)total_moves);
HDfprintf(stdout,
"%s Total entry / cache flush moves = %ld / %ld\n",
cache_ptr->prefix,
(long)total_entry_flush_moves,
(long)total_cache_flush_moves);
HDfprintf(stdout, "%s Total entry size incrs / decrs = %ld / %ld\n",
cache_ptr->prefix,
(long)total_size_increases,
(long)total_size_decreases);
HDfprintf(stdout, "%s Ttl entry/cache flush size changes = %ld / %ld\n",
cache_ptr->prefix,
(long)total_entry_flush_size_changes,
(long)total_cache_flush_size_changes);
HDfprintf(stdout,
"%s Total entry pins (dirty) / unpins = %ld (%ld) / %ld\n",
cache_ptr->prefix,
(long)total_pins,
(long)total_dirty_pins,
(long)total_unpins);
HDfprintf(stdout, "%s Total pinned flushes / clears = %ld / %ld\n",
cache_ptr->prefix,
(long)total_pinned_flushes,
(long)total_pinned_clears);
HDfprintf(stdout, "%s MSIC: (make space in cache) calls = %lld\n",
cache_ptr->prefix,
(long long)(cache_ptr->calls_to_msic));
if (cache_ptr->calls_to_msic > 0)
average_entries_skipped_per_calls_to_msic =
(((double)(cache_ptr->total_entries_skipped_in_msic)) /
((double)(cache_ptr->calls_to_msic)));
HDfprintf(stdout, "%s MSIC: Average/max entries skipped = %lf / %ld\n",
cache_ptr->prefix,
(double)average_entries_skipped_per_calls_to_msic,
(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)));
HDfprintf(stdout, "%s MSIC: Average/max entries scanned = %lf / %ld\n",
cache_ptr->prefix,
(double)average_entries_scanned_per_calls_to_msic,
(long)(cache_ptr->max_entries_scanned_in_msic));
HDfprintf(stdout, "%s MSIC: Scanned to make space(evict) = %lld\n",
cache_ptr->prefix,
(long long)(cache_ptr->entries_scanned_to_make_space));
HDfprintf(stdout, "%s MSIC: Scanned to satisfy min_clean = %lld\n",
cache_ptr->prefix,
(long long)(cache_ptr->total_entries_scanned_in_msic -
cache_ptr->entries_scanned_to_make_space));
HDfprintf(stdout,
"%s slist/LRU/index scan restarts = %lld / %lld / %lld.\n",
cache_ptr->prefix,
(long long)(cache_ptr->slist_scan_restarts),
(long long)(cache_ptr->LRU_scan_restarts),
(long long)(cache_ptr->index_scan_restarts));
HDfprintf(stdout,
"%s cache image creations/reads/loads/size = %d / %d /%d / %Hu\n",
cache_ptr->prefix,
cache_ptr->images_created,
cache_ptr->images_read,
cache_ptr->images_loaded,
cache_ptr->last_image_size);
HDfprintf(stdout,
"%s prefetches / dirty prefetches = %lld / %lld\n",
cache_ptr->prefix,
(long long)(cache_ptr->prefetches),
(long long)(cache_ptr->dirty_prefetches));
HDfprintf(stdout,
"%s prefetch hits/flushes/evictions = %lld / %lld / %lld\n",
cache_ptr->prefix,
(long long)(cache_ptr->prefetch_hits),
(long long)(cache_ptr->flushes[H5AC_PREFETCHED_ENTRY_ID]),
(long long)(cache_ptr->evictions[H5AC_PREFETCHED_ENTRY_ID]));
if(cache_ptr->prefetches > 0)
prefetch_use_rate =
(double)100.0f * ((double)(cache_ptr->prefetch_hits)) /
((double)(cache_ptr->prefetches));
else
prefetch_use_rate = 0.0f;
HDfprintf(stdout,
"%s prefetched entry use rate = %lf\n",
cache_ptr->prefix,
prefetch_use_rate);
#if H5C_COLLECT_CACHE_ENTRY_STATS
HDfprintf(stdout, "%s aggregate max / min accesses = %d / %d\n",
cache_ptr->prefix,
(int)aggregate_max_accesses,
(int)aggregate_min_accesses);
HDfprintf(stdout, "%s aggregate max_clears / max_flushes = %d / %d\n",
cache_ptr->prefix,
(int)aggregate_max_clears,
(int)aggregate_max_flushes);
HDfprintf(stdout, "%s aggregate max_size / max_pins = %d / %d\n",
cache_ptr->prefix,
(int)aggregate_max_size,
(int)aggregate_max_pins);
#endif
if(display_detailed_stats) {
for(i = 0; i <= cache_ptr->max_type_id; i++) {
HDfprintf(stdout, "\n");
HDfprintf(stdout, "%s Stats on %s:\n",
cache_ptr->prefix,
((cache_ptr->class_table_ptr))[i]->name);
if((cache_ptr->hits[i] > 0) || (cache_ptr->misses[i] > 0))
hit_rate = (double)100.0f * ((double)(cache_ptr->hits[i])) /
((double)(cache_ptr->hits[i] + cache_ptr->misses[i]));
else
hit_rate = 0.0f;
HDfprintf(stdout,
"%s hits / misses / hit_rate = %ld / %ld / %f\n",
cache_ptr->prefix,
(long)(cache_ptr->hits[i]),
(long)(cache_ptr->misses[i]),
hit_rate);
HDfprintf(stdout,
"%s write / read (max) protects = %ld / %ld (%d)\n",
cache_ptr->prefix,
(long)(cache_ptr->write_protects[i]),
(long)(cache_ptr->read_protects[i]),
(int)(cache_ptr->max_read_protects[i]));
HDfprintf(stdout,
"%s clears / flushes = %ld / %ld\n",
cache_ptr->prefix,
(long)(cache_ptr->clears[i]),
(long)(cache_ptr->flushes[i]));
HDfprintf(stdout,
"%s evictions / take ownerships = %ld / %ld\n",
cache_ptr->prefix,
(long)(cache_ptr->evictions[i]),
(long)(cache_ptr->take_ownerships[i]));
HDfprintf(stdout,
"%s insertions(pinned) / moves = %ld(%ld) / %ld\n",
cache_ptr->prefix,
(long)(cache_ptr->insertions[i]),
(long)(cache_ptr->pinned_insertions[i]),
(long)(cache_ptr->moves[i]));
HDfprintf(stdout,
"%s entry / cache flush moves = %ld / %ld\n",
cache_ptr->prefix,
(long)(cache_ptr->entry_flush_moves[i]),
(long)(cache_ptr->cache_flush_moves[i]));
HDfprintf(stdout,
"%s size increases / decreases = %ld / %ld\n",
cache_ptr->prefix,
(long)(cache_ptr->size_increases[i]),
(long)(cache_ptr->size_decreases[i]));
HDfprintf(stdout,
"%s entry/cache flush size changes = %ld / %ld\n",
cache_ptr->prefix,
(long)(cache_ptr->entry_flush_size_changes[i]),
(long)(cache_ptr->cache_flush_size_changes[i]));
HDfprintf(stdout,
"%s entry pins / unpins = %ld / %ld\n",
cache_ptr->prefix,
(long)(cache_ptr->pins[i]),
(long)(cache_ptr->unpins[i]));
HDfprintf(stdout,
"%s entry dirty pins/pin'd flushes = %ld / %ld\n",
cache_ptr->prefix,
(long)(cache_ptr->dirty_pins[i]),
(long)(cache_ptr->pinned_flushes[i]));
#if H5C_COLLECT_CACHE_ENTRY_STATS
HDfprintf(stdout,
"%s entry max / min accesses = %d / %d\n",
cache_ptr->prefix,
cache_ptr->max_accesses[i],
cache_ptr->min_accesses[i]);
HDfprintf(stdout,
"%s entry max_clears / max_flushes = %d / %d\n",
cache_ptr->prefix,
cache_ptr->max_clears[i],
cache_ptr->max_flushes[i]);
HDfprintf(stdout,
"%s entry max_size / max_pins = %d / %d\n",
cache_ptr->prefix,
(int)(cache_ptr->max_size[i]),
(int)(cache_ptr->max_pins[i]));
#endif
}
}
HDfprintf(stdout, "\n");
#endif
done:
FUNC_LEAVE_NOAPI(ret_value)
}
void
#ifndef NDEBUG
H5C_stats__reset(H5C_t * cache_ptr)
#else
#if H5C_COLLECT_CACHE_STATS
H5C_stats__reset(H5C_t * cache_ptr)
#else
H5C_stats__reset(H5C_t H5_ATTR_UNUSED * cache_ptr)
#endif
#endif
{
#if H5C_COLLECT_CACHE_STATS
int i;
#endif
HDassert(cache_ptr);
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
#if H5C_COLLECT_CACHE_STATS
for(i = 0; i <= cache_ptr->max_type_id; i++) {
cache_ptr->hits[i] = 0;
cache_ptr->misses[i] = 0;
cache_ptr->write_protects[i] = 0;
cache_ptr->read_protects[i] = 0;
cache_ptr->max_read_protects[i] = 0;
cache_ptr->insertions[i] = 0;
cache_ptr->pinned_insertions[i] = 0;
cache_ptr->clears[i] = 0;
cache_ptr->flushes[i] = 0;
cache_ptr->evictions[i] = 0;
cache_ptr->take_ownerships[i] = 0;
cache_ptr->moves[i] = 0;
cache_ptr->entry_flush_moves[i] = 0;
cache_ptr->cache_flush_moves[i] = 0;
cache_ptr->pins[i] = 0;
cache_ptr->unpins[i] = 0;
cache_ptr->dirty_pins[i] = 0;
cache_ptr->pinned_flushes[i] = 0;
cache_ptr->pinned_clears[i] = 0;
cache_ptr->size_increases[i] = 0;
cache_ptr->size_decreases[i] = 0;
cache_ptr->entry_flush_size_changes[i] = 0;
cache_ptr->cache_flush_size_changes[i] = 0;
}
cache_ptr->total_ht_insertions = 0;
cache_ptr->total_ht_deletions = 0;
cache_ptr->successful_ht_searches = 0;
cache_ptr->total_successful_ht_search_depth = 0;
cache_ptr->failed_ht_searches = 0;
cache_ptr->total_failed_ht_search_depth = 0;
cache_ptr->max_index_len = 0;
cache_ptr->max_index_size = (size_t)0;
cache_ptr->max_clean_index_size = (size_t)0;
cache_ptr->max_dirty_index_size = (size_t)0;
cache_ptr->max_slist_len = 0;
cache_ptr->max_slist_size = (size_t)0;
cache_ptr->max_pl_len = 0;
cache_ptr->max_pl_size = (size_t)0;
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_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;
cache_ptr->index_scan_restarts = 0;
cache_ptr->images_created = 0;
cache_ptr->images_read = 0;
cache_ptr->images_loaded = 0;
cache_ptr->last_image_size = (hsize_t)0;
cache_ptr->prefetches = 0;
cache_ptr->dirty_prefetches = 0;
cache_ptr->prefetch_hits = 0;
#if H5C_COLLECT_CACHE_ENTRY_STATS
for(i = 0; i <= cache_ptr->max_type_id; i++) {
cache_ptr->max_accesses[i] = 0;
cache_ptr->min_accesses[i] = 1000000;
cache_ptr->max_clears[i] = 0;
cache_ptr->max_flushes[i] = 0;
cache_ptr->max_size[i] = (size_t)0;
cache_ptr->max_pins[i] = 0;
}
#endif
#endif
return;
}
extern void
H5C__dump_entry(H5C_t *cache_ptr, const H5C_cache_entry_t *entry_ptr,
hbool_t dump_parents, const char *prefix, int indent);
static void
H5C__dump_parents(H5C_t *cache_ptr, const H5C_cache_entry_t *entry_ptr, const char *prefix, int indent)
{
unsigned u;
for(u = 0; u < entry_ptr->flush_dep_nparents; u++)
H5C__dump_entry(cache_ptr, entry_ptr->flush_dep_parent[u], TRUE, prefix, indent + 2);
}
typedef struct H5C__dump_child_ctx_t {
H5C_t *cache_ptr;
const H5C_cache_entry_t *parent;
hbool_t dump_parents;
const char *prefix;
int indent;
} H5C__dump_child_ctx_t;
static int
H5C__dump_children_cb(H5C_cache_entry_t *entry_ptr, void *_ctx)
{
H5C__dump_child_ctx_t *ctx = (H5C__dump_child_ctx_t *)_ctx;
if(entry_ptr->tag_info->tag != entry_ptr->addr) {
unsigned u;
HDassert(entry_ptr->flush_dep_nparents);
for(u = 0; u < entry_ptr->flush_dep_nparents; u++)
if(ctx->parent == entry_ptr->flush_dep_parent[u])
H5C__dump_entry(ctx->cache_ptr, entry_ptr, ctx->dump_parents, ctx->prefix, ctx->indent + 2);
}
return(H5_ITER_CONT);
}
static void
H5C__dump_children(H5C_t *cache_ptr, const H5C_cache_entry_t *entry_ptr,
hbool_t dump_parents, const char *prefix, int indent)
{
H5C__dump_child_ctx_t ctx;
HDassert(entry_ptr->tag_info);
ctx.cache_ptr = cache_ptr;
ctx.parent = entry_ptr;
ctx.dump_parents = dump_parents;
ctx.prefix = prefix;
ctx.indent = indent;
H5C__iter_tagged_entries(cache_ptr, entry_ptr->tag_info->tag, FALSE, H5C__dump_children_cb, &ctx);
}
void
H5C__dump_entry(H5C_t *cache_ptr, const H5C_cache_entry_t *entry_ptr,
hbool_t dump_parents, const char *prefix, int indent)
{
HDassert(cache_ptr);
HDassert(entry_ptr);
HDfprintf(stderr, "%*s%s: entry_ptr = (%a, '%s', %a, %t, %u, %u/%u)\n", indent, "", prefix, entry_ptr->addr, entry_ptr->type->name, entry_ptr->tag_info ? entry_ptr->tag_info->tag : HADDR_UNDEF, entry_ptr->is_dirty, entry_ptr->flush_dep_nparents, entry_ptr->flush_dep_nchildren, entry_ptr->flush_dep_ndirty_children);
if(dump_parents && entry_ptr->flush_dep_nparents)
H5C__dump_parents(cache_ptr, entry_ptr, "Parent", indent);
if(entry_ptr->flush_dep_nchildren)
H5C__dump_children(cache_ptr, entry_ptr, FALSE, "Child", indent);
}
#ifndef NDEBUG
herr_t
H5C_flush_dependency_exists(H5C_t *cache_ptr, haddr_t parent_addr, haddr_t child_addr,
hbool_t *fd_exists_ptr)
{
hbool_t fd_exists = FALSE;
H5C_cache_entry_t * parent_ptr;
H5C_cache_entry_t * child_ptr;
hbool_t ret_value = FALSE;
FUNC_ENTER_NOAPI(NULL)
HDassert(cache_ptr);
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
HDassert(H5F_addr_defined(parent_addr));
HDassert(H5F_addr_defined(child_addr));
HDassert(fd_exists_ptr);
H5C__SEARCH_INDEX(cache_ptr, parent_addr, parent_ptr, FAIL)
H5C__SEARCH_INDEX(cache_ptr, child_addr, child_ptr, FAIL)
if(parent_ptr && child_ptr) {
HDassert(parent_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
HDassert(child_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
if(child_ptr->flush_dep_nparents > 0) {
unsigned u;
HDassert(child_ptr->flush_dep_parent);
HDassert(child_ptr->flush_dep_parent_nalloc >= child_ptr->flush_dep_nparents);
for(u = 0; u < child_ptr->flush_dep_nparents; u++) {
if(child_ptr->flush_dep_parent[u] == parent_ptr) {
fd_exists = TRUE;
HDassert(parent_ptr->flush_dep_nchildren > 0);
break;
}
}
}
}
*fd_exists_ptr = fd_exists;
done:
FUNC_LEAVE_NOAPI(ret_value)
}
#endif
#ifndef NDEBUG
herr_t
H5C_validate_index_list(H5C_t *cache_ptr)
{
H5C_cache_entry_t * entry_ptr = NULL;
uint32_t len = 0;
int32_t index_ring_len[H5C_RING_NTYPES];
size_t size = 0;
size_t clean_size = 0;
size_t dirty_size = 0;
size_t index_ring_size[H5C_RING_NTYPES];
size_t clean_index_ring_size[H5C_RING_NTYPES];
size_t dirty_index_ring_size[H5C_RING_NTYPES];
int i;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT
HDassert(cache_ptr);
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
for(i = 0; i < H5C_RING_NTYPES; i++) {
index_ring_len[i] = 0;
index_ring_size[i] = 0;
clean_index_ring_size[i] = 0;
dirty_index_ring_size[i] = 0;
}
if(((cache_ptr->il_head == NULL) || (cache_ptr->il_tail == NULL))
&& (cache_ptr->il_head != cache_ptr->il_tail))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Index list pointer validation failed")
if((cache_ptr->index_len == 1) && ((cache_ptr->il_head != cache_ptr->il_tail)
|| (cache_ptr->il_head == NULL) || (cache_ptr->il_head->size != cache_ptr->index_size)))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Index list pointer sanity checks failed")
if((cache_ptr->index_len >= 1)
&& ((cache_ptr->il_head == NULL)
|| (cache_ptr->il_head->il_prev != NULL)
|| (cache_ptr->il_tail == NULL)
|| (cache_ptr->il_tail->il_next != NULL)))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Index list length sanity checks failed")
entry_ptr = cache_ptr->il_head;
while(entry_ptr != NULL) {
if((entry_ptr != cache_ptr->il_head)
&& ((entry_ptr->il_prev == NULL) || (entry_ptr->il_prev->il_next != entry_ptr)))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Index list pointers for entry are invalid")
if((entry_ptr != cache_ptr->il_tail)
&& ((entry_ptr->il_next == NULL) || (entry_ptr->il_next->il_prev != entry_ptr)))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Index list pointers for entry are invalid")
HDassert(entry_ptr->ring > 0);
HDassert(entry_ptr->ring < H5C_RING_NTYPES);
len++;
index_ring_len[entry_ptr->ring] += 1;
size += entry_ptr->size;
index_ring_size[entry_ptr->ring] += entry_ptr->size;
if(entry_ptr->is_dirty) {
dirty_size += entry_ptr->size;
dirty_index_ring_size[entry_ptr->ring] += entry_ptr->size;
}
else {
clean_size += entry_ptr->size;
clean_index_ring_size[entry_ptr->ring] += entry_ptr->size;
}
entry_ptr = entry_ptr->il_next;
}
if((cache_ptr->index_len != len) || (cache_ptr->il_len != len)
|| (cache_ptr->index_size != size) || (cache_ptr->il_size != size)
|| (cache_ptr->clean_index_size != clean_size)
|| (cache_ptr->dirty_index_size != dirty_size)
|| (clean_size + dirty_size != size))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Index, clean and dirty sizes for cache are invalid")
size = 0;
clean_size = 0;
dirty_size = 0;
for(i = 0; i < H5C_RING_NTYPES; i++) {
size += clean_index_ring_size[i] + dirty_index_ring_size[i];
clean_size += clean_index_ring_size[i];
dirty_size += dirty_index_ring_size[i];
}
if((cache_ptr->index_size != size)
|| (cache_ptr->clean_index_size != clean_size)
|| (cache_ptr->dirty_index_size != dirty_size))
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Index, clean and dirty sizes for cache are invalid")
done:
if(ret_value != SUCCEED)
HDassert(0);
FUNC_LEAVE_NOAPI(ret_value)
}
#endif
#ifndef NDEBUG
herr_t
H5C_get_entry_ptr_from_addr(H5C_t *cache_ptr, haddr_t addr, void **entry_ptr_ptr)
{
H5C_cache_entry_t * entry_ptr = NULL;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert(cache_ptr);
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
HDassert(H5F_addr_defined(addr));
HDassert(entry_ptr_ptr);
H5C__SEARCH_INDEX(cache_ptr, addr, entry_ptr, FAIL)
if(entry_ptr == NULL)
*entry_ptr_ptr = NULL;
else {
*entry_ptr_ptr = entry_ptr;
(cache_ptr->get_entry_ptr_from_addr_counter)++;
}
done:
FUNC_LEAVE_NOAPI(ret_value)
}
#endif
#ifndef NDEBUG
hbool_t
H5C_get_serialization_in_progress(const H5C_t *cache_ptr)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(cache_ptr);
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
FUNC_LEAVE_NOAPI(cache_ptr->serialization_in_progress)
}
#endif
#ifndef NDEBUG
hbool_t
H5C_cache_is_clean(const H5C_t *cache_ptr, H5C_ring_t inner_ring)
{
H5C_ring_t ring = H5C_RING_USER;
hbool_t ret_value = TRUE;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(cache_ptr);
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
HDassert(inner_ring >= H5C_RING_USER);
HDassert(inner_ring <= H5C_RING_SB);
while(ring <= inner_ring) {
if(cache_ptr->dirty_index_ring_size[ring] > 0)
HGOTO_DONE(FALSE)
ring++;
}
done:
FUNC_LEAVE_NOAPI(ret_value)
}
#endif
#ifndef NDEBUG
herr_t
H5C_verify_entry_type(H5C_t *cache_ptr, haddr_t addr,
const H5C_class_t *expected_type, hbool_t *in_cache_ptr,
hbool_t *type_ok_ptr)
{
H5C_cache_entry_t * entry_ptr = NULL;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert(cache_ptr);
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
HDassert(H5F_addr_defined(addr));
HDassert(expected_type);
HDassert(in_cache_ptr);
HDassert(type_ok_ptr);
H5C__SEARCH_INDEX(cache_ptr, addr, entry_ptr, FAIL)
if(entry_ptr == NULL)
*in_cache_ptr = FALSE;
else {
*in_cache_ptr = TRUE;
if(entry_ptr->prefetched)
*type_ok_ptr = (expected_type->id == entry_ptr->prefetch_type_id);
else
*type_ok_ptr = (expected_type == entry_ptr->type);
}
done:
FUNC_LEAVE_NOAPI(ret_value)
}
#endif