summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorvchoi-hdfgroup <55293060+vchoi-hdfgroup@users.noreply.github.com>2021-11-16 23:39:05 (GMT)
committerGitHub <noreply@github.com>2021-11-16 23:39:05 (GMT)
commitf3293556b7af7191496909f4577e983da19a9e68 (patch)
tree8f9a1bfab01ede517230e87ef65b91139fa603e7 /src
parentb92c7e58a97bc81a8983da3312dbfe72f6a75745 (diff)
parentd4bd58d1ecd97436806288bf57b6351dc025af38 (diff)
downloadhdf5-f3293556b7af7191496909f4577e983da19a9e68.zip
hdf5-f3293556b7af7191496909f4577e983da19a9e68.tar.gz
hdf5-f3293556b7af7191496909f4577e983da19a9e68.tar.bz2
Merge pull request #45 from vchoi-hdfgroup/feature/vfd_swmr
Feature/vfd swmr
Diffstat (limited to 'src')
-rw-r--r--src/H5Fint.c22
-rw-r--r--src/H5Fpkg.h69
-rw-r--r--src/H5Fvfd_swmr.c126
-rw-r--r--src/H5Pfapl.c4
4 files changed, 218 insertions, 3 deletions
diff --git a/src/H5Fint.c b/src/H5Fint.c
index e650878..c3fc346 100644
--- a/src/H5Fint.c
+++ b/src/H5Fint.c
@@ -2013,7 +2013,8 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
/* Short cuts */
shared = file->shared;
- lf = shared->lf;
+
+ lf = shared->lf;
/* Set the file locking flag. If the file is already open, the file
* requested file locking flag must match that of the open file.
@@ -2092,6 +2093,22 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
/* Checked if configured for VFD SWMR */
if (H5F_VFD_SWMR_CONFIG(file)) {
+
+ /* Set up the VFD SWMR LOG file */
+ /* Kent*/
+ if (HDstrlen(vfd_swmr_config_ptr->log_file_path) > 0)
+ shared->vfd_swmr_log_on = TRUE;
+ if (TRUE == shared->vfd_swmr_log_on) {
+ /* Create the log file */
+ if ((shared->vfd_swmr_log_file_ptr = HDfopen(vfd_swmr_config_ptr->log_file_path, "w")) == NULL)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create the log file")
+ if (H5_timer_init(&(shared->vfd_swmr_log_start_time)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't initialize HDF5 timer.")
+ if (H5_timer_start(&(shared->vfd_swmr_log_start_time)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't obtain the time from the HDF5 timer.")
+ }
+ /* End of Kent */
+
/* Initialization for VFD SWMR writer and reader */
if (1 == shared->nrefs) {
if (H5F_vfd_swmr_init(file, file_create) < 0)
@@ -2210,6 +2227,9 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
/* Success */
ret_value = file;
+#if 1 /*Kent: write to the log file when H5F_open ends. Tested, can be commented out if necessary.*/
+ H5F_POST_VFD_SWMR_LOG_ENTRY(file, FILE_OPEN, "File open ends");
+#endif
done:
if ((NULL == ret_value) && file) {
if (file->shared->root_grp && file->shared->nrefs == 1) {
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index c94c5af..706e41d 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -468,7 +468,17 @@ struct H5F_shared_t {
H5F_fs_state_t fs_state_md; /* State of the free space
* manager
*/
-
+ /* Log file for VFD SWMR */
+ FILE *vfd_swmr_log_file_ptr; /* File pointer for the
+ * log file.
+ */
+ hbool_t vfd_swmr_log_on; /* flag to indicate if
+ * the log file is
+ * created. */
+ H5_timer_t vfd_swmr_log_start_time; /* The starting time for
+ * calculating the time
+ * stamp of a log message.
+ */
/* Delayed free space release doubly linked list */
shadow_defree_queue_t shadow_defrees;
@@ -608,4 +618,61 @@ H5_DLL htri_t H5F__same_file_test(hid_t file_id1, hid_t file_id2);
H5_DLL herr_t H5F__reparse_file_lock_variable_test(void);
#endif /* H5F_TESTING */
+/* VFD SMWR LOG REPORTING MACROS */
+
+/* H5F_POST_VFD_SWMR_LOG_ENTRY is the macro that can help the developers debug VFD SWMR features.
+ * It calls an internal reporting function H5F_post_vfd_swmr_log_entry() that receives
+ * a log entry_type_code, which generates a log tag, and the message log_info, which
+ * the developers want to save into a log file.
+ *
+ * The macro H5F_POST_VFD_SWMR_LOG_ENTRY_PRODUCTION(f, c, number_entry_production, m) is
+ * called by H5F_POST_VFD_SWMR_LOG_ENTRY when the HDF5 library is built with the
+ * production mode. Number_entry_production will control the number of entry tags that
+ * applications can receive. Currently this number is set to 1 and is subject to change
+ * when more tags are useful to be present to applications.
+ *
+ * The first argument of the macro is the HDF5 file pointer(H5F_t *).
+ * Its value needs to be checked to avoid a failure caused by "Low-Level File I/O "
+ * in the testhdf5 program, which involves the test of a non-existing HDF5 file.
+ */
+
+H5_DLL void H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log_info);
+
+#define H5F_POST_VFD_SWMR_LOG_ENTRY_INTERNAL(fp, entry_type_code, log_info) \
+ do { \
+ if (fp != NULL) { \
+ if (fp->shared != NULL) { \
+ if (fp->shared->vfd_swmr_log_on == TRUE) { \
+ H5F_post_vfd_swmr_log_entry(fp, entry_type_code, log_info); \
+ } \
+ } \
+ } \
+ } while (0)
+
+#define H5F_POST_VFD_SWMR_LOG_ENTRY_PRODUCTION(fp, entry_type_code, max_code, log_info) \
+ do { \
+ if (entry_type_code < max_code) { \
+ H5F_POST_VFD_SWMR_LOG_ENTRY_INTERNAL(fp, entry_type_code, log_info); \
+ } \
+ } while (0)
+
+/* Note: change H5F_POST_VFD_SWMR_LOG_ENTRY_PRODUCTION(f, c, 1, m) on the following lines to
+ * H5F_POST_VFD_SWMR_LOG_ENTRY_PRODUCTION(f, c, your_number_entry_production, m)
+ * as necessary.
+ */
+#ifndef NDEBUG
+#define H5F_POST_VFD_SWMR_LOG_ENTRY(f, c, m) H5F_POST_VFD_SWMR_LOG_ENTRY_INTERNAL(f, c, m)
+#else
+#define H5F_POST_VFD_SWMR_LOG_ENTRY(f, c, m) H5F_POST_VFD_SWMR_LOG_ENTRY_PRODUCTION(f, c, 1, m)
+#endif
+
+/* Macros for VFD SWMR log entry code
+ * Note: this should be consistent with const char *H5Fvfd_swmr_log_tags[] declared at
+ * H5Fvfd_swmr.c .
+ */
+#define EOT_PROCESSING_TIME 0
+#define FILE_OPEN 1
+#define FILE_CLOSE 2
+#define EOT_TRIGGER_TIME 3
+#define EOT_META_FILE_INDEX 4
#endif /* H5Fpkg_H */
diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c
index 69e03a0..8da238c 100644
--- a/src/H5Fvfd_swmr.c
+++ b/src/H5Fvfd_swmr.c
@@ -54,6 +54,44 @@
#define nanosecs_per_second 1000000000 /* nanoseconds per second */
#define nanosecs_per_tenth_sec 100000000 /* nanoseconds per 0.1 second */
+/* Declare an array of string to identify the VFD SMWR Log tags.
+ * Note this array is used to generate the entry tag by the log reporting macro
+ * H5F_POST_VFD_SWMR_LOG_ENTRY.
+ *
+ * The following is the first version. Developers can add/modify the tags as necessary.
+ *
+ * If the entry code is 0, H5Fvfd_swmr_log_tags[0] is used to report the entry tag.
+ * H5F_POST_VFD_SWMR_LOG_ENTRY(f, EOT_PROCESSING_TIME, log_msg) will put the log_msg attached to
+ * the entry tag "EOT_PROCESSING_TIME".
+ * The entry code number is listed in the comment for convenience.
+ * Currently for the production mode, only the "EOT_PROCESSING_TIME" is present.
+ */
+
+/* clang-format off */
+static const char *H5Fvfd_swmr_log_tags[] = {
+ "EOT_PROCESSING_TIME", /* 0 */
+ "FILE_OPEN", /* 1 */
+ "FILE_CLOSE", /* 2 */
+ "EOT_TRIGGER_TIME", /* 3 */
+ "EOT_META_FILE_INDEX" /* 4 */
+ };
+/* clang-format on */
+
+/* This string defines the format of the VFD SWMR log file.
+ * The current maximum length of entry tag string is set to 26.
+ * One can enlarge or reduce this number as necessary.
+ * For example, to enlarge the maximum length of entry tag string to 30,
+ * Just change 26 to 30 in the following line, like
+ * const char *log_fmt_str="%-30s: %.3lf s: %s\n";
+ */
+const char *log_fmt_str = "%-26s: %.3lf s: %s\n";
+
+/* The length of the EOT processing time log message, subject to change */
+const unsigned int eot_pt_log_mesg_length = 48;
+
+/* The length of error message in the log */
+const unsigned int log_err_mesg_length = 14;
+
/********************/
/* Local Prototypes */
/********************/
@@ -157,7 +195,6 @@ H5F_vfd_swmr_init(H5F_t *f, hbool_t file_create)
/* Create the metadata file */
if (((shared->vfd_swmr_md_fd = HDopen(shared->vfd_swmr_config.md_file_path, O_CREAT | O_RDWR,
H5_POSIX_CREATE_MODE_RW))) < 0)
-
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to create the metadata file")
md_size = (hsize_t)shared->vfd_swmr_config.md_pages_reserved * shared->fs_page_size;
@@ -319,7 +356,21 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing)
if (H5F__vfd_swmr_update_end_of_tick_and_tick_num(shared, TRUE) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to update end of tick");
}
+#if 1 /*Kent Save the end of close info. to the log file, subject to comment out. */
+ if (closing)
+ H5F_POST_VFD_SWMR_LOG_ENTRY(f, FILE_CLOSE, "VFD SWMR File close ends");
+#endif
done:
+
+ /* Kent: Stop the timer and close the VFD SWMR log file if it is turned on.
+ * Please REVIEW to ensure this is the right place to
+ * close the log file.
+ */
+ if (shared->vfd_swmr_log_on && closing) {
+ H5_timer_stop(&(shared->vfd_swmr_log_start_time));
+ HDfclose(shared->vfd_swmr_log_file_ptr);
+ }
+ /* Kent */
FUNC_LEAVE_NOAPI(ret_value)
}
@@ -755,12 +806,28 @@ H5F_vfd_swmr_writer_end_of_tick(H5F_t *f, hbool_t wait_for_reader)
herr_t ret_value = SUCCEED; /* Return value */
hbool_t incr_tick = FALSE;
+ /* Kent: define the local variables to calculate the EOT time
+ and write them to the log file. */
+ H5_timevals_t current_time;
+ double start_elapsed_time, end_elapsed_time;
+ unsigned int temp_time;
+ char * log_msg;
+
FUNC_ENTER_NOAPI(FAIL)
HDassert(shared);
HDassert(shared->page_buf);
HDassert(shared->vfd_swmr_writer);
+ /* Kent */
+ /* Obtain the starting time for the logging info: the processing time of this function. */
+ if (shared->vfd_swmr_log_on == true) {
+ if (H5_timer_get_times(shared->vfd_swmr_log_start_time, &current_time) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time from H5_timer_get_times")
+ start_elapsed_time = current_time.elapsed;
+ }
+ /* Kent */
+
if (!vfd_swmr_writer_may_increase_tick_to(shared->tick_num + 1, wait_for_reader))
goto update_eot;
@@ -883,6 +950,19 @@ update_eot:
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to insert entry into the EOT queue")
done:
+ /* Kent: Calcuate the processing time and write the time info to the log file */
+ if (shared->vfd_swmr_log_on == true) {
+ if (H5_timer_get_times(shared->vfd_swmr_log_start_time, &current_time) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time from H5_timer_get_times")
+ end_elapsed_time = current_time.elapsed;
+ if (NULL != (log_msg = HDmalloc(eot_pt_log_mesg_length * sizeof(char)))) {
+ temp_time = (unsigned int)((end_elapsed_time - start_elapsed_time) * 1000);
+ HDsprintf(log_msg, "Writer time is %u milliseconds", temp_time);
+ H5F_POST_VFD_SWMR_LOG_ENTRY(f, EOT_PROCESSING_TIME, log_msg);
+ HDfree(log_msg);
+ }
+ }
+ /* Kent */
FUNC_LEAVE_NOAPI(ret_value)
}
@@ -1886,3 +1966,47 @@ H5F_vfd_swmr_process_eot_queue(hbool_t entering_api)
done:
FUNC_LEAVE_NOAPI(ret_value)
}
+
+/*-------------------------------------------------------------------------
+ *
+ * Function: H5F_post_vfd_swmr_log_entry
+ *
+ * Purpose: Write the log information to the log file.
+ *
+ * Parameters:
+ * H5F_t *f IN: HDF5 file pointer
+ * int entry_type_code IN: The entry type code to identify the
+ * log entry tag.
+ * char *log_info IN: The information to be stored in the
+ * log file.
+ * Return: None
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void
+H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log_info)
+{
+ double temp_time;
+ H5_timevals_t current_time;
+ char * gettime_error;
+
+ /* Obtain the current time.
+ If failed, write an error message to the log file.
+ else obtain the elapsed time in seconds since the log file
+ was created and write the time to the log file. */
+ if (H5_timer_get_times(f->shared->vfd_swmr_log_start_time, &current_time) < 0) {
+ if (NULL != (gettime_error = HDmalloc(log_err_mesg_length * sizeof(char)))) {
+ HDsprintf(gettime_error, "gettime_error");
+ HDfprintf(f->shared->vfd_swmr_log_file_ptr, "%-26s: %s\n", H5Fvfd_swmr_log_tags[entry_type_code],
+ gettime_error);
+ HDfree(gettime_error);
+ }
+ }
+ else {
+ temp_time = current_time.elapsed;
+ HDfprintf(f->shared->vfd_swmr_log_file_ptr, log_fmt_str, H5Fvfd_swmr_log_tags[entry_type_code],
+ temp_time, log_info);
+ }
+ return;
+}
diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c
index d20503f..3b39f12 100644
--- a/src/H5Pfapl.c
+++ b/src/H5Pfapl.c
@@ -5710,6 +5710,10 @@ H5Pset_vfd_swmr_config(hid_t plist_id, H5F_vfd_swmr_config_t *config_ptr)
else if (name_len > H5F__MAX_VFD_SWMR_FILE_NAME_LEN)
HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "md_file_path is too long")
+ name_len = HDstrlen(config_ptr->log_file_path);
+ if (name_len > H5F__MAX_VFD_SWMR_FILE_NAME_LEN)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "log_file_path is too long")
+
/* Set the modified config */
if (H5P_set(plist, H5F_ACS_VFD_SWMR_CONFIG_NAME, config_ptr) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set metadata cache initial config")