diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5AC.c | 336 | ||||
-rw-r--r-- | src/H5AClog.c | 894 | ||||
-rw-r--r-- | src/H5ACpkg.h | 61 | ||||
-rw-r--r-- | src/H5ACpublic.h | 9 | ||||
-rw-r--r-- | src/H5C.c | 366 | ||||
-rw-r--r-- | src/H5Cpkg.h | 26 | ||||
-rw-r--r-- | src/H5Cprivate.h | 15 | ||||
-rw-r--r-- | src/H5Edefin.h | 1 | ||||
-rw-r--r-- | src/H5Einit.h | 5 | ||||
-rw-r--r-- | src/H5Epubgen.h | 2 | ||||
-rw-r--r-- | src/H5Eterm.h | 3 | ||||
-rw-r--r-- | src/H5F.c | 102 | ||||
-rw-r--r-- | src/H5Fint.c | 24 | ||||
-rw-r--r-- | src/H5Fpkg.h | 4 | ||||
-rw-r--r-- | src/H5Fprivate.h | 9 | ||||
-rw-r--r-- | src/H5Fpublic.h | 5 | ||||
-rw-r--r-- | src/H5Pfapl.c | 402 | ||||
-rw-r--r-- | src/H5Ppublic.h | 7 | ||||
-rw-r--r-- | src/H5err.txt | 1 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/Makefile.in | 11 |
21 files changed, 2177 insertions, 108 deletions
@@ -505,6 +505,16 @@ H5AC_create(const H5F_t *f, H5AC_cache_config_t *config_ptr) HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "H5C_set_prefix() failed") #endif /* H5_HAVE_PARALLEL */ + /* Turn on metadata cache logging, if being used */ + if(f->shared->use_mdc_logging) { + if(H5C_set_up_logging(f->shared->cache, f->shared->mdc_log_location, f->shared->start_mdc_log_on_access) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "mdc logging setup failed") + /* Write the log header regardless of current logging status */ + if(H5AC__write_create_cache_log_msg(f->shared->cache) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + } + + /* Set the cache parameters */ if(H5AC_set_cache_auto_resize_config(f->shared->cache, config_ptr) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "auto resize configuration failed") @@ -563,10 +573,13 @@ H5AC_dest(H5F_t *f, hid_t dxpl_id) H5AC_stats(f); #endif /* H5AC_DUMP_STATS_ON_CLOSE */ -#if H5AC__TRACE_FILE_ENABLED - if(H5AC_close_trace_file(f->shared->cache) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_close_trace_file() failed.") -#endif /* H5AC__TRACE_FILE_ENABLED */ + if(f->shared->use_mdc_logging) { + /* Write the log footer regardless of current logging status */ + if(H5AC__write_destroy_cache_log_msg(f->shared->cache) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + if(H5C_tear_down_logging(f->shared->cache) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "mdc logging tear-down failed") + } #ifdef H5_HAVE_PARALLEL aux_ptr = (struct H5AC_aux_t *)(f->shared->cache->aux_ptr); @@ -617,6 +630,8 @@ done: herr_t H5AC_evict(H5F_t *f, hid_t dxpl_id) { + hbool_t log_enabled; /* TRUE if logging was set up */ + hbool_t curr_logging; /* TRUE if currently logging */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -626,11 +641,21 @@ H5AC_evict(H5F_t *f, hid_t dxpl_id) HDassert(f->shared); HDassert(f->shared->cache); + /* Check if log messages are being emitted */ + if(H5C_get_logging_status(f->shared->cache, &log_enabled, &curr_logging) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to get logging status") + /* Evict all entries in the cache except the pinned superblock entry */ if(H5C_evict(f, dxpl_id, H5AC_dxpl_id) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "can't evict cache") done: + + /* If currently logging, generate a message */ + if(curr_logging) + if(H5AC__write_evict_cache_log_msg(f->shared->cache, ret_value) < 0) + HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_evict() */ @@ -657,6 +682,8 @@ H5AC_expunge_entry(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, char trace[128] = ""; FILE * trace_file_ptr = NULL; #endif /* H5AC__TRACE_FILE_ENABLED */ + hbool_t log_enabled; /* TRUE if logging was set up */ + hbool_t curr_logging; /* TRUE if currently logging */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -670,6 +697,10 @@ H5AC_expunge_entry(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, HDassert(type->dest); HDassert(H5F_addr_defined(addr)); + /* Check if log messages are being emitted */ + if(H5C_get_logging_status(f->shared->cache, &log_enabled, &curr_logging) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to get logging status") + #if H5AC__TRACE_FILE_ENABLED { H5AC_t * cache_ptr = f->shared->cache; @@ -687,11 +718,18 @@ H5AC_expunge_entry(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, 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); + HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); #endif /* H5AC__TRACE_FILE_ENABLED */ + /* If currently logging, generate a message */ + if(curr_logging) + if(H5AC__write_expunge_entry_log_msg(f->shared->cache, addr, type->id, ret_value) < 0) + HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + + FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_expunge_entry() */ @@ -720,10 +758,12 @@ herr_t H5AC_flush(H5F_t *f, hid_t dxpl_id) { #if H5AC__TRACE_FILE_ENABLED - char trace[128] = ""; - FILE * trace_file_ptr = NULL; + char trace[128] = ""; + FILE * trace_file_ptr = NULL; #endif /* H5AC__TRACE_FILE_ENABLED */ - herr_t ret_value = SUCCEED; /* Return value */ + hbool_t log_enabled; /* TRUE if logging was set up */ + hbool_t curr_logging; /* TRUE if currently logging */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -732,12 +772,16 @@ H5AC_flush(H5F_t *f, hid_t dxpl_id) HDassert(f->shared); HDassert(f->shared->cache); + /* Check if log messages are being emitted */ + if(H5C_get_logging_status(f->shared->cache, &log_enabled, &curr_logging) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to get logging status") + #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(NULL != (trace_file_ptr = H5C_get_trace_file_ptr(cache_ptr))) - sprintf(trace, "%s", FUNC); + sprintf(trace, "%s", FUNC); #endif /* H5AC__TRACE_FILE_ENABLED */ #ifdef H5_HAVE_PARALLEL @@ -752,15 +796,20 @@ H5AC_flush(H5F_t *f, hid_t dxpl_id) HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush cache.") 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 */ + /* If currently logging, generate a message */ + if(curr_logging) + if(H5AC__write_flush_cache_log_msg(f->shared->cache, ret_value) < 0) + HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_flush() */ - /*------------------------------------------------------------------------- * Function: H5AC_get_entry_status @@ -847,11 +896,13 @@ H5AC_insert_entry(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t add void *thing, unsigned int flags) { #if H5AC__TRACE_FILE_ENABLED - char trace[128] = ""; + char trace[128] = ""; size_t trace_entry_size = 0; - FILE * trace_file_ptr = NULL; + FILE * trace_file_ptr = NULL; #endif /* H5AC__TRACE_FILE_ENABLED */ - herr_t ret_value = SUCCEED; /* Return value */ + hbool_t log_enabled; /* TRUE if logging was set up */ + hbool_t curr_logging; /* TRUE if currently logging */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -865,6 +916,10 @@ H5AC_insert_entry(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t add HDassert(H5F_addr_defined(addr)); HDassert(thing); + /* Check if log messages are being emitted */ + if(H5C_get_logging_status(f->shared->cache, &log_enabled, &curr_logging) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to get logging status") + /* Check for invalid access request */ if(0 == (H5F_INTENT(f) & H5F_ACC_RDWR)) HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "no write intent on file") @@ -919,11 +974,17 @@ done: 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 */ + /* If currently logging, generate a message */ + if(curr_logging) + if(H5AC__write_insert_entry_log_msg(f->shared->cache, addr, type->id, flags, + ((H5C_cache_entry_t *)thing)->size, ret_value) < 0) + HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_insert_entry() */ + /*------------------------------------------------------------------------- * Function: H5AC_mark_entry_dirty * @@ -941,10 +1002,14 @@ herr_t H5AC_mark_entry_dirty(void *thing) { #if H5AC__TRACE_FILE_ENABLED - char trace[128] = ""; - FILE * trace_file_ptr = NULL; + char trace[128] = ""; + FILE * trace_file_ptr = NULL; #endif /* H5AC__TRACE_FILE_ENABLED */ - herr_t ret_value = SUCCEED; /* Return value */ + hbool_t log_enabled; /* TRUE if logging was set up */ + hbool_t curr_logging; /* TRUE if currently logging */ + H5AC_info_t *entry_ptr = NULL; /* Pointer to the cache entry */ + H5C_t *cache_ptr = NULL; /* Pointer to the entry's associated metadata cache */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -961,30 +1026,38 @@ H5AC_mark_entry_dirty(void *thing) (unsigned long)(((H5C_cache_entry_t *)thing)->addr)); #endif /* H5AC__TRACE_FILE_ENABLED */ -#ifdef H5_HAVE_PARALLEL -{ - H5AC_info_t *entry_ptr = (H5AC_info_t *)thing; - H5C_t *cache_ptr = entry_ptr->cache_ptr; + entry_ptr = (H5AC_info_t *)thing; + cache_ptr = entry_ptr->cache_ptr; HDassert(cache_ptr); HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); + /* Check if log messages are being emitted */ + if(H5C_get_logging_status(cache_ptr, &log_enabled, &curr_logging) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to get logging status") + +#ifdef H5_HAVE_PARALLEL if((!entry_ptr->is_dirty) && (!entry_ptr->is_protected) && (entry_ptr->is_pinned) && (NULL != cache_ptr->aux_ptr)) if(H5AC__log_dirtied_entry(entry_ptr) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKDIRTY, FAIL, "can't log dirtied entry") -} #endif /* H5_HAVE_PARALLEL */ if(H5C_mark_entry_dirty(thing) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKDIRTY, FAIL, "can't mark pinned or protected entry dirty") done: + #if H5AC__TRACE_FILE_ENABLED if(trace_file_ptr) - HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); + HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); #endif /* H5AC__TRACE_FILE_ENABLED */ + /* If currently logging, generate a message */ + if(curr_logging) + if(H5AC__write_mark_dirty_entry_log_msg(cache_ptr, entry_ptr, ret_value) < 0) + HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_mark_entry_dirty() */ @@ -1007,13 +1080,15 @@ herr_t H5AC_move_entry(H5F_t *f, const H5AC_class_t *type, haddr_t old_addr, haddr_t new_addr) { #if H5AC__TRACE_FILE_ENABLED - char trace[128] = ""; - FILE * trace_file_ptr = NULL; + char trace[128] = ""; + FILE * trace_file_ptr = NULL; #endif /* H5AC__TRACE_FILE_ENABLED */ #ifdef H5_HAVE_PARALLEL H5AC_aux_t *aux_ptr; #endif /* H5_HAVE_PARALLEL */ - herr_t ret_value = SUCCEED; /* Return value */ + hbool_t log_enabled; /* TRUE if logging was set up */ + hbool_t curr_logging; /* TRUE if currently logging */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -1025,6 +1100,10 @@ H5AC_move_entry(H5F_t *f, const H5AC_class_t *type, haddr_t old_addr, haddr_t ne HDassert(H5F_addr_defined(new_addr)); HDassert(H5F_addr_ne(old_addr, new_addr)); + /* Check if log messages are being emitted */ + if(H5C_get_logging_status(f->shared->cache, &log_enabled, &curr_logging) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to get logging status") + #if H5AC__TRACE_FILE_ENABLED /* For the move 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 @@ -1055,9 +1134,14 @@ H5AC_move_entry(H5F_t *f, const H5AC_class_t *type, haddr_t old_addr, haddr_t ne done: #if H5AC__TRACE_FILE_ENABLED if(trace_file_ptr != NULL) - HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); + HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); #endif /* H5AC__TRACE_FILE_ENABLED */ + /* If currently logging, generate a message */ + if(curr_logging) + if(H5AC__write_move_entry_log_msg(f->shared->cache, old_addr, new_addr, type->id, ret_value) < 0) + HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_move_entry() */ @@ -1082,6 +1166,10 @@ H5AC_pin_protected_entry(void *thing) char trace[128] = ""; FILE * trace_file_ptr = NULL; #endif /* H5AC__TRACE_FILE_ENABLED */ + hbool_t log_enabled; /* TRUE if logging was set up */ + hbool_t curr_logging; /* TRUE if currently logging */ + H5AC_info_t *entry_ptr = NULL; /* Pointer to the cache entry */ + H5C_t *cache_ptr = NULL; /* Pointer to the entry's associated metadata cache */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -1098,15 +1186,31 @@ H5AC_pin_protected_entry(void *thing) (unsigned long)(((H5C_cache_entry_t *)thing)->addr)); #endif /* H5AC__TRACE_FILE_ENABLED */ + entry_ptr = (H5AC_info_t *)thing; + cache_ptr = entry_ptr->cache_ptr; + + HDassert(cache_ptr); + HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); + + /* Check if log messages are being emitted */ + if(H5C_get_logging_status(cache_ptr, &log_enabled, &curr_logging) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to get logging status") + + /* pin entry */ if(H5C_pin_protected_entry(thing) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTPIN, FAIL, "can't pin entry") done: #if H5AC__TRACE_FILE_ENABLED if(trace_file_ptr) - HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); + HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); #endif /* H5AC__TRACE_FILE_ENABLED */ + /* If currently logging, generate a message */ + if(curr_logging) + if(H5AC__write_pin_entry_log_msg(cache_ptr, entry_ptr, ret_value) < 0) + HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_pin_protected_entry() */ @@ -1131,6 +1235,10 @@ H5AC_create_flush_dependency(void * parent_thing, void * child_thing) char trace[128] = ""; FILE * trace_file_ptr = NULL; #endif /* H5AC__TRACE_FILE_ENABLED */ + hbool_t log_enabled; /* TRUE if logging was set up */ + hbool_t curr_logging; /* TRUE if currently logging */ + H5AC_info_t *entry_ptr = NULL; /* Pointer to the cache entry */ + H5C_t *cache_ptr = NULL; /* Pointer to the entry's associated metadata cache */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -1146,15 +1254,32 @@ H5AC_create_flush_dependency(void * parent_thing, void * child_thing) (unsigned long)(((H5C_cache_entry_t *)child_thing)->addr)); #endif /* H5AC__TRACE_FILE_ENABLED */ + entry_ptr = (H5AC_info_t *)parent_thing; + cache_ptr = entry_ptr->cache_ptr; + + HDassert(cache_ptr); + HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); + + /* Check if log messages are being emitted */ + if(H5C_get_logging_status(cache_ptr, &log_enabled, &curr_logging) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to get logging status") + + /* Create the flush dependency */ if(H5C_create_flush_dependency(parent_thing, child_thing) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTDEPEND, FAIL, "H5C_create_flush_dependency() failed.") done: #if H5AC__TRACE_FILE_ENABLED if(trace_file_ptr != NULL) - HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); + HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); #endif /* H5AC__TRACE_FILE_ENABLED */ + /* If currently logging, generate a message */ + if(curr_logging) + if(H5AC__write_create_fd_log_msg(cache_ptr, (H5AC_info_t *)parent_thing, + (H5AC_info_t *)child_thing, ret_value) < 0) + HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_create_flush_dependency() */ @@ -1187,13 +1312,15 @@ void * H5AC_protect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, void *udata, H5AC_protect_t rw) { - unsigned protect_flags = H5C__NO_FLAGS_SET; - void * thing; /* Pointer to native data structure for entry */ #if H5AC__TRACE_FILE_ENABLED char trace[128] = ""; - size_t trace_entry_size = 0; + size_t trace_entry_size = 0; FILE * trace_file_ptr = NULL; #endif /* H5AC__TRACE_FILE_ENABLED */ + unsigned protect_flags = H5C__NO_FLAGS_SET; + void * thing; /* Pointer to native data structure for entry */ + hbool_t log_enabled; /* TRUE if logging was set up */ + hbool_t curr_logging; /* TRUE if currently logging */ void * ret_value; /* Return value */ FUNC_ENTER_NOAPI(NULL) @@ -1207,6 +1334,10 @@ H5AC_protect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, HDassert(type->load); HDassert(H5F_addr_defined(addr)); + /* Check if log messages are being emitted */ + if(H5C_get_logging_status(f->shared->cache, &log_enabled, &curr_logging) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, NULL, "unable to get logging status") + /* Check for invalid access request */ if(0 == (H5F_INTENT(f) & H5F_ACC_RDWR) && rw == H5AC_WRITE) HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "no write intent on file") @@ -1226,21 +1357,14 @@ H5AC_protect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, * catch occult errors. */ if(NULL != (trace_file_ptr = H5C_get_trace_file_ptr(cache_ptr))) { - const char * rw_string; - if ( rw == H5AC_WRITE ) { - + if (rw == H5AC_WRITE ) rw_string = "H5AC_WRITE"; - - } else if ( rw == H5AC_READ ) { - + else if (rw == H5AC_READ ) rw_string = "H5AC_READ"; - - } else { - + else rw_string = "???"; - } sprintf(trace, "%s 0x%lx %d %s", FUNC, (unsigned long)addr, (int)(type->id), rw_string); @@ -1271,9 +1395,18 @@ H5AC_protect(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 %d\n", trace, (int)trace_entry_size, (int)(ret_value != NULL)); + HDfprintf(trace_file_ptr, "%s %d %d\n", trace, (int)trace_entry_size, (int)(ret_value != NULL)); #endif /* H5AC__TRACE_FILE_ENABLED */ + /* If currently logging, generate a message */ + if(curr_logging) { + herr_t fake_ret_value = (NULL == ret_value) ? FAIL : SUCCEED; + + if(H5AC__write_protect_entry_log_msg(f->shared->cache, (H5AC_info_t *)thing, + rw, fake_ret_value) < 0) + HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, NULL, "unable to emit log message") + } + FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_protect() */ @@ -1294,10 +1427,14 @@ herr_t H5AC_resize_entry(void *thing, size_t new_size) { #if H5AC__TRACE_FILE_ENABLED - char trace[128] = ""; - FILE * trace_file_ptr = NULL; + char trace[128] = ""; + FILE * trace_file_ptr = NULL; #endif /* H5AC__TRACE_FILE_ENABLED */ - herr_t ret_value = SUCCEED; /* Return value */ + hbool_t log_enabled; /* TRUE if logging was set up */ + hbool_t curr_logging; /* TRUE if currently logging */ + H5AC_info_t *entry_ptr = NULL; /* Pointer to the cache entry */ + H5C_t *cache_ptr = NULL; /* Pointer to the entry's associated metadata cache */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -1315,29 +1452,37 @@ H5AC_resize_entry(void *thing, size_t new_size) (int)new_size); #endif /* H5AC__TRACE_FILE_ENABLED */ - if(H5C_resize_entry(thing, new_size) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTRESIZE, FAIL, "can't resize entry") - -#ifdef H5_HAVE_PARALLEL -{ - H5AC_info_t * entry_ptr = (H5AC_info_t *)thing; - H5C_t *cache_ptr = entry_ptr->cache_ptr; + entry_ptr = (H5AC_info_t *)thing; + cache_ptr = entry_ptr->cache_ptr; HDassert(cache_ptr); HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); + /* Check if log messages are being emitted */ + if(H5C_get_logging_status(cache_ptr, &log_enabled, &curr_logging) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to get logging status") + + /* resize the entry */ + if(H5C_resize_entry(thing, new_size) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTRESIZE, FAIL, "can't resize entry") + +#ifdef H5_HAVE_PARALLEL if((!entry_ptr->is_dirty) && (NULL != cache_ptr->aux_ptr)) if(H5AC__log_dirtied_entry(entry_ptr) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKDIRTY, FAIL, "can't log dirtied entry") -} #endif /* H5_HAVE_PARALLEL */ done: #if H5AC__TRACE_FILE_ENABLED if(trace_file_ptr) - HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); + HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); #endif /* H5AC__TRACE_FILE_ENABLED */ + /* If currently logging, generate a message */ + if(curr_logging) + if(H5AC__write_resize_entry_log_msg(cache_ptr, entry_ptr, new_size, ret_value) < 0) + HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_resize_entry() */ @@ -1362,6 +1507,10 @@ H5AC_unpin_entry(void *thing) char trace[128] = ""; FILE * trace_file_ptr = NULL; #endif /* H5AC__TRACE_FILE_ENABLED */ + hbool_t log_enabled; /* TRUE if logging was set up */ + hbool_t curr_logging; /* TRUE if currently logging */ + H5AC_info_t *entry_ptr = NULL; /* Pointer to the cache entry */ + H5C_t *cache_ptr = NULL; /* Pointer to the entry's associated metadata cache */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -1378,15 +1527,31 @@ H5AC_unpin_entry(void *thing) (unsigned long)(((H5C_cache_entry_t *)thing)->addr)); #endif /* H5AC__TRACE_FILE_ENABLED */ + entry_ptr = (H5AC_info_t *)thing; + cache_ptr = entry_ptr->cache_ptr; + + HDassert(cache_ptr); + HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); + + /* Check if log messages are being emitted */ + if(H5C_get_logging_status(cache_ptr, &log_enabled, &curr_logging) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to get logging status") + + /* unpin the entry */ if(H5C_unpin_entry(thing) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, "can't unpin entry") done: #if H5AC__TRACE_FILE_ENABLED if(trace_file_ptr) - HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); + HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); #endif /* H5AC__TRACE_FILE_ENABLED */ + /* If currently logging, generate a message */ + if(curr_logging) + if(H5AC__write_unpin_entry_log_msg(cache_ptr, entry_ptr, ret_value) < 0) + HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_unpin_entry() */ @@ -1410,6 +1575,10 @@ H5AC_destroy_flush_dependency(void * parent_thing, void * child_thing) char trace[128] = ""; FILE * trace_file_ptr = NULL; #endif /* H5AC__TRACE_FILE_ENABLED */ + hbool_t log_enabled; /* TRUE if logging was set up */ + hbool_t curr_logging; /* TRUE if currently logging */ + H5AC_info_t *entry_ptr = NULL; /* Pointer to the cache entry */ + H5C_t *cache_ptr = NULL; /* Pointer to the entry's associated metadata cache */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -1425,15 +1594,32 @@ H5AC_destroy_flush_dependency(void * parent_thing, void * child_thing) (unsigned long long)(((H5C_cache_entry_t *)child_thing)->addr)); #endif /* H5AC__TRACE_FILE_ENABLED */ + entry_ptr = (H5AC_info_t *)parent_thing; + cache_ptr = entry_ptr->cache_ptr; + + HDassert(cache_ptr); + HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); + + /* Check if log messages are being emitted */ + if(H5C_get_logging_status(cache_ptr, &log_enabled, &curr_logging) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to get logging status") + + /* destry the flush dependency */ if(H5C_destroy_flush_dependency(parent_thing, child_thing) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTUNDEPEND, FAIL, "H5C_destroy_flush_dependency() failed.") done: #if H5AC__TRACE_FILE_ENABLED if(trace_file_ptr != NULL) - HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); + HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); #endif /* H5AC__TRACE_FILE_ENABLED */ + /* If currently logging, generate a message */ + if(curr_logging) + if(H5AC__write_destroy_fd_log_msg(cache_ptr, (H5AC_info_t *)parent_thing, + (H5AC_info_t *)child_thing, ret_value) < 0) + HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_destroy_flush_dependency() */ @@ -1480,15 +1666,17 @@ herr_t H5AC_unprotect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, void *thing, unsigned flags) { +#if H5AC__TRACE_FILE_ENABLED + char trace[128] = ""; + FILE * trace_file_ptr = NULL; +#endif /* H5AC__TRACE_FILE_ENABLED */ hbool_t dirtied; hbool_t deleted; #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 */ + hbool_t log_enabled; /* TRUE if logging was set up */ + hbool_t curr_logging; /* TRUE if currently logging */ herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -1505,6 +1693,10 @@ 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 ); + /* Check if log messages are being emitted */ + if(H5C_get_logging_status(f->shared->cache, &log_enabled, &curr_logging) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to get logging status") + #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 @@ -1559,6 +1751,12 @@ done: HDfprintf(trace_file_ptr, "%s 0x%x %d\n", trace, (unsigned)flags, (int)ret_value); #endif /* H5AC__TRACE_FILE_ENABLED */ + /* If currently logging, generate a message */ + if(curr_logging) + if(H5AC__write_unprotect_entry_log_msg(f->shared->cache, (H5AC_info_t *)thing, + type->id, flags, ret_value) < 0) + HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_unprotect() */ @@ -1884,18 +2082,24 @@ done: herr_t H5AC_set_cache_auto_resize_config(H5AC_t *cache_ptr, H5AC_cache_config_t *config_ptr) { - 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 */ - herr_t ret_value = SUCCEED; /* Return value */ + hbool_t log_enabled; /* TRUE if logging was set up */ + hbool_t curr_logging; /* TRUE if currently logging */ + H5C_auto_size_ctl_t internal_config; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity checks */ HDassert(cache_ptr); + /* Check if log messages are being emitted */ + if(H5C_get_logging_status(cache_ptr, &log_enabled, &curr_logging) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to get logging status") + #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. @@ -1996,7 +2200,12 @@ done: (int)ret_value); #endif /* H5AC__TRACE_FILE_ENABLED */ + /* If currently logging, generate a message */ + if(curr_logging) + if(H5AC__write_set_cache_config_log_msg(cache_ptr, config_ptr, ret_value) < 0) + HDONE_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") FUNC_LEAVE_NOAPI(ret_value) + } /* H5AC_set_cache_auto_resize_config() */ @@ -2036,6 +2245,9 @@ H5AC_validate_config(H5AC_cache_config_t *config_ptr) if(config_ptr->version != H5AC__CURR_CACHE_CONFIG_VERSION) HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "Unknown config version.") + if((config_ptr->rpt_fcn_enabled != TRUE) && (config_ptr->rpt_fcn_enabled != FALSE)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "config_ptr->rpt_fcn_enabled 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) { size_t name_len; diff --git a/src/H5AClog.c b/src/H5AClog.c new file mode 100644 index 0000000..aaef674 --- /dev/null +++ b/src/H5AClog.c @@ -0,0 +1,894 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5AClog_json.c + * + * Purpose: Functions for metadata cache logging in JSON format + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ +#define H5AC_PACKAGE /* suppress error about including H5ACpkg */ +#define H5C_PACKAGE /* suppress error about including H5Cpkg */ + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5ACpkg.h" /* Metadata cache */ +#include "H5Cpkg.h" /* Cache */ +#include "H5Eprivate.h" /* Error handling */ + +/****************/ +/* Local Macros */ +/****************/ + +#define MSG_SIZE 128 + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + +/*------------------------------------------------------------------------- + * Function: H5AC__write_create_cache_log_msg + * + * Purpose: Write a log message for cache creation. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + *------------------------------------------------------------------------- + */ + + + +/*------------------------------------------------------------------------- + * Function: H5AC__write_create_cache_log_msg + * + * Purpose: Write a log message for cache creation. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC__write_create_cache_log_msg(H5AC_t *cache) +{ + char msg[MSG_SIZE]; + hbool_t orig_state; /* saved "current logging" flag state */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(cache); + HDassert(cache->magic == H5C__H5C_T_MAGIC); + + /* Create the log message string */ + snprintf(msg, MSG_SIZE, +"\ +{\n\ +\"create_time\":%lld,\n\ +\"messages\":\n\ +[\n\ +" + , (long long)time(NULL)); + + /* Since we're about to override the current logging flag, + * check the "log enabled" flag to see if we didn't get here + * by mistake. + */ + if(!(cache->logging_enabled)) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "attempt to write opening log message when logging is disabled") + + /* Write the log message to the file + * Have to temporarily enable logging for this. + */ + orig_state = cache->currently_logging; + cache->currently_logging = TRUE; + if(H5C_write_log_message(cache, msg) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + cache->currently_logging = orig_state; + +done: + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC__write_create_cache_log_msg() */ + + +/*------------------------------------------------------------------------- + * Function: H5AC__write_destroy_cache_log_msg + * + * Purpose: Write a log message for cache destruction. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC__write_destroy_cache_log_msg(H5AC_t *cache) +{ + char msg[MSG_SIZE]; + hbool_t orig_state; /* saved "current logging" flag state */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(cache); + HDassert(cache->magic == H5C__H5C_T_MAGIC); + + /* Create the log message string */ + snprintf(msg, MSG_SIZE, +"\ +],\n\ +\"close_time\":%lld,\n\ +}\n\ +" + , (long long)time(NULL)); + + /* Since we're about to override the current logging flag, + * check the "log enabled" flag to see if we didn't get here + * by mistake. + */ + if(!(cache->logging_enabled)) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "attempt to write closing log message when logging is disabled") + + /* Write the log message to the file + * Have to temporarily enable logging for this. + */ + orig_state = cache->currently_logging; + cache->currently_logging = TRUE; + if(H5C_write_log_message(cache, msg) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + cache->currently_logging = orig_state; + +done: + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC__write_destroy_cache_log_msg() */ + + +/*------------------------------------------------------------------------- + * Function: H5AC__write_evict_cache_log_msg + * + * Purpose: Write a log message for eviction of cache entries. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC__write_evict_cache_log_msg(const H5AC_t *cache, + herr_t fxn_ret_value) +{ + char msg[MSG_SIZE]; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(cache); + HDassert(cache->magic == H5C__H5C_T_MAGIC); + + /* Create the log message string */ + snprintf(msg, MSG_SIZE, +"\ +{\ +\"timestamp\":%lld,\ +\"action\":\"evict\",\ +\"returned\":%d\ +},\n\ +" + , (long long)time(NULL), (int)fxn_ret_value); + + /* Write the log message to the file */ + if(H5C_write_log_message(cache, msg) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + +done: + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC__write_evict_cache_log_msg() */ + + +/*------------------------------------------------------------------------- + * Function: H5AC__write_expunge_entry_log_msg + * + * Purpose: Write a log message for expunge of cache entries. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC__write_expunge_entry_log_msg(const H5AC_t *cache, + haddr_t address, + int type_id, + herr_t fxn_ret_value) +{ + char msg[MSG_SIZE]; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(cache); + HDassert(cache->magic == H5C__H5C_T_MAGIC); + + /* Create the log message string */ + snprintf(msg, MSG_SIZE, +"\ +{\ +\"timestamp\":%lld,\ +\"action\":\"expunge\",\ +\"address\":0x%lx,\ +\"type_id\":%d,\ +\"returned\":%d\ +},\n\ +" + , (long long)time(NULL), (unsigned long)address, (int)type_id, (int)fxn_ret_value); + + + /* Write the log message to the file */ + if(H5C_write_log_message(cache, msg) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + +done: + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC__write_expunge_entry_log_msg() */ + + +/*------------------------------------------------------------------------- + * Function: H5AC__write_flush_cache_log_msg + * + * Purpose: Write a log message for cache flushes. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC__write_flush_cache_log_msg(const H5AC_t *cache, + herr_t fxn_ret_value) +{ + char msg[MSG_SIZE]; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(cache); + HDassert(cache->magic == H5C__H5C_T_MAGIC); + + /* Create the log message string */ + snprintf(msg, MSG_SIZE, +"\ +{\ +\"timestamp\":%lld,\ +\"action\":\"flush\",\ +\"returned\":%d\ +},\n\ +" + , (long long)time(NULL), (int)fxn_ret_value); + + /* Write the log message to the file */ + if(H5C_write_log_message(cache, msg) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + +done: + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC__write_flush_cache_log_msg() */ + + +/*------------------------------------------------------------------------- + * Function: H5AC__write_insert_entry_log_msg + * + * Purpose: Write a log message for insertion of cache entries. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC__write_insert_entry_log_msg(const H5AC_t *cache, + haddr_t address, + int type_id, + unsigned flags, + size_t size, + herr_t fxn_ret_value) +{ + char msg[MSG_SIZE]; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(cache); + HDassert(cache->magic == H5C__H5C_T_MAGIC); + + + /* Create the log message string */ + snprintf(msg, MSG_SIZE, +"\ +{\ +\"timestamp\":%lld,\ +\"action\":\"insert\",\ +\"address\":0x%lx,\ +\"flags\":0x%x,\ +\"type_id\":%d,\ +\"size\":%d,\ +\"returned\":%d\ +},\n\ +" + , (long long)time(NULL), (unsigned long)address, flags, type_id, + (int)size, (int)fxn_ret_value); + + /* Write the log message to the file */ + if(H5C_write_log_message(cache, msg) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + +done: + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC__write_insert_entry_log_msg() */ + + +/*------------------------------------------------------------------------- + * Function: H5AC__write_mark_dirty_entry_log_msg + * + * Purpose: Write a log message for marking cache entries as dirty. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC__write_mark_dirty_entry_log_msg(const H5AC_t *cache, + const H5AC_info_t *entry, + herr_t fxn_ret_value) +{ + char msg[MSG_SIZE]; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(cache); + HDassert(cache->magic == H5C__H5C_T_MAGIC); + HDassert(entry); + + /* Create the log message string */ + snprintf(msg, MSG_SIZE, +"\ +{\ +\"timestamp\":%lld,\ +\"action\":\"dirty\",\ +\"address\":0x%lx,\ +\"returned\":%d\ +},\n\ +" + , (long long)time(NULL), (unsigned long)entry->addr, (int)fxn_ret_value); + + /* Write the log message to the file */ + if(H5C_write_log_message(cache, msg) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + +done: + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC__write_mark_dirty_entry_log_msg() */ + + +/*------------------------------------------------------------------------- + * Function: H5AC__write_move_entry_log_msg + * + * Purpose: Write a log message for moving a cache entry. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC__write_move_entry_log_msg(const H5AC_t *cache, + haddr_t old_addr, + haddr_t new_addr, + int type_id, + herr_t fxn_ret_value) +{ + char msg[MSG_SIZE]; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(cache); + HDassert(cache->magic == H5C__H5C_T_MAGIC); + + /* Create the log message string */ + snprintf(msg, MSG_SIZE, +"\ +{\ +\"timestamp\":%lld,\ +\"action\":\"move\",\ +\"old_address\":0x%lx,\ +\"new_address\":0x%lx,\ +\"type_id\":%d,\ +\"returned\":%d\ +},\n\ +" + , (long long)time(NULL), (unsigned long)old_addr, + (unsigned long)new_addr, type_id, (int)fxn_ret_value); + + /* Write the log message to the file */ + if(H5C_write_log_message(cache, msg) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + +done: + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC__write_move_entry_log_msg() */ + + +/*------------------------------------------------------------------------- + * Function: H5AC__write_pin_entry_log_msg + * + * Purpose: Write a log message for pinning a cache entry. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC__write_pin_entry_log_msg(const H5AC_t *cache, + const H5AC_info_t *entry, + herr_t fxn_ret_value) +{ + char msg[MSG_SIZE]; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(cache); + HDassert(cache->magic == H5C__H5C_T_MAGIC); + HDassert(entry); + + /* Create the log message string */ + snprintf(msg, MSG_SIZE, +"\ +{\ +\"timestamp\":%lld,\ +\"action\":\"pin\",\ +\"address\":0x%lx,\ +\"returned\":%d\ +},\n\ +" + , (long long)time(NULL), (unsigned long)entry->addr, + (int)fxn_ret_value); + + /* Write the log message to the file */ + if(H5C_write_log_message(cache, msg) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + +done: + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC__write_pin_entry_log_msg() */ + + +/*------------------------------------------------------------------------- + * Function: H5AC__write_create_fd_log_msg + * + * Purpose: Write a log message for creating a flush dependency between + * two cache entries. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC__write_create_fd_log_msg(const H5AC_t *cache, + const H5AC_info_t *parent, + const H5AC_info_t *child, + herr_t fxn_ret_value) +{ + char msg[MSG_SIZE]; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(cache); + HDassert(cache->magic == H5C__H5C_T_MAGIC); + HDassert(parent); + HDassert(child); + + /* Create the log message string */ + snprintf(msg, MSG_SIZE, +"\ +{\ +\"timestamp\":%lld,\ +\"action\":\"create_fd\",\ +\"parent_addr\":0x%lx,\ +\"child_addr\":0x%lx,\ +\"returned\":%d\ +},\n\ +" + , (long long)time(NULL), (unsigned long)parent->addr, + (unsigned long)child->addr, (int)fxn_ret_value); + + /* Write the log message to the file */ + if(H5C_write_log_message(cache, msg) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + +done: + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC__write_create_fd_log_msg() */ + + +/*------------------------------------------------------------------------- + * Function: H5AC__write_protect_entry_log_msg + * + * Purpose: Write a log message for protecting a cache entry. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC__write_protect_entry_log_msg(const H5AC_t *cache, + const H5AC_info_t *entry, + H5AC_protect_t rw, + herr_t fxn_ret_value) +{ + char msg[MSG_SIZE]; + char rw_s[16]; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(cache); + HDassert(cache->magic == H5C__H5C_T_MAGIC); + HDassert(entry); + + if(H5AC_READ == rw) + HDstrcpy(rw_s, "READ"); + else if(H5AC_WRITE == rw) + HDstrcpy(rw_s, "WRITE"); + else + HDstrcpy(rw_s, "UNKNOWN"); + + /* Create the log message string */ + snprintf(msg, MSG_SIZE, +"\ +{\ +\"timestamp\":%lld,\ +\"action\":\"protect\",\ +\"address\":0x%lx,\ +\"readwrite\":\"%s\",\ +\"size\":%d,\ +\"returned\":%d\ +},\n\ +" + , (long long)time(NULL), (unsigned long)entry->addr, + rw_s, (int)entry->size, (int)fxn_ret_value); + + /* Write the log message to the file */ + if(H5C_write_log_message(cache, msg) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + +done: + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC__write_protect_entry_log_msg() */ + + +/*------------------------------------------------------------------------- + * Function: H5AC__write_resize_entry_log_msg + * + * Purpose: Write a log message for resizing a cache entry. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC__write_resize_entry_log_msg(const H5AC_t *cache, + const H5AC_info_t *entry, + size_t new_size, + herr_t fxn_ret_value) +{ + char msg[MSG_SIZE]; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(cache); + HDassert(cache->magic == H5C__H5C_T_MAGIC); + HDassert(entry); + + /* Create the log message string */ + snprintf(msg, MSG_SIZE, +"\ +{\ +\"timestamp\":%lld,\ +\"action\":\"resize\",\ +\"address\":0x%lx,\ +\"new_size\":%d,\ +\"returned\":%d\ +},\n\ +" + , (long long)time(NULL), (unsigned long)entry->addr, + (int)new_size, (int)fxn_ret_value); + + /* Write the log message to the file */ + if(H5C_write_log_message(cache, msg) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + +done: + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC__write_resize_entry_log_msg() */ + + +/*------------------------------------------------------------------------- + * Function: H5AC__write_unpin_entry_log_msg + * + * Purpose: Write a log message for unpinning a cache entry. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC__write_unpin_entry_log_msg(const H5AC_t *cache, + const H5AC_info_t *entry, + herr_t fxn_ret_value) +{ + char msg[MSG_SIZE]; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(cache); + HDassert(cache->magic == H5C__H5C_T_MAGIC); + HDassert(entry); + + /* Create the log message string */ + snprintf(msg, MSG_SIZE, +"\ +{\ +\"timestamp\":%lld,\ +\"action\":\"unpin\",\ +\"address\":0x%lx,\ +\"returned\":%d\ +},\n\ +" + , (long long)time(NULL), (unsigned long)entry->addr, + (int)fxn_ret_value); + + /* Write the log message to the file */ + if(H5C_write_log_message(cache, msg) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + +done: + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC__write_unpin_entry_log_msg() */ + + +/*------------------------------------------------------------------------- + * Function: H5AC__write_destroy_fd_log_msg + * + * Purpose: Write a log message for destroying a flush dependency + * between two cache entries. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC__write_destroy_fd_log_msg(const H5AC_t *cache, + const H5AC_info_t *parent, + const H5AC_info_t *child, + herr_t fxn_ret_value) +{ + char msg[MSG_SIZE]; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(cache); + HDassert(cache->magic == H5C__H5C_T_MAGIC); + HDassert(parent); + HDassert(child); + + /* Create the log message string */ + snprintf(msg, MSG_SIZE, +"\ +{\ +\"timestamp\":%lld,\ +\"action\":\"destroy_fd\",\ +\"parent_addr\":0x%lx,\ +\"child_addr\":0x%lx,\ +\"returned\":%d\ +},\n\ +" + , (long long)time(NULL), (unsigned long)parent->addr, + (unsigned long)child->addr, (int)fxn_ret_value); + + /* Write the log message to the file */ + if(H5C_write_log_message(cache, msg) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + +done: + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC__write_destroy_fd_log_msg() */ + + +/*------------------------------------------------------------------------- + * Function: H5AC__write_unprotect_entry_log_msg + * + * Purpose: Write a log message for unprotecting a cache entry. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC__write_unprotect_entry_log_msg(const H5AC_t *cache, + const H5AC_info_t *entry, + int type_id, + unsigned flags, + herr_t fxn_ret_value) +{ + char msg[MSG_SIZE]; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(cache); + HDassert(cache->magic == H5C__H5C_T_MAGIC); + HDassert(entry); + + /* Create the log message string */ + snprintf(msg, MSG_SIZE, +"\ +{\ +\"timestamp\":%lld,\ +\"action\":\"unprotect\",\ +\"address\":0x%lx,\ +\"id\":%d,\ +\"flags\":%x,\ +\"returned\":%d\ +},\n\ +" + , (long long)time(NULL), (unsigned long)entry->addr, + type_id, flags, (int)fxn_ret_value); + + snprintf(msg, MSG_SIZE, " "); + + /* Write the log message to the file */ + if(H5C_write_log_message(cache, msg) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + +done: + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC__write_unprotect_entry_log_msg() */ + + +/*------------------------------------------------------------------------- + * Function: H5AC__write_set_cache_config_log_msg + * + * Purpose: Write a log message for setting the cache configuration. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC__write_set_cache_config_log_msg(const H5AC_t *cache, + const H5AC_cache_config_t *config, + herr_t fxn_ret_value) +{ + char msg[MSG_SIZE]; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(cache); + HDassert(cache->magic == H5C__H5C_T_MAGIC); + HDassert(config); + + /* Create the log message string */ + snprintf(msg, MSG_SIZE, +"\ +{\ +\"timestamp\":%lld,\ +\"action\":\"set_config\",\ +\"returned\":%d\ +},\n\ +" + , (long long)time(NULL), (int)fxn_ret_value); + + + /* Write the log message to the file */ + if(H5C_write_log_message(cache, msg) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") + +done: + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC__write_set_cache_config_log_msg() */ + diff --git a/src/H5ACpkg.h b/src/H5ACpkg.h index 950bdea..e1c2693 100644 --- a/src/H5ACpkg.h +++ b/src/H5ACpkg.h @@ -389,10 +389,69 @@ typedef struct H5AC_aux_t void (* sync_point_done)(int num_writes, haddr_t * written_entries_tbl); - } H5AC_aux_t; /* struct H5AC_aux_t */ #endif /* H5_HAVE_PARALLEL */ +/******************************/ +/* Pacakge Private Prototypes */ +/******************************/ + +/* Cache logging routines */ +H5_DLL herr_t H5AC__write_create_cache_log_msg(H5AC_t *cache); +H5_DLL herr_t H5AC__write_destroy_cache_log_msg(H5AC_t *cache); +H5_DLL herr_t H5AC__write_evict_cache_log_msg(const H5AC_t *cache, + herr_t fxn_ret_value); +H5_DLL herr_t H5AC__write_expunge_entry_log_msg(const H5AC_t *cache, + haddr_t address, + int type_id, + herr_t fxn_ret_value); +H5_DLL herr_t H5AC__write_flush_cache_log_msg(const H5AC_t *cache, + herr_t fxn_ret_value); +H5_DLL herr_t H5AC__write_insert_entry_log_msg(const H5AC_t *cache, + haddr_t address, + int type_id, + unsigned flags, + size_t size, + herr_t fxn_ret_value); +H5_DLL herr_t H5AC__write_mark_dirty_entry_log_msg(const H5AC_t *cache, + const H5AC_info_t *entry, + herr_t fxn_ret_value); +H5_DLL herr_t H5AC__write_move_entry_log_msg(const H5AC_t *cache, + haddr_t old_addr, + haddr_t new_addr, + int type_id, + herr_t fxn_ret_value); +H5_DLL herr_t H5AC__write_pin_entry_log_msg(const H5AC_t *cache, + const H5AC_info_t *entry, + herr_t fxn_ret_value); +H5_DLL herr_t H5AC__write_create_fd_log_msg(const H5AC_t *cache, + const H5AC_info_t *parent, + const H5AC_info_t *child, + herr_t fxn_ret_value); +H5_DLL herr_t H5AC__write_protect_entry_log_msg(const H5AC_t *cache, + const H5AC_info_t *entry, + H5AC_protect_t rw, + herr_t fxn_ret_value); +H5_DLL herr_t H5AC__write_resize_entry_log_msg(const H5AC_t *cache, + const H5AC_info_t *entry, + size_t new_size, + herr_t fxn_ret_value); +H5_DLL herr_t H5AC__write_unpin_entry_log_msg(const H5AC_t *cache, + const H5AC_info_t *entry, + herr_t fxn_ret_value); +H5_DLL herr_t H5AC__write_destroy_fd_log_msg(const H5AC_t *cache, + const H5AC_info_t *parent, + const H5AC_info_t *child, + herr_t fxn_ret_value); +H5_DLL herr_t H5AC__write_unprotect_entry_log_msg(const H5AC_t *cache, + const H5AC_info_t *entry, + int type_id, + unsigned flags, + herr_t fxn_ret_value); +H5_DLL herr_t H5AC__write_set_cache_config_log_msg(const H5AC_t *cache, + const H5AC_cache_config_t *config, + herr_t fxn_ret_value); + #endif /* _H5ACpkg_H */ diff --git a/src/H5ACpublic.h b/src/H5ACpublic.h index 598197f..ac75d1f 100644 --- a/src/H5ACpublic.h +++ b/src/H5ACpublic.h @@ -78,6 +78,8 @@ extern "C" { * open_trace_file: Boolean field indicating whether the trace_file_name * field should be used to open a trace file for the cache. * + * *** DEPRECATED *** Use H5Fstart/stop logging functions instead + * * The trace file is a debuging feature that allow the capture of * top level metadata cache requests for purposes of debugging and/or * optimization. This field should normally be set to FALSE, as @@ -91,6 +93,8 @@ extern "C" { * close_trace_file: Boolean field indicating whether the current trace * file (if any) should be closed. * + * *** DEPRECATED *** Use H5Fstart/stop logging functions instead + * * See the above comments on the open_trace_file field. This field * should be set to FALSE unless there is an open trace file on the * cache that you wish to close. @@ -98,6 +102,8 @@ extern "C" { * trace_file_name: Full path of the trace file to be opened if the * open_trace_file field is TRUE. * + * *** DEPRECATED *** Use H5Fstart/stop logging functions instead + * * In the parallel case, an ascii representation of the mpi rank of * the process will be appended to the file name to yield a unique * trace file name for each process. @@ -435,7 +441,7 @@ extern "C" { ****************************************************************************/ #define H5AC__CURR_CACHE_CONFIG_VERSION 1 -#define H5AC__MAX_TRACE_FILE_NAME_LEN 1024 +#define H5AC__MAX_TRACE_FILE_NAME_LEN 1024 #define H5AC_METADATA_WRITE_STRATEGY__PROCESS_0_ONLY 0 #define H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED 1 @@ -506,3 +512,4 @@ typedef struct H5AC_cache_config_t } #endif #endif + @@ -70,13 +70,14 @@ * **************************************************************************/ +#define H5AC_PACKAGE /*suppress error about including H5ACpkg */ #define H5C_PACKAGE /*suppress error about including H5Cpkg */ #define H5F_PACKAGE /*suppress error about including H5Fpkg */ #include "H5private.h" /* Generic Functions */ #ifdef H5_HAVE_PARALLEL -#include "H5ACprivate.h" /* Metadata cache */ +#include "H5ACpkg.h" /* Metadata cache */ #endif /* H5_HAVE_PARALLEL */ #include "H5Cpkg.h" /* Cache */ #include "H5Dprivate.h" /* Dataset functions */ @@ -1177,7 +1178,11 @@ H5C_create(size_t max_cache_size, cache_ptr->flush_in_progress = FALSE; - cache_ptr->trace_file_ptr = NULL; + cache_ptr->logging_enabled = FALSE; + + cache_ptr->currently_logging = FALSE; + + cache_ptr->log_file_ptr = NULL; cache_ptr->aux_ptr = aux_ptr; @@ -2657,6 +2662,321 @@ H5C_get_trace_file_ptr_from_entry(const H5C_cache_entry_t *entry_ptr) FUNC_LEAVE_NOAPI(H5C_get_trace_file_ptr(entry_ptr->cache_ptr)) } /* H5C_get_trace_file_ptr_from_entry() */ + +/*------------------------------------------------------------------------- + * Function: H5C_set_up_logging + * + * Purpose: Setup for metadata cache logging. + * + * Metadata logging is enabled and disabled at two levels. This + * function and the associated tear_down function open and close + * the log file. the start_ and stop_logging functions are then + * used to switch logging on/off. Optionally, logging can begin + * as soon as the log file is opened (set via the start_immediately + * parameter to this function). + * + * The log functionality is split between the H5C and H5AC + * packages. Log state and direct log manipulation resides in + * H5C. Log messages are generated in H5AC and sent to + * the H5C_write_log_message function. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5C_set_up_logging(H5C_t *cache_ptr, const char log_location[], + hbool_t start_immediately) +{ +#ifdef H5_HAVE_PARALLEL + H5AC_aux_t *aux_ptr = NULL; +#endif /*H5_HAVE_PARALLEL*/ + char *file_name; + size_t n_chars; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(cache_ptr); + HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); + HDassert(log_location); + + /* Sanity checks */ + if(NULL == cache_ptr) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cache_ptr == NULL") + + if(H5C__H5C_T_MAGIC != cache_ptr->magic) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cache magic value incorrect") + + if(cache_ptr->logging_enabled) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "logging already set up") + + if(NULL == log_location) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL log location not allowed") + + /* Possibly fix up the log file name. + * The extra 39 characters are for adding the rank to the file name + * under parallel HDF5. 39 characters allows > 2^127 processes which + * should be enough for anybody. + * + * allocation size = <path length> + dot + <rank # length> + \0 + */ + n_chars = HDstrlen(log_location) + 1 + 39 + 1; + if(NULL == (file_name = (char *)HDcalloc(n_chars, sizeof(char)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, \ + "can't allocate memory for mdc log file name manipulation") + +#ifdef H5_HAVE_PARALLEL + + /* Add the rank to the log file name when MPI is in use */ + aux_ptr = (H5AC_aux_t *)(cache_ptr->aux_ptr); + + if(NULL == aux_ptr) { + HDsnprintf(file_name, n_chars, "%s", log_location); + } + else { + if(aux_ptr->magic != H5AC__H5AC_AUX_T_MAGIC) { + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "bad aux_ptr->magic") + } + HDsnprintf(file_name, n_chars, "%s.%d", log_location, aux_ptr->mpi_rank); + } + +#else /* H5_HAVE_PARALLEL */ + + HDsnprintf(file_name, n_chars, "%s", log_location); + +#endif /* H5_HAVE_PARALLEL */ + + /* Open log file */ + if(NULL == (cache_ptr->log_file_ptr = HDfopen(file_name, "w"))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "can't create mdc log file") + + /* Set logging flags */ + cache_ptr->logging_enabled = TRUE; + cache_ptr->currently_logging = start_immediately; + + done: + + HDfree(file_name); + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5C_set_up_logging() */ + + +/*------------------------------------------------------------------------- + * Function: H5C_tear_down_logging + * + * Purpose: Tear-down for metadata cache logging. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5C_tear_down_logging(H5C_t *cache_ptr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(cache_ptr); + HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); + + /* Sanity checks */ + if(NULL == cache_ptr) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cache_ptr == NULL") + + if(H5C__H5C_T_MAGIC != cache_ptr->magic) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cache magic value incorrect") + + if(FALSE == cache_ptr->logging_enabled) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "logging not enabled") + + /* Unset logging flags */ + cache_ptr->logging_enabled = FALSE; + cache_ptr->currently_logging = FALSE; + + /* Close log file */ + if(EOF == HDfclose(cache_ptr->log_file_ptr)) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problem closing mdc log file") + cache_ptr->log_file_ptr = NULL; + + done: + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5C_tear_down_logging() */ + + +/*------------------------------------------------------------------------- + * Function: H5C_start_logging + * + * Purpose: Start logging metadata cache operations. + * + * TODO: Add a function that dumps the current state of the + * metadata cache. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5C_start_logging(H5C_t *cache_ptr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(cache_ptr); + HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); + + /* Sanity checks */ + if(NULL == cache_ptr) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cache_ptr == NULL") + + if(H5C__H5C_T_MAGIC != cache_ptr->magic) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cache magic value incorrect") + + if(FALSE == cache_ptr->logging_enabled) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "logging not enabled") + + if(cache_ptr->currently_logging) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "logging already in progress") + + /* Set logging flags */ + cache_ptr->currently_logging = TRUE; + + /* TODO - Dump cache state */ + + done: + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5C_start_logging() */ + + +/*------------------------------------------------------------------------- + * Function: H5C_stop_logging + * + * Purpose: Stop logging metadata cache operations. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5C_stop_logging(H5C_t *cache_ptr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(cache_ptr); + HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); + + /* Sanity checks */ + if(NULL == cache_ptr) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cache_ptr == NULL") + + if(H5C__H5C_T_MAGIC != cache_ptr->magic) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cache magic value incorrect") + + if(FALSE == cache_ptr->logging_enabled) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "logging not enabled") + + if(FALSE == cache_ptr->currently_logging) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "logging not in progress") + + /* Set logging flags */ + cache_ptr->currently_logging = FALSE; + + done: + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5C_stop_logging() */ + + +/*------------------------------------------------------------------------- + * Function: H5C_get_logging_status + * + * Purpose: Determines if the cache is actively logging (via the OUT + * parameter). + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5C_get_logging_status(const H5C_t *cache_ptr, /*OUT*/ hbool_t *is_enabled, + /*OUT*/ hbool_t *is_currently_logging) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(cache_ptr); + HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); + HDassert(is_enabled); + HDassert(is_currently_logging); + + /* Sanity checks */ + if(NULL == cache_ptr) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cache_ptr == NULL") + + if(H5C__H5C_T_MAGIC != cache_ptr->magic) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cache magic value incorrect") + + *is_enabled = cache_ptr->logging_enabled; + *is_currently_logging = cache_ptr->currently_logging; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5C_get_logging_status() */ + + +/*------------------------------------------------------------------------- + * Function: H5C_write_log_message + * + * Purpose: Write a message to the log file and flush the file. + * The message string is neither modified nor freed. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5C_write_log_message(const H5C_t *cache_ptr, const char message[]) +{ + size_t n_chars; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(cache_ptr); + HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); + HDassert(message); + + /* Sanity checks */ + if(NULL == cache_ptr) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cache_ptr == NULL") + + if(H5C__H5C_T_MAGIC != cache_ptr->magic) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cache magic value incorrect") + + if(FALSE == cache_ptr->currently_logging) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "not currently logging") + + if(NULL == message) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL log message not allowed") + + /* Write the log message and flush */ + n_chars = HDstrlen(message); + if((int)n_chars != HDfprintf(cache_ptr->log_file_ptr, message)) + HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "error writing log message") + if(EOF == HDfflush(cache_ptr->log_file_ptr)) + HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "error flushing log message") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5C_write_log_message() */ /*------------------------------------------------------------------------- @@ -4661,7 +4981,7 @@ herr_t H5C_set_trace_file_ptr(H5C_t * cache_ptr, FILE * trace_file_ptr) { - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -4682,6 +5002,46 @@ done: /*------------------------------------------------------------------------- + * Function: H5C_set_log_file_ptr + * + * Purpose: Set the log_file_ptr field for the cache. + * + * This field must either be NULL (which turns of metadata + * cache logging), or be a pointer to an open file to which + * log entries are to be written. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: John Mainzer + * 1/20/06 + * + *------------------------------------------------------------------------- + */ +herr_t +H5C_set_log_file_ptr(H5C_t * cache_ptr, + FILE * log_file_ptr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* This would normally be an assert, but we need to use an HGOTO_ERROR + * call to shut up the compiler. + */ + if ( ( ! cache_ptr ) || ( cache_ptr->magic != H5C__H5C_T_MAGIC ) ) { + + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad cache_ptr") + } + + cache_ptr->log_file_ptr = log_file_ptr; + +done: + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5C_set_log_file_ptr() */ + + +/*------------------------------------------------------------------------- * Function: H5C_stats * * Purpose: Prints statistics about the cache. diff --git a/src/H5Cpkg.h b/src/H5Cpkg.h index 7118391..61c0539 100644 --- a/src/H5Cpkg.h +++ b/src/H5Cpkg.h @@ -2661,6 +2661,29 @@ if ( (cache_ptr)->index_size != \ * When we get to using H5C in other places, we may add * code to write trace file data at the H5C level as well. * + * logging_enabled: Boolean flag indicating whether cache logging + * which is used to record cache operations for use in + * debugging and performance analysis. When this flag is set + * to TRUE, it means that the log file is open and ready to + * receive log entries. It does NOT mean that cache operations + * are currently being recorded. That is controlled by the + * currently_logging flag (below). + * + * Since much of the code supporting the parallel metadata + * cache is in H5AC, we don't write the trace file from + * H5C. Instead, H5AC reads the trace_file_ptr as needed. + * + * When we get to using H5C in other places, we may add + * code to write trace file data at the H5C level as well. + * + * currently_logging: Boolean flag that indicates if cache operations are + * currently being logged. This flag is flipped by the + * H5Fstart/stop_mdc_logging functions. + * + * log_file_ptr: File pointer pointing to the log file. The I/O functions + * in stdio.h are used to write to the log file regardless of + * the VFD selected. + * * aux_ptr: Pointer to void used to allow wrapper code to associate * its data with an instance of H5C_t. The H5C cache code * sets this field to NULL, and otherwise leaves it alone. @@ -3417,6 +3440,9 @@ struct H5C_t { uint32_t magic; hbool_t flush_in_progress; FILE * trace_file_ptr; + hbool_t logging_enabled; + hbool_t currently_logging; + FILE * log_file_ptr; void * aux_ptr; int32_t max_type_id; const char * (* type_name_table_ptr); diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h index 446505c..902e635 100644 --- a/src/H5Cprivate.h +++ b/src/H5Cprivate.h @@ -1027,6 +1027,14 @@ H5_DLL H5C_t *H5C_create(size_t max_cache_size, size_t min_clean_size, int max_type_id, const char *(*type_name_table_ptr), H5C_write_permitted_func_t check_write_permitted, hbool_t write_permitted, H5C_log_flush_func_t log_flush, void *aux_ptr); +H5_DLL herr_t H5C_set_up_logging(H5C_t *cache_ptr, const char log_location[], hbool_t start_immediately); +H5_DLL herr_t H5C_tear_down_logging(H5C_t *cache_ptr); +H5_DLL herr_t H5C_start_logging(H5C_t *cache_ptr); +H5_DLL herr_t H5C_stop_logging(H5C_t *cache_ptr); +H5_DLL herr_t H5C_get_logging_status(const H5C_t *cache_ptr, /*OUT*/ hbool_t *is_enabled, + /*OUT*/ hbool_t *is_currently_logging); +H5_DLL herr_t H5C_write_log_message(const H5C_t *cache_ptr, const char message[]); + H5_DLL void H5C_def_auto_resize_rpt_fcn(H5C_t *cache_ptr, int32_t version, double hit_rate, enum H5C_resize_status status, size_t old_max_cache_size, size_t new_max_cache_size, @@ -1066,10 +1074,10 @@ H5_DLL void * H5C_protect(H5F_t *f, hid_t primary_dxpl_id, hid_t secondary_dxpl_ const H5C_class_t *type, haddr_t addr, void *udata, unsigned flags); H5_DLL herr_t H5C_reset_cache_hit_rate_stats(H5C_t *cache_ptr); H5_DLL herr_t H5C_resize_entry(void *thing, size_t new_size); -H5_DLL herr_t H5C_set_cache_auto_resize_config(H5C_t *cache_ptr, - H5C_auto_size_ctl_t *config_ptr); +H5_DLL herr_t H5C_set_cache_auto_resize_config(H5C_t *cache_ptr, H5C_auto_size_ctl_t *config_ptr); H5_DLL herr_t H5C_set_evictions_enabled(H5C_t *cache_ptr, hbool_t evictions_enabled); H5_DLL herr_t H5C_set_prefix(H5C_t *cache_ptr, char *prefix); +H5_DLL herr_t H5C_set_log_file_ptr(H5C_t * cache_ptr, FILE * log_file_ptr); H5_DLL herr_t H5C_set_trace_file_ptr(H5C_t *cache_ptr, FILE *trace_file_ptr); H5_DLL herr_t H5C_stats(H5C_t *cache_ptr, const char *cache_name, hbool_t display_detailed_stats); @@ -1083,6 +1091,7 @@ H5_DLL herr_t H5C_validate_resize_config(H5C_auto_size_ctl_t *config_ptr, unsigned int tests); H5_DLL herr_t H5C_ignore_tags(H5C_t *cache_ptr); H5_DLL void H5C_retag_entries(H5C_t * cache_ptr, haddr_t src_tag, haddr_t dest_tag); +H5_DLL herr_t H5C_cork(H5C_t *cache_ptr, haddr_t obj_addr, unsigned action, hbool_t *corked); #ifdef H5_HAVE_PARALLEL H5_DLL herr_t H5C_apply_candidate_list(H5F_t *f, hid_t primary_dxpl_id, @@ -1100,7 +1109,5 @@ H5_DLL herr_t H5C_verify_entry_type(const H5F_t *f, haddr_t addr, hbool_t *type_ok_ptr); #endif /* NDEBUG */ -H5_DLL herr_t H5C_cork(H5C_t *cache_ptr, haddr_t obj_addr, unsigned action, hbool_t *corked); - #endif /* !_H5Cprivate_H */ diff --git a/src/H5Edefin.h b/src/H5Edefin.h index 183f72c..5135920 100644 --- a/src/H5Edefin.h +++ b/src/H5Edefin.h @@ -174,6 +174,7 @@ hid_t H5E_CANTRESIZE_g = FAIL; /* Unable to resize a metadata cache ent hid_t H5E_CANTDEPEND_g = FAIL; /* Unable to create a flush dependency */ hid_t H5E_CANTUNDEPEND_g = FAIL; /* Unable to destroy a flush dependency */ hid_t H5E_CANTNOTIFY_g = FAIL; /* Unable to notify object about action */ +hid_t H5E_LOGFAIL_g = FAIL; /* Failure in the cache logging framework */ /* Link related errors */ hid_t H5E_TRAVERSE_g = FAIL; /* Link traversal failure */ diff --git a/src/H5Einit.h b/src/H5Einit.h index 9724748..4371349 100644 --- a/src/H5Einit.h +++ b/src/H5Einit.h @@ -664,6 +664,11 @@ if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to notify object about action") HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") if((H5E_CANTNOTIFY_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_LOGFAIL_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Failure in the cache logging framework"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_LOGFAIL_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") /* Link related errors */ assert(H5E_TRAVERSE_g==(-1)); diff --git a/src/H5Epubgen.h b/src/H5Epubgen.h index e79106f..a2a90e7 100644 --- a/src/H5Epubgen.h +++ b/src/H5Epubgen.h @@ -281,6 +281,7 @@ H5_DLLVAR hid_t H5E_NOIDS_g; /* Out of IDs for group */ #define H5E_CANTDEPEND (H5OPEN H5E_CANTDEPEND_g) #define H5E_CANTUNDEPEND (H5OPEN H5E_CANTUNDEPEND_g) #define H5E_CANTNOTIFY (H5OPEN H5E_CANTNOTIFY_g) +#define H5E_LOGFAIL (H5OPEN H5E_LOGFAIL_g) H5_DLLVAR hid_t H5E_CANTFLUSH_g; /* Unable to flush data from cache */ H5_DLLVAR hid_t H5E_CANTSERIALIZE_g; /* Unable to serialize data from cache */ H5_DLLVAR hid_t H5E_CANTTAG_g; /* Unable to tag metadata in the cache */ @@ -300,6 +301,7 @@ H5_DLLVAR hid_t H5E_CANTRESIZE_g; /* Unable to resize a metadata cache entry H5_DLLVAR hid_t H5E_CANTDEPEND_g; /* Unable to create a flush dependency */ H5_DLLVAR hid_t H5E_CANTUNDEPEND_g; /* Unable to destroy a flush dependency */ H5_DLLVAR hid_t H5E_CANTNOTIFY_g; /* Unable to notify object about action */ +H5_DLLVAR hid_t H5E_LOGFAIL_g; /* Failure in the cache logging framework */ /* Link related errors */ #define H5E_TRAVERSE (H5OPEN H5E_TRAVERSE_g) diff --git a/src/H5Eterm.h b/src/H5Eterm.h index 5db503c..7acbab3 100644 --- a/src/H5Eterm.h +++ b/src/H5Eterm.h @@ -175,7 +175,8 @@ H5E_CANTEXPUNGE_g= H5E_CANTRESIZE_g= H5E_CANTDEPEND_g= H5E_CANTUNDEPEND_g= -H5E_CANTNOTIFY_g= +H5E_CANTNOTIFY_g= +H5E_LOGFAIL_g= /* Link related errors */ H5E_TRAVERSE_g= @@ -1805,3 +1805,105 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Fstart_swmr_write() */ + + +/*------------------------------------------------------------------------- + * Function: H5Fstart_mdc_logging + * + * Purpose: Start metadata cache logging operations for a file. + * - Logging must have been set up via the fapl. + * + * Return: Non-negative on success/Negative on errors + * + *------------------------------------------------------------------------- + */ +herr_t +H5Fstart_mdc_logging(hid_t file_id) +{ + H5F_t *file; /* File info */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "i", file_id); + + /* Sanity check */ + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID") + + /* Call mdc logging function */ + if(H5C_start_logging(file->shared->cache) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_LOGFAIL, FAIL, "unable to start mdc logging") + +done: + FUNC_LEAVE_API(ret_value) + +} /* H5Fstart_mdc_logging() */ + + +/*------------------------------------------------------------------------- + * Function: H5Fstop_mdc_logging + * + * Purpose: Stop metadata cache logging operations for a file. + * - Does not close the log file. + * - Logging must have been set up via the fapl. + * + * Return: Non-negative on success/Negative on errors + * + *------------------------------------------------------------------------- + */ +herr_t +H5Fstop_mdc_logging(hid_t file_id) +{ + H5F_t *file; /* File info */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "i", file_id); + + /* Sanity check */ + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID") + + /* Call mdc logging function */ + if(H5C_stop_logging(file->shared->cache) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_LOGFAIL, FAIL, "unable to stop mdc logging") + +done: + FUNC_LEAVE_API(ret_value) + +} /* H5Fstop_mdc_logging() */ + + +/*------------------------------------------------------------------------- + * Function: H5Fget_mdc_logging_status + * + * Purpose: Get the logging flags. is_enabled determines if logging was + * set up via the fapl. is_currently_logging determines if + * log messages are being recorded at this time. + * + * Return: Non-negative on success/Negative on errors + * + *------------------------------------------------------------------------- + */ +herr_t +H5Fget_mdc_logging_status(hid_t file_id, hbool_t *is_enabled, + hbool_t *is_currently_logging) +{ + H5F_t *file; /* File info */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "i*b*b", file_id, is_enabled, is_currently_logging); + + /* Sanity check */ + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID") + + /* Call mdc logging function */ + if(H5C_get_logging_status(file->shared->cache, is_enabled, is_currently_logging) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_LOGFAIL, FAIL, "unable to get logging status") + +done: + FUNC_LEAVE_API(ret_value) + +} /* H5Fstop_mdc_logging() */ diff --git a/src/H5Fint.c b/src/H5Fint.c index c7a3013..ed8c638 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -665,6 +665,10 @@ H5F_new(H5F_file_t *shared, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5FD_t HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get sieve buffer size") if(H5P_get(plist, H5F_ACS_LATEST_FORMAT_NAME, &(f->shared->latest_format)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'latest format' flag") + if(H5P_get(plist, H5F_ACS_USE_MDC_LOGGING_NAME, &(f->shared->use_mdc_logging)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'use mdc logging' flag") + if(H5P_get(plist, H5F_ACS_START_MDC_LOG_ON_ACCESS_NAME, &(f->shared->start_mdc_log_on_access)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'start mdc log on access' flag") /* Require the latest format to use SWMR */ /* (Need to revisit this when the 1.10 release is made, and require * 1.10 or later -QAK) @@ -732,6 +736,22 @@ H5F_new(H5F_file_t *shared, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5FD_t if(H5F_set_retries(f) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't set retries and retries_nbins") + /* Get the metadata cache log location (if we're logging) */ + { + char *mdc_log_location = NULL; /* location of metadata cache log location */ + + if(H5P_get(plist, H5F_ACS_MDC_LOG_LOCATION_NAME, &mdc_log_location) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get mdc log location") + if(mdc_log_location != NULL) { + size_t len = HDstrlen(mdc_log_location); + if(NULL == (f->shared->mdc_log_location = HDcalloc(len + 1, sizeof(char)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "can't allocate memory for mdc log file name") + HDstrncpy(f->shared->mdc_log_location, mdc_log_location, len); + } + else + f->shared->mdc_log_location = NULL; + } + /* Get object flush callback information */ if(H5P_get(plist, H5F_ACS_OBJECT_FLUSH_CB_NAME, &(f->shared->object_flush)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get object flush cb info") @@ -878,6 +898,10 @@ H5F_dest(H5F_t *f, hid_t dxpl_id, hbool_t flush) /* Push error, but keep going*/ HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") + /* Clean up the metadata cache log location string */ + if(f->shared->mdc_log_location) + HDfree(f->shared->mdc_log_location); + /* * Do not close the root group since we didn't count it, but free * the memory associated with it. diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 0bc7f5c..d2c43b5 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -246,6 +246,10 @@ struct H5F_file_t { /* metadata cache. This structure is */ /* fixed at creation time and should */ /* not change thereafter. */ + hbool_t use_mdc_logging; /* Set when metadata logging is desired */ + hbool_t start_mdc_log_on_access; /* set when mdc logging should */ + /* begin on file access/create */ + char *mdc_log_location; /* location of mdc log */ hid_t fcpl_id; /* File creation property list ID */ H5F_close_degree_t fc_degree; /* File close behavior degree */ size_t rdcc_nslots; /* Size of raw data chunk cache (slots) */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 2364386..7d69eac 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -458,6 +458,9 @@ #define H5F_ACS_EFC_SIZE_NAME "efc_size" /* Size of external file cache */ #define H5F_ACS_FILE_IMAGE_INFO_NAME "file_image_info" /* struct containing initial file image and callback info */ #define H5F_ACS_CLEAR_STATUS_FLAGS_NAME "clear_status_flags" /* Whether to clear superblock status_flags (private property only used by h5clear) */ +#define H5F_ACS_USE_MDC_LOGGING_NAME "use_mdc_logging" /* Whether to use metadata cache logging */ +#define H5F_ACS_MDC_LOG_LOCATION_NAME "mdc_log_location" /* Name of metadata cache log location */ +#define H5F_ACS_START_MDC_LOG_ON_ACCESS_NAME "start_mdc_log_on_access" /* Whether logging starts on file create/open */ #define H5F_ACS_CORE_WRITE_TRACKING_FLAG_NAME "core_write_tracking_flag" /* Whether or not core VFD backing store write tracking is enabled */ #define H5F_ACS_CORE_WRITE_TRACKING_PAGE_SIZE_NAME "core_write_tracking_page_size" /* The page size in kiB when core VFD write tracking is enabled */ @@ -548,6 +551,9 @@ /* Global heap signature */ #define H5HG_MAGIC "GCOL" +/* Global heap signature */ +#define H5HG_MAGIC "GCOL" + /* Local heap signature */ #define H5HL_MAGIC "HEAP" @@ -669,9 +675,6 @@ H5_DLL hid_t H5F_get_driver_id(const H5F_t *f); H5_DLL herr_t H5F_get_fileno(const H5F_t *f, unsigned long *filenum); H5_DLL hbool_t H5F_has_feature(const H5F_t *f, unsigned feature); H5_DLL haddr_t H5F_get_eoa(const H5F_t *f, H5FD_mem_t type); -H5_DLL herr_t H5F_get_vfd_handle(const H5F_t *file, hid_t fapl, - void **file_handle); - /* Functions that check file mounting information */ H5_DLL hbool_t H5F_is_mount(const H5F_t *file); H5_DLL hbool_t H5F_has_mount(const H5F_t *file); diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h index 1deac35..fa45d10 100644 --- a/src/H5Fpublic.h +++ b/src/H5Fpublic.h @@ -241,6 +241,11 @@ H5_DLL herr_t H5Fstart_swmr_write(hid_t file_id); H5_DLL ssize_t H5Fget_free_sections(hid_t file_id, H5F_mem_t type, size_t nsects, H5F_sect_info_t *sect_info/*out*/); H5_DLL herr_t H5Fclear_elink_file_cache(hid_t file_id); +H5_DLL herr_t H5Fstart_mdc_logging(hid_t file_id); +H5_DLL herr_t H5Fstop_mdc_logging(hid_t file_id); +H5_DLL herr_t H5Fget_mdc_logging_status(hid_t file_id, + /*OUT*/ hbool_t *is_enabled, + /*OUT*/ hbool_t *is_currently_logging); #ifdef H5_HAVE_PARALLEL H5_DLL herr_t H5Fset_mpi_atomicity(hid_t file_id, hbool_t flag); H5_DLL herr_t H5Fget_mpi_atomicity(hid_t file_id, hbool_t *flag); diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index 628100a..aa79885 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -160,6 +160,16 @@ #define H5F_ACS_FILE_IMAGE_INFO_DEL H5P_file_image_info_del #define H5F_ACS_FILE_IMAGE_INFO_COPY H5P_file_image_info_copy #define H5F_ACS_FILE_IMAGE_INFO_CLOSE H5P_file_image_info_close +/* Definition of core VFD write tracking flag */ +#define H5F_ACS_CORE_WRITE_TRACKING_FLAG_SIZE sizeof(hbool_t) +#define H5F_ACS_CORE_WRITE_TRACKING_FLAG_DEF FALSE +#define H5F_ACS_CORE_WRITE_TRACKING_FLAG_ENC H5P__encode_hbool_t +#define H5F_ACS_CORE_WRITE_TRACKING_FLAG_DEC H5P__decode_hbool_t +/* Definition of core VFD write tracking page size */ +#define H5F_ACS_CORE_WRITE_TRACKING_PAGE_SIZE_SIZE sizeof(size_t) +#define H5F_ACS_CORE_WRITE_TRACKING_PAGE_SIZE_DEF 524288 +#define H5F_ACS_CORE_WRITE_TRACKING_PAGE_SIZE_ENC H5P__encode_size_t +#define H5F_ACS_CORE_WRITE_TRACKING_PAGE_SIZE_DEC H5P__decode_size_t /* Definition for # of metadata read attempts */ #define H5F_ACS_METADATA_READ_ATTEMPTS_SIZE sizeof(unsigned) #define H5F_ACS_METADATA_READ_ATTEMPTS_DEF 0 @@ -171,16 +181,25 @@ /* Definition for status_flags in the superblock */ #define H5F_ACS_CLEAR_STATUS_FLAGS_SIZE sizeof(hbool_t) #define H5F_ACS_CLEAR_STATUS_FLAGS_DEF FALSE -/* Definition of core VFD write tracking flag */ -#define H5F_ACS_CORE_WRITE_TRACKING_FLAG_SIZE sizeof(hbool_t) -#define H5F_ACS_CORE_WRITE_TRACKING_FLAG_DEF FALSE -#define H5F_ACS_CORE_WRITE_TRACKING_FLAG_ENC H5P__encode_hbool_t -#define H5F_ACS_CORE_WRITE_TRACKING_FLAG_DEC H5P__decode_hbool_t -/* Definition of core VFD write tracking page size */ -#define H5F_ACS_CORE_WRITE_TRACKING_PAGE_SIZE_SIZE sizeof(size_t) -#define H5F_ACS_CORE_WRITE_TRACKING_PAGE_SIZE_DEF 524288 -#define H5F_ACS_CORE_WRITE_TRACKING_PAGE_SIZE_ENC H5P__encode_size_t -#define H5F_ACS_CORE_WRITE_TRACKING_PAGE_SIZE_DEC H5P__decode_size_t +/* Definition for 'use metadata cache logging' flag */ +#define H5F_ACS_USE_MDC_LOGGING_SIZE sizeof(hbool_t) +#define H5F_ACS_USE_MDC_LOGGING_DEF FALSE +#define H5F_ACS_USE_MDC_LOGGING_ENC H5P__encode_hbool_t +#define H5F_ACS_USE_MDC_LOGGING_DEC H5P__decode_hbool_t +/* Definition for 'mdc log location' flag */ +#define H5F_ACS_MDC_LOG_LOCATION_SIZE sizeof(char *) +#define H5F_ACS_MDC_LOG_LOCATION_DEF NULL /* default is no log location */ +#define H5F_ACS_MDC_LOG_LOCATION_ENC H5P_facc_mdc_log_location_enc +#define H5F_ACS_MDC_LOG_LOCATION_DEC H5P_facc_mdc_log_location_dec +#define H5F_ACS_MDC_LOG_LOCATION_DEL H5P_facc_mdc_log_location_del +#define H5F_ACS_MDC_LOG_LOCATION_COPY H5P_facc_mdc_log_location_copy +#define H5F_ACS_MDC_LOG_LOCATION_CMP H5P_facc_mdc_log_location_cmp +#define H5F_ACS_MDC_LOG_LOCATION_CLOSE H5P_facc_mdc_log_location_close +/* Definition for 'start metadata cache logging on access' flag */ +#define H5F_ACS_START_MDC_LOG_ON_ACCESS_SIZE sizeof(hbool_t) +#define H5F_ACS_START_MDC_LOG_ON_ACCESS_DEF FALSE +#define H5F_ACS_START_MDC_LOG_ON_ACCESS_ENC H5P__encode_hbool_t +#define H5F_ACS_START_MDC_LOG_ON_ACCESS_DEC H5P__decode_hbool_t /******************/ @@ -216,6 +235,14 @@ static herr_t H5P__facc_fclose_degree_dec(const void **pp, void *value); static herr_t H5P__facc_multi_type_enc(const void *value, void **_pp, size_t *size); static herr_t H5P__facc_multi_type_dec(const void **_pp, void *value); +/* Metadata cache log location property callbacks */ +static herr_t H5P_facc_mdc_log_location_enc(const void *value, void **_pp, size_t *size); +static herr_t H5P_facc_mdc_log_location_dec(const void **_pp, void *value); +static herr_t H5P_facc_mdc_log_location_del(hid_t prop_id, const char *name, size_t size, void *value); +static herr_t H5P_facc_mdc_log_location_copy(const char *name, size_t size, void *value); +static int H5P_facc_mdc_log_location_cmp(const void *value1, const void *value2, size_t size); +static herr_t H5P_facc_mdc_log_location_close(const char *name, size_t size, void *value); + /*********************/ /* Package Variables */ @@ -274,8 +301,11 @@ static const H5FD_file_image_info_t H5F_def_file_image_info_g = H5F_ACS_FILE_IMA static const hbool_t H5F_def_core_write_tracking_flag_g = H5F_ACS_CORE_WRITE_TRACKING_FLAG_DEF; /* Default setting for core VFD write tracking */ static const size_t H5F_def_core_write_tracking_page_size_g = H5F_ACS_CORE_WRITE_TRACKING_PAGE_SIZE_DEF; /* Default core VFD write tracking page size */ static const unsigned H5F_def_metadata_read_attempts_g = H5F_ACS_METADATA_READ_ATTEMPTS_DEF; /* Default setting for the # of metadata read attempts */ -static const H5F_object_flush_t H5F_def_object_flush_cb_g = H5F_ACS_OBJECT_FLUSH_CB_DEF; /* Default setting for object flush callback */ -static const hbool_t H5F_def_clear_status_flags_g = H5F_ACS_CLEAR_STATUS_FLAGS_DEF; /* Default to clear the superblock status_flags */ +static const H5F_object_flush_t H5F_def_object_flush_cb_g = H5F_ACS_OBJECT_FLUSH_CB_DEF; /* Default setting for object flush callback */ +static const hbool_t H5F_def_clear_status_flags_g = H5F_ACS_CLEAR_STATUS_FLAGS_DEF; /* Default to clear the superblock status_flags */ +static const hbool_t H5F_def_use_mdc_logging_g = H5F_ACS_USE_MDC_LOGGING_DEF; /* Default metadata cache logging flag */ +static const char *H5F_def_mdc_log_location_g = H5F_ACS_MDC_LOG_LOCATION_DEF; /* Default mdc log location */ +static const hbool_t H5F_def_start_mdc_log_on_access_g = H5F_ACS_START_MDC_LOG_ON_ACCESS_DEF; /* Default mdc log start on access flag */ /*------------------------------------------------------------------------- @@ -453,6 +483,21 @@ H5P_facc_reg_prop(H5P_genclass_t *pclass) NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + /* Register the metadata cache logging flag. */ + if(H5P_register_real(pclass, H5F_ACS_USE_MDC_LOGGING_NAME, H5F_ACS_USE_MDC_LOGGING_SIZE, &H5F_def_use_mdc_logging_g, + NULL, NULL, NULL, H5F_ACS_USE_MDC_LOGGING_ENC, H5F_ACS_USE_MDC_LOGGING_DEC, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + + /* Register the metadata cache log location. */ + if(H5P_register_real(pclass, H5F_ACS_MDC_LOG_LOCATION_NAME, H5F_ACS_MDC_LOG_LOCATION_SIZE, &H5F_def_mdc_log_location_g, + NULL, NULL, NULL, H5F_ACS_MDC_LOG_LOCATION_ENC, H5F_ACS_MDC_LOG_LOCATION_DEC, + H5F_ACS_MDC_LOG_LOCATION_DEL, H5F_ACS_MDC_LOG_LOCATION_COPY, H5F_ACS_MDC_LOG_LOCATION_CMP, H5F_ACS_MDC_LOG_LOCATION_CLOSE) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + + /* Register the flag that indicates whether mdc logging starts on file access. */ + if(H5P_register_real(pclass, H5F_ACS_START_MDC_LOG_ON_ACCESS_NAME, H5F_ACS_START_MDC_LOG_ON_ACCESS_SIZE, &H5F_def_start_mdc_log_on_access_g, + NULL, NULL, NULL, H5F_ACS_START_MDC_LOG_ON_ACCESS_ENC, H5F_ACS_START_MDC_LOG_ON_ACCESS_DEC, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") done: FUNC_LEAVE_NOAPI(ret_value) @@ -1038,7 +1083,7 @@ H5Pget_family_offset(hid_t fapl_id, hsize_t *offset) /* Get value */ if(offset) { if(H5P_get(plist, H5F_ACS_FAMILY_OFFSET_NAME, offset) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set offset for family file") + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set offset for family file") } /* end if */ done: @@ -1118,7 +1163,7 @@ H5Pget_multi_type(hid_t fapl_id, H5FD_mem_t *type) /* Get value */ if(type) { if(H5P_get(plist, H5F_ACS_MULTI_TYPE_NAME, type) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't get type for multi driver") + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get type for multi driver") } /* end if */ done: @@ -2523,16 +2568,6 @@ H5P__facc_cache_config_cmp(const void *_config1, const void *_config2, size_t H5 if(config1->rpt_fcn_enabled < config2->rpt_fcn_enabled) HGOTO_DONE(-1); if(config1->rpt_fcn_enabled > config2->rpt_fcn_enabled) HGOTO_DONE(1); - if(config1->open_trace_file < config2->open_trace_file) HGOTO_DONE(-1); - if(config1->open_trace_file > config2->open_trace_file) HGOTO_DONE(1); - - if(config1->close_trace_file < config2->close_trace_file) HGOTO_DONE(-1); - if(config1->close_trace_file > config2->close_trace_file) HGOTO_DONE(1); - - if((ret_value = HDstrncmp(config1->trace_file_name, config2->trace_file_name, - (size_t)(H5AC__MAX_TRACE_FILE_NAME_LEN + 1))) != 0) - HGOTO_DONE(ret_value); - if(config1->evictions_enabled < config2->evictions_enabled) HGOTO_DONE(-1); if(config1->evictions_enabled > config2->evictions_enabled) HGOTO_DONE(1); @@ -3242,6 +3277,7 @@ H5Pset_object_flush_cb(hid_t plist_id, H5F_flush_cb_t func, void *udata) done: FUNC_LEAVE_API(ret_value) } /* H5Pset_obj_flush_cb() */ + /*------------------------------------------------------------------------- * Function: H5Pget_obj_flush_cb @@ -3282,3 +3318,321 @@ H5Pget_object_flush_cb(hid_t plist_id, H5F_flush_cb_t *func, void **udata) done: FUNC_LEAVE_API(ret_value) } /* H5Pget_obj_flush_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pset_mdc_log_options + * + * Purpose: Set metadata cache log options. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_mdc_log_options(hid_t plist_id, hbool_t is_enabled, const char *location, + hbool_t start_on_access) +{ + H5P_genplist_t *plist; /* Property list pointer */ + char * tmp_location; /* Working location pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE4("e", "ib*sb", plist_id, is_enabled, location, start_on_access); + + /* Check arguments */ + if(H5P_DEFAULT == plist_id) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "can't modify default property list") + if(!location) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "location cannot be NULL") + + /* Get the property list structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_FILE_ACCESS))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plist_id is not a file access property list") + + /* Get the current location string and free it */ + if(H5P_get(plist, H5F_ACS_MDC_LOG_LOCATION_NAME, &tmp_location) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get current log location") + H5MM_xfree(tmp_location); + + /* Make a copy of the passed-in location */ + if(NULL == (tmp_location = H5MM_xstrdup(location))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy passed-in log location") + + /* Set values */ + if(H5P_set(plist, H5F_ACS_USE_MDC_LOGGING_NAME, &is_enabled) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set is_enabled flag") + if(H5P_set(plist, H5F_ACS_MDC_LOG_LOCATION_NAME, &tmp_location) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set log location") + if(H5P_set(plist, H5F_ACS_START_MDC_LOG_ON_ACCESS_NAME, &start_on_access) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set start_on_access flag") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_mdc_log_options() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_mdc_log_options + * + * Purpose: Get metadata cache log options. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_mdc_log_options(hid_t plist_id, hbool_t *is_enabled, char *location, + size_t *location_size, hbool_t *start_on_access) +{ + H5P_genplist_t *plist; /* Property list pointer */ + char *location_ptr; /* Pointer to location string */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "i*b*s*z*b", plist_id, is_enabled, location, location_size, + start_on_access); + + /* Get the property list structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_FILE_ACCESS))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plist_id is not a file access property list") + + /* Get simple values */ + if(is_enabled) + if(H5P_get(plist, H5F_ACS_USE_MDC_LOGGING_NAME, is_enabled) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get log location") + if(start_on_access) + if(H5P_get(plist, H5F_ACS_START_MDC_LOG_ON_ACCESS_NAME, start_on_access) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get start_on_access flag") + + /* Get the location */ + if(location || location_size) + if(H5P_get(plist, H5F_ACS_MDC_LOG_LOCATION_NAME, &location_ptr) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get log location") + + /* Copy log location to output buffer */ + if(location_ptr && location) + HDmemcpy(location, location_ptr, *location_size); + + /* Get location size, including terminating NULL */ + if(location_size) { + if(location_ptr) + *location_size = HDstrlen(location_ptr) + 1; + else + *location_size = 0; + } + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_mdc_log_options() */ + + +/*------------------------------------------------------------------------- + * Function: H5P_facc_mdc_log_location_enc + * + * Purpose: Callback routine which is called whenever the metadata + * cache log location property in the file access property + * list is encoded. + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +static herr_t +H5P_facc_mdc_log_location_enc(const void *value, void **_pp, size_t *size) +{ + const char *log_location = *(const char * const *)value; + uint8_t **pp = (uint8_t **)_pp; + size_t len = 0; + uint64_t enc_value; + unsigned enc_size; + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t)); + + /* calculate prefix length */ + if(NULL != log_location) + len = HDstrlen(log_location); + + enc_value = (uint64_t)len; + enc_size = H5VM_limit_enc_size(enc_value); + HDassert(enc_size < 256); + + if(NULL != *pp) { + /* encode the length of the prefix */ + *(*pp)++ = (uint8_t)enc_size; + UINT64ENCODE_VAR(*pp, enc_value, enc_size); + + /* encode the prefix */ + if(NULL != log_location) { + HDmemcpy(*(char **)pp, log_location, len); + *pp += len; + } /* end if */ + } /* end if */ + + *size += (1 + enc_size); + if(NULL != log_location) + *size += len; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5P_facc_mdc_log_location_enc() */ + + +/*------------------------------------------------------------------------- + * Function: H5P_facc_mdc_log_location_dec + * + * Purpose: Callback routine which is called whenever the metadata + * cache log location property in the file access property + * list is decoded. + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +static herr_t +H5P_facc_mdc_log_location_dec(const void **_pp, void *_value) +{ + char **log_location = (char **)_value; + const uint8_t **pp = (const uint8_t **)_pp; + size_t len; + uint64_t enc_value; /* Decoded property value */ + unsigned enc_size; /* Size of encoded property */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + HDassert(pp); + HDassert(*pp); + HDassert(log_location); + HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t)); + + /* Decode the size */ + enc_size = *(*pp)++; + HDassert(enc_size < 256); + + /* Decode the value */ + UINT64DECODE_VAR(*pp, enc_value, enc_size); + len = enc_value; + + if(0 != len) { + /* Make a copy of the user's prefix string */ + if(NULL == (*log_location = (char *)H5MM_malloc(len + 1))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "memory allocation failed for prefix") + HDstrncpy(*log_location, *(const char **)pp, len); + (*log_location)[len] = '\0'; + + *pp += len; + } /* end if */ + else + *log_location = NULL; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P_facc_mdc_log_location_dec() */ + + +/*------------------------------------------------------------------------- + * Function: H5P_facc_mdc_log_location_del + * + * Purpose: Frees memory used to store the metadata cache log location. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +static herr_t +H5P_facc_mdc_log_location_del(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name, + size_t H5_ATTR_UNUSED size, void *value) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(value); + + H5MM_xfree(*(void **)value); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5P_facc_mdc_log_location_del() */ + + +/*------------------------------------------------------------------------- + * Function: H5P_facc_mdc_log_location_copy + * + * Purpose: Creates a copy of the metadata cache log location string. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +static herr_t +H5P_facc_mdc_log_location_copy(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(value); + + *(char **)value = H5MM_xstrdup(*(const char **)value); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5P_facc_mdc_log_location_copy() */ + + +/*------------------------------------------------------------------------- + * Function: H5P_facc_mdc_log_location_cmp + * + * Purpose: Callback routine which is called whenever the metadata + * cache log location property in the file creation property + * list is compared. + * + * Return: zero if VALUE1 and VALUE2 are equal, non zero otherwise. + * + *------------------------------------------------------------------------- + */ +static int +H5P_facc_mdc_log_location_cmp(const void *value1, const void *value2, size_t H5_ATTR_UNUSED size) +{ + const char *pref1 = *(const char * const *)value1; + const char *pref2 = *(const char * const *)value2; + int ret_value = 0; + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + if(NULL == pref1 && NULL != pref2) + HGOTO_DONE(1); + if(NULL != pref1 && NULL == pref2) + HGOTO_DONE(-1); + if(NULL != pref1 && NULL != pref2) + ret_value = HDstrcmp(pref1, pref2); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P_facc_mdc_log_location_cmp() */ + + +/*------------------------------------------------------------------------- + * Function: H5P_facc_mdc_log_location_close + * + * Purpose: Frees memory used to store the metadata cache log location + * string + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +static herr_t +H5P_facc_mdc_log_location_close(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(value); + + H5MM_xfree(*(void **)value); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5P_facc_mdc_log_location_close() */ + diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index cfbbf39..69de7ce 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -345,13 +345,14 @@ H5_DLL herr_t H5Pset_file_image_callbacks(hid_t fapl_id, H5FD_file_image_callbacks_t *callbacks_ptr); H5_DLL herr_t H5Pget_file_image_callbacks(hid_t fapl_id, H5FD_file_image_callbacks_t *callbacks_ptr); +H5_DLL herr_t H5Pset_core_write_tracking(hid_t fapl_id, hbool_t is_enabled, size_t page_size); +H5_DLL herr_t H5Pget_core_write_tracking(hid_t fapl_id, hbool_t *is_enabled, size_t *page_size); H5_DLL herr_t H5Pset_metadata_read_attempts(hid_t plist_id, unsigned attempts); H5_DLL herr_t H5Pget_metadata_read_attempts(hid_t plist_id, unsigned *attempts); H5_DLL herr_t H5Pset_object_flush_cb(hid_t plist_id, H5F_flush_cb_t func, void *udata); H5_DLL herr_t H5Pget_object_flush_cb(hid_t plist_id, H5F_flush_cb_t *func, void **udata); - -H5_DLL herr_t H5Pset_core_write_tracking(hid_t fapl_id, hbool_t is_enabled, size_t page_size); -H5_DLL herr_t H5Pget_core_write_tracking(hid_t fapl_id, hbool_t *is_enabled, size_t *page_size); +H5_DLL herr_t H5Pset_mdc_log_options(hid_t plist_id, hbool_t is_enabled, const char *location, hbool_t start_on_access); +H5_DLL herr_t H5Pget_mdc_log_options(hid_t plist_id, hbool_t *is_enabled, char *location, size_t *location_size, hbool_t *start_on_access); /* Dataset creation property list (DCPL) routines */ H5_DLL herr_t H5Pset_layout(hid_t plist_id, H5D_layout_t layout); diff --git a/src/H5err.txt b/src/H5err.txt index 5a38cdf..61c1a40 100644 --- a/src/H5err.txt +++ b/src/H5err.txt @@ -175,6 +175,7 @@ MINOR, CACHE, H5E_CANTRESIZE, Unable to resize a metadata cache entry MINOR, CACHE, H5E_CANTDEPEND, Unable to create a flush dependency MINOR, CACHE, H5E_CANTUNDEPEND, Unable to destroy a flush dependency MINOR, CACHE, H5E_CANTNOTIFY, Unable to notify object about action +MINOR, CACHE, H5E_LOGFAIL, Failure in the cache logging framework # B-tree related errors MINOR, BTREE, H5E_NOTFOUND, Object not found diff --git a/src/Makefile.am b/src/Makefile.am index d92c0c8..22443db 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,7 +42,7 @@ DISTCLEANFILES=H5pubconf.h # library sources libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5A.c H5Abtree2.c H5Adense.c H5Adeprec.c H5Aint.c H5Atest.c \ - H5AC.c H5B.c H5Bcache.c H5Bdbg.c \ + H5AC.c H5AClog.c H5B.c H5Bcache.c H5Bdbg.c \ H5B2.c H5B2cache.c H5B2dbg.c H5B2hdr.c H5B2int.c H5B2stat.c H5B2test.c \ H5C.c H5CS.c \ H5D.c H5Dbtree.c H5Dbtree2.c H5Dchunk.c H5Dcompact.c H5Dcontig.c H5Ddbg.c \ diff --git a/src/Makefile.in b/src/Makefile.in index 941a81d..a8dce92 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -150,10 +150,10 @@ LTLIBRARIES = $(lib_LTLIBRARIES) libhdf5_la_LIBADD = am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \ H5timer.lo H5trace.lo H5A.lo H5Abtree2.lo H5Adense.lo \ - H5Adeprec.lo H5Aint.lo H5Atest.lo H5AC.lo H5B.lo H5Bcache.lo \ - H5Bdbg.lo H5B2.lo H5B2cache.lo H5B2dbg.lo H5B2hdr.lo \ - H5B2int.lo H5B2stat.lo H5B2test.lo H5C.lo H5CS.lo H5D.lo \ - H5Dbtree.lo H5Dbtree2.lo H5Dchunk.lo H5Dcompact.lo \ + H5Adeprec.lo H5Aint.lo H5Atest.lo H5AC.lo H5AClog.lo H5B.lo \ + H5Bcache.lo H5Bdbg.lo H5B2.lo H5B2cache.lo H5B2dbg.lo \ + H5B2hdr.lo H5B2int.lo H5B2stat.lo H5B2test.lo H5C.lo H5CS.lo \ + H5D.lo H5Dbtree.lo H5Dbtree2.lo H5Dchunk.lo H5Dcompact.lo \ H5Dcontig.lo H5Ddbg.lo H5Ddeprec.lo H5Dearray.lo H5Defl.lo \ H5Dfarray.lo H5Dfill.lo H5Dint.lo H5Dio.lo H5Dlayout.lo \ H5Dmpio.lo H5Dnone.lo H5Doh.lo H5Dscatgath.lo H5Dselect.lo \ @@ -743,7 +743,7 @@ DISTCLEANFILES = H5pubconf.h # library sources libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5A.c H5Abtree2.c H5Adense.c H5Adeprec.c H5Aint.c H5Atest.c \ - H5AC.c H5B.c H5Bcache.c H5Bdbg.c \ + H5AC.c H5AClog.c H5B.c H5Bcache.c H5Bdbg.c \ H5B2.c H5B2cache.c H5B2dbg.c H5B2hdr.c H5B2int.c H5B2stat.c H5B2test.c \ H5C.c H5CS.c \ H5D.c H5Dbtree.c H5Dbtree2.c H5Dchunk.c H5Dcompact.c H5Dcontig.c H5Ddbg.c \ @@ -970,6 +970,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5A.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5AC.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5AClog.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Abtree2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Adense.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Adeprec.Plo@am__quote@ |