diff options
-rw-r--r-- | test/cache_api.c | 3186 | ||||
-rw-r--r-- | test/cache_common.c | 2878 | ||||
-rw-r--r-- | test/cache_common.h | 500 |
3 files changed, 6564 insertions, 0 deletions
diff --git a/test/cache_api.c b/test/cache_api.c new file mode 100644 index 0000000..902a829 --- /dev/null +++ b/test/cache_api.c @@ -0,0 +1,3186 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* Programmer: John Mainzer + * 11/10/05 + * + * This file contains tests for the API calls associated + * with the cache implemented in H5C.c + */ + +#include "h5test.h" +#include "H5Iprivate.h" +#include "H5ACprivate.h" +#include "cache_common.h" + +/* global variable declarations: */ + +const char *FILENAME[] = { + "cache_api", + NULL +}; + +/* macro definitions */ + +#define RESIZE_CONFIGS_ARE_EQUAL(a, b, compare_init) \ +( ( (a).version == (b).version ) && \ + ( (a).rpt_fcn == (b).rpt_fcn ) && \ + ( ( ! compare_init ) || \ + ( (a).set_initial_size == (b).set_initial_size ) ) && \ + ( ( ! compare_init ) || \ + ( (a).initial_size == (b).initial_size ) ) && \ + ( (a).min_clean_fraction == (b).min_clean_fraction ) && \ + ( (a).max_size == (b).max_size ) && \ + ( (a).min_size == (b).min_size ) && \ + ( (a).epoch_length == (b).epoch_length ) && \ + ( (a).incr_mode == (b).incr_mode ) && \ + ( (a).lower_hr_threshold == (b).lower_hr_threshold ) && \ + ( (a).increment == (b).increment ) && \ + ( (a).apply_max_increment == (b).apply_max_increment ) && \ + ( (a).max_increment == (b).max_increment ) && \ + ( (a).decr_mode == (b).decr_mode ) && \ + ( (a).upper_hr_threshold == (b).upper_hr_threshold ) && \ + ( (a).decrement == (b).decrement ) && \ + ( (a).apply_max_decrement == (b).apply_max_decrement ) && \ + ( (a).max_decrement == (b).max_decrement ) && \ + ( (a).epochs_before_eviction == (b).epochs_before_eviction ) && \ + ( (a).apply_empty_reserve == (b).apply_empty_reserve ) && \ + ( (a).empty_reserve == (b).empty_reserve ) ) + + +/* private function declarations: */ + +static void check_fapl_mdc_api_calls(void); + +static void validate_mdc_config(hid_t file_id, + H5AC_cache_config_t * ext_config_ptr, + hbool_t compare_init, + int test_num); + +static void check_file_mdc_api_calls(void); + +static void check_and_validate_cache_hit_rate(hid_t file_id, + double * hit_rate_ptr, + hbool_t dump_data, + int64_t min_accesses, + double min_hit_rate); + +static void check_and_validate_cache_size(hid_t file_id, + size_t * max_size_ptr, + size_t * min_clean_size_ptr, + size_t * cur_size_ptr, + int32_t * cur_num_entries_ptr, + hbool_t dump_data); + +static void mdc_api_call_smoke_check(void); + +static void check_fapl_mdc_api_errs(void); + +static void check_file_mdc_api_errs(void); + + +/**************************************************************************/ +/**************************************************************************/ +/********************************* tests: *********************************/ +/**************************************************************************/ +/**************************************************************************/ + +/*------------------------------------------------------------------------- + * Function: check_fapl_mdc_api_calls() + * + * Purpose: Verify that the file access property list related + * metadata cache related API calls are functioning + * correctly. + * + * Since we have tested the H5C code elsewhere, it should + * be sufficient to verify that the desired configuration + * data is getting to the cache. + * + * Return: void + * + * Programmer: John Mainzer + * 4/12/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +#define CACHE_CONFIGS_EQUAL(a, b, cmp_set_init, cmp_init_size) \ + ( ( (a).version == (b).version ) && \ + ( (a).rpt_fcn_enabled == (b).rpt_fcn_enabled ) && \ + ( ( ! cmp_set_init ) || \ + ( (a).set_initial_size == (b).set_initial_size ) ) && \ + ( ( ! cmp_init_size ) || \ + ( (a).initial_size == (b).initial_size ) ) && \ + ( (a).min_clean_fraction == (b).min_clean_fraction ) && \ + ( (a).max_size == (b).max_size ) && \ + ( (a).min_size == (b).min_size ) && \ + ( (a).epoch_length == (b).epoch_length ) && \ + ( (a).incr_mode == (b).incr_mode ) && \ + ( (a).lower_hr_threshold == (b).lower_hr_threshold ) && \ + ( (a).increment == (b).increment ) && \ + ( (a).apply_max_increment == (b).apply_max_increment ) && \ + ( (a).max_increment == (b).max_increment ) && \ + ( (a).decr_mode == (b).decr_mode ) && \ + ( (a).upper_hr_threshold == (b).upper_hr_threshold ) && \ + ( (a).decrement == (b).decrement ) && \ + ( (a).apply_max_decrement == (b).apply_max_decrement ) && \ + ( (a).max_decrement == (b).max_decrement ) && \ + ( (a).epochs_before_eviction == (b).epochs_before_eviction ) && \ + ( (a).apply_empty_reserve == (b).apply_empty_reserve ) && \ + ( (a).empty_reserve == (b).empty_reserve ) ) + +#define XLATE_EXT_TO_INT_MDC_CONFIG(i, e) \ +{ \ + (i).version = H5C__CURR_AUTO_SIZE_CTL_VER; \ + if ( (e).rpt_fcn_enabled ) \ + (i).rpt_fcn = H5C_def_auto_resize_rpt_fcn; \ + else \ + (i).rpt_fcn = NULL; \ + (i).set_initial_size = (e).set_initial_size; \ + (i).initial_size = (e).initial_size; \ + (i).min_clean_fraction = (e).min_clean_fraction; \ + (i).max_size = (e).max_size; \ + (i).min_size = (e).min_size; \ + (i).epoch_length = (long int)((e).epoch_length); \ + (i).incr_mode = (e).incr_mode; \ + (i).lower_hr_threshold = (e).lower_hr_threshold; \ + (i).increment = (e).increment; \ + (i).apply_max_increment = (e).apply_max_increment; \ + (i).max_increment = (e).max_increment; \ + (i).decr_mode = (e).decr_mode; \ + (i).upper_hr_threshold = (e).upper_hr_threshold; \ + (i).decrement = (e).decrement; \ + (i).apply_max_decrement = (e).apply_max_decrement; \ + (i).max_decrement = (e).max_decrement; \ + (i).epochs_before_eviction = (int)((e).epochs_before_eviction); \ + (i).apply_empty_reserve = (e).apply_empty_reserve; \ + (i).empty_reserve = (e).empty_reserve; \ +} + +static void +check_fapl_mdc_api_calls(void) +{ + const char * fcn_name = "check_fapl_mdc_api_calls()"; + char filename[512]; + herr_t result; + hid_t fapl_id = -1; + hid_t test_fapl_id = -1; + hid_t file_id = -1; + H5F_t * file_ptr = NULL; + H5C_t * cache_ptr = NULL; + H5AC_cache_config_t default_config = H5AC__DEFAULT_CACHE_CONFIG; + H5AC_cache_config_t mod_config = + { + /* int version = */ + H5AC__CURR_CACHE_CONFIG_VERSION, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024 + 1), + /* double min_clean_fraction = */ 0.2, + /* size_t max_size = */ (16 * 1024 * 1024 + 1), + /* size_t min_size = */ ( 1 * 1024 * 1024 + 1), + /* long int epoch_length = */ 50001, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.91, + /* double increment = */ 2.1, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024 + 1), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out, + /* double upper_hr_threshold = */ 0.998, + /* double decrement = */ 0.91, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024 - 1), + /* int epochs_before_eviction = */ 4, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.05, + /* int dirty_bytes_threshold = */ (256 * 1024) + }; + H5AC_cache_config_t scratch; + H5C_auto_size_ctl_t default_auto_size_ctl; + H5C_auto_size_ctl_t mod_auto_size_ctl; + + TESTING("MDC/FAPL related API calls"); + + pass = TRUE; + + XLATE_EXT_TO_INT_MDC_CONFIG(default_auto_size_ctl, default_config) + XLATE_EXT_TO_INT_MDC_CONFIG(mod_auto_size_ctl, mod_config) + + /* Create a FAPL and verify that it contains the default + * initial mdc configuration + */ + + if ( pass ) { + + fapl_id = H5Pcreate(H5P_FILE_ACCESS); + + if ( fapl_id < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pcreate(H5P_FILE_ACCESS) failed.\n"; + } + } + + if ( pass ) { + + scratch.version = H5C__CURR_AUTO_SIZE_CTL_VER; + + result = H5Pget_mdc_config(fapl_id, &scratch); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pget_mdc_config() failed.\n"; + + } else if (!CACHE_CONFIGS_EQUAL(default_config, scratch, TRUE, TRUE)) { + + pass = FALSE; + failure_mssg = "retrieved config doesn't match default."; + } + } + + + /* Modify the initial mdc configuration in a FAPL, and verify that + * the changes can be read back + */ + + if ( pass ) { + + result = H5Pset_mdc_config(fapl_id, &mod_config); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_mdc_config() failed.\n"; + } + } + + if ( pass ) { + + scratch.version = H5C__CURR_AUTO_SIZE_CTL_VER; + + result = H5Pget_mdc_config(fapl_id, &scratch); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pget_mdc_config() failed.\n"; + + } else if ( ! CACHE_CONFIGS_EQUAL(mod_config, scratch, TRUE, TRUE) ) { + + pass = FALSE; + failure_mssg = "retrieved config doesn't match mod config."; + } + } + + if ( pass ) { + + if ( H5Pclose(fapl_id) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pclose() failed.\n"; + } + } + + /* Open a file using the default FAPL. Verify that the resulting + * metadata cache uses the default configuration as well. Get a + * copy of the FAPL from the file, and verify that it contains the + * default initial meta data cache configuration. Close and delete + * the file. + */ + + /* setup the file name */ + if ( pass ) { + + if ( h5_fixname(FILENAME[0], H5P_DEFAULT, filename, sizeof(filename)) + == NULL ) { + + pass = FALSE; + failure_mssg = "h5_fixname() failed.\n"; + } + } + + /* create the file using the default FAPL */ + if ( pass ) { + + file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + if ( file_id < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fcreate() failed.\n"; + } + } + + /* get a pointer to the files internal data structure */ + if ( pass ) { + + file_ptr = H5I_object_verify(file_id, H5I_FILE); + + if ( file_ptr == NULL ) { + + pass = FALSE; + failure_mssg = "Can't get file_ptr.\n"; + + } else { + + cache_ptr = file_ptr->shared->cache; + } + } + + /* verify that we can access the internal version of the cache config */ + if ( pass ) { + + if ( ( cache_ptr == NULL ) || + ( cache_ptr->magic != H5C__H5C_T_MAGIC ) || + ( cache_ptr->resize_ctl.version != H5C__CURR_AUTO_SIZE_CTL_VER ) ){ + + pass = FALSE; + failure_mssg = "Can't access cache resize_ctl.\n"; + } + } + + /* conpare the cache's internal configuration with the expected value */ + if ( pass ) { + + if ( ! RESIZE_CONFIGS_ARE_EQUAL(default_auto_size_ctl, \ + cache_ptr->resize_ctl, TRUE) ) { + + + pass = FALSE; + failure_mssg = "Unexpected value(s) in cache resize_ctl.\n"; + } + } + + /* get a copy of the files FAPL */ + if ( pass ) { + + fapl_id = H5Fget_access_plist(file_id); + + if ( fapl_id < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fget_access_plist() failed.\n"; + } + } + + /* compare the initial cache config from the copy of the file's FAPL + * to the expected value. If all goes well, close the copy of the FAPL. + */ + if ( pass ) { + + scratch.version = H5C__CURR_AUTO_SIZE_CTL_VER; + + result = H5Pget_mdc_config(fapl_id, &scratch); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pget_mdc_config() failed.\n"; + + } else if (!CACHE_CONFIGS_EQUAL(default_config, scratch, TRUE, TRUE)) { + + pass = FALSE; + failure_mssg = "config retrieved from file doesn't match default."; + + } else if ( H5Pclose(fapl_id) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pclose() failed.\n"; + } + } + + /* close the file and delete it */ + if ( pass ) { + + if ( H5Fclose(file_id) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fclose() failed.\n"; + + } else if ( HDremove(filename) < 0 ) { + + pass = FALSE; + failure_mssg = "HDremove() failed.\n"; + } + } + + + /* Open a file using a FAPL with a modified initial metadata cache + * configuration. Verify that the resulting metadata cache uses the + * modified configuration as well. Get a copy of the FAPL from the + * file, and verify that it contains the modified initial meta data + * cache configuration. Close and delete the file. + */ + + /* Create a FAPL */ + if ( pass ) { + + fapl_id = H5Pcreate(H5P_FILE_ACCESS); + + if ( fapl_id < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pcreate(H5P_FILE_ACCESS) failed.\n"; + } + } + + /* Modify the initial mdc configuration in the FAPL. */ + + if ( pass ) { + + result = H5Pset_mdc_config(fapl_id, &mod_config); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_mdc_config() failed.\n"; + } + } + + /* setup the file name */ + if ( pass ) { + + if ( h5_fixname(FILENAME[0], H5P_DEFAULT, filename, sizeof(filename)) + == NULL ) { + + pass = FALSE; + failure_mssg = "h5_fixname() failed.\n"; + } + } + + /* create the file using the modified FAPL */ + if ( pass ) { + + file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id); + + if ( file_id < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fcreate() failed.\n"; + } + } + + /* get a pointer to the files internal data structure */ + if ( pass ) { + + file_ptr = H5I_object_verify(file_id, H5I_FILE); + + if ( file_ptr == NULL ) { + + pass = FALSE; + failure_mssg = "Can't get file_ptr.\n"; + + } else { + + cache_ptr = file_ptr->shared->cache; + } + } + + /* verify that we can access the internal version of the cache config */ + if ( pass ) { + + if ( ( cache_ptr == NULL ) || + ( cache_ptr->magic != H5C__H5C_T_MAGIC ) || + ( cache_ptr->resize_ctl.version != H5C__CURR_AUTO_SIZE_CTL_VER ) ){ + + pass = FALSE; + failure_mssg = "Can't access cache resize_ctl.\n"; + } + } + + /* conpare the cache's internal configuration with the expected value */ + if ( pass ) { + + if ( ! RESIZE_CONFIGS_ARE_EQUAL(mod_auto_size_ctl, \ + cache_ptr->resize_ctl, TRUE) ) { + + + pass = FALSE; + failure_mssg = "Unexpected value(s) in cache resize_ctl.\n"; + } + } + + /* get a copy of the files FAPL */ + if ( pass ) { + + test_fapl_id = H5Fget_access_plist(file_id); + + if ( test_fapl_id < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fget_access_plist() failed.\n"; + } + } + + /* compare the initial cache config from the copy of the file's FAPL + * to the expected value. If all goes well, close the copy of the FAPL. + */ + if ( pass ) { + + scratch.version = H5C__CURR_AUTO_SIZE_CTL_VER; + + result = H5Pget_mdc_config(test_fapl_id, &scratch); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pget_mdc_config() failed.\n"; + + } else if ( ! CACHE_CONFIGS_EQUAL(mod_config, scratch, TRUE, TRUE) ) { + + pass = FALSE; + failure_mssg = "config retrieved from file doesn't match."; + + } else if ( H5Pclose(test_fapl_id) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pclose() failed.\n"; + } + } + + /* close the fapl used to create the file */ + if ( pass ) { + + if ( H5Pclose(fapl_id) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pclose() failed.\n"; + } + } + + /* close the file and delete it */ + if ( pass ) { + + if ( H5Fclose(file_id) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fclose() failed.\n"; + + } else if ( HDremove(filename) < 0 ) { + + pass = FALSE; + failure_mssg = "HDremove() failed.\n"; + } + } + + if ( pass ) { PASSED(); } else { H5_FAILED(); } + + if ( ! pass ) + HDfprintf(stdout, "%s: failure_mssg = \"%s\".\n", + fcn_name, failure_mssg); + +} /* check_fapl_mdc_api_calls() */ + + +/*------------------------------------------------------------------------- + * Function: validate_mdc_config() + * + * Purpose: Verify that the file indicated by the file_id parameter + * has both internal and external configuration matching + * *config_ptr. + * + * Do nothin on success. On failure, set pass to FALSE, and + * load an error message into failue_mssg. Note that + * failure_msg is assumed to be at least 128 bytes in length. + * + * Return: void + * + * Programmer: John Mainzer + * 4/14/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static void +validate_mdc_config(hid_t file_id, + H5AC_cache_config_t * ext_config_ptr, + hbool_t compare_init, + int test_num) +{ + /* const char * fcn_name = "validate_mdc_config()"; */ + static char msg[256]; + H5F_t * file_ptr = NULL; + H5C_t * cache_ptr = NULL; + H5AC_cache_config_t scratch; + H5C_auto_size_ctl_t int_config; + + XLATE_EXT_TO_INT_MDC_CONFIG(int_config, (*ext_config_ptr)) + + /* get a pointer to the files internal data structure */ + if ( pass ) { + + file_ptr = H5I_object_verify(file_id, H5I_FILE); + + if ( file_ptr == NULL ) { + + pass = FALSE; + HDsnprintf(msg, (size_t)128, "Can't get file_ptr #%d.", test_num); + failure_mssg = msg; + + } else { + + cache_ptr = file_ptr->shared->cache; + } + } + + /* verify that we can access the internal version of the cache config */ + if ( pass ) { + + if ( ( cache_ptr == NULL ) || + ( cache_ptr->magic != H5C__H5C_T_MAGIC ) || + ( cache_ptr->resize_ctl.version != H5C__CURR_AUTO_SIZE_CTL_VER ) ){ + + pass = FALSE; + HDsnprintf(msg, (size_t)128, + "Can't access cache resize_ctl #%d.", test_num); + failure_mssg = msg; + } + } + + /* compare the cache's internal configuration with the expected value */ + if ( pass ) { + + if ( ! RESIZE_CONFIGS_ARE_EQUAL(int_config, cache_ptr->resize_ctl, + compare_init) ) { + + pass = FALSE; + HDsnprintf(msg, (size_t)128, + "Unexpected internal config #%d.", test_num); + failure_mssg = msg; + } + } + + /* obtain external cache config */ + if ( pass ) { + + scratch.version = H5AC__CURR_CACHE_CONFIG_VERSION; + + if ( H5Fget_mdc_config(file_id, &scratch) < 0 ) { + + pass = FALSE; + HDsnprintf(msg, (size_t)128, + "H5Fget_mdc_config() failed #%d.", test_num); + failure_mssg = msg; + } + } + + if ( pass ) { + + /* Recall that in any configuration supplied by the cache + * at run time, the set_initial_size field will always + * be FALSE, regardless of the value passed in. Thus we + * always resume that this field need not match that of + * the supplied external configuration. + * + * The cache also sets the initial_size field to the current + * cache max size instead of the value initialy supplied. + * Depending on circumstances, this may or may not match + * the original. Hence the compare_init parameter. + */ + if ( ! CACHE_CONFIGS_EQUAL((*ext_config_ptr), scratch, \ + FALSE, compare_init) ) { + + pass = FALSE; + HDsnprintf(msg, (size_t)128, + "Unexpected external config #%d.", test_num); + failure_mssg = msg; + } + } + + return; + +} /* validate_mdc_config() */ + + +/*------------------------------------------------------------------------- + * Function: check_file_mdc_api_calls() + * + * Purpose: Verify that the file related metadata cache API calls are + * functioning correctly. + * + * Since we have tested the H5C code elsewhere, it should + * be sufficient to verify that the desired configuration + * data is getting in and out of the cache. Similarly, + * we need only verify that the cache monitoring calls + * return the data that the cache thinks they should return. + * We shouldn't need to verify data correctness beyond that + * point. + * + * Return: void + * + * Programmer: John Mainzer + * 4/14/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static void +check_file_mdc_api_calls(void) +{ + const char * fcn_name = "check_file_mdc_api_calls()"; + char filename[512]; + hid_t file_id = -1; + size_t max_size; + size_t min_clean_size; + size_t cur_size; + int cur_num_entries; + double hit_rate; + H5AC_cache_config_t default_config = H5AC__DEFAULT_CACHE_CONFIG; + H5AC_cache_config_t mod_config_1 = + { + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024 + 1), + /* double min_clean_fraction = */ 0.2, + /* size_t max_size = */ (16 * 1024 * 1024 + 1), + /* size_t min_size = */ ( 1 * 1024 * 1024 + 1), + /* long int epoch_length = */ 50001, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.91, + /* double increment = */ 2.1, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024 + 1), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out, + /* double upper_hr_threshold = */ 0.998, + /* double decrement = */ 0.91, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024 - 1), + /* int epochs_before_eviction = */ 4, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.05, + /* int dirty_bytes_threshold = */ (256 * 1024) + }; + H5AC_cache_config_t mod_config_2 = + { + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ TRUE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (512 * 1024), + /* double min_clean_fraction = */ 0.1, + /* size_t max_size = */ ( 8 * 1024 * 1024), + /* size_t min_size = */ ( 512 * 1024), + /* long int epoch_length = */ 25000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (2 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__threshold, + /* double upper_hr_threshold = */ 0.9995, + /* double decrement = */ 0.95, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (512 * 1024), + /* int epochs_before_eviction = */ 4, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.05, + /* int dirty_bytes_threshold = */ (256 * 1024) + }; + H5AC_cache_config_t mod_config_3 = + { + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.2, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__off, + /* double lower_hr_threshold = */ 0.90, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__off, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ FALSE, + /* size_t max_decrement = */ (1 * 1024 * 1024 - 1), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ FALSE, + /* double empty_reserve = */ 0.05, + /* int dirty_bytes_threshold = */ (256 * 1024) + }; + H5AC_cache_config_t mod_config_4 = + { + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.15, + /* size_t max_size = */ (20 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 75000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (2 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ + H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }; + + TESTING("MDC/FILE related API calls"); + + pass = TRUE; + + /* Open a file with the default FAPL. Verify that the cache is + * configured as per the default both by looking at its internal + * configuration, and via the H5Fget_mdc_config() call. + * + * Then set serveral different configurations, and verify that + * they took as per above. + */ + + /* setup the file name */ + if ( pass ) { + + if ( h5_fixname(FILENAME[0], H5P_DEFAULT, filename, sizeof(filename)) + == NULL ) { + + pass = FALSE; + failure_mssg = "h5_fixname() failed.\n"; + } + } + + /* create the file using the default FAPL */ + if ( pass ) { + + file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + if ( file_id < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fcreate() failed.\n"; + } + } + + /* verify that the cache is set to the default config */ + validate_mdc_config(file_id, &default_config, TRUE, 1); + + /* set alternate config 1 */ + if ( pass ) { + + if ( H5Fset_mdc_config(file_id, &mod_config_1) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fset_mdc_config() failed 1.\n"; + } + } + + /* verify that the cache is now set to the alternate config */ + validate_mdc_config(file_id, &mod_config_1, TRUE, 2); + + /* set alternate config 2 */ + if ( pass ) { + + if ( H5Fset_mdc_config(file_id, &mod_config_2) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fset_mdc_config() failed 2.\n"; + } + } + + /* verify that the cache is now set to the alternate config */ + validate_mdc_config(file_id, &mod_config_2, TRUE, 3); + + /* set alternate config 3 */ + if ( pass ) { + + if ( H5Fset_mdc_config(file_id, &mod_config_3) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fset_mdc_config() failed 3.\n"; + } + } + + /* verify that the cache is now set to the alternate config */ + validate_mdc_config(file_id, &mod_config_3, TRUE, 4); + + /* set alternate config 4 */ + if ( pass ) { + + if ( H5Fset_mdc_config(file_id, &mod_config_4) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fset_mdc_config() failed 4.\n"; + } + } + + /* verify that the cache is now set to the alternate config */ + validate_mdc_config(file_id, &mod_config_4, TRUE, 5); + + + /* Run some quick smoke checks on the cache status monitoring + * calls -- no interesting data as the cache hasn't had a + * chance to do much yet. + */ + + if ( pass ) { + + if ( H5Fget_mdc_hit_rate(file_id, &hit_rate) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fget_mdc_hit_rate() failed 1.\n"; + + } else if ( hit_rate != 0.0 ) { + + pass = FALSE; + failure_mssg = + "H5Fget_mdc_hit_rate() returned unexpected hit rate.\n"; + + } +#if 0 /* this may be useful now and then -- keep it around */ + else { + + HDfprintf(stdout, + "H5Fget_mdc_hit_rate() reports hit_rate = %lf:\n", + hit_rate); + } +#endif + } + + if ( pass ) { + + if ( H5Fget_mdc_size(file_id, &max_size, &min_clean_size, + &cur_size, &cur_num_entries) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fget_mdc_size() failed 1.\n"; + + } else if ( ( mod_config_4.initial_size != max_size ) || + ( min_clean_size != (size_t) + ((double)max_size * mod_config_4.min_clean_fraction) ) ) { + + pass = FALSE; + failure_mssg = "H5Fget_mdc_size() returned unexpected value(s).\n"; + + } +#if 0 /* this may be useful now and then -- keep it around */ + else { + + HDfprintf(stdout, "H5Fget_mdc_size() reports:\n"); + HDfprintf(stdout, " max_size: %ld, min_clean_size: %ld\n", + (long)max_size, (long)min_clean_size); + HDfprintf(stdout, " cur_size: %ld, cur_num_entries: %d\n", + (long)cur_size, cur_num_entries); + } +#endif + } + + /* close the file and delete it */ + if ( pass ) { + + if ( H5Fclose(file_id) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fclose() failed.\n"; + + } else if ( HDremove(filename) < 0 ) { + + pass = FALSE; + failure_mssg = "HDremove() failed.\n"; + } + } + + if ( pass ) { PASSED(); } else { H5_FAILED(); } + + if ( ! pass ) + HDfprintf(stdout, "%s: failure_mssg = \"%s\".\n", + fcn_name, failure_mssg); + +} /* check_file_mdc_api_calls() */ + + +/*------------------------------------------------------------------------- + * Function: check_and_validate_cache_hit_rate() + * + * Purpose: Use the API functions to get and reset the cache hit rate. + * Verify that the value returned by the API call agrees with + * the cache internal data structures. + * + * If the number of cache accesses exceeds the value provided + * in the min_accesses parameter, and the hit rate is less than + * min_hit_rate, set pass to FALSE, and set failure_mssg to + * a string indicating that hit rate was unexpectedly low. + * + * Return hit rate in *hit_rate_ptr, and print the data to + * stdout if requested. + * + * If an error is detected, set pass to FALSE, and set + * failure_mssg to an appropriate value. + * + * Return: void + * + * Programmer: John Mainzer + * 4/18/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static void +check_and_validate_cache_hit_rate(hid_t file_id, + double * hit_rate_ptr, + hbool_t dump_data, + int64_t min_accesses, + double min_hit_rate) +{ + /* const char * fcn_name = "check_and_validate_cache_hit_rate()"; */ + herr_t result; + int64_t cache_hits; + int64_t cache_accesses; + double expected_hit_rate; + double hit_rate; + H5F_t * file_ptr = NULL; + H5C_t * cache_ptr = NULL; + + /* get a pointer to the files internal data structure */ + if ( pass ) { + + file_ptr = H5I_object_verify(file_id, H5I_FILE); + + if ( file_ptr == NULL ) { + + pass = FALSE; + failure_mssg = "Can't get file_ptr."; + + } else { + + cache_ptr = file_ptr->shared->cache; + } + } + + /* verify that we can access the cache data structure */ + if ( pass ) { + + if ( ( cache_ptr == NULL ) || + ( cache_ptr->magic != H5C__H5C_T_MAGIC ) ) { + + pass = FALSE; + failure_mssg = "Can't access cache resize_ctl."; + } + } + + /* compare the cache's internal configuration with the expected value */ + if ( pass ) { + + cache_hits = cache_ptr->cache_hits; + cache_accesses = cache_ptr->cache_accesses; + + if ( cache_accesses > 0 ) { + + expected_hit_rate = ((double)cache_hits) / ((double)cache_accesses); + + } else { + + expected_hit_rate = 0.0; + } + + result = H5Fget_mdc_hit_rate(file_id, &hit_rate); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fget_mdc_hit_rate() failed."; + + } else if ( hit_rate != expected_hit_rate ) { + + pass = FALSE; + failure_mssg = "unexpected hit rate."; + } + } + + if ( pass ) { /* reset the hit rate */ + + result = H5Freset_mdc_hit_rate_stats(file_id); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5Freset_mdc_hit_rate_stats() failed."; + } + } + + /* set *hit_rate_ptr if appropriate */ + if ( ( pass ) && ( hit_rate_ptr != NULL ) ) { + + *hit_rate_ptr = hit_rate; + } + + /* dump data to stdout if requested */ + if ( ( pass ) && ( dump_data ) ) { + + HDfprintf(stdout, + "cache_hits: %ld, cache_accesses: %ld, hit_rate: %lf\n", + (long)cache_hits, (long)cache_accesses, hit_rate); + } + + if ( ( pass ) && + ( cache_accesses > min_accesses ) && + ( hit_rate < min_hit_rate ) ) { + + pass = FALSE; + failure_mssg = "Unexpectedly low hit rate."; + } + + return; + +} /* check_and_validate_cache_hit_rate() */ + + +/*------------------------------------------------------------------------- + * Function: check_and_validate_cache_size() + * + * Purpose: Use the API function to get the cache size data. Verify + * that the values returned by the API call agree with + * the cache internal data structures. + * + * Return size data in the locations specified by the pointer + * parameters if these parameters are not NULL. Print the + * data to stdout if requested. + * + * If an error is detected, set pass to FALSE, and set + * failure_mssg to an appropriate value. + * + * Return: void + * + * Programmer: John Mainzer + * 4/18/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static void +check_and_validate_cache_size(hid_t file_id, + size_t * max_size_ptr, + size_t * min_clean_size_ptr, + size_t * cur_size_ptr, + int32_t * cur_num_entries_ptr, + hbool_t dump_data) +{ + /* const char * fcn_name = "check_and_validate_cache_size()"; */ + herr_t result; + size_t expected_max_size; + size_t max_size; + size_t expected_min_clean_size; + size_t min_clean_size; + size_t expected_cur_size; + size_t cur_size; + int32_t expected_cur_num_entries; + int cur_num_entries; + H5F_t * file_ptr = NULL; + H5C_t * cache_ptr = NULL; + + /* get a pointer to the files internal data structure */ + if ( pass ) { + + file_ptr = H5I_object_verify(file_id, H5I_FILE); + + if ( file_ptr == NULL ) { + + pass = FALSE; + failure_mssg = "Can't get file_ptr."; + + } else { + + cache_ptr = file_ptr->shared->cache; + } + } + + /* verify that we can access the cache data structure */ + if ( pass ) { + + if ( ( cache_ptr == NULL ) || + ( cache_ptr->magic != H5C__H5C_T_MAGIC ) ) { + + pass = FALSE; + failure_mssg = "Can't access cache data structure."; + } + } + + /* compare the cache's internal configuration with the expected value */ + if ( pass ) { + + expected_max_size = cache_ptr->max_cache_size; + expected_min_clean_size = cache_ptr->min_clean_size; + expected_cur_size = cache_ptr->index_size; + expected_cur_num_entries = cache_ptr->index_len; + + result = H5Fget_mdc_size(file_id, + &max_size, + &min_clean_size, + &cur_size, + &cur_num_entries); + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fget_mdc_size() failed."; + + } else if ( ( max_size != expected_max_size ) || + ( min_clean_size != expected_min_clean_size ) || + ( cur_size != expected_cur_size ) || + ( cur_num_entries != (int)expected_cur_num_entries ) ) { + + pass = FALSE; + failure_mssg = "H5Fget_mdc_size() returned unexpected value(s)."; + + } + } + + /* return size values if requested */ + if ( ( pass ) && ( max_size_ptr != NULL ) ) { + + *max_size_ptr = max_size; + } + + if ( ( pass ) && ( min_clean_size_ptr != NULL ) ) { + + *min_clean_size_ptr = min_clean_size; + } + + if ( ( pass ) && ( cur_size_ptr != NULL ) ) { + + *cur_size_ptr = cur_size; + } + + if ( ( pass ) && ( cur_num_entries_ptr != NULL ) ) { + + *cur_num_entries_ptr = cur_num_entries; + } + + + /* dump data to stdout if requested */ + if ( ( pass ) && ( dump_data ) ) { + + HDfprintf(stdout, + "max_sz: %ld, min_clean_sz: %ld, cur_sz: %ld, cur_ent: %ld\n", + (long)max_size, (long)min_clean_size, (long)cur_size, + (long)cur_num_entries); + } + + return; + +} /* check_and_validate_cache_size() */ + + +/*------------------------------------------------------------------------- + * Function: mdc_api_call_smoke_check() + * + * Purpose: + * + * Return: void + * + * Programmer: John Mainzer + * 4/14/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +#define CHUNK_SIZE 2 +#define DSET_SIZE (200 * CHUNK_SIZE) +#define NUM_DSETS 6 +#define NUM_RANDOM_ACCESSES 200000 + +static void +mdc_api_call_smoke_check(void) +{ + const char * fcn_name = "mdc_api_call_smoke_check()"; + char filename[512]; + hbool_t valid_chunk; + hbool_t dump_hit_rate = FALSE; + int64_t min_accesses = 1000; + double min_hit_rate = 0.90; + hbool_t dump_cache_size = FALSE; + hid_t file_id = -1; + hid_t dataspace_id; + hid_t filespace_ids[NUM_DSETS]; + hid_t memspace_id; + hid_t dataset_ids[NUM_DSETS]; + hid_t properties; + char dset_name[64]; + int i, j, k, l, m, n; + herr_t status; + hsize_t dims[2]; + hsize_t a_size[2]; + hsize_t offset[2]; + hsize_t chunk_size[2]; + int data_chunk[CHUNK_SIZE][CHUNK_SIZE]; + H5AC_cache_config_t default_config = H5AC__DEFAULT_CACHE_CONFIG; + H5AC_cache_config_t mod_config_1 = + { + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ 500000, + /* double min_clean_fraction = */ 0.1, + /* size_t max_size = */ 16000000, + /* size_t min_size = */ 250000, + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__off, + /* double lower_hr_threshold = */ 0.95, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ FALSE, + /* size_t max_increment = */ 4000000, + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__off, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ FALSE, + /* size_t max_decrement = */ 1000000, + /* int epochs_before_eviction = */ 2, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.05, + /* int dirty_bytes_threshold = */ (256 * 1024) + }; + H5AC_cache_config_t mod_config_2 = + { + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ 12000000, + /* double min_clean_fraction = */ 0.1, + /* size_t max_size = */ 16000000, + /* size_t min_size = */ 250000, + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__off, + /* double lower_hr_threshold = */ 0.95, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ FALSE, + /* size_t max_increment = */ 4000000, + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__off, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ FALSE, + /* size_t max_decrement = */ 1000000, + /* int epochs_before_eviction = */ 2, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.05, + /* int dirty_bytes_threshold = */ (256 * 1024) + }; + H5AC_cache_config_t mod_config_3 = + { + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ 2000000, + /* double min_clean_fraction = */ 0.1, + /* size_t max_size = */ 16000000, + /* size_t min_size = */ 250000, + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__off, + /* double lower_hr_threshold = */ 0.95, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ FALSE, + /* size_t max_increment = */ 4000000, + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__off, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ FALSE, + /* size_t max_decrement = */ 1000000, + /* int epochs_before_eviction = */ 2, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.05, + /* int dirty_bytes_threshold = */ (256 * 1024) + }; + + TESTING("MDC API smoke check"); + + pass = TRUE; + + /* Open a file with the default FAPL. Verify that the cache is + * configured as per the default both by looking at its internal + * configuration, and via the H5Fget_mdc_config() call. + * + * Then set the cache to mod_config_1, which fixes cache size at + * 500000 bytes, and turns off automatic cache resize. + */ + + /* setup the file name */ + if ( pass ) { + + if ( h5_fixname(FILENAME[0], H5P_DEFAULT, filename, sizeof(filename)) + == NULL ) { + + pass = FALSE; + failure_mssg = "h5_fixname() failed.\n"; + } + } + + /* create the file using the default FAPL */ + if ( pass ) { + + file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + if ( file_id < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fcreate() failed.\n"; + } + } + + /* verify that the cache is set to the default config */ + validate_mdc_config(file_id, &default_config, TRUE, 1); + + /* set alternate config 1 */ + if ( pass ) { + + if ( H5Fset_mdc_config(file_id, &mod_config_1) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fset_mdc_config() failed 1.\n"; + } + } + + /* verify that the cache is now set to the alternate config */ + validate_mdc_config(file_id, &mod_config_1, TRUE, 2); + + + /* create the datasets */ + if ( pass ) { + + i = 0; + + while ( ( pass ) && ( i < NUM_DSETS ) ) + { + /* create a dataspace for the chunked dataset */ + dims[0] = DSET_SIZE; + dims[1] = DSET_SIZE; + dataspace_id = H5Screate_simple(2, dims, NULL); + + if ( dataspace_id < 0 ) { + + pass = FALSE; + failure_mssg = "H5Screate_simple() failed."; + } + + /* set the dataset creation plist to specify that the raw data is + * to be partioned into 10X10 element chunks. + */ + + if ( pass ) { + + chunk_size[0] = CHUNK_SIZE; + chunk_size[1] = CHUNK_SIZE; + properties = H5Pcreate(H5P_DATASET_CREATE); + + if ( properties < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pcreate() failed."; + } + } + + if ( pass ) { + + if ( H5Pset_chunk(properties, 2, chunk_size) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_chunk() failed."; + } + } + + /* create the dataset */ + if ( pass ) { + + sprintf(dset_name, "/dset%03d", i); + dataset_ids[i] = H5Dcreate(file_id, dset_name, H5T_STD_I32BE, + dataspace_id, properties); + + if ( dataset_ids[i] < 0 ) { + + pass = FALSE; + failure_mssg = "H5Dcreate() failed."; + } + } + + /* get the file space ID */ + if ( pass ) { + + filespace_ids[i] = H5Dget_space(dataset_ids[i]); + + if ( filespace_ids[i] < 0 ) { + + pass = FALSE; + failure_mssg = "H5Dget_space() failed."; + } + } + + i++; + } + } + + /* create the mem space to be used to read and write chunks */ + if ( pass ) { + + dims[0] = CHUNK_SIZE; + dims[1] = CHUNK_SIZE; + memspace_id = H5Screate_simple(2, dims, NULL); + + if ( memspace_id < 0 ) { + + pass = FALSE; + failure_mssg = "H5Screate_simple() failed."; + } + } + + /* select in memory hyperslab */ + if ( pass ) { + + offset[0] = 0; /*offset of hyperslab in memory*/ + offset[1] = 0; + a_size[0] = CHUNK_SIZE; /*size of hyperslab*/ + a_size[1] = CHUNK_SIZE; + status = H5Sselect_hyperslab(memspace_id, H5S_SELECT_SET, offset, NULL, + a_size, NULL); + + if ( status < 0 ) { + + pass = FALSE; + failure_mssg = "H5Sselect_hyperslab() failed."; + } + } + + /* initialize all datasets on a round robin basis */ + i = 0; + while ( ( pass ) && ( i < DSET_SIZE ) ) + { + j = 0; + while ( ( pass ) && ( j < DSET_SIZE ) ) + { + m = 0; + while ( ( pass ) && ( m < NUM_DSETS ) ) + { + /* initialize the slab */ + for ( k = 0; k < CHUNK_SIZE; k++ ) + { + for ( l = 0; l < CHUNK_SIZE; l++ ) + { + data_chunk[k][l] = (DSET_SIZE * DSET_SIZE * m) + + (DSET_SIZE * (i + k)) + j + l; + } + } + + /* select on disk hyperslab */ + offset[0] = i; /*offset of hyperslab in file*/ + offset[1] = j; + a_size[0] = CHUNK_SIZE; /*size of hyperslab*/ + a_size[1] = CHUNK_SIZE; + status = H5Sselect_hyperslab(filespace_ids[m], H5S_SELECT_SET, + offset, NULL, a_size, NULL); + + if ( status < 0 ) { + + pass = FALSE; + failure_mssg = "disk H5Sselect_hyperslab() failed."; + } + + /* write the chunk to file */ + status = H5Dwrite(dataset_ids[m], H5T_NATIVE_INT, memspace_id, + filespace_ids[m], H5P_DEFAULT, data_chunk); + + if ( status < 0 ) { + + pass = FALSE; + failure_mssg = "H5Dwrite() failed."; + } + m++; + } + j += CHUNK_SIZE; + } + + /* check the cache hit rate, and reset the counters. + * Hit rate should be just about unity here, so we will just + * get the data and (possibly) print it without checking it + * beyond ensuring that it agrees with the cache internal + * data structures. + * + * similarly, check cache size. + */ + + if ( ( pass ) && ( i % (DSET_SIZE / 4) == 0 ) ) { + + check_and_validate_cache_hit_rate(file_id, NULL, dump_hit_rate, + min_accesses, min_hit_rate); + + check_and_validate_cache_size(file_id, NULL, NULL, NULL, NULL, + dump_cache_size); + } + + i += CHUNK_SIZE; + } + + /* set alternate config 2 */ + if ( pass ) { + + if ( H5Fset_mdc_config(file_id, &mod_config_2) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fset_mdc_config() failed 2.\n"; + } + } + + /* verify that the cache is now set to the alternate config */ + validate_mdc_config(file_id, &mod_config_2, TRUE, 3); + + /* do random reads on all datasets */ + n = 0; + while ( ( pass ) && ( n < NUM_RANDOM_ACCESSES ) ) + { + m = rand() % NUM_DSETS; + i = (rand() % (DSET_SIZE / CHUNK_SIZE)) * CHUNK_SIZE; + j = (rand() % (DSET_SIZE / CHUNK_SIZE)) * CHUNK_SIZE; + + /* select on disk hyperslab */ + offset[0] = i; /*offset of hyperslab in file*/ + offset[1] = j; + a_size[0] = CHUNK_SIZE; /*size of hyperslab*/ + a_size[1] = CHUNK_SIZE; + status = H5Sselect_hyperslab(filespace_ids[m], H5S_SELECT_SET, + offset, NULL, a_size, NULL); + + if ( status < 0 ) { + + pass = FALSE; + failure_mssg = "disk hyperslab create failed."; + } + + /* read the chunk from file */ + if ( pass ) { + + status = H5Dread(dataset_ids[m], H5T_NATIVE_INT, memspace_id, + filespace_ids[m], H5P_DEFAULT, data_chunk); + + if ( status < 0 ) { + + pass = FALSE; + failure_mssg = "disk hyperslab create failed."; + } + } + + /* validate the slab */ + if ( pass ) { + + valid_chunk = TRUE; + for ( k = 0; k < CHUNK_SIZE; k++ ) + { + for ( l = 0; l < CHUNK_SIZE; l++ ) + { + if ( data_chunk[k][l] + != + ((DSET_SIZE * DSET_SIZE * m) + + (DSET_SIZE * (i + k)) + j + l) ) { + + valid_chunk = FALSE; +#if 0 /* this will be useful from time to time -- lets keep it*/ + HDfprintf(stdout, + "data_chunk[%0d][%0d] = %0d, expect %0d.\n", + k, l, data_chunk[k][l], + ((DSET_SIZE * DSET_SIZE * m) + + (DSET_SIZE * (i + k)) + j + l)); + HDfprintf(stdout, + "m = %d, i = %d, j = %d, k = %d, l = %d\n", + m, i, j, k, l); +#endif + } + } + } + + if ( ! valid_chunk ) { +#if 1 + pass = FALSE; + failure_mssg = "slab validation failed."; +#else /* as above */ + fprintf(stdout, "Chunk (%0d, %0d) in /dset%03d is invalid.\n", + i, j, m); +#endif + } + } + + if ( ( pass ) && ( n % (NUM_RANDOM_ACCESSES / 4) == 0 ) ) { + + check_and_validate_cache_hit_rate(file_id, NULL, dump_hit_rate, + min_accesses, min_hit_rate); + + check_and_validate_cache_size(file_id, NULL, NULL, NULL, NULL, + dump_cache_size); + } + + n++; + } + + /* close the file spaces we are done with */ + i = 1; + while ( ( pass ) && ( i < NUM_DSETS ) ) + { + if ( H5Sclose(filespace_ids[i]) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Sclose() failed."; + } + i++; + } + + + /* close the datasets we are done with */ + i = 1; + while ( ( pass ) && ( i < NUM_DSETS ) ) + { + if ( H5Dclose(dataset_ids[i]) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Dclose() failed."; + } + i++; + } + + /* set alternate config 3 */ + if ( pass ) { + + if ( H5Fset_mdc_config(file_id, &mod_config_3) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fset_mdc_config() failed 3.\n"; + } + } + + /* verify that the cache is now set to the alternate config */ + validate_mdc_config(file_id, &mod_config_3, TRUE, 4); + + /* do random reads on data set 0 only */ + m = 0; + n = 0; + while ( ( pass ) && ( n < NUM_RANDOM_ACCESSES ) ) + { + i = (rand() % (DSET_SIZE / CHUNK_SIZE)) * CHUNK_SIZE; + j = (rand() % (DSET_SIZE / CHUNK_SIZE)) * CHUNK_SIZE; + + /* select on disk hyperslab */ + offset[0] = i; /*offset of hyperslab in file*/ + offset[1] = j; + a_size[0] = CHUNK_SIZE; /*size of hyperslab*/ + a_size[1] = CHUNK_SIZE; + status = H5Sselect_hyperslab(filespace_ids[m], H5S_SELECT_SET, + offset, NULL, a_size, NULL); + + if ( status < 0 ) { + + pass = FALSE; + failure_mssg = "disk hyperslab create failed."; + } + + /* read the chunk from file */ + if ( pass ) { + + status = H5Dread(dataset_ids[m], H5T_NATIVE_INT, memspace_id, + filespace_ids[m], H5P_DEFAULT, data_chunk); + + if ( status < 0 ) { + + pass = FALSE; + failure_mssg = "disk hyperslab create failed."; + } + } + + /* validate the slab */ + if ( pass ) { + + valid_chunk = TRUE; + for ( k = 0; k < CHUNK_SIZE; k++ ) + { + for ( l = 0; l < CHUNK_SIZE; l++ ) + { + if ( data_chunk[k][l] + != + ((DSET_SIZE * DSET_SIZE * m) + + (DSET_SIZE * (i + k)) + j + l) ) { + + valid_chunk = FALSE; + } +#if 0 /* this will be useful from time to time -- lets keep it */ + HDfprintf(stdout, "data_chunk[%0d][%0d] = %0d, expect %0d.\n", + k, l, data_chunk[k][l], + ((DSET_SIZE * DSET_SIZE * m) + + (DSET_SIZE * (i + k)) + j + l)); +#endif + } + } + + if ( ! valid_chunk ) { + + pass = FALSE; + failure_mssg = "slab validation failed."; +#if 0 /* as above */ + fprintf(stdout, "Chunk (%0d, %0d) in /dset%03d is invalid.\n", + i, j, m); +#endif + } + } + + if ( ( pass ) && ( n % (NUM_RANDOM_ACCESSES / 4) == 0 ) ) { + + check_and_validate_cache_hit_rate(file_id, NULL, dump_hit_rate, + min_accesses, min_hit_rate); + + check_and_validate_cache_size(file_id, NULL, NULL, NULL, NULL, + dump_cache_size); + } + + n++; + } + + /* close file space 0 */ + if ( pass ) { + + if ( H5Sclose(filespace_ids[0]) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Sclose(filespace_ids[0]) failed."; + } + } + + /* close the data space */ + if ( pass ) { + + if ( H5Sclose(dataspace_id) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Sclose(dataspace) failed."; + } + } + + /* close the mem space */ + if ( pass ) { + + if ( H5Sclose(memspace_id) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Sclose(memspace_id) failed."; + } + } + + /* close dataset 0 */ + if ( pass ) { + + if ( H5Dclose(dataset_ids[0]) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Dclose(dataset_ids[0]) failed."; + } + } + + /* close the file and delete it */ + if ( pass ) { + + if ( H5Fclose(file_id) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fclose() failed.\n"; + + } + else if ( HDremove(filename) < 0 ) { + + pass = FALSE; + failure_mssg = "HDremove() failed.\n"; + } + } + + if ( pass ) { PASSED(); } else { H5_FAILED(); } + + if ( ! pass ) + HDfprintf(stdout, "%s: failure_mssg = \"%s\".\n", + fcn_name, failure_mssg); + +} /* mdc_api_call_smoke_check() */ + + +/* The following array of invalid external MDC cache configurations is + * used to test error rejection in the MDC related API calls. + */ + +#define NUM_INVALID_CONFIGS 31 + +H5AC_cache_config_t invalid_configs[NUM_INVALID_CONFIGS] = +{ + { + /* 0 -- bad version */ + /* int version = */ -1, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 1 -- bad rpt_fcn_enabled */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ -1, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 2 -- bad set_initial_size */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ 2, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 3 -- max_size too big */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ H5C__MAX_MAX_CACHE_SIZE + 1, + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 4 -- min_size too small */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ H5C__MIN_MAX_CACHE_SIZE - 1, + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 5 -- min_size > max_size */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ FALSE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ (16 * 1024 * 1024 + 1), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 6 -- initial size out of range (too big) */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (16 * 1024 * 1024 + 1), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 7 -- initial_size out of range (too small) */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024 - 1), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 8 -- min_clean_fraction too big */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 1.000001, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 9 -- min_clean_fraction too small */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ -0.00000001, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 10 -- epoch_length too small */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ H5C__MIN_AR_EPOCH_LENGTH - 1, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 11 -- epoch_length too big */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ H5C__MAX_AR_EPOCH_LENGTH + 1, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 12 -- invalid incr_mode */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ -1, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 13 -- lower_hr_threshold too small */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ -0.000001, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 14 -- lower_hr_threshold too big */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 1.00000001, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 15 -- increment too small */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 0.999999999999, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 16 -- bad apply_max_increment */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ -1, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 17 -- bad decr_mode */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ -1, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 18 -- upper_hr_threshold too big */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__threshold, + /* double upper_hr_threshold = */ 1.00001, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 19 -- decrement too small */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ -0.0000000001, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 20 -- decrement too big */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 1.0000000001, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 21 -- epochs_before_eviction too small */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 0, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 22 -- epochs_before_eviction too big */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ H5C__MAX_EPOCH_MARKERS + 1, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 23 -- invalid apply_empty_reserve */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ 2, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 24 -- empty_reserve too small */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ -0.0000000001, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 25 -- empty_reserve too big */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 1.00000000001, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 26 -- upper_hr_threshold too small */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ -0.000000001, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 27 -- upper_hr_threshold too big */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 1.00000001, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 28 -- upper_hr_threshold <= lower_hr_threshold */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.9, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (256 * 1024) + }, + { + /* 29 -- dirty_bytes_threshold too small */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.999, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (H5C__MIN_MAX_CACHE_SIZE / 2) - 1 + }, + { + /* 30 -- dirty_bytes_threshold too big */ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, + /* hbool_t rpt_fcn_enabled = */ FALSE, + /* hbool_t set_initial_size = */ TRUE, + /* size_t initial_size = */ (1 * 1024 * 1024), + /* double min_clean_fraction = */ 0.25, + /* size_t max_size = */ (16 * 1024 * 1024), + /* size_t min_size = */ ( 1 * 1024 * 1024), + /* long int epoch_length = */ 50000, + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, + /* double lower_hr_threshold = */ 0.9, + /* double increment = */ 2.0, + /* hbool_t apply_max_increment = */ TRUE, + /* size_t max_increment = */ (4 * 1024 * 1024), + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, + /* double upper_hr_threshold = */ 0.9, + /* double decrement = */ 0.9, + /* hbool_t apply_max_decrement = */ TRUE, + /* size_t max_decrement = */ (1 * 1024 * 1024), + /* int epochs_before_eviction = */ 3, + /* hbool_t apply_empty_reserve = */ TRUE, + /* double empty_reserve = */ 0.1, + /* int dirty_bytes_threshold = */ (H5C__MAX_MAX_CACHE_SIZE / 4) + 1 + } +}; + + +/*------------------------------------------------------------------------- + * Function: check_fapl_mdc_api_errs() + * + * Purpose: Verify that the FAPL related MDC API calls reject input + * errors gracefully. + * + * Return: void + * + * Programmer: John Mainzer + * 4/19/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static void +check_fapl_mdc_api_errs(void) +{ + const char * fcn_name = "check_fapl_mdc_api_errs()"; + static char msg[128]; + int i; + herr_t result; + hid_t fapl_id; + H5AC_cache_config_t default_config = H5AC__DEFAULT_CACHE_CONFIG; + H5AC_cache_config_t scratch; + + TESTING("MDC/FAPL related API input errors"); + + pass = TRUE; + + + /* first test H5Pget_mdc_config(). + */ + + scratch.version = H5C__CURR_AUTO_SIZE_CTL_VER; + if ( pass ) { + + H5E_BEGIN_TRY { result = H5Pget_mdc_config(-1, &scratch); } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "H5Pget_mdc_config() accepted invalid plist_id."; + } + } + + /* Create a FAPL for test purposes, and veify that it contains the + * default MDC configuration. + */ + + if ( pass ) { + + fapl_id = H5Pcreate(H5P_FILE_ACCESS); + + if ( fapl_id < 0 ) { + + pass = FALSE; + failure_mssg = "H5Pcreate(H5P_FILE_ACCESS) failed.\n"; + } + } + + scratch.version = H5C__CURR_AUTO_SIZE_CTL_VER; + if ( ( pass ) && + ( ( H5Pget_mdc_config(fapl_id, &scratch) < 0 ) || + ( !CACHE_CONFIGS_EQUAL(default_config, scratch, TRUE, TRUE) ) ) ) { + + pass = FALSE; + failure_mssg = "New FAPL has unexpected metadata cache config?!?!?.\n"; + } + + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5Pget_mdc_config(fapl_id, NULL); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "H5Pget_mdc_config() accepted NULL config_ptr."; + } + } + + /* one last test for H5Pget_mdc_config() */ + + scratch.version = -1; /* a convenient, invalid value */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5Pget_mdc_config(fapl_id, &scratch); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "H5Pget_mdc_config() accepted bad config version."; + } + } + + + /* now test H5Pset_mdc_config() + */ + + scratch.version = H5C__CURR_AUTO_SIZE_CTL_VER; + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5Pset_mdc_config(-1, &default_config); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_mdc_config() accepted bad invalid plist_id."; + } + } + + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5Pset_mdc_config(fapl_id, NULL); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "H5Pset_mdc_config() accepted NULL config_ptr."; + } + } + + i = 0; + while ( ( pass ) && ( i < NUM_INVALID_CONFIGS ) ) + { + H5E_BEGIN_TRY { + result = H5Pset_mdc_config(fapl_id, &(invalid_configs[i])); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + HDsnprintf(msg, (size_t)128, + "H5Pset_mdc_config() accepted invalid_configs[%d].", i); + failure_mssg = msg; + } + i++; + } + + /* verify that none of the above calls to H5Pset_mdc_config() changed + * the configuration in the FAPL. + */ + scratch.version = H5C__CURR_AUTO_SIZE_CTL_VER; + if ( ( pass ) && + ( ( H5Pget_mdc_config(fapl_id, &scratch) < 0 ) || + ( !CACHE_CONFIGS_EQUAL(default_config, scratch, TRUE, TRUE) ) ) ) { + + pass = FALSE; + failure_mssg = "FAPL metadata cache config changed???.\n"; + } + + if ( pass ) { PASSED(); } else { H5_FAILED(); } + + if ( ! pass ) + HDfprintf(stdout, "%s: failure_mssg = \"%s\".\n", + fcn_name, failure_mssg); + +} /* check_fapl_mdc_api_errs() */ + + +/*------------------------------------------------------------------------- + * Function: check_file_mdc_api_errs() + * + * Purpose: Verify that the file related MDC API calls reject input + * errors gracefully. + * + * Return: void + * + * Programmer: John Mainzer + * 4/19/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +static void +check_file_mdc_api_errs(void) +{ + const char * fcn_name = "check_file_mdc_api_errs()"; + char filename[512]; + static char msg[128]; + int i; + herr_t result; + hid_t file_id; + size_t max_size; + size_t min_clean_size; + size_t cur_size; + int cur_num_entries; + double hit_rate; + H5AC_cache_config_t default_config = H5AC__DEFAULT_CACHE_CONFIG; + H5AC_cache_config_t scratch; + + TESTING("MDC/FILE related API input errors"); + + pass = TRUE; + + /* Create a file for test purposes, and veify that its metadata cache + * set to the default MDC configuration. + */ + + /* setup the file name */ + if ( pass ) { + + if ( h5_fixname(FILENAME[0], H5P_DEFAULT, filename, sizeof(filename)) + == NULL ) { + + pass = FALSE; + failure_mssg = "h5_fixname() failed.\n"; + } + } + + if ( pass ) { + + file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + if ( file_id < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fcreate() failed.\n"; + } + } + + validate_mdc_config(file_id, &default_config, TRUE, 1); + + + /* test H5Fget_mdc_config(). */ + + scratch.version = H5C__CURR_AUTO_SIZE_CTL_VER; + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5Fget_mdc_config(-1, &scratch); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "H5Fget_mdc_config() accepted invalid file_id."; + } + } + + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5Fget_mdc_config(file_id, NULL); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "H5Fget_mdc_config() accepted NULL config_ptr."; + } + } + + scratch.version = -1; /* a convenient, invalid value */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5Fget_mdc_config(file_id, &scratch); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "H5Fget_mdc_config() accepted bad config version."; + } + } + + + /* test H5Fset_mdc_config() */ + + scratch.version = H5C__CURR_AUTO_SIZE_CTL_VER; + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5Fset_mdc_config(-1, &default_config); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "H5Fset_mdc_config() accepted bad invalid file_id."; + } + } + + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5Fset_mdc_config(file_id, NULL); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "H5Fset_mdc_config() accepted NULL config_ptr."; + } + } + + i = 0; + while ( ( pass ) && ( i < NUM_INVALID_CONFIGS ) ) + { + H5E_BEGIN_TRY { + result = H5Fset_mdc_config(file_id, &(invalid_configs[i])); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + HDsnprintf(msg, (size_t)128, + "H5Fset_mdc_config() accepted invalid_configs[%d].", i); + failure_mssg = msg; + } + i++; + } + + /* verify that none of the above calls to H5Fset_mdc_config() changed + * the configuration in the FAPL. + */ + validate_mdc_config(file_id, &default_config, TRUE, 2); + + + /* test H5Fget_mdc_hit_rate() */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5Fget_mdc_hit_rate(-1, &hit_rate); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "H5Fget_mdc_hit_rate() accepted bad file_id."; + } + } + + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5Fget_mdc_hit_rate(file_id, NULL); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "H5Fget_mdc_hit_rate() accepted NULL hit_rate_ptr."; + } + } + + + /* test H5Freset_mdc_hit_rate_stats() */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5Freset_mdc_hit_rate_stats(-1); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = + "H5Freset_mdc_hit_rate_stats() accepted bad file_id."; + } + } + + + /* test H5Fget_mdc_size() */ + if ( pass ) { + + H5E_BEGIN_TRY { + result = H5Fget_mdc_size(-1, &max_size, &min_clean_size, + &cur_size, &cur_num_entries); + } H5E_END_TRY; + + if ( result >= 0 ) { + + pass = FALSE; + failure_mssg = "H5Fget_mdc_size() accepted bad file_id."; + } + } + + if ( pass ) { + + if ( ( H5Fget_mdc_size(file_id, &max_size, NULL, NULL, NULL) < 0 ) || + ( H5Fget_mdc_size(file_id, NULL, &min_clean_size, + NULL, NULL) < 0 ) || + ( H5Fget_mdc_size(file_id, NULL, NULL, &cur_size, NULL) < 0 ) || + ( H5Fget_mdc_size(file_id, NULL, NULL, NULL, + &cur_num_entries) < 0 ) || + ( H5Fget_mdc_size(file_id, NULL, NULL, NULL, NULL) < 0 ) ) { + + pass = FALSE; + failure_mssg = "H5Fget_mdc_size() failed to handle NULL params."; + } + } + + + /* close the file and delete it */ + if ( pass ) { + + if ( H5Fclose(file_id) < 0 ) { + + pass = FALSE; + failure_mssg = "H5Fclose() failed.\n"; + + } else if ( HDremove(filename) < 0 ) { + + pass = FALSE; + failure_mssg = "HDremove() failed.\n"; + } + } + + if ( pass ) { PASSED(); } else { H5_FAILED(); } + + if ( ! pass ) + HDfprintf(stdout, "%s: failure_mssg = \"%s\".\n", + fcn_name, failure_mssg); + +} /* check_file_mdc_api_errs() */ + + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: Run tests on the cache code contained in H5C.c + * + * Return: Success: + * + * Failure: + * + * Programmer: John Mainzer + * 6/24/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +int +main(void) +{ + H5open(); + + skip_long_tests = FALSE; + +#ifdef NDEBUG + run_full_test = TRUE; +#else /* NDEBUG */ + run_full_test = FALSE; +#endif /* NDEBUG */ + +#if 1 + check_fapl_mdc_api_calls(); + check_file_mdc_api_calls(); +#endif + mdc_api_call_smoke_check(); +#if 1 + check_fapl_mdc_api_errs(); + check_file_mdc_api_errs(); +#endif + + return(0); + +} /* main() */ diff --git a/test/cache_common.c b/test/cache_common.c new file mode 100644 index 0000000..c87fb7f --- /dev/null +++ b/test/cache_common.c @@ -0,0 +1,2878 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* Programmer: John Mainzer + * 10/27/05 + * + * This file contains common code for tests of the cache + * implemented in H5C.c + */ +#include "h5test.h" +#include "H5Iprivate.h" +#include "H5ACprivate.h" +#include "cache_common.h" + + +/* global variable declarations: */ + +hbool_t write_permitted = TRUE; +hbool_t pass = TRUE; /* set to false on error */ +hbool_t skip_long_tests = TRUE; +hbool_t run_full_test = TRUE; +const char *failure_mssg = NULL; + +test_entry_t pico_entries[NUM_PICO_ENTRIES]; +test_entry_t nano_entries[NUM_NANO_ENTRIES]; +test_entry_t micro_entries[NUM_MICRO_ENTRIES]; +test_entry_t tiny_entries[NUM_TINY_ENTRIES]; +test_entry_t small_entries[NUM_SMALL_ENTRIES]; +test_entry_t medium_entries[NUM_MEDIUM_ENTRIES]; +test_entry_t large_entries[NUM_LARGE_ENTRIES]; +test_entry_t huge_entries[NUM_HUGE_ENTRIES]; +test_entry_t monster_entries[NUM_MONSTER_ENTRIES]; + +test_entry_t * entries[NUMBER_OF_ENTRY_TYPES] = +{ + pico_entries, + nano_entries, + micro_entries, + tiny_entries, + small_entries, + medium_entries, + large_entries, + huge_entries, + monster_entries +}; + +const int32_t max_indices[NUMBER_OF_ENTRY_TYPES] = +{ + NUM_PICO_ENTRIES - 1, + NUM_NANO_ENTRIES - 1, + NUM_MICRO_ENTRIES - 1, + NUM_TINY_ENTRIES - 1, + NUM_SMALL_ENTRIES - 1, + NUM_MEDIUM_ENTRIES - 1, + NUM_LARGE_ENTRIES - 1, + NUM_HUGE_ENTRIES - 1, + NUM_MONSTER_ENTRIES - 1 +}; + +const size_t entry_sizes[NUMBER_OF_ENTRY_TYPES] = +{ + PICO_ENTRY_SIZE, + NANO_ENTRY_SIZE, + MICRO_ENTRY_SIZE, + TINY_ENTRY_SIZE, + SMALL_ENTRY_SIZE, + MEDIUM_ENTRY_SIZE, + LARGE_ENTRY_SIZE, + HUGE_ENTRY_SIZE, + MONSTER_ENTRY_SIZE +}; + +const haddr_t base_addrs[NUMBER_OF_ENTRY_TYPES] = +{ + PICO_BASE_ADDR, + NANO_BASE_ADDR, + MICRO_BASE_ADDR, + TINY_BASE_ADDR, + SMALL_BASE_ADDR, + MEDIUM_BASE_ADDR, + LARGE_BASE_ADDR, + HUGE_BASE_ADDR, + MONSTER_BASE_ADDR +}; + +const haddr_t alt_base_addrs[NUMBER_OF_ENTRY_TYPES] = +{ + PICO_ALT_BASE_ADDR, + NANO_ALT_BASE_ADDR, + MICRO_ALT_BASE_ADDR, + TINY_ALT_BASE_ADDR, + SMALL_ALT_BASE_ADDR, + MEDIUM_ALT_BASE_ADDR, + LARGE_ALT_BASE_ADDR, + HUGE_ALT_BASE_ADDR, + MONSTER_ALT_BASE_ADDR +}; + +const char * entry_type_names[NUMBER_OF_ENTRY_TYPES] = +{ + "pico entries -- 1 B", + "nano entries -- 4 B", + "micro entries -- 16 B", + "tiny entries -- 64 B", + "small entries -- 256 B", + "medium entries -- 1 KB", + "large entries -- 4 KB", + "huge entries -- 16 KB", + "monster entries -- 64 KB" +}; + + +/* callback table declaration */ + +const H5C_class_t types[NUMBER_OF_ENTRY_TYPES] = +{ + { + PICO_ENTRY_TYPE, + (H5C_load_func_t)pico_load, + (H5C_flush_func_t)pico_flush, + (H5C_dest_func_t)pico_dest, + (H5C_clear_func_t)pico_clear, + (H5C_size_func_t)pico_size + }, + { + NANO_ENTRY_TYPE, + (H5C_load_func_t)nano_load, + (H5C_flush_func_t)nano_flush, + (H5C_dest_func_t)nano_dest, + (H5C_clear_func_t)nano_clear, + (H5C_size_func_t)nano_size + }, + { + MICRO_ENTRY_TYPE, + (H5C_load_func_t)micro_load, + (H5C_flush_func_t)micro_flush, + (H5C_dest_func_t)micro_dest, + (H5C_clear_func_t)micro_clear, + (H5C_size_func_t)micro_size + }, + { + TINY_ENTRY_TYPE, + (H5C_load_func_t)tiny_load, + (H5C_flush_func_t)tiny_flush, + (H5C_dest_func_t)tiny_dest, + (H5C_clear_func_t)tiny_clear, + (H5C_size_func_t)tiny_size + }, + { + SMALL_ENTRY_TYPE, + (H5C_load_func_t)small_load, + (H5C_flush_func_t)small_flush, + (H5C_dest_func_t)small_dest, + (H5C_clear_func_t)small_clear, + (H5C_size_func_t)small_size + }, + { + MEDIUM_ENTRY_TYPE, + (H5C_load_func_t)medium_load, + (H5C_flush_func_t)medium_flush, + (H5C_dest_func_t)medium_dest, + (H5C_clear_func_t)medium_clear, + (H5C_size_func_t)medium_size + }, + { + LARGE_ENTRY_TYPE, + (H5C_load_func_t)large_load, + (H5C_flush_func_t)large_flush, + (H5C_dest_func_t)large_dest, + (H5C_clear_func_t)large_clear, + (H5C_size_func_t)large_size + }, + { + HUGE_ENTRY_TYPE, + (H5C_load_func_t)huge_load, + (H5C_flush_func_t)huge_flush, + (H5C_dest_func_t)huge_dest, + (H5C_clear_func_t)huge_clear, + (H5C_size_func_t)huge_size + }, + { + MONSTER_ENTRY_TYPE, + (H5C_load_func_t)monster_load, + (H5C_flush_func_t)monster_flush, + (H5C_dest_func_t)monster_dest, + (H5C_clear_func_t)monster_clear, + (H5C_size_func_t)monster_size + } +}; + +static herr_t clear(H5F_t * f, void * thing, hbool_t dest); +static herr_t destroy(H5F_t UNUSED * f, void * thing); +static herr_t flush(H5F_t *f, hid_t UNUSED dxpl_id, hbool_t dest, + haddr_t addr, void *thing); +static void * load(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, haddr_t addr, + const void UNUSED *udata1, void UNUSED *udata2); +static herr_t size(H5F_t UNUSED * f, void * thing, size_t * size_ptr); + + + +/* address translation funtions: */ + +/*------------------------------------------------------------------------- + * Function: addr_to_type_and_index + * + * Purpose: Given an address, compute the type and index of the + * associated entry. + * + * Return: void + * + * Programmer: John Mainzer + * 6/10/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +void +addr_to_type_and_index(haddr_t addr, + int32_t * type_ptr, + int32_t * index_ptr) +{ + int i; + int32_t type; + int32_t idx; + + HDassert( type_ptr ); + HDassert( index_ptr ); + + /* we only have a small number of entry types, so just do a + * linear search. If NUMBER_OF_ENTRY_TYPES grows, we may want + * to do a binary search instead. + */ + i = 1; + if ( addr >= PICO_ALT_BASE_ADDR ) { + + while ( ( i < NUMBER_OF_ENTRY_TYPES ) && + ( addr >= alt_base_addrs[i] ) ) + { + i++; + } + + } else { + + while ( ( i < NUMBER_OF_ENTRY_TYPES ) && + ( addr >= base_addrs[i] ) ) + { + i++; + } + } + + type = i - 1; + + HDassert( ( type >= 0 ) && ( type < NUMBER_OF_ENTRY_TYPES ) ); + + if ( addr >= PICO_ALT_BASE_ADDR ) { + + idx = (addr - alt_base_addrs[type]) / entry_sizes[type]; + HDassert( !((entries[type])[idx].at_main_addr) ); + HDassert( addr == (entries[type])[idx].alt_addr ); + + } else { + + idx = (addr - base_addrs[type]) / entry_sizes[type]; + HDassert( (entries[type])[idx].at_main_addr ); + HDassert( addr == (entries[type])[idx].main_addr ); + } + + HDassert( ( idx >= 0 ) && ( idx <= max_indices[type] ) ); + + HDassert( addr == (entries[type])[idx].addr ); + + *type_ptr = type; + *index_ptr = idx; + + return; + +} /* addr_to_type_and_index() */ + + +#if 0 /* This function has never been used, but we may want it + * some time. Lets keep it for now. + */ +/*------------------------------------------------------------------------- + * Function: type_and_index_to_addr + * + * Purpose: Given a type and index of an entry, compute the associated + * addr and return that value. + * + * Return: computed addr + * + * Programmer: John Mainzer + * 6/10/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +haddr_t +type_and_index_to_addr(int32_t type, + int32_t idx) +{ + haddr_t addr; + + HDassert( ( type >= 0 ) && ( type < NUMBER_OF_ENTRY_TYPES ) ); + HDassert( ( idx >= 0 ) && ( idx <= max_indices[type] ) ); + + addr = base_addrs[type] + (((haddr_t)idx) * entry_sizes[type]); + + HDassert( addr == (entries[type])[idx].addr ); + + if ( (entries[type])[idx].at_main_addr ) { + + HDassert( addr == (entries[type])[idx].main_addr ); + + } else { + + HDassert( addr == (entries[type])[idx].alt_addr ); + } + + return(addr); + +} /* type_and_index_to_addr() */ + +#endif + + +/* Call back functions: */ + +/*------------------------------------------------------------------------- + * + * Function: H5AC_check_if_write_permitted + * + * Purpose: Determine if a write is permitted under the current + * circumstances, and set *write_permitted_ptr accordingly. + * As a general rule it is, but when we are running in parallel + * mode with collective I/O, we must ensure that a read cannot + * cause a write. + * + * In the event of failure, the value of *write_permitted_ptr + * is undefined. + * + * Return: Non-negative on success/Negative on failure. + * + * Programmer: John Mainzer, 5/15/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t +check_write_permitted(const H5F_t UNUSED * f, + hid_t UNUSED dxpl_id, + hbool_t * write_permitted_ptr) +{ + + HDassert( write_permitted_ptr ); + *write_permitted_ptr = write_permitted; + + return(SUCCEED); + +} /* check_write_permitted() */ + + +/*------------------------------------------------------------------------- + * Function: clear & friends + * + * Purpose: clear the entry. The helper functions verify that the + * correct version of clear is being called, and then call + * clear proper. + * + * Return: SUCCEED + * + * Programmer: John Mainzer + * 6/10/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t +clear(H5F_t * f, + void * thing, + hbool_t dest) +{ + test_entry_t * entry_ptr; + test_entry_t * base_addr; + + HDassert( thing ); + + entry_ptr = (test_entry_t *)thing; + base_addr = entries[entry_ptr->type]; + + HDassert( entry_ptr->index >= 0 ); + HDassert( entry_ptr->index <= max_indices[entry_ptr->type] ); + HDassert( entry_ptr == &(base_addr[entry_ptr->index]) ); + HDassert( entry_ptr == entry_ptr->self ); + HDassert( entry_ptr->header.addr == entry_ptr->addr ); + HDassert( entry_ptr->header.size == entry_ptr->size ); + HDassert( entry_ptr->size == entry_sizes[entry_ptr->type] ); + + entry_ptr->header.is_dirty = FALSE; + entry_ptr->is_dirty = FALSE; + + entry_ptr->cleared = TRUE; + + if ( dest ) { + + destroy(f, thing); + + } + + return(SUCCEED); + +} /* clear() */ + +herr_t +pico_clear(H5F_t * f, void * thing, hbool_t dest) +{ + HDassert ( ((test_entry_t *)thing)->type == PICO_ENTRY_TYPE ); + return(clear(f, thing, dest)); +} + +herr_t +nano_clear(H5F_t * f, void * thing, hbool_t dest) +{ + HDassert ( ((test_entry_t *)thing)->type == NANO_ENTRY_TYPE ); + return(clear(f, thing, dest)); +} + +herr_t +micro_clear(H5F_t * f, void * thing, hbool_t dest) +{ + HDassert ( ((test_entry_t *)thing)->type == MICRO_ENTRY_TYPE ); + return(clear(f, thing, dest)); +} + +herr_t +tiny_clear(H5F_t * f, void * thing, hbool_t dest) +{ + HDassert ( ((test_entry_t *)thing)->type == TINY_ENTRY_TYPE ); + return(clear(f, thing, dest)); +} + +herr_t +small_clear(H5F_t * f, void * thing, hbool_t dest) +{ + HDassert ( ((test_entry_t *)thing)->type == SMALL_ENTRY_TYPE ); + return(clear(f, thing, dest)); +} + +herr_t +medium_clear(H5F_t * f, void * thing, hbool_t dest) +{ + HDassert ( ((test_entry_t *)thing)->type == MEDIUM_ENTRY_TYPE ); + return(clear(f, thing, dest)); +} + +herr_t +large_clear(H5F_t * f, void * thing, hbool_t dest) +{ + HDassert ( ((test_entry_t *)thing)->type == LARGE_ENTRY_TYPE ); + return(clear(f, thing, dest)); +} + +herr_t +huge_clear(H5F_t * f, void * thing, hbool_t dest) +{ + HDassert ( ((test_entry_t *)thing)->type == HUGE_ENTRY_TYPE ); + return(clear(f, thing, dest)); +} + +herr_t +monster_clear(H5F_t * f, void * thing, hbool_t dest) +{ + HDassert ( ((test_entry_t *)thing)->type == MONSTER_ENTRY_TYPE ); + return(clear(f, thing, dest)); +} + + +/*------------------------------------------------------------------------- + * Function: dest & friends + * + * Purpose: Destroy the entry. The helper functions verify that the + * correct version of dest is being called, and then call + * dest proper. + * + * Return: SUCCEED + * + * Programmer: John Mainzer + * 6/10/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t +destroy(H5F_t UNUSED * f, + void * thing) +{ + test_entry_t * entry_ptr; + test_entry_t * base_addr; + + HDassert( thing ); + + entry_ptr = (test_entry_t *)thing; + base_addr = entries[entry_ptr->type]; + + HDassert ( entry_ptr->index >= 0 ); + HDassert ( entry_ptr->index <= max_indices[entry_ptr->type] ); + HDassert( entry_ptr == &(base_addr[entry_ptr->index]) ); + HDassert( entry_ptr == entry_ptr->self ); + HDassert( entry_ptr->header.addr == entry_ptr->addr ); + HDassert( entry_ptr->header.size == entry_ptr->size ); + HDassert( entry_ptr->size == entry_sizes[entry_ptr->type] ); + + HDassert( !(entry_ptr->is_dirty) ); + HDassert( !(entry_ptr->header.is_dirty) ); + + entry_ptr->destroyed = TRUE; + + return(SUCCEED); + +} /* dest() */ + +herr_t +pico_dest(H5F_t * f, void * thing) +{ + HDassert ( ((test_entry_t *)thing)->type == PICO_ENTRY_TYPE ); + return(destroy(f, thing)); +} + +herr_t +nano_dest(H5F_t * f, void * thing) +{ + HDassert ( ((test_entry_t *)thing)->type == NANO_ENTRY_TYPE ); + return(destroy(f, thing)); +} + +herr_t +micro_dest(H5F_t * f, void * thing) +{ + HDassert ( ((test_entry_t *)thing)->type == MICRO_ENTRY_TYPE ); + return(destroy(f, thing)); +} + +herr_t +tiny_dest(H5F_t * f, void * thing) +{ + HDassert ( ((test_entry_t *)thing)->type == TINY_ENTRY_TYPE ); + return(destroy(f, thing)); +} + +herr_t +small_dest(H5F_t * f, void * thing) +{ + HDassert ( ((test_entry_t *)thing)->type == SMALL_ENTRY_TYPE ); + return(destroy(f, thing)); +} + +herr_t +medium_dest(H5F_t * f, void * thing) +{ + HDassert ( ((test_entry_t *)thing)->type == MEDIUM_ENTRY_TYPE ); + return(destroy(f, thing)); +} + +herr_t +large_dest(H5F_t * f, void * thing) +{ + HDassert ( ((test_entry_t *)thing)->type == LARGE_ENTRY_TYPE ); + return(destroy(f, thing)); +} + +herr_t +huge_dest(H5F_t * f, void * thing) +{ + HDassert ( ((test_entry_t *)thing)->type == HUGE_ENTRY_TYPE ); + return(destroy(f, thing)); +} + +herr_t +monster_dest(H5F_t * f, void * thing) +{ + HDassert ( ((test_entry_t *)thing)->type == MONSTER_ENTRY_TYPE ); + return(destroy(f, thing)); +} + + +/*------------------------------------------------------------------------- + * Function: flush & friends + * + * Purpose: flush the entry and mark it as clean. The helper functions + * verify that the correct version of flush is being called, + * and then call flush proper. + * + * Return: SUCCEED + * + * Programmer: John Mainzer + * 6/10/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t +flush(H5F_t *f, + hid_t UNUSED dxpl_id, + hbool_t dest, + haddr_t addr, + void *thing) +{ + test_entry_t * entry_ptr; + test_entry_t * base_addr; + + HDassert( thing ); + + entry_ptr = (test_entry_t *)thing; + base_addr = entries[entry_ptr->type]; + + HDassert( entry_ptr->index >= 0 ); + HDassert( entry_ptr->index <= max_indices[entry_ptr->type] ); + HDassert( entry_ptr == &(base_addr[entry_ptr->index]) ); + HDassert( entry_ptr == entry_ptr->self ); + HDassert( entry_ptr->header.addr == entry_ptr->addr ); + HDassert( entry_ptr->addr == addr ); + HDassert( entry_ptr->header.size == entry_ptr->size ); + HDassert( entry_ptr->size == entry_sizes[entry_ptr->type] ); + HDassert( entry_ptr->header.is_dirty == entry_ptr->is_dirty ); + + entry_ptr->flushed = TRUE; + + if ( ( ! write_permitted ) && ( entry_ptr->is_dirty ) ) { + + pass = FALSE; + failure_mssg = "called flush when write_permitted is FALSE."; + } + + if ( entry_ptr->is_dirty ) { + + (entry_ptr->writes)++; + entry_ptr->is_dirty = FALSE; + entry_ptr->header.is_dirty = FALSE; + } + + if ( dest ) { + + destroy(f, thing); + + } + + return(SUCCEED); + +} /* flush() */ + +herr_t +pico_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing) +{ + HDassert ( ((test_entry_t *)thing)->type == PICO_ENTRY_TYPE ); + return(flush(f, dxpl_id, dest, addr, thing)); +} + +herr_t +nano_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing) +{ + HDassert ( ((test_entry_t *)thing)->type == NANO_ENTRY_TYPE ); + return(flush(f, dxpl_id, dest, addr, thing)); +} + +herr_t +micro_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing) +{ + HDassert ( ((test_entry_t *)thing)->type == MICRO_ENTRY_TYPE ); + return(flush(f, dxpl_id, dest, addr, thing)); +} + +herr_t +tiny_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing) +{ + HDassert ( ((test_entry_t *)thing)->type == TINY_ENTRY_TYPE ); + return(flush(f, dxpl_id, dest, addr, thing)); +} + +herr_t +small_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing) +{ + HDassert ( ((test_entry_t *)thing)->type == SMALL_ENTRY_TYPE ); + return(flush(f, dxpl_id, dest, addr, thing)); +} + +herr_t +medium_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing) +{ + HDassert ( ((test_entry_t *)thing)->type == MEDIUM_ENTRY_TYPE ); + return(flush(f, dxpl_id, dest, addr, thing)); +} + +herr_t +large_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing) +{ + HDassert ( ((test_entry_t *)thing)->type == LARGE_ENTRY_TYPE ); + return(flush(f, dxpl_id, dest, addr, thing)); +} + +herr_t +huge_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing) +{ + HDassert ( ((test_entry_t *)thing)->type == HUGE_ENTRY_TYPE ); + return(flush(f, dxpl_id, dest, addr, thing)); +} + +herr_t +monster_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, void *thing) +{ + HDassert ( ((test_entry_t *)thing)->type == MONSTER_ENTRY_TYPE ); + return(flush(f, dxpl_id, dest, addr, thing)); +} + + +/*------------------------------------------------------------------------- + * Function: load & friends + * + * Purpose: "load" the requested entry and mark it as clean. The + * helper functions verify that the correct version of load + * is being called, and then call load proper. + * + * Return: SUCCEED + * + * Programmer: John Mainzer + * 6/10/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void * +load(H5F_t UNUSED *f, + hid_t UNUSED dxpl_id, + haddr_t addr, + const void UNUSED *udata1, + void UNUSED *udata2) +{ + int32_t type; + int32_t idx; + test_entry_t * entry_ptr; + test_entry_t * base_addr; + + addr_to_type_and_index(addr, &type, &idx); + + base_addr = entries[type]; + entry_ptr = &(base_addr[idx]); + + HDassert( entry_ptr->type == type ); + HDassert( entry_ptr->type >= 0 ); + HDassert( entry_ptr->type < NUMBER_OF_ENTRY_TYPES ); + HDassert( entry_ptr->index == idx ); + HDassert( entry_ptr->index >= 0 ); + HDassert( entry_ptr->index <= max_indices[type] ); + HDassert( entry_ptr == entry_ptr->self ); + HDassert( entry_ptr->addr == addr ); + HDassert( entry_ptr->size == entry_sizes[type] ); + + entry_ptr->loaded = TRUE; + + entry_ptr->header.is_dirty = FALSE; + entry_ptr->is_dirty = FALSE; + + (entry_ptr->reads)++; + + return(entry_ptr); + +} /* load() */ + +void * +pico_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2) +{ + return(load(f, dxpl_id, addr, udata1, udata2)); +} + +void * +nano_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2) +{ + return(load(f, dxpl_id, addr, udata1, udata2)); +} + +void * +micro_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2) +{ + return(load(f, dxpl_id, addr, udata1, udata2)); +} + +void * +tiny_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2) +{ + return(load(f, dxpl_id, addr, udata1, udata2)); +} + +void * +small_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2) +{ + return(load(f, dxpl_id, addr, udata1, udata2)); +} + +void * +medium_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2) +{ + return(load(f, dxpl_id, addr, udata1, udata2)); +} + +void * +large_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2) +{ + return(load(f, dxpl_id, addr, udata1, udata2)); +} + +void * +huge_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2) +{ + return(load(f, dxpl_id, addr, udata1, udata2)); +} + +void * +monster_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2) +{ + return(load(f, dxpl_id, addr, udata1, udata2)); +} + + +/*------------------------------------------------------------------------- + * Function: size & friends + * + * Purpose: Get the size of the specified entry. The helper functions + * verify that the correct version of size is being called, + * and then call size proper. + * + * Return: SUCCEED + * + * Programmer: John Mainzer + * 6/10/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t +size(H5F_t UNUSED * f, + void * thing, + size_t * size_ptr) +{ + test_entry_t * entry_ptr; + test_entry_t * base_addr; + + HDassert( size_ptr ); + HDassert( thing ); + + entry_ptr = (test_entry_t *)thing; + base_addr = entries[entry_ptr->type]; + + HDassert( entry_ptr->index >= 0 ); + HDassert( entry_ptr->index <= max_indices[entry_ptr->type] ); + HDassert( entry_ptr == &(base_addr[entry_ptr->index]) ); + HDassert( entry_ptr == entry_ptr->self ); + HDassert( entry_ptr->header.addr == entry_ptr->addr ); + HDassert( entry_ptr->size == entry_sizes[entry_ptr->type] ); + + *size_ptr = entry_ptr->size; + + return(SUCCEED); + +} /* size() */ + +herr_t +pico_size(H5F_t * f, void * thing, size_t * size_ptr) +{ + HDassert ( ((test_entry_t *)thing)->type == PICO_ENTRY_TYPE ); + return(size(f, thing, size_ptr)); +} + +herr_t +nano_size(H5F_t * f, void * thing, size_t * size_ptr) +{ + HDassert ( ((test_entry_t *)thing)->type == NANO_ENTRY_TYPE ); + return(size(f, thing, size_ptr)); +} + +herr_t +micro_size(H5F_t * f, void * thing, size_t * size_ptr) +{ + HDassert ( ((test_entry_t *)thing)->type == MICRO_ENTRY_TYPE ); + return(size(f, thing, size_ptr)); +} + +herr_t +tiny_size(H5F_t * f, void * thing, size_t * size_ptr) +{ + HDassert ( ((test_entry_t *)thing)->type == TINY_ENTRY_TYPE ); + return(size(f, thing, size_ptr)); +} + +herr_t +small_size(H5F_t * f, void * thing, size_t * size_ptr) +{ + HDassert ( ((test_entry_t *)thing)->type == SMALL_ENTRY_TYPE ); + return(size(f, thing, size_ptr)); +} + +herr_t +medium_size(H5F_t * f, void * thing, size_t * size_ptr) +{ + HDassert ( ((test_entry_t *)thing)->type == MEDIUM_ENTRY_TYPE ); + return(size(f, thing, size_ptr)); +} + +herr_t +large_size(H5F_t * f, void * thing, size_t * size_ptr) +{ + HDassert ( ((test_entry_t *)thing)->type == LARGE_ENTRY_TYPE ); + return(size(f, thing, size_ptr)); +} + +herr_t +huge_size(H5F_t * f, void * thing, size_t * size_ptr) +{ + HDassert ( ((test_entry_t *)thing)->type == HUGE_ENTRY_TYPE ); + return(size(f, thing, size_ptr)); +} + +herr_t +monster_size(H5F_t * f, void * thing, size_t * size_ptr) +{ + HDassert ( ((test_entry_t *)thing)->type == MONSTER_ENTRY_TYPE ); + return(size(f, thing, size_ptr)); +} + + +/**************************************************************************/ +/**************************************************************************/ +/************************** test utility functions: ***********************/ +/**************************************************************************/ +/**************************************************************************/ + +/*------------------------------------------------------------------------- + * Function: entry_in_cache + * + * Purpose: Given a pointer to a cache, an entry type, and an index, + * determine if the entry is currently in the cache. + * + * Return: TRUE if the entry is in the cache, and FALSE otherwise. + * + * Programmer: John Mainzer + * 6/10/04 + * + * Modifications: + * + * JRM - 10/12/04 + * Removed references to local_H5C_t, as we now get direct + * access to the definition of H5C_t via H5Cpkg.h. + * + *------------------------------------------------------------------------- + */ + +hbool_t +entry_in_cache(H5C_t * cache_ptr, + int32_t type, + int32_t idx) +{ + hbool_t in_cache = FALSE; /* will set to TRUE if necessary */ + test_entry_t * base_addr; + test_entry_t * entry_ptr; + H5C_cache_entry_t * test_ptr = NULL; + + HDassert( cache_ptr ); + HDassert( ( 0 <= type ) && ( type < NUMBER_OF_ENTRY_TYPES ) ); + HDassert( ( 0 <= idx ) && ( idx <= max_indices[type] ) ); + + base_addr = entries[type]; + entry_ptr = &(base_addr[idx]); + + HDassert( entry_ptr->index == idx ); + HDassert( entry_ptr->type == type ); + HDassert( entry_ptr == entry_ptr->self ); + + H5C__SEARCH_INDEX(cache_ptr, entry_ptr->addr, test_ptr) + + if ( test_ptr != NULL ) { + + in_cache = TRUE; + HDassert( test_ptr == (H5C_cache_entry_t *)entry_ptr ); + HDassert( entry_ptr->addr == entry_ptr->header.addr ); + } + + return(in_cache); + +} /* entry_in_cache() */ + + +/*------------------------------------------------------------------------- + * Function: reset_entries + * + * Purpose: reset the contents of the entries arrays to know values. + * + * Return: void + * + * Programmer: John Mainzer + * 6/10/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void +reset_entries(void) + +{ + int i; + int j; + int32_t max_index; + haddr_t addr = 0; + haddr_t alt_addr = PICO_ALT_BASE_ADDR; + size_t entry_size; + test_entry_t * base_addr; + + for ( i = 0; i < NUMBER_OF_ENTRY_TYPES; i++ ) + { + entry_size = entry_sizes[i]; + max_index = max_indices[i]; + base_addr = entries[i]; + + HDassert( base_addr ); + + for ( j = 0; j <= max_index; j++ ) + { + /* one can argue that we should fill the header with garbage. + * If this is desired, we can simply comment out the header + * initialization - the headers will be full of garbage soon + * enough. + */ + + base_addr[j].header.addr = (haddr_t)0; + base_addr[j].header.size = (size_t)0; + base_addr[j].header.type = NULL; + base_addr[j].header.is_dirty = FALSE; + base_addr[j].header.is_protected = FALSE; + base_addr[j].header.next = NULL; + base_addr[j].header.prev = NULL; + base_addr[j].header.aux_next = NULL; + base_addr[j].header.aux_prev = NULL; + + base_addr[j].self = &(base_addr[j]); + base_addr[j].addr = addr; + base_addr[j].at_main_addr = TRUE; + base_addr[j].main_addr = addr; + base_addr[j].alt_addr = alt_addr; + base_addr[j].size = entry_size; + base_addr[j].type = i; + base_addr[j].index = j; + base_addr[j].reads = 0; + base_addr[j].writes = 0; + base_addr[j].is_dirty = FALSE; + base_addr[j].is_protected = FALSE; + + base_addr[j].loaded = FALSE; + base_addr[j].cleared = FALSE; + base_addr[j].flushed = FALSE; + base_addr[j].destroyed = FALSE; + + addr += (haddr_t)entry_size; + alt_addr += (haddr_t)entry_size; + } + } + + return; + +} /* reset_entries() */ + + +/*------------------------------------------------------------------------- + * Function: verify_clean + * + * Purpose: Verify that all cache entries are marked as clean. If any + * are not, set pass to FALSE. + * + * Do nothing if pass is FALSE on entry. + * + * Return: void + * + * Programmer: John Mainzer + * 6/10/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void +verify_clean(void) + +{ + int i; + int j; + int dirty_count = 0; + int32_t max_index; + test_entry_t * base_addr; + + if ( pass ) { + + for ( i = 0; i < NUMBER_OF_ENTRY_TYPES; i++ ) + { + max_index = max_indices[i]; + base_addr = entries[i]; + + HDassert( base_addr ); + + for ( j = 0; j <= max_index; j++ ) + { + if ( ( base_addr[j].header.is_dirty ) || ( base_addr[j].is_dirty ) ) { + + dirty_count++; + } + } + } + + if ( dirty_count > 0 ) { + + pass = FALSE; + failure_mssg = "verify_clean() found dirty entry(s)."; + } + } + + return; + +} /* verify_clean() */ + + +/*------------------------------------------------------------------------- + * Function: verify_unprotected + * + * Purpose: Verify that no cache entries are marked as protected. If + * any are, set pass to FALSE. + * + * Do nothing if pass is FALSE on entry. + * + * Return: void + * + * Programmer: John Mainzer + * 6/10/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void +verify_unprotected(void) + +{ + int i; + int j; + int protected_count = 0; + int32_t max_index; + test_entry_t * base_addr; + + if ( pass ) { + + for ( i = 0; i < NUMBER_OF_ENTRY_TYPES; i++ ) + { + max_index = max_indices[i]; + base_addr = entries[i]; + + HDassert( base_addr ); + + for ( j = 0; j <= max_index; j++ ) + { + HDassert( base_addr[j].header.is_protected == + base_addr[j].is_protected ); + + if ( ( base_addr[j].header.is_protected ) || + ( base_addr[j].is_protected ) ) { + + protected_count++; + } + } + } + + if ( protected_count > 0 ) { + + pass = FALSE; + failure_mssg = "verify_unprotected() found protected entry(s)."; + } + } + + return; + +} /* verify_unprotected() */ + + +/*------------------------------------------------------------------------- + * Function: setup_cache() + * + * Purpose: Allocate a cache of the desired size and configure it for + * use in the test bed. Return a pointer to the new cache + * structure. + * + * Return: Pointer to new cache, or NULL on failure. + * + * Programmer: John Mainzer + * 6/11/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +H5C_t * +setup_cache(size_t max_cache_size, + size_t min_clean_size) +{ + H5C_t * cache_ptr = NULL; + + cache_ptr = H5C_create(max_cache_size, + min_clean_size, + (NUMBER_OF_ENTRY_TYPES - 1), + (const char **)entry_type_names, + check_write_permitted, + TRUE, + NULL, + NULL); + + if ( cache_ptr == NULL ) { + + pass = FALSE; + failure_mssg = "H5C_create() returned NULL."; + + } else { + + H5C_set_skip_flags(cache_ptr, TRUE, TRUE); + } + + return(cache_ptr); + +} /* setup_cache() */ + + +/*------------------------------------------------------------------------- + * Function: takedown_cache() + * + * Purpose: Flush the specified cache and disable it. If requested, + * dump stats first. If pass is FALSE, do nothing. + * + * Return: void + * + * Programmer: John Mainzer + * 6/11/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void +takedown_cache(H5C_t * cache_ptr, + hbool_t dump_stats, + hbool_t dump_detailed_stats) +{ + HDassert(cache_ptr); + + if ( pass ) { + + if ( dump_stats ) { + + H5C_stats(cache_ptr, "test cache", dump_detailed_stats); + } + + H5C_dest(NULL, -1, -1, cache_ptr); + } + + return; + +} /* takedown_cache() */ + + +/*------------------------------------------------------------------------- + * Function: flush_cache() + * + * Purpose: Flush the specified cache, destroying all entries if + requested. If requested, dump stats first. + * + * Return: void + * + * Programmer: John Mainzer + * 6/23/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void +flush_cache(H5C_t * cache_ptr, + hbool_t destroy_entries, + hbool_t dump_stats, + hbool_t dump_detailed_stats) +{ + herr_t result = 0; + + HDassert(cache_ptr); + + verify_unprotected(); + + if ( pass ) { + + if ( destroy_entries ) { + + result = H5C_flush_cache(NULL, -1, -1, cache_ptr, + H5C__FLUSH_INVALIDATE_FLAG); + + } else { + + result = H5C_flush_cache(NULL, -1, -1, cache_ptr, + H5C__NO_FLAGS_SET); + } + } + + if ( dump_stats ) { + + H5C_stats(cache_ptr, "test cache", dump_detailed_stats); + } + + if ( result < 0 ) { + + pass = FALSE; + failure_mssg = "error in H5C_flush_cache()."; + } + + return; + +} /* flush_cache() */ + + +/*------------------------------------------------------------------------- + * Function: insert_entry() + * + * Purpose: Insert the entry indicated by the type and index. Mark + * it clean or dirty as indicated. + * + * Note that I don't see much practical use for inserting + * a clean entry, but the interface permits it so we should + * test it. + * + * Do nothing if pass is false. + * + * Return: void + * + * Programmer: John Mainzer + * 6/16/04 + * + * Modifications: + * + * JRM -- 1/13/05 + * Updated function for the flags parameter in + * H5C_insert_entry(), and to allow access to this parameter. + * + * JRM -- 6/17/05 + * The interface no longer permits clean inserts. + * Accordingly, the dirty parameter is no longer meaningfull. + * + *------------------------------------------------------------------------- + */ + +void +insert_entry(H5C_t * cache_ptr, + int32_t type, + int32_t idx, + hbool_t UNUSED dirty, + unsigned int flags) +{ + herr_t result; + test_entry_t * base_addr; + test_entry_t * entry_ptr; + + if ( pass ) { + + HDassert( cache_ptr ); + HDassert( ( 0 <= type ) && ( type < NUMBER_OF_ENTRY_TYPES ) ); + HDassert( ( 0 <= idx ) && ( idx <= max_indices[type] ) ); + + base_addr = entries[type]; + entry_ptr = &(base_addr[idx]); + + HDassert( entry_ptr->index == idx ); + HDassert( entry_ptr->type == type ); + HDassert( entry_ptr == entry_ptr->self ); + HDassert( !(entry_ptr->is_protected) ); + + entry_ptr->is_dirty = TRUE; + + result = H5C_insert_entry(NULL, -1, -1, cache_ptr, &(types[type]), + entry_ptr->addr, (void *)entry_ptr, flags); + + if ( ( result < 0 ) || + ( entry_ptr->header.is_protected ) || + ( entry_ptr->header.type != &(types[type]) ) || + ( entry_ptr->size != entry_ptr->header.size ) || + ( entry_ptr->addr != entry_ptr->header.addr ) ) { + + pass = FALSE; + failure_mssg = "error in H5C_insert()."; + +#if 0 + /* This is useful debugging code. Lets keep it around. */ + + HDfprintf(stdout, "result = %d\n", (int)result); + HDfprintf(stdout, "entry_ptr->header.is_protected = %d\n", + (int)(entry_ptr->header.is_protected)); + HDfprintf(stdout, "entry_ptr->header.type != &(types[type]) = %d\n", + (int)(entry_ptr->header.type != &(types[type]))); + HDfprintf(stdout, + "entry_ptr->size != entry_ptr->header.size = %d\n", + (int)(entry_ptr->size != entry_ptr->header.size)); + HDfprintf(stdout, + "entry_ptr->addr != entry_ptr->header.addr = %d\n", + (int)(entry_ptr->addr != entry_ptr->header.addr)); +#endif + } + + HDassert( entry_ptr->header.is_dirty ); + HDassert( ((entry_ptr->header).type)->id == type ); + } + + return; + +} /* insert_entry() */ + + +/*------------------------------------------------------------------------- + * Function: rename_entry() + * + * Purpose: Rename the entry indicated by the type and index to its + * main or alternate address as indicated. If the entry is + * already at the desired entry, do nothing. + * + * Return: void + * + * Programmer: John Mainzer + * 6/21/04 + * + * Modifications: + * + * JRM -- 6/17/05 + * Updated code to reflect the fact that renames automatically + * dirty entries. + * + *------------------------------------------------------------------------- + */ + +void +rename_entry(H5C_t * cache_ptr, + int32_t type, + int32_t idx, + hbool_t main_addr) +{ + herr_t result; + hbool_t done = TRUE; /* will set to FALSE if we have work to do */ + haddr_t old_addr = HADDR_UNDEF; + haddr_t new_addr = HADDR_UNDEF; + test_entry_t * base_addr; + test_entry_t * entry_ptr; + + HDassert( cache_ptr ); + HDassert( ( 0 <= type ) && ( type < NUMBER_OF_ENTRY_TYPES ) ); + HDassert( ( 0 <= idx ) && ( idx <= max_indices[type] ) ); + + base_addr = entries[type]; + entry_ptr = &(base_addr[idx]); + + HDassert( entry_ptr->index == idx ); + HDassert( entry_ptr->type == type ); + HDassert( entry_ptr == entry_ptr->self ); + HDassert( !(entry_ptr->is_protected) ); + HDassert( !(entry_ptr->header.is_protected) ); + + if ( entry_ptr->at_main_addr && !main_addr ) { + + /* rename to alt addr */ + + HDassert( entry_ptr->addr == entry_ptr->main_addr ); + + done = FALSE; + old_addr = entry_ptr->addr; + new_addr = entry_ptr->alt_addr; + + } else if ( !(entry_ptr->at_main_addr) && main_addr ) { + + /* rename to main addr */ + + HDassert( entry_ptr->addr == entry_ptr->alt_addr ); + + done = FALSE; + old_addr = entry_ptr->addr; + new_addr = entry_ptr->main_addr; + } + + if ( ! done ) { + + entry_ptr->is_dirty = TRUE; + + result = H5C_rename_entry(cache_ptr, &(types[type]), + old_addr, new_addr); + } + + if ( ! done ) { + + if ( ( result < 0 ) || ( entry_ptr->header.addr != new_addr ) ) { + + pass = FALSE; + failure_mssg = "error in H5C_rename_entry()."; + + } else { + + entry_ptr->addr = new_addr; + entry_ptr->at_main_addr = main_addr; + } + } + + HDassert( ((entry_ptr->header).type)->id == type ); + + HDassert( entry_ptr->header.is_dirty ); + HDassert( entry_ptr->is_dirty ); + + return; + +} /* rename_entry() */ + + +/*------------------------------------------------------------------------- + * Function: protect_entry() + * + * Purpose: Protect the entry indicated by the type and index. + * + * Do nothing if pass is FALSE on entry. + * + * Return: void + * + * Programmer: John Mainzer + * 6/11/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void +protect_entry(H5C_t * cache_ptr, + int32_t type, + int32_t idx) +{ + /* const char * fcn_name = "protect_entry()"; */ + test_entry_t * base_addr; + test_entry_t * entry_ptr; + H5C_cache_entry_t * cache_entry_ptr; + + if ( pass ) { + + HDassert( cache_ptr ); + HDassert( ( 0 <= type ) && ( type < NUMBER_OF_ENTRY_TYPES ) ); + HDassert( ( 0 <= idx ) && ( idx <= max_indices[type] ) ); + + base_addr = entries[type]; + entry_ptr = &(base_addr[idx]); + + HDassert( entry_ptr->index == idx ); + HDassert( entry_ptr->type == type ); + HDassert( entry_ptr == entry_ptr->self ); + HDassert( !(entry_ptr->is_protected) ); + + cache_entry_ptr = H5C_protect(NULL, -1, -1, cache_ptr, &(types[type]), + entry_ptr->addr, NULL, NULL); + + if ( ( cache_entry_ptr != (void *)entry_ptr ) || + ( !(entry_ptr->header.is_protected) ) || + ( entry_ptr->header.type != &(types[type]) ) || + ( entry_ptr->size != entry_ptr->header.size ) || + ( entry_ptr->addr != entry_ptr->header.addr ) ) { + +#if 0 + /* I've written the following debugging code several times + * now. Lets keep it around so I don't have to write it + * again. + * - JRM + */ + HDfprintf(stdout, "( cache_entry_ptr != (void *)entry_ptr ) = %d\n", + (int)( cache_entry_ptr != (void *)entry_ptr )); + HDfprintf(stdout, "cache_entry_ptr = 0x%lx, entry_ptr = 0x%lx\n", + (long)cache_entry_ptr, (long)entry_ptr); + HDfprintf(stdout, "entry_ptr->header.is_protected = %d\n", + (int)(entry_ptr->header.is_protected)); + HDfprintf(stdout, + "( entry_ptr->header.type != &(types[type]) ) = %d\n", + (int)( entry_ptr->header.type != &(types[type]) )); + HDfprintf(stdout, + "entry_ptr->size = %d, entry_ptr->header.size = %d\n", + (int)(entry_ptr->size), (int)(entry_ptr->header.size)); + HDfprintf(stdout, + "entry_ptr->addr = %d, entry_ptr->header.addr = %d\n", + (int)(entry_ptr->addr), (int)(entry_ptr->header.addr)); +#endif + pass = FALSE; + failure_mssg = "error in H5C_protect()."; + + } else { + + entry_ptr->is_protected = TRUE; + + } + + HDassert( ((entry_ptr->header).type)->id == type ); + } + + return; + +} /* protect_entry() */ + + +/*------------------------------------------------------------------------- + * Function: unprotect_entry() + * + * Purpose: Unprotect the entry indicated by the type and index. + * + * Do nothing if pass is FALSE on entry. + * + * Return: void + * + * Programmer: John Mainzer + * 6/12/04 + * + * Modifications: + * + * JRM -- 1/7/05 + * Updated for the replacement of the deleted parameter in + * H5C_unprotect() with the new flags parameter. + * + * JRM - 6/17/05 + * Modified function to use the new dirtied parameter of + * H5C_unprotect(). + * + * JRM -- 9/8/05 + * Update for new entry size parameter in H5C_unprotect(). + * We don't use them here for now. + * + *------------------------------------------------------------------------- + */ + +void +unprotect_entry(H5C_t * cache_ptr, + int32_t type, + int32_t idx, + int dirty, + unsigned int flags) +{ + /* const char * fcn_name = "unprotect_entry()"; */ + herr_t result; + test_entry_t * base_addr; + test_entry_t * entry_ptr; + + if ( pass ) { + + HDassert( cache_ptr ); + HDassert( ( 0 <= type ) && ( type < NUMBER_OF_ENTRY_TYPES ) ); + HDassert( ( 0 <= idx ) && ( idx <= max_indices[type] ) ); + + base_addr = entries[type]; + entry_ptr = &(base_addr[idx]); + + HDassert( entry_ptr->index == idx ); + HDassert( entry_ptr->type == type ); + HDassert( entry_ptr == entry_ptr->self ); + HDassert( entry_ptr->header.is_protected ); + HDassert( entry_ptr->is_protected ); + + if ( ( dirty == TRUE ) || ( dirty == FALSE ) ) { + + flags |= (dirty ? H5AC__DIRTIED_FLAG : H5AC__NO_FLAGS_SET); + entry_ptr->is_dirty = (entry_ptr->is_dirty || dirty); + } + + result = H5C_unprotect(NULL, -1, -1, cache_ptr, &(types[type]), + entry_ptr->addr, (void *)entry_ptr, + flags, 0); + + if ( ( result < 0 ) || + ( entry_ptr->header.is_protected ) || + ( entry_ptr->header.type != &(types[type]) ) || + ( entry_ptr->size != entry_ptr->header.size ) || + ( entry_ptr->addr != entry_ptr->header.addr ) ) { + + pass = FALSE; + failure_mssg = "error in H5C_unprotect()."; + + } + else + { + entry_ptr->is_protected = FALSE; + } + + HDassert( ((entry_ptr->header).type)->id == type ); + + if ( ( flags & H5AC__DIRTIED_FLAG ) != 0 + && ( (flags & H5C__DELETED_FLAG) == 0 ) ) { + + HDassert( entry_ptr->header.is_dirty ); + HDassert( entry_ptr->is_dirty ); + } + } + + return; + +} /* unprotect_entry() */ + + +/*------------------------------------------------------------------------- + * Function: row_major_scan_forward() + * + * Purpose: Do a sequence of inserts, protects, unprotects, renames, + * destroys while scanning through the set of entries. If + * pass is false on entry, do nothing. + * + * Return: void + * + * Programmer: John Mainzer + * 6/12/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void +row_major_scan_forward(H5C_t * cache_ptr, + int32_t lag, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts, + hbool_t do_renames, + hbool_t rename_to_main_addr, + hbool_t do_destroys, + int dirty_destroys, + int dirty_unprotects) +{ + const char * fcn_name = "row_major_scan_forward"; + int32_t type; + int32_t idx; + + if ( verbose ) + HDfprintf(stdout, "%s(): entering.\n", fcn_name); + + HDassert( lag > 5 ); + + type = 0; + + if ( ( pass ) && ( reset_stats ) ) { + + H5C_stats__reset(cache_ptr); + } + + while ( ( pass ) && ( type < NUMBER_OF_ENTRY_TYPES ) ) + { + idx = -lag; + + while ( ( pass ) && ( idx <= (max_indices[type] + lag) ) ) + { + if ( ( pass ) && ( do_inserts ) && ( (idx + lag) >= 0 ) && + ( (idx + lag) <= max_indices[type] ) && + ( ((idx + lag) % 2) == 0 ) && + ( ! entry_in_cache(cache_ptr, type, (idx + lag)) ) ) { + + if ( verbose ) + HDfprintf(stdout, "(i, %d, %d) ", type, (idx + lag)); + + insert_entry(cache_ptr, type, (idx + lag), dirty_inserts, + H5C__NO_FLAGS_SET); + } + + + if ( ( pass ) && ( (idx + lag - 1) >= 0 ) && + ( (idx + lag - 1) <= max_indices[type] ) && + ( ( (idx + lag - 1) % 3 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, (idx + lag - 1)); + + protect_entry(cache_ptr, type, (idx + lag - 1)); + } + + if ( ( pass ) && ( (idx + lag - 2) >= 0 ) && + ( (idx + lag - 2) <= max_indices[type] ) && + ( ( (idx + lag - 2) % 3 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, (idx + lag - 2)); + + unprotect_entry(cache_ptr, type, idx+lag-2, NO_CHANGE, + H5C__NO_FLAGS_SET); + } + + + if ( ( pass ) && ( do_renames ) && ( (idx + lag - 2) >= 0 ) && + ( (idx + lag - 2) <= max_indices[type] ) && + ( ( (idx + lag - 2) % 3 ) == 0 ) ) { + + rename_entry(cache_ptr, type, (idx + lag - 2), + rename_to_main_addr); + } + + + if ( ( pass ) && ( (idx + lag - 3) >= 0 ) && + ( (idx + lag - 3) <= max_indices[type] ) && + ( ( (idx + lag - 3) % 5 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, (idx + lag - 3)); + + protect_entry(cache_ptr, type, (idx + lag - 3)); + } + + if ( ( pass ) && ( (idx + lag - 5) >= 0 ) && + ( (idx + lag - 5) <= max_indices[type] ) && + ( ( (idx + lag - 5) % 5 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, (idx + lag - 5)); + + unprotect_entry(cache_ptr, type, idx+lag-5, NO_CHANGE, + H5C__NO_FLAGS_SET); + } + + if ( ( pass ) && ( idx >= 0 ) && ( idx <= max_indices[type] ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, idx); + + protect_entry(cache_ptr, type, idx); + } + + + if ( ( pass ) && ( (idx - lag + 2) >= 0 ) && + ( (idx - lag + 2) <= max_indices[type] ) && + ( ( (idx - lag + 2) % 7 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, (idx - lag + 2)); + + unprotect_entry(cache_ptr, type, idx-lag+2, NO_CHANGE, + H5C__NO_FLAGS_SET); + } + + if ( ( pass ) && ( (idx - lag + 1) >= 0 ) && + ( (idx - lag + 1) <= max_indices[type] ) && + ( ( (idx - lag + 1) % 7 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, (idx - lag + 1)); + + protect_entry(cache_ptr, type, (idx - lag + 1)); + } + + + if ( do_destroys ) { + + if ( ( pass ) && ( (idx - lag) >= 0 ) && + ( ( idx - lag) <= max_indices[type] ) ) { + + switch ( (idx - lag) %4 ) { + + case 0: /* we just did an insert */ + unprotect_entry(cache_ptr, type, idx - lag, + NO_CHANGE, H5C__NO_FLAGS_SET); + break; + + case 1: + if ( (entries[type])[idx-lag].is_dirty ) { + + unprotect_entry(cache_ptr, type, idx - lag, + NO_CHANGE, H5C__NO_FLAGS_SET); + } else { + + unprotect_entry(cache_ptr, type, idx - lag, + dirty_unprotects, + H5C__NO_FLAGS_SET); + } + break; + + case 2: /* we just did an insrt */ + unprotect_entry(cache_ptr, type, idx - lag, + NO_CHANGE, H5C__DELETED_FLAG); + break; + + case 3: + if ( (entries[type])[idx-lag].is_dirty ) { + + unprotect_entry(cache_ptr, type, idx - lag, + NO_CHANGE, H5C__DELETED_FLAG); + } else { + + unprotect_entry(cache_ptr, type, idx - lag, + dirty_destroys, + H5C__DELETED_FLAG); + } + break; + + default: + HDassert(0); /* this can't happen... */ + break; + } + } + + } else { + + if ( ( pass ) && ( (idx - lag) >= 0 ) && + ( ( idx - lag) <= max_indices[type] ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, (idx - lag)); + + unprotect_entry(cache_ptr, type, idx - lag, + dirty_unprotects, H5C__NO_FLAGS_SET); + } + } + + if ( verbose ) + HDfprintf(stdout, "\n"); + + idx++; + } + type++; + } + + if ( ( pass ) && ( display_stats ) ) { + + H5C_stats(cache_ptr, "test cache", display_detailed_stats); + } + + return; + +} /* row_major_scan_forward() */ + + +/*------------------------------------------------------------------------- + * Function: hl_row_major_scan_forward() + * + * Purpose: Do a high locality sequence of inserts, protects, and + * unprotects while scanning through the set of entries. + * If pass is false on entry, do nothing. + * + * Return: void + * + * Programmer: John Mainzer + * 10/21/04 + * + * Modifications: + * + * JRM -- 1/21/05 + * Added the max_index parameter to allow the caller to + * throttle the size of the inner loop, and thereby the + * execution time of the function. + * + *------------------------------------------------------------------------- + */ + +void +hl_row_major_scan_forward(H5C_t * cache_ptr, + int32_t max_index, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts) +{ + const char * fcn_name = "hl_row_major_scan_forward"; + int32_t type; + int32_t idx; + int32_t i; + int32_t lag = 100; + int32_t local_max_index; + + if ( verbose ) + HDfprintf(stdout, "%s(): entering.\n", fcn_name); + + HDassert( lag > 5 ); + HDassert( max_index >= 200 ); + HDassert( max_index <= MAX_ENTRIES ); + + type = 0; + + if ( ( pass ) && ( reset_stats ) ) { + + H5C_stats__reset(cache_ptr); + } + + while ( ( pass ) && ( type < NUMBER_OF_ENTRY_TYPES ) ) + { + idx = -lag; + + local_max_index = MIN(max_index, max_indices[type]); + + while ( ( pass ) && ( idx <= (local_max_index + lag) ) ) + { + if ( ( pass ) && ( do_inserts ) && ( (idx + lag) >= 0 ) && + ( (idx + lag) <= max_indices[type] ) && + ( ((idx + lag) % 2) == 0 ) && + ( ! entry_in_cache(cache_ptr, type, (idx + lag)) ) ) { + + if ( verbose ) + HDfprintf(stdout, "(i, %d, %d) ", type, (idx + lag)); + + insert_entry(cache_ptr, type, (idx + lag), dirty_inserts, + H5C__NO_FLAGS_SET); + } + + i = idx; + + while ( ( pass ) && ( i >= idx - lag ) && ( i >= 0 ) ) + { + if ( ( pass ) && ( i >= 0 ) && ( i <= local_max_index ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, i); + + protect_entry(cache_ptr, type, i); + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, i); + + unprotect_entry(cache_ptr, type, i, NO_CHANGE, + H5C__NO_FLAGS_SET); + } + i--; + } + + if ( verbose ) + HDfprintf(stdout, "\n"); + + idx++; + } + type++; + } + + if ( ( pass ) && ( display_stats ) ) { + + H5C_stats(cache_ptr, "test cache", display_detailed_stats); + } + + return; + +} /* hl_row_major_scan_forward() */ + + +/*------------------------------------------------------------------------- + * Function: row_major_scan_backward() + * + * Purpose: Do a sequence of inserts, protects, unprotects, renames, + * destroys while scanning backwards through the set of + * entries. If pass is false on entry, do nothing. + * + * Return: void + * + * Programmer: John Mainzer + * 6/12/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void +row_major_scan_backward(H5C_t * cache_ptr, + int32_t lag, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts, + hbool_t do_renames, + hbool_t rename_to_main_addr, + hbool_t do_destroys, + int dirty_destroys, + int dirty_unprotects) +{ + const char * fcn_name = "row_major_scan_backward"; + int32_t type; + int32_t idx; + + if ( verbose ) + HDfprintf(stdout, "%s(): Entering.\n", fcn_name); + + HDassert( lag > 5 ); + + type = NUMBER_OF_ENTRY_TYPES - 1; + + if ( ( pass ) && ( reset_stats ) ) { + + H5C_stats__reset(cache_ptr); + } + + while ( ( pass ) && ( type >= 0 ) ) + { + idx = max_indices[type] + lag; + + while ( ( pass ) && ( idx >= -lag ) ) + { + if ( ( pass ) && ( do_inserts ) && ( (idx - lag) >= 0 ) && + ( (idx - lag) <= max_indices[type] ) && + ( ((idx - lag) % 2) == 1 ) && + ( ! entry_in_cache(cache_ptr, type, (idx - lag)) ) ) { + + if ( verbose ) + HDfprintf(stdout, "(i, %d, %d) ", type, (idx - lag)); + + insert_entry(cache_ptr, type, (idx - lag), dirty_inserts, + H5C__NO_FLAGS_SET); + } + + + if ( ( pass ) && ( (idx - lag + 1) >= 0 ) && + ( (idx - lag + 1) <= max_indices[type] ) && + ( ( (idx - lag + 1) % 3 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, (idx - lag + 1)); + + protect_entry(cache_ptr, type, (idx - lag + 1)); + } + + if ( ( pass ) && ( (idx - lag + 2) >= 0 ) && + ( (idx - lag + 2) <= max_indices[type] ) && + ( ( (idx - lag + 2) % 3 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, (idx - lag + 2)); + + unprotect_entry(cache_ptr, type, idx-lag+2, NO_CHANGE, + H5C__NO_FLAGS_SET); + } + + + if ( ( pass ) && ( do_renames ) && ( (idx - lag + 2) >= 0 ) && + ( (idx - lag + 2) <= max_indices[type] ) && + ( ( (idx - lag + 2) % 3 ) == 0 ) ) { + + rename_entry(cache_ptr, type, (idx - lag + 2), + rename_to_main_addr); + } + + + if ( ( pass ) && ( (idx - lag + 3) >= 0 ) && + ( (idx - lag + 3) <= max_indices[type] ) && + ( ( (idx - lag + 3) % 5 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, (idx - lag + 3)); + + protect_entry(cache_ptr, type, (idx - lag + 3)); + } + + if ( ( pass ) && ( (idx - lag + 5) >= 0 ) && + ( (idx - lag + 5) <= max_indices[type] ) && + ( ( (idx - lag + 5) % 5 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, (idx - lag + 5)); + + unprotect_entry(cache_ptr, type, idx-lag+5, NO_CHANGE, + H5C__NO_FLAGS_SET); + } + + if ( ( pass ) && ( idx >= 0 ) && ( idx <= max_indices[type] ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, idx); + + protect_entry(cache_ptr, type, idx); + } + + + if ( ( pass ) && ( (idx + lag - 2) >= 0 ) && + ( (idx + lag - 2) <= max_indices[type] ) && + ( ( (idx + lag - 2) % 7 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, (idx + lag - 2)); + + unprotect_entry(cache_ptr, type, idx+lag-2, NO_CHANGE, + H5C__NO_FLAGS_SET); + } + + if ( ( pass ) && ( (idx + lag - 1) >= 0 ) && + ( (idx + lag - 1) <= max_indices[type] ) && + ( ( (idx + lag - 1) % 7 ) == 0 ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, (idx + lag - 1)); + + protect_entry(cache_ptr, type, (idx + lag - 1)); + } + + + if ( do_destroys ) { + + if ( ( pass ) && ( (idx + lag) >= 0 ) && + ( ( idx + lag) <= max_indices[type] ) ) { + + switch ( (idx + lag) %4 ) { + + case 0: + if ( (entries[type])[idx+lag].is_dirty ) { + + unprotect_entry(cache_ptr, type, idx + lag, + NO_CHANGE, H5C__NO_FLAGS_SET); + } else { + + unprotect_entry(cache_ptr, type, idx + lag, + dirty_unprotects, + H5C__NO_FLAGS_SET); + } + break; + + case 1: /* we just did an insert */ + unprotect_entry(cache_ptr, type, idx + lag, + NO_CHANGE, H5C__NO_FLAGS_SET); + break; + + case 2: + if ( (entries[type])[idx + lag].is_dirty ) { + + unprotect_entry(cache_ptr, type, idx + lag, + NO_CHANGE, H5C__DELETED_FLAG); + } else { + + unprotect_entry(cache_ptr, type, idx + lag, + dirty_destroys, + H5C__DELETED_FLAG); + } + break; + + case 3: /* we just did an insrt */ + unprotect_entry(cache_ptr, type, idx + lag, + NO_CHANGE, H5C__DELETED_FLAG); + break; + + default: + HDassert(0); /* this can't happen... */ + break; + } + } + } else { + + if ( ( pass ) && ( (idx + lag) >= 0 ) && + ( ( idx + lag) <= max_indices[type] ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, (idx - lag)); + + unprotect_entry(cache_ptr, type, idx + lag, + dirty_unprotects, H5C__NO_FLAGS_SET); + } + } + + if ( verbose ) + HDfprintf(stdout, "\n"); + + idx--; + } + type--; + } + + if ( ( pass ) && ( display_stats ) ) { + + H5C_stats(cache_ptr, "test cache", display_detailed_stats); + } + + return; + +} /* row_major_scan_backward() */ + + +/*------------------------------------------------------------------------- + * Function: hl_row_major_scan_backward() + * + * Purpose: Do a high locality sequence of inserts, protects, and + * unprotects while scanning through the set of entries. + * If pass is false on entry, do nothing. + * + * Return: void + * + * Programmer: John Mainzer + * 10/21/04 + * + * Modifications: + * + * JRM -- 1/21/05 + * Added the max_index parameter to allow the caller to + * throttle the size of the inner loop, and thereby the + * execution time of the function. + * + *------------------------------------------------------------------------- + */ + +void +hl_row_major_scan_backward(H5C_t * cache_ptr, + int32_t max_index, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts) +{ + const char * fcn_name = "hl_row_major_scan_backward"; + int32_t type; + int32_t idx; + int32_t i; + int32_t lag = 100; + int32_t local_max_index; + + if ( verbose ) + HDfprintf(stdout, "%s(): entering.\n", fcn_name); + + HDassert( lag > 5 ); + HDassert( max_index >= 200 ); + HDassert( max_index <= MAX_ENTRIES ); + + type = NUMBER_OF_ENTRY_TYPES - 1; + + if ( ( pass ) && ( reset_stats ) ) { + + H5C_stats__reset(cache_ptr); + } + + while ( ( pass ) && ( type >= 0 ) ) + { + idx = max_indices[type] + lag; + + local_max_index = MIN(max_index, max_indices[type]); + + while ( ( pass ) && ( idx >= -lag ) ) + { + if ( ( pass ) && ( do_inserts ) && ( (idx + lag) >= 0 ) && + ( (idx + lag) <= local_max_index ) && + ( ((idx + lag) % 2) == 0 ) && + ( ! entry_in_cache(cache_ptr, type, (idx + lag)) ) ) { + + if ( verbose ) + HDfprintf(stdout, "(i, %d, %d) ", type, (idx + lag)); + + insert_entry(cache_ptr, type, (idx + lag), dirty_inserts, + H5C__NO_FLAGS_SET); + } + + i = idx; + + while ( ( pass ) && ( i >= idx - lag ) && ( i >= 0 ) ) + { + if ( ( pass ) && ( i >= 0 ) && ( i <= local_max_index ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, i); + + protect_entry(cache_ptr, type, i); + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, i); + + unprotect_entry(cache_ptr, type, i, NO_CHANGE, + H5C__NO_FLAGS_SET); + } + i--; + } + + if ( verbose ) + HDfprintf(stdout, "\n"); + + idx--; + } + type--; + } + + if ( ( pass ) && ( display_stats ) ) { + + H5C_stats(cache_ptr, "test cache", display_detailed_stats); + } + + return; + +} /* hl_row_major_scan_backward() */ + + +/*------------------------------------------------------------------------- + * Function: col_major_scan_forward() + * + * Purpose: Do a sequence of inserts, protects, and unprotects + * while scanning through the set of entries. If + * pass is false on entry, do nothing. + * + * Return: void + * + * Programmer: John Mainzer + * 6/23/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void +col_major_scan_forward(H5C_t * cache_ptr, + int32_t lag, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts, + int dirty_unprotects) +{ + const char * fcn_name = "col_major_scan_forward()"; + int32_t type; + int32_t idx; + + if ( verbose ) + HDfprintf(stdout, "%s: entering.\n", fcn_name); + + HDassert( lag > 5 ); + + type = 0; + + if ( ( pass ) && ( reset_stats ) ) { + + H5C_stats__reset(cache_ptr); + } + + idx = -lag; + + while ( ( pass ) && ( (idx - lag) <= MAX_ENTRIES ) ) + { + type = 0; + + while ( ( pass ) && ( type < NUMBER_OF_ENTRY_TYPES ) ) + { + if ( ( pass ) && ( do_inserts ) && ( (idx + lag) >= 0 ) && + ( (idx + lag) <= max_indices[type] ) && + ( ((idx + lag) % 3) == 0 ) && + ( ! entry_in_cache(cache_ptr, type, (idx + lag)) ) ) { + + if ( verbose ) + HDfprintf(stdout, "(i, %d, %d) ", type, (idx + lag)); + + insert_entry(cache_ptr, type, (idx + lag), dirty_inserts, + H5C__NO_FLAGS_SET); + } + + if ( ( pass ) && ( idx >= 0 ) && ( idx <= max_indices[type] ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, idx); + + protect_entry(cache_ptr, type, idx); + } + + if ( ( pass ) && ( (idx - lag) >= 0 ) && + ( (idx - lag) <= max_indices[type] ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, (idx - lag)); + + unprotect_entry(cache_ptr, type, idx - lag, + dirty_unprotects, H5C__NO_FLAGS_SET); + } + + if ( verbose ) + HDfprintf(stdout, "\n"); + + type++; + } + + idx++; + } + + if ( ( pass ) && ( display_stats ) ) { + + H5C_stats(cache_ptr, "test cache", display_detailed_stats); + } + + return; + +} /* col_major_scan_forward() */ + + +/*------------------------------------------------------------------------- + * Function: hl_col_major_scan_forward() + * + * Purpose: Do a high locality sequence of inserts, protects, and + * unprotects while scanning through the set of entries. If + * pass is false on entry, do nothing. + * + * Return: void + * + * Programmer: John Mainzer + * 19/25/04 + * + * Modifications: + * + * JRM -- 1/21/05 + * Added the max_index parameter to allow the caller to + * throttle the size of the inner loop, and thereby the + * execution time of the function. + * + *------------------------------------------------------------------------- + */ + +void +hl_col_major_scan_forward(H5C_t * cache_ptr, + int32_t max_index, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts, + int dirty_unprotects) +{ + const char * fcn_name = "hl_col_major_scan_forward()"; + int32_t type; + int32_t idx; + int32_t lag = 200; + int32_t i; + int32_t local_max_index; + + if ( verbose ) + HDfprintf(stdout, "%s: entering.\n", fcn_name); + + HDassert( lag > 5 ); + HDassert( max_index >= 500 ); + HDassert( max_index <= MAX_ENTRIES ); + + type = 0; + + if ( ( pass ) && ( reset_stats ) ) { + + H5C_stats__reset(cache_ptr); + } + + idx = 0; + + local_max_index = MIN(max_index, MAX_ENTRIES); + + while ( ( pass ) && ( idx <= local_max_index ) ) + { + + i = idx; + + while ( ( pass ) && ( i >= 0 ) && ( i >= (idx - lag) ) ) { + + type = 0; + + while ( ( pass ) && ( type < NUMBER_OF_ENTRY_TYPES ) ) + { + if ( ( pass ) && ( do_inserts ) && ( i == idx ) && + ( i <= local_max_index ) && + ( (i % 3) == 0 ) && + ( ! entry_in_cache(cache_ptr, type, i) ) ) { + + if ( verbose ) + HDfprintf(stdout, "(i, %d, %d) ", type, i); + + insert_entry(cache_ptr, type, i, dirty_inserts, + H5C__NO_FLAGS_SET); + } + + if ( ( pass ) && ( i >= 0 ) && ( i <= local_max_index ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, i); + + protect_entry(cache_ptr, type, i); + } + + if ( ( pass ) && ( i >= 0 ) && + ( i <= max_indices[type] ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, i); + + unprotect_entry(cache_ptr, type, i, + dirty_unprotects, H5C__NO_FLAGS_SET); + } + + if ( verbose ) + HDfprintf(stdout, "\n"); + + type++; + } + + i--; + } + + idx++; + } + + if ( ( pass ) && ( display_stats ) ) { + + H5C_stats(cache_ptr, "test cache", display_detailed_stats); + } + + return; + +} /* hl_col_major_scan_forward() */ + + +/*------------------------------------------------------------------------- + * Function: col_major_scan_backward() + * + * Purpose: Do a sequence of inserts, protects, and unprotects + * while scanning backwards through the set of + * entries. If pass is false on entry, do nothing. + * + * Return: void + * + * Programmer: John Mainzer + * 6/23/04 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +void +col_major_scan_backward(H5C_t * cache_ptr, + int32_t lag, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts, + int dirty_unprotects) +{ + const char * fcn_name = "col_major_scan_backward()"; + int mile_stone = 1; + int32_t type; + int32_t idx; + + if ( verbose ) + HDfprintf(stdout, "%s: entering.\n", fcn_name); + + HDassert( lag > 5 ); + + if ( ( pass ) && ( reset_stats ) ) { + + H5C_stats__reset(cache_ptr); + } + + idx = MAX_ENTRIES + lag; + + if ( verbose ) /* 1 */ + HDfprintf(stdout, "%s: point %d.\n", fcn_name, mile_stone++); + + + while ( ( pass ) && ( (idx + lag) >= 0 ) ) + { + type = NUMBER_OF_ENTRY_TYPES - 1; + + while ( ( pass ) && ( type >= 0 ) ) + { + if ( ( pass ) && ( do_inserts) && ( (idx - lag) >= 0 ) && + ( (idx - lag) <= max_indices[type] ) && + ( ((idx - lag) % 3) == 0 ) && + ( ! entry_in_cache(cache_ptr, type, (idx - lag)) ) ) { + + if ( verbose ) + HDfprintf(stdout, "(i, %d, %d) ", type, (idx - lag)); + + insert_entry(cache_ptr, type, (idx - lag), dirty_inserts, + H5C__NO_FLAGS_SET); + } + + if ( ( pass ) && ( idx >= 0 ) && ( idx <= max_indices[type] ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, idx); + + protect_entry(cache_ptr, type, idx); + } + + if ( ( pass ) && ( (idx + lag) >= 0 ) && + ( (idx + lag) <= max_indices[type] ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, (idx + lag)); + + unprotect_entry(cache_ptr, type, idx + lag, + dirty_unprotects, H5C__NO_FLAGS_SET); + } + + if ( verbose ) + HDfprintf(stdout, "\n"); + + type--; + } + + idx--; + } + + if ( verbose ) /* 2 */ + HDfprintf(stdout, "%s: point %d.\n", fcn_name, mile_stone++); + + if ( ( pass ) && ( display_stats ) ) { + + H5C_stats(cache_ptr, "test cache", display_detailed_stats); + } + + if ( verbose ) + HDfprintf(stdout, "%s: exiting.\n", fcn_name); + + return; + +} /* col_major_scan_backward() */ + + +/*------------------------------------------------------------------------- + * Function: hl_col_major_scan_backward() + * + * Purpose: Do a high locality sequence of inserts, protects, and + * unprotects while scanning backwards through the set of + * entries. If pass is false on entry, do nothing. + * + * Return: void + * + * Programmer: John Mainzer + * 10/25/04 + * + * Modifications: + * + * JRM -- 1/21/05 + * Added the max_index parameter to allow the caller to + * throttle the size of the inner loop, and thereby the + * execution time of the function. + * + *------------------------------------------------------------------------- + */ + +void +hl_col_major_scan_backward(H5C_t * cache_ptr, + int32_t max_index, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts, + int dirty_unprotects) +{ + const char * fcn_name = "hl_col_major_scan_backward()"; + int32_t type; + int32_t idx; + int32_t lag = 50; + int32_t i; + int32_t local_max_index; + + if ( verbose ) + HDfprintf(stdout, "%s: entering.\n", fcn_name); + + HDassert( lag > 5 ); + HDassert( max_index >= 500 ); + HDassert( max_index <= MAX_ENTRIES ); + + type = 0; + + local_max_index = MIN(max_index, MAX_ENTRIES); + + if ( ( pass ) && ( reset_stats ) ) { + + H5C_stats__reset(cache_ptr); + } + + idx = local_max_index; + + while ( ( pass ) && ( idx >= 0 ) ) + { + + i = idx; + + while ( ( pass ) && ( i <= local_max_index ) && ( i <= (idx + lag) ) ) { + + type = 0; + + while ( ( pass ) && ( type < NUMBER_OF_ENTRY_TYPES ) ) + { + if ( ( pass ) && ( do_inserts ) && ( i == idx ) && + ( i <= local_max_index ) && + ( ! entry_in_cache(cache_ptr, type, i) ) ) { + + if ( verbose ) + HDfprintf(stdout, "(i, %d, %d) ", type, i); + + insert_entry(cache_ptr, type, i, dirty_inserts, + H5C__NO_FLAGS_SET); + } + + if ( ( pass ) && ( i >= 0 ) && ( i <= local_max_index ) ) { + + if ( verbose ) + HDfprintf(stdout, "(p, %d, %d) ", type, i); + + protect_entry(cache_ptr, type, i); + } + + if ( ( pass ) && ( i >= 0 ) && + ( i <= local_max_index ) ) { + + if ( verbose ) + HDfprintf(stdout, "(u, %d, %d) ", type, i); + + unprotect_entry(cache_ptr, type, i, + dirty_unprotects, H5C__NO_FLAGS_SET); + } + + if ( verbose ) + HDfprintf(stdout, "\n"); + + type++; + } + + i++; + } + + idx--; + } + + if ( ( pass ) && ( display_stats ) ) { + + H5C_stats(cache_ptr, "test cache", display_detailed_stats); + } + + return; + +} /* hl_col_major_scan_backward() */ + diff --git a/test/cache_common.h b/test/cache_common.h new file mode 100644 index 0000000..acacb30 --- /dev/null +++ b/test/cache_common.h @@ -0,0 +1,500 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* Programmer: John Mainzer + * 10/27/05 + * + * This file contains common #defines, type definitions, and + * externs for tests of the cache implemented in H5C.c + */ +#include "h5test.h" +#include "H5Iprivate.h" +#include "H5ACprivate.h" + +#define H5C_PACKAGE /*suppress error about including H5Cpkg */ + +#include "H5Cpkg.h" + +#define H5F_PACKAGE /*suppress error about including H5Fpkg */ + +#include "H5Fpkg.h" + +#define NO_CHANGE -1 + +/* with apologies for the abuse of terminology... */ + +#define PICO_ENTRY_TYPE 0 +#define NANO_ENTRY_TYPE 1 +#define MICRO_ENTRY_TYPE 2 +#define TINY_ENTRY_TYPE 3 +#define SMALL_ENTRY_TYPE 4 +#define MEDIUM_ENTRY_TYPE 5 +#define LARGE_ENTRY_TYPE 6 +#define HUGE_ENTRY_TYPE 7 +#define MONSTER_ENTRY_TYPE 8 + +#define NUMBER_OF_ENTRY_TYPES 9 + +#define PICO_ENTRY_SIZE (size_t)1 +#define NANO_ENTRY_SIZE (size_t)4 +#define MICRO_ENTRY_SIZE (size_t)16 +#define TINY_ENTRY_SIZE (size_t)64 +#define SMALL_ENTRY_SIZE (size_t)256 +#define MEDIUM_ENTRY_SIZE (size_t)1024 +#define LARGE_ENTRY_SIZE (size_t)(4 * 1024) +#define HUGE_ENTRY_SIZE (size_t)(16 * 1024) +#define MONSTER_ENTRY_SIZE (size_t)(64 * 1024) + +#define NUM_PICO_ENTRIES (10 * 1024) +#define NUM_NANO_ENTRIES (10 * 1024) +#define NUM_MICRO_ENTRIES (10 * 1024) +#define NUM_TINY_ENTRIES (10 * 1024) +#define NUM_SMALL_ENTRIES (10 * 1024) +#define NUM_MEDIUM_ENTRIES (10 * 1024) +#define NUM_LARGE_ENTRIES (10 * 1024) +#define NUM_HUGE_ENTRIES (10 * 1024) +#define NUM_MONSTER_ENTRIES (10 * 1024) + +#define MAX_ENTRIES (10 * 1024) + +#define PICO_BASE_ADDR (haddr_t)0 +#define NANO_BASE_ADDR (haddr_t)(PICO_BASE_ADDR + \ + (PICO_ENTRY_SIZE * NUM_PICO_ENTRIES)) +#define MICRO_BASE_ADDR (haddr_t)(NANO_BASE_ADDR + \ + (NANO_ENTRY_SIZE * NUM_NANO_ENTRIES)) +#define TINY_BASE_ADDR (haddr_t)(MICRO_BASE_ADDR + \ + (MICRO_ENTRY_SIZE * NUM_MICRO_ENTRIES)) +#define SMALL_BASE_ADDR (haddr_t)(TINY_BASE_ADDR + \ + (TINY_ENTRY_SIZE * NUM_TINY_ENTRIES)) +#define MEDIUM_BASE_ADDR (haddr_t)(SMALL_BASE_ADDR + \ + (SMALL_ENTRY_SIZE * NUM_SMALL_ENTRIES)) +#define LARGE_BASE_ADDR (haddr_t)(MEDIUM_BASE_ADDR + \ + (MEDIUM_ENTRY_SIZE * NUM_MEDIUM_ENTRIES)) +#define HUGE_BASE_ADDR (haddr_t)(LARGE_BASE_ADDR + \ + (LARGE_ENTRY_SIZE * NUM_LARGE_ENTRIES)) +#define MONSTER_BASE_ADDR (haddr_t)(HUGE_BASE_ADDR + \ + (HUGE_ENTRY_SIZE * NUM_HUGE_ENTRIES)) + +#define PICO_ALT_BASE_ADDR (haddr_t)(MONSTER_BASE_ADDR + \ + (MONSTER_ENTRY_SIZE * NUM_MONSTER_ENTRIES)) +#define NANO_ALT_BASE_ADDR (haddr_t)(PICO_ALT_BASE_ADDR + \ + (PICO_ENTRY_SIZE * NUM_PICO_ENTRIES)) +#define MICRO_ALT_BASE_ADDR (haddr_t)(NANO_ALT_BASE_ADDR + \ + (NANO_ENTRY_SIZE * NUM_NANO_ENTRIES)) +#define TINY_ALT_BASE_ADDR (haddr_t)(MICRO_ALT_BASE_ADDR + \ + (MICRO_ENTRY_SIZE * NUM_MICRO_ENTRIES)) +#define SMALL_ALT_BASE_ADDR (haddr_t)(TINY_ALT_BASE_ADDR + \ + (TINY_ENTRY_SIZE * NUM_TINY_ENTRIES)) +#define MEDIUM_ALT_BASE_ADDR (haddr_t)(SMALL_ALT_BASE_ADDR + \ + (SMALL_ENTRY_SIZE * NUM_SMALL_ENTRIES)) +#define LARGE_ALT_BASE_ADDR (haddr_t)(MEDIUM_ALT_BASE_ADDR + \ + (MEDIUM_ENTRY_SIZE * NUM_MEDIUM_ENTRIES)) +#define HUGE_ALT_BASE_ADDR (haddr_t)(LARGE_ALT_BASE_ADDR + \ + (LARGE_ENTRY_SIZE * NUM_LARGE_ENTRIES)) +#define MONSTER_ALT_BASE_ADDR (haddr_t)(HUGE_ALT_BASE_ADDR + \ + (HUGE_ENTRY_SIZE * NUM_HUGE_ENTRIES)) + +typedef struct test_entry_t +{ + H5C_cache_entry_t header; /* entry data used by the cache + * -- must be first + */ + struct test_entry_t * self; /* pointer to this entry -- used for + * sanity checking. + */ + haddr_t addr; /* where the cache thinks this entry + * is located + */ + hbool_t at_main_addr; /* boolean flag indicating whether + * the entry is supposed to be at + * either its main or alternate + * address. + */ + haddr_t main_addr; /* initial location of the entry + */ + haddr_t alt_addr; /* location to which the entry + * can be relocated or "renamed" + */ + size_t size; /* how big the cache thinks this + * entry is + */ + int32_t type; /* indicates which entry array this + * entry is in + */ + int32_t index; /* index in its entry array + */ + int32_t reads; /* number of times this entry has + * been loaded. + */ + int32_t writes; /* number of times this entry has + * been written + */ + hbool_t is_dirty; /* entry has been modified since + * last write + */ + hbool_t is_protected; /* entry should currently be on + * the cache's protected list. + */ + hbool_t loaded; /* entry has been loaded since the + * last time it was reset. + */ + hbool_t cleared; /* entry has been cleared since the + * last time it was reset. + */ + hbool_t flushed; /* entry has been flushed since the + * last time it was reset. + */ + hbool_t destroyed; /* entry has been destroyed since the + * last time it was reset. + */ +} test_entry_t; + +/* The following is a cut down copy of the hash table manipulation + * macros from H5C.c, which have been further modified to avoid references + * to the error reporting macros. Needless to say, these macros must be + * updated as necessary. + */ + +#define H5C__HASH_MASK ((size_t)(H5C__HASH_TABLE_LEN - 1) << 3) +#define H5C__HASH_FCN(x) (int)(((x) & H5C__HASH_MASK) >> 3) + +#define H5C__PRE_HT_SEARCH_SC(cache_ptr, Addr) \ +if ( ( (cache_ptr) == NULL ) || \ + ( (cache_ptr)->magic != H5C__H5C_T_MAGIC ) || \ + ( ! H5F_addr_defined(Addr) ) || \ + ( H5C__HASH_FCN(Addr) < 0 ) || \ + ( H5C__HASH_FCN(Addr) >= H5C__HASH_TABLE_LEN ) ) { \ + HDfprintf(stdout, "Pre HT search SC failed.\n"); \ +} + +#define H5C__POST_SUC_HT_SEARCH_SC(cache_ptr, entry_ptr, Addr, k) \ +if ( ( (cache_ptr) == NULL ) || \ + ( (cache_ptr)->magic != H5C__H5C_T_MAGIC ) || \ + ( (cache_ptr)->index_len < 1 ) || \ + ( (entry_ptr) == NULL ) || \ + ( (cache_ptr)->index_size < (entry_ptr)->size ) || \ + ( H5F_addr_ne((entry_ptr)->addr, (Addr)) ) || \ + ( (entry_ptr)->size <= 0 ) || \ + ( ((cache_ptr)->index)[k] == NULL ) || \ + ( ( ((cache_ptr)->index)[k] != (entry_ptr) ) && \ + ( (entry_ptr)->ht_prev == NULL ) ) || \ + ( ( ((cache_ptr)->index)[k] == (entry_ptr) ) && \ + ( (entry_ptr)->ht_prev != NULL ) ) || \ + ( ( (entry_ptr)->ht_prev != NULL ) && \ + ( (entry_ptr)->ht_prev->ht_next != (entry_ptr) ) ) || \ + ( ( (entry_ptr)->ht_next != NULL ) && \ + ( (entry_ptr)->ht_next->ht_prev != (entry_ptr) ) ) ) { \ + HDfprintf(stdout, "Post successful HT search SC failed.\n"); \ +} + + +#define H5C__SEARCH_INDEX(cache_ptr, Addr, entry_ptr) \ +{ \ + int k; \ + int depth = 0; \ + H5C__PRE_HT_SEARCH_SC(cache_ptr, Addr) \ + k = H5C__HASH_FCN(Addr); \ + entry_ptr = ((cache_ptr)->index)[k]; \ + while ( ( entry_ptr ) && ( H5F_addr_ne(Addr, (entry_ptr)->addr) ) ) \ + { \ + (entry_ptr) = (entry_ptr)->ht_next; \ + (depth)++; \ + } \ + if ( entry_ptr ) \ + { \ + H5C__POST_SUC_HT_SEARCH_SC(cache_ptr, entry_ptr, Addr, k) \ + if ( entry_ptr != ((cache_ptr)->index)[k] ) \ + { \ + if ( (entry_ptr)->ht_next ) \ + { \ + (entry_ptr)->ht_next->ht_prev = (entry_ptr)->ht_prev; \ + } \ + HDassert( (entry_ptr)->ht_prev != NULL ); \ + (entry_ptr)->ht_prev->ht_next = (entry_ptr)->ht_next; \ + ((cache_ptr)->index)[k]->ht_prev = (entry_ptr); \ + (entry_ptr)->ht_next = ((cache_ptr)->index)[k]; \ + (entry_ptr)->ht_prev = NULL; \ + ((cache_ptr)->index)[k] = (entry_ptr); \ + } \ + } \ +} + + +/* misc type definitions */ + +struct flush_cache_test_spec +{ + int entry_num; + int entry_type; + int entry_index; + hbool_t insert_flag; + hbool_t dirty_flag; + unsigned int flags; + hbool_t expected_loaded; + hbool_t expected_cleared; + hbool_t expected_flushed; + hbool_t expected_destroyed; +}; + + +/* global variable externs: */ + +extern const char *FILENAME[]; + +extern hbool_t write_permitted; +extern hbool_t pass; /* set to false on error */ +extern hbool_t skip_long_tests; +extern hbool_t run_full_test; +extern const char *failure_mssg; + +extern test_entry_t pico_entries[NUM_PICO_ENTRIES]; +extern test_entry_t nano_entries[NUM_NANO_ENTRIES]; +extern test_entry_t micro_entries[NUM_MICRO_ENTRIES]; +extern test_entry_t tiny_entries[NUM_TINY_ENTRIES]; +extern test_entry_t small_entries[NUM_SMALL_ENTRIES]; +extern test_entry_t medium_entries[NUM_MEDIUM_ENTRIES]; +extern test_entry_t large_entries[NUM_LARGE_ENTRIES]; +extern test_entry_t huge_entries[NUM_HUGE_ENTRIES]; +extern test_entry_t monster_entries[NUM_MONSTER_ENTRIES]; + +extern test_entry_t * entries[NUMBER_OF_ENTRY_TYPES]; +extern const int32_t max_indices[NUMBER_OF_ENTRY_TYPES]; +extern const size_t entry_sizes[NUMBER_OF_ENTRY_TYPES]; +extern const haddr_t base_addrs[NUMBER_OF_ENTRY_TYPES]; +extern const haddr_t alt_base_addrs[NUMBER_OF_ENTRY_TYPES]; +extern const char * entry_type_names[NUMBER_OF_ENTRY_TYPES]; + + +/* call back function declarations: */ + +herr_t check_write_permitted(const H5F_t UNUSED * f, + hid_t UNUSED dxpl_id, + hbool_t * write_permitted_ptr); + +herr_t pico_clear(H5F_t * f, void * thing, hbool_t dest); +herr_t nano_clear(H5F_t * f, void * thing, hbool_t dest); +herr_t micro_clear(H5F_t * f, void * thing, hbool_t dest); +herr_t tiny_clear(H5F_t * f, void * thing, hbool_t dest); +herr_t small_clear(H5F_t * f, void * thing, hbool_t dest); +herr_t medium_clear(H5F_t * f, void * thing, hbool_t dest); +herr_t large_clear(H5F_t * f, void * thing, hbool_t dest); +herr_t huge_clear(H5F_t * f, void * thing, hbool_t dest); +herr_t monster_clear(H5F_t * f, void * thing, hbool_t dest); + + +herr_t pico_dest(H5F_t * f, void * thing); +herr_t nano_dest(H5F_t * f, void * thing); +herr_t micro_dest(H5F_t * f, void * thing); +herr_t tiny_dest(H5F_t * f, void * thing); +herr_t small_dest(H5F_t * f, void * thing); +herr_t medium_dest(H5F_t * f, void * thing); +herr_t large_dest(H5F_t * f, void * thing); +herr_t huge_dest(H5F_t * f, void * thing); +herr_t monster_dest(H5F_t * f, void * thing); + + +herr_t pico_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, + haddr_t addr, void *thing); +herr_t nano_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, + haddr_t addr, void *thing); +herr_t micro_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, + haddr_t addr, void *thing); +herr_t tiny_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, + haddr_t addr, void *thing); +herr_t small_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, + haddr_t addr, void *thing); +herr_t medium_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, + haddr_t addr, void *thing); +herr_t large_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, + haddr_t addr, void *thing); +herr_t huge_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, + haddr_t addr, void *thing); +herr_t monster_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, + haddr_t addr, void *thing); + + +void * pico_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2); +void * nano_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2); +void * micro_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2); +void * tiny_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2); +void * small_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2); +void * medium_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2); +void * large_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2); +void * huge_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2); +void * monster_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *udata1, void *udata2); + + +herr_t pico_size(H5F_t * f, void * thing, size_t * size_ptr); +herr_t nano_size(H5F_t * f, void * thing, size_t * size_ptr); +herr_t micro_size(H5F_t * f, void * thing, size_t * size_ptr); +herr_t tiny_size(H5F_t * f, void * thing, size_t * size_ptr); +herr_t small_size(H5F_t * f, void * thing, size_t * size_ptr); +herr_t medium_size(H5F_t * f, void * thing, size_t * size_ptr); +herr_t large_size(H5F_t * f, void * thing, size_t * size_ptr); +herr_t huge_size(H5F_t * f, void * thing, size_t * size_ptr); +herr_t monster_size(H5F_t * f, void * thing, size_t * size_ptr); + +/* callback table extern */ + +extern const H5C_class_t types[NUMBER_OF_ENTRY_TYPES]; + + +/* function declarations: */ + +void addr_to_type_and_index(haddr_t addr, + int32_t * type_ptr, + int32_t * index_ptr); + +#if 0 /* keep this for a while -- it may be useful */ +haddr_t type_and_index_to_addr(int32_t type, + int32_t idx); +#endif + +void insert_entry(H5C_t * cache_ptr, + int32_t type, + int32_t idx, + hbool_t dirty, + unsigned int flags); + +void rename_entry(H5C_t * cache_ptr, + int32_t type, + int32_t idx, + hbool_t main_addr); + +void protect_entry(H5C_t * cache_ptr, + int32_t type, + int32_t idx); + +hbool_t entry_in_cache(H5C_t * cache_ptr, + int32_t type, + int32_t idx); + +void reset_entries(void); + +H5C_t * setup_cache(size_t max_cache_size, size_t min_clean_size); + +void row_major_scan_forward(H5C_t * cache_ptr, + int32_t lag, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts, + hbool_t do_renames, + hbool_t rename_to_main_addr, + hbool_t do_destroys, + int dirty_destroys, + int dirty_unprotects); + +void hl_row_major_scan_forward(H5C_t * cache_ptr, + int32_t max_index, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts); + +void row_major_scan_backward(H5C_t * cache_ptr, + int32_t lag, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts, + hbool_t do_renames, + hbool_t rename_to_main_addr, + hbool_t do_destroys, + int dirty_destroys, + int dirty_unprotects); + +void hl_row_major_scan_backward(H5C_t * cache_ptr, + int32_t max_index, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts); + +void col_major_scan_forward(H5C_t * cache_ptr, + int32_t lag, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts, + int dirty_unprotects); + +void hl_col_major_scan_forward(H5C_t * cache_ptr, + int32_t max_index, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts, + int dirty_unprotects); + +void col_major_scan_backward(H5C_t * cache_ptr, + int32_t lag, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts, + int dirty_unprotects); + +void hl_col_major_scan_backward(H5C_t * cache_ptr, + int32_t max_index, + hbool_t verbose, + hbool_t reset_stats, + hbool_t display_stats, + hbool_t display_detailed_stats, + hbool_t do_inserts, + hbool_t dirty_inserts, + int dirty_unprotects); + +void takedown_cache(H5C_t * cache_ptr, + hbool_t dump_stats, + hbool_t dump_detailed_stats); + +void flush_cache(H5C_t * cache_ptr, + hbool_t destroy_entries, + hbool_t dump_stats, + hbool_t dump_detailed_stats); + +void unprotect_entry(H5C_t * cache_ptr, + int32_t type, + int32_t idx, + int dirty, + unsigned int flags); + +void verify_clean(void); + +void verify_unprotected(void); + |