diff options
author | John Mainzer <mainzer@hdfgroup.org> | 2006-07-13 17:59:39 (GMT) |
---|---|---|
committer | John Mainzer <mainzer@hdfgroup.org> | 2006-07-13 17:59:39 (GMT) |
commit | 801b5b09f26dac69e77bb4a794f2785977f9eb7e (patch) | |
tree | f96577fe353fe34c5ad7be4fcb72b62cebdcda4d /src/H5AC.c | |
parent | 8db4fe6d16d3e51e3d6122db02aaf888b911ebe0 (diff) | |
download | hdf5-801b5b09f26dac69e77bb4a794f2785977f9eb7e.zip hdf5-801b5b09f26dac69e77bb4a794f2785977f9eb7e.tar.gz hdf5-801b5b09f26dac69e77bb4a794f2785977f9eb7e.tar.bz2 |
[svn-r12462] Committed a variety of metadata cache related changes:
1) Added trace file support to the metadata cache. This allows capture
of all metadata cache calls in trace files for purposes of optimization
and debuging.
2) Added an expunge entry function. This allows an entry to be deleteded
from the cache without writing it to disk even if it is dirty.
3) Added a function call to resize pinned entries.
4) Added code to deal with entries that are dirty on load. This is
needed in support of a bug fix which can alter object headers on
load to repair files.
5) Added progress reporting code to the "MDC API smoke check" test in
cache_api.c. To enable the progress reporting, set report_progress
to TRUE in mdc_api_call_smoke_check().
Tested with h5committest, and a parallel test on phoenix (dual athelon
linux box).
Diffstat (limited to 'src/H5AC.c')
-rw-r--r-- | src/H5AC.c | 897 |
1 files changed, 883 insertions, 14 deletions
@@ -742,6 +742,10 @@ done: * Added code to free the auxiliary structure and its * associated slist if present. * JRM - 6/28/05 + * + * Added code to close the trace file if it is present. + * + * JRM - 6/8/06 * *------------------------------------------------------------------------- */ @@ -768,6 +772,14 @@ H5AC_dest(H5F_t *f, hid_t dxpl_id) } #endif /* H5_HAVE_PARALLEL */ +#if H5AC__TRACE_FILE_ENABLED + if ( H5AC_close_trace_file(cache) < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "H5AC_close_trace_file() failed.") + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + if ( H5C_dest(f, dxpl_id, H5AC_noblock_dxpl_id, cache) < 0 ) { HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "can't destroy cache") @@ -802,6 +814,92 @@ done: /*------------------------------------------------------------------------- + * Function: H5AC_expunge_entry + * + * Purpose: Expunge the target entry from the cache without writing it + * to disk even if it is dirty. The entry must not be either + * pinned or protected. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: John Mainzer + * 6/30/06 + * + * Modifications: + * + * None. + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC_expunge_entry(H5F_t *f, + hid_t dxpl_id, + const H5AC_class_t *type, + haddr_t addr) +{ + herr_t result; + herr_t ret_value=SUCCEED; /* Return value */ + H5AC_t * cache_ptr = NULL; +#if H5AC__TRACE_FILE_ENABLED + char trace[128] = ""; + FILE * trace_file_ptr = NULL; +#endif /* H5AC__TRACE_FILE_ENABLED */ + + FUNC_ENTER_NOAPI(H5AC_expunge_entry, FAIL) + + HDassert(f); + HDassert(f->shared); + HDassert(f->shared->cache); + HDassert(type); + HDassert(type->clear); + HDassert(type->dest); + HDassert(H5F_addr_defined(addr)); + + cache_ptr = f->shared->cache; + +#if H5AC__TRACE_FILE_ENABLED + /* For the expunge entry call, only the addr, and type id are really + * necessary in the trace file. Write the return value to catch occult + * errors. + */ + if ( ( cache_ptr != NULL ) && + ( H5C_get_trace_file_ptr(cache_ptr, &trace_file_ptr) >= 0 ) && + ( trace_file_ptr != NULL ) ) { + + sprintf(trace, "H5AC_expunge_entry %lx %d", + (unsigned long)addr, + (int)(type->id)); + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + + result = H5C_expunge_entry(f, + dxpl_id, + H5AC_noblock_dxpl_id, + cache_ptr, + type, + addr); + + if ( result < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_CANTEXPUNGE, FAIL, \ + "H5C_expunge_entry() failed.") + } + +done: + +#if H5AC__TRACE_FILE_ENABLED + if ( trace_file_ptr != NULL ) { + + HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5AC_expunge_entry() */ + + +/*------------------------------------------------------------------------- * Function: H5AC_flush * * Purpose: Flush (and possibly destroy) the metadata cache associated @@ -871,6 +969,9 @@ done: * JRM -- 5/11/06 * Added call to the write_done callback. * + * JRM -- 6/6/06 + * Added trace file support. + * *------------------------------------------------------------------------- */ herr_t @@ -882,6 +983,10 @@ H5AC_flush(H5F_t *f, hid_t dxpl_id, unsigned flags) H5AC_aux_t * aux_ptr = NULL; int mpi_code; #endif /* H5_HAVE_PARALLEL */ +#if H5AC__TRACE_FILE_ENABLED + char trace[128] = ""; + FILE * trace_file_ptr = NULL; +#endif /* H5AC__TRACE_FILE_ENABLED */ FUNC_ENTER_NOAPI(H5AC_flush, FAIL) @@ -889,6 +994,20 @@ H5AC_flush(H5F_t *f, hid_t dxpl_id, unsigned flags) HDassert(f); HDassert(f->shared->cache); +#if H5AC__TRACE_FILE_ENABLED + /* For the flush, only the flags are really necessary in the trace file. + * Write the result to catch occult errors. + */ + if ( ( f != NULL ) && + ( f->shared != NULL ) && + ( f->shared->cache != NULL ) && + ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) && + ( trace_file_ptr != NULL ) ) { + + sprintf(trace, "H5AC_flush 0x%x", flags); + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + #ifdef H5_HAVE_PARALLEL aux_ptr = f->shared->cache->aux_ptr; @@ -972,6 +1091,13 @@ H5AC_flush(H5F_t *f, hid_t dxpl_id, unsigned flags) done: +#if H5AC__TRACE_FILE_ENABLED + if ( trace_file_ptr != NULL ) { + + HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_flush() */ @@ -1118,6 +1244,9 @@ done: * the PHDF5 case. It should have no effect on either the * serial or FPHSD5 cases. * + * JRM - 6/6/06 + * Added trace file support. + * *------------------------------------------------------------------------- */ @@ -1131,6 +1260,11 @@ H5AC_set(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, void * #ifdef H5_HAVE_PARALLEL H5AC_aux_t * aux_ptr = NULL; #endif /* H5_HAVE_PARALLEL */ +#if H5AC__TRACE_FILE_ENABLED + char trace[128] = ""; + size_t trace_entry_size = 0; + FILE * trace_file_ptr = NULL; +#endif /* H5AC__TRACE_FILE_ENABLED */ FUNC_ENTER_NOAPI(H5AC_set, FAIL) @@ -1142,6 +1276,27 @@ H5AC_set(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, void * HDassert(H5F_addr_defined(addr)); HDassert(thing); +#if H5AC__TRACE_FILE_ENABLED + /* For the insert, only the addr, size, type id and flags are really + * necessary in the trace file. Write the result to catch occult + * errors. + * + * Note that some data is not available right now -- put what we can + * in the trace buffer now, and fill in the rest at the end. + */ + if ( ( f != NULL ) && + ( f->shared != NULL ) && + ( f->shared->cache != NULL ) && + ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) && + ( trace_file_ptr != NULL ) ) { + + sprintf(trace, "H5AC_set 0x%lx %d 0x%x", + (unsigned long)addr, + type->id, + flags); + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + /* Get local copy of this information */ cache = f->shared->cache; info = (H5AC_info_t *)thing; @@ -1181,6 +1336,14 @@ H5AC_set(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, void * HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, "H5C_insert_entry() failed") } +#if H5AC__TRACE_FILE_ENABLED + if ( trace_file_ptr != NULL ) { + + /* make note of the entry size */ + trace_entry_size = ((H5C_cache_entry_t *)thing)->size; + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + #ifdef H5_HAVE_PARALLEL if ( ( aux_ptr != NULL ) && ( aux_ptr->dirty_bytes >= aux_ptr->dirty_bytes_threshold ) ) { @@ -1199,6 +1362,15 @@ H5AC_set(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, void * done: +#if H5AC__TRACE_FILE_ENABLED + if ( trace_file_ptr != NULL ) { + + HDfprintf(trace_file_ptr, "%s %d %d\n", trace, + (int)trace_entry_size, + (int)ret_value); + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_set() */ @@ -1220,7 +1392,7 @@ done: * * Modifications: * - * None + * Added trace file support. JRM -- 6/6/06 * *------------------------------------------------------------------------- */ @@ -1233,9 +1405,31 @@ H5AC_mark_pinned_entry_dirty(H5F_t * f, H5C_t *cache_ptr = f->shared->cache; herr_t result; herr_t ret_value = SUCCEED; /* Return value */ +#if H5AC__TRACE_FILE_ENABLED + char trace[128] = ""; + FILE * trace_file_ptr = NULL; +#endif /* H5AC__TRACE_FILE_ENABLED */ FUNC_ENTER_NOAPI(H5AC_mark_pinned_entry_dirty, FAIL) +#if H5AC__TRACE_FILE_ENABLED + /* For the mark pinned entry dirty call, only the addr, size_changed, + * and new_size are really necessary in the trace file. Write the result + * to catch occult errors. + */ + if ( ( f != NULL ) && + ( f->shared != NULL ) && + ( f->shared->cache != NULL ) && + ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) && + ( trace_file_ptr != NULL ) ) { + + sprintf(trace, "H5AC_mark_pinned_entry_dirty 0x%lx %d %d", + (unsigned long)(((H5C_cache_entry_t *)thing)->addr), + (int)size_changed, + (int)new_size); + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + #ifdef H5_HAVE_PARALLEL HDassert( cache_ptr ); @@ -1290,6 +1484,13 @@ H5AC_mark_pinned_entry_dirty(H5F_t * f, done: +#if H5AC__TRACE_FILE_ENABLED + if ( trace_file_ptr != NULL ) { + + HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_mark_pinned_entry_dirty() */ @@ -1311,7 +1512,7 @@ done: * * Modifications: * - * None + * Added trace file support. JRM -- 6/6/06 * *------------------------------------------------------------------------- */ @@ -1325,9 +1526,29 @@ H5AC_mark_pinned_or_protected_entry_dirty(H5F_t * f, #endif /* H5_HAVE_PARALLEL */ herr_t result; herr_t ret_value = SUCCEED; /* Return value */ +#if H5AC__TRACE_FILE_ENABLED + char trace[128] = ""; + FILE * trace_file_ptr = NULL; +#endif /* H5AC__TRACE_FILE_ENABLED */ FUNC_ENTER_NOAPI(H5AC_mark_pinned_or_protected_entry_dirty, FAIL) +#if H5AC__TRACE_FILE_ENABLED + /* For the mark pinned or protected entry dirty call, only the addr + * is really necessary in the trace file. Write the result to catch + * occult errors. + */ + if ( ( f != NULL ) && + ( f->shared != NULL ) && + ( f->shared->cache != NULL ) && + ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) && + ( trace_file_ptr != NULL ) ) { + + sprintf(trace, "H5AC_mark_pinned_or_protected_entry_dirty %lx", + (unsigned long)(((H5C_cache_entry_t *)thing)->addr)); + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + #ifdef H5_HAVE_PARALLEL HDassert( cache_ptr ); @@ -1366,6 +1587,13 @@ H5AC_mark_pinned_or_protected_entry_dirty(H5F_t * f, done: +#if H5AC__TRACE_FILE_ENABLED + if ( trace_file_ptr != NULL ) { + + HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_mark_pinned_entry_dirty() */ @@ -1411,6 +1639,9 @@ done: * To maintain this invarient, only rename entries immediately * after you unprotect them. * + * JRM - 6/6/06 + * Added trace file support. + * *------------------------------------------------------------------------- */ herr_t @@ -1421,6 +1652,10 @@ H5AC_rename(H5F_t *f, const H5AC_class_t *type, haddr_t old_addr, haddr_t new_ad #ifdef H5_HAVE_PARALLEL H5AC_aux_t * aux_ptr = NULL; #endif /* H5_HAVE_PARALLEL */ +#if H5AC__TRACE_FILE_ENABLED + char trace[128] = ""; + FILE * trace_file_ptr = NULL; +#endif /* H5AC__TRACE_FILE_ENABLED */ FUNC_ENTER_NOAPI(H5AC_rename, FAIL) @@ -1431,6 +1666,24 @@ H5AC_rename(H5F_t *f, const H5AC_class_t *type, haddr_t old_addr, haddr_t new_ad HDassert(H5F_addr_defined(new_addr)); HDassert(H5F_addr_ne(old_addr, new_addr)); +#if H5AC__TRACE_FILE_ENABLED + /* For the rename call, only the old addr and new addr are really + * necessary in the trace file. Include the type id so we don't have to + * look it up. Also write the result to catch occult errors. + */ + if ( ( f != NULL ) && + ( f->shared != NULL ) && + ( f->shared->cache != NULL ) && + ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) && + ( trace_file_ptr != NULL ) ) { + + sprintf(trace, "H5AC_rename %lx %lx %d", + (unsigned long)old_addr, + (unsigned long)new_addr, + (int)(type->id)); + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + #ifdef H5_HAVE_PARALLEL if ( NULL != (aux_ptr = f->shared->cache->aux_ptr) ) { @@ -1475,6 +1728,13 @@ H5AC_rename(H5F_t *f, const H5AC_class_t *type, haddr_t old_addr, haddr_t new_ad done: +#if H5AC__TRACE_FILE_ENABLED + if ( trace_file_ptr != NULL ) { + + HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_rename() */ @@ -1493,7 +1753,7 @@ done: * * Modifications: * - * None. + * Added trace file support. 6/6/06 * *------------------------------------------------------------------------- */ @@ -1504,9 +1764,28 @@ H5AC_pin_protected_entry(H5F_t * f, H5C_t *cache_ptr = f->shared->cache; herr_t result; herr_t ret_value = SUCCEED; /* Return value */ +#if H5AC__TRACE_FILE_ENABLED + char trace[128] = ""; + FILE * trace_file_ptr = NULL; +#endif /* H5AC__TRACE_FILE_ENABLED */ FUNC_ENTER_NOAPI(H5AC_pin_protected_entry, FAIL) +#if H5AC__TRACE_FILE_ENABLED + /* For the pin protected entry call, only the addr is really necessary + * in the trace file. Also write the result to catch occult errors. + */ + if ( ( f != NULL ) && + ( f->shared != NULL ) && + ( f->shared->cache != NULL ) && + ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) && + ( trace_file_ptr != NULL ) ) { + + sprintf(trace, "H5AC_pin_protected_entry %lx", + (unsigned long)(((H5C_cache_entry_t *)thing)->addr)); + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + result = H5C_pin_protected_entry(cache_ptr, thing); if ( result < 0 ) { @@ -1517,6 +1796,13 @@ H5AC_pin_protected_entry(H5F_t * f, done: +#if H5AC__TRACE_FILE_ENABLED + if ( trace_file_ptr != NULL ) { + + HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_pin_protected_entry() */ @@ -1579,6 +1865,9 @@ done: * in H5C.c, and then re-wrote the function as a wrapper for * H5C_protect(). * + * JRM - 6/6/06 + * Added trace file support. + * *------------------------------------------------------------------------- */ void * @@ -1590,8 +1879,14 @@ H5AC_protect(H5F_t *f, void *udata2, H5AC_protect_t UNUSED rw) { - void * thing = NULL; + /* char * fcn_name = "H5AC_protect"; */ + void * thing = (void *)NULL; void * ret_value; /* Return value */ +#if H5AC__TRACE_FILE_ENABLED + char trace[128] = ""; + size_t trace_entry_size = 0; + FILE * trace_file_ptr = NULL; +#endif /* H5AC__TRACE_FILE_ENABLED */ FUNC_ENTER_NOAPI(H5AC_protect, NULL) @@ -1603,6 +1898,24 @@ H5AC_protect(H5F_t *f, HDassert(type->load); HDassert(H5F_addr_defined(addr)); +#if H5AC__TRACE_FILE_ENABLED + /* For the protect call, only the addr and type id is really necessary + * in the trace file. Include the size of the entry protected as a + * sanity check. Also indicate whether the call was successful to + * catch occult errors. + */ + if ( ( f != NULL ) && + ( f->shared != NULL ) && + ( f->shared->cache != NULL ) && + ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) && + ( trace_file_ptr != NULL ) ) { + + sprintf(trace, "H5AC_protect %lx %d", + (unsigned long)addr, + (int)(type->id)); + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + thing = H5C_protect(f, dxpl_id, H5AC_noblock_dxpl_id, @@ -1617,17 +1930,146 @@ H5AC_protect(H5F_t *f, HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, "H5C_protect() failed.") } +#if H5AC__TRACE_FILE_ENABLED + if ( trace_file_ptr != NULL ) { + + /* make note of the entry size */ + trace_entry_size = ((H5C_cache_entry_t *)thing)->size; + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + /* Set return value */ ret_value = thing; done: +#if H5AC__TRACE_FILE_ENABLED + if ( trace_file_ptr != NULL ) { + + HDfprintf(trace_file_ptr, "%s %d %d\n", trace, + (int)trace_entry_size, + (int)(ret_value != NULL)); + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_protect() */ /*------------------------------------------------------------------------- + * Function: H5AC_resize_pinned_entry + * + * Purpose: Resize a pinned entry. The target entry MUST be + * be pinned, and MUST not be unprotected. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: John Mainzer + * 7/5/06 + * + * Modifications: + * + * None. + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC_resize_pinned_entry(H5F_t * f, + void * thing, + size_t new_size) +{ + H5C_t *cache_ptr = f->shared->cache; + herr_t result; + herr_t ret_value = SUCCEED; /* Return value */ +#if H5AC__TRACE_FILE_ENABLED + char trace[128] = ""; + FILE * trace_file_ptr = NULL; +#endif /* H5AC__TRACE_FILE_ENABLED */ + + FUNC_ENTER_NOAPI(H5AC_resize_pinned_entry, FAIL) + +#if H5AC__TRACE_FILE_ENABLED + /* For the resize pinned entry call, only the addr, and new_size are + * really necessary in the trace file. Write the result to catch + * occult errors. + */ + if ( ( f != NULL ) && + ( f->shared != NULL ) && + ( f->shared->cache != NULL ) && + ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) && + ( trace_file_ptr != NULL ) ) { + + sprintf(trace, "H5AC_resize_pinned_entry 0x%lx %d %d", + (unsigned long)(((H5C_cache_entry_t *)thing)->addr), + (int)new_size); + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + +#ifdef H5_HAVE_PARALLEL + + HDassert( cache_ptr ); + HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC ); + HDassert( thing ); + + if ( ( ((H5AC_info_t *)thing)->is_dirty == FALSE ) && + ( NULL != cache_ptr->aux_ptr) ) { + + H5AC_info_t * entry_ptr; + + entry_ptr = (H5AC_info_t *)thing; + + if ( ! ( entry_ptr->is_pinned ) ) { + + HGOTO_ERROR(H5E_CACHE, H5E_CANTRESIZE, FAIL, \ + "Entry isn't pinned??") + } + + if ( entry_ptr->is_protected ) { + + HGOTO_ERROR(H5E_CACHE, H5E_CANTRESIZE, FAIL, \ + "Entry is protected??") + } + + result = H5AC_log_dirtied_entry(cache_ptr, + entry_ptr, + entry_ptr->addr, + TRUE, + new_size); + + if ( result < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKDIRTY, FAIL, \ + "H5AC_log_dirtied_entry() failed.") + } + } +#endif /* H5_HAVE_PARALLEL */ + + result = H5C_resize_pinned_entry(cache_ptr, + thing, + new_size); + if ( result < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_CANTRESIZE, FAIL, \ + "H5C_resize_pinned_entry() failed.") + + } + +done: + +#if H5AC__TRACE_FILE_ENABLED + if ( trace_file_ptr != NULL ) { + + HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5AC_resize_pinned_entry() */ + + +/*------------------------------------------------------------------------- * Function: H5AC_unpin_entry() * * Purpose: Unpin a cache entry. The entry must be unprotected at @@ -1640,7 +2082,7 @@ done: * * Modifications: * - * None. + * Added code supporting the trace file. JRM -- 6/7/06 * *------------------------------------------------------------------------- */ @@ -1651,9 +2093,28 @@ H5AC_unpin_entry(H5F_t * f, H5C_t *cache_ptr = f->shared->cache; herr_t result; herr_t ret_value = SUCCEED; /* Return value */ +#if H5AC__TRACE_FILE_ENABLED + char trace[128] = ""; + FILE * trace_file_ptr = NULL; +#endif /* H5AC__TRACE_FILE_ENABLED */ FUNC_ENTER_NOAPI(H5AC_unpin_entry, FAIL) +#if H5AC__TRACE_FILE_ENABLED + /* For the unpin entry call, only the addr is really necessary + * in the trace file. Also write the result to catch occult errors. + */ + if ( ( f != NULL ) && + ( f->shared != NULL ) && + ( f->shared->cache != NULL ) && + ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) && + ( trace_file_ptr != NULL ) ) { + + sprintf(trace, "H5AC_unpin_entry %lx", + (unsigned long)(((H5C_cache_entry_t *)thing)->addr)); + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + result = H5C_unpin_entry(cache_ptr, thing); if ( result < 0 ) { @@ -1663,6 +2124,13 @@ H5AC_unpin_entry(H5F_t * f, done: +#if H5AC__TRACE_FILE_ENABLED + if ( trace_file_ptr != NULL ) { + + HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_unpin_entry() */ @@ -1756,6 +2224,9 @@ done: * H5C_cache_entry_t in the test to see if the entry has * been dirtied. * + * JRM - 6/7/06 + * Added support for the trace file. + * *------------------------------------------------------------------------- */ herr_t @@ -1770,6 +2241,12 @@ H5AC_unprotect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, #ifdef H5_HAVE_PARALLEL H5AC_aux_t * aux_ptr = NULL; #endif /* H5_HAVE_PARALLEL */ +#if H5AC__TRACE_FILE_ENABLED + char trace[128] = ""; + size_t trace_new_size = 0; + unsigned trace_flags = 0; + FILE * trace_file_ptr = NULL; +#endif /* H5AC__TRACE_FILE_ENABLED */ FUNC_ENTER_NOAPI(H5AC_unprotect, FAIL) @@ -1783,6 +2260,25 @@ H5AC_unprotect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, HDassert( ((H5AC_info_t *)thing)->addr == addr ); HDassert( ((H5AC_info_t *)thing)->type == type ); +#if H5AC__TRACE_FILE_ENABLED + /* For the unprotect call, only the addr, type id, flags, and possible + * new size are really necessary in the trace file. Write the return + * value to catch occult errors. + */ + if ( ( f != NULL ) && + ( f->shared != NULL ) && + ( f->shared->cache != NULL ) && + ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) && + ( trace_file_ptr != NULL ) ) { + + sprintf(trace, "H5AC_protect %lx %d", + (unsigned long)addr, + (int)(type->id)); + + trace_flags = flags; + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + dirtied = ( ( (flags & H5AC__DIRTIED_FLAG) == H5AC__DIRTIED_FLAG ) || ( ((H5AC_info_t *)thing)->dirtied ) ); @@ -1798,6 +2294,10 @@ H5AC_unprotect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, size_changed = TRUE; flags = flags | H5AC__SIZE_CHANGED_FLAG; +#if H5AC__TRACE_FILE_ENABLED + trace_flags = flags; + trace_new_size = new_size; +#endif /* H5AC__TRACE_FILE_ENABLED */ } } @@ -1870,6 +2370,17 @@ H5AC_unprotect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, done: +#if H5AC__TRACE_FILE_ENABLED + if ( trace_file_ptr != NULL ) { + + HDfprintf(trace_file_ptr, "%s %d %x %d\n", + trace, + (int)trace_new_size, + (unsigned)trace_flags, + (int)ret_value); + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_unprotect() */ @@ -1983,6 +2494,9 @@ done: * Added support for the new dirty_bytes_threshold field of * both H5AC_cache_config_t and H5AC_aux_t. * + * JRM - 6/8/06 + * Added support for the new trace file related fields. + * *------------------------------------------------------------------------- */ @@ -2036,6 +2550,9 @@ H5AC_get_cache_auto_resize_config(H5AC_t * cache_ptr, config_ptr->rpt_fcn_enabled = TRUE; } + config_ptr->open_trace_file = FALSE; + config_ptr->close_trace_file = FALSE; + config_ptr->trace_file_name[0] = '\0'; config_ptr->set_initial_size = internal_config.set_initial_size; config_ptr->initial_size = internal_config.initial_size; config_ptr->min_clean_fraction = internal_config.min_clean_fraction; @@ -2224,10 +2741,13 @@ done: * John Mainzer -- 4/6/05 * Updated for the addition of H5AC_cache_config_t. * - * John Mainzer -- 1025/05 - * Added support for the new dirty_bytes_threshold field of + * John Mainzer -- 10/25/05 + * Added support for the new dirty_bytes_threshold field of * both H5AC_cache_config_t and H5AC_aux_t. * + * John Mainzer -- 6/7/06 + * Added trace file support. + * *------------------------------------------------------------------------- */ @@ -2235,12 +2755,29 @@ herr_t H5AC_set_cache_auto_resize_config(H5AC_t * cache_ptr, H5AC_cache_config_t *config_ptr) { - herr_t result; - herr_t ret_value = SUCCEED; /* Return value */ + /* const char * fcn_name = "H5AC_set_cache_auto_resize_config"; */ + herr_t result; + herr_t ret_value = SUCCEED; /* Return value */ + int name_len; H5C_auto_size_ctl_t internal_config; +#if H5AC__TRACE_FILE_ENABLED + H5AC_cache_config_t trace_config = H5AC__DEFAULT_CACHE_CONFIG; + FILE * trace_file_ptr = NULL; +#endif /* H5AC__TRACE_FILE_ENABLED */ FUNC_ENTER_NOAPI(H5AC_set_cache_auto_resize_config, FAIL) +#if H5AC__TRACE_FILE_ENABLED + /* Make note of the new configuration. Don't look up the trace file + * pointer, as that may change before we use it. + */ + if ( config_ptr != NULL ) { + + trace_config = *config_ptr; + + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + if ( ( cache_ptr == NULL ) #ifdef H5_HAVE_PARALLEL || @@ -2271,10 +2808,63 @@ H5AC_set_cache_auto_resize_config(H5AC_t * cache_ptr, if ( ( config_ptr->rpt_fcn_enabled != TRUE ) && ( config_ptr->rpt_fcn_enabled != FALSE ) ) { - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \ "config_ptr->rpt_fcn_enabled must be either TRUE or FALSE.") } + if ( ( config_ptr->open_trace_file != TRUE ) && + ( config_ptr->open_trace_file != FALSE ) ) { + + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \ + "config_ptr->open_trace_file must be either TRUE or FALSE.") + } + + if ( ( config_ptr->close_trace_file != TRUE ) && + ( config_ptr->close_trace_file != FALSE ) ) { + + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \ + "config_ptr->close_trace_file must be either TRUE or FALSE.") + } + + /* don't bother to test trace_file_name unless open_trace_file is TRUE */ + if ( config_ptr->open_trace_file ) { + + /* Can't really test the trace_file_name field without trying to + * open the file, so we will content ourselves with a couple of + * sanity checks on the length of the file name. + */ + name_len = HDstrlen(config_ptr->trace_file_name); + + if ( name_len <= 0 ) { + + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \ + "config_ptr->trace_file_name is empty.") + + } else if ( name_len > H5AC__MAX_TRACE_FILE_NAME_LEN ) { + + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \ + "config_ptr->trace_file_name too long.") + } + } + + if ( config_ptr->open_trace_file ) { + + FILE * file_ptr = NULL; + + if ( H5C_get_trace_file_ptr(cache_ptr, &file_ptr) < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "H5C_get_trace_file_ptr() failed.") + } + + if ( ( ! ( config_ptr->close_trace_file ) ) && + ( file_ptr != NULL ) ) { + + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \ + "Trace file already open.") + } + } + if ( ( config_ptr->dirty_bytes_threshold @@ -2293,6 +2883,25 @@ H5AC_set_cache_auto_resize_config(H5AC_t * cache_ptr, "config_ptr->dirty_bytes_threshold out of range.") } + if ( config_ptr->close_trace_file ) { + + if ( H5AC_close_trace_file(cache_ptr) < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "H5AC_close_trace_file() failed.") + } + } + + if ( config_ptr->open_trace_file ) { + + if ( H5AC_open_trace_file(cache_ptr, config_ptr->trace_file_name) < 0 ) + { + + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \ + "H5AC_open_trace_file() failed.") + } + } + if ( H5AC_ext_config_2_int_config(config_ptr, &internal_config) != SUCCEED ) { @@ -2318,6 +2927,47 @@ H5AC_set_cache_auto_resize_config(H5AC_t * cache_ptr, done: +#if H5AC__TRACE_FILE_ENABLED + /* For the set cache auto resize config call, only the contents + * of the config is necessary in the trace file. Write the return + * value to catch occult errors. + */ + if ( ( cache_ptr != NULL ) && + ( H5C_get_trace_file_ptr(cache_ptr, &trace_file_ptr) >= 0 ) && + ( trace_file_ptr != NULL ) ) { + + HDfprintf(trace_file_ptr, + "%s %d %d %d %d \"%s\" %d %d %f %d %d %ld %d %f %f %d %d %d %f %f %d %d %d %d %f %d %d\n", + "H5AC_set_cache_auto_resize_config", + trace_config.version, + (int)(trace_config.rpt_fcn_enabled), + (int)(trace_config.open_trace_file), + (int)(trace_config.close_trace_file), + trace_config.trace_file_name, + (int)(trace_config.set_initial_size), + (int)(trace_config.initial_size), + trace_config.min_clean_fraction, + (int)(trace_config.max_size), + (int)(trace_config.min_size), + trace_config.epoch_length, + (int)(trace_config.incr_mode), + trace_config.lower_hr_threshold, + trace_config.increment, + (int)(trace_config.apply_max_increment), + (int)(trace_config.max_increment), + (int)(trace_config.decr_mode), + trace_config.upper_hr_threshold, + trace_config.decrement, + (int)(trace_config.apply_max_decrement), + (int)(trace_config.max_decrement), + trace_config.epochs_before_eviction, + (int)(trace_config.apply_empty_reserve), + trace_config.empty_reserve, + trace_config.dirty_bytes_threshold, + (int)ret_value); + } +#endif /* H5AC__TRACE_FILE_ENABLED */ + FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_set_cache_auto_resize_config() */ @@ -2345,7 +2995,11 @@ done: * * Modifications: * - * None. + * - Added code testing the trace file configuration fields. + * These tests are not comprehensive, as many errors cannot + * be caught until the directives contained in these fields + * are applied. + * JRM - 5/15/06 * *------------------------------------------------------------------------- */ @@ -2354,8 +3008,9 @@ herr_t H5AC_validate_config(H5AC_cache_config_t * config_ptr) { - herr_t result; - herr_t ret_value = SUCCEED; /* Return value */ + herr_t result; + herr_t ret_value = SUCCEED; /* Return value */ + int name_len; H5C_auto_size_ctl_t internal_config; FUNC_ENTER_NOAPI(H5AC_validate_config, FAIL) @@ -2377,6 +3032,41 @@ H5AC_validate_config(H5AC_cache_config_t * config_ptr) "config_ptr->rpt_fcn_enabled must be either TRUE or FALSE.") } + if ( ( config_ptr->open_trace_file != TRUE ) && + ( config_ptr->open_trace_file != FALSE ) ) { + + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \ + "config_ptr->open_trace_file must be either TRUE or FALSE.") + } + + if ( ( config_ptr->close_trace_file != TRUE ) && + ( config_ptr->close_trace_file != FALSE ) ) { + + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \ + "config_ptr->close_trace_file must be either TRUE or FALSE.") + } + + /* don't bother to test trace_file_name unless open_trace_file is TRUE */ + if ( config_ptr->open_trace_file ) { + + /* Can't really test the trace_file_name field without trying to + * open the file, so we will content ourselves with a couple of + * sanity checks on the length of the file name. + */ + name_len = HDstrlen(config_ptr->trace_file_name); + + if ( name_len <= 0 ) { + + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \ + "config_ptr->trace_file_name is empty.") + + } else if ( name_len > H5AC__MAX_TRACE_FILE_NAME_LEN ) { + + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \ + "config_ptr->trace_file_name too long.") + } + } + if ( config_ptr->dirty_bytes_threshold < H5AC__MIN_DIRTY_BYTES_THRESHOLD ) { HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, @@ -2410,6 +3100,185 @@ done: } /* H5AC_validate_config() */ +/*------------------------------------------------------------------------- + * Function: H5AC_close_trace_file() + * + * Purpose: If a trace file is open, stop logging calls to the cache, + * and close the file. + * + * Note that the function does nothing if there is no trace + * file. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: John Mainzer + * 6/2/06 + * + * Modifications: + * + * None. + * + *------------------------------------------------------------------------- + */ + +herr_t +H5AC_close_trace_file(H5AC_t * cache_ptr) + +{ + herr_t ret_value = SUCCEED; /* Return value */ + FILE * trace_file_ptr = NULL; + + FUNC_ENTER_NOAPI(H5AC_close_trace_file, FAIL) + + if ( cache_ptr == NULL ) { + + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL cache_ptr on entry.") + } + + if ( H5C_get_trace_file_ptr(cache_ptr, &trace_file_ptr) < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "H5C_get_trace_file_ptr() failed.") + } + + if ( trace_file_ptr != NULL ) { + + if ( H5C_set_trace_file_ptr(cache_ptr, NULL) < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "H5C_set_trace_file_ptr() failed.") + } + + if ( HDfclose(trace_file_ptr) != 0 ) { + + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, \ + "can't close metadata cache trace file") + } + } + +done: + + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5AC_close_trace_file() */ + + +/*------------------------------------------------------------------------- + * Function: H5AC_open_trace_file() + * + * Purpose: Open a trace file, and start logging calls to the cache. + * + * This logging is done at the H5C level, and will only take + * place if H5C_TRACE_FILE_ENABLED (defined in H5Cprivate.h) + * is TRUE. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: John Mainzer + * 6/1/06 + * + * Modifications: + * + * None. + * + *------------------------------------------------------------------------- + */ + +herr_t +H5AC_open_trace_file(H5AC_t * cache_ptr, + const char * trace_file_name) +{ + herr_t ret_value = SUCCEED; /* Return value */ + char file_name[H5AC__MAX_TRACE_FILE_NAME_LEN + H5C__PREFIX_LEN + 2]; + FILE * file_ptr = NULL; +#ifdef H5_HAVE_PARALLEL + H5AC_aux_t * aux_ptr = NULL; +#endif /* H5_HAVE_PARALLEL */ + + FUNC_ENTER_NOAPI(H5AC_open_trace_file, FAIL) + + HDassert(cache_ptr); + + if ( cache_ptr == NULL ) { + + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cache_ptr NULL on entry.") + } + + if ( trace_file_name == NULL ) { + + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \ + "NULL trace_file_name on entry.") + } + + if ( HDstrlen(trace_file_name) > H5AC__MAX_TRACE_FILE_NAME_LEN ) { + + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "trace file name too long.") + } + + if ( H5C_get_trace_file_ptr(cache_ptr, &file_ptr) < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "H5C_get_trace_file_ptr() failed.") + } + + if ( file_ptr != NULL ) { + + HGOTO_ERROR(H5E_FILE, H5E_FILEOPEN, FAIL, "trace file already open.") + } + +#ifdef H5_HAVE_PARALLEL + + aux_ptr = (H5AC_aux_t *)(cache_ptr->aux_ptr); + + if ( cache_ptr->aux_ptr == NULL ) { + + sprintf(file_name, "%s", trace_file_name); + + } else { + + if ( aux_ptr->magic != H5AC__H5AC_AUX_T_MAGIC ) { + + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad aux_ptr->magic.") + } + + sprintf(file_name, "%s.%d", trace_file_name, aux_ptr->mpi_rank); + + } + + if ( HDstrlen(file_name) > + H5AC__MAX_TRACE_FILE_NAME_LEN + H5C__PREFIX_LEN + 1 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "cooked trace file name too long.") + } + +#else /* H5_HAVE_PARALLEL */ + + sprintf(file_name, "%s", trace_file_name); + +#endif /* H5_HAVE_PARALLEL */ + + if ( (file_ptr = HDfopen(file_name, "w")) == NULL ) { + + /* trace file open failed */ + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "trace file open failed.") + } + + HDfprintf(file_ptr, "### HDF5 metadata cache trace file version 1 ###\n"); + + if ( H5C_set_trace_file_ptr(cache_ptr, file_ptr) < 0 ) { + + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "H5C_set_trace_file_ptr() failed.") + } + +done: + + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5AC_open_trace_file() */ + + /*************************************************************************/ /**************************** Private Functions: *************************/ /*************************************************************************/ @@ -3063,7 +3932,7 @@ H5AC_log_flushed_entry(H5C_t * cache_ptr, haddr_t addr, hbool_t was_dirty, unsigned flags, - UNUSED int type_id) + int UNUSED type_id) { herr_t ret_value = SUCCEED; /* Return value */ hbool_t cleared; |