diff options
author | Quincey Koziol <koziol@lbl.gov> | 2016-11-03 21:15:26 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@lbl.gov> | 2016-11-03 21:15:26 (GMT) |
commit | 7ac8215cbffbf1a3c0000cc0b5ade502040b25be (patch) | |
tree | c4aa63e868aeab10846ca6aa72955ccc32af632d /src | |
parent | 50c7c5451486518ea8a57fa079db5cb007d159bd (diff) | |
parent | b2878dec04c120e4e3cdf00e943283e359862c84 (diff) | |
download | hdf5-7ac8215cbffbf1a3c0000cc0b5ade502040b25be.zip hdf5-7ac8215cbffbf1a3c0000cc0b5ade502040b25be.tar.gz hdf5-7ac8215cbffbf1a3c0000cc0b5ade502040b25be.tar.bz2 |
Merge pull request #123 in HDFFV/hdf5 from ~KOZIOL/hdf5:develop to develop
* commit 'b2878dec04c120e4e3cdf00e943283e359862c84':
Move cache debugging routines into separate module.
Change file memory type for extending to default, and correct error in backward compatibility for multi VFD.
Warning and whitespace cleanup.
Improvements to the log VFD, for helping with SWMR debugging.
Minor code cleanups.
Uncomment line in test/objcopy.c, clean up whitespace and POSIX call wrapping in tools code.
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/H5AC.c | 179 | ||||
-rw-r--r-- | src/H5ACdbg.c | 253 | ||||
-rw-r--r-- | src/H5C.c | 921 | ||||
-rw-r--r-- | src/H5Cdbg.c | 964 | ||||
-rw-r--r-- | src/H5FDint.c | 18 | ||||
-rw-r--r-- | src/H5FDlog.c | 118 | ||||
-rw-r--r-- | src/H5FDlog.h | 47 | ||||
-rw-r--r-- | src/H5FDmpio.c | 4 | ||||
-rw-r--r-- | src/H5FDmulti.c | 32 | ||||
-rw-r--r-- | src/H5FDprivate.h | 18 | ||||
-rw-r--r-- | src/H5Fint.c | 10 | ||||
-rw-r--r-- | src/H5Fsuper.c | 12 | ||||
-rw-r--r-- | src/Makefile.am | 4 |
14 files changed, 1416 insertions, 1166 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 94b2d11..3f03c87 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -44,6 +44,7 @@ IDE_GENERATED_PROPERTIES ("H5A" "${H5A_HDRS}" "${H5A_SOURCES}" ) set (H5AC_SOURCES ${HDF5_SRC_DIR}/H5AC.c + ${HDF5_SRC_DIR}/H5ACdbg.c ${HDF5_SRC_DIR}/H5ACmpio.c ) @@ -83,6 +84,7 @@ IDE_GENERATED_PROPERTIES ("H5B2" "${H5B2_HDRS}" "${H5B2_SOURCES}" ) set (H5C_SOURCES ${HDF5_SRC_DIR}/H5C.c + ${HDF5_SRC_DIR}/H5Cdbg.c ${HDF5_SRC_DIR}/H5Cepoch.c ${HDF5_SRC_DIR}/H5Cmpio.c ${HDF5_SRC_DIR}/H5Cquery.c @@ -1505,70 +1505,6 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_unprotect() */ -#ifndef NDEBUG /* debugging functions */ - -/*------------------------------------------------------------------------- - * Function: H5AC_stats - * - * Purpose: Prints statistics about the cache. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Thursday, October 30, 1997 - * - *------------------------------------------------------------------------- - */ -herr_t -H5AC_stats(const H5F_t *f) -{ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* Sanity checks */ - HDassert(f); - HDassert(f->shared); - HDassert(f->shared->cache); - - /* at present, this can't fail */ - (void)H5C_stats(f->shared->cache, H5F_OPEN_NAME(f), FALSE); - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5AC_stats() */ - - -/*------------------------------------------------------------------------- - * Function: H5AC_dump_cache - * - * Purpose: Dumps a summary of the contents of the metadata cache - * to stdout. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: John Mainzer - * Sunday, October 10, 2010 - * - *------------------------------------------------------------------------- - */ -herr_t -H5AC_dump_cache(const H5F_t *f) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - /* Sanity checks */ - HDassert(f); - HDassert(f->shared); - HDassert(f->shared->cache); - - if(H5C_dump_cache(f->shared->cache, H5F_OPEN_NAME(f)) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_dump_cache() failed.") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5AC_dump_cache() */ -#endif /* NDEBUG */ - /*------------------------------------------------------------------------- * Function: H5AC_get_cache_auto_resize_config @@ -1964,121 +1900,6 @@ done: } /* H5AC_validate_config() */ -/*------------------------------------------------------------------------- - * Function: H5AC__close_trace_file() - * - * Purpose: If a trace file is open, stop logging calls to the cache, - * and close the file. - * - * Note that the function does nothing if there is no trace - * file. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: John Mainzer - * 6/2/06 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5AC__close_trace_file(H5AC_t *cache_ptr) -{ - FILE * trace_file_ptr = NULL; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_STATIC - - if(cache_ptr == NULL) - HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "NULL cache_ptr on entry.") - - if(NULL == (trace_file_ptr = H5C_get_trace_file_ptr(cache_ptr))) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_get_trace_file_ptr() failed.") - - if(trace_file_ptr != NULL) { - if(H5C_set_trace_file_ptr(cache_ptr, NULL) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_set_trace_file_ptr() failed.") - - if(HDfclose(trace_file_ptr) != 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close metadata cache trace file") - } /* end if */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5AC__close_trace_file() */ - - -/*------------------------------------------------------------------------- - * Function: H5AC__open_trace_file() - * - * Purpose: Open a trace file, and start logging calls to the cache. - * - * This logging is done at the H5C level, and will only take - * place if H5C_TRACE_FILE_ENABLED (defined in H5Cprivate.h) - * is TRUE. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: John Mainzer - * 6/1/06 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5AC__open_trace_file(H5AC_t *cache_ptr, const char *trace_file_name) -{ - char file_name[H5AC__MAX_TRACE_FILE_NAME_LEN + H5C__PREFIX_LEN + 2]; - FILE * file_ptr = NULL; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_STATIC - - HDassert(cache_ptr); - - /* Check args */ - if(cache_ptr == NULL) - HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "cache_ptr NULL on entry.") - if(trace_file_name == NULL) - HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "NULL trace_file_name on entry.") - if(HDstrlen(trace_file_name) > H5AC__MAX_TRACE_FILE_NAME_LEN) - HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "trace file name too long.") - if(NULL != (file_ptr = H5C_get_trace_file_ptr(cache_ptr))) - HGOTO_ERROR(H5E_CACHE, H5E_FILEOPEN, FAIL, "trace file already open.") - -#ifdef H5_HAVE_PARALLEL -{ - H5AC_aux_t * aux_ptr; - - aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(cache_ptr); - if(aux_ptr == NULL) - sprintf(file_name, "%s", trace_file_name); - else { - if(aux_ptr->magic != H5AC__H5AC_AUX_T_MAGIC) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad aux_ptr->magic.") - - sprintf(file_name, "%s.%d", trace_file_name, aux_ptr->mpi_rank); - } /* end else */ - - if(HDstrlen(file_name) > H5AC__MAX_TRACE_FILE_NAME_LEN + H5C__PREFIX_LEN + 1) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "cooked trace file name too long.") -} -#else /* H5_HAVE_PARALLEL */ - HDsnprintf(file_name, (size_t)(H5AC__MAX_TRACE_FILE_NAME_LEN + H5C__PREFIX_LEN + 1), - "%s", trace_file_name); -#endif /* H5_HAVE_PARALLEL */ - - if((file_ptr = HDfopen(file_name, "w")) == NULL) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "trace file open failed.") - - HDfprintf(file_ptr, "### HDF5 metadata cache trace file version 1 ###\n"); - - if(H5C_set_trace_file_ptr(cache_ptr, file_ptr) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_set_trace_file_ptr() failed.") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5AC__open_trace_file() */ - - /*************************************************************************/ /**************************** Private Functions: *************************/ /*************************************************************************/ diff --git a/src/H5ACdbg.c b/src/H5ACdbg.c new file mode 100644 index 0000000..3830606 --- /dev/null +++ b/src/H5ACdbg.c @@ -0,0 +1,253 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5ACdbg.c + * + * Purpose: Functions for debugging the metadata cache + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ +#include "H5ACmodule.h" /* This source code file is part of the H5AC module */ +#define H5F_FRIEND /* Suppress error about including H5Fpkg */ + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5ACpkg.h" /* Metadata cache */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fpkg.h" /* Files */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + +#ifndef NDEBUG /* debugging functions */ + +/*------------------------------------------------------------------------- + * Function: H5AC_stats + * + * Purpose: Prints statistics about the cache. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Thursday, October 30, 1997 + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC_stats(const H5F_t *f) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Sanity checks */ + HDassert(f); + HDassert(f->shared); + HDassert(f->shared->cache); + + /* at present, this can't fail */ + (void)H5C_stats(f->shared->cache, H5F_OPEN_NAME(f), FALSE); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5AC_stats() */ + + +/*------------------------------------------------------------------------- + * Function: H5AC_dump_cache + * + * Purpose: Dumps a summary of the contents of the metadata cache + * to stdout. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: John Mainzer + * Sunday, October 10, 2010 + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC_dump_cache(const H5F_t *f) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(f); + HDassert(f->shared); + HDassert(f->shared->cache); + + if(H5C_dump_cache(f->shared->cache, H5F_OPEN_NAME(f)) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_dump_cache() failed.") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC_dump_cache() */ +#endif /* NDEBUG */ + + +/*------------------------------------------------------------------------- + * Function: H5AC__close_trace_file() + * + * Purpose: If a trace file is open, stop logging calls to the cache, + * and close the file. + * + * Note that the function does nothing if there is no trace + * file. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: John Mainzer + * 6/2/06 + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC__close_trace_file(H5AC_t *cache_ptr) +{ + FILE * trace_file_ptr; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + if(cache_ptr == NULL) + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "NULL cache_ptr on entry.") + + if(NULL == (trace_file_ptr = H5C_get_trace_file_ptr(cache_ptr))) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_get_trace_file_ptr() failed.") + + if(trace_file_ptr != NULL) { + if(H5C_set_trace_file_ptr(cache_ptr, NULL) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_set_trace_file_ptr() failed.") + + if(HDfclose(trace_file_ptr) != 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close metadata cache trace file") + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC__close_trace_file() */ + + +/*------------------------------------------------------------------------- + * Function: H5AC__open_trace_file() + * + * Purpose: Open a trace file, and start logging calls to the cache. + * + * This logging is done at the H5C level, and will only take + * place if H5C_TRACE_FILE_ENABLED (defined in H5Cprivate.h) + * is TRUE. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: John Mainzer + * 6/1/06 + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC__open_trace_file(H5AC_t *cache_ptr, const char *trace_file_name) +{ + char file_name[H5AC__MAX_TRACE_FILE_NAME_LEN + H5C__PREFIX_LEN + 2]; + FILE * file_ptr; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + HDassert(cache_ptr); + + /* Check args */ + if(cache_ptr == NULL) + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "cache_ptr NULL on entry.") + if(trace_file_name == NULL) + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "NULL trace_file_name on entry.") + if(HDstrlen(trace_file_name) > H5AC__MAX_TRACE_FILE_NAME_LEN) + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "trace file name too long.") + if(NULL != (file_ptr = H5C_get_trace_file_ptr(cache_ptr))) + HGOTO_ERROR(H5E_CACHE, H5E_FILEOPEN, FAIL, "trace file already open.") + +#ifdef H5_HAVE_PARALLEL +{ + H5AC_aux_t * aux_ptr; + + aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(cache_ptr); + if(aux_ptr == NULL) + sprintf(file_name, "%s", trace_file_name); + else { + if(aux_ptr->magic != H5AC__H5AC_AUX_T_MAGIC) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad aux_ptr->magic.") + + sprintf(file_name, "%s.%d", trace_file_name, aux_ptr->mpi_rank); + } /* end else */ + + if(HDstrlen(file_name) > H5AC__MAX_TRACE_FILE_NAME_LEN + H5C__PREFIX_LEN + 1) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "cooked trace file name too long.") +} +#else /* H5_HAVE_PARALLEL */ + HDsnprintf(file_name, (size_t)(H5AC__MAX_TRACE_FILE_NAME_LEN + H5C__PREFIX_LEN + 1), + "%s", trace_file_name); +#endif /* H5_HAVE_PARALLEL */ + + if((file_ptr = HDfopen(file_name, "w")) == NULL) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "trace file open failed.") + + HDfprintf(file_ptr, "### HDF5 metadata cache trace file version 1 ###\n"); + + if(H5C_set_trace_file_ptr(cache_ptr, file_ptr) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_set_trace_file_ptr() failed.") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC__open_trace_file() */ + @@ -189,11 +189,6 @@ static void H5C__assert_flush_dep_nocycle(const H5C_cache_entry_t * entry, const H5C_cache_entry_t * base_entry); #endif /* NDEBUG */ -#if 0 /* debugging routines */ -herr_t H5C_dump_cache(H5C_t * cache_ptr, const char * cache_name); -herr_t H5C_dump_cache_skip_list(H5C_t * cache_ptr, char * calling_fcn); -#endif /* debugging routines */ - /*********************/ /* Package Variables */ @@ -2907,922 +2902,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5C_set_prefix - * - * Purpose: Set the values of the prefix field of H5C_t. This - * filed is used to label some debugging output. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: John Mainzer - * 1/20/06 - * - *------------------------------------------------------------------------- - */ -herr_t -H5C_set_prefix(H5C_t * cache_ptr, char * prefix) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - 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) -} /* H5C_set_prefix() */ - - -/*------------------------------------------------------------------------- - * Function: H5C_set_trace_file_ptr - * - * Purpose: Set the trace_file_ptr field for the cache. - * - * This field must either be NULL (which turns of trace - * file logging), or be a pointer to an open file to which - * trace file data is to be written. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: John Mainzer - * 1/20/06 - * - *------------------------------------------------------------------------- - */ -herr_t -H5C_set_trace_file_ptr(H5C_t * cache_ptr, - FILE * trace_file_ptr) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - /* This would normally be an assert, but we need to use an HGOTO_ERROR - * call to shut up the compiler. - */ - if ( ( ! cache_ptr ) || ( cache_ptr->magic != H5C__H5C_T_MAGIC ) ) { - - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad cache_ptr") - } - - cache_ptr->trace_file_ptr = trace_file_ptr; - -done: - FUNC_LEAVE_NOAPI(ret_value) - -} /* H5C_set_trace_file_ptr() */ - - -/*------------------------------------------------------------------------- - * Function: H5C_stats - * - * Purpose: Prints statistics about the cache. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: John Mainzer - * 6/2/04 - * - * JRM -- 11/13/08 - * Added code displaying the max_clean_index_size and - * max_dirty_index_size. - * - * MAM -- 01/06/09 - * Added code displaying the calls_to_msic, - * total_entries_skipped_in_msic, total_entries_scanned_in_msic, - * and max_entries_skipped_in_msic fields. - * - * JRM -- 4/11/15 - * Added code displaying the new slist_scan_restarts, - * LRU_scan_restarts, and hash_bucket_scan_restarts fields; - * - *------------------------------------------------------------------------- - */ -herr_t -H5C_stats(H5C_t * cache_ptr, - const char * cache_name, - hbool_t -#if !H5C_COLLECT_CACHE_STATS - H5_ATTR_UNUSED -#endif /* H5C_COLLECT_CACHE_STATS */ - 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 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_entries_scanned_per_calls_to_msic = 0.0f; -#endif /* H5C_COLLECT_CACHE_STATS */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC ); - - /* This would normally be an assert, but we need to use an HGOTO_ERROR - * call to shut up the compiler. - */ - if ( ( ! cache_ptr ) || - ( cache_ptr->magic != H5C__H5C_T_MAGIC ) || - ( !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 /* H5C_COLLECT_CACHE_ENTRY_STATS */ - } - - 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) / %ld (%ld)\n", - cache_ptr->prefix, - (long)(cache_ptr->index_size), - (long)(cache_ptr->max_index_size), - (long)(cache_ptr->index_len), - (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) / %ld (%ld)\n", - cache_ptr->prefix, - (long)(cache_ptr->slist_size), - (long)(cache_ptr->max_slist_size), - (long)(cache_ptr->slist_len), - (long)(cache_ptr->max_slist_len)); - - HDfprintf(stdout, - "%s current (max) PL size / length = %ld (%ld) / %ld (%ld)\n", - cache_ptr->prefix, - (long)(cache_ptr->pl_size), - (long)(cache_ptr->max_pl_size), - (long)(cache_ptr->pl_len), - (long)(cache_ptr->max_pl_len)); - - HDfprintf(stdout, - "%s current (max) PEL size / length = %ld (%ld) / %ld (%ld)\n", - cache_ptr->prefix, - (long)(cache_ptr->pel_size), - (long)(cache_ptr->max_pel_size), - (long)(cache_ptr->pel_len), - (long)(cache_ptr->max_pel_len)); - - HDfprintf(stdout, - "%s current LRU list size / length = %ld / %ld\n", - cache_ptr->prefix, - (long)(cache_ptr->LRU_list_size), - (long)(cache_ptr->LRU_list_len)); - - HDfprintf(stdout, - "%s current clean LRU size / length = %ld / %ld\n", - cache_ptr->prefix, - (long)(cache_ptr->cLRU_list_size), - (long)(cache_ptr->cLRU_list_len)); - - HDfprintf(stdout, - "%s current dirty LRU size / length = %ld / %ld\n", - cache_ptr->prefix, - (long)(cache_ptr->dLRU_list_size), - (long)(cache_ptr->dLRU_list_len)); - - 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_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/hash bkt 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->hash_bucket_scan_restarts)); - -#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 /* H5C_COLLECT_CACHE_ENTRY_STATS */ - - 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->type_name_table_ptr))[i]); - - 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 /* H5C_COLLECT_CACHE_ENTRY_STATS */ - - } - } - - HDfprintf(stdout, "\n"); - -#endif /* H5C_COLLECT_CACHE_STATS */ - -done: - FUNC_LEAVE_NOAPI(ret_value) - -} /* H5C_stats() */ - - -/*------------------------------------------------------------------------- - * - * Function: H5C_stats__reset - * - * Purpose: Reset the stats fields to their initial values. - * - * Return: void - * - * Programmer: John Mainzer, 4/28/04 - * - * JRM 11/13/08 - * Added initialization for the new max_clean_index_size and - * max_dirty_index_size fields. - * - * MAM -- 01/06/09 - * Added code to initalize the calls_to_msic, - * total_entries_skipped_in_msic, total_entries_scanned_in_msic, - * and max_entries_skipped_in_msic fields. - * - * JRM 4/11/15 - * Added code to initialize the new slist_scan_restarts, - * LRU_scan_restarts, hash_bucket_scan_restarts, and - * take_ownerships fields. - * - *------------------------------------------------------------------------- - */ -void -#ifndef NDEBUG -H5C_stats__reset(H5C_t * cache_ptr) -#else /* NDEBUG */ -#if H5C_COLLECT_CACHE_STATS -H5C_stats__reset(H5C_t * cache_ptr) -#else /* H5C_COLLECT_CACHE_STATS */ -H5C_stats__reset(H5C_t H5_ATTR_UNUSED * cache_ptr) -#endif /* H5C_COLLECT_CACHE_STATS */ -#endif /* NDEBUG */ -{ -#if H5C_COLLECT_CACHE_STATS - int i; -#endif /* H5C_COLLECT_CACHE_STATS */ - - 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_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->slist_scan_restarts = 0; - cache_ptr->LRU_scan_restarts = 0; - cache_ptr->hash_bucket_scan_restarts = 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 /* H5C_COLLECT_CACHE_ENTRY_STATS */ -#endif /* H5C_COLLECT_CACHE_STATS */ - - return; - -} /* H5C_stats__reset() */ - - -/*------------------------------------------------------------------------- - * Function: H5C_dump_cache - * - * Purpose: Print a summary of the contents of the metadata cache for - * debugging purposes. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: John Mainzer - * 10/10/10 - * - *------------------------------------------------------------------------- - */ -herr_t -H5C_dump_cache(H5C_t * cache_ptr, - const char * cache_name) -{ - herr_t ret_value = SUCCEED; /* Return value */ - int i; - H5C_cache_entry_t * entry_ptr = NULL; - H5SL_t * slist_ptr = NULL; - H5SL_node_t * node_ptr = NULL; - - FUNC_ENTER_NOAPI(FAIL) - - HDassert(cache_ptr != NULL); - HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); - HDassert(cache_name != NULL ); - - /* First, create a skip list */ - slist_ptr = H5SL_create(H5SL_TYPE_HADDR, NULL); - - if ( slist_ptr == NULL ) { - - HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, FAIL, "can't create skip list.") - } - - /* Next, scan the index, and insert all entries in the skip list. - * Do this, as we want to display cache entries in increasing address - * order. - */ - 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; - } - } - - /* If we get this far, all entries in the cache are listed in the - * skip list -- scan the skip list generating the desired output. - */ - - HDfprintf(stdout, "\n\nDump of metadata cache \"%s\".\n", cache_name); - HDfprintf(stdout, - "Num: Addr: Tag: Len: Type: Prot: Pinned: Dirty: Corked:\n"); - - i = 0; - - node_ptr = H5SL_first(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%16llx 0x%3llx 0x%3llx %2d %d %d %d %d\n", - cache_ptr->prefix, i, - (long long)(entry_ptr->addr), - (long long)(entry_ptr->tag), - (long long)(entry_ptr->size), - (int)(entry_ptr->type->id), - (int)(entry_ptr->is_protected), - (int)(entry_ptr->is_pinned), - (int)(entry_ptr->is_dirty), - (int)(entry_ptr->is_corked)); - - /* increment node_ptr before we delete its target */ - node_ptr = H5SL_next(node_ptr); - - /* remove the first item in the skip list */ - if ( H5SL_remove(slist_ptr, &(entry_ptr->addr)) != entry_ptr ) { - - HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, \ - "Can't delete entry from skip list.") - } - - if ( node_ptr != NULL ) { - - entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr); - - } else { - - entry_ptr = NULL; - } - - i++; - } - - HDfprintf(stdout, "\n\n"); - - /* Finally, discard the skip list */ - - HDassert( H5SL_count(slist_ptr) == 0 ); - - H5SL_close(slist_ptr); - -done: - - FUNC_LEAVE_NOAPI(ret_value) - -} /* H5C_dump_cache() */ - - -/*------------------------------------------------------------------------- - * Function: H5C_dump_cache_skip_list - * - * Purpose: Debugging routine that prints a summary of the contents of - * the skip list used by the metadata cache metadata cache to - * maintain an address sorted list of dirty entries. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: John Mainzer - * 11/15/14 - * - *------------------------------------------------------------------------- - */ -#if 0 /* debugging routine */ -herr_t -H5C_dump_cache_skip_list(H5C_t * cache_ptr, char * calling_fcn) -{ - herr_t ret_value = SUCCEED; /* Return value */ - int i; - H5C_cache_entry_t * entry_ptr = NULL; - H5SL_node_t * node_ptr = NULL; - - FUNC_ENTER_NOAPI(FAIL) - - 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 len = %d.\n", cache_ptr->slist_len); - HDfprintf(stdout, " slist size = %lld.\n", - (long long)(cache_ptr->slist_size)); - - if ( cache_ptr->slist_len > 0 ) - { - /* If we get this far, all entries in the cache are listed in the - * skip list -- scan the skip list generating the desired output. - */ - - 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 = 0x%llx, item = 0x%llx\n", - (unsigned long long)node_ptr, - (unsigned long long)H5SL_item(node_ptr)); - - /* increment node_ptr before we delete its target */ - 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"); - -done: - - FUNC_LEAVE_NOAPI(ret_value) - -} /* H5C_dump_cache_skip_list() */ -#endif /* debugging routine */ - - -/*------------------------------------------------------------------------- * Function: H5C_unpin_entry_from_client() * * Purpose: Internal routine to unpin a cache entry from a client action. diff --git a/src/H5Cdbg.c b/src/H5Cdbg.c new file mode 100644 index 0000000..08a7068 --- /dev/null +++ b/src/H5Cdbg.c @@ -0,0 +1,964 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5Cdbg.c + * July 8 2016 + * Quincey Koziol + * + * Purpose: Debugging Routines for the generic cache structure or entries. + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#include "H5Cmodule.h" /* This source code file is part of the H5C module */ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Cpkg.h" /* Cache */ +#include "H5Eprivate.h" /* Error handling */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + +#if 0 /* debugging routines */ +herr_t H5C_dump_cache_skip_list(H5C_t *cache_ptr, char *calling_fcn); +#endif /* debugging routines */ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + + +/*------------------------------------------------------------------------- + * Function: H5C_dump_cache + * + * Purpose: Print a summary of the contents of the metadata cache for + * debugging purposes. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: John Mainzer + * 10/10/10 + * + *------------------------------------------------------------------------- + */ +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; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(cache_ptr != NULL); + HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); + HDassert(cache_name != NULL ); + + /* First, create a skip list */ + if(NULL == (slist_ptr = H5SL_create(H5SL_TYPE_HADDR, NULL))) + HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, FAIL, "can't create skip list.") + + /* Next, scan the index, and insert all entries in the skip list. + * Do this, as we want to display cache entries in increasing address + * order. + */ + 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; + } /* end while */ + } /* end for */ + + /* If we get this far, all entries in the cache are listed in the + * skip list -- scan the skip list generating the desired output. + */ + + HDfprintf(stdout, "\n\nDump of metadata cache \"%s\".\n", cache_name); + HDfprintf(stdout, + "Num: Addr: Len: Type: Prot: Pinned: Dirty:\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%d 0x%16llx 0x%3llx %2d %d %d %d\n", + cache_ptr->prefix, i, + (long long)(entry_ptr->addr), + (long long)(entry_ptr->size), + (int)(entry_ptr->type->id), + (int)(entry_ptr->is_protected), + (int)(entry_ptr->is_pinned), + (int)(entry_ptr->is_dirty)); + + /* remove the next (first) item in the skip list */ + entry_ptr = (H5C_cache_entry_t *)H5SL_remove_first(slist_ptr); + + i++; + } /* end while */ + + HDfprintf(stdout, "\n\n"); + + /* Verify that all the entries were removed from the skip list */ + HDassert(H5SL_count(slist_ptr) == 0); + +done: + /* Discard the skip list */ + if(slist_ptr) + H5SL_close(slist_ptr); + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5C_dump_cache() */ + + +/*------------------------------------------------------------------------- + * Function: H5C_dump_cache_skip_list + * + * Purpose: Debugging routine that prints a summary of the contents of + * the skip list used by the metadata cache metadata cache to + * maintain an address sorted list of dirty entries. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: John Mainzer + * 11/15/14 + * + *------------------------------------------------------------------------- + */ +#if 0 /* debugging routine */ +herr_t +H5C_dump_cache_skip_list(H5C_t * cache_ptr, char * calling_fcn) +{ + herr_t ret_value = SUCCEED; /* Return value */ + int i; + H5C_cache_entry_t * entry_ptr = NULL; + H5SL_node_t * node_ptr = NULL; + + FUNC_ENTER_NOAPI(FAIL) + + 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 len = %d.\n", cache_ptr->slist_len); + HDfprintf(stdout, " slist size = %lld.\n", (long long)(cache_ptr->slist_size)); + + if(cache_ptr->slist_len > 0) { + /* If we get this far, all entries in the cache are listed in the + * skip list -- scan the skip list generating the desired output. + */ + 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 = 0x%llx, item = 0x%llx\n", + (unsigned long long)node_ptr, + (unsigned long long)H5SL_item(node_ptr)); + + /* increment node_ptr before we delete its target */ + 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++; + } /* end while */ + } /* end if */ + + HDfprintf(stdout, "\n\n"); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5C_dump_cache_skip_list() */ +#endif /* debugging routine */ + + +/*------------------------------------------------------------------------- + * Function: H5C_set_prefix + * + * Purpose: Set the values of the prefix field of H5C_t. This + * filed is used to label some debugging output. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: John Mainzer + * 1/20/06 + * + *------------------------------------------------------------------------- + */ +herr_t +H5C_set_prefix(H5C_t * cache_ptr, char * prefix) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + 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) +} /* H5C_set_prefix() */ + + +/*------------------------------------------------------------------------- + * Function: H5C_set_trace_file_ptr + * + * Purpose: Set the trace_file_ptr field for the cache. + * + * This field must either be NULL (which turns of trace + * file logging), or be a pointer to an open file to which + * trace file data is to be written. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: John Mainzer + * 1/20/06 + * + *------------------------------------------------------------------------- + */ +herr_t +H5C_set_trace_file_ptr(H5C_t * cache_ptr, FILE * trace_file_ptr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* This would normally be an assert, but we need to use an HGOTO_ERROR + * call to shut up the compiler. + */ + if((NULL == cache_ptr) || (cache_ptr->magic != H5C__H5C_T_MAGIC)) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad cache_ptr") + + cache_ptr->trace_file_ptr = trace_file_ptr; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5C_set_trace_file_ptr() */ + + +/*------------------------------------------------------------------------- + * Function: H5C_stats + * + * Purpose: Prints statistics about the cache. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: John Mainzer + * 6/2/04 + * + * JRM -- 11/13/08 + * Added code displaying the max_clean_index_size and + * max_dirty_index_size. + * + * MAM -- 01/06/09 + * Added code displaying the calls_to_msic, + * total_entries_skipped_in_msic, total_entries_scanned_in_msic, + * and max_entries_skipped_in_msic fields. + * + * JRM -- 4/11/15 + * Added code displaying the new slist_scan_restarts, + * LRU_scan_restarts, and hash_bucket_scan_restarts fields; + * + *------------------------------------------------------------------------- + */ +herr_t +H5C_stats(H5C_t * cache_ptr, + const char * cache_name, + hbool_t +#if !H5C_COLLECT_CACHE_STATS + H5_ATTR_UNUSED +#endif /* H5C_COLLECT_CACHE_STATS */ + 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 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_entries_scanned_per_calls_to_msic = 0.0f; +#endif /* H5C_COLLECT_CACHE_STATS */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC ); + + /* This would normally be an assert, but we need to use an HGOTO_ERROR + * call to shut up the compiler. + */ + 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 /* H5C_COLLECT_CACHE_ENTRY_STATS */ + } /* end for */ + + 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) / %ld (%ld)\n", + cache_ptr->prefix, + (long)(cache_ptr->index_size), + (long)(cache_ptr->max_index_size), + (long)(cache_ptr->index_len), + (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) / %ld (%ld)\n", + cache_ptr->prefix, + (long)(cache_ptr->slist_size), + (long)(cache_ptr->max_slist_size), + (long)(cache_ptr->slist_len), + (long)(cache_ptr->max_slist_len)); + + HDfprintf(stdout, + "%s current (max) PL size / length = %ld (%ld) / %ld (%ld)\n", + cache_ptr->prefix, + (long)(cache_ptr->pl_size), + (long)(cache_ptr->max_pl_size), + (long)(cache_ptr->pl_len), + (long)(cache_ptr->max_pl_len)); + + HDfprintf(stdout, + "%s current (max) PEL size / length = %ld (%ld) / %ld (%ld)\n", + cache_ptr->prefix, + (long)(cache_ptr->pel_size), + (long)(cache_ptr->max_pel_size), + (long)(cache_ptr->pel_len), + (long)(cache_ptr->max_pel_len)); + + HDfprintf(stdout, + "%s current LRU list size / length = %ld / %ld\n", + cache_ptr->prefix, + (long)(cache_ptr->LRU_list_size), + (long)(cache_ptr->LRU_list_len)); + + HDfprintf(stdout, + "%s current clean LRU size / length = %ld / %ld\n", + cache_ptr->prefix, + (long)(cache_ptr->cLRU_list_size), + (long)(cache_ptr->cLRU_list_len)); + + HDfprintf(stdout, + "%s current dirty LRU size / length = %ld / %ld\n", + cache_ptr->prefix, + (long)(cache_ptr->dLRU_list_size), + (long)(cache_ptr->dLRU_list_len)); + + 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_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/hash bkt 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->hash_bucket_scan_restarts)); + +#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 /* H5C_COLLECT_CACHE_ENTRY_STATS */ + + 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->type_name_table_ptr))[i]); + + 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 /* H5C_COLLECT_CACHE_ENTRY_STATS */ + + } /* end for */ + } /* end if */ + + HDfprintf(stdout, "\n"); + +#endif /* H5C_COLLECT_CACHE_STATS */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5C_stats() */ + + +/*------------------------------------------------------------------------- + * + * Function: H5C_stats__reset + * + * Purpose: Reset the stats fields to their initial values. + * + * Return: void + * + * Programmer: John Mainzer, 4/28/04 + * + * JRM 11/13/08 + * Added initialization for the new max_clean_index_size and + * max_dirty_index_size fields. + * + * MAM -- 01/06/09 + * Added code to initalize the calls_to_msic, + * total_entries_skipped_in_msic, total_entries_scanned_in_msic, + * and max_entries_skipped_in_msic fields. + * + * JRM 4/11/15 + * Added code to initialize the new slist_scan_restarts, + * LRU_scan_restarts, hash_bucket_scan_restarts, and + * take_ownerships fields. + * + *------------------------------------------------------------------------- + */ +void +#ifndef NDEBUG +H5C_stats__reset(H5C_t * cache_ptr) +#else /* NDEBUG */ +#if H5C_COLLECT_CACHE_STATS +H5C_stats__reset(H5C_t * cache_ptr) +#else /* H5C_COLLECT_CACHE_STATS */ +H5C_stats__reset(H5C_t H5_ATTR_UNUSED * cache_ptr) +#endif /* H5C_COLLECT_CACHE_STATS */ +#endif /* NDEBUG */ +{ +#if H5C_COLLECT_CACHE_STATS + int i; +#endif /* H5C_COLLECT_CACHE_STATS */ + + 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; + } /* end for */ + + 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_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->slist_scan_restarts = 0; + cache_ptr->LRU_scan_restarts = 0; + cache_ptr->hash_bucket_scan_restarts = 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; + } /* end for */ + +#endif /* H5C_COLLECT_CACHE_ENTRY_STATS */ +#endif /* H5C_COLLECT_CACHE_STATS */ + +} /* H5C_stats__reset() */ + +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 != 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); + } /* end if */ + + 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; + + 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, 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, 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); +} diff --git a/src/H5FDint.c b/src/H5FDint.c index 128f30f..cd48197 100644 --- a/src/H5FDint.c +++ b/src/H5FDint.c @@ -93,7 +93,11 @@ *------------------------------------------------------------------------- */ herr_t -H5FD_locate_signature(H5FD_t *file, const H5P_genplist_t *dxpl, haddr_t *sig_addr) +H5FD_locate_signature(H5FD_t *file, +#ifndef H5_DEBUG_BUILD +const +#endif /* H5_DEBUG_BUILD */ +H5P_genplist_t *dxpl, haddr_t *sig_addr) { haddr_t addr, eoa, eof; uint8_t buf[H5F_SIGNATURE_LEN]; @@ -158,7 +162,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5FD_read(H5FD_t *file, const H5P_genplist_t *dxpl, H5FD_mem_t type, haddr_t addr, +H5FD_read(H5FD_t *file, +#ifndef H5_DEBUG_BUILD +const +#endif /* H5_DEBUG_BUILD */ +H5P_genplist_t *dxpl, H5FD_mem_t type, haddr_t addr, size_t size, void *buf/*out*/) { haddr_t eoa = HADDR_UNDEF; @@ -226,7 +234,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5FD_write(H5FD_t *file, const H5P_genplist_t *dxpl, H5FD_mem_t type, haddr_t addr, +H5FD_write(H5FD_t *file, +#ifndef H5_DEBUG_BUILD +const +#endif /* H5_DEBUG_BUILD */ +H5P_genplist_t *dxpl, H5FD_mem_t type, haddr_t addr, size_t size, const void *buf) { haddr_t eoa = HADDR_UNDEF; diff --git a/src/H5FDlog.c b/src/H5FDlog.c index d0c4647..dae0e4a 100644 --- a/src/H5FDlog.c +++ b/src/H5FDlog.c @@ -132,6 +132,7 @@ typedef struct H5FD_log_t { double total_read_time; /* Total time spent in read operations */ double total_write_time; /* Total time spent in write operations */ double total_seek_time; /* Total time spent in seek operations */ + double total_truncate_time; /* Total time spent in truncate operations */ size_t iosize; /* Size of I/O information buffers */ FILE *logfp; /* Log file pointer */ H5FD_log_fapl_t fa; /* Driver-specific file access properties */ @@ -170,6 +171,8 @@ static herr_t H5FD_log_close(H5FD_t *_file); static int H5FD_log_cmp(const H5FD_t *_f1, const H5FD_t *_f2); static herr_t H5FD_log_query(const H5FD_t *_f1, unsigned long *flags); static haddr_t H5FD_log_alloc(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size); +static herr_t H5FD__log_free(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, + hsize_t size); static haddr_t H5FD_log_get_eoa(const H5FD_t *_file, H5FD_mem_t type); static herr_t H5FD_log_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr); static haddr_t H5FD_log_get_eof(const H5FD_t *_file, H5FD_mem_t type); @@ -203,7 +206,7 @@ static const H5FD_class_t H5FD_log_g = { H5FD_log_query, /*query */ NULL, /*get_type_map */ H5FD_log_alloc, /*alloc */ - NULL, /*free */ + H5FD__log_free, /*free */ H5FD_log_get_eoa, /*get_eoa */ H5FD_log_set_eoa, /*set_eoa */ H5FD_log_get_eof, /*get_eof */ @@ -735,6 +738,8 @@ H5FD_log_close(H5FD_t *_file) HDfprintf(file->logfp, "Total time in write operations: %f s\n", file->total_write_time); if(file->fa.flags & H5FD_LOG_TIME_SEEK) HDfprintf(file->logfp, "Total time in seek operations: %f s\n", file->total_seek_time); + if(file->fa.flags & H5FD_LOG_TIME_TRUNCATE) + HDfprintf(file->logfp, "Total time in truncate operations: %f s\n", file->total_truncate_time); /* Dump the write I/O information */ if(file->fa.flags & H5FD_LOG_FILE_WRITE) { @@ -957,6 +962,43 @@ H5FD_log_alloc(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, hsi /*------------------------------------------------------------------------- + * Function: H5FD__log_free + * + * Purpose: Release file memory. + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * Wednesday, September 28, 2016 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD__log_free(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, + haddr_t addr, hsize_t size) +{ + H5FD_log_t *file = (H5FD_log_t *)_file; + + FUNC_ENTER_STATIC_NOERR + + if(file->fa.flags != 0) { + /* Reset the flavor of the information in the file */ + if(file->fa.flags & H5FD_LOG_FLAVOR) { + HDassert(addr < file->iosize); + H5_CHECK_OVERFLOW(size, hsize_t, size_t); + HDmemset(&file->flavor[addr], H5FD_MEM_DEFAULT, (size_t)size); + } /* end if */ + + /* Log the file memory freed */ + if(file->fa.flags & H5FD_LOG_FREE) + HDfprintf(file->logfp, "%10a-%10a (%10Hu bytes) (%s) Freed\n", addr, (addr + size) - 1, size, flavors[type]); + } /* end if */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5FD__log_free() */ + + +/*------------------------------------------------------------------------- * Function: H5FD_log_get_eoa * * Purpose: Gets the end-of-address marker for the file. The EOA marker @@ -1004,6 +1046,7 @@ H5FD_log_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr) FUNC_ENTER_NOAPI_NOINIT_NOERR if(file->fa.flags != 0) { + /* Check for increasing file size */ if(H5F_addr_gt(addr, file->eoa) && H5F_addr_gt(addr, 0)) { hsize_t size = addr - file->eoa; @@ -1018,6 +1061,22 @@ H5FD_log_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr) if(file->fa.flags & H5FD_LOG_ALLOC) HDfprintf(file->logfp, "%10a-%10a (%10Hu bytes) (%s) Allocated\n", file->eoa, addr, size, flavors[type]); } /* end if */ + + /* Check for decreasing file size */ + if(H5F_addr_lt(addr, file->eoa) && H5F_addr_gt(addr, 0)) { + hsize_t size = file->eoa - addr; + + /* Reset the flavor of the space freed by the shrink */ + if(file->fa.flags & H5FD_LOG_FLAVOR) { + HDassert((addr + size) < file->iosize); + H5_CHECK_OVERFLOW(size, hsize_t, size_t); + HDmemset(&file->flavor[addr], H5FD_MEM_DEFAULT, (size_t)size); + } /* end if */ + + /* Log the shrink like a free */ + if(file->fa.flags & H5FD_LOG_FREE) + HDfprintf(file->logfp, "%10a-%10a (%10Hu bytes) (%s) Freed\n", file->eoa, addr, size, flavors[type]); + } /* end if */ } /* end if */ file->eoa = addr; @@ -1167,7 +1226,7 @@ H5FD_log_read(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, hadd timeval_diff.tv_sec--; } /* end if */ time_diff = (double)timeval_diff.tv_sec + ((double)timeval_diff.tv_usec / (double)1000000.0f); - HDfprintf(file->logfp, " (%f s)\n", time_diff); + HDfprintf(file->logfp, " (%fs @ %.6lu.%.6llu)\n", time_diff, (unsigned long long)timeval_start.tv_sec, (unsigned long long)timeval_start.tv_usec); /* Add to total seek time */ file->total_seek_time += time_diff; @@ -1241,7 +1300,12 @@ H5FD_log_read(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, hadd if(file->fa.flags & H5FD_LOG_LOC_READ) { HDfprintf(file->logfp, "%10a-%10a (%10Zu bytes) (%s) Read", orig_addr, (orig_addr + orig_size) - 1, orig_size, flavors[type]); - /* XXX: Verify the flavor information, if we have it? */ + /* Verify that we are reading in the type of data we allocated in this location */ + if(file->flavor) { + HDassert(type == H5FD_MEM_DEFAULT || type == (H5FD_mem_t)file->flavor[orig_addr] || (H5FD_mem_t)file->flavor[orig_addr] == H5FD_MEM_DEFAULT); + HDassert(type == H5FD_MEM_DEFAULT || type == (H5FD_mem_t)file->flavor[(orig_addr + orig_size) - 1] || (H5FD_mem_t)file->flavor[(orig_addr + orig_size) - 1] == H5FD_MEM_DEFAULT); + } /* end if */ + #ifdef H5_HAVE_GETTIMEOFDAY if(file->fa.flags & H5FD_LOG_TIME_READ) { @@ -1256,7 +1320,7 @@ H5FD_log_read(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, hadd timeval_diff.tv_sec--; } /* end if */ time_diff = (double)timeval_diff.tv_sec + ((double)timeval_diff.tv_usec / (double)1000000.0f); - HDfprintf(file->logfp, " (%f s)\n", time_diff); + HDfprintf(file->logfp, " (%fs @ %.6lu.%.6llu)\n", time_diff, (unsigned long long)timeval_start.tv_sec, (unsigned long long)timeval_start.tv_usec); /* Add to total read time */ file->total_read_time += time_diff; @@ -1369,7 +1433,7 @@ H5FD_log_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, had timeval_diff.tv_sec--; } /* end if */ time_diff = (double)timeval_diff.tv_sec + ((double)timeval_diff.tv_usec / (double)1000000.0f); - HDfprintf(file->logfp, " (%f s)\n", time_diff); + HDfprintf(file->logfp, " (%fs @ %.6lu.%.6llu)\n", time_diff, (unsigned long long)timeval_start.tv_sec, (unsigned long long)timeval_start.tv_usec); /* Add to total seek time */ file->total_seek_time += time_diff; @@ -1438,8 +1502,10 @@ H5FD_log_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, had /* Check if this is the first write into a "default" section, grabbed by the metadata agregation algorithm */ if(file->fa.flags & H5FD_LOG_FLAVOR) { - if((H5FD_mem_t)file->flavor[orig_addr] == H5FD_MEM_DEFAULT) + if((H5FD_mem_t)file->flavor[orig_addr] == H5FD_MEM_DEFAULT) { HDmemset(&file->flavor[orig_addr], (int)type, orig_size); + HDfprintf(file->logfp, " (fresh)"); + } /* end if */ } /* end if */ #ifdef H5_HAVE_GETTIMEOFDAY @@ -1455,7 +1521,7 @@ H5FD_log_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, had timeval_diff.tv_sec--; } /* end if */ time_diff = (double)timeval_diff.tv_sec + ((double)timeval_diff.tv_usec / (double)1000000.0f); - HDfprintf(file->logfp, " (%f s)\n", time_diff); + HDfprintf(file->logfp, " (%fs @ %.6lu.%.6llu)\n", time_diff, (unsigned long long)timeval_start.tv_sec, (unsigned long long)timeval_start.tv_usec); /* Add to total write time */ file->total_write_time += time_diff; @@ -1509,6 +1575,14 @@ H5FD_log_truncate(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, hbool_t H5_ATTR_U /* Extend the file to make sure it's large enough */ if(!H5F_addr_eq(file->eoa, file->eof)) { +#ifdef H5_HAVE_GETTIMEOFDAY + struct timeval timeval_start, timeval_stop; +#endif /* H5_HAVE_GETTIMEOFDAY */ + +#ifdef H5_HAVE_GETTIMEOFDAY + if(file->fa.flags & H5FD_LOG_TIME_TRUNCATE) + HDgettimeofday(&timeval_start, NULL); +#endif /* H5_HAVE_GETTIMEOFDAY */ #ifdef H5_HAVE_WIN32_API LARGE_INTEGER li; /* 64-bit (union) integer for SetFilePointer() call */ DWORD dwPtrLow; /* Low-order pointer bits from SetFilePointer() @@ -1539,10 +1613,40 @@ H5FD_log_truncate(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, hbool_t H5_ATTR_U if(-1 == HDftruncate(file->fd, (HDoff_t)file->eoa)) HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly") #endif /* H5_HAVE_WIN32_API */ +#ifdef H5_HAVE_GETTIMEOFDAY + if(file->fa.flags & H5FD_LOG_TIME_TRUNCATE) + HDgettimeofday(&timeval_stop, NULL); +#endif /* H5_HAVE_GETTIMEOFDAY */ /* Log information about the truncate */ if(file->fa.flags & H5FD_LOG_NUM_TRUNCATE) file->total_truncate_ops++; + if(file->fa.flags & H5FD_LOG_TRUNCATE) { + HDfprintf(file->logfp, "Truncate: To %10a", file->eoa); +#ifdef H5_HAVE_GETTIMEOFDAY + if(file->fa.flags & H5FD_LOG_TIME_TRUNCATE) { + struct timeval timeval_diff; + double time_diff; + + /* Calculate the elapsed gettimeofday time */ + timeval_diff.tv_usec = timeval_stop.tv_usec - timeval_start.tv_usec; + timeval_diff.tv_sec = timeval_stop.tv_sec - timeval_start.tv_sec; + if(timeval_diff.tv_usec < 0) { + timeval_diff.tv_usec += 1000000; + timeval_diff.tv_sec--; + } /* end if */ + time_diff = (double)timeval_diff.tv_sec + ((double)timeval_diff.tv_usec / (double)1000000.0f); + HDfprintf(file->logfp, " (%fs @ %.6lu.%.6llu)\n", time_diff, (unsigned long long)timeval_start.tv_sec, (unsigned long long)timeval_start.tv_usec); + + /* Add to total truncate time */ + file->total_truncate_time += time_diff; + } /* end if */ + else + HDfprintf(file->logfp, "\n"); +#else /* H5_HAVE_GETTIMEOFDAY */ + HDfprintf(file->logfp, "\n"); +#endif /* H5_HAVE_GETTIMEOFDAY */ + } /* end if */ /* Update the eof value */ file->eof = file->eoa; diff --git a/src/H5FDlog.h b/src/H5FDlog.h index 2f1544e..11044e2 100644 --- a/src/H5FDlog.h +++ b/src/H5FDlog.h @@ -25,34 +25,39 @@ #define H5FD_LOG (H5FD_log_init()) /* Flags for H5Pset_fapl_log() */ +/* Flags for tracking 'meta' operations (truncate) */ +#define H5FD_LOG_TRUNCATE 0x00000001 +#define H5FD_LOG_META_IO (H5FD_LOG_TRUNCATE) /* Flags for tracking where reads/writes/seeks occur */ -#define H5FD_LOG_LOC_READ 0x00000001 -#define H5FD_LOG_LOC_WRITE 0x00000002 -#define H5FD_LOG_LOC_SEEK 0x00000004 +#define H5FD_LOG_LOC_READ 0x00000002 +#define H5FD_LOG_LOC_WRITE 0x00000004 +#define H5FD_LOG_LOC_SEEK 0x00000008 #define H5FD_LOG_LOC_IO (H5FD_LOG_LOC_READ|H5FD_LOG_LOC_WRITE|H5FD_LOG_LOC_SEEK) /* Flags for tracking number of times each byte is read/written */ -#define H5FD_LOG_FILE_READ 0x00000008 -#define H5FD_LOG_FILE_WRITE 0x00000010 +#define H5FD_LOG_FILE_READ 0x00000010 +#define H5FD_LOG_FILE_WRITE 0x00000020 #define H5FD_LOG_FILE_IO (H5FD_LOG_FILE_READ|H5FD_LOG_FILE_WRITE) /* Flag for tracking "flavor" (type) of information stored at each byte */ -#define H5FD_LOG_FLAVOR 0x00000020 +#define H5FD_LOG_FLAVOR 0x00000040 /* Flags for tracking total number of reads/writes/seeks/truncates */ -#define H5FD_LOG_NUM_READ 0x00000040 -#define H5FD_LOG_NUM_WRITE 0x00000080 -#define H5FD_LOG_NUM_SEEK 0x00000100 -#define H5FD_LOG_NUM_TRUNCATE 0x00000200 +#define H5FD_LOG_NUM_READ 0x00000080 +#define H5FD_LOG_NUM_WRITE 0x00000100 +#define H5FD_LOG_NUM_SEEK 0x00000200 +#define H5FD_LOG_NUM_TRUNCATE 0x00000400 #define H5FD_LOG_NUM_IO (H5FD_LOG_NUM_READ|H5FD_LOG_NUM_WRITE|H5FD_LOG_NUM_SEEK|H5FD_LOG_NUM_TRUNCATE) -/* Flags for tracking time spent in open/stat/read/write/seek/close */ -#define H5FD_LOG_TIME_OPEN 0x00000400 -#define H5FD_LOG_TIME_STAT 0x00000800 -#define H5FD_LOG_TIME_READ 0x00001000 -#define H5FD_LOG_TIME_WRITE 0x00002000 -#define H5FD_LOG_TIME_SEEK 0x00004000 -#define H5FD_LOG_TIME_CLOSE 0x00008000 -#define H5FD_LOG_TIME_IO (H5FD_LOG_TIME_OPEN|H5FD_LOG_TIME_STAT|H5FD_LOG_TIME_READ|H5FD_LOG_TIME_WRITE|H5FD_LOG_TIME_SEEK|H5FD_LOG_TIME_CLOSE) -/* Flag for tracking allocation of space in file */ -#define H5FD_LOG_ALLOC 0x00010000 -#define H5FD_LOG_ALL (H5FD_LOG_ALLOC|H5FD_LOG_TIME_IO|H5FD_LOG_NUM_IO|H5FD_LOG_FLAVOR|H5FD_LOG_FILE_IO|H5FD_LOG_LOC_IO) +/* Flags for tracking time spent in open/stat/read/write/seek/truncate/close */ +#define H5FD_LOG_TIME_OPEN 0x00000800 +#define H5FD_LOG_TIME_STAT 0x00001000 +#define H5FD_LOG_TIME_READ 0x00002000 +#define H5FD_LOG_TIME_WRITE 0x00004000 +#define H5FD_LOG_TIME_SEEK 0x00008000 +#define H5FD_LOG_TIME_TRUNCATE 0x00010000 +#define H5FD_LOG_TIME_CLOSE 0x00020000 +#define H5FD_LOG_TIME_IO (H5FD_LOG_TIME_OPEN|H5FD_LOG_TIME_STAT|H5FD_LOG_TIME_READ|H5FD_LOG_TIME_WRITE|H5FD_LOG_TIME_SEEK|H5FD_LOG_TIME_TRUNCATE|H5FD_LOG_TIME_CLOSE) +/* Flags for tracking allocation/release of space in file */ +#define H5FD_LOG_ALLOC 0x00040000 +#define H5FD_LOG_FREE 0x00080000 +#define H5FD_LOG_ALL (H5FD_LOG_FREE|H5FD_LOG_ALLOC|H5FD_LOG_TIME_IO|H5FD_LOG_NUM_IO|H5FD_LOG_FLAVOR|H5FD_LOG_FILE_IO|H5FD_LOG_LOC_IO|H5FD_LOG_META_IO) #ifdef __cplusplus extern "C" { diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index ed70e20..a3a404f 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -90,7 +90,7 @@ static herr_t H5FD_mpio_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, hadd size_t size, void *buf); static herr_t H5FD_mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size, const void *buf); -static herr_t H5FD_mpio_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing); +static herr_t H5FD_mpio_flush(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); static herr_t H5FD_mpio_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); static int H5FD_mpio_mpi_rank(const H5FD_t *_file); static int H5FD_mpio_mpi_size(const H5FD_t *_file); @@ -1866,7 +1866,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5FD_mpio_flush(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, unsigned closing) +H5FD_mpio_flush(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, hbool_t closing) { H5FD_mpio_t *file = (H5FD_mpio_t*)_file; int mpi_code; /* mpi return code */ diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c index d0dfab3..38d0ae3 100644 --- a/src/H5FDmulti.c +++ b/src/H5FDmulti.c @@ -1290,7 +1290,7 @@ H5FD_multi_get_eoa(const H5FD_t *_file, H5FD_mem_t type) } else { H5FD_mem_t mmt = file->fa.memb_map[type]; - if(H5FD_MEM_DEFAULT==mmt) + if(H5FD_MEM_DEFAULT == mmt) mmt = type; if(file->memb[mmt]) { @@ -1358,18 +1358,24 @@ H5FD_multi_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t eoa) H5Eclear2(H5E_DEFAULT); mmt = file->fa.memb_map[type]; - if(H5FD_MEM_DEFAULT == mmt) - mmt = type; - - /* Handle backward compatibility in a quick and simple way. v1.6 library had EOA for the entire virtual - * file. But it wasn't meaningful. So v1.8 library doesn't have it anymore. It saves the EOA for the - * metadata file, instead. Here we try to figure out whether the EOA is from a v1.6 file by comparing its - * value. If it is a big value, we assume it's from v1.6 and simply discard it. This is the normal case - * when the metadata file has the smallest starting address. If the metadata file has the biggest address, - * the EOAs of v1.6 and v1.8 files are the same. It won't cause any trouble. (Please see Issue 2598 - * in Jira) SLU - 2011/6/21 + if(H5FD_MEM_DEFAULT == mmt) { + if(H5FD_MEM_DEFAULT == type) + mmt = H5FD_MEM_SUPER; + else + mmt = type; + } /* end if */ + + /* Handle backward compatibility in a quick and simple way. v1.6 library + * had EOA for the entire virtual file. But it wasn't meaningful. So v1.8 + * library doesn't have it anymore. It saves the EOA for the metadata file, + * instead. Here we try to figure out whether the EOA is from a v1.6 file + * by comparing its value. If it is a big value, we assume it's from v1.6 + * and simply discard it. This is the normal case when the metadata file + * has the smallest starting address. If the metadata file has the biggest + * address, the EOAs of v1.6 and v1.8 files are the same. It won't cause + * any trouble. (Please see Issue 2598 in Jira) SLU - 2011/6/21 */ - if(H5FD_MEM_SUPER == type && file->memb_eoa[H5FD_MEM_SUPER] > 0 && eoa > file->memb_eoa[H5FD_MEM_SUPER]) + if(H5FD_MEM_SUPER == mmt && file->memb_eoa[H5FD_MEM_SUPER] > 0 && eoa > (file->memb_next[H5FD_MEM_SUPER] / 2)) return 0; assert(eoa >= file->fa.memb_addr[mmt]); @@ -1378,7 +1384,7 @@ H5FD_multi_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t eoa) H5E_BEGIN_TRY { status = H5FDset_eoa(file->memb[mmt], mmt, (eoa - file->fa.memb_addr[mmt])); } H5E_END_TRY; - if (status<0) + if(status < 0) H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_BADVALUE, "member H5FDset_eoa failed", -1) return 0; diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index 915f7e1..c40dc54 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -130,7 +130,11 @@ struct H5P_genplist_t; struct H5F_t; H5_DLL int H5FD_term_interface(void); -H5_DLL herr_t H5FD_locate_signature(H5FD_t *file, const H5P_genplist_t *dxpl, haddr_t *sig_addr); +H5_DLL herr_t H5FD_locate_signature(H5FD_t *file, +#ifndef H5_DEBUG_BUILD +const +#endif /* H5_DEBUG_BUILD */ +H5P_genplist_t *dxpl, haddr_t *sig_addr); H5_DLL H5FD_class_t *H5FD_get_class(hid_t id); H5_DLL hsize_t H5FD_sb_size(H5FD_t *file); H5_DLL herr_t H5FD_sb_encode(H5FD_t *file, char *name/*out*/, uint8_t *buf); @@ -154,9 +158,17 @@ H5_DLL haddr_t H5FD_get_eof(const H5FD_t *file, H5FD_mem_t type); H5_DLL haddr_t H5FD_get_maxaddr(const H5FD_t *file); H5_DLL herr_t H5FD_get_feature_flags(const H5FD_t *file, unsigned long *feature_flags); H5_DLL herr_t H5FD_get_fs_type_map(const H5FD_t *file, H5FD_mem_t *type_map); -H5_DLL herr_t H5FD_read(H5FD_t *file, const H5P_genplist_t *dxpl, H5FD_mem_t type, +H5_DLL herr_t H5FD_read(H5FD_t *file, +#ifndef H5_DEBUG_BUILD +const +#endif /* H5_DEBUG_BUILD */ +H5P_genplist_t *dxpl, H5FD_mem_t type, haddr_t addr, size_t size, void *buf/*out*/); -H5_DLL herr_t H5FD_write(H5FD_t *file, const H5P_genplist_t *dxpl, H5FD_mem_t type, +H5_DLL herr_t H5FD_write(H5FD_t *file, +#ifndef H5_DEBUG_BUILD +const +#endif /* H5_DEBUG_BUILD */ +H5P_genplist_t *dxpl, H5FD_mem_t type, haddr_t addr, size_t size, const void *buf); H5_DLL herr_t H5FD_flush(H5FD_t *file, hid_t dxpl_id, hbool_t closing); H5_DLL herr_t H5FD_truncate(H5FD_t *file, hid_t dxpl_id, hbool_t closing); diff --git a/src/H5Fint.c b/src/H5Fint.c index 5b7fdda..201dd65 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -1041,16 +1041,12 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, * open it are different than the desired flags. Close the tentative * file and open it for real. */ - if(H5FD_close(lf) < 0) { - file = NULL; /*to prevent destruction of wrong file*/ + if(H5FD_close(lf) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to close low-level file info") - } /* end if */ - if(NULL == (lf = H5FD_open(name, flags, fapl_id, HADDR_UNDEF))) { - file = NULL; /*to prevent destruction of wrong file*/ + + if(NULL == (lf = H5FD_open(name, flags, fapl_id, HADDR_UNDEF))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file") - } /* end if */ } /* end if */ - if(NULL == (file = H5F_new(NULL, flags, fcpl_id, fapl_id, lf))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create new file object") } /* end else */ diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c index 23b7f78..66b34bc 100644 --- a/src/H5Fsuper.c +++ b/src/H5Fsuper.c @@ -401,7 +401,7 @@ H5F__super_read(H5F_t *f, hid_t dxpl_id, hbool_t initial_read) * individually. */ /* Can skip this test when it is not the initial file open-- - * H5F_super_read() call from H5F_evict_tagged_metadata() for + * H5F__super_read() call from H5F_evict_tagged_metadata() for * refreshing object. * When flushing file buffers and fractal heap is involved, * the library will allocate actual space for tmp addresses @@ -448,8 +448,7 @@ H5F__super_read(H5F_t *f, hid_t dxpl_id, hbool_t initial_read) * portion of the driver info block */ if(H5FD_set_eoa(f->shared->lf, H5FD_MEM_SUPER, sblock->driver_addr + H5F_DRVINFOBLOCK_HDR_SIZE) < 0) /* will extend eoa later if required */ - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, \ - "set end of space allocation request failed") + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "set end of space allocation request failed") /* Look up the driver info block */ if(NULL == (drvinfo = (H5O_drvinfo_t *)H5AC_protect(f, dxpl_id, H5AC_DRVRINFO, sblock->driver_addr, &drvrinfo_udata, rw_flags))) @@ -458,11 +457,8 @@ H5F__super_read(H5F_t *f, hid_t dxpl_id, hbool_t initial_read) /* Loading the driver info block is enough to set up the right info */ /* Check if we need to rewrite the driver info block info */ - if ( ( (rw_flags & H5AC__READ_ONLY_FLAG) == 0 ) && - ( H5F_HAS_FEATURE(f, H5FD_FEAT_DIRTY_DRVRINFO_LOAD) ) ) { - + if(((rw_flags & H5AC__READ_ONLY_FLAG) == 0) && H5F_HAS_FEATURE(f, H5FD_FEAT_DIRTY_DRVRINFO_LOAD)) drvinfo_flags |= H5AC__DIRTIED_FLAG; - } /* end if */ /* set the pin entry flag so that the driver information block * cache entry will be pinned in the cache. @@ -478,7 +474,7 @@ H5F__super_read(H5F_t *f, hid_t dxpl_id, hbool_t initial_read) } /* end if */ /* (Account for the stored EOA being absolute offset -NAF) */ - if(H5F__set_eoa(f, H5FD_MEM_SUPER, udata.stored_eof - sblock->base_addr) < 0) + if(H5F__set_eoa(f, H5FD_MEM_DEFAULT, udata.stored_eof - sblock->base_addr) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to set end-of-address marker for file") /* Decode the optional superblock extension info */ diff --git a/src/Makefile.am b/src/Makefile.am index 7facf9a..8d9df87 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,10 +42,10 @@ DISTCLEANFILES=H5pubconf.h # library sources libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5A.c H5Abtree2.c H5Adense.c H5Adeprec.c H5Aint.c H5Atest.c \ - H5AC.c \ + H5AC.c H5ACdbg.c \ H5B.c H5Bcache.c H5Bdbg.c \ H5B2.c H5B2cache.c H5B2dbg.c H5B2hdr.c H5B2int.c H5B2stat.c H5B2test.c \ - H5C.c H5Cepoch.c H5Cquery.c H5Ctag.c H5Ctest.c \ + H5C.c H5Cdbg.c H5Cepoch.c H5Cquery.c H5Ctag.c H5Ctest.c \ H5CS.c \ H5D.c H5Dbtree.c H5Dbtree2.c H5Dchunk.c H5Dcompact.c H5Dcontig.c H5Ddbg.c \ H5Ddeprec.c H5Dearray.c H5Defl.c H5Dfarray.c H5Dfill.c H5Dint.c \ |