diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2010-05-27 22:57:29 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2010-05-27 22:57:29 (GMT) |
commit | e4246519c9d59a5f837f2b1009471533b729b778 (patch) | |
tree | 0ed23bfb58157edccfa11487a6c9f293b9e97670 /test/cache_common.c | |
parent | fc3de1ec794584b1bdc6e615d8d2afc15f5bb5ec (diff) | |
download | hdf5-e4246519c9d59a5f837f2b1009471533b729b778.zip hdf5-e4246519c9d59a5f837f2b1009471533b729b778.tar.gz hdf5-e4246519c9d59a5f837f2b1009471533b729b778.tar.bz2 |
[svn-r18920] Description:
Bring r18917 from trunk to 1.8 branch:
Bring r18911 (plus some adaptions to match the code on the trunk)
from the metadata journaling "merging" branch to the trunk:
More general changes to align trunk with eventual changes from
metadata journaling branch.
Tested on:
FreeBSD/32 6.3 (duty) in debug mode
FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode
Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x,
w/C++ & FORTRAN, w/threadsafe, in debug mode
Linux/64-amd64 2.6 (amani) w/Intel compilers, w/default API=1.6.x,
w/C++ & FORTRAN, in production mode
Diffstat (limited to 'test/cache_common.c')
-rw-r--r-- | test/cache_common.c | 576 |
1 files changed, 457 insertions, 119 deletions
diff --git a/test/cache_common.c b/test/cache_common.c index 0d7df25..7362fe9 100644 --- a/test/cache_common.c +++ b/test/cache_common.c @@ -511,10 +511,6 @@ check_write_permitted(const H5F_t UNUSED * f, * Programmer: John Mainzer * 6/10/04 * - * Modifications: - * - * Added variable_clear. -- JRM 8/30/06 - * *------------------------------------------------------------------------- */ @@ -639,16 +635,6 @@ variable_clear(H5F_t * f, void * thing, hbool_t dest) * Programmer: John Mainzer * 6/10/04 * - * Modifications: - * - * JRM -- 4/4/06 - * Added code to decrement the pinning_ref_count s of entries - * pinned by the target entry, and to unpin those entries - * if the reference count drops to zero. - * - * JRM -- 8/30/06 - * Added variable_destroy(). - * *------------------------------------------------------------------------- */ @@ -805,14 +791,6 @@ variable_dest(H5F_t * f, void * thing) * Programmer: John Mainzer * 6/10/04 * - * Modifications: - * - * JRM -- 8/30/06 - * Added variable_flush() and flags_ptr parameter. - * - * JRM -- 9/1/06 - * Added support for flush operations. - * *------------------------------------------------------------------------- */ @@ -984,11 +962,6 @@ variable_flush(H5F_t *f, hid_t dxpl_id, hbool_t dest, haddr_t addr, * Programmer: John Mainzer * 6/10/04 * - * Modifications: - * - * JRM -- 8/30/06 - * Added variable_load(). - * *------------------------------------------------------------------------- */ @@ -1113,11 +1086,6 @@ variable_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *udata) * Programmer: John Mainzer * 6/10/04 * - * Modifications: - * - * JRM -- 8/30/06 - * Added variable_size(). - * *------------------------------------------------------------------------- */ @@ -1472,7 +1440,7 @@ execute_flush_op(H5F_t * file_ptr, { H5C_t * cache_ptr; - HDassert( file_ptr ) ; + HDassert( file_ptr ); cache_ptr = file_ptr->shared->cache; HDassert( cache_ptr != NULL ); HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC ); @@ -1483,7 +1451,7 @@ execute_flush_op(H5F_t * file_ptr, ( entry_ptr->header.size == entry_ptr->size ) ); HDassert( op_ptr != NULL ); HDassert( ( 0 <= entry_ptr->type ) && - ( entry_ptr->type < NUMBER_OF_ENTRY_TYPES ) ); + ( entry_ptr->type < NUMBER_OF_ENTRY_TYPES ) ); HDassert( ( 0 <= entry_ptr->index ) && ( entry_ptr->index <= max_indices[entry_ptr->type] ) ); HDassert( ( 0 <= op_ptr->type ) && @@ -1774,26 +1742,27 @@ resize_entry(H5F_t * file_ptr, if ( pass ) { - 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 ); - if ( in_cache ) { H5C_t *cache_ptr = file_ptr->shared->cache; HDassert( cache_ptr ); - if ( ! entry_in_cache(cache_ptr, type, idx) ) { + if ( ! entry_in_cache(cache_ptr, type, idx) ) { - pass = FALSE; + pass = FALSE; failure_mssg = "entry to be resized pinned is not in cache."; - } else { + } else { - if ( ! ( entry_ptr->header.is_pinned || entry_ptr->header.is_protected ) ) { + base_addr = entries[type]; + entry_ptr = &(base_addr[idx]); + + HDassert( entry_ptr->index == idx ); + HDassert( entry_ptr->type == type ); + HDassert( entry_ptr->cache_ptr == cache_ptr ); + HDassert( entry_ptr == entry_ptr->self ); + + if ( ! ( entry_ptr->header.is_pinned || entry_ptr->header.is_protected ) ) { pass = FALSE; failure_mssg = "entry to be resized is not pinned or protected."; @@ -2815,9 +2784,8 @@ insert_entry(H5F_t * file_ptr, void mark_entry_dirty(int32_t type, - int32_t idx) + int32_t idx) { - /* const char * fcn_name = "mark_pinned_entry_dirty()"; */ herr_t result; test_entry_t * base_addr; test_entry_t * entry_ptr; @@ -2865,7 +2833,7 @@ mark_entry_dirty(int32_t type, /*------------------------------------------------------------------------- * Function: move_entry() * - * Purpose: move the entry indicated by the type and index to its + * Purpose: Move 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. * @@ -2890,70 +2858,73 @@ move_entry(H5C_t * cache_ptr, 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] ) ); + if ( pass ) { - base_addr = entries[type]; - entry_ptr = &(base_addr[idx]); + HDassert( cache_ptr ); + HDassert( ( 0 <= type ) && ( type < NUMBER_OF_ENTRY_TYPES ) ); + HDassert( ( 0 <= idx ) && ( idx <= max_indices[type] ) ); - HDassert( entry_ptr->index == idx ); - HDassert( entry_ptr->type == type ); - HDassert( entry_ptr == entry_ptr->self ); - HDassert( entry_ptr->cache_ptr == cache_ptr ); - HDassert( !(entry_ptr->is_protected) ); - HDassert( !(entry_ptr->header.is_protected) ); + 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->cache_ptr == cache_ptr ); + HDassert( !(entry_ptr->is_protected) ); + HDassert( !(entry_ptr->header.is_protected) ); - if ( entry_ptr->at_main_addr && !main_addr ) { - /* move to alt addr */ + if ( entry_ptr->at_main_addr && !main_addr ) { - HDassert( entry_ptr->addr == entry_ptr->main_addr ); + /* move to alt addr */ - done = FALSE; - old_addr = entry_ptr->addr; - new_addr = entry_ptr->alt_addr; + HDassert( entry_ptr->addr == entry_ptr->main_addr ); - } else if ( !(entry_ptr->at_main_addr) && main_addr ) { + done = FALSE; + old_addr = entry_ptr->addr; + new_addr = entry_ptr->alt_addr; - /* move to main addr */ + } else if ( !(entry_ptr->at_main_addr) && main_addr ) { - HDassert( entry_ptr->addr == entry_ptr->alt_addr ); + /* move to main addr */ - done = FALSE; - old_addr = entry_ptr->addr; - new_addr = entry_ptr->main_addr; - } + HDassert( entry_ptr->addr == entry_ptr->alt_addr ); - if ( ! done ) { + done = FALSE; + old_addr = entry_ptr->addr; + new_addr = entry_ptr->main_addr; + } - entry_ptr->is_dirty = TRUE; + if ( ! done ) { - result = H5C_move_entry(cache_ptr, &(types[type]), - old_addr, new_addr); - } + entry_ptr->is_dirty = TRUE; - if ( ! done ) { + result = H5C_move_entry(cache_ptr, &(types[type]), + old_addr, new_addr); + } - if ( ( result < 0 ) || - ( ( ! ( entry_ptr->header.destroy_in_progress ) ) && - ( entry_ptr->header.addr != new_addr ) ) ) { + if ( ! done ) { - pass = FALSE; - failure_mssg = "error in H5C_move_entry()."; + if ( ( result < 0 ) || + ( ( ! ( entry_ptr->header.destroy_in_progress ) ) && + ( entry_ptr->header.addr != new_addr ) ) ) { - } else { + pass = FALSE; + failure_mssg = "error in H5C_move_entry()."; + + } else { - entry_ptr->addr = new_addr; - entry_ptr->at_main_addr = main_addr; + entry_ptr->addr = new_addr; + entry_ptr->at_main_addr = main_addr; + } } - } - HDassert( ((entry_ptr->header).type)->id == type ); + HDassert( ((entry_ptr->header).type)->id == type ); - HDassert( entry_ptr->header.is_dirty ); - HDassert( entry_ptr->is_dirty ); + HDassert( entry_ptr->header.is_dirty ); + HDassert( entry_ptr->is_dirty ); + } return; @@ -2980,7 +2951,6 @@ protect_entry(H5F_t * file_ptr, int32_t type, int32_t idx) { - /* const char * fcn_name = "protect_entry()"; */ H5C_t * cache_ptr; test_entry_t * base_addr; test_entry_t * entry_ptr; @@ -3155,7 +3125,6 @@ unpin_entry(int32_t type, test_entry_t * entry_ptr; if ( pass ) { - HDassert( ( 0 <= type ) && ( type < NUMBER_OF_ENTRY_TYPES ) ); HDassert( ( 0 <= idx ) && ( idx <= max_indices[type] ) ); @@ -3214,8 +3183,6 @@ unprotect_entry(H5F_t * file_ptr, int32_t idx, unsigned int flags) { - /* const char * fcn_name = "unprotect_entry()"; */ - H5C_t *cache_ptr; herr_t result; hbool_t pin_flag_set; hbool_t unpin_flag_set; @@ -3223,10 +3190,6 @@ unprotect_entry(H5F_t * file_ptr, test_entry_t * entry_ptr; if ( pass ) { - - cache_ptr = file_ptr->shared->cache; - - HDassert( cache_ptr ); HDassert( ( 0 <= type ) && ( type < NUMBER_OF_ENTRY_TYPES ) ); HDassert( ( 0 <= idx ) && ( idx <= max_indices[type] ) ); @@ -3236,7 +3199,6 @@ unprotect_entry(H5F_t * file_ptr, HDassert( entry_ptr->index == idx ); HDassert( entry_ptr->type == type ); HDassert( entry_ptr == entry_ptr->self ); - HDassert( entry_ptr->cache_ptr == cache_ptr ); HDassert( entry_ptr->header.is_protected ); HDassert( entry_ptr->is_protected ); @@ -3261,26 +3223,6 @@ unprotect_entry(H5F_t * file_ptr, ( entry_ptr->size != entry_ptr->header.size ) || ( entry_ptr->addr != entry_ptr->header.addr ) ) { -#if 1 /* JRM */ - if ( result < 0 ) { - HDfprintf(stdout, "result is negative.\n"); - } - if ( ( entry_ptr->header.is_protected ) && - ( ( ! ( entry_ptr->is_read_only ) ) || - ( entry_ptr->ro_ref_count <= 0 ) ) ) { - HDfprintf(stdout, "protected and not RO or refcnt <= 0.\n"); - } - if ( entry_ptr->header.type != &(types[type]) ) { - HDfprintf(stdout, "type disagreement.\n"); - } - if ( entry_ptr->size != entry_ptr->header.size ) { - HDfprintf(stdout, "size disagreement.\n"); - } - if ( entry_ptr->addr != entry_ptr->header.addr ) { - HDfprintf(stdout, "addr disagreement.\n"); - } -#endif /* JRM */ - pass = FALSE; failure_mssg = "error in H5C_unprotect()."; @@ -4584,3 +4526,399 @@ hl_col_major_scan_backward(H5F_t * file_ptr, } /* hl_col_major_scan_backward() */ + +/*** H5AC level utility functions ***/ + + +/*------------------------------------------------------------------------- + * 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 + * + *------------------------------------------------------------------------- + */ + +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 = 0; + int64_t cache_accesses = 0; + 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 = (H5F_t *)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 ( ! DBL_REL_EQUAL(hit_rate, expected_hit_rate, 0.00001) ) { + + 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 + * + *------------------------------------------------------------------------- + */ + +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 = (H5F_t *)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: 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 + * + *------------------------------------------------------------------------- + */ + +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 = (H5F_t *)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 presume 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() */ + |