diff options
Diffstat (limited to 'src/H5C.c')
-rw-r--r-- | src/H5C.c | 453 |
1 files changed, 443 insertions, 10 deletions
@@ -2596,6 +2596,10 @@ static herr_t H5C__autoadjust__ageout__remove_all_markers(H5C_t * cache_ptr); static herr_t H5C__autoadjust__ageout__remove_excess_markers(H5C_t * cache_ptr); +static herr_t H5C__flash_increase_cache_size(H5C_t * cache_ptr, + size_t old_entry_size, + size_t new_entry_size); + static herr_t H5C_flush_single_entry(H5F_t * f, hid_t primary_dxpl_id, hid_t secondary_dxpl_id, @@ -2836,8 +2840,12 @@ done: * ro_ref_count fields. * * JRM -- 7/27/07 -* Added initialization for the new evictions_enabled -* field of H5C_t. + * Added initialization for the new evictions_enabled + * field of H5C_t. + * + * JRM -- 12/31/07 + * Added initialization for the new flash cache size increase + * related fields of H5C_t. * *------------------------------------------------------------------------- */ @@ -2954,6 +2962,8 @@ H5C_create(size_t max_cache_size, cache_ptr->dLRU_tail_ptr = NULL; cache_ptr->size_increase_possible = FALSE; + cache_ptr->flash_size_increase_possible = FALSE; + cache_ptr->flash_size_increase_threshold = 0; cache_ptr->size_decrease_possible = FALSE; cache_ptr->resize_enabled = FALSE; cache_ptr->cache_full = FALSE; @@ -2974,6 +2984,11 @@ H5C_create(size_t max_cache_size, (cache_ptr->resize_ctl).apply_max_increment = TRUE; (cache_ptr->resize_ctl).max_increment = H5C__DEF_AR_MAX_INCREMENT; + (cache_ptr->resize_ctl).flash_incr_mode = H5C_flash_incr__off; + (cache_ptr->resize_ctl).flash_multiple = 1.0; + (cache_ptr->resize_ctl).flash_threshold = 0.25; + + (cache_ptr->resize_ctl).decr_mode = H5C_decr__off; (cache_ptr->resize_ctl).upper_hr_threshold = H5C__DEF_AR_UPPER_THRESHHOLD; (cache_ptr->resize_ctl).decrement = H5C__DEF_AR_DECREMENT; @@ -3079,6 +3094,9 @@ done: * Updated function for display the new prefix field of * H5C_t in output. * + * JRM 12/31/07 + * Updated function to handle flash size increases. + * *------------------------------------------------------------------------- */ void @@ -3125,6 +3143,24 @@ H5C_def_auto_resize_rpt_fcn(H5C_t * cache_ptr, new_min_clean_size); break; + case flash_increase: + HDassert( old_max_cache_size < new_max_cache_size ); + + HDfprintf(stdout, + "%sflash cache resize(%d) -- size threshold = %Zu.\n", + cache_ptr->prefix, + (int)((cache_ptr->resize_ctl).flash_incr_mode), + cache_ptr->flash_size_increase_threshold); + + HDfprintf(stdout, + "%s cache size increased from (%Zu/%Zu) to (%Zu/%Zu).\n", + cache_ptr->prefix, + old_max_cache_size, + old_min_clean_size, + new_max_cache_size, + new_min_clean_size); + break; + case decrease: HDassert( old_max_cache_size > new_max_cache_size ); @@ -4434,6 +4470,9 @@ done: * Added code to disable evictions when the new * evictions_enabled field is FALSE. * + * JRM -- 12/31/07 + * Added code supporting flash cache size increases. + * *------------------------------------------------------------------------- */ @@ -4447,6 +4486,7 @@ H5C_insert_entry(H5F_t * f, void * thing, unsigned int flags) { + const char * fcn_name = "H5C_insert_entry()"; herr_t result; herr_t ret_value = SUCCEED; /* Return value */ hbool_t first_flush = TRUE; @@ -4524,6 +4564,18 @@ H5C_insert_entry(H5F_t * f, H5C__RESET_CACHE_ENTRY_STATS(entry_ptr) + if ( ( cache_ptr->flash_size_increase_possible ) && + ( entry_ptr->size > cache_ptr->flash_size_increase_threshold ) ) { + + result = H5C__flash_increase_cache_size(cache_ptr, 0, entry_ptr->size); + + if ( result < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, \ + "H5C__flash_increase_cache_size failed.") + } + } + if ( ( cache_ptr->evictions_enabled ) && ( (cache_ptr->index_size + entry_ptr->size) > cache_ptr->max_cache_size ) ) { @@ -4999,7 +5051,9 @@ done: * * Modifications: * - * None + * Added code to do a flash cache size increase if + * appropriate. + * JRM -- 1/11/08 * *------------------------------------------------------------------------- */ @@ -5010,6 +5064,8 @@ H5C_mark_pinned_entry_dirty(H5C_t * cache_ptr, size_t new_size) { herr_t ret_value = SUCCEED; /* Return value */ + herr_t result; + size_t size_increase; H5C_cache_entry_t * entry_ptr; FUNC_ENTER_NOAPI(H5C_mark_pinned_entry_dirty, FAIL) @@ -5039,6 +5095,29 @@ H5C_mark_pinned_entry_dirty(H5C_t * cache_ptr, /* update for change in entry size if necessary */ if ( ( size_changed ) && ( entry_ptr->size != new_size ) ) { + /* do a flash cache size increase if appropriate */ + if ( cache_ptr->flash_size_increase_possible ) { + + if ( new_size > entry_ptr->size ) { + + size_increase = new_size - entry_ptr->size; + + if ( size_increase >= + cache_ptr->flash_size_increase_threshold ) { + + result = H5C__flash_increase_cache_size(cache_ptr, + entry_ptr->size, + new_size); + + if ( result < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, \ + "H5C__flash_increase_cache_size failed.") + } + } + } + } + /* update the protected entry list */ H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr->pel_len), \ (cache_ptr->pel_size), \ @@ -5371,7 +5450,9 @@ done: * * Modifications: * - * None + * Added code to apply a flash cache size increment if + * appropriate. + * JRM -- 1/11/08 * *------------------------------------------------------------------------- */ @@ -5380,8 +5461,11 @@ H5C_resize_pinned_entry(H5C_t * cache_ptr, void * thing, size_t new_size) { + const char * fcn_name = "H5C_resize_pinned_entry()"; herr_t ret_value = SUCCEED; /* Return value */ + herr_t result; H5C_cache_entry_t * entry_ptr; + size_t size_increase; FUNC_ENTER_NOAPI(H5C_resize_pinned_entry, FAIL) @@ -5417,6 +5501,29 @@ H5C_resize_pinned_entry(H5C_t * cache_ptr, /* update for change in entry size if necessary */ if ( entry_ptr->size != new_size ) { + /* do a flash cache size increase if appropriate */ + if ( cache_ptr->flash_size_increase_possible ) { + + if ( new_size > entry_ptr->size ) { + + size_increase = new_size - entry_ptr->size; + + if ( size_increase >= + cache_ptr->flash_size_increase_threshold ) { + + result = H5C__flash_increase_cache_size(cache_ptr, + entry_ptr->size, + new_size); + + if ( result < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, \ + "H5C__flash_increase_cache_size failed.") + } + } + } + } + /* update the protected entry list */ H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr->pel_len), \ (cache_ptr->pel_size), \ @@ -5604,9 +5711,13 @@ done: * of cache entries. * * JRM -- 7/27/07 - * Added code supporting the new evictions_enabled fieled + * Added code supporting the new evictions_enabled field * in H5C_t. * + * JRM -- 1/3/08 + * Added to do a flash cache size increase if appropriate + * when a large entry is loaded. + * *------------------------------------------------------------------------- */ @@ -5621,6 +5732,7 @@ H5C_protect(H5F_t * f, void * udata2, unsigned flags) { + const char * fcn_name = "H5C_protect()"; hbool_t hit; hbool_t first_flush; hbool_t have_write_permitted = FALSE; @@ -5678,7 +5790,25 @@ H5C_protect(H5F_t * f, entry_ptr = (H5C_cache_entry_t *)thing; - /* try to free up some space if necessary and if evictions are permitted */ + /* If the entry is very large, and we are configured to allow it, + * we may wish to perform a flash cache size increase. + */ + if ( ( cache_ptr->flash_size_increase_possible ) && + ( entry_ptr->size > cache_ptr->flash_size_increase_threshold ) ) { + + result = H5C__flash_increase_cache_size(cache_ptr, 0, + entry_ptr->size); + + if ( result < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, \ + "H5C__flash_increase_cache_size failed.") + } + } + + /* try to free up some space if necessary and if evictions are + * permitted + */ if ( ( cache_ptr->evictions_enabled ) && ( (cache_ptr->index_size + entry_ptr->size) > cache_ptr->max_cache_size ) ) { @@ -5978,6 +6108,10 @@ done: * if the new configuration forces an immediate reduction * in cache size. * + * JRM -- 12/31/07 + * Added code supporting the new flash cache size increase + * code. + * *------------------------------------------------------------------------- */ @@ -5985,6 +6119,7 @@ herr_t H5C_set_cache_auto_resize_config(H5C_t * cache_ptr, H5C_auto_size_ctl_t *config_ptr) { + const char *fcn_name = "H5C_set_cache_auto_resize_config()"; herr_t ret_value = SUCCEED; /* Return value */ herr_t result; size_t new_max_cache_size; @@ -6039,8 +6174,10 @@ H5C_set_cache_auto_resize_config(H5C_t * cache_ptr, "conflicting threshold fields in new config.") } - cache_ptr->size_increase_possible = TRUE; /* will set to FALSE if needed */ - cache_ptr->size_decrease_possible = TRUE; /* will set to FALSE if needed */ + /* will set the increase possible fields to FALSE later if needed */ + cache_ptr->size_increase_possible = TRUE; + cache_ptr->flash_size_increase_possible = TRUE; + cache_ptr->size_decrease_possible = TRUE; switch ( config_ptr->incr_mode ) { @@ -6062,6 +6199,11 @@ H5C_set_cache_auto_resize_config(H5C_t * cache_ptr, HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Unknown incr_mode?!?!?.") } + /* logically, this is were configuration for flash cache size increases + * should go. However, this configuration depends on max_cache_size, so + * we wait until the end of the function, when this field is set. + */ + switch ( config_ptr->decr_mode ) { case H5C_decr__off: @@ -6106,9 +6248,13 @@ H5C_set_cache_auto_resize_config(H5C_t * cache_ptr, if ( config_ptr->max_size == config_ptr->min_size ) { cache_ptr->size_increase_possible = FALSE; + cache_ptr->flash_size_increase_possible = FALSE; cache_ptr->size_decrease_possible = FALSE; } + /* flash_size_increase_possible is intentionally omitted from the + * following: + */ cache_ptr->resize_enabled = cache_ptr->size_increase_possible || cache_ptr->size_decrease_possible; @@ -6196,6 +6342,37 @@ H5C_set_cache_auto_resize_config(H5C_t * cache_ptr, } } + /* configure flash size increase facility. We wait until the + * end of the function, as we need the max_cache_size set before + * we start to keep things simple. + * + * If we haven't already ruled out flash cache size increases above, + * go ahead and configure it. + */ + + if ( cache_ptr->flash_size_increase_possible ) { + + switch ( config_ptr->flash_incr_mode ) + { + case H5C_flash_incr__off: + cache_ptr->flash_size_increase_possible = FALSE; + break; + + case H5C_flash_incr__add_space: + cache_ptr->flash_size_increase_possible = TRUE; + cache_ptr->flash_size_increase_threshold = + (size_t) + (((double)(cache_ptr->max_cache_size)) * + ((cache_ptr->resize_ctl).flash_threshold)); + break; + + default: /* should be unreachable */ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "Unknown flash_incr_mode?!?!?.") + break; + } + } + done: FUNC_LEAVE_NOAPI(ret_value) @@ -7095,6 +7272,9 @@ done: * Also added sanity checks using the new is_read_only and * ro_ref_count parameters. * + * JRM -- 12/31/07 + * Modified funtion to support flash cache resizes. + * *------------------------------------------------------------------------- */ herr_t @@ -7108,6 +7288,7 @@ H5C_unprotect(H5F_t * f, unsigned int flags, size_t new_size) { + const char * fcn_name = "H5C_unprotect()"; hbool_t deleted; hbool_t dirtied; hbool_t set_flush_marker; @@ -7118,6 +7299,8 @@ H5C_unprotect(H5F_t * f, hbool_t clear_entry = FALSE; #endif /* H5_HAVE_PARALLEL */ herr_t ret_value = SUCCEED; /* Return value */ + herr_t result; + size_t size_increase = 0; H5C_cache_entry_t * entry_ptr; H5C_cache_entry_t * test_entry_ptr; @@ -7265,6 +7448,29 @@ H5C_unprotect(H5F_t * f, /* update for change in entry size if necessary */ if ( ( size_changed ) && ( entry_ptr->size != new_size ) ) { + /* do a flash cache size increase if appropriate */ + if ( cache_ptr->flash_size_increase_possible ) { + + if ( new_size > entry_ptr->size ) { + + size_increase = new_size - entry_ptr->size; + + if ( size_increase >= + cache_ptr->flash_size_increase_threshold ) { + + result = H5C__flash_increase_cache_size(cache_ptr, + entry_ptr->size, + new_size); + + if ( result < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, \ + "H5C__flash_increase_cache_size failed.") + } + } + } + } + /* update the protected list */ H5C__DLL_UPDATE_FOR_SIZE_CHANGE((cache_ptr->pl_len), \ (cache_ptr->pl_size), \ @@ -7458,7 +7664,9 @@ done: * * Modifications: * - * None. + * Added validation for the flash increment fields. + * + * JRM -- 12/31/07 * *------------------------------------------------------------------------- */ @@ -7560,7 +7768,7 @@ H5C_validate_resize_config(H5C_auto_size_ctl_t * config_ptr, ( config_ptr->apply_max_increment != FALSE ) ) { HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \ - "apply_max_increment must be either TRUE or FALSE"); + "apply_max_increment must be either TRUE or FALSE"); } /* no need to check max_increment, as it is a size_t, @@ -7568,6 +7776,33 @@ H5C_validate_resize_config(H5C_auto_size_ctl_t * config_ptr, */ } /* H5C_incr__threshold */ + switch ( config_ptr->flash_incr_mode ) + { + case H5C_flash_incr__off: + /* nothing to do here */ + break; + + case H5C_flash_incr__add_space: + if ( ( config_ptr->flash_multiple < 0.1 ) || + ( config_ptr->flash_multiple > 10.0 ) ) { + + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \ + "flash_multiple must be in the range [0.1, 10.0]"); + } + + if ( ( config_ptr->flash_threshold < 0.1 ) || + ( config_ptr->flash_threshold > 1.0 ) ) { + + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \ + "flash_threshold must be in the range [0.1, 1.0]"); + } + break; + + default: + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \ + "Invalid flash_incr_mode"); + break; + } } /* H5C_RESIZE_CFG__VALIDATE_INCREMENT */ @@ -7707,6 +7942,9 @@ done: * reduction, and to adjust to changes in the * H5C_auto_size_ctl_t structure. * + * JRM -- 1/5/08 + * Added support for flash cache size increases. + * *------------------------------------------------------------------------- */ @@ -7990,6 +8228,30 @@ H5C__auto_adjust_cache_size(H5C_t * cache_ptr, cache_ptr->size_decreased = TRUE; } + + /* update flash cache size increase fields as appropriate */ + if ( cache_ptr->flash_size_increase_possible ) { + + switch ( (cache_ptr->resize_ctl).flash_incr_mode ) + { + case H5C_flash_incr__off: + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "flash_size_increase_possible but H5C_flash_incr__off?!") + break; + + case H5C_flash_incr__add_space: + cache_ptr->flash_size_increase_threshold = + (size_t) + (((double)(cache_ptr->max_cache_size)) * + ((cache_ptr->resize_ctl).flash_threshold)); + break; + + default: /* should be unreachable */ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "Unknown flash_incr_mode?!?!?.") + break; + } + } } if ( (cache_ptr->resize_ctl).rpt_fcn != NULL ) { @@ -8741,6 +9003,177 @@ done: } /* H5C__autoadjust__ageout__remove_excess_markers() */ +/*------------------------------------------------------------------------- + * + * Function: H5C__flash_increase_cache_size + * + * Purpose: If there is not at least new_entry_size - old_entry_size + * bytes of free space in the cache and the current + * max_cache_size is less than (cache_ptr->resize_ctl).max_size, + * perform a flash increase in the cache size and then reset + * the full cache hit rate statistics, and exit. + * + * Return: Non-negative on success/Negative on failure. + * + * Programmer: John Mainzer, 12/31/07 + * + * Modifications: + * + * None. + * + *------------------------------------------------------------------------- + */ + +static herr_t +H5C__flash_increase_cache_size(H5C_t * cache_ptr, + size_t old_entry_size, + size_t new_entry_size) +{ + const char * fcn_name = "H5C__flash_increase_cache_size()"; + herr_t ret_value = SUCCEED; /* Return value */ + size_t new_max_cache_size = 0; + size_t old_max_cache_size = 0; + size_t new_min_clean_size = 0; + size_t old_min_clean_size = 0; + size_t space_needed; + enum H5C_resize_status status = flash_increase; /* may change */ + double hit_rate; + + FUNC_ENTER_NOAPI_NOINIT(H5C__flash_increase_cache_size) +#if 0 + HDfprintf(stdout, "%s: old = %ld, new = %ld.\n", fcn_name, + (long)old_entry_size, (long)new_entry_size); +#endif + HDassert( cache_ptr ); + HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC ); + HDassert( cache_ptr->flash_size_increase_possible ); + HDassert( new_entry_size > cache_ptr->flash_size_increase_threshold ); + HDassert( old_entry_size < new_entry_size ); + + if ( old_entry_size >= new_entry_size ) { + + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "old_entry_size >= new_entry_size") + } + + space_needed = new_entry_size - old_entry_size; + + if ( ( (cache_ptr->index_size + space_needed) > + cache_ptr->max_cache_size ) && + ( cache_ptr->max_cache_size < (cache_ptr->resize_ctl).max_size ) ) { + + /* we have work to do */ + + switch ( (cache_ptr->resize_ctl).flash_incr_mode ) + { + case H5C_flash_incr__off: + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "flash_size_increase_possible but H5C_flash_incr__off?!") + break; + + case H5C_flash_incr__add_space: + if ( cache_ptr->index_size < cache_ptr->max_cache_size ) { + + HDassert( (cache_ptr->max_cache_size - cache_ptr->index_size) + < space_needed ); + space_needed -= cache_ptr->max_cache_size - cache_ptr->index_size; + } + space_needed = + (size_t)(((double)space_needed) * + (cache_ptr->resize_ctl).flash_multiple); + + new_max_cache_size = cache_ptr->max_cache_size + space_needed; + + break; + + default: /* should be unreachable */ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "Unknown flash_incr_mode?!?!?.") + break; + } + + if ( new_max_cache_size > (cache_ptr->resize_ctl).max_size ) { + + new_max_cache_size = (cache_ptr->resize_ctl).max_size; + } + + HDassert( new_max_cache_size > cache_ptr->max_cache_size ); + + new_min_clean_size = (size_t) + ((double)new_max_cache_size * + ((cache_ptr->resize_ctl).min_clean_fraction)); + + HDassert( new_min_clean_size <= new_max_cache_size ); + + old_max_cache_size = cache_ptr->max_cache_size; + old_min_clean_size = cache_ptr->min_clean_size; + + cache_ptr->max_cache_size = new_max_cache_size; + cache_ptr->min_clean_size = new_min_clean_size; + + /* update flash cache size increase fields as appropriate */ + HDassert ( cache_ptr->flash_size_increase_possible ); + + switch ( (cache_ptr->resize_ctl).flash_incr_mode ) + { + case H5C_flash_incr__off: + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "flash_size_increase_possible but H5C_flash_incr__off?!") + break; + + case H5C_flash_incr__add_space: + cache_ptr->flash_size_increase_threshold = + (size_t) + (((double)(cache_ptr->max_cache_size)) * + ((cache_ptr->resize_ctl).flash_threshold)); + break; + + default: /* should be unreachable */ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "Unknown flash_incr_mode?!?!?.") + break; + } + + /* note that we don't cycle the epoch markers. We can + * argue either way as to whether we should, but for now + * we don't. + */ + + if ( (cache_ptr->resize_ctl).rpt_fcn != NULL ) { + + /* get the hit rate for the reporting function. Should still + * be good as we havent reset the hit rate statistics. + */ + if ( H5C_get_cache_hit_rate(cache_ptr, &hit_rate) != SUCCEED ) { + + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't get hit rate.") + } + + (*((cache_ptr->resize_ctl).rpt_fcn)) + (cache_ptr, + H5C__CURR_AUTO_RESIZE_RPT_FCN_VER, + hit_rate, + status, + old_max_cache_size, + new_max_cache_size, + old_min_clean_size, + new_min_clean_size); + } + + if ( H5C_reset_cache_hit_rate_stats(cache_ptr) != SUCCEED ) { + + /* this should be impossible... */ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "H5C_reset_cache_hit_rate_stats failed.") + } + } + +done: + + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5C__flash_increase_cache_size() */ + /*------------------------------------------------------------------------- * Function: H5C_flush_invalidate_cache |