summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MANIFEST3
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/H5AC.c205
-rw-r--r--src/H5AClog.c1012
-rw-r--r--src/H5ACpkg.h58
-rw-r--r--src/H5ACprivate.h3
-rw-r--r--src/H5ACpublic.h6
-rw-r--r--src/H5C.c6
-rw-r--r--src/H5Clog.c370
-rw-r--r--src/H5Cpkg.h26
-rw-r--r--src/H5Cprivate.h7
-rw-r--r--src/H5F.c99
-rw-r--r--src/H5Fint.c8
-rw-r--r--src/H5Fpkg.h4
-rw-r--r--src/H5Fprivate.h12
-rw-r--r--src/H5Fpublic.h5
-rw-r--r--src/H5Fquery.c84
-rw-r--r--src/H5Pfapl.c370
-rw-r--r--src/H5Ppublic.h2
-rw-r--r--src/H5err.txt1
-rw-r--r--src/Makefile.am4
-rw-r--r--test/CMakeLists.txt1
-rw-r--r--test/CMakeTests.cmake3
-rw-r--r--test/Makefile.am6
-rw-r--r--test/cache_logging.c176
25 files changed, 2452 insertions, 21 deletions
diff --git a/MANIFEST b/MANIFEST
index f4b8b83..f6b2ea9 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -471,6 +471,7 @@
./src/H5Apublic.h
./src/H5AC.c
./src/H5ACdbg.c
+./src/H5AClog.c
./src/H5ACmodule.h
./src/H5ACmpio.c
./src/H5ACpkg.h
@@ -497,6 +498,7 @@
./src/H5C.c
./src/H5Cdbg.c
./src/H5Cepoch.c
+./src/H5Clog.c
./src/H5Cmodule.h
./src/H5Cmpio.c
./src/H5Cpkg.h
@@ -889,6 +891,7 @@
./test/cache_api.c
./test/cache_common.c
./test/cache_common.h
+./test/cache_logging.c
./test/cache_tagging.c
./test/cmpd_dset.c
./test/cork.c
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3f03c87..a4c6367 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -45,6 +45,7 @@ IDE_GENERATED_PROPERTIES ("H5A" "${H5A_HDRS}" "${H5A_SOURCES}" )
set (H5AC_SOURCES
${HDF5_SRC_DIR}/H5AC.c
${HDF5_SRC_DIR}/H5ACdbg.c
+ ${HDF5_SRC_DIR}/H5AClog.c
${HDF5_SRC_DIR}/H5ACmpio.c
)
@@ -86,6 +87,7 @@ set (H5C_SOURCES
${HDF5_SRC_DIR}/H5C.c
${HDF5_SRC_DIR}/H5Cdbg.c
${HDF5_SRC_DIR}/H5Cepoch.c
+ ${HDF5_SRC_DIR}/H5Clog.c
${HDF5_SRC_DIR}/H5Cmpio.c
${HDF5_SRC_DIR}/H5Cquery.c
${HDF5_SRC_DIR}/H5Ctag.c
diff --git a/src/H5AC.c b/src/H5AC.c
index c3c4dd3..f226c3d 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -70,8 +70,6 @@ static herr_t H5AC__ext_config_2_int_config(H5AC_cache_config_t *ext_conf_ptr,
#if H5AC_DO_TAGGING_SANITY_CHECKS
static herr_t H5AC__verify_tag(hid_t dxpl_id, const H5AC_class_t * type);
#endif /* H5AC_DO_TAGGING_SANITY_CHECKS */
-static herr_t H5AC__open_trace_file(H5AC_t *cache_ptr, const char *trace_file_name);
-static herr_t H5AC__close_trace_file(H5AC_t *cache_ptr);
/*********************/
@@ -485,6 +483,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(H5F_USE_MDC_LOGGING(f)) {
+ if(H5C_set_up_logging(f->shared->cache, H5F_MDC_LOG_LOCATION(f), H5F_START_MDC_LOG_ON_ACCESS(f)) < 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")
+ } /* end if */
+
/* 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")
@@ -549,6 +557,14 @@ H5AC_dest(H5F_t *f, hid_t dxpl_id)
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC__close_trace_file() failed.")
#endif /* H5AC__TRACE_FILE_ENABLED */
+ if(H5F_USE_MDC_LOGGING(f)) {
+ /* 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")
+ } /* end if */
+
#ifdef H5_HAVE_PARALLEL
/* destroying the cache, so clear all collective entries */
if(H5C_clear_coll_entries(f->shared->cache, 0) < 0)
@@ -609,6 +625,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)
@@ -621,6 +639,10 @@ H5AC_expunge_entry(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type,
HDassert(type->serialize);
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;
@@ -643,6 +665,11 @@ done:
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_LOGFAIL, FAIL, "unable to emit log message")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_expunge_entry() */
@@ -674,6 +701,8 @@ H5AC_flush(H5F_t *f, hid_t dxpl_id)
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)
@@ -683,6 +712,10 @@ 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.
@@ -712,6 +745,11 @@ done:
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_LOGFAIL, FAIL, "unable to emit log message")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_flush() */
@@ -805,6 +843,8 @@ H5AC_insert_entry(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t add
size_t trace_entry_size = 0;
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)
@@ -818,6 +858,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")
@@ -872,6 +916,10 @@ 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_LOGFAIL, FAIL, "unable to emit log message")
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_insert_entry() */
@@ -897,6 +945,10 @@ H5AC_mark_entry_dirty(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)
@@ -904,6 +956,10 @@ H5AC_mark_entry_dirty(void *thing)
/* Sanity check */
HDassert(thing);
+ /* Set up entry & cache pointers */
+ entry_ptr = (H5AC_info_t *)thing;
+ cache_ptr = entry_ptr->cache_ptr;
+
#if H5AC__TRACE_FILE_ENABLED
/* For the mark pinned or protected entry dirty call, only the addr
* is really necessary in the trace file. Write the result to catch
@@ -914,10 +970,12 @@ H5AC_mark_entry_dirty(void *thing)
(unsigned long)(((H5C_cache_entry_t *)thing)->addr));
#endif /* H5AC__TRACE_FILE_ENABLED */
+ /* 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
{
- H5AC_info_t *entry_ptr = (H5AC_info_t *)thing;
- H5C_t *cache_ptr = entry_ptr->cache_ptr;
H5AC_aux_t *aux_ptr;
aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(cache_ptr);
@@ -937,6 +995,11 @@ done:
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_LOGFAIL, FAIL, "unable to emit log message")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_mark_entry_dirty() */
@@ -970,6 +1033,8 @@ H5_ATTR_UNUSED
#ifdef H5_HAVE_PARALLEL
H5AC_aux_t *aux_ptr;
#endif /* H5_HAVE_PARALLEL */
+ 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)
@@ -982,6 +1047,10 @@ H5_ATTR_UNUSED
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
@@ -1015,6 +1084,11 @@ done:
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_LOGFAIL, FAIL, "unable to emit log message")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_move_entry() */
@@ -1039,6 +1113,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)
@@ -1055,6 +1133,14 @@ 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);
+
+ /* 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")
@@ -1065,6 +1151,11 @@ done:
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_LOGFAIL, FAIL, "unable to emit log message")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_pin_protected_entry() */
@@ -1089,6 +1180,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)
@@ -1104,6 +1199,14 @@ 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);
+
+ /* 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.")
@@ -1114,6 +1217,11 @@ done:
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_LOGFAIL, FAIL, "unable to emit log message")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_create_flush_dependency() */
@@ -1152,6 +1260,8 @@ H5AC_protect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr,
FILE * trace_file_ptr = NULL;
#endif /* H5AC__TRACE_FILE_ENABLED */
void * thing = NULL; /* 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 = NULL; /* Return value */
FUNC_ENTER_NOAPI(NULL)
@@ -1164,6 +1274,10 @@ H5AC_protect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr,
HDassert(type->serialize);
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 unexpected flags -- H5C__FLUSH_COLLECTIVELY_FLAG
* only permitted in the parallel case.
*/
@@ -1213,6 +1327,14 @@ done:
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, flags, fake_ret_value) < 0)
+ HDONE_ERROR(H5E_CACHE, H5E_LOGFAIL, NULL, "unable to emit log message")
+ } /* end if */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_protect() */
@@ -1236,6 +1358,10 @@ H5AC_resize_entry(void *thing, size_t new_size)
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)
@@ -1254,14 +1380,20 @@ H5AC_resize_entry(void *thing, size_t new_size)
(int)new_size);
#endif /* H5AC__TRACE_FILE_ENABLED */
+ entry_ptr = (H5AC_info_t *)thing;
+ cache_ptr = entry_ptr->cache_ptr;
+ 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")
+
/* 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
{
- H5AC_info_t * entry_ptr = (H5AC_info_t *)thing;
- H5C_t *cache_ptr = entry_ptr->cache_ptr;
H5AC_aux_t *aux_ptr;
aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(cache_ptr);
@@ -1277,6 +1409,11 @@ done:
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_LOGFAIL, FAIL, "unable to emit log message")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_resize_entry() */
@@ -1301,6 +1438,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)
@@ -1317,6 +1458,14 @@ 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);
+
+ /* 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")
@@ -1327,6 +1476,11 @@ done:
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_LOGFAIL, FAIL, "unable to emit log message")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_unpin_entry() */
@@ -1350,6 +1504,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)
@@ -1365,6 +1523,14 @@ 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);
+
+ /* 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")
+
/* Destroy 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.")
@@ -1375,6 +1541,11 @@ done:
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_LOGFAIL, FAIL, "unable to emit log message")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_destroy_flush_dependency() */
@@ -1430,6 +1601,8 @@ H5AC_unprotect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr,
#ifdef H5_HAVE_PARALLEL
H5AC_aux_t * aux_ptr = NULL;
#endif /* H5_HAVE_PARALLEL */
+ 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)
@@ -1446,6 +1619,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
@@ -1502,6 +1679,11 @@ 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_LOGFAIL, FAIL, "unable to emit log message")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_unprotect() */
@@ -1703,6 +1885,8 @@ H5AC_set_cache_auto_resize_config(H5AC_t *cache_ptr, H5AC_cache_config_t *config
H5AC_cache_config_t trace_config = H5AC__DEFAULT_CACHE_CONFIG;
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 */
H5C_auto_size_ctl_t internal_config;
herr_t ret_value = SUCCEED; /* Return value */
@@ -1711,6 +1895,10 @@ H5AC_set_cache_auto_resize_config(H5AC_t *cache_ptr, H5AC_cache_config_t *config
/* 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.
@@ -1819,6 +2007,11 @@ 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_LOGFAIL, FAIL, "unable to emit log message")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5AC_set_cache_auto_resize_config() */
diff --git a/src/H5AClog.c b/src/H5AClog.c
new file mode 100644
index 0000000..1cdaa00
--- /dev/null
+++ b/src/H5AClog.c
@@ -0,0 +1,1012 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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.c
+ *
+ * Purpose: Functions for metadata cache logging in JSON format
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+#include "H5ACmodule.h" /* This source code file is part of the H5AC module */
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5ACpkg.h" /* Metadata cache */
+#include "H5Cprivate.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
+ *
+ * Programmer: Dana Robinson
+ * Sunday, March 16, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5AC__write_create_cache_log_msg(H5AC_t *cache)
+{
+ char msg[MSG_SIZE];
+ 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)
+
+ /* Sanity checks */
+ HDassert(cache);
+
+ /* Check if log messages are being emitted */
+ if(H5C_get_logging_status(cache, &log_enabled, &curr_logging) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to get logging status")
+
+ /* 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(!log_enabled)
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "attempt to write opening log message when logging is disabled")
+
+ /* Create the log message string */
+ HDsnprintf(msg, MSG_SIZE,
+"\
+{\n\
+\"create_time\":%lld,\n\
+\"messages\":\n\
+[\n\
+"
+ , (long long)HDtime(NULL));
+
+ /* Have to temporarily enable logging, if it isn't currently */
+ if(!curr_logging)
+ if(H5C_start_logging(cache) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_LOGFAIL, FAIL, "unable to start mdc logging")
+
+ /* 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")
+
+ /* Stop logging, if it wasn't started originally */
+ if(!curr_logging)
+ if(H5C_stop_logging(cache) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_LOGFAIL, FAIL, "unable to stop mdc logging")
+
+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
+ *
+ * Programmer: Dana Robinson
+ * Sunday, March 16, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5AC__write_destroy_cache_log_msg(H5AC_t *cache)
+{
+ char msg[MSG_SIZE];
+ 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)
+
+ /* Sanity checks */
+ HDassert(cache);
+
+ /* Check if log messages are being emitted */
+ if(H5C_get_logging_status(cache, &log_enabled, &curr_logging) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to get logging status")
+
+ /* 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(!log_enabled)
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "attempt to write closing log message when logging is disabled")
+
+ /* Create the log message string */
+ HDsnprintf(msg, MSG_SIZE,
+"\
+],\n\
+\"close_time\":%lld,\n\
+}\n\
+"
+ , (long long)HDtime(NULL));
+
+ /* Have to temporarily enable logging, if it isn't currently */
+ if(!curr_logging)
+ if(H5C_start_logging(cache) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_LOGFAIL, FAIL, "unable to start mdc logging")
+
+ /* 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")
+
+ /* Stop logging, if it wasn't started originally */
+ if(!curr_logging)
+ if(H5C_stop_logging(cache) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_LOGFAIL, FAIL, "unable to stop mdc logging")
+
+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
+ *
+ * Programmer: Dana Robinson
+ * Sunday, March 16, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+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);
+
+ /* Create the log message string */
+ HDsnprintf(msg, MSG_SIZE,
+"\
+{\
+\"timestamp\":%lld,\
+\"action\":\"evict\",\
+\"returned\":%d\
+},\n\
+"
+ , (long long)HDtime(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
+ *
+ * Programmer: Dana Robinson
+ * Sunday, March 16, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+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);
+
+ /* Create the log message string */
+ HDsnprintf(msg, MSG_SIZE,
+"\
+{\
+\"timestamp\":%lld,\
+\"action\":\"expunge\",\
+\"address\":0x%lx,\
+\"type_id\":%d,\
+\"returned\":%d\
+},\n\
+"
+ , (long long)HDtime(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
+ *
+ * Programmer: Dana Robinson
+ * Sunday, March 16, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+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);
+
+ /* Create the log message string */
+ HDsnprintf(msg, MSG_SIZE,
+"\
+{\
+\"timestamp\":%lld,\
+\"action\":\"flush\",\
+\"returned\":%d\
+},\n\
+"
+ , (long long)HDtime(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
+ *
+ * Programmer: Dana Robinson
+ * Sunday, March 16, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+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);
+
+
+ /* Create the log message string */
+ HDsnprintf(msg, MSG_SIZE,
+"\
+{\
+\"timestamp\":%lld,\
+\"action\":\"insert\",\
+\"address\":0x%lx,\
+\"flags\":0x%x,\
+\"type_id\":%d,\
+\"size\":%d,\
+\"returned\":%d\
+},\n\
+"
+ , (long long)HDtime(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
+ *
+ * Programmer: Dana Robinson
+ * Sunday, March 16, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+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(entry);
+
+ /* Create the log message string */
+ HDsnprintf(msg, MSG_SIZE,
+"\
+{\
+\"timestamp\":%lld,\
+\"action\":\"dirty\",\
+\"address\":0x%lx,\
+\"returned\":%d\
+},\n\
+"
+ , (long long)HDtime(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_mark_clean_entry_log_msg
+ *
+ * Purpose: Write a log message for marking cache entries as clean.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, July 23, 2016
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5AC__write_mark_clean_entry_log_msg(const H5AC_t *cache, const H5AC_info_t *entry,
+ herr_t fxn_ret_value)
+{
+ char msg[MSG_SIZE]; /* Log message buffer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity checks */
+ HDassert(cache);
+ HDassert(entry);
+
+ /* Create the log message string */
+ HDsnprintf(msg, MSG_SIZE,
+"\
+{\
+\"timestamp\":%lld,\
+\"action\":\"clean\",\
+\"address\":0x%lx,\
+\"returned\":%d\
+},\n\
+"
+ , (long long)HDtime(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_clean_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
+ *
+ * Programmer: Dana Robinson
+ * Sunday, March 16, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+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);
+
+ /* Create the log message string */
+ HDsnprintf(msg, MSG_SIZE,
+"\
+{\
+\"timestamp\":%lld,\
+\"action\":\"move\",\
+\"old_address\":0x%lx,\
+\"new_address\":0x%lx,\
+\"type_id\":%d,\
+\"returned\":%d\
+},\n\
+"
+ , (long long)HDtime(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
+ *
+ * Programmer: Dana Robinson
+ * Sunday, March 16, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+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(entry);
+
+ /* Create the log message string */
+ HDsnprintf(msg, MSG_SIZE,
+"\
+{\
+\"timestamp\":%lld,\
+\"action\":\"pin\",\
+\"address\":0x%lx,\
+\"returned\":%d\
+},\n\
+"
+ , (long long)HDtime(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
+ *
+ * Programmer: Dana Robinson
+ * Sunday, March 16, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+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(parent);
+ HDassert(child);
+
+ /* Create the log message string */
+ HDsnprintf(msg, MSG_SIZE,
+"\
+{\
+\"timestamp\":%lld,\
+\"action\":\"create_fd\",\
+\"parent_addr\":0x%lx,\
+\"child_addr\":0x%lx,\
+\"returned\":%d\
+},\n\
+"
+ , (long long)HDtime(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
+ *
+ * Programmer: Dana Robinson
+ * Sunday, March 16, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5AC__write_protect_entry_log_msg(const H5AC_t *cache,
+ const H5AC_info_t *entry,
+ unsigned flags,
+ 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(entry);
+
+ if(H5AC__READ_ONLY_FLAG == flags)
+ HDstrcpy(rw_s, "READ");
+ else
+ HDstrcpy(rw_s, "WRITE");
+
+ /* Create the log message string */
+ HDsnprintf(msg, MSG_SIZE,
+"\
+{\
+\"timestamp\":%lld,\
+\"action\":\"protect\",\
+\"address\":0x%lx,\
+\"readwrite\":\"%s\",\
+\"size\":%d,\
+\"returned\":%d\
+},\n\
+"
+ , (long long)HDtime(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
+ *
+ * Programmer: Dana Robinson
+ * Sunday, March 16, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+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(entry);
+
+ /* Create the log message string */
+ HDsnprintf(msg, MSG_SIZE,
+"\
+{\
+\"timestamp\":%lld,\
+\"action\":\"resize\",\
+\"address\":0x%lx,\
+\"new_size\":%d,\
+\"returned\":%d\
+},\n\
+"
+ , (long long)HDtime(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
+ *
+ * Programmer: Dana Robinson
+ * Sunday, March 16, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+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(entry);
+
+ /* Create the log message string */
+ HDsnprintf(msg, MSG_SIZE,
+"\
+{\
+\"timestamp\":%lld,\
+\"action\":\"unpin\",\
+\"address\":0x%lx,\
+\"returned\":%d\
+},\n\
+"
+ , (long long)HDtime(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
+ *
+ * Programmer: Dana Robinson
+ * Sunday, March 16, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+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(parent);
+ HDassert(child);
+
+ /* Create the log message string */
+ HDsnprintf(msg, MSG_SIZE,
+"\
+{\
+\"timestamp\":%lld,\
+\"action\":\"destroy_fd\",\
+\"parent_addr\":0x%lx,\
+\"child_addr\":0x%lx,\
+\"returned\":%d\
+},\n\
+"
+ , (long long)HDtime(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
+ *
+ * Programmer: Dana Robinson
+ * Sunday, March 16, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+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(entry);
+
+ /* Create the log message string */
+ HDsnprintf(msg, MSG_SIZE,
+"\
+{\
+\"timestamp\":%lld,\
+\"action\":\"unprotect\",\
+\"address\":0x%lx,\
+\"id\":%d,\
+\"flags\":%x,\
+\"returned\":%d\
+},\n\
+"
+ , (long long)HDtime(NULL), (unsigned long)entry->addr,
+ type_id, flags, (int)fxn_ret_value);
+
+ HDsnprintf(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
+ *
+ * Programmer: Dana Robinson
+ * Sunday, March 16, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+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(config);
+
+ /* Create the log message string */
+ HDsnprintf(msg, MSG_SIZE,
+"\
+{\
+\"timestamp\":%lld,\
+\"action\":\"set_config\",\
+\"returned\":%d\
+},\n\
+"
+ , (long long)HDtime(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() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5AC__write_remove_entry_log_msg
+ *
+ * Purpose: Write a log message for removing a cache entry.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * September 17, 2016
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5AC__write_remove_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(entry);
+
+ /* Create the log message string */
+ HDsnprintf(msg, MSG_SIZE,
+"\
+{\
+\"timestamp\":%lld,\
+\"action\":\"remove\",\
+\"address\":0x%lx,\
+\"returned\":%d\
+},\n\
+"
+ , (long long)HDtime(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_remove_entry_log_msg() */
+
diff --git a/src/H5ACpkg.h b/src/H5ACpkg.h
index 6b964d6..a689ffd 100644
--- a/src/H5ACpkg.h
+++ b/src/H5ACpkg.h
@@ -426,5 +426,63 @@ H5_DLL herr_t H5AC__set_write_done_callback(H5C_t * cache_ptr,
void (* write_done)(void));
#endif /* H5_HAVE_PARALLEL */
+/* Trace file routines */
+H5_DLL herr_t H5AC__close_trace_file(H5AC_t *cache_ptr);
+H5_DLL herr_t H5AC__open_trace_file(H5AC_t *cache_ptr, const char *trace_file_name);
+
+/* 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_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,
+ unsigned flags,
+ 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/H5ACprivate.h b/src/H5ACprivate.h
index 84c9e93..c5bf8f3 100644
--- a/src/H5ACprivate.h
+++ b/src/H5ACprivate.h
@@ -378,7 +378,8 @@ H5_DLL herr_t H5AC_expunge_tag_type_metadata(H5F_t *f, hid_t dxpl_id, haddr_t ta
H5_DLL herr_t H5AC_add_candidate(H5AC_t * cache_ptr, haddr_t addr);
#endif /* H5_HAVE_PARALLEL */
-#ifndef NDEBUG /* debugging functions */
+/* Debugging functions */
+#ifndef NDEBUG
H5_DLL herr_t H5AC_stats(const H5F_t *f);
H5_DLL herr_t H5AC_dump_cache(const H5F_t *f);
#endif /* NDEBUG */ /* end debugging functions */
diff --git a/src/H5ACpublic.h b/src/H5ACpublic.h
index 4e5502d..dd16764 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.
diff --git a/src/H5C.c b/src/H5C.c
index 58b5ea3..d122910 100644
--- a/src/H5C.c
+++ b/src/H5C.c
@@ -299,6 +299,12 @@ H5C_create(size_t max_cache_size,
cache_ptr->flush_in_progress = FALSE;
+ cache_ptr->logging_enabled = FALSE;
+
+ cache_ptr->currently_logging = FALSE;
+
+ cache_ptr->log_file_ptr = NULL;
+
cache_ptr->trace_file_ptr = NULL;
cache_ptr->aux_ptr = aux_ptr;
diff --git a/src/H5Clog.c b/src/H5Clog.c
new file mode 100644
index 0000000..e3e4388
--- /dev/null
+++ b/src/H5Clog.c
@@ -0,0 +1,370 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Clog.c
+ * May 30 2016
+ * Quincey Koziol
+ *
+ * Purpose: Functions for generic cache logging in JSON format
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+#include "H5Cmodule.h" /* This source code file is part of the H5C module */
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#ifdef H5_HAVE_PARALLEL
+#define H5AC_FRIEND /*suppress error about including H5ACpkg */
+#include "H5ACpkg.h" /* Metadata cache */
+#endif /* H5_HAVE_PARALLEL */
+#include "H5Cpkg.h" /* Metadata cache */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5MMprivate.h" /* Memory management */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * 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
+ *
+ * Programmer: Dana Robinson
+ * Sunday, March 16, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+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 = NULL;
+ size_t n_chars;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* 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 *)H5MM_calloc(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);
+ } /* end else */
+#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:
+ if(file_name)
+ file_name = (char *)H5MM_xfree(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
+ *
+ * Programmer: Dana Robinson
+ * Sunday, March 16, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5C_tear_down_logging(H5C_t *cache_ptr)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* 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
+ *
+ * Programmer: Dana Robinson
+ * Sunday, March 16, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5C_start_logging(H5C_t *cache_ptr)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* 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
+ *
+ * Programmer: Dana Robinson
+ * Sunday, March 16, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5C_stop_logging(H5C_t *cache_ptr)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* 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
+ *
+ * Programmer: Dana Robinson
+ * Sunday, March 16, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+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)
+
+ /* 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(NULL == is_enabled)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cache magic value incorrect")
+ if(NULL == is_currently_logging)
+ 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
+ *
+ * Programmer: Dana Robinson
+ * Sunday, March 16, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+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)
+
+ /* 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() */
+
diff --git a/src/H5Cpkg.h b/src/H5Cpkg.h
index cf2da3e..92f4cdd 100644
--- a/src/H5Cpkg.h
+++ b/src/H5Cpkg.h
@@ -3201,6 +3201,29 @@ if ( ( (entry_ptr) == NULL ) || \
* 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.
@@ -4059,6 +4082,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 4137edf..9b0dbd4 100644
--- a/src/H5Cprivate.h
+++ b/src/H5Cprivate.h
@@ -1961,6 +1961,13 @@ 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,
diff --git a/src/H5F.c b/src/H5F.c
index 9f78440..c70f813 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -1444,6 +1444,105 @@ done:
/*-------------------------------------------------------------------------
+ * 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_FILE, 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_FILE, 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_FILE, H5E_LOGFAIL, FAIL, "unable to get logging status")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Fstop_mdc_logging() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Fformat_convert_super (Internal)
*
* Purpose: Downgrade the superblock version to v2 and
diff --git a/src/H5Fint.c b/src/H5Fint.c
index 201dd65..fb05efc 100644
--- a/src/H5Fint.c
+++ b/src/H5Fint.c
@@ -642,6 +642,10 @@ H5F_new(H5F_file_t *shared, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5FD_t
/* For latest format, activate all latest version support */
if(latest_format)
f->shared->latest_flags |= H5F_LATEST_ALL_FLAGS;
+ 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")
if(H5P_get(plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(f->shared->meta_aggr.alloc_size)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get metadata cache size")
f->shared->meta_aggr.feature_flag = H5FD_FEAT_AGGREGATE_METADATA;
@@ -827,6 +831,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)
+ f->shared->mdc_log_location = (char *)H5MM_xfree(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 8ec2a93..4d324d1 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -259,6 +259,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 */
hbool_t evict_on_close; /* If the file's objects should be evicted from the metadata cache on close */
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 40e5ff2..19a8117 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -319,6 +319,9 @@
#ifdef H5_HAVE_PARALLEL
#define H5F_COLL_MD_READ(F) ((F)->coll_md_read)
#endif /* H5_HAVE_PARALLEL */
+#define H5F_USE_MDC_LOGGING(F) ((F)->shared->use_mdc_logging)
+#define H5F_START_MDC_LOG_ON_ACCESS(F) ((F)->shared->start_mdc_log_on_access)
+#define H5F_MDC_LOG_LOCATION(F) ((F)->shared->mdc_log_location)
#else /* H5F_MODULE */
#define H5F_INTENT(F) (H5F_get_intent(F))
#define H5F_OPEN_NAME(F) (H5F_get_open_name(F))
@@ -365,6 +368,9 @@
#ifdef H5_HAVE_PARALLEL
#define H5F_COLL_MD_READ(F) (H5F_coll_md_read(F))
#endif /* H5_HAVE_PARALLEL */
+#define H5F_USE_MDC_LOGGING(F) (H5F_use_mdc_logging(F))
+#define H5F_START_MDC_LOG_ON_ACCESS(F) (H5F_start_mdc_log_on_access(F))
+#define H5F_MDC_LOG_LOCATION(F) (H5F_mdc_log_location(F))
#endif /* H5F_MODULE */
@@ -464,6 +470,9 @@
#define H5F_ACS_OBJECT_FLUSH_CB_NAME "object_flush_cb" /* Object flush callback */
#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_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_EVICT_ON_CLOSE_FLAG_NAME "evict_on_close_flag" /* Whether or not the metadata cache will evict objects on close */
#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 */
@@ -680,6 +689,9 @@ H5_DLL hbool_t H5F_is_tmp_addr(const H5F_t *f, haddr_t addr);
H5_DLL H5P_coll_md_read_flag_t H5F_coll_md_read(const H5F_t *f);
H5_DLL void H5F_set_coll_md_read(H5F_t *f, H5P_coll_md_read_flag_t flag);
#endif /* H5_HAVE_PARALLEL */
+H5_DLL hbool_t H5F_use_mdc_logging(const H5F_t *f);
+H5_DLL hbool_t H5F_start_mdc_log_on_access(const H5F_t *f);
+H5_DLL char *H5F_mdc_log_location(const H5F_t *f);
/* Functions that retrieve values from VFD layer */
H5_DLL hid_t H5F_get_driver_id(const H5F_t *f);
diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h
index fcccf07..6db5a69 100644
--- a/src/H5Fpublic.h
+++ b/src/H5Fpublic.h
@@ -219,6 +219,11 @@ H5_DLL herr_t H5Fget_info2(hid_t obj_id, H5F_info2_t *finfo);
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);
H5_DLL herr_t H5Fformat_convert(hid_t fid);
#ifdef H5_HAVE_PARALLEL
H5_DLL herr_t H5Fset_mpi_atomicity(hid_t file_id, hbool_t flag);
diff --git a/src/H5Fquery.c b/src/H5Fquery.c
index f59a9b7..487eb85 100644
--- a/src/H5Fquery.c
+++ b/src/H5Fquery.c
@@ -1127,3 +1127,87 @@ H5F_coll_md_read(const H5F_t *f)
} /* end H5F_coll_md_read() */
#endif /* H5_HAVE_PARALLEL */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_use_mdc_logging
+ *
+ * Purpose: Quick and dirty routine to determine if using MDC logging
+ * is enabled for this file.
+ * (Mainly added to stop non-file routines from poking about in the
+ * H5F_t data structure)
+ *
+ * Return: TRUE/FALSE on success/abort on failure (shouldn't fail)
+ *
+ * Programmer: Quincey Koziol <koziol@hdfgroup.org>
+ * June 5, 2016
+ *
+ *-------------------------------------------------------------------------
+ */
+hbool_t
+H5F_use_mdc_logging(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ FUNC_LEAVE_NOAPI(f->shared->use_mdc_logging)
+} /* end H5F_use_mdc_logging() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_start_mdc_log_on_access
+ *
+ * Purpose: Quick and dirty routine to determine if we should start MDC
+ * logging on access for this file.
+ * (Mainly added to stop non-file routines from poking about in the
+ * H5F_t data structure)
+ *
+ * Return: TRUE/FALSE on success/abort on failure (shouldn't fail)
+ *
+ * Programmer: Quincey Koziol <koziol@hdfgroup.org>
+ * June 5, 2016
+ *
+ *-------------------------------------------------------------------------
+ */
+hbool_t
+H5F_start_mdc_log_on_access(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ FUNC_LEAVE_NOAPI(f->shared->start_mdc_log_on_access)
+} /* end H5F_start_mdc_log_on_access() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_mdc_log_location
+ *
+ * Purpose: Quick and dirty routine to retrieve the MDC log location
+ * for this file.
+ * (Mainly added to stop non-file routines from poking about in the
+ * H5F_t data structure)
+ *
+ * Return: TRUE/FALSE on success/abort on failure (shouldn't fail)
+ *
+ * Programmer: Quincey Koziol <koziol@hdfgroup.org>
+ * June 5, 2016
+ *
+ *-------------------------------------------------------------------------
+ */
+char *
+H5F_mdc_log_location(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ FUNC_LEAVE_NOAPI(f->shared->mdc_log_location)
+} /* end H5F_mdc_log_location() */
+
diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c
index 8801061..9309ea9 100644
--- a/src/H5Pfapl.c
+++ b/src/H5Pfapl.c
@@ -181,6 +181,25 @@
/* Definition for object flush callback */
#define H5F_ACS_OBJECT_FLUSH_CB_SIZE sizeof(H5F_object_flush_t)
#define H5F_ACS_OBJECT_FLUSH_CB_DEF {NULL, NULL}
+/* 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
/* Definition for evict on close property */
#define H5F_ACS_EVICT_ON_CLOSE_FLAG_SIZE sizeof(hbool_t)
#define H5F_ACS_EVICT_ON_CLOSE_FLAG_DEF FALSE
@@ -244,6 +263,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 */
@@ -301,6 +328,9 @@ 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 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_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 */
static const hbool_t H5F_def_evict_on_close_flag_g = H5F_ACS_EVICT_ON_CLOSE_FLAG_DEF; /* Default setting for evict on close property */
#ifdef H5_HAVE_PARALLEL
static const H5P_coll_md_read_flag_t H5F_def_coll_md_read_flag_g = H5F_ACS_COLL_MD_READ_FLAG_DEF; /* Default setting for the collective metedata read flag */
@@ -468,6 +498,22 @@ 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")
+
/* Register the evict on close flag */
if(H5P_register_real(pclass, H5F_ACS_EVICT_ON_CLOSE_FLAG_NAME, H5F_ACS_EVICT_ON_CLOSE_FLAG_SIZE, &H5F_def_evict_on_close_flag_g,
NULL, NULL, NULL, H5F_ACS_EVICT_ON_CLOSE_FLAG_ENC, H5F_ACS_EVICT_ON_CLOSE_FLAG_DEC,
@@ -2934,16 +2980,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);
@@ -3619,6 +3655,320 @@ done:
/*-------------------------------------------------------------------------
+ * 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
+ *
+ *-------------------------------------------------------------------------
+ */
+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
+ *
+ *-------------------------------------------------------------------------
+ */
+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
+ *
+ *-------------------------------------------------------------------------
+ */
+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() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Pset_evict_on_close
*
* Purpose: Sets the evict_on_close property value.
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index b807a37..fc902a8 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -353,6 +353,8 @@ H5_DLL herr_t H5Pset_core_write_tracking(hid_t fapl_id, hbool_t is_enabled, 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_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_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);
H5_DLL herr_t H5Pset_evict_on_close(hid_t fapl_id, hbool_t evict_on_close);
H5_DLL herr_t H5Pget_evict_on_close(hid_t fapl_id, hbool_t *evict_on_close);
#ifdef H5_HAVE_PARALLEL
diff --git a/src/H5err.txt b/src/H5err.txt
index 8219408..a156316 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
MINOR, CACHE, H5E_CANTCORK, Unable to cork an object
MINOR, CACHE, H5E_CANTUNCORK, Unable to uncork an object
diff --git a/src/Makefile.am b/src/Makefile.am
index 8d9df87..ff845d1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -42,10 +42,10 @@ 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 H5ACdbg.c \
+ H5AC.c H5ACdbg.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 H5Cdbg.c H5Cepoch.c H5Cquery.c H5Ctag.c H5Ctest.c \
+ H5C.c H5Cdbg.c H5Cepoch.c H5Clog.c H5Cquery.c H5Ctag.c H5Ctest.c \
H5CS.c \
H5D.c H5Dbtree.c H5Dbtree2.c H5Dchunk.c H5Dcompact.c H5Dcontig.c H5Ddbg.c \
H5Ddeprec.c H5Dearray.c H5Defl.c H5Dfarray.c H5Dfill.c H5Dint.c \
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 6e6a0b9..22774cd 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -249,6 +249,7 @@ set (H5_TESTS
vds
file_image
unregister
+ cache_logging
cork
)
diff --git a/test/CMakeTests.cmake b/test/CMakeTests.cmake
index 1e7940a..f4b37f3 100644
--- a/test/CMakeTests.cmake
+++ b/test/CMakeTests.cmake
@@ -493,6 +493,8 @@ set (test_CLEANFILES
vds_src_0.h5
vds_src_1.h5
tbogus.h5.copy
+ cache_logging.h5
+ cache_logging.out
)
# Remove any output file left over from previous test run
@@ -558,6 +560,7 @@ set (H5TEST_TESTS
vds
file_image
unregister
+ cache_logging
cork
)
diff --git a/test/Makefile.am b/test/Makefile.am
index 7d062f4..b6be746 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -48,7 +48,7 @@ TEST_PROG= testhdf5 cache cache_api cache_tagging lheap ohdr stab gheap \
big mtime fillval mount flush1 flush2 app_ref enum \
set_extent ttsafe enc_dec_plist enc_dec_plist_cross_platform\
getname vfd ntypes dangle dtransform reserved cross_read \
- freespace mf vds file_image unregister cork
+ freespace mf vds file_image unregister cache_logging cork
# List programs to be built when testing here.
# error_test and err_compat are built at the same time as the other tests, but executed by testerror.sh.
@@ -160,7 +160,9 @@ CHECK_CLEANFILES+=accum.h5 cmpd_dset.h5 compact_dataset.h5 dataset.h5 dset_offse
new_multi_file_v16-r.h5 new_multi_file_v16-s.h5 \
split_get_file_image_test-m.h5 split_get_file_image_test-r.h5 \
file_image_core_test.h5.copy unregister_filter_1.h5 unregister_filter_2.h5 \
- vds_virt.h5 vds_dapl.h5 vds_src_[0-1].h5
+ vds_virt.h5 vds_dapl.h5 vds_src_[0-1].h5 \
+ cache_logging.h5 cache_logging.out
+
# Sources for testhdf5 executable
testhdf5_SOURCES=testhdf5.c tarray.c tattr.c tchecksum.c tconfig.c tfile.c \
tgenprop.c th5o.c th5s.c tcoords.c theap.c tid.c titerate.c tmeta.c tmisc.c \
diff --git a/test/cache_logging.c b/test/cache_logging.c
new file mode 100644
index 0000000..a5e399c
--- /dev/null
+++ b/test/cache_logging.c
@@ -0,0 +1,176 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/* Purpose: Tests the metadata cache logging framework */
+
+#include "h5test.h"
+
+#define LOG_LOCATION "cache_logging.out"
+#define FILE_NAME "cache_logging"
+
+#define N_GROUPS 100
+
+/*-------------------------------------------------------------------------
+ * Function: test_logging_api
+ *
+ * Purpose: Tests the API calls that affect mdc logging
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_logging_api(void)
+{
+ hid_t fapl = -1;
+ hbool_t is_enabled;
+ hbool_t is_enabled_out;
+ hbool_t start_on_access;
+ hbool_t start_on_access_out;
+ char *location = NULL;
+ size_t size;
+
+ hid_t fid;
+ hid_t gid;
+ hbool_t is_currently_logging;
+ char group_name[8];
+ char filename[1024];
+ int i;
+
+ TESTING("metadata cache log api calls");
+
+ fapl = h5_fileaccess();
+ h5_fixname(FILE_NAME, fapl, filename, sizeof filename);
+
+ /* Set up metadata cache logging */
+ is_enabled = TRUE;
+ start_on_access = FALSE;
+ if(H5Pset_mdc_log_options(fapl, is_enabled, LOG_LOCATION, start_on_access) < 0)
+ TEST_ERROR;
+
+ /* Check to make sure that the property list getter returns the correct
+ * location string buffer size;
+ */
+ is_enabled_out = FALSE;
+ start_on_access_out = TRUE;
+ location = NULL;
+ size = 999;
+ if(H5Pget_mdc_log_options(fapl, &is_enabled_out, location, &size,
+ &start_on_access_out) < 0)
+ TEST_ERROR;
+ if(size != strlen(LOG_LOCATION) + 1)
+ TEST_ERROR;
+
+ /* Check to make sure that the property list getter works */
+ if(NULL == (location = (char *)HDcalloc(size, sizeof(char))))
+ TEST_ERROR;
+ if(H5Pget_mdc_log_options(fapl, &is_enabled_out, location, &size,
+ &start_on_access_out) < 0)
+ TEST_ERROR;
+ if((is_enabled != is_enabled_out)
+ || (start_on_access != start_on_access_out)
+ || HDstrcmp(LOG_LOCATION, location))
+ TEST_ERROR;
+
+ /* Create a file */
+ if(H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
+ TEST_ERROR;
+ if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ TEST_ERROR;
+ if(H5Pclose(fapl) < 0)
+ TEST_ERROR;
+
+
+ /* Check to see if the logging flags were set correctly */
+ is_enabled = FALSE;
+ is_currently_logging = TRUE;
+ if((H5Fget_mdc_logging_status(fid, &is_enabled, &is_currently_logging) < 0)
+ || (is_enabled != TRUE)
+ || (is_currently_logging != FALSE))
+ TEST_ERROR;
+
+ /* Turn on logging and check flags */
+ if(H5Fstart_mdc_logging(fid) < 0)
+ TEST_ERROR;
+ is_enabled = FALSE;
+ is_currently_logging = FALSE;
+ if((H5Fget_mdc_logging_status(fid, &is_enabled, &is_currently_logging) < 0)
+ || (is_enabled != TRUE)
+ || (is_currently_logging != TRUE))
+ TEST_ERROR;
+
+ /* Perform some manipulations */
+ for(i = 0; i < N_GROUPS; i++) {
+ HDmemset(group_name, 0, 8);
+ HDsnprintf(group_name, 8, "%d", i);
+ if((gid = H5Gcreate2(fid, group_name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR;
+ if(H5Gclose(gid) < 0)
+ TEST_ERROR;
+ }
+
+ /* Turn off logging and check flags */
+ if(H5Fstop_mdc_logging(fid) < 0)
+ TEST_ERROR;
+ is_enabled = FALSE;
+ is_currently_logging = TRUE;
+ if((H5Fget_mdc_logging_status(fid, &is_enabled, &is_currently_logging) < 0)
+ || (is_enabled != TRUE)
+ || (is_currently_logging != FALSE))
+ TEST_ERROR;
+
+ /* Clean up */
+ if(H5Fclose(fid) < 0)
+ TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+error:
+ return 1;
+ } /* test_logging_api() */
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: Test basic cache logging operations
+ *
+ * Return: Success: zero
+ * Failure: non-zero
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main(void)
+{
+ int nerrors = 0;
+
+ /* Reset library */
+ h5_reset();
+
+ printf("Testing basic metadata cache logging functionality.\n");
+
+ nerrors += test_logging_api();
+
+ if(nerrors) {
+ printf("***** %d Metadata cache logging TEST%s FAILED! *****\n",
+ nerrors, nerrors > 1 ? "S" : "");
+ return 1;
+ }
+
+ printf("All Metadata Cache Logging tests passed.\n");
+ return 0;
+}
+