From 89cde3e0009bf2e97319ba3f36c100c97b6208e1 Mon Sep 17 00:00:00 2001 From: myang6 Date: Fri, 15 Oct 2021 13:29:19 -0500 Subject: Test to just write a log file for H5Fopen. Add a testing routine vfd_swmr_log_writer.c. --- src/H5FDvfd_swmr_private.h | 9 + src/H5Fint.c | 28 + src/H5Pfapl.c | 4 + test/Makefile.am | 3 + test/vfd_swmr_common.c | 13 + test/vfd_swmr_common.h | 2 + test/vfd_swmr_log_writer.c | 2980 ++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 3039 insertions(+) create mode 100644 test/vfd_swmr_log_writer.c diff --git a/src/H5FDvfd_swmr_private.h b/src/H5FDvfd_swmr_private.h index 12fd2e2..280ea2f 100644 --- a/src/H5FDvfd_swmr_private.h +++ b/src/H5FDvfd_swmr_private.h @@ -57,6 +57,15 @@ typedef struct eot_queue_entry { TAILQ_ENTRY(eot_queue_entry) link; } eot_queue_entry_t; +#define TOTAL_TIME_PASSED(X, Y) \ + ((double)((Y.tv_sec - X.tv_sec) * 1000000000 + (Y.tv_nsec - X.tv_nsec))) / 1000000.0 + +#define TIME_PASSED_MIN(X) (unsigned int)(X/60000) +#define TIME_PASSED_SEC(X,Y) (unsigned int)((X-Y*60000)/1000) +#define TIME_PASSED_MSEC(X,Y,Z) (unsigned int)(X-Y*60000-Z*1000) +//H5_DLLVAR extern hbool_t vfd_swmr_log_on; +//H5_DLLVAR extern FILE *vfd_swmr_log_file_ptr; + H5_DLLVAR unsigned int vfd_swmr_api_entries_g; /* The head of the EOT queue */ diff --git a/src/H5Fint.c b/src/H5Fint.c index e650878..49c8561 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -108,6 +108,8 @@ htri_t use_locks_env_g = FAIL; /*******************/ /* Local Variables */ /*******************/ +hbool_t vfd_swmr_log_on; +FILE *vfd_swmr_log_file_ptr; /* Declare a free list to manage the H5F_t struct */ H5FL_DEFINE(H5F_t); @@ -1853,8 +1855,15 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) hbool_t ci_write = FALSE; /* Whether MDC CI write requested */ hbool_t file_create = FALSE; /* Creating a new file or not */ H5F_vfd_swmr_config_t *vfd_swmr_config_ptr = NULL; /* Points to VFD SMWR config info */ + //FILE * vfd_swmr_log_file_ptr = NULL; + //hbool_t vfd_swmr_log_on = FALSE; + struct timespec start_time, end_time; + double temp_time; + unsigned int elap_min,elap_sec,elap_msec; + H5F_t * ret_value = NULL; /* Actual return value */ + FUNC_ENTER_NOAPI(NULL) /* Get the file access property list, for future queries */ @@ -1869,8 +1878,17 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) if (H5P_get(a_plist, H5F_ACS_VFD_SWMR_CONFIG_NAME, vfd_swmr_config_ptr) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get VFD SWMR config info") + vfd_swmr_log_on = FALSE; /* When configured with VFD SWMR */ if (vfd_swmr_config_ptr->version) { + + if(HDstrlen(vfd_swmr_config_ptr->log_file_path) >0) + vfd_swmr_log_on = TRUE; + if( TRUE == vfd_swmr_log_on) { + clock_gettime(CLOCK_MONOTONIC,&start_time); + if((vfd_swmr_log_file_ptr=HDfopen(vfd_swmr_config_ptr->log_file_path,"w"))==NULL) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to create the metadata file") + } /* Verify that file access flags are consistent with VFD SWMR configuartion */ if ((flags & H5F_ACC_RDWR) && !vfd_swmr_config_ptr->writer) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "file access is writer but VFD SWMR config is reader") @@ -2221,6 +2239,16 @@ done: if (H5F__dest(file, FALSE) < 0) HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file") } + + if (TRUE == vfd_swmr_log_on) { + clock_gettime(CLOCK_MONOTONIC,&end_time); + temp_time = TOTAL_TIME_PASSED(start_time,end_time); + elap_min = TIME_PASSED_MIN(temp_time); + elap_sec = TIME_PASSED_SEC(temp_time,elap_min); + elap_msec = TIME_PASSED_MSEC(temp_time,elap_min,elap_sec); + HDfprintf(vfd_swmr_log_file_ptr,"FILE OPEN: %u m %u s %u ms, time - %lf seconds\n",elap_min,elap_sec,elap_msec,temp_time/1000); + HDfclose(vfd_swmr_log_file_ptr); + } if (vfd_swmr_config_ptr) H5MM_free(vfd_swmr_config_ptr); diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index d20503f..35bb09e 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") diff --git a/test/Makefile.am b/test/Makefile.am index 87b2925..a97e968 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -56,6 +56,7 @@ SCRIPT_DEPEND = error_test$(EXEEXT) err_compat$(EXEEXT) links_env$(EXEEXT) \ vfd_swmr_zoo_reader$(EXEEXT) vfd_swmr_zoo_writer$(EXEEXT) \ vfd_swmr_gperf_reader$(EXEEXT) vfd_swmr_gperf_writer$(EXEEXT) \ vfd_swmr_gfail_reader$(EXEEXT) vfd_swmr_gfail_writer$(EXEEXT) \ + vfd_swmr_log_reader$(EXEEXT) vfd_swmr_log_writer$(EXEEXT) \ vds_env$(EXEEXT) \ vds_swmr_gen$(EXEEXT) vds_swmr_reader$(EXEEXT) vds_swmr_writer$(EXEEXT) if HAVE_SHARED_CONDITIONAL @@ -115,6 +116,7 @@ check_PROGRAMS=$(TEST_PROG) error_test err_compat tcheck_version \ vfd_swmr_attrdset_reader vfd_swmr_attrdset_writer \ vfd_swmr_gperf_reader vfd_swmr_gperf_writer \ vfd_swmr_gfail_reader vfd_swmr_gfail_writer \ + vfd_swmr_log_reader vfd_swmr_log_writer \ vfd_swmr_check_compat \ vfd_swmr_dsetchks_reader vfd_swmr_dsetchks_writer \ swmr_check_compat_vfd vds_env vds_swmr_gen vds_swmr_reader vds_swmr_writer \ @@ -184,6 +186,7 @@ vfd_swmr_bigset_reader_SOURCES=vfd_swmr_bigset_writer.c vfd_swmr_group_reader_SOURCES=vfd_swmr_group_writer.c vfd_swmr_gperf_reader_SOURCES=vfd_swmr_gperf_writer.c vfd_swmr_gfail_reader_SOURCES=vfd_swmr_gfail_writer.c +vfd_swmr_log_reader_SOURCES=vfd_swmr_log_writer.c vfd_swmr_dsetops_reader_SOURCES=vfd_swmr_dsetops_writer.c vfd_swmr_attrdset_writer_SOURCES=vfd_swmr_attrdset_writer.c diff --git a/test/vfd_swmr_common.c b/test/vfd_swmr_common.c index f57f39a..f20f01e 100644 --- a/test/vfd_swmr_common.c +++ b/test/vfd_swmr_common.c @@ -369,6 +369,19 @@ init_vfd_swmr_config(H5F_vfd_swmr_config_t *config, uint32_t tick_len, uint32_t } /* init_vfd_swmr_config() */ +void +init_vfd_swmr_config_log(H5F_vfd_swmr_config_t *config, const char *log_file_fmtstr,...) + +{ + va_list ap; + + HDva_start(ap, log_file_fmtstr); + evsnprintf(config->log_file_path, sizeof(config->log_file_path), log_file_fmtstr, ap); + HDva_end(ap); + +} /* init_vfd_swmr_config() */ + + /* Perform common VFD SWMR configuration on the file-access property list: * configure page buffering, set reasonable VFD SWMR defaults. */ diff --git a/test/vfd_swmr_common.h b/test/vfd_swmr_common.h index b2fbbbd..8c51e0b 100644 --- a/test/vfd_swmr_common.h +++ b/test/vfd_swmr_common.h @@ -77,6 +77,8 @@ H5TEST_DLL void init_vfd_swmr_config(H5F_vfd_swmr_config_t *config, uint32_t tic hbool_t writer, hbool_t flush_raw_data, uint32_t md_pages_reserved, const char *md_file_fmtstr, ...) H5_ATTR_FORMAT(printf, 7, 8); +H5TEST_DLL void init_vfd_swmr_config_log(H5F_vfd_swmr_config_t *config, const char * log_file_fmtstr, ...) H5_ATTR_FORMAT(printf, 2, 3); + H5TEST_DLL hid_t vfd_swmr_create_fcpl(H5F_fspace_strategy_t fs_strategy, hsize_t fs_page_size); H5TEST_DLL void dbgf(int, const char *, ...) H5_ATTR_FORMAT(printf, 2, 3); diff --git a/test/vfd_swmr_log_writer.c b/test/vfd_swmr_log_writer.c new file mode 100644 index 0000000..1834d44 --- /dev/null +++ b/test/vfd_swmr_log_writer.c @@ -0,0 +1,2980 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * 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 COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* Description of this program: + * This program checks the performance of group creations for VFD SWMR. + * Currently the group creation time, H5Fopen and H5Fclose time are measured. + * After compiling the program, + * ./vfd_swmr_gperf_writer -n 1000 -P -N 5 -q + * will generate 1000 groups, each group has 5 attributes. + * ./vfd_swmr_gperf_writer -n 1000 -P -N 0 -q + * will generate 1000 empty groups. + * ./vfd_swmr_gperf_writer -n 1000 -P -l 1 -q + * will generate 1000 groups with 1 level of nested groups,(like /g1/g2) + * each group has one attribute. + * ./vfd_swmr_gperf_writer -n 1000 -P -S -G -V -N 5 -l 1 -m 8 -t 4 -B 16384 -s 8192 + * will generate 1000 groups with 1 level of nested groups,(like /g1/g2) + * each group has 5 attributes and the attribute type is variable length string. + * The groups is created without using VFD SWMR; + * The groups are created with the earliest file format(old-styled) + * The program is run with max_lag = 8, tick_len = 4; + * The page buffer size is 16384 bytes. The page size is 8192 bytes. + * + */ +#define H5F_FRIEND /*suppress error about including H5Fpkg */ + +#include "hdf5.h" + +#include "H5Fpkg.h" +#include "H5HGprivate.h" +#include "H5VLprivate.h" + +#include "testhdf5.h" +#include "vfd_swmr_common.h" + +#ifndef H5_HAVE_WIN32_API + +#define VS_ATTR_NAME_LEN 21 + +#define TIME_PASSED(X, Y) \ + ((double)((Y.tv_sec - X.tv_sec) * 1000000000 + (Y.tv_nsec - X.tv_nsec))) / 1000000000.0 + +typedef struct { + hid_t file, filetype, one_by_one_sid; + char filename[PATH_MAX]; + char progname[PATH_MAX]; + unsigned int asteps; + unsigned int nsteps; + bool use_vfd_swmr; + bool old_style_grp; + char grp_op_pattern; + bool grp_op_test; + char at_pattern; + bool attr_test; + uint32_t max_lag; + uint32_t tick_len; + bool gperf; + double min_gc_time; + double max_gc_time; + double mean_gc_time; + double total_gc_time; + double total_time; + double mean_time; + double fo_total_time; + double fc_total_time; + unsigned int num_attrs; + bool vlstr_test; + unsigned int ps; + unsigned int pbs; + unsigned int nglevels; +} state_t; + +#define ALL_HID_INITIALIZER \ + (state_t) \ + { \ + .file = H5I_INVALID_HID, .one_by_one_sid = H5I_INVALID_HID, .filename = "", \ + .filetype = H5T_NATIVE_UINT32, .asteps = 1, .nsteps = 100, .use_vfd_swmr = true, \ + .old_style_grp = false, .grp_op_pattern = ' ', .grp_op_test = false, .at_pattern = ' ', \ + .attr_test = false, .tick_len = 4, .max_lag = 7, .gperf = false, .min_gc_time = 100., \ + .max_gc_time = 0., .mean_gc_time = 0., .total_gc_time = 0., .total_time = 0., .mean_time = 0., \ + .fo_total_time = 0., .fc_total_time = 0., .num_attrs = 1, .vlstr_test = false, .ps = 4096, \ + .pbs = 4096, .nglevels = 0 \ + } + +static void +usage(const char *progname) +{ + fprintf(stderr, + "usage: ./%s -P -n 1000 -N 5 -q (create 1000 groups, each group has 5 attributes)\n" + "Options: \n" + " [-P] [-S] [-G] [-t tick_len] [-m max_lag][-B pbs] [-s ps]\n" + " [-n ngroups] [-l ng_levels] [-O grp_op_pattern]\n" + " [-N num_attrs] [-V] [-b] [-A at_pattern] [-a steps] [-q]\n" + "\n" + "-P: carry out the performance test\n" + "-S: do not use VFD SWMR\n" + "-G: old-style type of group\n" + "-t tick_len: length of a tick in tenths of a second.\n" + "-m max_lag: maximum expected lag(in ticks) between writer and readers\n" + "-B pbs: page Buffer Size in bytes:\n" + " The default value is 4K(4096).\n" + "-s ps: page size used by page aggregation, page buffer and \n" + " the metadata file. \n" + "-n ngroups: the number of groups\n" + "-l ng_levels: the number of level of nested groups. \n" + " If all the groups are under the root group, \n" + " this number should be 0.\n" + "-N num_attrs: the number of attributes \n" + "-V use variable length string attributes for performance test\n" + "-b: write data in big-endian byte order\n" + " (For the performance test, -V overwrites -b)\n" + "-A at_pattern: `at_pattern' for different attribute tests\n" + " The value of `at_pattern` is one of the following:\n" + " `compact` - Attributes added in compact storage\n" + " `dense` - An attribute added in dense storage\n" + " `compact-del` - Attributes added and then one\n" + " attribute deleted, in compact \n" + " `dense-del` - Attributes added until the storage\n" + " is dense then an attribute deleted\n" + " the storge still in dense\n" + " `compact-add-to-dense` - Attributes added first in compact\n" + " then in dense storage\n" + " `dense-del-to-compact` - Attributes added until the storage\n" + " is dense, then several attributes \n" + " deleted, the storage changed to\n" + " compact\n" + " `modify` - An attribute added then modified\n" + " `add-vstr` - A VL string attribute added\n" + " `remove-vstr` - A VL string attribute added then\n" + " deleted\n" + " `modify-vstr` - A VL string attribute added then \n" + " modified \n" + " `add-ohr-block` - An attribute is added and this forces\n" + " the creation of object header\n" + " continuation block \n" + " `del-ohr-block` - An attribute is added and this forces\n" + " the creation of object header\n" + " continuation block and then this \n" + " attribute is deleted so the \n" + " object header continuation block is \n" + " removed. \n" + "-O grp_op_pattern: `grp_op_pattern' for different group operation tests\n" + " The value of `grp_op_pattern` is one of the following:\n" + " `grp-creation` - A group is created.\n" + " `grp-deletion` - An existing group is deleted.\n" + " `grp-move` - A group is moved to become \n" + " another group. \n" + " `grp-ins-links` - Links are inserted, including\n" + " both hard and soft links. \n" + " `grp-del-links` - Links are deleted, including\n" + " both hard ans soft links. \n" + " `grp-compact-t-dense` - Links are inserted to the group.\n" + " The link storage of this group \n" + " changed from compact to dense. \n" + " The links include both hard and\n" + " soft links. \n" + " `grp-dense-t-compact` - Links are inserted to the group\n" + " The link storage of this group \n" + " changed from compact to dense. \n" + " Then several links are deleted.\n" + " The link storage changed from \n" + " dense to compact again. \n" + " The links include both hard and\n" + " soft links. \n" + "-a steps: `steps` between adding attributes\n" + " (Don't recommend to use this option for performance test.)\n" + "-q: silence printouts, few messages\n" + "\n", + progname); + exit(EXIT_FAILURE); +} + +static bool +state_init(state_t *s, int argc, char **argv) +{ + unsigned long tmp; + int ch; + const hsize_t dims = 1; + char * tfile = NULL; + char * end; + + *s = ALL_HID_INITIALIZER; + + if (H5_basename(argv[0], &tfile) < 0) { + printf("H5_basename failed\n"); + TEST_ERROR; + } + + esnprintf(s->progname, sizeof(s->progname), "%s", tfile); + + if (tfile) { + HDfree(tfile); + tfile = NULL; + } + + if (argc == 1) + usage(s->progname); + while ((ch = getopt(argc, argv, "PSGa:bVt:m:B:s:n:qA:N:l:O:")) != -1) { + switch (ch) { + case 'P': + s->gperf = true; + break; + case 'S': + s->use_vfd_swmr = false; + break; + case 'G': + s->old_style_grp = true; + break; + case 'a': + case 'n': + case 'N': + case 'l': + case 't': + case 'm': + case 'B': + case 's': + errno = 0; + tmp = HDstrtoul(optarg, &end, 0); + if (end == optarg || *end != '\0') { + printf("couldn't parse `-%c` argument `%s`\n", ch, optarg); + TEST_ERROR; + } + else if (errno != 0) { + printf("couldn't parse `-%c` argument `%s`\n", ch, optarg); + TEST_ERROR; + } + else if (tmp > UINT_MAX) { + printf("`-%c` argument `%lu` too large\n", ch, tmp); + TEST_ERROR; + } + + if (ch == 'a') + s->asteps = (unsigned)tmp; + else if (ch == 'n') + s->nsteps = (unsigned)tmp; + else if (ch == 'N') + s->num_attrs = (unsigned)tmp; + else if (ch == 'l') + s->nglevels = (unsigned)tmp; + else if (ch == 't') + s->tick_len = (unsigned)tmp; + else if (ch == 'm') + s->max_lag = (unsigned)tmp; + else if (ch == 's') + s->ps = (unsigned)tmp; + else if (ch == 'B') + s->pbs = (unsigned)tmp; + break; + case 'b': + s->filetype = H5T_STD_U32BE; + break; + case 'V': + s->vlstr_test = true; + break; + case 'O': + if (HDstrcmp(optarg, "grp-creation") == 0) + s->grp_op_pattern = 'c'; + else if (HDstrcmp(optarg, "grp-deletion") == 0) + s->grp_op_pattern = 'd'; + else if (HDstrcmp(optarg, "grp-move") == 0) + s->grp_op_pattern = 'm'; + else if (HDstrcmp(optarg, "grp-ins-links") == 0) + s->grp_op_pattern = 'i'; + else if (HDstrcmp(optarg, "grp-del-links") == 0) + s->grp_op_pattern = 'D'; + else if (HDstrcmp(optarg, "grp-compact-t-dense") == 0) + s->grp_op_pattern = 't'; + else if (HDstrcmp(optarg, "grp-dense-t-compact") == 0) + s->grp_op_pattern = 'T'; + else { + printf("Invalid -O argument \"%s\"", optarg); + TEST_ERROR; + } + break; + case 'A': + if (HDstrcmp(optarg, "compact") == 0) + s->at_pattern = 'c'; + else if (HDstrcmp(optarg, "dense") == 0) + s->at_pattern = 'd'; + else if (HDstrcmp(optarg, "compact-add-to-dense") == 0) + s->at_pattern = 't'; + else if (HDstrcmp(optarg, "compact-del") == 0) + s->at_pattern = 'C'; + else if (HDstrcmp(optarg, "dense-del") == 0) + s->at_pattern = 'D'; + else if (HDstrcmp(optarg, "dense-del-to-compact") == 0) + s->at_pattern = 'T'; + else if (HDstrcmp(optarg, "modify") == 0) + s->at_pattern = 'M'; + else if (HDstrcmp(optarg, "add-vstr") == 0) + s->at_pattern = 'v'; + else if (HDstrcmp(optarg, "remove-vstr") == 0) + s->at_pattern = 'r'; + else if (HDstrcmp(optarg, "modify-vstr") == 0) + s->at_pattern = 'm'; + else if (HDstrcmp(optarg, "add-ohr-block") == 0) + s->at_pattern = 'a'; + else if (HDstrcmp(optarg, "del-ohr-block") == 0) + s->at_pattern = 'R'; + else { + printf("Invalid -A argument \"%s\"", optarg); + TEST_ERROR; + } + break; + case 'q': + verbosity = 0; + break; + case '?': + default: + usage(s->progname); + break; + } + } + argc -= optind; + argv += optind; + + if (s->grp_op_pattern != ' ') + s->grp_op_test = true; + if (s->at_pattern != ' ') + s->attr_test = true; + + if (!s->grp_op_test) { + if (s->asteps < 1 || s->asteps > s->nsteps) { + printf("attribute interval is out of bounds\n"); + TEST_ERROR; + } + } + + if (s->grp_op_test && s->attr_test) { + printf("Cannot test both group operation and attribute tests!\n"); + printf("Attribute tests are ignored.\n"); + } + + if (argc > 0) { + printf("unexpected command-line arguments\n"); + TEST_ERROR; + } + + /* space for attributes */ + if ((s->one_by_one_sid = H5Screate_simple(1, &dims, &dims)) < 0) { + printf("H5Screate_simple failed\n"); + TEST_ERROR; + } + + esnprintf(s->filename, sizeof(s->filename), "vfd_swmr_group.h5"); + + return true; + +error: + if (tfile) + HDfree(tfile); + return false; +} + +/*------------------------------------------------------------------------- + * Function: check_ohr_num_chunk + * + * Purpose: Check if the number of object header chunks is as expected. + * + * Parameters: hid_t oid + * HDF5 object ID (in this file: means group ID) + * + * bool one_chunk_ohr + * flag to indicate if the object header chunk is 1 or greater + * 1: true + * greater than 1: false + * + * Return: Success: true + * Failure: false + * + *------------------------------------------------------------------------- + */ + +static bool +check_ohr_num_chunk(hid_t g, bool one_chunk_ohr) +{ + + H5O_native_info_t ninfo; + + /* Get the object information */ + if (H5Oget_native_info(g, &ninfo, H5O_NATIVE_INFO_HDR) < 0) { + printf("H5Oget_native_info failed\n"); + TEST_ERROR; + } + + if (true == one_chunk_ohr) { + if (ninfo.hdr.nchunks != 1) { + printf("Object header should have only one chunk,but it is not.\n"); + TEST_ERROR; + } + } + else { + if (ninfo.hdr.nchunks <= 1) { + printf("Object header should have more than one chunk,but it is not.\n"); + TEST_ERROR; + } + } + + return true; + +error: + return false; +} + +/*------------------------------------------------------------------------- + * Function: add_attr + * + * Purpose: Add attributes to a group. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * hid_t oid + * HDF5 object ID (in this file: means group ID) + * + * unsigned int which + * The number of iterations for group creation, use to generate + * newly created group name. The group name is "group-which". + * + * unsigned num_attrs + * The number of attributes to be created + * + * const char*aname_fmt + * The attribute name template used to create unique attribute names. + * + * unsigned int g_which + * This parameter is used to generate correct group name in a key + * debugging message. + * + * Return: Success: true + * Failure: false + * + *------------------------------------------------------------------------- + */ + +static bool +add_attr(state_t *s, hid_t oid, unsigned int which, unsigned num_attrs, const char *aname_fmt, + unsigned int g_which) +{ + + char attrname[VS_ATTR_NAME_LEN]; + unsigned u; + unsigned attr_value; + hid_t aid = H5I_INVALID_HID; + hid_t amtype = H5I_INVALID_HID; + hid_t atype = s->filetype; + hid_t sid = s->one_by_one_sid; + + /* Need to obtain native datatype for H5Aread */ + if ((amtype = H5Tget_native_type(atype, H5T_DIR_ASCEND)) < 0) { + printf("H5Tget_native_type failed\n"); + TEST_ERROR; + } + + for (u = 0; u < num_attrs; u++) { + + /* Create attribute */ + /* Construct attribute name like attr-0-0 */ + HDsprintf(attrname, aname_fmt, which, u); + if ((aid = H5Acreate2(oid, attrname, atype, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + printf("H5Acreate2 failed\n"); + TEST_ERROR; + } + + attr_value = u + which; + + dbgf(1, "setting attribute %s on group %u to %u\n", attrname, g_which, u + which); + + /* Write data into the attribute */ + if (H5Awrite(aid, amtype, &attr_value) < 0) { + printf("H5Awrite failed\n"); + TEST_ERROR; + } + + /* Close attribute */ + if (H5Aclose(aid) < 0) { + printf("H5Aclose failed\n"); + TEST_ERROR; + } + + /* If coming to an "object header continuation block" test, + * we need to check if this test behaves as expected. */ + if (s->at_pattern == 'a' || s->at_pattern == 'R') { + if (false == check_ohr_num_chunk(oid, false)) { + printf("An object header continuation block should be created. \n"); + printf("But it is not.\n"); + TEST_ERROR; + } + } + + } /* end for */ + + if (H5Tclose(amtype) < 0) { + TEST_ERROR; + } + + return true; + +error: + H5E_BEGIN_TRY + { + H5Aclose(aid); + H5Tclose(amtype); + } + H5E_END_TRY; + + return false; +} + +/*------------------------------------------------------------------------- + * Function: add_vlstr_attr + * + * Purpose: Add a variable length string attribute to a group. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * hid_t g + * HDF5 object ID (in this file: means group ID) + * + * unsigned int which + * The number of iterations for group creation, use to generate + * newly created group and attribute names. + * The group name is "group-which" and the attribute name + * is "attr-which". + * + * + * Return: Success: true + * Failure: false + * + * Note: This is for the "vstr" test. + *------------------------------------------------------------------------- + */ + +static bool +add_vlstr_attr(state_t *s, hid_t g, unsigned int which) +{ + + hid_t aid = H5I_INVALID_HID; + hid_t atype = H5I_INVALID_HID; + char name[VS_ATTR_NAME_LEN]; + char *astr_val = NULL; + hid_t sid = s->one_by_one_sid; + + /* Allocate buffer for the VL string value */ + astr_val = HDmalloc(VS_ATTR_NAME_LEN); + if (astr_val == NULL) { + printf("Allocate memory for VL string failed.\n"); + TEST_ERROR; + } + + /* Assign the VL string value and the attribute name.. */ + HDsprintf(astr_val, "%u", which); + esnprintf(name, sizeof(name), "attr-%u", which); + + dbgf(1, "setting attribute %s on group %u to %u\n", name, which, which); + + /* Create a datatype to refer to. */ + if ((atype = H5Tcopy(H5T_C_S1)) < 0) { + printf("Cannot create variable length datatype.\n"); + TEST_ERROR; + } + + if (H5Tset_size(atype, H5T_VARIABLE) < 0) { + printf("Cannot set variable length datatype.\n"); + TEST_ERROR; + } + + /* Generate the VL string attribute.*/ + if ((aid = H5Acreate2(g, name, atype, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + printf("H5Acreate2 failed.\n"); + TEST_ERROR; + } + + if (H5Awrite(aid, atype, &astr_val) < 0) { + printf("H5Awrite failed.\n"); + TEST_ERROR; + } + + if (H5Tclose(atype) < 0) { + printf("H5Tclose() failed\n"); + TEST_ERROR; + } + if (H5Aclose(aid) < 0) { + printf("H5Aclose() failed\n"); + TEST_ERROR; + } + + HDfree(astr_val); + + return true; + +error: + H5E_BEGIN_TRY + { + H5Aclose(aid); + H5Tclose(atype); + } + H5E_END_TRY; + + if (astr_val) + HDfree(astr_val); + + return false; +} + +/*------------------------------------------------------------------------- + * Function: add_vlstr_attrs + * + * Purpose: Add variable length string attributes to a group. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * hid_t g + * HDF5 object ID (in this file: means group ID) + * + * unsigned int which + * The number of iterations for group creation, use to generate + * newly created group and attribute names. + * The group name is "group-which". The attribute names + * are "attr-which","attr-which+1".... + * + * + * Return: Success: true + * Failure: false + * + * Note: This is for the performance test that has the VL string type. + *------------------------------------------------------------------------- + */ + +static bool +add_vlstr_attrs(state_t *s, hid_t g, unsigned int which, unsigned int num_attrs) +{ + unsigned u; + bool ret_value = true; + for (u = 0; u < num_attrs; u++) { + ret_value = add_vlstr_attr(s, g, u + which); + if (ret_value == false) + break; + } + + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: add_default_group_attr + * + * Purpose: Add an attribute to a group. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * hid_t g + * HDF5 object ID (in this file: means group ID) + * + * unsigned int which + * The number of iterations for group creation, use to generate + * newly created group and attribute names. + * The group name is "group-which" and the attribute name + * is "attr-which". + * + * + * Return: Success: true + * Failure: false + * + * Note: This function is used for the "dense" storage test. + * It is also used by the group-only, "add-ohr-block" + * and "del-ohr-block" tests. + *------------------------------------------------------------------------- + */ + +static bool +add_default_group_attr(state_t *s, hid_t g, unsigned int which) +{ + + const char *aname_format = "attr-%u-%u"; + + /* Note: the number of attributes can be configurable, + * the default number of attribute is 1. + */ + /* If the vl string attribute type is chosen. */ + if (s->vlstr_test == true) + return add_vlstr_attrs(s, g, which, s->num_attrs); + else + return add_attr(s, g, which, s->num_attrs, aname_format, which); +} + +/*------------------------------------------------------------------------- + * Function: del_one_attr + * + * Purpose: delete one attribute in a group. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * hid_t obj_id + * HDF5 object ID (in this file: means group ID) + * + * bool is_dense + * if the deleted attribute is for checking the dense storage + * + * bool is_vl_or_ohrc + * if the deleted attribute is a VL string or for object header + * continuation check test + * + * unsigned int which + * The number of iterations for group creation, use to generate + * newly created group and attribute names. + * The group name is "group-which" and the attribute names + * according to if this attribute is a VL string or for checking + * the dense storage or the storage transition from dense to + * compact. + * + * + * Return: Success: true + * Failure: false + * + *------------------------------------------------------------------------- + */ + +static bool +del_one_attr(state_t *s, hid_t obj_id, bool is_dense, bool is_vl_or_ohrc, unsigned int which) +{ + + char attrname[VS_ATTR_NAME_LEN]; + + /*attribute name template for the dense storage related deletion operation */ + const char *aname_format_d = "attr-d-%u-%u"; + + /*attribute name template used for general attribute deletion operation */ + const char *aname_format = "attr-%u-%u"; + + /*attribute name template used for VL string attribute deletion + * or object header continuation check operations */ + const char *aname_format_vl = "attr-%u"; + + dbgf(2, "writer: coming to delete the attribute.\n"); + + /* Construct the attribute name */ + if (is_dense == true) + HDsprintf(attrname, aname_format_d, which, 0); + else if (is_vl_or_ohrc == true) + HDsprintf(attrname, aname_format_vl, which, 0); + else + HDsprintf(attrname, aname_format, which, 0); + + /* Delete the attribute */ + if (H5Adelete(obj_id, attrname) < 0) { + printf("H5Adelete() failed\n"); + TEST_ERROR; + } + + /* If coming to an "object header continuation block" test, + * we need to check if this test behaves as expected. */ + if (s->at_pattern == 'R') { + if (false == check_ohr_num_chunk(obj_id, true)) { + printf("The object header chunk should not continue. \n"); + TEST_ERROR; + } + } + return true; + +error: + return false; +} + +/*------------------------------------------------------------------------- + * Function: add_del_vlstr_attr + * + * Purpose: Add a variable length string attribute + * then delete this attribute in this a group. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * hid_t g + * HDF5 object ID (in this file: means group ID) + * + * unsigned int which + * The number of iterations for group creation, use to generate + * newly created group and attribute names. + * The group name is "group-which" and the attribute name + * is "attr-which". + * + * + * Return: Success: true + * Failure: false + * + * Note: This is for the "remove-vstr" test. + *------------------------------------------------------------------------- + */ + +static bool +add_del_vlstr_attr(state_t *s, hid_t g, unsigned int which) +{ + + bool ret_value = false; + + /* Add a VL string attribute then delete it. */ + ret_value = add_vlstr_attr(s, g, which); + if (ret_value == true) + ret_value = del_one_attr(s, g, false, true, which); + + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: modify_attr + * + * Purpose: Modify the value of an attribute in a group. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * hid_t g + * HDF5 object ID (in this file: means group ID) + * + * const char*aname_fmt + * The attribute name template used to create unique attribute names. + * + * unsigned int which + * The number of iterations for group creation, use to generate + * newly created group name. The group name is "group-which". + * + * + * Return: Success: true + * Failure: false + * + *------------------------------------------------------------------------- + */ + +static bool +modify_attr(state_t *s, hid_t g, const char *aname_fmt, unsigned int which) +{ + + char attrname[VS_ATTR_NAME_LEN]; + hid_t aid = H5I_INVALID_HID; + hid_t amtype = H5I_INVALID_HID; + unsigned int modify_value; + + HDsprintf(attrname, aname_fmt, which, 0); + if ((aid = H5Aopen(g, attrname, H5P_DEFAULT)) < 0) { + printf("H5Aopen failed\n"); + TEST_ERROR; + } + + if ((amtype = H5Tget_native_type(s->filetype, H5T_DIR_ASCEND)) < 0) { + printf("H5Tget_native_type failed\n"); + TEST_ERROR; + } + + /* Make a large number to verify the change easily */ + modify_value = which + 10000; + + if (H5Awrite(aid, amtype, &modify_value) < 0) { + printf("H5Awrite failed\n"); + TEST_ERROR; + } + if (H5Tclose(amtype) < 0) { + printf("H5Tclose failed\n"); + TEST_ERROR; + } + if (H5Aclose(aid) < 0) { + printf("H5Aclose failed\n"); + TEST_ERROR; + } + + return true; +error: + H5E_BEGIN_TRY + { + H5Aclose(aid); + H5Tclose(aid); + } + H5E_END_TRY; + + return false; +} + +/*------------------------------------------------------------------------- + * Function: modify_vlstr_attr + * + * Purpose: Modify the value of an VL string attribute in a group. + * + * Parameters: + * hid_t g + * HDF5 object ID (in this file: means group ID) + * + * unsigned int which + * The number of iterations for group creation, use to generate + * newly created group name. The group name is "group-which". + * + * + * Return: Success: true + * Failure: false + * + *------------------------------------------------------------------------- + */ + +static bool +modify_vlstr_attr(hid_t g, unsigned int which) +{ + + hid_t aid = H5I_INVALID_HID; + hid_t atype = H5I_INVALID_HID; + char name[VS_ATTR_NAME_LEN]; + char *astr_val = NULL; + + astr_val = HDmalloc(VS_ATTR_NAME_LEN); + if (astr_val == NULL) { + printf("Allocate memory for VL string failed.\n"); + TEST_ERROR; + } + + /* Change the VL string value and create the attribute name. */ + HDsprintf(astr_val, "%u%c", which, 'A'); + esnprintf(name, sizeof(name), "attr-%u", which); + + dbgf(1, "setting attribute %s on group %u to %u\n", name, which, which); + + /* Create a datatype to refer to. */ + if ((atype = H5Tcopy(H5T_C_S1)) < 0) { + printf("Cannot create variable length datatype.\n"); + TEST_ERROR; + } + + if (H5Tset_size(atype, H5T_VARIABLE) < 0) { + printf("Cannot set variable length datatype.\n"); + TEST_ERROR; + } + + /* Open this attribute. */ + if ((aid = H5Aopen(g, name, H5P_DEFAULT)) < 0) { + printf("H5Aopen failed.\n"); + TEST_ERROR; + } + + dbgf(1, "The modified VL string value is %s \n", astr_val); + + if (H5Awrite(aid, atype, &astr_val) < 0) { + printf("H5Awrite failed.\n"); + TEST_ERROR; + } + + if (H5Tclose(atype) < 0) { + printf("H5Tclose() failed\n"); + TEST_ERROR; + } + + if (H5Aclose(aid) < 0) { + printf("H5Aclose() failed\n"); + TEST_ERROR; + } + + HDfree(astr_val); + + return true; + +error: + H5E_BEGIN_TRY + { + H5Aclose(aid); + H5Tclose(atype); + } + H5E_END_TRY; + + if (astr_val) + HDfree(astr_val); + + return false; +} + +/*------------------------------------------------------------------------- + * Function: add_modify_vlstr_attr + * + * Purpose: Add a variable length string attribute + * then modify this attribute in the group. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * hid_t g + * HDF5 object ID (in this file: means group ID) + * + * unsigned int which + * The number of iterations for group creation, use to generate + * newly created group and attribute names. + * The group name is "group-which" and the attribute name + * is "attr-which". + * + * + * Return: Success: true + * Failure: false + * + * Note: This is for the "modify-vstr" test. + *------------------------------------------------------------------------- + */ + +static bool +add_modify_vlstr_attr(state_t *s, hid_t g, unsigned int which) +{ + + bool ret_value = false; + ret_value = add_vlstr_attr(s, g, which); + if (true == ret_value) + ret_value = modify_vlstr_attr(g, which); + + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: add_attrs_compact + * + * Purpose: Add some attributes to the group. + * the number of attributes should be the maximal number of + * attributes that the compact storage can hold + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * hid_t g + * HDF5 object ID (in this file: means group ID) + * + * hid_t gcpl + * Object creation property list ID + * + * unsigned int which + * The number of iterations for group creation, use to generate + * newly created group and attribute names. + * The group name is "group-which" and the attribute name + * is "attr-which". + * + * + * Return: Success: true + * Failure: false + * + * Note: This is for the "modify-vstr" test. + * For attribute compact/dense storage, check the reference + * manual of H5Pget_attr_phase_change. + *------------------------------------------------------------------------- + */ + +static bool +add_attrs_compact(state_t *s, hid_t g, hid_t gcpl, unsigned int which) +{ + + unsigned max_compact = 0; + unsigned min_dense = 0; + const char *aname_format = "attr-%u-%u"; + + if (s->old_style_grp) + max_compact = 2; + else { + /* Obtain the maximal number of attributes to be stored in compact + * storage and the minimal number of attributes to be stored in + * dense storage. */ + if (H5Pget_attr_phase_change(gcpl, &max_compact, &min_dense) < 0) { + printf("H5Pget_attr_phase_change() failed\n"); + TEST_ERROR; + } + } + + /* Add max_compact attributes, these attributes are stored in + * compact storage. */ + return add_attr(s, g, which, max_compact, aname_format, which); + +error: + return false; +} + +/*------------------------------------------------------------------------- + * Function: add_attrs_compact_dense + * + * Purpose: Add some attributes to the group. + * First, the number of attributes should be the maximal number + * of attributes that the compact storage can hold. + * Then, add another atribute, the storage becomes dense. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * hid_t g + * HDF5 object ID (in this file: means group ID) + * + * hid_t gcpl + * Object creation property list ID + * + * unsigned int which + * The number of iterations for group creation, use to generate + * newly created group and attribute names. + * + * Return: Success: true + * Failure: false + * + * Note: This is for the "compact-to-dense" test. + * For attribute compact/dense storage, check the reference + * manual of H5Pget_attr_phase_change. + *------------------------------------------------------------------------- + */ + +static bool +add_attrs_compact_dense(state_t *s, hid_t g, hid_t gcpl, unsigned int which) +{ + + unsigned max_compact = 0; + unsigned min_dense = 0; + const char *aname_format = "attr-d-%u-%u"; + bool ret_value = false; + + if (H5Pget_attr_phase_change(gcpl, &max_compact, &min_dense) < 0) { + printf("H5Pget_attr_phase_change failed\n"); + TEST_ERROR; + } + + /* Add attributes, until just before converting to dense storage */ + ret_value = add_attrs_compact(s, g, gcpl, which); + + /* Add another attribute, the storage becomes dense. */ + if (ret_value == true) + ret_value = add_attr(s, g, which + max_compact, 1, aname_format, which); + + return ret_value; + +error: + return false; +} + +/*------------------------------------------------------------------------- + * Function: del_attrs_compact_dense_compact + * + * Purpose: delete some attributes in the group. + * The number of attributes are deleted in such a way + * that the attribute storage changes from compact to + * dense then to compact again. + * + * Parameters: hid_t g + * HDF5 object ID (in this file: means group ID) + * + * hid_t gcpl + * Object creation property list ID + * + * unsigned int which + * The number of iterations for group creation, use to generate + * newly created group and attribute names. + * + * Return: Success: true + * Failure: false + * + * Note: This is an internal function used by the + * "dense-del-to-compact" test. + * For attribute compact/dense storage, check the reference + * manual of H5Pget_attr_phase_change. + *------------------------------------------------------------------------- + */ + +static bool +del_attrs_compact_dense_compact(hid_t obj_id, hid_t gcpl, unsigned int which) +{ + + unsigned max_compact = 0; + unsigned min_dense = 0; + unsigned u = 0; + + char attrname[VS_ATTR_NAME_LEN]; + const char *aname_format = "attr-%u-%u"; + const char *adname_format = "attr-d-%u-%u"; + + /* Obtain the maximal number of attributes to be stored in compact + * storage and the minimal number of attributes to be stored in + * dense storage. */ + if (H5Pget_attr_phase_change(gcpl, &max_compact, &min_dense) < 0) { + printf("H5Pget_attr_phase_change failed\n"); + TEST_ERROR; + } + u = max_compact + 1; + + /* delete a number of attributes so that the attribute storage just becomes dense.*/ + for (u--; u >= (min_dense - 1); u--) { + HDsprintf(attrname, aname_format, which, max_compact - u); + if (H5Adelete(obj_id, attrname) < 0) { + printf("H5Adelete failed\n"); + TEST_ERROR; + } + } + + /* The writer deletes another attribute, the storage is + * still dense. However, the attribute to be deleted + * doesn't follow the previous for loop. It may be + * in different location in the object header. Just add + * a litter variation to check if this operation is successful. + * The attribute name to be deleted is attr-max_compact+which-0 + */ + + HDsprintf(attrname, adname_format, max_compact + which, 0); + if (H5Adelete(obj_id, attrname) < 0) { + printf("H5Adelete failed\n"); + TEST_ERROR; + } + + return true; + +error: + return false; +} + +/*------------------------------------------------------------------------- + * Function: add_del_attrs_compact + * + * Purpose: Add some attributes to the group and then delete one attribute. + * First, the number of attributes to be added should be the + * maximal number of attributes that the compact storage can hold. + * Then, delete one atribute, the storage is still compact. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * hid_t g + * HDF5 object ID (in this file: means group ID) + * + * hid_t gcpl + * Object creation property list ID + * + * unsigned int which + * The number of iterations for group creation, use to generate + * newly created group and attribute names. + * + * Return: Success: true + * Failure: false + * + * Note: This is for the "compact-del" test. + * For attribute compact/dense storage, check the reference + * manual of H5Pget_attr_phase_change. + *------------------------------------------------------------------------- + */ + +static bool +add_del_attrs_compact(state_t *s, hid_t g, hid_t gcpl, unsigned int which) +{ + + bool ret_value = false; + ret_value = add_attrs_compact(s, g, gcpl, which); + if (ret_value == true) { + dbgf(2, "writer: before deleting the attribute.\n"); + ret_value = del_one_attr(s, g, false, false, which); + } + + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: add_del_attrs_compact_dense + * + * Purpose: Add some attributes to the group and then delete one attribute. + * First, the number of attributes to be added exceeds + * the maximal number of attributes that the compact storage can hold. + * The storage changes from compact to dense. + * Then, delete one atribute, the storage is still dense. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * hid_t g + * HDF5 object ID (in this file: means group ID) + * + * hid_t gcpl + * Object creation property list ID + * + * unsigned int which + * The number of iterations for group creation, use to generate + * newly created group and attribute names. + * + * Return: Success: true + * Failure: false + * + * Note: This is for the "dense-del" test. + * For attribute compact/dense storage, check the reference + * manual of H5Pget_attr_phase_change. + *------------------------------------------------------------------------- + */ + +static bool +add_del_attrs_compact_dense(state_t *s, hid_t g, hid_t gcpl, unsigned int which) +{ + + bool ret_value = false; + unsigned max_compact = 0; + unsigned min_dense = 0; + + if (H5Pget_attr_phase_change(gcpl, &max_compact, &min_dense) < 0) { + printf("H5Pget_attr_phase_change failed\n"); + TEST_ERROR; + } + + ret_value = add_attrs_compact_dense(s, g, gcpl, which); + if (ret_value == true) + ret_value = del_one_attr(s, g, true, false, which + max_compact); + + return ret_value; + +error: + return false; +} + +/*------------------------------------------------------------------------- + * Function: add_del_attrs_compact_dense_compact + * + * Purpose: Add attributes to the group and then delete some of them. + * First, the number of attributes to be added exceeds + * the maximal number of attributes that the compact storage can hold. + * The storage changes from compact to dense. + * Then, delete some attributes, the storage changes from + * dense to compact again. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * hid_t g + * HDF5 object ID (in this file: means group ID) + * + * hid_t gcpl + * Object creation property list ID + * + * unsigned int which + * The number of iterations for group creation, use to generate + * newly created group and attribute names. + * + * Return: Success: true + * Failure: false + * + * Note: This is for the "dense-del-to-compact" test. + * For attribute compact/dense storage, check the reference + * manual of H5Pget_attr_phase_change. + *------------------------------------------------------------------------- + */ + +static bool +add_del_attrs_compact_dense_compact(state_t *s, hid_t g, hid_t gcpl, unsigned int which) +{ + + bool ret_value = false; + ret_value = add_attrs_compact_dense(s, g, gcpl, which); + if (ret_value == true) + ret_value = del_attrs_compact_dense_compact(g, gcpl, which); + + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: add_modify_default_group_attr + * + * Purpose: Add an attribute then modify the value to a group. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * hid_t g + * HDF5 object ID (in this file: means group ID) + * + * unsigned int which + * The number of iterations for group creation, use to generate + * newly created group and attribute names. + * The group name is "group-which" and the attribute name + * is "attr-which". + * + * + * Return: Success: true + * Failure: false + * + * Note: This function is used for the "modify" test. + *------------------------------------------------------------------------- + */ + +static bool +add_modify_default_group_attr(state_t *s, hid_t g, unsigned int which) +{ + + bool ret_value = false; + const char *aname_format = "attr-%u"; + ret_value = add_default_group_attr(s, g, which); + if (ret_value == true) + ret_value = modify_attr(s, g, aname_format, which); + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: del_ohr_block_attr + * + * Purpose: Add an attribute to force creation of object header + * continuation block and remove this attribute to delete + * the object header continuation block + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * hid_t g + * HDF5 object ID (in this file: means group ID) + * + * unsigned int which + * The number of iterations for group creation, use to generate + * newly created group and attribute names. + * The group name is "group-which" and the attribute name + * is "attr-which". + * + * + * Return: Success: true + * Failure: false + * + * Note: This function is used for the + * "deletion of object header continuation block" test. + *------------------------------------------------------------------------- + */ + +static bool +del_ohr_block_attr(state_t *s, hid_t g, unsigned int which) +{ + + bool ret_value = false; + ret_value = add_default_group_attr(s, g, which); + if (ret_value == true) + ret_value = del_one_attr(s, g, false, true, which); + return ret_value; +} +/*------------------------------------------------------------------------- + * Function: add_group_attribute + * + * Purpose: Check the attribute test pattern and then call the + * correponding test function.. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * hid_t g + * HDF5 object ID (in this file: means group ID) + * + * hid_t gcpl + * Object creation property list ID + * + * unsigned int which + * The number of iterations for group creation, use to generate + * newly created group and attribute names. + * + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the write_group() function. + *------------------------------------------------------------------------- + */ + +static bool +add_group_attribute(state_t *s, hid_t g, hid_t gcpl, unsigned int which) +{ + + bool ret_value = false; + char test_pattern = s->at_pattern; + + switch (test_pattern) { + case 'c': + ret_value = add_attrs_compact(s, g, gcpl, which); + break; + case 't': + ret_value = add_attrs_compact_dense(s, g, gcpl, which); + break; + case 'C': + ret_value = add_del_attrs_compact(s, g, gcpl, which); + break; + case 'D': + ret_value = add_del_attrs_compact_dense(s, g, gcpl, which); + break; + case 'T': + ret_value = add_del_attrs_compact_dense_compact(s, g, gcpl, which); + break; + case 'M': + ret_value = add_modify_default_group_attr(s, g, which); + break; + case 'v': + ret_value = add_vlstr_attr(s, g, which); + break; + case 'r': + ret_value = add_del_vlstr_attr(s, g, which); + break; + case 'm': + ret_value = add_modify_vlstr_attr(s, g, which); + break; + case 'R': + ret_value = del_ohr_block_attr(s, g, which); + break; + case 'a': + case 'd': + case ' ': + default: + ret_value = add_default_group_attr(s, g, which); + break; + } + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: write_group + * + * Purpose: Create a group and carry out attribute operations(add,delete etc.) + * according to the attribute test pattern. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * unsigned int which + * The number of iterations for group creation + * + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the main() function. + *------------------------------------------------------------------------- + */ + +static bool +write_group(state_t *s, unsigned int which) +{ + char name[sizeof("/group-9999999999")]; + hid_t g = H5I_INVALID_HID; + hid_t dummy_d = H5I_INVALID_HID; + hid_t gcpl = H5I_INVALID_HID; + bool result = true; + H5G_info_t group_info; + struct timespec start_time, end_time; + double temp_time; + + if (which >= s->nsteps) { + printf("Number of created groups is out of bounds\n"); + TEST_ERROR; + } + + esnprintf(name, sizeof(name), "/group-%u", which); + + if (s->old_style_grp) + gcpl = H5P_DEFAULT; + else { + gcpl = H5Pcreate(H5P_GROUP_CREATE); + if (gcpl < 0) { + printf("H5Pcreate failed\n"); + TEST_ERROR; + } + + /* If we test the dense storage, change the attribute phase. */ + if (s->at_pattern == 'd') { + if (H5Pset_attr_phase_change(gcpl, 0, 0) < 0) { + printf("H5Pset_attr_phase_change failed for the dense storage.\n"); + TEST_ERROR; + } + } + } + + if (s->gperf) { + + if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { + + fprintf(stderr, "HDclock_gettime failed"); + + TEST_ERROR; + } + } + + if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, gcpl, H5P_DEFAULT)) < 0) { + printf("H5Gcreate2 failed\n"); + TEST_ERROR; + } + + if (s->gperf) { + + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { + + fprintf(stderr, "HDclock_gettime failed"); + + TEST_ERROR; + } + + temp_time = TIME_PASSED(start_time, end_time); + if (temp_time < s->min_gc_time) + s->min_gc_time = temp_time; + if (temp_time > s->max_gc_time) + s->max_gc_time = temp_time; + s->total_gc_time += temp_time; + } + + /* We need to create a dummy dataset for the object header continuation block test. */ + if (s->at_pattern == 'a' || s->at_pattern == 'R') { + if ((dummy_d = H5Dcreate2(g, "Dataset", H5T_NATIVE_INT, s->one_by_one_sid, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + printf("H5Dcreate2 failed\n"); + TEST_ERROR; + } + } + /* We only need to check the first group */ + if (which == 0) { + if (H5Gget_info(g, &group_info) < 0) { + printf("H5Gget_info failed\n"); + TEST_ERROR; + } + + if (s->old_style_grp) { + if (group_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) { + printf("Old-styled group test: but the group is not in old-style. \n"); + TEST_ERROR; + } + dbgf(2, "Writer: group is created with the old-style.\n"); + } + else { + if (group_info.storage_type == H5G_STORAGE_TYPE_SYMBOL_TABLE) { + printf("The created group should NOT be in old-style . \n"); + TEST_ERROR; + } + dbgf(2, "Writer: group is created with the new-style.\n"); + } + } + + /* If coming to an "object header continuation block" test, + * we need to check if this test behaves as expected. */ + if (s->at_pattern == 'a' || s->at_pattern == 'R') { + if (false == check_ohr_num_chunk(g, true)) { + printf("An object header continuation block should NOT be created. \n"); + printf("But it is created.\n"); + TEST_ERROR; + } + } + + /* Then carry out the attribute operation. */ + if (s->asteps != 0 && which % s->asteps == 0) + result = add_group_attribute(s, g, gcpl, which); + + if (s->at_pattern == 'a' || s->at_pattern == 'R') { + if (H5Dclose(dummy_d) < 0) { + printf("H5Dclose failed\n"); + TEST_ERROR; + } + } + + if (H5Gclose(g) < 0) { + printf("H5Gclose failed\n"); + TEST_ERROR; + } + + if (!s->old_style_grp && H5Pclose(gcpl) < 0) { + printf("H5Pclose failed\n"); + TEST_ERROR; + } + + return result; + +error: + + H5E_BEGIN_TRY + { + H5Gclose(g); + if (s->at_pattern == 'a' || s->at_pattern == 'R') + H5Dclose(dummy_d); + if (!s->old_style_grp) + H5Pclose(gcpl); + } + H5E_END_TRY; + + return false; +} + +/*------------------------------------------------------------------------- + * Function: create_group_id + * + * Purpose: Create a group and return the group ID. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * unsigned int which + * The number of iterations for group creation + * This is used to generate the group name. + * + * bool dense_to_compact + * true if this function is used to test the transition from dense to + * compact, false if the test is from compact to dense. + * + * Return: Success: the group ID + * Failure: -1 + * + * Note: Only used by testing the link storage transit functions. + *------------------------------------------------------------------------- + */ + +static hid_t +create_group_id(state_t *s, unsigned int which, bool dense_to_compact) +{ + + char name[sizeof("/group-9999999999")]; + hid_t g = H5I_INVALID_HID; + hid_t gcpl = H5I_INVALID_HID; + H5G_info_t group_info; + + if (which >= s->nsteps) { + printf("Number of created groups is out of bounds\n"); + TEST_ERROR; + } + + gcpl = H5Pcreate(H5P_GROUP_CREATE); + if (gcpl < 0) { + printf("H5Pcreate failed\n"); + TEST_ERROR; + } + + if (dense_to_compact) { + if (H5Pset_link_phase_change(gcpl, 2, 2) < 0) { + printf("H5Pset_link_phase_change failed for dense to compact.\n"); + TEST_ERROR; + } + } + else { + if (H5Pset_link_phase_change(gcpl, 1, 1) < 0) { + printf("H5Pset_attr_phase_change failed for compact to dense.\n"); + TEST_ERROR; + } + } + + esnprintf(name, sizeof(name), "/group-%u", which); + if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, gcpl, H5P_DEFAULT)) < 0) { + printf("H5Gcreate2 failed\n"); + TEST_ERROR; + } + + if (H5Gget_info(g, &group_info) < 0) { + printf("H5Gget_info failed\n"); + TEST_ERROR; + } + + /* The storage type should always be compact when a group is created. */ + if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) { + printf("New-style group link storage test:. \n"); + printf(" still be compact after group creation. \n"); + TEST_ERROR; + } + + if (H5Pclose(gcpl) < 0) { + printf("H5Pclose failed\n"); + TEST_ERROR; + } + + return g; + +error: + + H5E_BEGIN_TRY + { + H5Pclose(gcpl); + } + H5E_END_TRY; + + return -1; +} + +/*------------------------------------------------------------------------- + * Function: close_group_id + * + * Purpose: Verify is a group is closed successfully. + * + * Parameters: hid_t g + * The ID of the group to be closed. + * + * Return: Success: true + * Failure: false + * + * Note: This is used by the link storage transit functions. + *------------------------------------------------------------------------- + */ + +static bool +close_group_id(hid_t g) +{ + + if (H5Gclose(g) < 0) { + printf("H5Gclose failed\n"); + TEST_ERROR; + } + + return true; + +error: + return false; +} + +/*------------------------------------------------------------------------- + * Function: create_group + * + * Purpose: Create a group + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * unsigned int which + * The number of iterations for group creation + * This is used to generate the group name. + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the main() function. + *------------------------------------------------------------------------- + */ + +static bool +create_group(state_t *s, unsigned int which) +{ + + char name[sizeof("/group-9999999999")]; + hid_t g = H5I_INVALID_HID; + H5G_info_t group_info; + + if (which >= s->nsteps) { + printf("Number of created groups is out of bounds\n"); + TEST_ERROR; + } + + esnprintf(name, sizeof(name), "/group-%u", which); + if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + printf("H5Gcreate2 failed\n"); + TEST_ERROR; + } + + if (H5Gget_info(g, &group_info) < 0) { + printf("H5Gget_info failed\n"); + TEST_ERROR; + } + + if (s->old_style_grp) { + if (group_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) { + printf("Old-styled group test: but the group is not in old-style. \n"); + TEST_ERROR; + } + dbgf(2, "Writer: group is created with the old-style.\n"); + } + else { + if (group_info.storage_type == H5G_STORAGE_TYPE_SYMBOL_TABLE) { + printf("The created group should NOT be in old-style . \n"); + TEST_ERROR; + } + dbgf(2, "Writer: group is created with the new-style.\n"); + } + + if (H5Gclose(g) < 0) { + printf("H5Gclose failed\n"); + TEST_ERROR; + } + + return true; + +error: + + H5E_BEGIN_TRY + { + H5Gclose(g); + } + H5E_END_TRY; + + return false; +} + +/*------------------------------------------------------------------------- + * Function: delete_one_link + * + * Purpose: Delete a link(either hard/soft) in group operation tests. + * according to the group test pattern. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * hid_t obj_id + * The HDF5 object ID that the deleted link is attached to. + * + * const char *name + * The name of the link to be deleted. + * + * short link_storage + * <=0: link storage is ignored. + * 1: link storage should be compact after link deletion.. + * >1: link storage should be dense after link deletion. + * + * unsigned int which + * The number of iterations for group creation + * + * + * Return: Success: true + * Failure: false + * + * Note: This is used by delete_groups() and delete_links() functions. + *------------------------------------------------------------------------- + */ + +static bool +delete_one_link(state_t *s, hid_t obj_id, const char *name, short link_storage, unsigned int which) +{ + + H5G_info_t group_info; + + if (which >= s->nsteps) { + printf("Number of created groups is out of bounds\n"); + TEST_ERROR; + } + + if (H5Ldelete(obj_id, name, H5P_DEFAULT) < 0) { + printf("H5Ldelete failed\n"); + TEST_ERROR; + } + + if (link_storage > 0) { + + if (s->old_style_grp) { + printf("Old style group doesn't support the indexed storage.\n"); + TEST_ERROR; + } + + if (H5Gget_info(obj_id, &group_info) < 0) { + printf("H5Gget_info failed\n"); + TEST_ERROR; + } + + if (link_storage == 1) { + + if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) { + printf("The group link storage should be compact. \n"); + TEST_ERROR; + } + } + else { + + if (group_info.storage_type != H5G_STORAGE_TYPE_DENSE) { + printf("The group link storage should be dense. \n"); + TEST_ERROR; + } + } + } + + return true; + +error: + return false; +} + +/*------------------------------------------------------------------------- + * Function: delete_group + * + * Purpose: Delete a group and carry out group operations(add,delete etc.) + * according to the group operation test pattern. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * unsigned int which + * The number of iterations for group creation + * This is used to generate the group name + * + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the group_operations() function. + *------------------------------------------------------------------------- + */ + +static bool +delete_group(state_t *s, unsigned int which) +{ + + char name[sizeof("/group-9999999999")]; + bool ret_value = create_group(s, which); + if (ret_value == true) { + esnprintf(name, sizeof(name), "/group-%u", which); + ret_value = delete_one_link(s, s->file, name, 0, which); + } + + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: move_one_group + * + * Purpose: A helper function used by the move_group operation. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * hid_t obj_id + * ID of the object this group is attached to + * + * const char *name + * The original group name + * + * const char *newname + * The new group name + * + * unsigned int which + * The number of iterations for group creation + * + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the move_group() function. + *------------------------------------------------------------------------- + */ + +static bool +move_one_group(state_t *s, hid_t obj_id, const char *name, const char *newname, unsigned int which) +{ + + if (which >= s->nsteps) { + printf("Number of created groups is out of bounds\n"); + TEST_ERROR; + } + + if (H5Lmove(obj_id, name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { + printf("H5Ldelete failed\n"); + TEST_ERROR; + } + + return true; + +error: + return false; +} + +/*------------------------------------------------------------------------- + * Function: move_group + * + * Purpose: Move a group to another group. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * unsigned int which + * The number of iterations for group creation + * used to generate the group name. + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the group_operations() function. + *------------------------------------------------------------------------- + */ + +static bool +move_group(state_t *s, unsigned int which) +{ + + char name[sizeof("/group-9999999999")]; + char new_name[sizeof("/new-group-9999999999")]; + bool ret_value = create_group(s, which); + if (ret_value == true) { + esnprintf(name, sizeof(name), "/group-%u", which); + esnprintf(new_name, sizeof(new_name), "/new-group-%u", which); + ret_value = move_one_group(s, s->file, name, new_name, which); + } + + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: insert_one_link + * + * Purpose: A helper function used to attach a link to a group. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * hid_t obj_id + * ID of the object this link is attached to + * + * const char *name + * The name of the target object used by creating links + * + * const char *newname + * The name of the linked objects + * + * bool is_hard + * true if inserting a hard link + * false if inserting a soft link + * + * short link_storage + * <=0: link storage is ignored. + * 1: link storage should be compact. + * >1: link storage should be dense. + + * unsigned int which + * The number of iterations for group creation + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the insert_links and link storage transit functions. + * For link storage, we test at both the writer and the reader. + *------------------------------------------------------------------------- +*/ + +static bool +insert_one_link(state_t *s, hid_t obj_id, const char *name, const char *newname, bool is_hard, + short link_storage, unsigned int which) +{ + + H5G_info_t group_info; + + if (which >= s->nsteps) { + printf("Number of created groups is out of bounds\n"); + TEST_ERROR; + } + + /* For storage transit and insert_links cases, we + * create links in different style, just add a little + * variation of the tests.*/ + if (is_hard) { + if (link_storage > 0) { + if (H5Lcreate_hard(s->file, name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { + printf("H5Lcreate_hard failed\n"); + TEST_ERROR; + } + } + else { + if (H5Lcreate_hard(obj_id, name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { + printf("H5Lcreate_hard failed\n"); + TEST_ERROR; + } + } + } + else { + if (link_storage > 0) { + if (H5Lcreate_soft("/", obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { + printf("H5Lcreate_soft failed\n"); + TEST_ERROR; + } + } + else { + if (H5Lcreate_soft(name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { + printf("H5Lcreate_soft failed.\n"); + TEST_ERROR; + } + } + } + + if (link_storage > 0) { + + if (s->old_style_grp) { + printf("Old style group doesn't support dense or compact storage.\n"); + TEST_ERROR; + } + + if (H5Gget_info(obj_id, &group_info) < 0) { + printf("H5Gget_info failed\n"); + TEST_ERROR; + } + + if (link_storage == 1) { + if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) { + printf("The group link storage should be compact. \n"); + TEST_ERROR; + } + } + else { + if (group_info.storage_type != H5G_STORAGE_TYPE_DENSE) { + printf("The group link storage should be dense. \n"); + TEST_ERROR; + } + } + } + + return true; + +error: + return false; +} + +/*------------------------------------------------------------------------- + * Function: insert_links + * + * Purpose: create links with a group. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * unsigned int which + * The number of iterations + * used to generate the group name. + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the group_operations() function. + *------------------------------------------------------------------------- + */ + +static bool +insert_links(state_t *s, unsigned int which) +{ + + char name[sizeof("/group-9999999999")]; + char hd_name[sizeof("/hd-group-9999999999")]; + char st_name[sizeof("/st-group-9999999999")]; + + bool ret_value = create_group(s, which); + if (ret_value == true) { + esnprintf(name, sizeof(name), "/group-%u", which); + esnprintf(hd_name, sizeof(hd_name), "/hd-group-%u", which); + esnprintf(st_name, sizeof(st_name), "/st-group-%u", which); + ret_value = insert_one_link(s, s->file, name, hd_name, true, 0, which); + if (ret_value == true) + ret_value = insert_one_link(s, s->file, name, st_name, false, 0, which); + } + + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: delete_links + * + * Purpose: create links with a group and then delete them successfully. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * unsigned int which + * The number of iterations + * used to generate the group name. + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the group_operations() function. + *------------------------------------------------------------------------- + */ + +static bool +delete_links(state_t *s, unsigned int which) +{ + + char name[sizeof("/group-9999999999")]; + char hd_name[sizeof("/hd-group-9999999999")]; + char st_name[sizeof("/st-group-9999999999")]; + + bool ret_value = insert_links(s, which); + if (ret_value == true) { + esnprintf(name, sizeof(name), "/group-%u", which); + esnprintf(hd_name, sizeof(hd_name), "/hd-group-%u", which); + esnprintf(st_name, sizeof(st_name), "/st-group-%u", which); + ret_value = delete_one_link(s, s->file, hd_name, 0, which); + if (ret_value == true) + ret_value = delete_one_link(s, s->file, st_name, 0, which); + } + + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: transit_storage_compact_to_dense + * + * Purpose: Add links so that the link storage transits from + * compact to dense. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * unsigned int which + * The number of iterations used to generate the group name. + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the group_operations() function. + *------------------------------------------------------------------------- + */ + +static bool +transit_storage_compact_to_dense(state_t *s, unsigned int which) +{ + + char name[sizeof("/group-9999999999")]; + char hd_name[sizeof("/hd-group-9999999999")]; + char st_name[sizeof("/st-group-9999999999")]; + + hid_t g = create_group_id(s, which, false); + if (g < 0) { + printf("create_group_id failed\n"); + TEST_ERROR; + } + + /* First insert a hard link, compact storage. */ + esnprintf(name, sizeof(name), "/group-%u", which); + esnprintf(hd_name, sizeof(hd_name), "hd-group-%u", which); + if (insert_one_link(s, g, name, hd_name, true, 1, which) == false) { + printf("insert_one_link for compact storage failed\n"); + TEST_ERROR; + } + + /* Then insert a soft link, the storage becomes dense. */ + esnprintf(st_name, sizeof(st_name), "st-group-%u", which); + if (insert_one_link(s, g, name, st_name, false, 2, which) == false) { + printf("insert_one_link for dense storage failed\n"); + TEST_ERROR; + } + + if (close_group_id(g) == false) { + printf("insert_one_link for dense storage failed\n"); + TEST_ERROR; + } + + return true; + +error: + H5E_BEGIN_TRY + { + H5Gclose(g); + } + H5E_END_TRY; + + return false; +} + +/*------------------------------------------------------------------------- + * Function: transit_storage_dense_to_compact + * + * Purpose: Add or delete links so that the link storage transits from + * compact to dense then to compact. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * unsigned int which + * The number of iterations used to generate the group name. + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the group_operations() function. + *------------------------------------------------------------------------- + */ + +static bool +transit_storage_dense_to_compact(state_t *s, unsigned int which) +{ + + char name[sizeof("/group-9999999999")]; + char hd_name[sizeof("/hd-group-9999999999")]; + char st_name[sizeof("st-group-9999999999")]; + char st2_name[sizeof("st2-group-9999999999")]; + + hid_t g = create_group_id(s, which, true); + if (g < 0) { + printf("create_group_id failed\n"); + TEST_ERROR; + } + + /* Insert a link, storage is compact. */ + esnprintf(name, sizeof(name), "/group-%u", which); + esnprintf(hd_name, sizeof(hd_name), "hd-group-%u", which); + if (insert_one_link(s, g, name, hd_name, true, 1, which) == false) { + printf("insert_one_link for compact storage failed\n"); + TEST_ERROR; + } + + /* Insert a link, storage is still compact. */ + esnprintf(st_name, sizeof(st_name), "st-group-%u", which); + if (insert_one_link(s, g, name, st_name, false, 1, which) == false) { + printf("insert_one_link for compact storage failed\n"); + TEST_ERROR; + } + + /* Insert a link, storage becomes dense. */ + esnprintf(st2_name, sizeof(st2_name), "st2-group-%u", which); + if (insert_one_link(s, g, name, st2_name, false, 2, which) == false) { + printf("insert_one_link for dense storage failed\n"); + TEST_ERROR; + } + + /* Delete a link, storage is still dense */ + if (delete_one_link(s, g, st_name, 2, which) == false) { + printf("delete_one_link for dense storage failed\n"); + TEST_ERROR; + } + + /* Delete another link, storage becomes compact */ + if (delete_one_link(s, g, st2_name, 1, which) == false) { + printf("delete_one_link for compact storage failed\n"); + TEST_ERROR; + } + + if (close_group_id(g) == false) { + printf("insert_one_link for dense storage failed\n"); + TEST_ERROR; + } + + return true; + +error: + H5E_BEGIN_TRY + { + H5Gclose(g); + } + H5E_END_TRY; + + return false; +} + +/*------------------------------------------------------------------------- + * Function: group_operations + * + * Purpose: Carry out group and attribute operations(add,delete etc.) + * according to the group operation and attribute test patterns. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * unsigned int which + * The number of iterations for group creation + * + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the main() function. The check of attribute + * operations is inside the write_group() function. + *------------------------------------------------------------------------- + */ +static bool +group_operations(state_t *s, unsigned int which) +{ + + bool ret_value = false; + char test_pattern = s->grp_op_pattern; + + switch (test_pattern) { + case 'c': + ret_value = create_group(s, which); + break; + case 'd': + ret_value = delete_group(s, which); + break; + case 'm': + ret_value = move_group(s, which); + break; + case 'i': + ret_value = insert_links(s, which); + break; + case 'D': + ret_value = delete_links(s, which); + break; + case 't': + ret_value = transit_storage_compact_to_dense(s, which); + break; + case 'T': + ret_value = transit_storage_dense_to_compact(s, which); + break; + case ' ': + default: + ret_value = write_group(s, which); + break; + } + return ret_value; +} + +static unsigned int grp_counter = 0; + +/*------------------------------------------------------------------------- + * Function: UI_Pow + * + * Purpose: Helper function to obtain the power 'n' of + * an unsigned integer 'x' + * Similar to pow(x,y) but for an unsigned integer. + * + * Parameters: unsigned int x + * unsigned int n + * + * Return: Return an unsigned integer of value of pow(x,n) + * Note: If the returned value is > 2^32-1, an overflow + * may occur. For our testing purpose, this may never happen. + * + *------------------------------------------------------------------------- + */ + +static unsigned int +UI_Pow(unsigned int x, unsigned int n) +{ + unsigned int i; /* Variable used in loop grp_counter */ + unsigned int number = 1; + + for (i = 0; i < n; ++i) + number *= x; + + return (number); +} + +/*------------------------------------------------------------------------- + * Function: obtain_tree_level_elems + * + * Purpose: Helper function to obtain the maximum number of elements + * at one level. + * + * Parameters: unsigned int total_ele + * The total number of elements of a tree(excluding the root) + * + * unsigned int level + * The number of nested levels + * (If every element of the tree is under the root, + * the level is 0.) + * + * Return: Return the maximum number of elements at one level + * + * Example: If the total number of elements is 6 and level is 1, + * the maximum number of elements is 2.The tree is + * a perfectly balanced tree. + * Such as: + * 0 + * 1 2 + * 3 4 5 6 + * + * If the total number of elements is 5 and level is 1, + * the maximum number of elements is still 2. The + * tree is not balanced, there is no element on the + * right-most leaf but the level is still 1. + * Such as: + * 0 + * 1 2 + * 3 4 5 + * + *------------------------------------------------------------------------- + */ + +static unsigned int +obtain_tree_level_elems(unsigned int total_ele, unsigned int level) +{ + + assert(level <= total_ele); + /* if every element is under the root, just return the total number of elements. */ + if (level == 0) + return total_ele; + else { + unsigned int test_elems_level = 0; + unsigned total = 0; + unsigned int i = 1; + /* Obtain the maximum number of elements for a level with the brutal force way. */ + while (total < total_ele) { + test_elems_level++; + total = 0; + for (i = 1; i <= level + 1; i++) + total += UI_Pow(test_elems_level, i); + } + if (total == total_ele) + dbgf(2, "Perfectly match: Number of elements per level is %u\n", test_elems_level); + return test_elems_level; + } +} + +/*------------------------------------------------------------------------- + * Function: gen_tree_struct + * + * Purpose: Generate the nested groups + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file + * and some VFD SWMR configuration parameters + * + * unsigned int level + * The number of nested levels +1 + * (Note: If every element of the tree is under the root, + * the level is 1 in this function.) + * unsigned num_elems_per_level + * The maximum number of element in a level + * hid_t group_id + * The ID of the parent group + * + * Return: Success: true + * Failure: false + */ +static bool +gen_tree_struct(state_t *s, unsigned int level, unsigned ne_per_level, hid_t pgrp_id) +{ + + char name[sizeof("group-9999999999")]; + unsigned int i; + hid_t grp_id; + bool result = true; + H5G_info_t group_info; + struct timespec start_time, end_time; + double temp_time; + + if (level > 0 && grp_counter < s->nsteps) { + + for (i = 0; i < ne_per_level; i++) { + + /* For each i a group is created. + Use grp_counter to generate the group name. + printf("id: %u,level: %u, index: %u\n",id,level,i); + */ + esnprintf(name, sizeof(name), "group-%u", grp_counter); + if (grp_counter == s->nsteps) + break; + + dbgf(2, "writer in nested group: step %d\n", grp_counter); + if (s->gperf) { + + if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { + fprintf(stderr, "HDclock_gettime failed"); + TEST_ERROR; + } + } + + if ((grp_id = H5Gcreate2(pgrp_id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + printf("H5Gcreate2 failed\n"); + TEST_ERROR; + } + + if (s->gperf) { + + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { + + fprintf(stderr, "HDclock_gettime failed"); + + TEST_ERROR; + } + + temp_time = TIME_PASSED(start_time, end_time); + if (temp_time < s->min_gc_time) + s->min_gc_time = temp_time; + if (temp_time > s->max_gc_time) + s->max_gc_time = temp_time; + s->total_gc_time += temp_time; + } + + /* Just check the first group information. */ + if (grp_counter == 0) { + if (H5Gget_info(grp_id, &group_info) < 0) { + printf("H5Gget_info failed\n"); + TEST_ERROR; + } + + if (s->old_style_grp) { + if (group_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) { + printf("Old-styled group test: but the group is not in old-style. \n"); + TEST_ERROR; + } + dbgf(2, "Writer: group is created with the old-style.\n"); + } + else { + if (group_info.storage_type == H5G_STORAGE_TYPE_SYMBOL_TABLE) { + printf("The created group should NOT be in old-style . \n"); + TEST_ERROR; + } + dbgf(2, "Writer: group is created with the new-style.\n"); + } + } + + /* Then carry out the attribute operation. */ + if (s->asteps != 0 && grp_counter % s->asteps == 0) + result = add_default_group_attr(s, grp_id, grp_counter); + + if (result == false) { + printf("Cannot create group attributes. \n"); + TEST_ERROR; + } + grp_counter++; + + /* Generate groups in the next level */ + result = gen_tree_struct(s, level - 1, ne_per_level, grp_id); + if (result == false) { + printf("Cannot create nested groups. \n"); + TEST_ERROR; + } + + /* close the group ID. No problem. */ + if (H5Gclose(grp_id) < 0) { + printf("H5Gclose failed. \n"); + TEST_ERROR; + } + } + } + + return true; + +error: + + H5E_BEGIN_TRY + { + H5Gclose(grp_id); + } + H5E_END_TRY; + + return false; +} + +int +main(int argc, char **argv) +{ + hid_t fapl = H5I_INVALID_HID, fcpl = H5I_INVALID_HID; + unsigned step; + bool writer = false; + state_t s; + const char * personality; + H5F_vfd_swmr_config_t config; + bool wg_ret = false; + struct timespec start_time, end_time; + unsigned int num_elems_per_level; + + if (!state_init(&s, argc, argv)) { + printf("state_init failed\n"); + TEST_ERROR; + } + + personality = HDstrstr(s.progname, "vfd_swmr_log_"); + + if (personality != NULL && HDstrcmp(personality, "vfd_swmr_log_writer") == 0) + writer = true; + else if (personality != NULL && HDstrcmp(personality, "vfd_swmr_log_reader") == 0) + writer = false; + else { + printf("unknown personality, expected vfd_swmr_log_{reader,writer}\n"); + TEST_ERROR; + } + + if (writer == false) { + printf("Reader is skipped for the performance tests.\n"); + return EXIT_SUCCESS; + } + + /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ + init_vfd_swmr_config(&config, s.tick_len, s.max_lag, writer, FALSE, 128, "./group-shadow"); + init_vfd_swmr_config_log(&config, "./log-test"); + + /* If old-style option is chosen, use the earliest file format(H5F_LIBVER_EARLIEST) + * as the second parameter of H5Pset_libver_bound() that is called by + * vfd_swmr_create_fapl. Otherwise, the latest file format(H5F_LIBVER_LATEST) + * should be used as the second parameter of H5Pset_libver_bound(). + * Also pass the use_vfd_swmr, only_meta_page, page buffer size, config to vfd_swmr_create_fapl().*/ + if ((fapl = vfd_swmr_create_fapl(!s.old_style_grp, s.use_vfd_swmr, true, s.pbs, &config)) < 0) { + printf("vfd_swmr_create_fapl failed\n"); + TEST_ERROR; + } + + /* Set fs_strategy (file space strategy) and fs_page_size (file space page size) */ + if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, s.ps)) < 0) { + HDprintf("vfd_swmr_create_fcpl() failed"); + TEST_ERROR; + } + + if (s.nglevels > 0) { + if (s.grp_op_pattern != ' ' || s.at_pattern != ' ') { + printf("For nested group creation test, only the default option is supported.\n"); + printf("Please re-run the tests with the appopriate option.\n"); + TEST_ERROR; + } + } + + if (s.gperf) { + + if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { + fprintf(stderr, "HDclock_gettime failed"); + TEST_ERROR; + } + } + + s.file = H5Fcreate(s.filename, H5F_ACC_TRUNC, fcpl, fapl); + + if (s.gperf) { + + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { + fprintf(stderr, "HDclock_gettime failed"); + TEST_ERROR; + } + + s.fo_total_time = TIME_PASSED(start_time, end_time); + } + + if (s.file < 0) { + printf("H5Fcreate failed\n"); + TEST_ERROR; + } + + /* If generating nested groups, calculate the maximum number of + elements per level. */ + if (s.nglevels > 0) + num_elems_per_level = obtain_tree_level_elems(s.nsteps, s.nglevels); + + if (s.gperf) { + + if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { + fprintf(stderr, "HDclock_gettime failed"); + TEST_ERROR; + } + } + + /* If generating nested groups */ + if (s.nglevels > 0) { + + /* for the recursive call, the groups under the root is treated as one level */ + wg_ret = gen_tree_struct(&s, s.nglevels + 1, num_elems_per_level, s.file); + if (wg_ret == false) { + printf("write nested group failed at group counter %u\n", grp_counter); + TEST_ERROR; + } + } + else { + for (step = 0; step < s.nsteps; step++) { + + dbgf(2, "writer: step %d\n", step); + wg_ret = group_operations(&s, step); + if (wg_ret == false) { + printf("write_group failed at step %d\n", step); + TEST_ERROR; + } + } + } + + if (s.gperf) { + + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { + + fprintf(stderr, "HDclock_gettime failed"); + TEST_ERROR; + } + + s.total_time = TIME_PASSED(start_time, end_time); + s.mean_time = s.total_time / s.nsteps; + s.mean_gc_time = s.total_gc_time / s.nsteps; + } + + if (H5Pclose(fapl) < 0) { + printf("H5Pclose failed\n"); + TEST_ERROR; + } + + if (H5Pclose(fcpl) < 0) { + printf("H5Pclose failed\n"); + TEST_ERROR; + } + + if (H5Sclose(s.one_by_one_sid) < 0) { + printf("H5Sclose failed\n"); + TEST_ERROR; + } + + if (s.gperf) { + + if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { + + fprintf(stderr, "HDclock_gettime failed"); + + TEST_ERROR; + } + } + + if (H5Fclose(s.file) < 0) { + printf("H5Fclose failed\n"); + TEST_ERROR; + } + + if (s.gperf) { + + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { + + fprintf(stderr, "HDclock_gettime failed"); + + TEST_ERROR; + } + + s.fc_total_time = TIME_PASSED(start_time, end_time); + } + + /* Performance statistics summary */ + if (s.gperf) { + + if (verbosity != 0) { + + fprintf(stdout, "\nPerformance Test Configuration: "); + if (s.use_vfd_swmr) + fprintf(stdout, " Using VFD SWMR \n"); + else + fprintf(stdout, " Not using VFD SWMR \n"); + + if (s.old_style_grp) + fprintf(stdout, " Groups: Created via the earlist file format(old-style) \n"); + else + fprintf(stdout, " Groups: Created via the latest file format(new-style) \n"); + + fprintf(stdout, "\n"); + + fprintf(stdout, "The length of a tick = %u\n", s.tick_len); + fprintf(stdout, "The maximum expected lag(in ticks)= %u\n", s.max_lag); + fprintf(stdout, "The page size(in bytes) = %u\n", s.ps); + fprintf(stdout, "The page buffer size(in bytes) = %u\n", s.pbs); + fprintf(stdout, "\n"); + fprintf(stdout, "Number of groups = %u\n", s.nsteps); + fprintf(stdout, "Group Nested levels = %u\n", s.nglevels); + fprintf(stdout, "Number of attributes = %u\n", s.num_attrs); + fprintf(stdout, "Number of element per attribute = 1\n"); + if (s.vlstr_test) + fprintf(stdout, "Attribute datatype is variable length string. \n"); + else if (s.filetype == H5T_STD_U32BE) + fprintf(stdout, "Attribute datatype is big-endian unsigned 32-bit integer.\n"); + else + fprintf(stdout, "Attribute datatype is native unsigned 32-bit integer.\n"); + + fprintf(stdout, "\n"); + fprintf(stdout, + "(If the nested level is 0, all the groups are created directly under the root.)\n\n"); + fprintf(stdout, "group creation maximum time =%lf\n", s.max_gc_time); + fprintf(stdout, "group creation minimum time =%lf\n", s.min_gc_time); + } + + fprintf(stdout, "group creation total time = %lf\n", s.total_gc_time); + fprintf(stdout, "group creation mean time(per group) = %lf\n", s.mean_gc_time); + fprintf(stdout, "group creation and attributes generation total time = %lf\n", s.total_time); + fprintf(stdout, "group creation and attributes generation mean time(per group) = %lf\n", s.mean_time); + fprintf(stdout, "H5Fcreate time = %lf\n", s.fo_total_time); + fprintf(stdout, "H5Fclose time = %lf\n", s.fc_total_time); + } + + return EXIT_SUCCESS; + +error: + H5E_BEGIN_TRY + { + H5Pclose(fapl); + H5Pclose(fcpl); + H5Sclose(s.one_by_one_sid); + H5Fclose(s.file); + } + H5E_END_TRY; + + return EXIT_FAILURE; +} + +#else /* H5_HAVE_WIN32_API */ + +int +main(void) +{ + HDfprintf(stderr, "Non-POSIX platform. Skipping.\n"); + return EXIT_SUCCESS; +} /* end main() */ + +#endif /* H5_HAVE_WIN32_API */ -- cgit v0.12 From 97638647034a0452bed5bc0b2eb951e41f5c92b0 Mon Sep 17 00:00:00 2001 From: myang6 Date: Fri, 15 Oct 2021 14:12:00 -0500 Subject: Clean up H5Fint.c, ready to implement the report function. --- src/H5Fint.c | 28 ---------------------------- test/vfd_swmr_common.c | 4 ++-- test/vfd_swmr_common.h | 2 +- test/vfd_swmr_log_writer.c | 2 +- 4 files changed, 4 insertions(+), 32 deletions(-) diff --git a/src/H5Fint.c b/src/H5Fint.c index 49c8561..e650878 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -108,8 +108,6 @@ htri_t use_locks_env_g = FAIL; /*******************/ /* Local Variables */ /*******************/ -hbool_t vfd_swmr_log_on; -FILE *vfd_swmr_log_file_ptr; /* Declare a free list to manage the H5F_t struct */ H5FL_DEFINE(H5F_t); @@ -1855,15 +1853,8 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) hbool_t ci_write = FALSE; /* Whether MDC CI write requested */ hbool_t file_create = FALSE; /* Creating a new file or not */ H5F_vfd_swmr_config_t *vfd_swmr_config_ptr = NULL; /* Points to VFD SMWR config info */ - //FILE * vfd_swmr_log_file_ptr = NULL; - //hbool_t vfd_swmr_log_on = FALSE; - struct timespec start_time, end_time; - double temp_time; - unsigned int elap_min,elap_sec,elap_msec; - H5F_t * ret_value = NULL; /* Actual return value */ - FUNC_ENTER_NOAPI(NULL) /* Get the file access property list, for future queries */ @@ -1878,17 +1869,8 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) if (H5P_get(a_plist, H5F_ACS_VFD_SWMR_CONFIG_NAME, vfd_swmr_config_ptr) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get VFD SWMR config info") - vfd_swmr_log_on = FALSE; /* When configured with VFD SWMR */ if (vfd_swmr_config_ptr->version) { - - if(HDstrlen(vfd_swmr_config_ptr->log_file_path) >0) - vfd_swmr_log_on = TRUE; - if( TRUE == vfd_swmr_log_on) { - clock_gettime(CLOCK_MONOTONIC,&start_time); - if((vfd_swmr_log_file_ptr=HDfopen(vfd_swmr_config_ptr->log_file_path,"w"))==NULL) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to create the metadata file") - } /* Verify that file access flags are consistent with VFD SWMR configuartion */ if ((flags & H5F_ACC_RDWR) && !vfd_swmr_config_ptr->writer) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "file access is writer but VFD SWMR config is reader") @@ -2239,16 +2221,6 @@ done: if (H5F__dest(file, FALSE) < 0) HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file") } - - if (TRUE == vfd_swmr_log_on) { - clock_gettime(CLOCK_MONOTONIC,&end_time); - temp_time = TOTAL_TIME_PASSED(start_time,end_time); - elap_min = TIME_PASSED_MIN(temp_time); - elap_sec = TIME_PASSED_SEC(temp_time,elap_min); - elap_msec = TIME_PASSED_MSEC(temp_time,elap_min,elap_sec); - HDfprintf(vfd_swmr_log_file_ptr,"FILE OPEN: %u m %u s %u ms, time - %lf seconds\n",elap_min,elap_sec,elap_msec,temp_time/1000); - HDfclose(vfd_swmr_log_file_ptr); - } if (vfd_swmr_config_ptr) H5MM_free(vfd_swmr_config_ptr); diff --git a/test/vfd_swmr_common.c b/test/vfd_swmr_common.c index f20f01e..d6750e0 100644 --- a/test/vfd_swmr_common.c +++ b/test/vfd_swmr_common.c @@ -370,7 +370,7 @@ init_vfd_swmr_config(H5F_vfd_swmr_config_t *config, uint32_t tick_len, uint32_t } /* init_vfd_swmr_config() */ void -init_vfd_swmr_config_log(H5F_vfd_swmr_config_t *config, const char *log_file_fmtstr,...) +init_vfd_swmr_log(H5F_vfd_swmr_config_t *config, const char *log_file_fmtstr,...) { va_list ap; @@ -379,7 +379,7 @@ init_vfd_swmr_config_log(H5F_vfd_swmr_config_t *config, const char *log_file_fmt evsnprintf(config->log_file_path, sizeof(config->log_file_path), log_file_fmtstr, ap); HDva_end(ap); -} /* init_vfd_swmr_config() */ +} /* init_vfd_swmr_log() */ /* Perform common VFD SWMR configuration on the file-access property list: diff --git a/test/vfd_swmr_common.h b/test/vfd_swmr_common.h index 8c51e0b..c011142 100644 --- a/test/vfd_swmr_common.h +++ b/test/vfd_swmr_common.h @@ -77,7 +77,7 @@ H5TEST_DLL void init_vfd_swmr_config(H5F_vfd_swmr_config_t *config, uint32_t tic hbool_t writer, hbool_t flush_raw_data, uint32_t md_pages_reserved, const char *md_file_fmtstr, ...) H5_ATTR_FORMAT(printf, 7, 8); -H5TEST_DLL void init_vfd_swmr_config_log(H5F_vfd_swmr_config_t *config, const char * log_file_fmtstr, ...) H5_ATTR_FORMAT(printf, 2, 3); +H5TEST_DLL void init_vfd_swmr_log(H5F_vfd_swmr_config_t *config, const char * log_file_fmtstr, ...) H5_ATTR_FORMAT(printf, 2, 3); H5TEST_DLL hid_t vfd_swmr_create_fcpl(H5F_fspace_strategy_t fs_strategy, hsize_t fs_page_size); diff --git a/test/vfd_swmr_log_writer.c b/test/vfd_swmr_log_writer.c index 1834d44..9ab50bd 100644 --- a/test/vfd_swmr_log_writer.c +++ b/test/vfd_swmr_log_writer.c @@ -2763,7 +2763,7 @@ main(int argc, char **argv) /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ init_vfd_swmr_config(&config, s.tick_len, s.max_lag, writer, FALSE, 128, "./group-shadow"); - init_vfd_swmr_config_log(&config, "./log-test"); + init_vfd_swmr_log(&config, "./log-test"); /* If old-style option is chosen, use the earliest file format(H5F_LIBVER_EARLIEST) * as the second parameter of H5Pset_libver_bound() that is called by -- cgit v0.12 From 519c50b981eb3d719c4e6a96a899689df0109195 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 15 Oct 2021 19:15:11 +0000 Subject: Committing clang-format changes --- src/H5FDvfd_swmr_private.h | 12 ++++++------ src/H5Pfapl.c | 2 +- test/vfd_swmr_common.c | 3 +-- test/vfd_swmr_common.h | 3 ++- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/H5FDvfd_swmr_private.h b/src/H5FDvfd_swmr_private.h index 280ea2f..56cb93e 100644 --- a/src/H5FDvfd_swmr_private.h +++ b/src/H5FDvfd_swmr_private.h @@ -57,14 +57,14 @@ typedef struct eot_queue_entry { TAILQ_ENTRY(eot_queue_entry) link; } eot_queue_entry_t; -#define TOTAL_TIME_PASSED(X, Y) \ +#define TOTAL_TIME_PASSED(X, Y) \ ((double)((Y.tv_sec - X.tv_sec) * 1000000000 + (Y.tv_nsec - X.tv_nsec))) / 1000000.0 -#define TIME_PASSED_MIN(X) (unsigned int)(X/60000) -#define TIME_PASSED_SEC(X,Y) (unsigned int)((X-Y*60000)/1000) -#define TIME_PASSED_MSEC(X,Y,Z) (unsigned int)(X-Y*60000-Z*1000) -//H5_DLLVAR extern hbool_t vfd_swmr_log_on; -//H5_DLLVAR extern FILE *vfd_swmr_log_file_ptr; +#define TIME_PASSED_MIN(X) (unsigned int)(X / 60000) +#define TIME_PASSED_SEC(X, Y) (unsigned int)((X - Y * 60000) / 1000) +#define TIME_PASSED_MSEC(X, Y, Z) (unsigned int)(X - Y * 60000 - Z * 1000) +// H5_DLLVAR extern hbool_t vfd_swmr_log_on; +// H5_DLLVAR extern FILE *vfd_swmr_log_file_ptr; H5_DLLVAR unsigned int vfd_swmr_api_entries_g; diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index 35bb09e..3b39f12 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -5711,7 +5711,7 @@ H5Pset_vfd_swmr_config(hid_t plist_id, H5F_vfd_swmr_config_t *config_ptr) 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) + 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 */ diff --git a/test/vfd_swmr_common.c b/test/vfd_swmr_common.c index d6750e0..2cae0be 100644 --- a/test/vfd_swmr_common.c +++ b/test/vfd_swmr_common.c @@ -370,7 +370,7 @@ init_vfd_swmr_config(H5F_vfd_swmr_config_t *config, uint32_t tick_len, uint32_t } /* init_vfd_swmr_config() */ void -init_vfd_swmr_log(H5F_vfd_swmr_config_t *config, const char *log_file_fmtstr,...) +init_vfd_swmr_log(H5F_vfd_swmr_config_t *config, const char *log_file_fmtstr, ...) { va_list ap; @@ -381,7 +381,6 @@ init_vfd_swmr_log(H5F_vfd_swmr_config_t *config, const char *log_file_fmtstr,... } /* init_vfd_swmr_log() */ - /* Perform common VFD SWMR configuration on the file-access property list: * configure page buffering, set reasonable VFD SWMR defaults. */ diff --git a/test/vfd_swmr_common.h b/test/vfd_swmr_common.h index c011142..f5981a5 100644 --- a/test/vfd_swmr_common.h +++ b/test/vfd_swmr_common.h @@ -77,7 +77,8 @@ H5TEST_DLL void init_vfd_swmr_config(H5F_vfd_swmr_config_t *config, uint32_t tic hbool_t writer, hbool_t flush_raw_data, uint32_t md_pages_reserved, const char *md_file_fmtstr, ...) H5_ATTR_FORMAT(printf, 7, 8); -H5TEST_DLL void init_vfd_swmr_log(H5F_vfd_swmr_config_t *config, const char * log_file_fmtstr, ...) H5_ATTR_FORMAT(printf, 2, 3); +H5TEST_DLL void init_vfd_swmr_log(H5F_vfd_swmr_config_t *config, const char *log_file_fmtstr, ...) + H5_ATTR_FORMAT(printf, 2, 3); H5TEST_DLL hid_t vfd_swmr_create_fcpl(H5F_fspace_strategy_t fs_strategy, hsize_t fs_page_size); -- cgit v0.12 From 217a7589836ecb8679aaeb68dbc3d9c7529ab84b Mon Sep 17 00:00:00 2001 From: myang6 Date: Fri, 15 Oct 2021 16:53:45 -0500 Subject: skeleton of the logging report function --- src/H5Fint.c | 3 +++ src/H5Fpkg.h | 5 +++++ src/H5Fvfd_swmr.c | 5 +++++ 3 files changed, 13 insertions(+) diff --git a/src/H5Fint.c b/src/H5Fint.c index e650878..3c4006b 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -2013,6 +2013,9 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) /* Short cuts */ shared = file->shared; +#if 1 /* Kent*/ + H5F_post_vfd_swrm_log_entry(file,0,NULL); +#endif lf = shared->lf; /* Set the file locking flag. If the file is already open, the file diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index c94c5af..b9cc015 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -469,6 +469,10 @@ struct H5F_shared_t { * manager */ + int vfd_swmr_log_fd; + hbool_t use_vfd_swmr_log; + double vfd_swmr_log_time_elapsed; + /* Delayed free space release doubly linked list */ shadow_defree_queue_t shadow_defrees; @@ -608,4 +612,5 @@ 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 */ +H5_DLL void* H5F_post_vfd_swrm_log_entry(H5F_t *f, int entry_type_code, char * body); #endif /* H5Fpkg_H */ diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index 69e03a0..f5e13ab 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -1886,3 +1886,8 @@ H5F_vfd_swmr_process_eot_queue(hbool_t entering_api) done: FUNC_LEAVE_NOAPI(ret_value) } + +void* H5F_post_vfd_swrm_log_entry(H5F_t *f, int entry_type_code, char * body) { + + +} -- cgit v0.12 From 9d48ca295f5352a9f084fda84e23dc43eebf1648 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 15 Oct 2021 21:58:04 +0000 Subject: Committing clang-format changes --- src/H5Fint.c | 4 ++-- src/H5Fpkg.h | 6 +++--- src/H5Fvfd_swmr.c | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/H5Fint.c b/src/H5Fint.c index 3c4006b..4a88b8c 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -2014,9 +2014,9 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) /* Short cuts */ shared = file->shared; #if 1 /* Kent*/ - H5F_post_vfd_swrm_log_entry(file,0,NULL); + H5F_post_vfd_swrm_log_entry(file, 0, NULL); #endif - 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. diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index b9cc015..ae9c037 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -469,9 +469,9 @@ struct H5F_shared_t { * manager */ - int vfd_swmr_log_fd; + int vfd_swmr_log_fd; hbool_t use_vfd_swmr_log; - double vfd_swmr_log_time_elapsed; + double vfd_swmr_log_time_elapsed; /* Delayed free space release doubly linked list */ shadow_defree_queue_t shadow_defrees; @@ -612,5 +612,5 @@ 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 */ -H5_DLL void* H5F_post_vfd_swrm_log_entry(H5F_t *f, int entry_type_code, char * body); +H5_DLL void *H5F_post_vfd_swrm_log_entry(H5F_t *f, int entry_type_code, char *body); #endif /* H5Fpkg_H */ diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index f5e13ab..5ef8260 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -1887,7 +1887,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } -void* H5F_post_vfd_swrm_log_entry(H5F_t *f, int entry_type_code, char * body) { - - +void * +H5F_post_vfd_swrm_log_entry(H5F_t *f, int entry_type_code, char *body) +{ } -- cgit v0.12 From a9670aaa117d7be70c2039bf0fcb7c12104c6ea3 Mon Sep 17 00:00:00 2001 From: myang6 Date: Mon, 18 Oct 2021 16:23:25 -0500 Subject: Add the log entry report function, also add logs for 'File open','File close' and 'EOT processing time' --- src/H5FDvfd_swmr_private.h | 24 +++++++++++++-------- src/H5Fint.c | 16 +++++++++++++- src/H5Fpkg.h | 8 +++---- src/H5Fvfd_swmr.c | 52 ++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 84 insertions(+), 16 deletions(-) diff --git a/src/H5FDvfd_swmr_private.h b/src/H5FDvfd_swmr_private.h index 56cb93e..6a35ec0 100644 --- a/src/H5FDvfd_swmr_private.h +++ b/src/H5FDvfd_swmr_private.h @@ -57,15 +57,6 @@ typedef struct eot_queue_entry { TAILQ_ENTRY(eot_queue_entry) link; } eot_queue_entry_t; -#define TOTAL_TIME_PASSED(X, Y) \ - ((double)((Y.tv_sec - X.tv_sec) * 1000000000 + (Y.tv_nsec - X.tv_nsec))) / 1000000.0 - -#define TIME_PASSED_MIN(X) (unsigned int)(X / 60000) -#define TIME_PASSED_SEC(X, Y) (unsigned int)((X - Y * 60000) / 1000) -#define TIME_PASSED_MSEC(X, Y, Z) (unsigned int)(X - Y * 60000 - Z * 1000) -// H5_DLLVAR extern hbool_t vfd_swmr_log_on; -// H5_DLLVAR extern FILE *vfd_swmr_log_file_ptr; - H5_DLLVAR unsigned int vfd_swmr_api_entries_g; /* The head of the EOT queue */ @@ -93,4 +84,19 @@ H5_DLL herr_t H5F_vfd_swmr_insert_entry_eot(struct H5F_t *f); H5_DLL void H5F_vfd_swmr_update_entry_eot(eot_queue_entry_t *); H5_DLL herr_t H5F_dump_eot_queue(void); + +/***************************************/ +/* Log Macros and Functions */ +/***************************************/ + +#define TOTAL_TIME_PASSED(X, Y) \ + ((double)((Y.tv_sec - X.tv_sec) * 1000000000 + (Y.tv_nsec - X.tv_nsec))) / 1000000.0 +#define TIME_PASSED_MIN(X) (unsigned int)(X / 60000) +#define TIME_PASSED_SEC(X, Y) (unsigned int)((X - Y * 60000) / 1000) +#define TIME_PASSED_MSEC(X, Y, Z) (unsigned int)(X - Y * 60000 - Z * 1000) + +/* Add more tags */ +static const char *H5Fvfd_swmr_log_tags[] = { "FILE_OPEN", "FILE_CLOSE", "EOT_TRIGGER_TIME", + "EOT_PROCESSING_TIME", "EOT_META_FILE_INDEX"}; + #endif /* H5FDvfd_swmr_private_H */ diff --git a/src/H5Fint.c b/src/H5Fint.c index 4a88b8c..9d739b7 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -2014,7 +2014,18 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) /* Short cuts */ shared = file->shared; #if 1 /* Kent*/ - H5F_post_vfd_swrm_log_entry(file, 0, NULL); + if (vfd_swmr_config_ptr->version) { + + 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(HDclock_gettime(CLOCK_MONOTONIC, &(shared->vfd_swmr_log_start_time))<0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get time via clock_gettime"); + } + } #endif lf = shared->lf; @@ -2224,6 +2235,9 @@ done: if (H5F__dest(file, FALSE) < 0) HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file") } +#if 1 /*KENT*/ + H5F_post_vfd_swrm_log_entry(file, 0, "File open ends"); +#endif if (vfd_swmr_config_ptr) H5MM_free(vfd_swmr_config_ptr); diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index ae9c037..3ab0cd3 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -469,9 +469,9 @@ struct H5F_shared_t { * manager */ - int vfd_swmr_log_fd; - hbool_t use_vfd_swmr_log; - double vfd_swmr_log_time_elapsed; + FILE* vfd_swmr_log_file_ptr; + hbool_t vfd_swmr_log_on; + struct timespec vfd_swmr_log_start_time; /* Delayed free space release doubly linked list */ shadow_defree_queue_t shadow_defrees; @@ -612,5 +612,5 @@ 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 */ -H5_DLL void *H5F_post_vfd_swrm_log_entry(H5F_t *f, int entry_type_code, char *body); +H5_DLL herr_t H5F_post_vfd_swrm_log_entry(H5F_t *f, int entry_type_code, char *body); #endif /* H5Fpkg_H */ diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index 5ef8260..b549eeb 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -157,7 +157,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; @@ -277,6 +276,7 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing) FUNC_ENTER_NOAPI(FAIL) + HDassert(shared->vfd_swmr_writer); HDassert(shared->vfd_swmr_md_fd >= 0); @@ -320,6 +320,12 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing) HDONE_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to update end of tick"); } done: + + H5F_post_vfd_swrm_log_entry(f, 1, "File close ends"); + + if (shared->vfd_swmr_log_on) { + HDfclose(shared->vfd_swmr_log_file_ptr); + } FUNC_LEAVE_NOAPI(ret_value) } @@ -628,10 +634,13 @@ H5F_vfd_swmr_writer__prep_for_flush_or_close(H5F_t *f) FUNC_ENTER_NOAPI(FAIL) + HDassert(shared->vfd_swmr); HDassert(shared->vfd_swmr_writer); HDassert(shared->page_buf); + H5F_post_vfd_swrm_log_entry(f, 1, "File close starts"); + /* since we are about to flush the page buffer, force and end of * tick so as to avoid attempts to flush entries on the page buffer * tick list that were modified during the current tick. @@ -755,12 +764,21 @@ 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; + struct timespec start_time,end_time; + unsigned int temp_time; + char* log_msg; + FUNC_ENTER_NOAPI(FAIL) HDassert(shared); HDassert(shared->page_buf); HDassert(shared->vfd_swmr_writer); + if(f->shared->vfd_swmr_log_on == true) { + H5F_post_vfd_swrm_log_entry(f, 3, "EOT gets started"); + if(HDclock_gettime(CLOCK_MONOTONIC, &start_time)<0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); + } if (!vfd_swmr_writer_may_increase_tick_to(shared->tick_num + 1, wait_for_reader)) goto update_eot; @@ -883,6 +901,15 @@ update_eot: HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to insert entry into the EOT queue") done: + if(f->shared->vfd_swmr_log_on == true) { + if(HDclock_gettime(CLOCK_MONOTONIC, &end_time)<0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); + log_msg = HDmalloc(48); + temp_time = (unsigned int) (TOTAL_TIME_PASSED(start_time, end_time)); + HDsprintf(log_msg,"Writer time is %u milliseconds",temp_time); + H5F_post_vfd_swrm_log_entry(f, 3, log_msg); + HDfree(log_msg); + } FUNC_LEAVE_NOAPI(ret_value) } @@ -1887,7 +1914,28 @@ done: FUNC_LEAVE_NOAPI(ret_value) } -void * +herr_t H5F_post_vfd_swrm_log_entry(H5F_t *f, int entry_type_code, char *body) { + herr_t ret_value = SUCCEED; + double temp_time; + struct timespec current_time; + unsigned int elap_min, elap_sec, elap_msec; + + FUNC_ENTER_NOAPI(FAIL) + if(f->shared->vfd_swmr_log_on == false) + HGOTO_DONE(TRUE) + if(HDclock_gettime(CLOCK_MONOTONIC, ¤t_time)<0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); + temp_time = TOTAL_TIME_PASSED(f->shared->vfd_swmr_log_start_time, current_time); + elap_min = TIME_PASSED_MIN(temp_time); + elap_sec = TIME_PASSED_SEC(temp_time, elap_min); + elap_msec = TIME_PASSED_MSEC(temp_time, elap_min, elap_sec); + + /* TODO: add a check for the range of entry_type_code to separate debug mode from the production mode.*/ + HDfprintf(f->shared->vfd_swmr_log_file_ptr, "%s: %u m %u s %u ms, Content - %s\n", + H5Fvfd_swmr_log_tags[entry_type_code],elap_min,elap_sec, elap_msec, body); + +done: + FUNC_LEAVE_NOAPI(ret_value) } -- cgit v0.12 From cbf5ca9147e229373d8ee75df3f60d1f01211b2a Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 18 Oct 2021 21:25:39 +0000 Subject: Committing clang-format changes --- src/H5FDvfd_swmr_private.h | 5 ++--- src/H5Fint.c | 8 ++++---- src/H5Fpkg.h | 8 ++++---- src/H5Fvfd_swmr.c | 46 ++++++++++++++++++++++------------------------ 4 files changed, 32 insertions(+), 35 deletions(-) diff --git a/src/H5FDvfd_swmr_private.h b/src/H5FDvfd_swmr_private.h index 6a35ec0..f9b8f15 100644 --- a/src/H5FDvfd_swmr_private.h +++ b/src/H5FDvfd_swmr_private.h @@ -84,7 +84,6 @@ H5_DLL herr_t H5F_vfd_swmr_insert_entry_eot(struct H5F_t *f); H5_DLL void H5F_vfd_swmr_update_entry_eot(eot_queue_entry_t *); H5_DLL herr_t H5F_dump_eot_queue(void); - /***************************************/ /* Log Macros and Functions */ /***************************************/ @@ -96,7 +95,7 @@ H5_DLL herr_t H5F_dump_eot_queue(void); #define TIME_PASSED_MSEC(X, Y, Z) (unsigned int)(X - Y * 60000 - Z * 1000) /* Add more tags */ -static const char *H5Fvfd_swmr_log_tags[] = { "FILE_OPEN", "FILE_CLOSE", "EOT_TRIGGER_TIME", - "EOT_PROCESSING_TIME", "EOT_META_FILE_INDEX"}; +static const char *H5Fvfd_swmr_log_tags[] = {"FILE_OPEN", "FILE_CLOSE", "EOT_TRIGGER_TIME", + "EOT_PROCESSING_TIME", "EOT_META_FILE_INDEX"}; #endif /* H5FDvfd_swmr_private_H */ diff --git a/src/H5Fint.c b/src/H5Fint.c index 9d739b7..a50c38c 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -2017,12 +2017,12 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) if (vfd_swmr_config_ptr->version) { if (HDstrlen(vfd_swmr_config_ptr->log_file_path) > 0) - shared->vfd_swmr_log_on = TRUE; + 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) + 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(HDclock_gettime(CLOCK_MONOTONIC, &(shared->vfd_swmr_log_start_time))<0) + if (HDclock_gettime(CLOCK_MONOTONIC, &(shared->vfd_swmr_log_start_time)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get time via clock_gettime"); } } @@ -2237,7 +2237,7 @@ done: } #if 1 /*KENT*/ H5F_post_vfd_swrm_log_entry(file, 0, "File open ends"); -#endif +#endif if (vfd_swmr_config_ptr) H5MM_free(vfd_swmr_config_ptr); diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 3ab0cd3..5cb1ecb 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -469,9 +469,9 @@ struct H5F_shared_t { * manager */ - FILE* vfd_swmr_log_file_ptr; - hbool_t vfd_swmr_log_on; - struct timespec vfd_swmr_log_start_time; + FILE * vfd_swmr_log_file_ptr; + hbool_t vfd_swmr_log_on; + struct timespec vfd_swmr_log_start_time; /* Delayed free space release doubly linked list */ shadow_defree_queue_t shadow_defrees; @@ -612,5 +612,5 @@ 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 */ -H5_DLL herr_t H5F_post_vfd_swrm_log_entry(H5F_t *f, int entry_type_code, char *body); +H5_DLL herr_t H5F_post_vfd_swrm_log_entry(H5F_t *f, int entry_type_code, char *body); #endif /* H5Fpkg_H */ diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index b549eeb..f746090 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -276,7 +276,6 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing) FUNC_ENTER_NOAPI(FAIL) - HDassert(shared->vfd_swmr_writer); HDassert(shared->vfd_swmr_md_fd >= 0); @@ -320,11 +319,11 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing) HDONE_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to update end of tick"); } done: - + H5F_post_vfd_swrm_log_entry(f, 1, "File close ends"); if (shared->vfd_swmr_log_on) { - HDfclose(shared->vfd_swmr_log_file_ptr); + HDfclose(shared->vfd_swmr_log_file_ptr); } FUNC_LEAVE_NOAPI(ret_value) } @@ -634,7 +633,6 @@ H5F_vfd_swmr_writer__prep_for_flush_or_close(H5F_t *f) FUNC_ENTER_NOAPI(FAIL) - HDassert(shared->vfd_swmr); HDassert(shared->vfd_swmr_writer); HDassert(shared->page_buf); @@ -764,9 +762,9 @@ 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; - struct timespec start_time,end_time; - unsigned int temp_time; - char* log_msg; + struct timespec start_time, end_time; + unsigned int temp_time; + char * log_msg; FUNC_ENTER_NOAPI(FAIL) @@ -774,9 +772,9 @@ H5F_vfd_swmr_writer_end_of_tick(H5F_t *f, hbool_t wait_for_reader) HDassert(shared->page_buf); HDassert(shared->vfd_swmr_writer); - if(f->shared->vfd_swmr_log_on == true) { - H5F_post_vfd_swrm_log_entry(f, 3, "EOT gets started"); - if(HDclock_gettime(CLOCK_MONOTONIC, &start_time)<0) + if (f->shared->vfd_swmr_log_on == true) { + H5F_post_vfd_swrm_log_entry(f, 3, "EOT gets started"); + if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); } if (!vfd_swmr_writer_may_increase_tick_to(shared->tick_num + 1, wait_for_reader)) @@ -901,13 +899,13 @@ update_eot: HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to insert entry into the EOT queue") done: - if(f->shared->vfd_swmr_log_on == true) { - if(HDclock_gettime(CLOCK_MONOTONIC, &end_time)<0) + if (f->shared->vfd_swmr_log_on == true) { + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); - log_msg = HDmalloc(48); - temp_time = (unsigned int) (TOTAL_TIME_PASSED(start_time, end_time)); - HDsprintf(log_msg,"Writer time is %u milliseconds",temp_time); - H5F_post_vfd_swrm_log_entry(f, 3, log_msg); + log_msg = HDmalloc(48); + temp_time = (unsigned int)(TOTAL_TIME_PASSED(start_time, end_time)); + HDsprintf(log_msg, "Writer time is %u milliseconds", temp_time); + H5F_post_vfd_swrm_log_entry(f, 3, log_msg); HDfree(log_msg); } FUNC_LEAVE_NOAPI(ret_value) @@ -1914,18 +1912,18 @@ done: FUNC_LEAVE_NOAPI(ret_value) } -herr_t +herr_t H5F_post_vfd_swrm_log_entry(H5F_t *f, int entry_type_code, char *body) { - herr_t ret_value = SUCCEED; - double temp_time; - struct timespec current_time; + herr_t ret_value = SUCCEED; + double temp_time; + struct timespec current_time; unsigned int elap_min, elap_sec, elap_msec; FUNC_ENTER_NOAPI(FAIL) - if(f->shared->vfd_swmr_log_on == false) + if (f->shared->vfd_swmr_log_on == false) HGOTO_DONE(TRUE) - if(HDclock_gettime(CLOCK_MONOTONIC, ¤t_time)<0) + if (HDclock_gettime(CLOCK_MONOTONIC, ¤t_time) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); temp_time = TOTAL_TIME_PASSED(f->shared->vfd_swmr_log_start_time, current_time); elap_min = TIME_PASSED_MIN(temp_time); @@ -1933,8 +1931,8 @@ H5F_post_vfd_swrm_log_entry(H5F_t *f, int entry_type_code, char *body) elap_msec = TIME_PASSED_MSEC(temp_time, elap_min, elap_sec); /* TODO: add a check for the range of entry_type_code to separate debug mode from the production mode.*/ - HDfprintf(f->shared->vfd_swmr_log_file_ptr, "%s: %u m %u s %u ms, Content - %s\n", - H5Fvfd_swmr_log_tags[entry_type_code],elap_min,elap_sec, elap_msec, body); + HDfprintf(f->shared->vfd_swmr_log_file_ptr, "%s: %u m %u s %u ms, Content - %s\n", + H5Fvfd_swmr_log_tags[entry_type_code], elap_min, elap_sec, elap_msec, body); done: FUNC_LEAVE_NOAPI(ret_value) -- cgit v0.12 From 383fd055affb3e003828fc42fba726583ebeebca Mon Sep 17 00:00:00 2001 From: myang6 Date: Mon, 18 Oct 2021 17:17:26 -0500 Subject: Make sure to check the file point. --- src/H5Fvfd_swmr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index b549eeb..1b9650f 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -1923,6 +1923,8 @@ H5F_post_vfd_swrm_log_entry(H5F_t *f, int entry_type_code, char *body) unsigned int elap_min, elap_sec, elap_msec; FUNC_ENTER_NOAPI(FAIL) + if(f==NULL) + HGOTO_DONE(TRUE) if(f->shared->vfd_swmr_log_on == false) HGOTO_DONE(TRUE) if(HDclock_gettime(CLOCK_MONOTONIC, ¤t_time)<0) -- cgit v0.12 From 148606eff814d84d044a268ab2703bef23c305f1 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 18 Oct 2021 22:42:32 +0000 Subject: Committing clang-format changes --- src/H5Fvfd_swmr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index c938014..bfa2c64 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -1921,7 +1921,7 @@ H5F_post_vfd_swrm_log_entry(H5F_t *f, int entry_type_code, char *body) unsigned int elap_min, elap_sec, elap_msec; FUNC_ENTER_NOAPI(FAIL) - if (f==NULL) + if (f == NULL) HGOTO_DONE(TRUE) if (f->shared->vfd_swmr_log_on == false) HGOTO_DONE(TRUE) -- cgit v0.12 From 25bcb8e953772b21e46426655fb6a6f0f7edc1f5 Mon Sep 17 00:00:00 2001 From: Muqun Yang Date: Mon, 18 Oct 2021 18:20:56 -0500 Subject: Revise the H5Fopen log test. --- src/H5Fint.c | 6 +++--- src/H5Fvfd_swmr.c | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/H5Fint.c b/src/H5Fint.c index a50c38c..9c4a143 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -2225,6 +2225,9 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) ret_value = file; done: +#if 1 /*KENT*/ + H5F_post_vfd_swrm_log_entry(file, 0, "File open ends"); +#endif if ((NULL == ret_value) && file) { if (file->shared->root_grp && file->shared->nrefs == 1) { if (H5AC_expunge_tag_type_metadata(file, H5G_oloc(file->shared->root_grp)->addr, H5AC_OHDR_ID, @@ -2235,9 +2238,6 @@ done: if (H5F__dest(file, FALSE) < 0) HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file") } -#if 1 /*KENT*/ - H5F_post_vfd_swrm_log_entry(file, 0, "File open ends"); -#endif if (vfd_swmr_config_ptr) H5MM_free(vfd_swmr_config_ptr); diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index c938014..77f5019 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -1923,6 +1923,8 @@ H5F_post_vfd_swrm_log_entry(H5F_t *f, int entry_type_code, char *body) FUNC_ENTER_NOAPI(FAIL) if (f==NULL) HGOTO_DONE(TRUE) + else if(f->shared==NULL) + HGOTO_DONE(TRUE) if (f->shared->vfd_swmr_log_on == false) HGOTO_DONE(TRUE) if (HDclock_gettime(CLOCK_MONOTONIC, ¤t_time) < 0) -- cgit v0.12 From 9f3adc68aa94405652abbe146336b0019b57fac5 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 18 Oct 2021 23:25:06 +0000 Subject: Committing clang-format changes --- src/H5Fvfd_swmr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index 80d8040..378fd82 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -1923,7 +1923,7 @@ H5F_post_vfd_swrm_log_entry(H5F_t *f, int entry_type_code, char *body) FUNC_ENTER_NOAPI(FAIL) if (f == NULL) HGOTO_DONE(TRUE) - else if(f->shared==NULL) + else if (f->shared == NULL) HGOTO_DONE(TRUE) if (f->shared->vfd_swmr_log_on == false) HGOTO_DONE(TRUE) -- cgit v0.12 From c17ec107bb9d3afd99774e66fba2a6c8f8ca5142 Mon Sep 17 00:00:00 2001 From: myang6 Date: Wed, 20 Oct 2021 08:59:16 -0500 Subject: Still need to support the NULL pointer in the log report function. --- src/H5Fvfd_swmr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index 378fd82..ee9ccda 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -1921,6 +1921,10 @@ H5F_post_vfd_swrm_log_entry(H5F_t *f, int entry_type_code, char *body) unsigned int elap_min, elap_sec, elap_msec; FUNC_ENTER_NOAPI(FAIL) +#if 0 + HDassert(f); + HDassert(f->shared); +#endif if (f == NULL) HGOTO_DONE(TRUE) else if (f->shared == NULL) -- cgit v0.12 From 56e0e6ad352c895e35718cec51d346fa45430382 Mon Sep 17 00:00:00 2001 From: myang6 Date: Mon, 25 Oct 2021 13:12:23 -0500 Subject: add macro, need to debug an error caused by using the macro --- src/H5FDvfd_swmr_private.h | 5 +++-- src/H5Fint.c | 5 +++-- src/H5Fpkg.h | 9 ++++++++- src/H5Fvfd_swmr.c | 31 ++++++++++++++++++++----------- 4 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/H5FDvfd_swmr_private.h b/src/H5FDvfd_swmr_private.h index f9b8f15..f040af3 100644 --- a/src/H5FDvfd_swmr_private.h +++ b/src/H5FDvfd_swmr_private.h @@ -89,13 +89,14 @@ H5_DLL herr_t H5F_dump_eot_queue(void); /***************************************/ #define TOTAL_TIME_PASSED(X, Y) \ - ((double)((Y.tv_sec - X.tv_sec) * 1000000000 + (Y.tv_nsec - X.tv_nsec))) / 1000000.0 + ((double)((Y.tv_sec - X.tv_sec) * 1000000000 + (Y.tv_nsec - X.tv_nsec))) / 1000000000.0 #define TIME_PASSED_MIN(X) (unsigned int)(X / 60000) #define TIME_PASSED_SEC(X, Y) (unsigned int)((X - Y * 60000) / 1000) #define TIME_PASSED_MSEC(X, Y, Z) (unsigned int)(X - Y * 60000 - Z * 1000) /* Add more tags */ -static const char *H5Fvfd_swmr_log_tags[] = {"FILE_OPEN", "FILE_CLOSE", "EOT_TRIGGER_TIME", +static const char *H5Fvfd_swmr_log_tags[] = {"FILE_OPEN", + "FILE_CLOSE", "EOT_TRIGGER_TIME", "EOT_PROCESSING_TIME", "EOT_META_FILE_INDEX"}; #endif /* H5FDvfd_swmr_private_H */ diff --git a/src/H5Fint.c b/src/H5Fint.c index 9c4a143..b681c23 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -2224,10 +2224,11 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) /* Success */ ret_value = file; -done: #if 1 /*KENT*/ - H5F_post_vfd_swrm_log_entry(file, 0, "File open ends"); + //H5F_post_vfd_swmr_log_entry(file, 0, "File open ends"); + H5F_POST_VFD_SWMR_LOG_ENTRY(file, 0, "File open ends") #endif +done: if ((NULL == ret_value) && file) { if (file->shared->root_grp && file->shared->nrefs == 1) { if (H5AC_expunge_tag_type_metadata(file, H5G_oloc(file->shared->root_grp)->addr, H5AC_OHDR_ID, diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 5cb1ecb..7b93c72 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -612,5 +612,12 @@ 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 */ -H5_DLL herr_t H5F_post_vfd_swrm_log_entry(H5F_t *f, int entry_type_code, char *body); +#define H5F_POST_VFD_SWMR_LOG_ENTRY(fp,entry_type_code,body) \ +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,body); + + +H5_DLL herr_t H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *body); #endif /* H5Fpkg_H */ diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index ee9ccda..9031176 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -318,10 +318,11 @@ 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(H5F_post_vfd_swmr_log_entry(f, 1, "File close ends")<0) + // HDONE_ERROR(H5E_FILE, H5E_LOGGING, FAIL, "Fail to report VFD SMWR logging info."); + H5F_POST_VFD_SWMR_LOG_ENTRY(f, 1, "File close ends") done: - H5F_post_vfd_swrm_log_entry(f, 1, "File close ends"); - if (shared->vfd_swmr_log_on) { HDfclose(shared->vfd_swmr_log_file_ptr); } @@ -637,7 +638,7 @@ H5F_vfd_swmr_writer__prep_for_flush_or_close(H5F_t *f) HDassert(shared->vfd_swmr_writer); HDassert(shared->page_buf); - H5F_post_vfd_swrm_log_entry(f, 1, "File close starts"); + H5F_post_vfd_swmr_log_entry(f, 1, "File close starts"); /* since we are about to flush the page buffer, force and end of * tick so as to avoid attempts to flush entries on the page buffer @@ -773,7 +774,7 @@ H5F_vfd_swmr_writer_end_of_tick(H5F_t *f, hbool_t wait_for_reader) HDassert(shared->vfd_swmr_writer); if (f->shared->vfd_swmr_log_on == true) { - H5F_post_vfd_swrm_log_entry(f, 3, "EOT gets started"); + H5F_post_vfd_swmr_log_entry(f, 3, "EOT gets started"); if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); } @@ -903,9 +904,9 @@ done: if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); log_msg = HDmalloc(48); - temp_time = (unsigned int)(TOTAL_TIME_PASSED(start_time, end_time)); + temp_time = (unsigned int)(TOTAL_TIME_PASSED(start_time, end_time)*1000); HDsprintf(log_msg, "Writer time is %u milliseconds", temp_time); - H5F_post_vfd_swrm_log_entry(f, 3, log_msg); + H5F_post_vfd_swmr_log_entry(f, 3, log_msg); HDfree(log_msg); } FUNC_LEAVE_NOAPI(ret_value) @@ -1913,7 +1914,7 @@ done: } herr_t -H5F_post_vfd_swrm_log_entry(H5F_t *f, int entry_type_code, char *body) +H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *body) { herr_t ret_value = SUCCEED; double temp_time; @@ -1925,13 +1926,15 @@ H5F_post_vfd_swrm_log_entry(H5F_t *f, int entry_type_code, char *body) HDassert(f); HDassert(f->shared); #endif +#if 0 if (f == NULL) - HGOTO_DONE(TRUE) + HGOTO_DONE(SUCCEED) else if (f->shared == NULL) - HGOTO_DONE(TRUE) + HGOTO_DONE(SUCCEED) if (f->shared->vfd_swmr_log_on == false) - HGOTO_DONE(TRUE) - if (HDclock_gettime(CLOCK_MONOTONIC, ¤t_time) < 0) + HGOTO_DONE(SUCCEED) +#endif + if (HDclock_gettime(CLOCK_MONOTONIC, ¤t_time) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); temp_time = TOTAL_TIME_PASSED(f->shared->vfd_swmr_log_start_time, current_time); elap_min = TIME_PASSED_MIN(temp_time); @@ -1939,9 +1942,15 @@ H5F_post_vfd_swrm_log_entry(H5F_t *f, int entry_type_code, char *body) elap_msec = TIME_PASSED_MSEC(temp_time, elap_min, elap_sec); /* TODO: add a check for the range of entry_type_code to separate debug mode from the production mode.*/ +#if 0 HDfprintf(f->shared->vfd_swmr_log_file_ptr, "%s: %u m %u s %u ms, Content - %s\n", H5Fvfd_swmr_log_tags[entry_type_code], elap_min, elap_sec, elap_msec, body); +#endif + + HDfprintf(f->shared->vfd_swmr_log_file_ptr, "%-25s: %.3lf s: %s\n", + H5Fvfd_swmr_log_tags[entry_type_code], temp_time, body); done: + //return ret_value; FUNC_LEAVE_NOAPI(ret_value) } -- cgit v0.12 From d89fb6e09c0e4c8470a919082ac292c8d23c8fab Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 25 Oct 2021 18:14:29 +0000 Subject: Committing clang-format changes --- src/H5FDvfd_swmr_private.h | 3 +-- src/H5Fint.c | 2 +- src/H5Fpkg.h | 11 +++++------ src/H5Fvfd_swmr.c | 12 ++++++------ 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/H5FDvfd_swmr_private.h b/src/H5FDvfd_swmr_private.h index f040af3..bc5c177 100644 --- a/src/H5FDvfd_swmr_private.h +++ b/src/H5FDvfd_swmr_private.h @@ -95,8 +95,7 @@ H5_DLL herr_t H5F_dump_eot_queue(void); #define TIME_PASSED_MSEC(X, Y, Z) (unsigned int)(X - Y * 60000 - Z * 1000) /* Add more tags */ -static const char *H5Fvfd_swmr_log_tags[] = {"FILE_OPEN", - "FILE_CLOSE", "EOT_TRIGGER_TIME", +static const char *H5Fvfd_swmr_log_tags[] = {"FILE_OPEN", "FILE_CLOSE", "EOT_TRIGGER_TIME", "EOT_PROCESSING_TIME", "EOT_META_FILE_INDEX"}; #endif /* H5FDvfd_swmr_private_H */ diff --git a/src/H5Fint.c b/src/H5Fint.c index b681c23..04e913e 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -2225,7 +2225,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) ret_value = file; #if 1 /*KENT*/ - //H5F_post_vfd_swmr_log_entry(file, 0, "File open ends"); + // H5F_post_vfd_swmr_log_entry(file, 0, "File open ends"); H5F_POST_VFD_SWMR_LOG_ENTRY(file, 0, "File open ends") #endif done: diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 7b93c72..cf68c8c 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -612,12 +612,11 @@ 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 */ -#define H5F_POST_VFD_SWMR_LOG_ENTRY(fp,entry_type_code,body) \ -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,body); - +#define H5F_POST_VFD_SWMR_LOG_ENTRY(fp, entry_type_code, body) \ + 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, body); H5_DLL herr_t H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *body); #endif /* H5Fpkg_H */ diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index 9031176..1bfe65b 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -318,7 +318,7 @@ 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(H5F_post_vfd_swmr_log_entry(f, 1, "File close ends")<0) + // if(H5F_post_vfd_swmr_log_entry(f, 1, "File close ends")<0) // HDONE_ERROR(H5E_FILE, H5E_LOGGING, FAIL, "Fail to report VFD SMWR logging info."); H5F_POST_VFD_SWMR_LOG_ENTRY(f, 1, "File close ends") done: @@ -904,7 +904,7 @@ done: if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); log_msg = HDmalloc(48); - temp_time = (unsigned int)(TOTAL_TIME_PASSED(start_time, end_time)*1000); + temp_time = (unsigned int)(TOTAL_TIME_PASSED(start_time, end_time) * 1000); HDsprintf(log_msg, "Writer time is %u milliseconds", temp_time); H5F_post_vfd_swmr_log_entry(f, 3, log_msg); HDfree(log_msg); @@ -1934,7 +1934,7 @@ H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *body) if (f->shared->vfd_swmr_log_on == false) HGOTO_DONE(SUCCEED) #endif - if (HDclock_gettime(CLOCK_MONOTONIC, ¤t_time) < 0) + if (HDclock_gettime(CLOCK_MONOTONIC, ¤t_time) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); temp_time = TOTAL_TIME_PASSED(f->shared->vfd_swmr_log_start_time, current_time); elap_min = TIME_PASSED_MIN(temp_time); @@ -1947,10 +1947,10 @@ H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *body) H5Fvfd_swmr_log_tags[entry_type_code], elap_min, elap_sec, elap_msec, body); #endif - HDfprintf(f->shared->vfd_swmr_log_file_ptr, "%-25s: %.3lf s: %s\n", - H5Fvfd_swmr_log_tags[entry_type_code], temp_time, body); + HDfprintf(f->shared->vfd_swmr_log_file_ptr, "%-25s: %.3lf s: %s\n", H5Fvfd_swmr_log_tags[entry_type_code], + temp_time, body); done: - //return ret_value; + // return ret_value; FUNC_LEAVE_NOAPI(ret_value) } -- cgit v0.12 From 09e891477e3946e48d2216e06aca150ad5f2ddb3 Mon Sep 17 00:00:00 2001 From: myang6 Date: Mon, 25 Oct 2021 14:51:28 -0500 Subject: Update comments, formats etc. --- src/H5FDvfd_swmr_private.h | 23 +++++++++++++++++++++-- src/H5Fint.c | 11 ++++++----- src/H5Fpkg.h | 4 ++++ src/H5Fvfd_swmr.c | 34 +++++----------------------------- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/H5FDvfd_swmr_private.h b/src/H5FDvfd_swmr_private.h index bc5c177..333bcc7 100644 --- a/src/H5FDvfd_swmr_private.h +++ b/src/H5FDvfd_swmr_private.h @@ -88,14 +88,33 @@ H5_DLL herr_t H5F_dump_eot_queue(void); /* Log Macros and Functions */ /***************************************/ +/* VFD SWMR Helper macros to calcuate the elapsed time */ +/* The total time in seconds */ #define TOTAL_TIME_PASSED(X, Y) \ ((double)((Y.tv_sec - X.tv_sec) * 1000000000 + (Y.tv_nsec - X.tv_nsec))) / 1000000000.0 + +/* #define TIME_PASSED_MIN(X) (unsigned int)(X / 60000) #define TIME_PASSED_SEC(X, Y) (unsigned int)((X - Y * 60000) / 1000) #define TIME_PASSED_MSEC(X, Y, Z) (unsigned int)(X - Y * 60000 - Z * 1000) +*/ /* Add more tags */ -static const char *H5Fvfd_swmr_log_tags[] = {"FILE_OPEN", "FILE_CLOSE", "EOT_TRIGGER_TIME", - "EOT_PROCESSING_TIME", "EOT_META_FILE_INDEX"}; +/* The VFD SMWR Log tags. Note this array of string is used to generate the + * entry tag by the log reporting function H5F_POST_VFD_SWMR_LOG_ENTRY. + * 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, 3, log_msg) will put the log_msg attached to + * the entry tag "EOT_PROCESSING_TIME". + */ +/* clang-format off */ +/* The entry code number is listed in the comment for convenience. */ +static const char *H5Fvfd_swmr_log_tags[] = { + "FILE_OPEN", /* 0 */ + "FILE_CLOSE", /* 1 */ + "EOT_TRIGGER_TIME", /* 2 */ + "EOT_PROCESSING_TIME", /* 3 */ + "EOT_META_FILE_INDEX" /* 4 */ + }; +/* clang-format on */ #endif /* H5FDvfd_swmr_private_H */ diff --git a/src/H5Fint.c b/src/H5Fint.c index 04e913e..f6b4e1a 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -2013,9 +2013,10 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) /* Short cuts */ shared = file->shared; -#if 1 /* Kent*/ + + /* Set up the VFD SWMR LOG file */ + /* Kent*/ if (vfd_swmr_config_ptr->version) { - if (HDstrlen(vfd_swmr_config_ptr->log_file_path) > 0) shared->vfd_swmr_log_on = TRUE; if (TRUE == shared->vfd_swmr_log_on) { @@ -2026,7 +2027,8 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get time via clock_gettime"); } } -#endif + /* End of Kent */ + lf = shared->lf; /* Set the file locking flag. If the file is already open, the file @@ -2224,8 +2226,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) /* Success */ ret_value = file; -#if 1 /*KENT*/ - // H5F_post_vfd_swmr_log_entry(file, 0, "File open ends"); +#if 1 /*Kent: write to the log file when H5F_open ends. Tested, now comment out.*/ H5F_POST_VFD_SWMR_LOG_ENTRY(file, 0, "File open ends") #endif done: diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index cf68c8c..5eaee3c 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -612,6 +612,10 @@ 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 */ +/* The first argument 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 which involves + * the test of a non-existing HDF5 file. */ #define H5F_POST_VFD_SWMR_LOG_ENTRY(fp, entry_type_code, body) \ if (fp != NULL) \ if (fp->shared != NULL) \ diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index 1bfe65b..3bc405f 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -318,9 +318,9 @@ 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(H5F_post_vfd_swmr_log_entry(f, 1, "File close ends")<0) - // HDONE_ERROR(H5E_FILE, H5E_LOGGING, FAIL, "Fail to report VFD SMWR logging info."); - H5F_POST_VFD_SWMR_LOG_ENTRY(f, 1, "File close ends") +#if 1 /*Kent */ + H5F_POST_VFD_SWMR_LOG_ENTRY(f, 1, "VFD SWMR File close or flush ends") +#endif done: if (shared->vfd_swmr_log_on) { @@ -638,8 +638,6 @@ H5F_vfd_swmr_writer__prep_for_flush_or_close(H5F_t *f) HDassert(shared->vfd_swmr_writer); HDassert(shared->page_buf); - H5F_post_vfd_swmr_log_entry(f, 1, "File close starts"); - /* since we are about to flush the page buffer, force and end of * tick so as to avoid attempts to flush entries on the page buffer * tick list that were modified during the current tick. @@ -774,7 +772,6 @@ H5F_vfd_swmr_writer_end_of_tick(H5F_t *f, hbool_t wait_for_reader) HDassert(shared->vfd_swmr_writer); if (f->shared->vfd_swmr_log_on == true) { - H5F_post_vfd_swmr_log_entry(f, 3, "EOT gets started"); if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); } @@ -906,7 +903,7 @@ done: log_msg = HDmalloc(48); temp_time = (unsigned int)(TOTAL_TIME_PASSED(start_time, end_time) * 1000); HDsprintf(log_msg, "Writer time is %u milliseconds", temp_time); - H5F_post_vfd_swmr_log_entry(f, 3, log_msg); + H5F_POST_VFD_SWMR_LOG_ENTRY(f, 3, log_msg) HDfree(log_msg); } FUNC_LEAVE_NOAPI(ret_value) @@ -1913,44 +1910,23 @@ done: FUNC_LEAVE_NOAPI(ret_value) } +/* Log reporting function, called by macro H5F_POST_VFD_SWMR_LOG_ENTRY */ herr_t H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *body) { herr_t ret_value = SUCCEED; double temp_time; struct timespec current_time; - unsigned int elap_min, elap_sec, elap_msec; FUNC_ENTER_NOAPI(FAIL) -#if 0 - HDassert(f); - HDassert(f->shared); -#endif -#if 0 - if (f == NULL) - HGOTO_DONE(SUCCEED) - else if (f->shared == NULL) - HGOTO_DONE(SUCCEED) - if (f->shared->vfd_swmr_log_on == false) - HGOTO_DONE(SUCCEED) -#endif if (HDclock_gettime(CLOCK_MONOTONIC, ¤t_time) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); temp_time = TOTAL_TIME_PASSED(f->shared->vfd_swmr_log_start_time, current_time); - elap_min = TIME_PASSED_MIN(temp_time); - elap_sec = TIME_PASSED_SEC(temp_time, elap_min); - elap_msec = TIME_PASSED_MSEC(temp_time, elap_min, elap_sec); /* TODO: add a check for the range of entry_type_code to separate debug mode from the production mode.*/ -#if 0 - HDfprintf(f->shared->vfd_swmr_log_file_ptr, "%s: %u m %u s %u ms, Content - %s\n", - H5Fvfd_swmr_log_tags[entry_type_code], elap_min, elap_sec, elap_msec, body); -#endif - HDfprintf(f->shared->vfd_swmr_log_file_ptr, "%-25s: %.3lf s: %s\n", H5Fvfd_swmr_log_tags[entry_type_code], temp_time, body); done: - // return ret_value; FUNC_LEAVE_NOAPI(ret_value) } -- cgit v0.12 From fb51aa0da2322ca10326adb3f4b82d0022ad68f4 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 25 Oct 2021 19:53:48 +0000 Subject: Committing clang-format changes --- src/H5FDvfd_swmr_private.h | 2 +- src/H5Fint.c | 2 +- src/H5Fvfd_swmr.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/H5FDvfd_swmr_private.h b/src/H5FDvfd_swmr_private.h index 333bcc7..2dd9513 100644 --- a/src/H5FDvfd_swmr_private.h +++ b/src/H5FDvfd_swmr_private.h @@ -93,7 +93,7 @@ H5_DLL herr_t H5F_dump_eot_queue(void); #define TOTAL_TIME_PASSED(X, Y) \ ((double)((Y.tv_sec - X.tv_sec) * 1000000000 + (Y.tv_nsec - X.tv_nsec))) / 1000000000.0 -/* +/* #define TIME_PASSED_MIN(X) (unsigned int)(X / 60000) #define TIME_PASSED_SEC(X, Y) (unsigned int)((X - Y * 60000) / 1000) #define TIME_PASSED_MSEC(X, Y, Z) (unsigned int)(X - Y * 60000 - Z * 1000) diff --git a/src/H5Fint.c b/src/H5Fint.c index f6b4e1a..f7a988b 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -2013,7 +2013,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) /* Short cuts */ shared = file->shared; - + /* Set up the VFD SWMR LOG file */ /* Kent*/ if (vfd_swmr_config_ptr->version) { diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index 3bc405f..918ef97 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -320,7 +320,7 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing) } #if 1 /*Kent */ H5F_POST_VFD_SWMR_LOG_ENTRY(f, 1, "VFD SWMR File close or flush ends") -#endif +#endif done: if (shared->vfd_swmr_log_on) { -- cgit v0.12 From 016a42fd6e446af25d43c53d413356026ebc5db2 Mon Sep 17 00:00:00 2001 From: Muqun Yang Date: Mon, 25 Oct 2021 16:37:35 -0500 Subject: Remove the compiler warnings. --- src/H5FDvfd_swmr_private.h | 2 ++ src/H5Fpkg.h | 15 +++++++++++++++ src/H5Fvfd_swmr.c | 12 +++++++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/H5FDvfd_swmr_private.h b/src/H5FDvfd_swmr_private.h index 2dd9513..9e56d00 100644 --- a/src/H5FDvfd_swmr_private.h +++ b/src/H5FDvfd_swmr_private.h @@ -106,6 +106,7 @@ H5_DLL herr_t H5F_dump_eot_queue(void); * H5F_POST_VFD_SWMR_LOG_ENTRY(f, 3, log_msg) will put the log_msg attached to * the entry tag "EOT_PROCESSING_TIME". */ +#if 0 /* clang-format off */ /* The entry code number is listed in the comment for convenience. */ static const char *H5Fvfd_swmr_log_tags[] = { @@ -116,5 +117,6 @@ static const char *H5Fvfd_swmr_log_tags[] = { "EOT_META_FILE_INDEX" /* 4 */ }; /* clang-format on */ +#endif #endif /* H5FDvfd_swmr_private_H */ diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 5eaee3c..3240d84 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -623,4 +623,19 @@ H5_DLL herr_t H5F__reparse_file_lock_variable_test(void); H5F_post_vfd_swmr_log_entry(fp, entry_type_code, body); H5_DLL herr_t H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *body); +/* clang-format off */ +/* The entry code number is listed in the comment for convenience. */ + +#if 0 +static const char *H5Fvfd_swmr_log_tags[] = { + "FILE_OPEN", /* 0 */ + "FILE_CLOSE", /* 1 */ + "EOT_TRIGGER_TIME", /* 2 */ + "EOT_PROCESSING_TIME", /* 3 */ + "EOT_META_FILE_INDEX" /* 4 */ + }; +#endif +/* clang-format on */ + + #endif /* H5Fpkg_H */ diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index 918ef97..5119b38 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -54,6 +54,17 @@ #define nanosecs_per_second 1000000000 /* nanoseconds per second */ #define nanosecs_per_tenth_sec 100000000 /* nanoseconds per 0.1 second */ +/* clang-format off */ +/* The entry code number is listed in the comment for convenience. */ +static const char *H5Fvfd_swmr_log_tags[] = { + "FILE_OPEN", /* 0 */ + "FILE_CLOSE", /* 1 */ + "EOT_TRIGGER_TIME", /* 2 */ + "EOT_PROCESSING_TIME", /* 3 */ + "EOT_META_FILE_INDEX" /* 4 */ + }; +/* clang-format on */ + /********************/ /* Local Prototypes */ /********************/ @@ -1917,7 +1928,6 @@ H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *body) herr_t ret_value = SUCCEED; double temp_time; struct timespec current_time; - FUNC_ENTER_NOAPI(FAIL) if (HDclock_gettime(CLOCK_MONOTONIC, ¤t_time) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); -- cgit v0.12 From 060d02023bce2f2922a7c548636d628e396f70e6 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 25 Oct 2021 21:40:45 +0000 Subject: Committing clang-format changes --- src/H5Fpkg.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 3240d84..41c4b6b 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -637,5 +637,4 @@ static const char *H5Fvfd_swmr_log_tags[] = { #endif /* clang-format on */ - #endif /* H5Fpkg_H */ -- cgit v0.12 From f3bca0e22f1ae6dded606e170bfb5699fe8f42a2 Mon Sep 17 00:00:00 2001 From: myang6 Date: Wed, 27 Oct 2021 12:30:40 -0500 Subject: Add comments, descriptions for the VFD log feature. --- src/H5FDvfd_swmr_private.h | 28 +----------- src/H5Fint.c | 4 +- src/H5Fpkg.h | 69 ++++++++++++++++++++---------- src/H5Fvfd_swmr.c | 103 ++++++++++++++++++++++++++++++++++----------- test/vfd_swmr_common.c | 1 + test/vfd_swmr_log_writer.c | 85 ++++++++----------------------------- 6 files changed, 145 insertions(+), 145 deletions(-) diff --git a/src/H5FDvfd_swmr_private.h b/src/H5FDvfd_swmr_private.h index 9e56d00..a2c29cd 100644 --- a/src/H5FDvfd_swmr_private.h +++ b/src/H5FDvfd_swmr_private.h @@ -89,34 +89,8 @@ H5_DLL herr_t H5F_dump_eot_queue(void); /***************************************/ /* VFD SWMR Helper macros to calcuate the elapsed time */ -/* The total time in seconds */ +/* The total time is in seconds */ #define TOTAL_TIME_PASSED(X, Y) \ ((double)((Y.tv_sec - X.tv_sec) * 1000000000 + (Y.tv_nsec - X.tv_nsec))) / 1000000000.0 -/* -#define TIME_PASSED_MIN(X) (unsigned int)(X / 60000) -#define TIME_PASSED_SEC(X, Y) (unsigned int)((X - Y * 60000) / 1000) -#define TIME_PASSED_MSEC(X, Y, Z) (unsigned int)(X - Y * 60000 - Z * 1000) -*/ - -/* Add more tags */ -/* The VFD SMWR Log tags. Note this array of string is used to generate the - * entry tag by the log reporting function H5F_POST_VFD_SWMR_LOG_ENTRY. - * 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, 3, log_msg) will put the log_msg attached to - * the entry tag "EOT_PROCESSING_TIME". - */ -#if 0 -/* clang-format off */ -/* The entry code number is listed in the comment for convenience. */ -static const char *H5Fvfd_swmr_log_tags[] = { - "FILE_OPEN", /* 0 */ - "FILE_CLOSE", /* 1 */ - "EOT_TRIGGER_TIME", /* 2 */ - "EOT_PROCESSING_TIME", /* 3 */ - "EOT_META_FILE_INDEX" /* 4 */ - }; -/* clang-format on */ -#endif - #endif /* H5FDvfd_swmr_private_H */ diff --git a/src/H5Fint.c b/src/H5Fint.c index f7a988b..6827158 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -2226,8 +2226,8 @@ 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, now comment out.*/ - H5F_POST_VFD_SWMR_LOG_ENTRY(file, 0, "File open ends") +#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, 1, "File open ends"); #endif done: if ((NULL == ret_value) && file) { diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 41c4b6b..2fc896a 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -612,29 +612,52 @@ 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 */ -/* The first argument 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 which involves - * the test of a non-existing HDF5 file. */ -#define H5F_POST_VFD_SWMR_LOG_ENTRY(fp, entry_type_code, body) \ - 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, body); - -H5_DLL herr_t H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *body); -/* clang-format off */ -/* The entry code number is listed in the comment for convenience. */ - -#if 0 -static const char *H5Fvfd_swmr_log_tags[] = { - "FILE_OPEN", /* 0 */ - "FILE_CLOSE", /* 1 */ - "EOT_TRIGGER_TIME", /* 2 */ - "EOT_PROCESSING_TIME", /* 3 */ - "EOT_META_FILE_INDEX" /* 4 */ - }; +/* VFD SMWR LOG REPORTING MACROS */ + +/* H5F_POST_VFD_SWMR_LOG_ENTRY is the macro that needs to be used by the developers. + * It calls an internal reporting function H5F_post_vfd_swmr_log_entry() that receives + * the log entry_type_code, which generates the log tag, and the message log_info, which + * the library developer wants to save into the log file. + * + * The macro H5F_POST_VFD_SWMR_LOG_ENTRY_RELEASE(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_RELEASE(fp, entry_type_code, max_code, log_info) \ + do { \ + if (entry_type_code vfd_swmr_log_on) { HDfclose(shared->vfd_swmr_log_file_ptr); } + /* Kent */ FUNC_LEAVE_NOAPI(ret_value) } @@ -782,10 +805,14 @@ H5F_vfd_swmr_writer_end_of_tick(H5F_t *f, hbool_t wait_for_reader) HDassert(shared->page_buf); HDassert(shared->vfd_swmr_writer); - if (f->shared->vfd_swmr_log_on == true) { + /* Kent */ + /* Obtain the starting time for the logging info: the processing time of this function. */ + if (shared->vfd_swmr_log_on == true) { if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); } + /* Kent */ + if (!vfd_swmr_writer_may_increase_tick_to(shared->tick_num + 1, wait_for_reader)) goto update_eot; @@ -908,15 +935,17 @@ update_eot: HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to insert entry into the EOT queue") done: - if (f->shared->vfd_swmr_log_on == true) { + /* Kent: Calcuate the processing time and write the time info to the log file */ + if (shared->vfd_swmr_log_on == true) { if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); log_msg = HDmalloc(48); temp_time = (unsigned int)(TOTAL_TIME_PASSED(start_time, end_time) * 1000); HDsprintf(log_msg, "Writer time is %u milliseconds", temp_time); - H5F_POST_VFD_SWMR_LOG_ENTRY(f, 3, log_msg) + H5F_POST_VFD_SWMR_LOG_ENTRY(f, 0, log_msg); HDfree(log_msg); } + /* Kent */ FUNC_LEAVE_NOAPI(ret_value) } @@ -1921,22 +1950,46 @@ done: FUNC_LEAVE_NOAPI(ret_value) } -/* Log reporting function, called by macro H5F_POST_VFD_SWMR_LOG_ENTRY */ -herr_t -H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *body) +/*------------------------------------------------------------------------- + * + * 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) { - herr_t ret_value = SUCCEED; double temp_time; struct timespec current_time; - FUNC_ENTER_NOAPI(FAIL) - if (HDclock_gettime(CLOCK_MONOTONIC, ¤t_time) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); - temp_time = TOTAL_TIME_PASSED(f->shared->vfd_swmr_log_start_time, current_time); - - /* TODO: add a check for the range of entry_type_code to separate debug mode from the production mode.*/ - HDfprintf(f->shared->vfd_swmr_log_file_ptr, "%-25s: %.3lf s: %s\n", H5Fvfd_swmr_log_tags[entry_type_code], - temp_time, body); - -done: - FUNC_LEAVE_NOAPI(ret_value) + char *gettime_error; + + /* Obtain the current time. + If failed, write an error message to the log file. + else calcluate the elapsed time in seconds since the log file + was created and wirte the time to the log file. */ + if (HDclock_gettime(CLOCK_MONOTONIC, ¤t_time) < 0) { + gettime_error = HDmalloc(14); + 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 = TOTAL_TIME_PASSED(f->shared->vfd_swmr_log_start_time, current_time); + 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/test/vfd_swmr_common.c b/test/vfd_swmr_common.c index 2cae0be..cfe93aa 100644 --- a/test/vfd_swmr_common.c +++ b/test/vfd_swmr_common.c @@ -369,6 +369,7 @@ init_vfd_swmr_config(H5F_vfd_swmr_config_t *config, uint32_t tick_len, uint32_t } /* init_vfd_swmr_config() */ +/* Initialize the log file path in config, this function should be called after init_vfd_swmr_config. */ void init_vfd_swmr_log(H5F_vfd_swmr_config_t *config, const char *log_file_fmtstr, ...) diff --git a/test/vfd_swmr_log_writer.c b/test/vfd_swmr_log_writer.c index 9ab50bd..62d8318 100644 --- a/test/vfd_swmr_log_writer.c +++ b/test/vfd_swmr_log_writer.c @@ -11,24 +11,23 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Description of this program: - * This program checks the performance of group creations for VFD SWMR. + * This program shows an example on how a VFD log file can be written. + * It is adapted from the group performence test. Most options of the + * group performance test are still kept. + * To turn on the log feature, one just needs to provide the log file path as + * indicated by the line init_vfd_swmr_log(&config, "./log-test") in the main + * function. The init_vfd_swmr_log is defined inside the vfd_swmr_common.c. + * For the demo of the log feature, + * one just needs to do te following: + * After compiling the program, just run the following line + * ./vfd_swmr_log_writer -n 1000 -P -q + * A VFD SWMR log file log-test is generated. + * The log-test should include something like: + * 'EOT_PROCESSING_TIME : 0.040 s: Writer time is 1 milliseconds' + * This program also checks the performance of group creations for VFD SWMR. * Currently the group creation time, H5Fopen and H5Fclose time are measured. - * After compiling the program, - * ./vfd_swmr_gperf_writer -n 1000 -P -N 5 -q - * will generate 1000 groups, each group has 5 attributes. - * ./vfd_swmr_gperf_writer -n 1000 -P -N 0 -q - * will generate 1000 empty groups. - * ./vfd_swmr_gperf_writer -n 1000 -P -l 1 -q - * will generate 1000 groups with 1 level of nested groups,(like /g1/g2) - * each group has one attribute. - * ./vfd_swmr_gperf_writer -n 1000 -P -S -G -V -N 5 -l 1 -m 8 -t 4 -B 16384 -s 8192 - * will generate 1000 groups with 1 level of nested groups,(like /g1/g2) - * each group has 5 attributes and the attribute type is variable length string. - * The groups is created without using VFD SWMR; - * The groups are created with the earliest file format(old-styled) - * The program is run with max_lag = 8, tick_len = 4; - * The page buffer size is 16384 bytes. The page size is 8192 bytes. - * + * The output can help check the contents in the log-test. + * */ #define H5F_FRIEND /*suppress error about including H5Fpkg */ @@ -118,58 +117,7 @@ usage(const char *progname) "-b: write data in big-endian byte order\n" " (For the performance test, -V overwrites -b)\n" "-A at_pattern: `at_pattern' for different attribute tests\n" - " The value of `at_pattern` is one of the following:\n" - " `compact` - Attributes added in compact storage\n" - " `dense` - An attribute added in dense storage\n" - " `compact-del` - Attributes added and then one\n" - " attribute deleted, in compact \n" - " `dense-del` - Attributes added until the storage\n" - " is dense then an attribute deleted\n" - " the storge still in dense\n" - " `compact-add-to-dense` - Attributes added first in compact\n" - " then in dense storage\n" - " `dense-del-to-compact` - Attributes added until the storage\n" - " is dense, then several attributes \n" - " deleted, the storage changed to\n" - " compact\n" - " `modify` - An attribute added then modified\n" - " `add-vstr` - A VL string attribute added\n" - " `remove-vstr` - A VL string attribute added then\n" - " deleted\n" - " `modify-vstr` - A VL string attribute added then \n" - " modified \n" - " `add-ohr-block` - An attribute is added and this forces\n" - " the creation of object header\n" - " continuation block \n" - " `del-ohr-block` - An attribute is added and this forces\n" - " the creation of object header\n" - " continuation block and then this \n" - " attribute is deleted so the \n" - " object header continuation block is \n" - " removed. \n" "-O grp_op_pattern: `grp_op_pattern' for different group operation tests\n" - " The value of `grp_op_pattern` is one of the following:\n" - " `grp-creation` - A group is created.\n" - " `grp-deletion` - An existing group is deleted.\n" - " `grp-move` - A group is moved to become \n" - " another group. \n" - " `grp-ins-links` - Links are inserted, including\n" - " both hard and soft links. \n" - " `grp-del-links` - Links are deleted, including\n" - " both hard ans soft links. \n" - " `grp-compact-t-dense` - Links are inserted to the group.\n" - " The link storage of this group \n" - " changed from compact to dense. \n" - " The links include both hard and\n" - " soft links. \n" - " `grp-dense-t-compact` - Links are inserted to the group\n" - " The link storage of this group \n" - " changed from compact to dense. \n" - " Then several links are deleted.\n" - " The link storage changed from \n" - " dense to compact again. \n" - " The links include both hard and\n" - " soft links. \n" "-a steps: `steps` between adding attributes\n" " (Don't recommend to use this option for performance test.)\n" "-q: silence printouts, few messages\n" @@ -2763,6 +2711,7 @@ main(int argc, char **argv) /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ init_vfd_swmr_config(&config, s.tick_len, s.max_lag, writer, FALSE, 128, "./group-shadow"); + /* Create the log file log-test under the current directory. */ init_vfd_swmr_log(&config, "./log-test"); /* If old-style option is chosen, use the earliest file format(H5F_LIBVER_EARLIEST) -- cgit v0.12 From be9a0b58b26733fa3bb542cac7cef2dc4f5f7f66 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 27 Oct 2021 17:34:01 +0000 Subject: Committing clang-format changes --- src/H5Fpkg.h | 38 +++++++++++++++++++------------------- src/H5Fvfd_swmr.c | 35 +++++++++++++++++------------------ test/vfd_swmr_log_writer.c | 6 +++--- 3 files changed, 39 insertions(+), 40 deletions(-) diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 2fc896a..578c6ab 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -612,11 +612,11 @@ 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 */ +/* VFD SMWR LOG REPORTING MACROS */ -/* H5F_POST_VFD_SWMR_LOG_ENTRY is the macro that needs to be used by the developers. +/* H5F_POST_VFD_SWMR_LOG_ENTRY is the macro that needs to be used by the developers. * It calls an internal reporting function H5F_post_vfd_swmr_log_entry() that receives - * the log entry_type_code, which generates the log tag, and the message log_info, which + * the log entry_type_code, which generates the log tag, and the message log_info, which * the library developer wants to save into the log file. * * The macro H5F_POST_VFD_SWMR_LOG_ENTRY_RELEASE(f, c, number_entry_production, m) is @@ -625,34 +625,34 @@ H5_DLL herr_t H5F__reparse_file_lock_variable_test(void); * 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 " + * 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) \ +#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); \ - } \ - } \ - } \ + 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_RELEASE(fp, entry_type_code, max_code, log_info) \ +#define H5F_POST_VFD_SWMR_LOG_ENTRY_RELEASE(fp, entry_type_code, max_code, log_info) \ do { \ - if (entry_type_code shared->vfd_swmr_log_file_ptr, - "%-26s: %s\n", H5Fvfd_swmr_log_tags[entry_type_code], + 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 = TOTAL_TIME_PASSED(f->shared->vfd_swmr_log_start_time, current_time); - HDfprintf(f->shared->vfd_swmr_log_file_ptr,log_fmt_str, - H5Fvfd_swmr_log_tags[entry_type_code], temp_time, log_info); + 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/test/vfd_swmr_log_writer.c b/test/vfd_swmr_log_writer.c index 62d8318..d1eef18 100644 --- a/test/vfd_swmr_log_writer.c +++ b/test/vfd_swmr_log_writer.c @@ -11,9 +11,9 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Description of this program: - * This program shows an example on how a VFD log file can be written. + * This program shows an example on how a VFD log file can be written. * It is adapted from the group performence test. Most options of the - * group performance test are still kept. + * group performance test are still kept. * To turn on the log feature, one just needs to provide the log file path as * indicated by the line init_vfd_swmr_log(&config, "./log-test") in the main * function. The init_vfd_swmr_log is defined inside the vfd_swmr_common.c. @@ -27,7 +27,7 @@ * This program also checks the performance of group creations for VFD SWMR. * Currently the group creation time, H5Fopen and H5Fclose time are measured. * The output can help check the contents in the log-test. - * + * */ #define H5F_FRIEND /*suppress error about including H5Fpkg */ -- cgit v0.12 From 645aadd77be93ee971ffc02a8d8652048338f110 Mon Sep 17 00:00:00 2001 From: Muqun Yang Date: Wed, 27 Oct 2021 17:53:33 -0500 Subject: Modify the description a bit. --- test/vfd_swmr_log_writer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/vfd_swmr_log_writer.c b/test/vfd_swmr_log_writer.c index d1eef18..95f89f0 100644 --- a/test/vfd_swmr_log_writer.c +++ b/test/vfd_swmr_log_writer.c @@ -20,7 +20,7 @@ * For the demo of the log feature, * one just needs to do te following: * After compiling the program, just run the following line - * ./vfd_swmr_log_writer -n 1000 -P -q + * ./vfd_swmr_log_writer -n 100000 -P -q * A VFD SWMR log file log-test is generated. * The log-test should include something like: * 'EOT_PROCESSING_TIME : 0.040 s: Writer time is 1 milliseconds' -- cgit v0.12 From e52f6fdb1322a1b770eac4297ce7d0dd01e1da73 Mon Sep 17 00:00:00 2001 From: myang6 Date: Thu, 28 Oct 2021 10:32:12 -0500 Subject: Add vfd_swmr_log_writer.c to the MANIFEST. --- MANIFEST | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST b/MANIFEST index 75a7aca..208bfc3 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1444,6 +1444,7 @@ ./test/vfd_swmr_vlstr_writer.c ./test/vfd_swmr_writer.c ./test/vfd_swmr_zoo_writer.c +./test/vfd_swmr_log_writer.c ./test/vfd.c ./test/vol.c ./test/vol_plugin.c -- cgit v0.12 From 7a527aac5a69449a185cdd40de43b82723cc3fbb Mon Sep 17 00:00:00 2001 From: Muqun Yang Date: Thu, 28 Oct 2021 12:29:39 -0500 Subject: Modify comments. --- src/H5FDvfd_swmr_private.h | 2 +- src/H5Fpkg.h | 20 +++++++++++++------- src/H5Fvfd_swmr.c | 7 +++++-- test/vfd_swmr_log_writer.c | 8 ++++---- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/H5FDvfd_swmr_private.h b/src/H5FDvfd_swmr_private.h index a2c29cd..d0e2380 100644 --- a/src/H5FDvfd_swmr_private.h +++ b/src/H5FDvfd_swmr_private.h @@ -88,7 +88,7 @@ H5_DLL herr_t H5F_dump_eot_queue(void); /* Log Macros and Functions */ /***************************************/ -/* VFD SWMR Helper macros to calcuate the elapsed time */ +/* VFD SWMR Helper macro to calcuate the elapsed time */ /* The total time is in seconds */ #define TOTAL_TIME_PASSED(X, Y) \ ((double)((Y.tv_sec - X.tv_sec) * 1000000000 + (Y.tv_nsec - X.tv_nsec))) / 1000000000.0 diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 578c6ab..7bb5e45 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -468,11 +468,17 @@ struct H5F_shared_t { H5F_fs_state_t fs_state_md; /* State of the free space * manager */ - - FILE * vfd_swmr_log_file_ptr; - hbool_t vfd_swmr_log_on; - struct timespec vfd_swmr_log_start_time; - + /* 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. */ + struct timespec 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; @@ -614,10 +620,10 @@ H5_DLL herr_t H5F__reparse_file_lock_variable_test(void); /* VFD SMWR LOG REPORTING MACROS */ -/* H5F_POST_VFD_SWMR_LOG_ENTRY is the macro that needs to be used by the developers. +/* 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 * the log entry_type_code, which generates the log tag, and the message log_info, which - * the library developer wants to save into the log file. + * the developers want to save into the log file. * * The macro H5F_POST_VFD_SWMR_LOG_ENTRY_RELEASE(f, c, number_entry_production, m) is * called by H5F_POST_VFD_SWMR_LOG_ENTRY when the HDF5 library is built with the diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index 12c8905..c3ecae3 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -355,7 +355,10 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing) #endif done: - /* Kent: close the VFD SWMR log file if it is turned on */ + /* Kent: 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) { HDfclose(shared->vfd_swmr_log_file_ptr); } @@ -1977,7 +1980,7 @@ H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log_info) /* Obtain the current time. If failed, write an error message to the log file. else calcluate the elapsed time in seconds since the log file - was created and wirte the time to the log file. */ + was created and write the time to the log file. */ if (HDclock_gettime(CLOCK_MONOTONIC, ¤t_time) < 0) { gettime_error = HDmalloc(14); HDsprintf(gettime_error, "gettime_error"); diff --git a/test/vfd_swmr_log_writer.c b/test/vfd_swmr_log_writer.c index 95f89f0..06b5654 100644 --- a/test/vfd_swmr_log_writer.c +++ b/test/vfd_swmr_log_writer.c @@ -21,12 +21,12 @@ * one just needs to do te following: * After compiling the program, just run the following line * ./vfd_swmr_log_writer -n 100000 -P -q - * A VFD SWMR log file log-test is generated. - * The log-test should include something like: + * A VFD SWMR log file "log-test" is generated. + * The "log-test" should include something like: * 'EOT_PROCESSING_TIME : 0.040 s: Writer time is 1 milliseconds' * This program also checks the performance of group creations for VFD SWMR. * Currently the group creation time, H5Fopen and H5Fclose time are measured. - * The output can help check the contents in the log-test. + * The standard output can help check the contents in the "log-test". * */ #define H5F_FRIEND /*suppress error about including H5Fpkg */ @@ -93,7 +93,7 @@ static void usage(const char *progname) { fprintf(stderr, - "usage: ./%s -P -n 1000 -N 5 -q (create 1000 groups, each group has 5 attributes)\n" + "usage: ./%s -P -n 100000 -q (create 100000 groups, each group has 1 attribute)\n" "Options: \n" " [-P] [-S] [-G] [-t tick_len] [-m max_lag][-B pbs] [-s ps]\n" " [-n ngroups] [-l ng_levels] [-O grp_op_pattern]\n" -- cgit v0.12 From 89ed2f20043326d9fe482f275aead9576f420c02 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 28 Oct 2021 17:32:03 +0000 Subject: Committing clang-format changes --- src/H5Fpkg.h | 8 ++++---- src/H5Fvfd_swmr.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 7bb5e45..4a23cd1 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -469,14 +469,14 @@ struct H5F_shared_t { * manager */ /* Log file for VFD SWMR */ - FILE * vfd_swmr_log_file_ptr; /* File pointer for the + 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 + hbool_t vfd_swmr_log_on; /* flag to indicate if + * the log file is * created. */ struct timespec vfd_swmr_log_start_time; /* The starting time for - * calculating the time + * calculating the time * stamp of a log message. */ /* Delayed free space release doubly linked list */ diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index c3ecae3..dc5d1f0 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -355,10 +355,10 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing) #endif done: - /* Kent: 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. - */ + /* Kent: 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) { HDfclose(shared->vfd_swmr_log_file_ptr); } -- cgit v0.12 From 81f733ea6637df3252bae2c2fa9124ddcb59e1fe Mon Sep 17 00:00:00 2001 From: myang6 Date: Thu, 28 Oct 2021 14:56:49 -0500 Subject: Revise a comment to trigger another github check --- src/H5Fpkg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 4a23cd1..ecd9c16 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -622,8 +622,8 @@ H5_DLL herr_t H5F__reparse_file_lock_variable_test(void); /* 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 - * the log entry_type_code, which generates the log tag, and the message log_info, which - * the developers want to save into the log file. + * 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_RELEASE(f, c, number_entry_production, m) is * called by H5F_POST_VFD_SWMR_LOG_ENTRY when the HDF5 library is built with the -- cgit v0.12 From 65cf226e8ac757d2ae932daeeace6fa821850eb2 Mon Sep 17 00:00:00 2001 From: myang6 Date: Thu, 28 Oct 2021 18:13:19 -0500 Subject: Add macros to make windows ignore the HDgetclock_time(). --- src/H5Fint.c | 2 ++ src/H5Fvfd_swmr.c | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/H5Fint.c b/src/H5Fint.c index 6827158..cdba7de 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -2023,8 +2023,10 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) /* 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") +#ifndef H5_HAVE_WIN32_API if (HDclock_gettime(CLOCK_MONOTONIC, &(shared->vfd_swmr_log_start_time)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get time via clock_gettime"); +#endif } } /* End of Kent */ diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index dc5d1f0..e958c52 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -811,8 +811,10 @@ H5F_vfd_swmr_writer_end_of_tick(H5F_t *f, hbool_t wait_for_reader) /* Kent */ /* Obtain the starting time for the logging info: the processing time of this function. */ if (shared->vfd_swmr_log_on == true) { +#ifndef H5_HAVE_WIN32_API if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); +#endif } /* Kent */ @@ -940,6 +942,7 @@ update_eot: done: /* Kent: Calcuate the processing time and write the time info to the log file */ if (shared->vfd_swmr_log_on == true) { +#ifndef H5_HAVE_WIN32_API if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); log_msg = HDmalloc(48); @@ -947,6 +950,7 @@ done: HDsprintf(log_msg, "Writer time is %u milliseconds", temp_time); H5F_POST_VFD_SWMR_LOG_ENTRY(f, 0, log_msg); HDfree(log_msg); +#endif } /* Kent */ FUNC_LEAVE_NOAPI(ret_value) @@ -1977,6 +1981,7 @@ H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log_info) struct timespec current_time; char * gettime_error; +#ifndef H5_HAVE_WIN32_API /* Obtain the current time. If failed, write an error message to the log file. else calcluate the elapsed time in seconds since the log file @@ -1993,5 +1998,12 @@ H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log_info) HDfprintf(f->shared->vfd_swmr_log_file_ptr, log_fmt_str, H5Fvfd_swmr_log_tags[entry_type_code], temp_time, log_info); } +#else /* H5_HAVE_WIN32_API */ + gettime_error = HDmalloc(22); + HDsprintf(gettime_error, "unsupported on windows"); + HDfprintf(f->shared->vfd_swmr_log_file_ptr, "%-26s: %s\n", H5Fvfd_swmr_log_tags[entry_type_code], + gettime_error); + HDfree(gettime_error); +#endif return; } -- cgit v0.12 From 40f67b4b19d8f2acb078baf2dcce4af7bedb5d25 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 28 Oct 2021 23:15:32 +0000 Subject: Committing clang-format changes --- src/H5Fvfd_swmr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index e958c52..9586004 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -811,7 +811,7 @@ H5F_vfd_swmr_writer_end_of_tick(H5F_t *f, hbool_t wait_for_reader) /* Kent */ /* Obtain the starting time for the logging info: the processing time of this function. */ if (shared->vfd_swmr_log_on == true) { -#ifndef H5_HAVE_WIN32_API +#ifndef H5_HAVE_WIN32_API if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); #endif @@ -942,7 +942,7 @@ update_eot: done: /* Kent: Calcuate the processing time and write the time info to the log file */ if (shared->vfd_swmr_log_on == true) { -#ifndef H5_HAVE_WIN32_API +#ifndef H5_HAVE_WIN32_API if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); log_msg = HDmalloc(48); @@ -2002,7 +2002,7 @@ H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log_info) gettime_error = HDmalloc(22); HDsprintf(gettime_error, "unsupported on windows"); HDfprintf(f->shared->vfd_swmr_log_file_ptr, "%-26s: %s\n", H5Fvfd_swmr_log_tags[entry_type_code], - gettime_error); + gettime_error); HDfree(gettime_error); #endif return; -- cgit v0.12 From d0e0e9a418d8c9969329b33ef7cda479f2cd7e61 Mon Sep 17 00:00:00 2001 From: myang6 Date: Fri, 29 Oct 2021 10:59:16 -0500 Subject: Use HDF5 timer function --- src/H5Fint.c | 8 ++++---- src/H5Fpkg.h | 2 +- src/H5Fvfd_swmr.c | 34 +++++++++++++--------------------- 3 files changed, 18 insertions(+), 26 deletions(-) diff --git a/src/H5Fint.c b/src/H5Fint.c index cdba7de..0f2d71e 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -2023,10 +2023,10 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) /* 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") -#ifndef H5_HAVE_WIN32_API - if (HDclock_gettime(CLOCK_MONOTONIC, &(shared->vfd_swmr_log_start_time)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get time via clock_gettime"); -#endif + 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 start HDF5 timer.") } } /* End of Kent */ diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index ecd9c16..971d52a 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -475,7 +475,7 @@ struct H5F_shared_t { hbool_t vfd_swmr_log_on; /* flag to indicate if * the log file is * created. */ - struct timespec vfd_swmr_log_start_time; /* The starting time for + H5_timer_t vfd_swmr_log_start_time; /* The starting time for * calculating the time * stamp of a log message. */ diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index 9586004..eb7a470 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -360,6 +360,7 @@ done: * close the log file. */ if (shared->vfd_swmr_log_on) { + H5_timer_stop(&(shared->vfd_swmr_log_start_time)); HDfclose(shared->vfd_swmr_log_file_ptr); } /* Kent */ @@ -798,7 +799,8 @@ 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; - struct timespec start_time, end_time; + H5_timevals_t current_time; + double start_elapsed_time,end_elapsed_time; unsigned int temp_time; char * log_msg; @@ -811,10 +813,9 @@ H5F_vfd_swmr_writer_end_of_tick(H5F_t *f, hbool_t wait_for_reader) /* Kent */ /* Obtain the starting time for the logging info: the processing time of this function. */ if (shared->vfd_swmr_log_on == true) { -#ifndef H5_HAVE_WIN32_API - if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); -#endif + if (H5_timer_get_times(f->shared->vfd_swmr_log_start_time,¤t_time) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get H5_timer_get_times") + start_elapsed_time = current_time.elapsed; } /* Kent */ @@ -942,15 +943,14 @@ update_eot: done: /* Kent: Calcuate the processing time and write the time info to the log file */ if (shared->vfd_swmr_log_on == true) { -#ifndef H5_HAVE_WIN32_API - if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime"); + if (H5_timer_get_times(f->shared->vfd_swmr_log_start_time,¤t_time) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get H5_timer_get_times") + end_elapsed_time = current_time.elapsed; log_msg = HDmalloc(48); - temp_time = (unsigned int)(TOTAL_TIME_PASSED(start_time, end_time) * 1000); + 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, 0, log_msg); HDfree(log_msg); -#endif } /* Kent */ FUNC_LEAVE_NOAPI(ret_value) @@ -1978,15 +1978,14 @@ void H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log_info) { double temp_time; - struct timespec current_time; + H5_timevals_t current_time; char * gettime_error; -#ifndef H5_HAVE_WIN32_API /* Obtain the current time. If failed, write an error message to the log file. else calcluate the elapsed time in seconds since the log file was created and write the time to the log file. */ - if (HDclock_gettime(CLOCK_MONOTONIC, ¤t_time) < 0) { + if (H5_timer_get_times(f->shared->vfd_swmr_log_start_time,¤t_time) < 0) { gettime_error = HDmalloc(14); HDsprintf(gettime_error, "gettime_error"); HDfprintf(f->shared->vfd_swmr_log_file_ptr, "%-26s: %s\n", H5Fvfd_swmr_log_tags[entry_type_code], @@ -1994,16 +1993,9 @@ H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log_info) HDfree(gettime_error); } else { - temp_time = TOTAL_TIME_PASSED(f->shared->vfd_swmr_log_start_time, current_time); + 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); } -#else /* H5_HAVE_WIN32_API */ - gettime_error = HDmalloc(22); - HDsprintf(gettime_error, "unsupported on windows"); - HDfprintf(f->shared->vfd_swmr_log_file_ptr, "%-26s: %s\n", H5Fvfd_swmr_log_tags[entry_type_code], - gettime_error); - HDfree(gettime_error); -#endif return; } -- cgit v0.12 From 553c1b449e7c77cf143d587beb41deaa63282904 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 29 Oct 2021 16:01:17 +0000 Subject: Committing clang-format changes --- src/H5Fint.c | 2 +- src/H5Fpkg.h | 20 ++++++++++---------- src/H5Fvfd_swmr.c | 24 ++++++++++++------------ 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/H5Fint.c b/src/H5Fint.c index 0f2d71e..2937056 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -2025,7 +2025,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) 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) + if (H5_timer_start(&(shared->vfd_swmr_log_start_time)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't start HDF5 timer.") } } diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 971d52a..3de5a84 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -469,16 +469,16 @@ struct H5F_shared_t { * 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. - */ + 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; diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index eb7a470..be3dbb6 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -799,10 +799,10 @@ 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; - H5_timevals_t current_time; - double start_elapsed_time,end_elapsed_time; - unsigned int temp_time; - char * log_msg; + H5_timevals_t current_time; + double start_elapsed_time, end_elapsed_time; + unsigned int temp_time; + char * log_msg; FUNC_ENTER_NOAPI(FAIL) @@ -813,7 +813,7 @@ H5F_vfd_swmr_writer_end_of_tick(H5F_t *f, hbool_t wait_for_reader) /* 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(f->shared->vfd_swmr_log_start_time,¤t_time) < 0) + if (H5_timer_get_times(f->shared->vfd_swmr_log_start_time, ¤t_time) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get H5_timer_get_times") start_elapsed_time = current_time.elapsed; } @@ -943,11 +943,11 @@ update_eot: 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(f->shared->vfd_swmr_log_start_time,¤t_time) < 0) + if (H5_timer_get_times(f->shared->vfd_swmr_log_start_time, ¤t_time) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get H5_timer_get_times") end_elapsed_time = current_time.elapsed; - log_msg = HDmalloc(48); - temp_time = (unsigned int)((end_elapsed_time - start_elapsed_time) * 1000); + log_msg = HDmalloc(48); + 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, 0, log_msg); HDfree(log_msg); @@ -1977,15 +1977,15 @@ done: 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; + 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 calcluate 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,¤t_time) < 0) { + if (H5_timer_get_times(f->shared->vfd_swmr_log_start_time, ¤t_time) < 0) { gettime_error = HDmalloc(14); HDsprintf(gettime_error, "gettime_error"); HDfprintf(f->shared->vfd_swmr_log_file_ptr, "%-26s: %s\n", H5Fvfd_swmr_log_tags[entry_type_code], -- cgit v0.12 From b8a775cbe44e3518a817f413993adef7a6eca88f Mon Sep 17 00:00:00 2001 From: myang6 Date: Fri, 29 Oct 2021 15:00:02 -0500 Subject: Update comments to use the HDF5 timer for the log feature. --- src/H5FDvfd_swmr_private.h | 5 ----- src/H5Fint.c | 2 +- src/H5Fvfd_swmr.c | 14 ++++++++------ 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/H5FDvfd_swmr_private.h b/src/H5FDvfd_swmr_private.h index d0e2380..02e1c44 100644 --- a/src/H5FDvfd_swmr_private.h +++ b/src/H5FDvfd_swmr_private.h @@ -88,9 +88,4 @@ H5_DLL herr_t H5F_dump_eot_queue(void); /* Log Macros and Functions */ /***************************************/ -/* VFD SWMR Helper macro to calcuate the elapsed time */ -/* The total time is in seconds */ -#define TOTAL_TIME_PASSED(X, Y) \ - ((double)((Y.tv_sec - X.tv_sec) * 1000000000 + (Y.tv_nsec - X.tv_nsec))) / 1000000000.0 - #endif /* H5FDvfd_swmr_private_H */ diff --git a/src/H5Fint.c b/src/H5Fint.c index 2937056..1adc7d5 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -2026,7 +2026,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) 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 start HDF5 timer.") + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't obtain the time from the HDF5 timer.") } } /* End of Kent */ diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index be3dbb6..ce9e468 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -355,7 +355,7 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing) #endif done: - /* Kent: close the VFD SWMR log file if it is turned on. + /* 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. */ @@ -799,6 +799,8 @@ 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; @@ -813,8 +815,8 @@ H5F_vfd_swmr_writer_end_of_tick(H5F_t *f, hbool_t wait_for_reader) /* 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(f->shared->vfd_swmr_log_start_time, ¤t_time) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get H5_timer_get_times") + if (H5_timer_get_times(shared->vfd_swmr_log_start_time, ¤t_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 */ @@ -943,8 +945,8 @@ update_eot: 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(f->shared->vfd_swmr_log_start_time, ¤t_time) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get H5_timer_get_times") + if (H5_timer_get_times(shared->vfd_swmr_log_start_time, ¤t_time) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time from H5_timer_get_times") end_elapsed_time = current_time.elapsed; log_msg = HDmalloc(48); temp_time = (unsigned int)((end_elapsed_time - start_elapsed_time) * 1000); @@ -1983,7 +1985,7 @@ H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log_info) /* Obtain the current time. If failed, write an error message to the log file. - else calcluate the elapsed time in seconds since 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, ¤t_time) < 0) { gettime_error = HDmalloc(14); -- cgit v0.12 From abed0f75f22ebbcd777def072ff286f296d32908 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 29 Oct 2021 20:02:12 +0000 Subject: Committing clang-format changes --- src/H5Fvfd_swmr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index ce9e468..476af3e 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -799,7 +799,7 @@ 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 + /* 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; -- cgit v0.12 From ad76c0de4e6502fd82d1a105271e8b680c348e85 Mon Sep 17 00:00:00 2001 From: Songyu Lu Date: Mon, 1 Nov 2021 10:57:55 -0500 Subject: Two purposes for this PR: 1. added an option to enable the legacy SWMR in vfd_swmr_bigset_writer.c. 2. adjusted the options for big set test to make sure it passes the exhaustive test in testvfdswmr.sh.in. --- test/testvfdswmr.sh.in | 34 +++++++++++----------- test/vfd_swmr_bigset_writer.c | 66 +++++++++++++++++++++++++++---------------- 2 files changed, 59 insertions(+), 41 deletions(-) diff --git a/test/testvfdswmr.sh.in b/test/testvfdswmr.sh.in index 4dc1e82..535aafa 100644 --- a/test/testvfdswmr.sh.in +++ b/test/testvfdswmr.sh.in @@ -1047,31 +1047,31 @@ fi # BIGSET_n=25 # -n option: # of iterations BIGSET_few_s=10 # -s option: # of datasets (for few_big test) -BIGSET_many_s=100 # -s option: # of datasets (for many_small test) +BIGSET_many_s=50 # -s option: # of datasets (for many_small test) # # # Setting for exhaustive and quick runs # if [[ "$HDF5TestExpress" -eq 0 ]] ; then # exhaustive run - BIGSET_n=200 - BIGSET_few_s=100 - BIGSET_many_s=1000 + BIGSET_n=100 + BIGSET_few_s=25 + BIGSET_many_s=100 elif [[ "$HDF5TestExpress" -gt 1 ]]; then # quick run BIGSET_n=10 BIGSET_few_s=3 - BIGSET_many_s=50 + BIGSET_many_s=25 fi # # -for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-d 1 -t" "-d 1 -t -F" "-d 1 -t -R" "-d 1 -V" "-d 1 -M" "-d 1 -V -F" "-d 1 -M -F"; do +for options in "-d 1" "-d 1 -F" "-d 2 -l 16" "-d 2 -F -l 16" "-d 1 -t" "-d 1 -t -F" "-d 1 -t -R" "-d 1 -V" "-d 1 -M" "-d 1 -V -F" "-d 1 -M -F"; do if [ ${do_many_small:-no} = no ]; then continue fi # - # Test many small datasets of one and two dimensions. + # Test many small datasets of two or three dimensions. # # Perform 25 iterations on 100 extensible datasets configured with - # 2D 16x16 chunks or 3D 8x16x16 chunks of 32-bit unsigned integer elements, + # 2D 16x16 chunks or 3D 1x16x16 chunks of 32-bit unsigned integer elements, # expanding each dataset by a chunk in one dimension (up to 25x1 # 16x16 chunks) on each iteration. # @@ -1079,16 +1079,16 @@ for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-d 1 -t" "-d 1 -t -F" "-d 1 -t # in *two* dimensions (up to 25x25 16x16 chunks). # # If testing 3D datasets (-t option), extending each dataset along the - # first dimension (up to 25 8x16x16) + # first dimension (up to 25 1x16x16) # echo launch vfd_swmr_bigset_writer many small, options $options catch_out_err_and_rc vfd_swmr_bigset_writer \ - ../vfd_swmr_bigset_writer -n $BIGSET_n $options -s $BIGSET_many_s -e 8 -r 16 -c 16 -q -l 3 & + ../vfd_swmr_bigset_writer -n $BIGSET_n $options -s $BIGSET_many_s -e 1 -r 16 -c 16 -q & pid_writer=$! catch_out_err_and_rc vfd_swmr_bigset_reader \ - ../vfd_swmr_bigset_reader -n $BIGSET_n $options -s $BIGSET_many_s -e 8 -r 16 -c 16 -q -l 3 & + ../vfd_swmr_bigset_reader -n $BIGSET_n $options -s $BIGSET_many_s -e 1 -r 16 -c 16 -q & pid_reader=$! # Wait for the reader to finish before signalling the @@ -1116,12 +1116,12 @@ for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-d 1 -t" "-d 1 -t -F" "-d 1 -t done # bigset test for bigger chunks -for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-d 1 -t" "-d 1 -t -F" "-d 1 -t -R" "-d 1 -V" "-d 1 -M" "-d 1 -V -F" "-d 1 -M -F"; do +for options in "-d 1" "-d 1 -F" "-d 2 -l 10" "-d 2 -F -l 10" "-d 1 -t -l 10" "-d 1 -t -F -l 10" "-d 1 -t -R" "-d 1 -V" "-d 1 -M" "-d 1 -V -F" "-d 1 -M -F"; do # - # Test a few big datasets of one and two dimensions. + # Test a few big datasets of two or three dimensions. # # Perform 25 iterations on 10 extensible datasets configured with - # 2D 256x256 chunks or 3D 64x256x256 of 32-bit unsigned integer elements, + # 2D 256x256 chunks or 3D 8x256x256 of 32-bit unsigned integer elements, # expanding each dataset by a chunk in one dimension (up to 25x1 # 256x256 chunks) on each iteration. # @@ -1129,7 +1129,7 @@ for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-d 1 -t" "-d 1 -t -F" "-d 1 -t # in *two* dimensions (up to 25x25 256x256 chunks). # # If testing 3D datasets (-t option), extending each dataset along the - # first dimension (up to 25 64x256x256) + # first dimension (up to 25 8x256x256) # if [ ${do_few_big:-no} = no ]; then @@ -1137,11 +1137,11 @@ for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-d 1 -t" "-d 1 -t -F" "-d 1 -t fi echo launch vfd_swmr_bigset_writer few big, options $options ......may take some time...... catch_out_err_and_rc vfd_swmr_bigset_writer \ - ../vfd_swmr_bigset_writer -n $BIGSET_n $options -s $BIGSET_few_s -e 64 -r 256 -c 256 -q -l 3 & + ../vfd_swmr_bigset_writer -n $BIGSET_n $options -s $BIGSET_few_s -e 8 -r 256 -c 256 -q & pid_writer=$! catch_out_err_and_rc vfd_swmr_bigset_reader \ - ../vfd_swmr_bigset_reader -n $BIGSET_n $options -s $BIGSET_few_s -e 64 -r 256 -c 256 -q -l 3 & + ../vfd_swmr_bigset_reader -n $BIGSET_n $options -s $BIGSET_few_s -e 8 -r 256 -c 256 -q & pid_reader=$! # Wait for the reader to finish before signalling the diff --git a/test/vfd_swmr_bigset_writer.c b/test/vfd_swmr_bigset_writer.c index 956973a..123efbd 100644 --- a/test/vfd_swmr_bigset_writer.c +++ b/test/vfd_swmr_bigset_writer.c @@ -149,6 +149,7 @@ typedef struct { bool test_3d; enum { vds_off, vds_single, vds_multi } vds; bool use_vfd_swmr; + bool use_legacy_swmr; bool use_named_pipe; bool do_perf; bool cross_chunk_read; @@ -214,6 +215,7 @@ state_initializer(void) .test_3d = false, .vds = vds_off, .use_vfd_swmr = true, + .use_legacy_swmr = false, .use_named_pipe = true, .do_perf = false, .cross_chunk_read = false, @@ -256,6 +258,7 @@ usage(const char *progname) "-P: do the performance measurement\n" "-R: flush raw data\n" "-S: do not use VFD SWMR\n" + "-T: use legacy SWMR (-S and -N must also be specified)\n" "-V: use virtual datasets and a single\n" " source file\n" "-a steps: `steps` between adding attributes\n" @@ -339,7 +342,7 @@ state_init(state_t *s, int argc, char **argv) if (tfile) HDfree(tfile); - while ((ch = getopt(argc, argv, "CFMNPRSVa:bc:d:e:f:g:j:k:l:m:n:o:p:qr:s:tu:v:w:")) != -1) { + while ((ch = getopt(argc, argv, "CFMNPRSTVa:bc:d:e:f:g:j:k:l:m:n:o:p:qr:s:tu:v:w:")) != -1) { switch (ch) { case 'C': /* This flag indicates cross-over chunk read during data validation */ @@ -362,6 +365,9 @@ state_init(state_t *s, int argc, char **argv) case 'S': s->use_vfd_swmr = false; break; + case 'T': + s->use_legacy_swmr = true; + break; case 'V': s->vds = vds_single; break; @@ -745,6 +751,18 @@ state_init(state_t *s, int argc, char **argv) TEST_ERROR; } + if (s->use_legacy_swmr) { + if (s->use_vfd_swmr) { + HDfprintf(stderr, "Can't use both VFD SWMR and Legacy SWMR\n"); + TEST_ERROR; + } + + if (s->use_named_pipe) { + HDfprintf(stderr, "Can't use named pipe for the Legacy SWMR\n"); + TEST_ERROR; + } + } + return true; error: @@ -826,14 +844,14 @@ state_destroy(state_t *s) if (s->vds != vds_multi) { if (H5Fvfd_swmr_end_tick(s->file[0]) < 0) { - HDfprintf(stderr, "H5Fclose failed\n"); + HDfprintf(stderr, "H5Fvfd_swmr_end_tick failed\n"); TEST_ERROR; } } else { for (j = 0; j < NELMTS(s->file); j++) if (H5Fvfd_swmr_end_tick(s->file[j]) < 0) { - HDfprintf(stderr, "H5Fclose failed\n"); + HDfprintf(stderr, "H5Fvfd_swmr_end_tick failed\n"); TEST_ERROR; } } @@ -869,7 +887,7 @@ state_destroy(state_t *s) } HDfprintf(stdout, "File close time (for running the writer alone) = %lf seconds\n", - TIME_PASSED(start_time, end_time)); + TIME_PASSED(start_time, end_time)); } if (s->dataset) @@ -1407,9 +1425,8 @@ open_extensible_dset(state_t *s) if (s->test_3d) { if (maxdims3[0] != three_dee_max_dims[0] || maxdims3[1] != three_dee_max_dims[1] || maxdims3[2] != three_dee_max_dims[2]) { - HDfprintf(stderr, - "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE " x %" PRIuHSIZE, - maxdims3[0], maxdims3[1], maxdims3[2]); + HDfprintf(stderr, "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE " x %" PRIuHSIZE, + maxdims3[0], maxdims3[1], maxdims3[2]); TEST_ERROR; } } @@ -1417,17 +1434,17 @@ open_extensible_dset(state_t *s) if (s->expand_2d) { if (maxdims2[0] != two_dee_max_dims[0] || maxdims2[1] != two_dee_max_dims[1] || maxdims2[0] != maxdims2[1]) { - HDfprintf(stderr, "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE, - maxdims2[0], maxdims2[1]); + HDfprintf(stderr, "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE, maxdims2[0], + maxdims2[1]); TEST_ERROR; } } else if (maxdims2[0] != s->one_dee_max_dims[0] || maxdims2[1] != s->one_dee_max_dims[1] || dims2[0] != s->chunk_dims[0]) { HDfprintf(stderr, - "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE - " or columns %" PRIuHSIZE, - maxdims2[0], maxdims2[1], dims2[1]); + "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE + " or columns %" PRIuHSIZE, + maxdims2[0], maxdims2[1], dims2[1]); } } @@ -1479,7 +1496,7 @@ create_dsets(state_t s) } HDfprintf(stdout, "Dataset creation time (for running the writer alone) = %lf seconds\n", - TIME_PASSED(start_time, end_time)); + TIME_PASSED(start_time, end_time)); } return true; @@ -2081,7 +2098,7 @@ verify_dsets(state_t s, np_state_t *np, mat_t *mat) * the validation of the chunks */ if (s.use_named_pipe && below_speed_limit(&(last.time), &(s.ival))) { AT(); - HDfprintf(stderr, "verify_extensible_dset took too long to finish\n"); + HDfprintf(stderr, "Warning: verify_extensible_dset took too long to finish\n"); } /* For checking the time lapse between the writer's finishing writing a batch of chunks @@ -2109,7 +2126,7 @@ verify_dsets(state_t s, np_state_t *np, mat_t *mat) /* Print out the performance information */ if (s.use_named_pipe && s.do_perf && counter) HDfprintf(stdout, "Dataset verification: mean time = %lf, max time = %lf, min time = %lf\n", - total_time / (double)counter, max_time, min_time); + total_time / (double)counter, max_time, min_time); return true; @@ -2396,18 +2413,13 @@ write_dsets(state_t s, np_state_t *np, mat_t *mat) /* Calculate the write speed */ if (s.test_3d) - throughput = - ((double)(sizeof(unsigned int) * s.depth * s.rows * s.cols * s.nsteps * s.ndatasets)) / - time_passed; + throughput = ((double)(sizeof(unsigned int) * s.depth * s.rows * s.cols * s.nsteps * s.ndatasets)) / time_passed; else - throughput = - ((double)(sizeof(unsigned int) * s.rows * s.cols * s.nsteps * s.ndatasets)) / time_passed; + throughput = ((double)(sizeof(unsigned int) * s.rows * s.cols * s.nsteps * s.ndatasets)) / time_passed; /* Print out the performance information */ - HDfprintf(stdout, - "Dataset write time (for running the writer alone) = %lf seconds, write speed = %.2lf " - "bytes/second\n", - time_passed, throughput); + HDfprintf(stdout, "Dataset write time (for running the writer alone) = %lf seconds, write speed = %.2lf bytes/second\n", + time_passed, throughput); } return true; @@ -2544,6 +2556,12 @@ main(int argc, char **argv) TEST_ERROR; } + /* Enable the Legacy SWMR writing mode if specified */ + if (s.use_legacy_swmr && H5Fstart_swmr_write(s.file[0]) < 0) { + HDfprintf(stderr, "failed to start the Legacy SWMR writing mode\n"); + TEST_ERROR; + } + /* Start to write chunks. The writer writes as many chunks as possible within a tick, then * notify the reader. But it doesn't receive back the reader's notice. */ if (!write_dsets(s, &np, mat)) { -- cgit v0.12 From e5c8d80a12721212f8c5ca75d5130f5a5cb7edfa Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 1 Nov 2021 16:14:45 +0000 Subject: Committing clang-format changes --- test/vfd_swmr_bigset_writer.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/test/vfd_swmr_bigset_writer.c b/test/vfd_swmr_bigset_writer.c index 123efbd..77c7b26 100644 --- a/test/vfd_swmr_bigset_writer.c +++ b/test/vfd_swmr_bigset_writer.c @@ -887,7 +887,7 @@ state_destroy(state_t *s) } HDfprintf(stdout, "File close time (for running the writer alone) = %lf seconds\n", - TIME_PASSED(start_time, end_time)); + TIME_PASSED(start_time, end_time)); } if (s->dataset) @@ -1425,8 +1425,9 @@ open_extensible_dset(state_t *s) if (s->test_3d) { if (maxdims3[0] != three_dee_max_dims[0] || maxdims3[1] != three_dee_max_dims[1] || maxdims3[2] != three_dee_max_dims[2]) { - HDfprintf(stderr, "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE " x %" PRIuHSIZE, - maxdims3[0], maxdims3[1], maxdims3[2]); + HDfprintf(stderr, + "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE " x %" PRIuHSIZE, + maxdims3[0], maxdims3[1], maxdims3[2]); TEST_ERROR; } } @@ -1434,17 +1435,17 @@ open_extensible_dset(state_t *s) if (s->expand_2d) { if (maxdims2[0] != two_dee_max_dims[0] || maxdims2[1] != two_dee_max_dims[1] || maxdims2[0] != maxdims2[1]) { - HDfprintf(stderr, "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE, maxdims2[0], - maxdims2[1]); + HDfprintf(stderr, "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE, + maxdims2[0], maxdims2[1]); TEST_ERROR; } } else if (maxdims2[0] != s->one_dee_max_dims[0] || maxdims2[1] != s->one_dee_max_dims[1] || dims2[0] != s->chunk_dims[0]) { HDfprintf(stderr, - "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE - " or columns %" PRIuHSIZE, - maxdims2[0], maxdims2[1], dims2[1]); + "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE + " or columns %" PRIuHSIZE, + maxdims2[0], maxdims2[1], dims2[1]); } } @@ -1496,7 +1497,7 @@ create_dsets(state_t s) } HDfprintf(stdout, "Dataset creation time (for running the writer alone) = %lf seconds\n", - TIME_PASSED(start_time, end_time)); + TIME_PASSED(start_time, end_time)); } return true; @@ -2126,7 +2127,7 @@ verify_dsets(state_t s, np_state_t *np, mat_t *mat) /* Print out the performance information */ if (s.use_named_pipe && s.do_perf && counter) HDfprintf(stdout, "Dataset verification: mean time = %lf, max time = %lf, min time = %lf\n", - total_time / (double)counter, max_time, min_time); + total_time / (double)counter, max_time, min_time); return true; @@ -2413,13 +2414,18 @@ write_dsets(state_t s, np_state_t *np, mat_t *mat) /* Calculate the write speed */ if (s.test_3d) - throughput = ((double)(sizeof(unsigned int) * s.depth * s.rows * s.cols * s.nsteps * s.ndatasets)) / time_passed; + throughput = + ((double)(sizeof(unsigned int) * s.depth * s.rows * s.cols * s.nsteps * s.ndatasets)) / + time_passed; else - throughput = ((double)(sizeof(unsigned int) * s.rows * s.cols * s.nsteps * s.ndatasets)) / time_passed; + throughput = + ((double)(sizeof(unsigned int) * s.rows * s.cols * s.nsteps * s.ndatasets)) / time_passed; /* Print out the performance information */ - HDfprintf(stdout, "Dataset write time (for running the writer alone) = %lf seconds, write speed = %.2lf bytes/second\n", - time_passed, throughput); + HDfprintf(stdout, + "Dataset write time (for running the writer alone) = %lf seconds, write speed = %.2lf " + "bytes/second\n", + time_passed, throughput); } return true; -- cgit v0.12 From 2045b7984b6ffb71cb75393230a11edfed03f3fb Mon Sep 17 00:00:00 2001 From: myang6 Date: Tue, 2 Nov 2021 12:20:14 -0500 Subject: 1. Close the log file when the file closing flag is true in H5F_vfd_swmr_close_or_flush(). 2. Move the log test to the group performance test code with an option. 3. Use constant variables for log message lengths. 4. Misc. clean-up. --- MANIFEST | 1 - src/H5FDvfd_swmr_private.h | 3 - src/H5Fint.c | 33 +- src/H5Fpkg.h | 10 +- src/H5Fvfd_swmr.c | 36 +- test/Makefile.am | 3 - test/vfd_swmr_gperf_writer.c | 37 +- test/vfd_swmr_log_writer.c | 2929 ------------------------------------------ 8 files changed, 77 insertions(+), 2975 deletions(-) delete mode 100644 test/vfd_swmr_log_writer.c diff --git a/MANIFEST b/MANIFEST index 208bfc3..75a7aca 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1444,7 +1444,6 @@ ./test/vfd_swmr_vlstr_writer.c ./test/vfd_swmr_writer.c ./test/vfd_swmr_zoo_writer.c -./test/vfd_swmr_log_writer.c ./test/vfd.c ./test/vol.c ./test/vol_plugin.c diff --git a/src/H5FDvfd_swmr_private.h b/src/H5FDvfd_swmr_private.h index 02e1c44..985bd70 100644 --- a/src/H5FDvfd_swmr_private.h +++ b/src/H5FDvfd_swmr_private.h @@ -84,8 +84,5 @@ H5_DLL herr_t H5F_vfd_swmr_insert_entry_eot(struct H5F_t *f); H5_DLL void H5F_vfd_swmr_update_entry_eot(eot_queue_entry_t *); H5_DLL herr_t H5F_dump_eot_queue(void); -/***************************************/ -/* Log Macros and Functions */ -/***************************************/ #endif /* H5FDvfd_swmr_private_H */ diff --git a/src/H5Fint.c b/src/H5Fint.c index 1adc7d5..c0579bd 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -2014,23 +2014,6 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) /* Short cuts */ shared = file->shared; - /* Set up the VFD SWMR LOG file */ - /* Kent*/ - if (vfd_swmr_config_ptr->version) { - 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 */ - lf = shared->lf; /* Set the file locking flag. If the file is already open, the file @@ -2110,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) diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 3de5a84..3bece42 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -625,7 +625,7 @@ H5_DLL herr_t H5F__reparse_file_lock_variable_test(void); * 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_RELEASE(f, c, number_entry_production, m) is + * 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 @@ -649,21 +649,21 @@ H5_DLL void H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log } \ } while (0) -#define H5F_POST_VFD_SWMR_LOG_ENTRY_RELEASE(fp, entry_type_code, max_code, log_info) \ +#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_RELEASE(f, c, 1, m) on the following lines to - * H5F_POST_VFD_SWMR_LOG_ENTRY_RELEASE(f, c, your_number_entry_production, m) +/* 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_RELEASE(f, c, 1, m) +#define H5F_POST_VFD_SWMR_LOG_ENTRY(f, c, m) H5F_POST_VFD_SWMR_LOG_ENTRY_PRODUCTION(f, c, 1, m) #endif #endif /* H5Fpkg_H */ diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index 476af3e..9404cf4 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -54,6 +54,7 @@ #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. @@ -86,6 +87,12 @@ static const char *H5Fvfd_swmr_log_tags[] = { */ 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 */ /********************/ @@ -350,8 +357,9 @@ 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 or flush info. to the log file, subject to comment out. */ - H5F_POST_VFD_SWMR_LOG_ENTRY(f, 2, "VFD SWMR File close or flush ends"); +#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, 2, "VFD SWMR File close ends"); #endif done: @@ -359,7 +367,7 @@ done: * Please REVIEW to ensure this is the right place to * close the log file. */ - if (shared->vfd_swmr_log_on) { + if (shared->vfd_swmr_log_on && closing) { H5_timer_stop(&(shared->vfd_swmr_log_start_time)); HDfclose(shared->vfd_swmr_log_file_ptr); } @@ -948,11 +956,12 @@ done: if (H5_timer_get_times(shared->vfd_swmr_log_start_time, ¤t_time) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time from H5_timer_get_times") end_elapsed_time = current_time.elapsed; - log_msg = HDmalloc(48); - 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, 0, log_msg); - HDfree(log_msg); + 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, 0, log_msg); + HDfree(log_msg); + } } /* Kent */ FUNC_LEAVE_NOAPI(ret_value) @@ -1988,11 +1997,12 @@ H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log_info) 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, ¤t_time) < 0) { - gettime_error = HDmalloc(14); - 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); + 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; diff --git a/test/Makefile.am b/test/Makefile.am index a97e968..87b2925 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -56,7 +56,6 @@ SCRIPT_DEPEND = error_test$(EXEEXT) err_compat$(EXEEXT) links_env$(EXEEXT) \ vfd_swmr_zoo_reader$(EXEEXT) vfd_swmr_zoo_writer$(EXEEXT) \ vfd_swmr_gperf_reader$(EXEEXT) vfd_swmr_gperf_writer$(EXEEXT) \ vfd_swmr_gfail_reader$(EXEEXT) vfd_swmr_gfail_writer$(EXEEXT) \ - vfd_swmr_log_reader$(EXEEXT) vfd_swmr_log_writer$(EXEEXT) \ vds_env$(EXEEXT) \ vds_swmr_gen$(EXEEXT) vds_swmr_reader$(EXEEXT) vds_swmr_writer$(EXEEXT) if HAVE_SHARED_CONDITIONAL @@ -116,7 +115,6 @@ check_PROGRAMS=$(TEST_PROG) error_test err_compat tcheck_version \ vfd_swmr_attrdset_reader vfd_swmr_attrdset_writer \ vfd_swmr_gperf_reader vfd_swmr_gperf_writer \ vfd_swmr_gfail_reader vfd_swmr_gfail_writer \ - vfd_swmr_log_reader vfd_swmr_log_writer \ vfd_swmr_check_compat \ vfd_swmr_dsetchks_reader vfd_swmr_dsetchks_writer \ swmr_check_compat_vfd vds_env vds_swmr_gen vds_swmr_reader vds_swmr_writer \ @@ -186,7 +184,6 @@ vfd_swmr_bigset_reader_SOURCES=vfd_swmr_bigset_writer.c vfd_swmr_group_reader_SOURCES=vfd_swmr_group_writer.c vfd_swmr_gperf_reader_SOURCES=vfd_swmr_gperf_writer.c vfd_swmr_gfail_reader_SOURCES=vfd_swmr_gfail_writer.c -vfd_swmr_log_reader_SOURCES=vfd_swmr_log_writer.c vfd_swmr_dsetops_reader_SOURCES=vfd_swmr_dsetops_writer.c vfd_swmr_attrdset_writer_SOURCES=vfd_swmr_attrdset_writer.c diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c index e21f931..ad2b373 100644 --- a/test/vfd_swmr_gperf_writer.c +++ b/test/vfd_swmr_gperf_writer.c @@ -12,6 +12,12 @@ /* Description of this program: * This program checks the performance of group creations for VFD SWMR. + * It also has an option to turn on the VFD SWMR logging feature and generates + * a log message for group creations. The performance test illustration is in + * section I. The log feature illustration is in section II. + * + * I. Performance tests with options + * * Currently the group creation time, H5Fopen and H5Fclose time are measured. * After compiling the program, * ./vfd_swmr_gperf_writer -n 1000 -P -N 5 -q @@ -29,6 +35,18 @@ * The program is run with max_lag = 8, tick_len = 4; * The page buffer size is 16384 bytes. The page size is 8192 bytes. * + * II. How to generate log message + * + * ./vfd_swmr_gperf_writer -n 100000 -P -L -q + * will generate 100000 groups, each group has one attribute. It also writes the log message + * to file "log-test" under the same directory. + * To turn on the log feature, one just needs to provide the log file path as + * indicated by the line init_vfd_swmr_log(&config, "./log-test") in the main + * function. The init_vfd_swmr_log is defined inside the vfd_swmr_common.c. + * The "log-test" should include something like: + * 'EOT_PROCESSING_TIME : 0.040 s: Writer time is 1 milliseconds' + * The standard output of performance measurement can help check the correctness in the "log-test". + * */ #define H5F_FRIEND /*suppress error about including H5Fpkg */ @@ -63,6 +81,7 @@ typedef struct { uint32_t max_lag; uint32_t tick_len; bool gperf; + bool glog; double min_gc_time; double max_gc_time; double mean_gc_time; @@ -84,7 +103,7 @@ typedef struct { .file = H5I_INVALID_HID, .one_by_one_sid = H5I_INVALID_HID, .filename = "", \ .filetype = H5T_NATIVE_UINT32, .asteps = 1, .nsteps = 100, .use_vfd_swmr = true, \ .old_style_grp = false, .grp_op_pattern = ' ', .grp_op_test = false, .at_pattern = ' ', \ - .attr_test = false, .tick_len = 4, .max_lag = 7, .gperf = false, .min_gc_time = 100., \ + .attr_test = false, .tick_len = 4, .max_lag = 7, .gperf = false, .glog = false, .min_gc_time = 100., \ .max_gc_time = 0., .mean_gc_time = 0., .total_gc_time = 0., .total_time = 0., .mean_time = 0., \ .fo_total_time = 0., .fc_total_time = 0., .num_attrs = 1, .vlstr_test = false, .ps = 4096, \ .pbs = 4096, .nglevels = 0 \ @@ -95,14 +114,16 @@ usage(const char *progname) { fprintf(stderr, "usage: ./%s -P -n 1000 -N 5 -q (create 1000 groups, each group has 5 attributes)\n" + "usage: ./%s -P -L -n 100000 -q (create 100000 groups and generate log message to file 'log-test')\n" "Options: \n" - " [-P] [-S] [-G] [-t tick_len] [-m max_lag][-B pbs] [-s ps]\n" + " [-P] [-S] [-G] [-L] [-t tick_len] [-m max_lag][-B pbs] [-s ps]\n" " [-n ngroups] [-l ng_levels] [-O grp_op_pattern]\n" " [-N num_attrs] [-V] [-b] [-A at_pattern] [-a steps] [-q]\n" "\n" "-P: carry out the performance test\n" "-S: do not use VFD SWMR\n" "-G: old-style type of group\n" + "-L: Turn on the logging feature.\n" "-t tick_len: length of a tick in tenths of a second.\n" "-m max_lag: maximum expected lag(in ticks) between writer and readers\n" "-B pbs: page Buffer Size in bytes:\n" @@ -174,7 +195,7 @@ usage(const char *progname) " (Don't recommend to use this option for performance test.)\n" "-q: silence printouts, few messages\n" "\n", - progname); + progname,progname); exit(EXIT_FAILURE); } @@ -203,7 +224,7 @@ state_init(state_t *s, int argc, char **argv) if (argc == 1) usage(s->progname); - while ((ch = getopt(argc, argv, "PSGa:bVt:m:B:s:n:qA:N:l:O:")) != -1) { + while ((ch = getopt(argc, argv, "PSGLa:bVt:m:B:s:n:qA:N:l:O:")) != -1) { switch (ch) { case 'P': s->gperf = true; @@ -214,6 +235,9 @@ state_init(state_t *s, int argc, char **argv) case 'G': s->old_style_grp = true; break; + case 'L': + s->glog = true; + break; case 'a': case 'n': case 'N': @@ -2764,6 +2788,11 @@ main(int argc, char **argv) /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ init_vfd_swmr_config(&config, s.tick_len, s.max_lag, writer, FALSE, 128, "./group-shadow"); + /* If the log flag is on, create the log file log-test under the current directory. */ + if(s.glog == true) + init_vfd_swmr_log(&config, "./log-test"); + + /* If old-style option is chosen, use the earliest file format(H5F_LIBVER_EARLIEST) * as the second parameter of H5Pset_libver_bound() that is called by * vfd_swmr_create_fapl. Otherwise, the latest file format(H5F_LIBVER_LATEST) diff --git a/test/vfd_swmr_log_writer.c b/test/vfd_swmr_log_writer.c deleted file mode 100644 index 06b5654..0000000 --- a/test/vfd_swmr_log_writer.c +++ /dev/null @@ -1,2929 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * 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 COPYING file, which can be found at the root of the source code * - * distribution tree, or in https://www.hdfgroup.org/licenses. * - * If you do not have access to either file, you may request a copy from * - * help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* Description of this program: - * This program shows an example on how a VFD log file can be written. - * It is adapted from the group performence test. Most options of the - * group performance test are still kept. - * To turn on the log feature, one just needs to provide the log file path as - * indicated by the line init_vfd_swmr_log(&config, "./log-test") in the main - * function. The init_vfd_swmr_log is defined inside the vfd_swmr_common.c. - * For the demo of the log feature, - * one just needs to do te following: - * After compiling the program, just run the following line - * ./vfd_swmr_log_writer -n 100000 -P -q - * A VFD SWMR log file "log-test" is generated. - * The "log-test" should include something like: - * 'EOT_PROCESSING_TIME : 0.040 s: Writer time is 1 milliseconds' - * This program also checks the performance of group creations for VFD SWMR. - * Currently the group creation time, H5Fopen and H5Fclose time are measured. - * The standard output can help check the contents in the "log-test". - * - */ -#define H5F_FRIEND /*suppress error about including H5Fpkg */ - -#include "hdf5.h" - -#include "H5Fpkg.h" -#include "H5HGprivate.h" -#include "H5VLprivate.h" - -#include "testhdf5.h" -#include "vfd_swmr_common.h" - -#ifndef H5_HAVE_WIN32_API - -#define VS_ATTR_NAME_LEN 21 - -#define TIME_PASSED(X, Y) \ - ((double)((Y.tv_sec - X.tv_sec) * 1000000000 + (Y.tv_nsec - X.tv_nsec))) / 1000000000.0 - -typedef struct { - hid_t file, filetype, one_by_one_sid; - char filename[PATH_MAX]; - char progname[PATH_MAX]; - unsigned int asteps; - unsigned int nsteps; - bool use_vfd_swmr; - bool old_style_grp; - char grp_op_pattern; - bool grp_op_test; - char at_pattern; - bool attr_test; - uint32_t max_lag; - uint32_t tick_len; - bool gperf; - double min_gc_time; - double max_gc_time; - double mean_gc_time; - double total_gc_time; - double total_time; - double mean_time; - double fo_total_time; - double fc_total_time; - unsigned int num_attrs; - bool vlstr_test; - unsigned int ps; - unsigned int pbs; - unsigned int nglevels; -} state_t; - -#define ALL_HID_INITIALIZER \ - (state_t) \ - { \ - .file = H5I_INVALID_HID, .one_by_one_sid = H5I_INVALID_HID, .filename = "", \ - .filetype = H5T_NATIVE_UINT32, .asteps = 1, .nsteps = 100, .use_vfd_swmr = true, \ - .old_style_grp = false, .grp_op_pattern = ' ', .grp_op_test = false, .at_pattern = ' ', \ - .attr_test = false, .tick_len = 4, .max_lag = 7, .gperf = false, .min_gc_time = 100., \ - .max_gc_time = 0., .mean_gc_time = 0., .total_gc_time = 0., .total_time = 0., .mean_time = 0., \ - .fo_total_time = 0., .fc_total_time = 0., .num_attrs = 1, .vlstr_test = false, .ps = 4096, \ - .pbs = 4096, .nglevels = 0 \ - } - -static void -usage(const char *progname) -{ - fprintf(stderr, - "usage: ./%s -P -n 100000 -q (create 100000 groups, each group has 1 attribute)\n" - "Options: \n" - " [-P] [-S] [-G] [-t tick_len] [-m max_lag][-B pbs] [-s ps]\n" - " [-n ngroups] [-l ng_levels] [-O grp_op_pattern]\n" - " [-N num_attrs] [-V] [-b] [-A at_pattern] [-a steps] [-q]\n" - "\n" - "-P: carry out the performance test\n" - "-S: do not use VFD SWMR\n" - "-G: old-style type of group\n" - "-t tick_len: length of a tick in tenths of a second.\n" - "-m max_lag: maximum expected lag(in ticks) between writer and readers\n" - "-B pbs: page Buffer Size in bytes:\n" - " The default value is 4K(4096).\n" - "-s ps: page size used by page aggregation, page buffer and \n" - " the metadata file. \n" - "-n ngroups: the number of groups\n" - "-l ng_levels: the number of level of nested groups. \n" - " If all the groups are under the root group, \n" - " this number should be 0.\n" - "-N num_attrs: the number of attributes \n" - "-V use variable length string attributes for performance test\n" - "-b: write data in big-endian byte order\n" - " (For the performance test, -V overwrites -b)\n" - "-A at_pattern: `at_pattern' for different attribute tests\n" - "-O grp_op_pattern: `grp_op_pattern' for different group operation tests\n" - "-a steps: `steps` between adding attributes\n" - " (Don't recommend to use this option for performance test.)\n" - "-q: silence printouts, few messages\n" - "\n", - progname); - exit(EXIT_FAILURE); -} - -static bool -state_init(state_t *s, int argc, char **argv) -{ - unsigned long tmp; - int ch; - const hsize_t dims = 1; - char * tfile = NULL; - char * end; - - *s = ALL_HID_INITIALIZER; - - if (H5_basename(argv[0], &tfile) < 0) { - printf("H5_basename failed\n"); - TEST_ERROR; - } - - esnprintf(s->progname, sizeof(s->progname), "%s", tfile); - - if (tfile) { - HDfree(tfile); - tfile = NULL; - } - - if (argc == 1) - usage(s->progname); - while ((ch = getopt(argc, argv, "PSGa:bVt:m:B:s:n:qA:N:l:O:")) != -1) { - switch (ch) { - case 'P': - s->gperf = true; - break; - case 'S': - s->use_vfd_swmr = false; - break; - case 'G': - s->old_style_grp = true; - break; - case 'a': - case 'n': - case 'N': - case 'l': - case 't': - case 'm': - case 'B': - case 's': - errno = 0; - tmp = HDstrtoul(optarg, &end, 0); - if (end == optarg || *end != '\0') { - printf("couldn't parse `-%c` argument `%s`\n", ch, optarg); - TEST_ERROR; - } - else if (errno != 0) { - printf("couldn't parse `-%c` argument `%s`\n", ch, optarg); - TEST_ERROR; - } - else if (tmp > UINT_MAX) { - printf("`-%c` argument `%lu` too large\n", ch, tmp); - TEST_ERROR; - } - - if (ch == 'a') - s->asteps = (unsigned)tmp; - else if (ch == 'n') - s->nsteps = (unsigned)tmp; - else if (ch == 'N') - s->num_attrs = (unsigned)tmp; - else if (ch == 'l') - s->nglevels = (unsigned)tmp; - else if (ch == 't') - s->tick_len = (unsigned)tmp; - else if (ch == 'm') - s->max_lag = (unsigned)tmp; - else if (ch == 's') - s->ps = (unsigned)tmp; - else if (ch == 'B') - s->pbs = (unsigned)tmp; - break; - case 'b': - s->filetype = H5T_STD_U32BE; - break; - case 'V': - s->vlstr_test = true; - break; - case 'O': - if (HDstrcmp(optarg, "grp-creation") == 0) - s->grp_op_pattern = 'c'; - else if (HDstrcmp(optarg, "grp-deletion") == 0) - s->grp_op_pattern = 'd'; - else if (HDstrcmp(optarg, "grp-move") == 0) - s->grp_op_pattern = 'm'; - else if (HDstrcmp(optarg, "grp-ins-links") == 0) - s->grp_op_pattern = 'i'; - else if (HDstrcmp(optarg, "grp-del-links") == 0) - s->grp_op_pattern = 'D'; - else if (HDstrcmp(optarg, "grp-compact-t-dense") == 0) - s->grp_op_pattern = 't'; - else if (HDstrcmp(optarg, "grp-dense-t-compact") == 0) - s->grp_op_pattern = 'T'; - else { - printf("Invalid -O argument \"%s\"", optarg); - TEST_ERROR; - } - break; - case 'A': - if (HDstrcmp(optarg, "compact") == 0) - s->at_pattern = 'c'; - else if (HDstrcmp(optarg, "dense") == 0) - s->at_pattern = 'd'; - else if (HDstrcmp(optarg, "compact-add-to-dense") == 0) - s->at_pattern = 't'; - else if (HDstrcmp(optarg, "compact-del") == 0) - s->at_pattern = 'C'; - else if (HDstrcmp(optarg, "dense-del") == 0) - s->at_pattern = 'D'; - else if (HDstrcmp(optarg, "dense-del-to-compact") == 0) - s->at_pattern = 'T'; - else if (HDstrcmp(optarg, "modify") == 0) - s->at_pattern = 'M'; - else if (HDstrcmp(optarg, "add-vstr") == 0) - s->at_pattern = 'v'; - else if (HDstrcmp(optarg, "remove-vstr") == 0) - s->at_pattern = 'r'; - else if (HDstrcmp(optarg, "modify-vstr") == 0) - s->at_pattern = 'm'; - else if (HDstrcmp(optarg, "add-ohr-block") == 0) - s->at_pattern = 'a'; - else if (HDstrcmp(optarg, "del-ohr-block") == 0) - s->at_pattern = 'R'; - else { - printf("Invalid -A argument \"%s\"", optarg); - TEST_ERROR; - } - break; - case 'q': - verbosity = 0; - break; - case '?': - default: - usage(s->progname); - break; - } - } - argc -= optind; - argv += optind; - - if (s->grp_op_pattern != ' ') - s->grp_op_test = true; - if (s->at_pattern != ' ') - s->attr_test = true; - - if (!s->grp_op_test) { - if (s->asteps < 1 || s->asteps > s->nsteps) { - printf("attribute interval is out of bounds\n"); - TEST_ERROR; - } - } - - if (s->grp_op_test && s->attr_test) { - printf("Cannot test both group operation and attribute tests!\n"); - printf("Attribute tests are ignored.\n"); - } - - if (argc > 0) { - printf("unexpected command-line arguments\n"); - TEST_ERROR; - } - - /* space for attributes */ - if ((s->one_by_one_sid = H5Screate_simple(1, &dims, &dims)) < 0) { - printf("H5Screate_simple failed\n"); - TEST_ERROR; - } - - esnprintf(s->filename, sizeof(s->filename), "vfd_swmr_group.h5"); - - return true; - -error: - if (tfile) - HDfree(tfile); - return false; -} - -/*------------------------------------------------------------------------- - * Function: check_ohr_num_chunk - * - * Purpose: Check if the number of object header chunks is as expected. - * - * Parameters: hid_t oid - * HDF5 object ID (in this file: means group ID) - * - * bool one_chunk_ohr - * flag to indicate if the object header chunk is 1 or greater - * 1: true - * greater than 1: false - * - * Return: Success: true - * Failure: false - * - *------------------------------------------------------------------------- - */ - -static bool -check_ohr_num_chunk(hid_t g, bool one_chunk_ohr) -{ - - H5O_native_info_t ninfo; - - /* Get the object information */ - if (H5Oget_native_info(g, &ninfo, H5O_NATIVE_INFO_HDR) < 0) { - printf("H5Oget_native_info failed\n"); - TEST_ERROR; - } - - if (true == one_chunk_ohr) { - if (ninfo.hdr.nchunks != 1) { - printf("Object header should have only one chunk,but it is not.\n"); - TEST_ERROR; - } - } - else { - if (ninfo.hdr.nchunks <= 1) { - printf("Object header should have more than one chunk,but it is not.\n"); - TEST_ERROR; - } - } - - return true; - -error: - return false; -} - -/*------------------------------------------------------------------------- - * Function: add_attr - * - * Purpose: Add attributes to a group. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * hid_t oid - * HDF5 object ID (in this file: means group ID) - * - * unsigned int which - * The number of iterations for group creation, use to generate - * newly created group name. The group name is "group-which". - * - * unsigned num_attrs - * The number of attributes to be created - * - * const char*aname_fmt - * The attribute name template used to create unique attribute names. - * - * unsigned int g_which - * This parameter is used to generate correct group name in a key - * debugging message. - * - * Return: Success: true - * Failure: false - * - *------------------------------------------------------------------------- - */ - -static bool -add_attr(state_t *s, hid_t oid, unsigned int which, unsigned num_attrs, const char *aname_fmt, - unsigned int g_which) -{ - - char attrname[VS_ATTR_NAME_LEN]; - unsigned u; - unsigned attr_value; - hid_t aid = H5I_INVALID_HID; - hid_t amtype = H5I_INVALID_HID; - hid_t atype = s->filetype; - hid_t sid = s->one_by_one_sid; - - /* Need to obtain native datatype for H5Aread */ - if ((amtype = H5Tget_native_type(atype, H5T_DIR_ASCEND)) < 0) { - printf("H5Tget_native_type failed\n"); - TEST_ERROR; - } - - for (u = 0; u < num_attrs; u++) { - - /* Create attribute */ - /* Construct attribute name like attr-0-0 */ - HDsprintf(attrname, aname_fmt, which, u); - if ((aid = H5Acreate2(oid, attrname, atype, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) { - printf("H5Acreate2 failed\n"); - TEST_ERROR; - } - - attr_value = u + which; - - dbgf(1, "setting attribute %s on group %u to %u\n", attrname, g_which, u + which); - - /* Write data into the attribute */ - if (H5Awrite(aid, amtype, &attr_value) < 0) { - printf("H5Awrite failed\n"); - TEST_ERROR; - } - - /* Close attribute */ - if (H5Aclose(aid) < 0) { - printf("H5Aclose failed\n"); - TEST_ERROR; - } - - /* If coming to an "object header continuation block" test, - * we need to check if this test behaves as expected. */ - if (s->at_pattern == 'a' || s->at_pattern == 'R') { - if (false == check_ohr_num_chunk(oid, false)) { - printf("An object header continuation block should be created. \n"); - printf("But it is not.\n"); - TEST_ERROR; - } - } - - } /* end for */ - - if (H5Tclose(amtype) < 0) { - TEST_ERROR; - } - - return true; - -error: - H5E_BEGIN_TRY - { - H5Aclose(aid); - H5Tclose(amtype); - } - H5E_END_TRY; - - return false; -} - -/*------------------------------------------------------------------------- - * Function: add_vlstr_attr - * - * Purpose: Add a variable length string attribute to a group. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * hid_t g - * HDF5 object ID (in this file: means group ID) - * - * unsigned int which - * The number of iterations for group creation, use to generate - * newly created group and attribute names. - * The group name is "group-which" and the attribute name - * is "attr-which". - * - * - * Return: Success: true - * Failure: false - * - * Note: This is for the "vstr" test. - *------------------------------------------------------------------------- - */ - -static bool -add_vlstr_attr(state_t *s, hid_t g, unsigned int which) -{ - - hid_t aid = H5I_INVALID_HID; - hid_t atype = H5I_INVALID_HID; - char name[VS_ATTR_NAME_LEN]; - char *astr_val = NULL; - hid_t sid = s->one_by_one_sid; - - /* Allocate buffer for the VL string value */ - astr_val = HDmalloc(VS_ATTR_NAME_LEN); - if (astr_val == NULL) { - printf("Allocate memory for VL string failed.\n"); - TEST_ERROR; - } - - /* Assign the VL string value and the attribute name.. */ - HDsprintf(astr_val, "%u", which); - esnprintf(name, sizeof(name), "attr-%u", which); - - dbgf(1, "setting attribute %s on group %u to %u\n", name, which, which); - - /* Create a datatype to refer to. */ - if ((atype = H5Tcopy(H5T_C_S1)) < 0) { - printf("Cannot create variable length datatype.\n"); - TEST_ERROR; - } - - if (H5Tset_size(atype, H5T_VARIABLE) < 0) { - printf("Cannot set variable length datatype.\n"); - TEST_ERROR; - } - - /* Generate the VL string attribute.*/ - if ((aid = H5Acreate2(g, name, atype, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) { - printf("H5Acreate2 failed.\n"); - TEST_ERROR; - } - - if (H5Awrite(aid, atype, &astr_val) < 0) { - printf("H5Awrite failed.\n"); - TEST_ERROR; - } - - if (H5Tclose(atype) < 0) { - printf("H5Tclose() failed\n"); - TEST_ERROR; - } - if (H5Aclose(aid) < 0) { - printf("H5Aclose() failed\n"); - TEST_ERROR; - } - - HDfree(astr_val); - - return true; - -error: - H5E_BEGIN_TRY - { - H5Aclose(aid); - H5Tclose(atype); - } - H5E_END_TRY; - - if (astr_val) - HDfree(astr_val); - - return false; -} - -/*------------------------------------------------------------------------- - * Function: add_vlstr_attrs - * - * Purpose: Add variable length string attributes to a group. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * hid_t g - * HDF5 object ID (in this file: means group ID) - * - * unsigned int which - * The number of iterations for group creation, use to generate - * newly created group and attribute names. - * The group name is "group-which". The attribute names - * are "attr-which","attr-which+1".... - * - * - * Return: Success: true - * Failure: false - * - * Note: This is for the performance test that has the VL string type. - *------------------------------------------------------------------------- - */ - -static bool -add_vlstr_attrs(state_t *s, hid_t g, unsigned int which, unsigned int num_attrs) -{ - unsigned u; - bool ret_value = true; - for (u = 0; u < num_attrs; u++) { - ret_value = add_vlstr_attr(s, g, u + which); - if (ret_value == false) - break; - } - - return ret_value; -} - -/*------------------------------------------------------------------------- - * Function: add_default_group_attr - * - * Purpose: Add an attribute to a group. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * hid_t g - * HDF5 object ID (in this file: means group ID) - * - * unsigned int which - * The number of iterations for group creation, use to generate - * newly created group and attribute names. - * The group name is "group-which" and the attribute name - * is "attr-which". - * - * - * Return: Success: true - * Failure: false - * - * Note: This function is used for the "dense" storage test. - * It is also used by the group-only, "add-ohr-block" - * and "del-ohr-block" tests. - *------------------------------------------------------------------------- - */ - -static bool -add_default_group_attr(state_t *s, hid_t g, unsigned int which) -{ - - const char *aname_format = "attr-%u-%u"; - - /* Note: the number of attributes can be configurable, - * the default number of attribute is 1. - */ - /* If the vl string attribute type is chosen. */ - if (s->vlstr_test == true) - return add_vlstr_attrs(s, g, which, s->num_attrs); - else - return add_attr(s, g, which, s->num_attrs, aname_format, which); -} - -/*------------------------------------------------------------------------- - * Function: del_one_attr - * - * Purpose: delete one attribute in a group. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * hid_t obj_id - * HDF5 object ID (in this file: means group ID) - * - * bool is_dense - * if the deleted attribute is for checking the dense storage - * - * bool is_vl_or_ohrc - * if the deleted attribute is a VL string or for object header - * continuation check test - * - * unsigned int which - * The number of iterations for group creation, use to generate - * newly created group and attribute names. - * The group name is "group-which" and the attribute names - * according to if this attribute is a VL string or for checking - * the dense storage or the storage transition from dense to - * compact. - * - * - * Return: Success: true - * Failure: false - * - *------------------------------------------------------------------------- - */ - -static bool -del_one_attr(state_t *s, hid_t obj_id, bool is_dense, bool is_vl_or_ohrc, unsigned int which) -{ - - char attrname[VS_ATTR_NAME_LEN]; - - /*attribute name template for the dense storage related deletion operation */ - const char *aname_format_d = "attr-d-%u-%u"; - - /*attribute name template used for general attribute deletion operation */ - const char *aname_format = "attr-%u-%u"; - - /*attribute name template used for VL string attribute deletion - * or object header continuation check operations */ - const char *aname_format_vl = "attr-%u"; - - dbgf(2, "writer: coming to delete the attribute.\n"); - - /* Construct the attribute name */ - if (is_dense == true) - HDsprintf(attrname, aname_format_d, which, 0); - else if (is_vl_or_ohrc == true) - HDsprintf(attrname, aname_format_vl, which, 0); - else - HDsprintf(attrname, aname_format, which, 0); - - /* Delete the attribute */ - if (H5Adelete(obj_id, attrname) < 0) { - printf("H5Adelete() failed\n"); - TEST_ERROR; - } - - /* If coming to an "object header continuation block" test, - * we need to check if this test behaves as expected. */ - if (s->at_pattern == 'R') { - if (false == check_ohr_num_chunk(obj_id, true)) { - printf("The object header chunk should not continue. \n"); - TEST_ERROR; - } - } - return true; - -error: - return false; -} - -/*------------------------------------------------------------------------- - * Function: add_del_vlstr_attr - * - * Purpose: Add a variable length string attribute - * then delete this attribute in this a group. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * hid_t g - * HDF5 object ID (in this file: means group ID) - * - * unsigned int which - * The number of iterations for group creation, use to generate - * newly created group and attribute names. - * The group name is "group-which" and the attribute name - * is "attr-which". - * - * - * Return: Success: true - * Failure: false - * - * Note: This is for the "remove-vstr" test. - *------------------------------------------------------------------------- - */ - -static bool -add_del_vlstr_attr(state_t *s, hid_t g, unsigned int which) -{ - - bool ret_value = false; - - /* Add a VL string attribute then delete it. */ - ret_value = add_vlstr_attr(s, g, which); - if (ret_value == true) - ret_value = del_one_attr(s, g, false, true, which); - - return ret_value; -} - -/*------------------------------------------------------------------------- - * Function: modify_attr - * - * Purpose: Modify the value of an attribute in a group. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * hid_t g - * HDF5 object ID (in this file: means group ID) - * - * const char*aname_fmt - * The attribute name template used to create unique attribute names. - * - * unsigned int which - * The number of iterations for group creation, use to generate - * newly created group name. The group name is "group-which". - * - * - * Return: Success: true - * Failure: false - * - *------------------------------------------------------------------------- - */ - -static bool -modify_attr(state_t *s, hid_t g, const char *aname_fmt, unsigned int which) -{ - - char attrname[VS_ATTR_NAME_LEN]; - hid_t aid = H5I_INVALID_HID; - hid_t amtype = H5I_INVALID_HID; - unsigned int modify_value; - - HDsprintf(attrname, aname_fmt, which, 0); - if ((aid = H5Aopen(g, attrname, H5P_DEFAULT)) < 0) { - printf("H5Aopen failed\n"); - TEST_ERROR; - } - - if ((amtype = H5Tget_native_type(s->filetype, H5T_DIR_ASCEND)) < 0) { - printf("H5Tget_native_type failed\n"); - TEST_ERROR; - } - - /* Make a large number to verify the change easily */ - modify_value = which + 10000; - - if (H5Awrite(aid, amtype, &modify_value) < 0) { - printf("H5Awrite failed\n"); - TEST_ERROR; - } - if (H5Tclose(amtype) < 0) { - printf("H5Tclose failed\n"); - TEST_ERROR; - } - if (H5Aclose(aid) < 0) { - printf("H5Aclose failed\n"); - TEST_ERROR; - } - - return true; -error: - H5E_BEGIN_TRY - { - H5Aclose(aid); - H5Tclose(aid); - } - H5E_END_TRY; - - return false; -} - -/*------------------------------------------------------------------------- - * Function: modify_vlstr_attr - * - * Purpose: Modify the value of an VL string attribute in a group. - * - * Parameters: - * hid_t g - * HDF5 object ID (in this file: means group ID) - * - * unsigned int which - * The number of iterations for group creation, use to generate - * newly created group name. The group name is "group-which". - * - * - * Return: Success: true - * Failure: false - * - *------------------------------------------------------------------------- - */ - -static bool -modify_vlstr_attr(hid_t g, unsigned int which) -{ - - hid_t aid = H5I_INVALID_HID; - hid_t atype = H5I_INVALID_HID; - char name[VS_ATTR_NAME_LEN]; - char *astr_val = NULL; - - astr_val = HDmalloc(VS_ATTR_NAME_LEN); - if (astr_val == NULL) { - printf("Allocate memory for VL string failed.\n"); - TEST_ERROR; - } - - /* Change the VL string value and create the attribute name. */ - HDsprintf(astr_val, "%u%c", which, 'A'); - esnprintf(name, sizeof(name), "attr-%u", which); - - dbgf(1, "setting attribute %s on group %u to %u\n", name, which, which); - - /* Create a datatype to refer to. */ - if ((atype = H5Tcopy(H5T_C_S1)) < 0) { - printf("Cannot create variable length datatype.\n"); - TEST_ERROR; - } - - if (H5Tset_size(atype, H5T_VARIABLE) < 0) { - printf("Cannot set variable length datatype.\n"); - TEST_ERROR; - } - - /* Open this attribute. */ - if ((aid = H5Aopen(g, name, H5P_DEFAULT)) < 0) { - printf("H5Aopen failed.\n"); - TEST_ERROR; - } - - dbgf(1, "The modified VL string value is %s \n", astr_val); - - if (H5Awrite(aid, atype, &astr_val) < 0) { - printf("H5Awrite failed.\n"); - TEST_ERROR; - } - - if (H5Tclose(atype) < 0) { - printf("H5Tclose() failed\n"); - TEST_ERROR; - } - - if (H5Aclose(aid) < 0) { - printf("H5Aclose() failed\n"); - TEST_ERROR; - } - - HDfree(astr_val); - - return true; - -error: - H5E_BEGIN_TRY - { - H5Aclose(aid); - H5Tclose(atype); - } - H5E_END_TRY; - - if (astr_val) - HDfree(astr_val); - - return false; -} - -/*------------------------------------------------------------------------- - * Function: add_modify_vlstr_attr - * - * Purpose: Add a variable length string attribute - * then modify this attribute in the group. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * hid_t g - * HDF5 object ID (in this file: means group ID) - * - * unsigned int which - * The number of iterations for group creation, use to generate - * newly created group and attribute names. - * The group name is "group-which" and the attribute name - * is "attr-which". - * - * - * Return: Success: true - * Failure: false - * - * Note: This is for the "modify-vstr" test. - *------------------------------------------------------------------------- - */ - -static bool -add_modify_vlstr_attr(state_t *s, hid_t g, unsigned int which) -{ - - bool ret_value = false; - ret_value = add_vlstr_attr(s, g, which); - if (true == ret_value) - ret_value = modify_vlstr_attr(g, which); - - return ret_value; -} - -/*------------------------------------------------------------------------- - * Function: add_attrs_compact - * - * Purpose: Add some attributes to the group. - * the number of attributes should be the maximal number of - * attributes that the compact storage can hold - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * hid_t g - * HDF5 object ID (in this file: means group ID) - * - * hid_t gcpl - * Object creation property list ID - * - * unsigned int which - * The number of iterations for group creation, use to generate - * newly created group and attribute names. - * The group name is "group-which" and the attribute name - * is "attr-which". - * - * - * Return: Success: true - * Failure: false - * - * Note: This is for the "modify-vstr" test. - * For attribute compact/dense storage, check the reference - * manual of H5Pget_attr_phase_change. - *------------------------------------------------------------------------- - */ - -static bool -add_attrs_compact(state_t *s, hid_t g, hid_t gcpl, unsigned int which) -{ - - unsigned max_compact = 0; - unsigned min_dense = 0; - const char *aname_format = "attr-%u-%u"; - - if (s->old_style_grp) - max_compact = 2; - else { - /* Obtain the maximal number of attributes to be stored in compact - * storage and the minimal number of attributes to be stored in - * dense storage. */ - if (H5Pget_attr_phase_change(gcpl, &max_compact, &min_dense) < 0) { - printf("H5Pget_attr_phase_change() failed\n"); - TEST_ERROR; - } - } - - /* Add max_compact attributes, these attributes are stored in - * compact storage. */ - return add_attr(s, g, which, max_compact, aname_format, which); - -error: - return false; -} - -/*------------------------------------------------------------------------- - * Function: add_attrs_compact_dense - * - * Purpose: Add some attributes to the group. - * First, the number of attributes should be the maximal number - * of attributes that the compact storage can hold. - * Then, add another atribute, the storage becomes dense. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * hid_t g - * HDF5 object ID (in this file: means group ID) - * - * hid_t gcpl - * Object creation property list ID - * - * unsigned int which - * The number of iterations for group creation, use to generate - * newly created group and attribute names. - * - * Return: Success: true - * Failure: false - * - * Note: This is for the "compact-to-dense" test. - * For attribute compact/dense storage, check the reference - * manual of H5Pget_attr_phase_change. - *------------------------------------------------------------------------- - */ - -static bool -add_attrs_compact_dense(state_t *s, hid_t g, hid_t gcpl, unsigned int which) -{ - - unsigned max_compact = 0; - unsigned min_dense = 0; - const char *aname_format = "attr-d-%u-%u"; - bool ret_value = false; - - if (H5Pget_attr_phase_change(gcpl, &max_compact, &min_dense) < 0) { - printf("H5Pget_attr_phase_change failed\n"); - TEST_ERROR; - } - - /* Add attributes, until just before converting to dense storage */ - ret_value = add_attrs_compact(s, g, gcpl, which); - - /* Add another attribute, the storage becomes dense. */ - if (ret_value == true) - ret_value = add_attr(s, g, which + max_compact, 1, aname_format, which); - - return ret_value; - -error: - return false; -} - -/*------------------------------------------------------------------------- - * Function: del_attrs_compact_dense_compact - * - * Purpose: delete some attributes in the group. - * The number of attributes are deleted in such a way - * that the attribute storage changes from compact to - * dense then to compact again. - * - * Parameters: hid_t g - * HDF5 object ID (in this file: means group ID) - * - * hid_t gcpl - * Object creation property list ID - * - * unsigned int which - * The number of iterations for group creation, use to generate - * newly created group and attribute names. - * - * Return: Success: true - * Failure: false - * - * Note: This is an internal function used by the - * "dense-del-to-compact" test. - * For attribute compact/dense storage, check the reference - * manual of H5Pget_attr_phase_change. - *------------------------------------------------------------------------- - */ - -static bool -del_attrs_compact_dense_compact(hid_t obj_id, hid_t gcpl, unsigned int which) -{ - - unsigned max_compact = 0; - unsigned min_dense = 0; - unsigned u = 0; - - char attrname[VS_ATTR_NAME_LEN]; - const char *aname_format = "attr-%u-%u"; - const char *adname_format = "attr-d-%u-%u"; - - /* Obtain the maximal number of attributes to be stored in compact - * storage and the minimal number of attributes to be stored in - * dense storage. */ - if (H5Pget_attr_phase_change(gcpl, &max_compact, &min_dense) < 0) { - printf("H5Pget_attr_phase_change failed\n"); - TEST_ERROR; - } - u = max_compact + 1; - - /* delete a number of attributes so that the attribute storage just becomes dense.*/ - for (u--; u >= (min_dense - 1); u--) { - HDsprintf(attrname, aname_format, which, max_compact - u); - if (H5Adelete(obj_id, attrname) < 0) { - printf("H5Adelete failed\n"); - TEST_ERROR; - } - } - - /* The writer deletes another attribute, the storage is - * still dense. However, the attribute to be deleted - * doesn't follow the previous for loop. It may be - * in different location in the object header. Just add - * a litter variation to check if this operation is successful. - * The attribute name to be deleted is attr-max_compact+which-0 - */ - - HDsprintf(attrname, adname_format, max_compact + which, 0); - if (H5Adelete(obj_id, attrname) < 0) { - printf("H5Adelete failed\n"); - TEST_ERROR; - } - - return true; - -error: - return false; -} - -/*------------------------------------------------------------------------- - * Function: add_del_attrs_compact - * - * Purpose: Add some attributes to the group and then delete one attribute. - * First, the number of attributes to be added should be the - * maximal number of attributes that the compact storage can hold. - * Then, delete one atribute, the storage is still compact. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * hid_t g - * HDF5 object ID (in this file: means group ID) - * - * hid_t gcpl - * Object creation property list ID - * - * unsigned int which - * The number of iterations for group creation, use to generate - * newly created group and attribute names. - * - * Return: Success: true - * Failure: false - * - * Note: This is for the "compact-del" test. - * For attribute compact/dense storage, check the reference - * manual of H5Pget_attr_phase_change. - *------------------------------------------------------------------------- - */ - -static bool -add_del_attrs_compact(state_t *s, hid_t g, hid_t gcpl, unsigned int which) -{ - - bool ret_value = false; - ret_value = add_attrs_compact(s, g, gcpl, which); - if (ret_value == true) { - dbgf(2, "writer: before deleting the attribute.\n"); - ret_value = del_one_attr(s, g, false, false, which); - } - - return ret_value; -} - -/*------------------------------------------------------------------------- - * Function: add_del_attrs_compact_dense - * - * Purpose: Add some attributes to the group and then delete one attribute. - * First, the number of attributes to be added exceeds - * the maximal number of attributes that the compact storage can hold. - * The storage changes from compact to dense. - * Then, delete one atribute, the storage is still dense. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * hid_t g - * HDF5 object ID (in this file: means group ID) - * - * hid_t gcpl - * Object creation property list ID - * - * unsigned int which - * The number of iterations for group creation, use to generate - * newly created group and attribute names. - * - * Return: Success: true - * Failure: false - * - * Note: This is for the "dense-del" test. - * For attribute compact/dense storage, check the reference - * manual of H5Pget_attr_phase_change. - *------------------------------------------------------------------------- - */ - -static bool -add_del_attrs_compact_dense(state_t *s, hid_t g, hid_t gcpl, unsigned int which) -{ - - bool ret_value = false; - unsigned max_compact = 0; - unsigned min_dense = 0; - - if (H5Pget_attr_phase_change(gcpl, &max_compact, &min_dense) < 0) { - printf("H5Pget_attr_phase_change failed\n"); - TEST_ERROR; - } - - ret_value = add_attrs_compact_dense(s, g, gcpl, which); - if (ret_value == true) - ret_value = del_one_attr(s, g, true, false, which + max_compact); - - return ret_value; - -error: - return false; -} - -/*------------------------------------------------------------------------- - * Function: add_del_attrs_compact_dense_compact - * - * Purpose: Add attributes to the group and then delete some of them. - * First, the number of attributes to be added exceeds - * the maximal number of attributes that the compact storage can hold. - * The storage changes from compact to dense. - * Then, delete some attributes, the storage changes from - * dense to compact again. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * hid_t g - * HDF5 object ID (in this file: means group ID) - * - * hid_t gcpl - * Object creation property list ID - * - * unsigned int which - * The number of iterations for group creation, use to generate - * newly created group and attribute names. - * - * Return: Success: true - * Failure: false - * - * Note: This is for the "dense-del-to-compact" test. - * For attribute compact/dense storage, check the reference - * manual of H5Pget_attr_phase_change. - *------------------------------------------------------------------------- - */ - -static bool -add_del_attrs_compact_dense_compact(state_t *s, hid_t g, hid_t gcpl, unsigned int which) -{ - - bool ret_value = false; - ret_value = add_attrs_compact_dense(s, g, gcpl, which); - if (ret_value == true) - ret_value = del_attrs_compact_dense_compact(g, gcpl, which); - - return ret_value; -} - -/*------------------------------------------------------------------------- - * Function: add_modify_default_group_attr - * - * Purpose: Add an attribute then modify the value to a group. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * hid_t g - * HDF5 object ID (in this file: means group ID) - * - * unsigned int which - * The number of iterations for group creation, use to generate - * newly created group and attribute names. - * The group name is "group-which" and the attribute name - * is "attr-which". - * - * - * Return: Success: true - * Failure: false - * - * Note: This function is used for the "modify" test. - *------------------------------------------------------------------------- - */ - -static bool -add_modify_default_group_attr(state_t *s, hid_t g, unsigned int which) -{ - - bool ret_value = false; - const char *aname_format = "attr-%u"; - ret_value = add_default_group_attr(s, g, which); - if (ret_value == true) - ret_value = modify_attr(s, g, aname_format, which); - return ret_value; -} - -/*------------------------------------------------------------------------- - * Function: del_ohr_block_attr - * - * Purpose: Add an attribute to force creation of object header - * continuation block and remove this attribute to delete - * the object header continuation block - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * hid_t g - * HDF5 object ID (in this file: means group ID) - * - * unsigned int which - * The number of iterations for group creation, use to generate - * newly created group and attribute names. - * The group name is "group-which" and the attribute name - * is "attr-which". - * - * - * Return: Success: true - * Failure: false - * - * Note: This function is used for the - * "deletion of object header continuation block" test. - *------------------------------------------------------------------------- - */ - -static bool -del_ohr_block_attr(state_t *s, hid_t g, unsigned int which) -{ - - bool ret_value = false; - ret_value = add_default_group_attr(s, g, which); - if (ret_value == true) - ret_value = del_one_attr(s, g, false, true, which); - return ret_value; -} -/*------------------------------------------------------------------------- - * Function: add_group_attribute - * - * Purpose: Check the attribute test pattern and then call the - * correponding test function.. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * hid_t g - * HDF5 object ID (in this file: means group ID) - * - * hid_t gcpl - * Object creation property list ID - * - * unsigned int which - * The number of iterations for group creation, use to generate - * newly created group and attribute names. - * - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the write_group() function. - *------------------------------------------------------------------------- - */ - -static bool -add_group_attribute(state_t *s, hid_t g, hid_t gcpl, unsigned int which) -{ - - bool ret_value = false; - char test_pattern = s->at_pattern; - - switch (test_pattern) { - case 'c': - ret_value = add_attrs_compact(s, g, gcpl, which); - break; - case 't': - ret_value = add_attrs_compact_dense(s, g, gcpl, which); - break; - case 'C': - ret_value = add_del_attrs_compact(s, g, gcpl, which); - break; - case 'D': - ret_value = add_del_attrs_compact_dense(s, g, gcpl, which); - break; - case 'T': - ret_value = add_del_attrs_compact_dense_compact(s, g, gcpl, which); - break; - case 'M': - ret_value = add_modify_default_group_attr(s, g, which); - break; - case 'v': - ret_value = add_vlstr_attr(s, g, which); - break; - case 'r': - ret_value = add_del_vlstr_attr(s, g, which); - break; - case 'm': - ret_value = add_modify_vlstr_attr(s, g, which); - break; - case 'R': - ret_value = del_ohr_block_attr(s, g, which); - break; - case 'a': - case 'd': - case ' ': - default: - ret_value = add_default_group_attr(s, g, which); - break; - } - return ret_value; -} - -/*------------------------------------------------------------------------- - * Function: write_group - * - * Purpose: Create a group and carry out attribute operations(add,delete etc.) - * according to the attribute test pattern. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * unsigned int which - * The number of iterations for group creation - * - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the main() function. - *------------------------------------------------------------------------- - */ - -static bool -write_group(state_t *s, unsigned int which) -{ - char name[sizeof("/group-9999999999")]; - hid_t g = H5I_INVALID_HID; - hid_t dummy_d = H5I_INVALID_HID; - hid_t gcpl = H5I_INVALID_HID; - bool result = true; - H5G_info_t group_info; - struct timespec start_time, end_time; - double temp_time; - - if (which >= s->nsteps) { - printf("Number of created groups is out of bounds\n"); - TEST_ERROR; - } - - esnprintf(name, sizeof(name), "/group-%u", which); - - if (s->old_style_grp) - gcpl = H5P_DEFAULT; - else { - gcpl = H5Pcreate(H5P_GROUP_CREATE); - if (gcpl < 0) { - printf("H5Pcreate failed\n"); - TEST_ERROR; - } - - /* If we test the dense storage, change the attribute phase. */ - if (s->at_pattern == 'd') { - if (H5Pset_attr_phase_change(gcpl, 0, 0) < 0) { - printf("H5Pset_attr_phase_change failed for the dense storage.\n"); - TEST_ERROR; - } - } - } - - if (s->gperf) { - - if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { - - fprintf(stderr, "HDclock_gettime failed"); - - TEST_ERROR; - } - } - - if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, gcpl, H5P_DEFAULT)) < 0) { - printf("H5Gcreate2 failed\n"); - TEST_ERROR; - } - - if (s->gperf) { - - if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { - - fprintf(stderr, "HDclock_gettime failed"); - - TEST_ERROR; - } - - temp_time = TIME_PASSED(start_time, end_time); - if (temp_time < s->min_gc_time) - s->min_gc_time = temp_time; - if (temp_time > s->max_gc_time) - s->max_gc_time = temp_time; - s->total_gc_time += temp_time; - } - - /* We need to create a dummy dataset for the object header continuation block test. */ - if (s->at_pattern == 'a' || s->at_pattern == 'R') { - if ((dummy_d = H5Dcreate2(g, "Dataset", H5T_NATIVE_INT, s->one_by_one_sid, H5P_DEFAULT, H5P_DEFAULT, - H5P_DEFAULT)) < 0) { - printf("H5Dcreate2 failed\n"); - TEST_ERROR; - } - } - /* We only need to check the first group */ - if (which == 0) { - if (H5Gget_info(g, &group_info) < 0) { - printf("H5Gget_info failed\n"); - TEST_ERROR; - } - - if (s->old_style_grp) { - if (group_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) { - printf("Old-styled group test: but the group is not in old-style. \n"); - TEST_ERROR; - } - dbgf(2, "Writer: group is created with the old-style.\n"); - } - else { - if (group_info.storage_type == H5G_STORAGE_TYPE_SYMBOL_TABLE) { - printf("The created group should NOT be in old-style . \n"); - TEST_ERROR; - } - dbgf(2, "Writer: group is created with the new-style.\n"); - } - } - - /* If coming to an "object header continuation block" test, - * we need to check if this test behaves as expected. */ - if (s->at_pattern == 'a' || s->at_pattern == 'R') { - if (false == check_ohr_num_chunk(g, true)) { - printf("An object header continuation block should NOT be created. \n"); - printf("But it is created.\n"); - TEST_ERROR; - } - } - - /* Then carry out the attribute operation. */ - if (s->asteps != 0 && which % s->asteps == 0) - result = add_group_attribute(s, g, gcpl, which); - - if (s->at_pattern == 'a' || s->at_pattern == 'R') { - if (H5Dclose(dummy_d) < 0) { - printf("H5Dclose failed\n"); - TEST_ERROR; - } - } - - if (H5Gclose(g) < 0) { - printf("H5Gclose failed\n"); - TEST_ERROR; - } - - if (!s->old_style_grp && H5Pclose(gcpl) < 0) { - printf("H5Pclose failed\n"); - TEST_ERROR; - } - - return result; - -error: - - H5E_BEGIN_TRY - { - H5Gclose(g); - if (s->at_pattern == 'a' || s->at_pattern == 'R') - H5Dclose(dummy_d); - if (!s->old_style_grp) - H5Pclose(gcpl); - } - H5E_END_TRY; - - return false; -} - -/*------------------------------------------------------------------------- - * Function: create_group_id - * - * Purpose: Create a group and return the group ID. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * unsigned int which - * The number of iterations for group creation - * This is used to generate the group name. - * - * bool dense_to_compact - * true if this function is used to test the transition from dense to - * compact, false if the test is from compact to dense. - * - * Return: Success: the group ID - * Failure: -1 - * - * Note: Only used by testing the link storage transit functions. - *------------------------------------------------------------------------- - */ - -static hid_t -create_group_id(state_t *s, unsigned int which, bool dense_to_compact) -{ - - char name[sizeof("/group-9999999999")]; - hid_t g = H5I_INVALID_HID; - hid_t gcpl = H5I_INVALID_HID; - H5G_info_t group_info; - - if (which >= s->nsteps) { - printf("Number of created groups is out of bounds\n"); - TEST_ERROR; - } - - gcpl = H5Pcreate(H5P_GROUP_CREATE); - if (gcpl < 0) { - printf("H5Pcreate failed\n"); - TEST_ERROR; - } - - if (dense_to_compact) { - if (H5Pset_link_phase_change(gcpl, 2, 2) < 0) { - printf("H5Pset_link_phase_change failed for dense to compact.\n"); - TEST_ERROR; - } - } - else { - if (H5Pset_link_phase_change(gcpl, 1, 1) < 0) { - printf("H5Pset_attr_phase_change failed for compact to dense.\n"); - TEST_ERROR; - } - } - - esnprintf(name, sizeof(name), "/group-%u", which); - if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, gcpl, H5P_DEFAULT)) < 0) { - printf("H5Gcreate2 failed\n"); - TEST_ERROR; - } - - if (H5Gget_info(g, &group_info) < 0) { - printf("H5Gget_info failed\n"); - TEST_ERROR; - } - - /* The storage type should always be compact when a group is created. */ - if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) { - printf("New-style group link storage test:. \n"); - printf(" still be compact after group creation. \n"); - TEST_ERROR; - } - - if (H5Pclose(gcpl) < 0) { - printf("H5Pclose failed\n"); - TEST_ERROR; - } - - return g; - -error: - - H5E_BEGIN_TRY - { - H5Pclose(gcpl); - } - H5E_END_TRY; - - return -1; -} - -/*------------------------------------------------------------------------- - * Function: close_group_id - * - * Purpose: Verify is a group is closed successfully. - * - * Parameters: hid_t g - * The ID of the group to be closed. - * - * Return: Success: true - * Failure: false - * - * Note: This is used by the link storage transit functions. - *------------------------------------------------------------------------- - */ - -static bool -close_group_id(hid_t g) -{ - - if (H5Gclose(g) < 0) { - printf("H5Gclose failed\n"); - TEST_ERROR; - } - - return true; - -error: - return false; -} - -/*------------------------------------------------------------------------- - * Function: create_group - * - * Purpose: Create a group - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * unsigned int which - * The number of iterations for group creation - * This is used to generate the group name. - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the main() function. - *------------------------------------------------------------------------- - */ - -static bool -create_group(state_t *s, unsigned int which) -{ - - char name[sizeof("/group-9999999999")]; - hid_t g = H5I_INVALID_HID; - H5G_info_t group_info; - - if (which >= s->nsteps) { - printf("Number of created groups is out of bounds\n"); - TEST_ERROR; - } - - esnprintf(name, sizeof(name), "/group-%u", which); - if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { - printf("H5Gcreate2 failed\n"); - TEST_ERROR; - } - - if (H5Gget_info(g, &group_info) < 0) { - printf("H5Gget_info failed\n"); - TEST_ERROR; - } - - if (s->old_style_grp) { - if (group_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) { - printf("Old-styled group test: but the group is not in old-style. \n"); - TEST_ERROR; - } - dbgf(2, "Writer: group is created with the old-style.\n"); - } - else { - if (group_info.storage_type == H5G_STORAGE_TYPE_SYMBOL_TABLE) { - printf("The created group should NOT be in old-style . \n"); - TEST_ERROR; - } - dbgf(2, "Writer: group is created with the new-style.\n"); - } - - if (H5Gclose(g) < 0) { - printf("H5Gclose failed\n"); - TEST_ERROR; - } - - return true; - -error: - - H5E_BEGIN_TRY - { - H5Gclose(g); - } - H5E_END_TRY; - - return false; -} - -/*------------------------------------------------------------------------- - * Function: delete_one_link - * - * Purpose: Delete a link(either hard/soft) in group operation tests. - * according to the group test pattern. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * hid_t obj_id - * The HDF5 object ID that the deleted link is attached to. - * - * const char *name - * The name of the link to be deleted. - * - * short link_storage - * <=0: link storage is ignored. - * 1: link storage should be compact after link deletion.. - * >1: link storage should be dense after link deletion. - * - * unsigned int which - * The number of iterations for group creation - * - * - * Return: Success: true - * Failure: false - * - * Note: This is used by delete_groups() and delete_links() functions. - *------------------------------------------------------------------------- - */ - -static bool -delete_one_link(state_t *s, hid_t obj_id, const char *name, short link_storage, unsigned int which) -{ - - H5G_info_t group_info; - - if (which >= s->nsteps) { - printf("Number of created groups is out of bounds\n"); - TEST_ERROR; - } - - if (H5Ldelete(obj_id, name, H5P_DEFAULT) < 0) { - printf("H5Ldelete failed\n"); - TEST_ERROR; - } - - if (link_storage > 0) { - - if (s->old_style_grp) { - printf("Old style group doesn't support the indexed storage.\n"); - TEST_ERROR; - } - - if (H5Gget_info(obj_id, &group_info) < 0) { - printf("H5Gget_info failed\n"); - TEST_ERROR; - } - - if (link_storage == 1) { - - if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) { - printf("The group link storage should be compact. \n"); - TEST_ERROR; - } - } - else { - - if (group_info.storage_type != H5G_STORAGE_TYPE_DENSE) { - printf("The group link storage should be dense. \n"); - TEST_ERROR; - } - } - } - - return true; - -error: - return false; -} - -/*------------------------------------------------------------------------- - * Function: delete_group - * - * Purpose: Delete a group and carry out group operations(add,delete etc.) - * according to the group operation test pattern. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * unsigned int which - * The number of iterations for group creation - * This is used to generate the group name - * - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the group_operations() function. - *------------------------------------------------------------------------- - */ - -static bool -delete_group(state_t *s, unsigned int which) -{ - - char name[sizeof("/group-9999999999")]; - bool ret_value = create_group(s, which); - if (ret_value == true) { - esnprintf(name, sizeof(name), "/group-%u", which); - ret_value = delete_one_link(s, s->file, name, 0, which); - } - - return ret_value; -} - -/*------------------------------------------------------------------------- - * Function: move_one_group - * - * Purpose: A helper function used by the move_group operation. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * hid_t obj_id - * ID of the object this group is attached to - * - * const char *name - * The original group name - * - * const char *newname - * The new group name - * - * unsigned int which - * The number of iterations for group creation - * - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the move_group() function. - *------------------------------------------------------------------------- - */ - -static bool -move_one_group(state_t *s, hid_t obj_id, const char *name, const char *newname, unsigned int which) -{ - - if (which >= s->nsteps) { - printf("Number of created groups is out of bounds\n"); - TEST_ERROR; - } - - if (H5Lmove(obj_id, name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { - printf("H5Ldelete failed\n"); - TEST_ERROR; - } - - return true; - -error: - return false; -} - -/*------------------------------------------------------------------------- - * Function: move_group - * - * Purpose: Move a group to another group. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * unsigned int which - * The number of iterations for group creation - * used to generate the group name. - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the group_operations() function. - *------------------------------------------------------------------------- - */ - -static bool -move_group(state_t *s, unsigned int which) -{ - - char name[sizeof("/group-9999999999")]; - char new_name[sizeof("/new-group-9999999999")]; - bool ret_value = create_group(s, which); - if (ret_value == true) { - esnprintf(name, sizeof(name), "/group-%u", which); - esnprintf(new_name, sizeof(new_name), "/new-group-%u", which); - ret_value = move_one_group(s, s->file, name, new_name, which); - } - - return ret_value; -} - -/*------------------------------------------------------------------------- - * Function: insert_one_link - * - * Purpose: A helper function used to attach a link to a group. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * hid_t obj_id - * ID of the object this link is attached to - * - * const char *name - * The name of the target object used by creating links - * - * const char *newname - * The name of the linked objects - * - * bool is_hard - * true if inserting a hard link - * false if inserting a soft link - * - * short link_storage - * <=0: link storage is ignored. - * 1: link storage should be compact. - * >1: link storage should be dense. - - * unsigned int which - * The number of iterations for group creation - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the insert_links and link storage transit functions. - * For link storage, we test at both the writer and the reader. - *------------------------------------------------------------------------- -*/ - -static bool -insert_one_link(state_t *s, hid_t obj_id, const char *name, const char *newname, bool is_hard, - short link_storage, unsigned int which) -{ - - H5G_info_t group_info; - - if (which >= s->nsteps) { - printf("Number of created groups is out of bounds\n"); - TEST_ERROR; - } - - /* For storage transit and insert_links cases, we - * create links in different style, just add a little - * variation of the tests.*/ - if (is_hard) { - if (link_storage > 0) { - if (H5Lcreate_hard(s->file, name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { - printf("H5Lcreate_hard failed\n"); - TEST_ERROR; - } - } - else { - if (H5Lcreate_hard(obj_id, name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { - printf("H5Lcreate_hard failed\n"); - TEST_ERROR; - } - } - } - else { - if (link_storage > 0) { - if (H5Lcreate_soft("/", obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { - printf("H5Lcreate_soft failed\n"); - TEST_ERROR; - } - } - else { - if (H5Lcreate_soft(name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { - printf("H5Lcreate_soft failed.\n"); - TEST_ERROR; - } - } - } - - if (link_storage > 0) { - - if (s->old_style_grp) { - printf("Old style group doesn't support dense or compact storage.\n"); - TEST_ERROR; - } - - if (H5Gget_info(obj_id, &group_info) < 0) { - printf("H5Gget_info failed\n"); - TEST_ERROR; - } - - if (link_storage == 1) { - if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) { - printf("The group link storage should be compact. \n"); - TEST_ERROR; - } - } - else { - if (group_info.storage_type != H5G_STORAGE_TYPE_DENSE) { - printf("The group link storage should be dense. \n"); - TEST_ERROR; - } - } - } - - return true; - -error: - return false; -} - -/*------------------------------------------------------------------------- - * Function: insert_links - * - * Purpose: create links with a group. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * unsigned int which - * The number of iterations - * used to generate the group name. - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the group_operations() function. - *------------------------------------------------------------------------- - */ - -static bool -insert_links(state_t *s, unsigned int which) -{ - - char name[sizeof("/group-9999999999")]; - char hd_name[sizeof("/hd-group-9999999999")]; - char st_name[sizeof("/st-group-9999999999")]; - - bool ret_value = create_group(s, which); - if (ret_value == true) { - esnprintf(name, sizeof(name), "/group-%u", which); - esnprintf(hd_name, sizeof(hd_name), "/hd-group-%u", which); - esnprintf(st_name, sizeof(st_name), "/st-group-%u", which); - ret_value = insert_one_link(s, s->file, name, hd_name, true, 0, which); - if (ret_value == true) - ret_value = insert_one_link(s, s->file, name, st_name, false, 0, which); - } - - return ret_value; -} - -/*------------------------------------------------------------------------- - * Function: delete_links - * - * Purpose: create links with a group and then delete them successfully. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * unsigned int which - * The number of iterations - * used to generate the group name. - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the group_operations() function. - *------------------------------------------------------------------------- - */ - -static bool -delete_links(state_t *s, unsigned int which) -{ - - char name[sizeof("/group-9999999999")]; - char hd_name[sizeof("/hd-group-9999999999")]; - char st_name[sizeof("/st-group-9999999999")]; - - bool ret_value = insert_links(s, which); - if (ret_value == true) { - esnprintf(name, sizeof(name), "/group-%u", which); - esnprintf(hd_name, sizeof(hd_name), "/hd-group-%u", which); - esnprintf(st_name, sizeof(st_name), "/st-group-%u", which); - ret_value = delete_one_link(s, s->file, hd_name, 0, which); - if (ret_value == true) - ret_value = delete_one_link(s, s->file, st_name, 0, which); - } - - return ret_value; -} - -/*------------------------------------------------------------------------- - * Function: transit_storage_compact_to_dense - * - * Purpose: Add links so that the link storage transits from - * compact to dense. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * unsigned int which - * The number of iterations used to generate the group name. - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the group_operations() function. - *------------------------------------------------------------------------- - */ - -static bool -transit_storage_compact_to_dense(state_t *s, unsigned int which) -{ - - char name[sizeof("/group-9999999999")]; - char hd_name[sizeof("/hd-group-9999999999")]; - char st_name[sizeof("/st-group-9999999999")]; - - hid_t g = create_group_id(s, which, false); - if (g < 0) { - printf("create_group_id failed\n"); - TEST_ERROR; - } - - /* First insert a hard link, compact storage. */ - esnprintf(name, sizeof(name), "/group-%u", which); - esnprintf(hd_name, sizeof(hd_name), "hd-group-%u", which); - if (insert_one_link(s, g, name, hd_name, true, 1, which) == false) { - printf("insert_one_link for compact storage failed\n"); - TEST_ERROR; - } - - /* Then insert a soft link, the storage becomes dense. */ - esnprintf(st_name, sizeof(st_name), "st-group-%u", which); - if (insert_one_link(s, g, name, st_name, false, 2, which) == false) { - printf("insert_one_link for dense storage failed\n"); - TEST_ERROR; - } - - if (close_group_id(g) == false) { - printf("insert_one_link for dense storage failed\n"); - TEST_ERROR; - } - - return true; - -error: - H5E_BEGIN_TRY - { - H5Gclose(g); - } - H5E_END_TRY; - - return false; -} - -/*------------------------------------------------------------------------- - * Function: transit_storage_dense_to_compact - * - * Purpose: Add or delete links so that the link storage transits from - * compact to dense then to compact. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * unsigned int which - * The number of iterations used to generate the group name. - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the group_operations() function. - *------------------------------------------------------------------------- - */ - -static bool -transit_storage_dense_to_compact(state_t *s, unsigned int which) -{ - - char name[sizeof("/group-9999999999")]; - char hd_name[sizeof("/hd-group-9999999999")]; - char st_name[sizeof("st-group-9999999999")]; - char st2_name[sizeof("st2-group-9999999999")]; - - hid_t g = create_group_id(s, which, true); - if (g < 0) { - printf("create_group_id failed\n"); - TEST_ERROR; - } - - /* Insert a link, storage is compact. */ - esnprintf(name, sizeof(name), "/group-%u", which); - esnprintf(hd_name, sizeof(hd_name), "hd-group-%u", which); - if (insert_one_link(s, g, name, hd_name, true, 1, which) == false) { - printf("insert_one_link for compact storage failed\n"); - TEST_ERROR; - } - - /* Insert a link, storage is still compact. */ - esnprintf(st_name, sizeof(st_name), "st-group-%u", which); - if (insert_one_link(s, g, name, st_name, false, 1, which) == false) { - printf("insert_one_link for compact storage failed\n"); - TEST_ERROR; - } - - /* Insert a link, storage becomes dense. */ - esnprintf(st2_name, sizeof(st2_name), "st2-group-%u", which); - if (insert_one_link(s, g, name, st2_name, false, 2, which) == false) { - printf("insert_one_link for dense storage failed\n"); - TEST_ERROR; - } - - /* Delete a link, storage is still dense */ - if (delete_one_link(s, g, st_name, 2, which) == false) { - printf("delete_one_link for dense storage failed\n"); - TEST_ERROR; - } - - /* Delete another link, storage becomes compact */ - if (delete_one_link(s, g, st2_name, 1, which) == false) { - printf("delete_one_link for compact storage failed\n"); - TEST_ERROR; - } - - if (close_group_id(g) == false) { - printf("insert_one_link for dense storage failed\n"); - TEST_ERROR; - } - - return true; - -error: - H5E_BEGIN_TRY - { - H5Gclose(g); - } - H5E_END_TRY; - - return false; -} - -/*------------------------------------------------------------------------- - * Function: group_operations - * - * Purpose: Carry out group and attribute operations(add,delete etc.) - * according to the group operation and attribute test patterns. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * unsigned int which - * The number of iterations for group creation - * - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the main() function. The check of attribute - * operations is inside the write_group() function. - *------------------------------------------------------------------------- - */ -static bool -group_operations(state_t *s, unsigned int which) -{ - - bool ret_value = false; - char test_pattern = s->grp_op_pattern; - - switch (test_pattern) { - case 'c': - ret_value = create_group(s, which); - break; - case 'd': - ret_value = delete_group(s, which); - break; - case 'm': - ret_value = move_group(s, which); - break; - case 'i': - ret_value = insert_links(s, which); - break; - case 'D': - ret_value = delete_links(s, which); - break; - case 't': - ret_value = transit_storage_compact_to_dense(s, which); - break; - case 'T': - ret_value = transit_storage_dense_to_compact(s, which); - break; - case ' ': - default: - ret_value = write_group(s, which); - break; - } - return ret_value; -} - -static unsigned int grp_counter = 0; - -/*------------------------------------------------------------------------- - * Function: UI_Pow - * - * Purpose: Helper function to obtain the power 'n' of - * an unsigned integer 'x' - * Similar to pow(x,y) but for an unsigned integer. - * - * Parameters: unsigned int x - * unsigned int n - * - * Return: Return an unsigned integer of value of pow(x,n) - * Note: If the returned value is > 2^32-1, an overflow - * may occur. For our testing purpose, this may never happen. - * - *------------------------------------------------------------------------- - */ - -static unsigned int -UI_Pow(unsigned int x, unsigned int n) -{ - unsigned int i; /* Variable used in loop grp_counter */ - unsigned int number = 1; - - for (i = 0; i < n; ++i) - number *= x; - - return (number); -} - -/*------------------------------------------------------------------------- - * Function: obtain_tree_level_elems - * - * Purpose: Helper function to obtain the maximum number of elements - * at one level. - * - * Parameters: unsigned int total_ele - * The total number of elements of a tree(excluding the root) - * - * unsigned int level - * The number of nested levels - * (If every element of the tree is under the root, - * the level is 0.) - * - * Return: Return the maximum number of elements at one level - * - * Example: If the total number of elements is 6 and level is 1, - * the maximum number of elements is 2.The tree is - * a perfectly balanced tree. - * Such as: - * 0 - * 1 2 - * 3 4 5 6 - * - * If the total number of elements is 5 and level is 1, - * the maximum number of elements is still 2. The - * tree is not balanced, there is no element on the - * right-most leaf but the level is still 1. - * Such as: - * 0 - * 1 2 - * 3 4 5 - * - *------------------------------------------------------------------------- - */ - -static unsigned int -obtain_tree_level_elems(unsigned int total_ele, unsigned int level) -{ - - assert(level <= total_ele); - /* if every element is under the root, just return the total number of elements. */ - if (level == 0) - return total_ele; - else { - unsigned int test_elems_level = 0; - unsigned total = 0; - unsigned int i = 1; - /* Obtain the maximum number of elements for a level with the brutal force way. */ - while (total < total_ele) { - test_elems_level++; - total = 0; - for (i = 1; i <= level + 1; i++) - total += UI_Pow(test_elems_level, i); - } - if (total == total_ele) - dbgf(2, "Perfectly match: Number of elements per level is %u\n", test_elems_level); - return test_elems_level; - } -} - -/*------------------------------------------------------------------------- - * Function: gen_tree_struct - * - * Purpose: Generate the nested groups - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file - * and some VFD SWMR configuration parameters - * - * unsigned int level - * The number of nested levels +1 - * (Note: If every element of the tree is under the root, - * the level is 1 in this function.) - * unsigned num_elems_per_level - * The maximum number of element in a level - * hid_t group_id - * The ID of the parent group - * - * Return: Success: true - * Failure: false - */ -static bool -gen_tree_struct(state_t *s, unsigned int level, unsigned ne_per_level, hid_t pgrp_id) -{ - - char name[sizeof("group-9999999999")]; - unsigned int i; - hid_t grp_id; - bool result = true; - H5G_info_t group_info; - struct timespec start_time, end_time; - double temp_time; - - if (level > 0 && grp_counter < s->nsteps) { - - for (i = 0; i < ne_per_level; i++) { - - /* For each i a group is created. - Use grp_counter to generate the group name. - printf("id: %u,level: %u, index: %u\n",id,level,i); - */ - esnprintf(name, sizeof(name), "group-%u", grp_counter); - if (grp_counter == s->nsteps) - break; - - dbgf(2, "writer in nested group: step %d\n", grp_counter); - if (s->gperf) { - - if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { - fprintf(stderr, "HDclock_gettime failed"); - TEST_ERROR; - } - } - - if ((grp_id = H5Gcreate2(pgrp_id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { - printf("H5Gcreate2 failed\n"); - TEST_ERROR; - } - - if (s->gperf) { - - if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { - - fprintf(stderr, "HDclock_gettime failed"); - - TEST_ERROR; - } - - temp_time = TIME_PASSED(start_time, end_time); - if (temp_time < s->min_gc_time) - s->min_gc_time = temp_time; - if (temp_time > s->max_gc_time) - s->max_gc_time = temp_time; - s->total_gc_time += temp_time; - } - - /* Just check the first group information. */ - if (grp_counter == 0) { - if (H5Gget_info(grp_id, &group_info) < 0) { - printf("H5Gget_info failed\n"); - TEST_ERROR; - } - - if (s->old_style_grp) { - if (group_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) { - printf("Old-styled group test: but the group is not in old-style. \n"); - TEST_ERROR; - } - dbgf(2, "Writer: group is created with the old-style.\n"); - } - else { - if (group_info.storage_type == H5G_STORAGE_TYPE_SYMBOL_TABLE) { - printf("The created group should NOT be in old-style . \n"); - TEST_ERROR; - } - dbgf(2, "Writer: group is created with the new-style.\n"); - } - } - - /* Then carry out the attribute operation. */ - if (s->asteps != 0 && grp_counter % s->asteps == 0) - result = add_default_group_attr(s, grp_id, grp_counter); - - if (result == false) { - printf("Cannot create group attributes. \n"); - TEST_ERROR; - } - grp_counter++; - - /* Generate groups in the next level */ - result = gen_tree_struct(s, level - 1, ne_per_level, grp_id); - if (result == false) { - printf("Cannot create nested groups. \n"); - TEST_ERROR; - } - - /* close the group ID. No problem. */ - if (H5Gclose(grp_id) < 0) { - printf("H5Gclose failed. \n"); - TEST_ERROR; - } - } - } - - return true; - -error: - - H5E_BEGIN_TRY - { - H5Gclose(grp_id); - } - H5E_END_TRY; - - return false; -} - -int -main(int argc, char **argv) -{ - hid_t fapl = H5I_INVALID_HID, fcpl = H5I_INVALID_HID; - unsigned step; - bool writer = false; - state_t s; - const char * personality; - H5F_vfd_swmr_config_t config; - bool wg_ret = false; - struct timespec start_time, end_time; - unsigned int num_elems_per_level; - - if (!state_init(&s, argc, argv)) { - printf("state_init failed\n"); - TEST_ERROR; - } - - personality = HDstrstr(s.progname, "vfd_swmr_log_"); - - if (personality != NULL && HDstrcmp(personality, "vfd_swmr_log_writer") == 0) - writer = true; - else if (personality != NULL && HDstrcmp(personality, "vfd_swmr_log_reader") == 0) - writer = false; - else { - printf("unknown personality, expected vfd_swmr_log_{reader,writer}\n"); - TEST_ERROR; - } - - if (writer == false) { - printf("Reader is skipped for the performance tests.\n"); - return EXIT_SUCCESS; - } - - /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ - init_vfd_swmr_config(&config, s.tick_len, s.max_lag, writer, FALSE, 128, "./group-shadow"); - /* Create the log file log-test under the current directory. */ - init_vfd_swmr_log(&config, "./log-test"); - - /* If old-style option is chosen, use the earliest file format(H5F_LIBVER_EARLIEST) - * as the second parameter of H5Pset_libver_bound() that is called by - * vfd_swmr_create_fapl. Otherwise, the latest file format(H5F_LIBVER_LATEST) - * should be used as the second parameter of H5Pset_libver_bound(). - * Also pass the use_vfd_swmr, only_meta_page, page buffer size, config to vfd_swmr_create_fapl().*/ - if ((fapl = vfd_swmr_create_fapl(!s.old_style_grp, s.use_vfd_swmr, true, s.pbs, &config)) < 0) { - printf("vfd_swmr_create_fapl failed\n"); - TEST_ERROR; - } - - /* Set fs_strategy (file space strategy) and fs_page_size (file space page size) */ - if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, s.ps)) < 0) { - HDprintf("vfd_swmr_create_fcpl() failed"); - TEST_ERROR; - } - - if (s.nglevels > 0) { - if (s.grp_op_pattern != ' ' || s.at_pattern != ' ') { - printf("For nested group creation test, only the default option is supported.\n"); - printf("Please re-run the tests with the appopriate option.\n"); - TEST_ERROR; - } - } - - if (s.gperf) { - - if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { - fprintf(stderr, "HDclock_gettime failed"); - TEST_ERROR; - } - } - - s.file = H5Fcreate(s.filename, H5F_ACC_TRUNC, fcpl, fapl); - - if (s.gperf) { - - if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { - fprintf(stderr, "HDclock_gettime failed"); - TEST_ERROR; - } - - s.fo_total_time = TIME_PASSED(start_time, end_time); - } - - if (s.file < 0) { - printf("H5Fcreate failed\n"); - TEST_ERROR; - } - - /* If generating nested groups, calculate the maximum number of - elements per level. */ - if (s.nglevels > 0) - num_elems_per_level = obtain_tree_level_elems(s.nsteps, s.nglevels); - - if (s.gperf) { - - if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { - fprintf(stderr, "HDclock_gettime failed"); - TEST_ERROR; - } - } - - /* If generating nested groups */ - if (s.nglevels > 0) { - - /* for the recursive call, the groups under the root is treated as one level */ - wg_ret = gen_tree_struct(&s, s.nglevels + 1, num_elems_per_level, s.file); - if (wg_ret == false) { - printf("write nested group failed at group counter %u\n", grp_counter); - TEST_ERROR; - } - } - else { - for (step = 0; step < s.nsteps; step++) { - - dbgf(2, "writer: step %d\n", step); - wg_ret = group_operations(&s, step); - if (wg_ret == false) { - printf("write_group failed at step %d\n", step); - TEST_ERROR; - } - } - } - - if (s.gperf) { - - if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { - - fprintf(stderr, "HDclock_gettime failed"); - TEST_ERROR; - } - - s.total_time = TIME_PASSED(start_time, end_time); - s.mean_time = s.total_time / s.nsteps; - s.mean_gc_time = s.total_gc_time / s.nsteps; - } - - if (H5Pclose(fapl) < 0) { - printf("H5Pclose failed\n"); - TEST_ERROR; - } - - if (H5Pclose(fcpl) < 0) { - printf("H5Pclose failed\n"); - TEST_ERROR; - } - - if (H5Sclose(s.one_by_one_sid) < 0) { - printf("H5Sclose failed\n"); - TEST_ERROR; - } - - if (s.gperf) { - - if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { - - fprintf(stderr, "HDclock_gettime failed"); - - TEST_ERROR; - } - } - - if (H5Fclose(s.file) < 0) { - printf("H5Fclose failed\n"); - TEST_ERROR; - } - - if (s.gperf) { - - if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { - - fprintf(stderr, "HDclock_gettime failed"); - - TEST_ERROR; - } - - s.fc_total_time = TIME_PASSED(start_time, end_time); - } - - /* Performance statistics summary */ - if (s.gperf) { - - if (verbosity != 0) { - - fprintf(stdout, "\nPerformance Test Configuration: "); - if (s.use_vfd_swmr) - fprintf(stdout, " Using VFD SWMR \n"); - else - fprintf(stdout, " Not using VFD SWMR \n"); - - if (s.old_style_grp) - fprintf(stdout, " Groups: Created via the earlist file format(old-style) \n"); - else - fprintf(stdout, " Groups: Created via the latest file format(new-style) \n"); - - fprintf(stdout, "\n"); - - fprintf(stdout, "The length of a tick = %u\n", s.tick_len); - fprintf(stdout, "The maximum expected lag(in ticks)= %u\n", s.max_lag); - fprintf(stdout, "The page size(in bytes) = %u\n", s.ps); - fprintf(stdout, "The page buffer size(in bytes) = %u\n", s.pbs); - fprintf(stdout, "\n"); - fprintf(stdout, "Number of groups = %u\n", s.nsteps); - fprintf(stdout, "Group Nested levels = %u\n", s.nglevels); - fprintf(stdout, "Number of attributes = %u\n", s.num_attrs); - fprintf(stdout, "Number of element per attribute = 1\n"); - if (s.vlstr_test) - fprintf(stdout, "Attribute datatype is variable length string. \n"); - else if (s.filetype == H5T_STD_U32BE) - fprintf(stdout, "Attribute datatype is big-endian unsigned 32-bit integer.\n"); - else - fprintf(stdout, "Attribute datatype is native unsigned 32-bit integer.\n"); - - fprintf(stdout, "\n"); - fprintf(stdout, - "(If the nested level is 0, all the groups are created directly under the root.)\n\n"); - fprintf(stdout, "group creation maximum time =%lf\n", s.max_gc_time); - fprintf(stdout, "group creation minimum time =%lf\n", s.min_gc_time); - } - - fprintf(stdout, "group creation total time = %lf\n", s.total_gc_time); - fprintf(stdout, "group creation mean time(per group) = %lf\n", s.mean_gc_time); - fprintf(stdout, "group creation and attributes generation total time = %lf\n", s.total_time); - fprintf(stdout, "group creation and attributes generation mean time(per group) = %lf\n", s.mean_time); - fprintf(stdout, "H5Fcreate time = %lf\n", s.fo_total_time); - fprintf(stdout, "H5Fclose time = %lf\n", s.fc_total_time); - } - - return EXIT_SUCCESS; - -error: - H5E_BEGIN_TRY - { - H5Pclose(fapl); - H5Pclose(fcpl); - H5Sclose(s.one_by_one_sid); - H5Fclose(s.file); - } - H5E_END_TRY; - - return EXIT_FAILURE; -} - -#else /* H5_HAVE_WIN32_API */ - -int -main(void) -{ - HDfprintf(stderr, "Non-POSIX platform. Skipping.\n"); - return EXIT_SUCCESS; -} /* end main() */ - -#endif /* H5_HAVE_WIN32_API */ -- cgit v0.12 From 43c2c955b876b5eef2446bac2159c8e03fe60b47 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Nov 2021 17:25:26 +0000 Subject: Committing clang-format changes --- src/H5FDvfd_swmr_private.h | 1 - src/H5Fpkg.h | 2 +- src/H5Fvfd_swmr.c | 13 ++-- test/vfd_swmr_gperf_writer.c | 178 +++++++++++++++++++++---------------------- 4 files changed, 96 insertions(+), 98 deletions(-) diff --git a/src/H5FDvfd_swmr_private.h b/src/H5FDvfd_swmr_private.h index 985bd70..12fd2e2 100644 --- a/src/H5FDvfd_swmr_private.h +++ b/src/H5FDvfd_swmr_private.h @@ -84,5 +84,4 @@ H5_DLL herr_t H5F_vfd_swmr_insert_entry_eot(struct H5F_t *f); H5_DLL void H5F_vfd_swmr_update_entry_eot(eot_queue_entry_t *); H5_DLL herr_t H5F_dump_eot_queue(void); - #endif /* H5FDvfd_swmr_private_H */ diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 3bece42..6dd896e 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -649,7 +649,7 @@ H5_DLL void H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log } \ } while (0) -#define H5F_POST_VFD_SWMR_LOG_ENTRY_PRODUCTION(fp, entry_type_code, max_code, log_info) \ +#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); \ diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index 9404cf4..b3c3ffe 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -54,7 +54,6 @@ #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. @@ -87,8 +86,8 @@ static const char *H5Fvfd_swmr_log_tags[] = { */ 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 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; @@ -358,7 +357,7 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing) 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) + if (closing) H5F_POST_VFD_SWMR_LOG_ENTRY(f, 2, "VFD SWMR File close ends"); #endif done: @@ -956,8 +955,8 @@ done: if (H5_timer_get_times(shared->vfd_swmr_log_start_time, ¤t_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); + 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, 0, log_msg); HDfree(log_msg); @@ -1997,7 +1996,7 @@ H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log_info) 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, ¤t_time) < 0) { - if(NULL != (gettime_error = HDmalloc(log_err_mesg_length*sizeof(char)))) { + 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); diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c index ad2b373..3342b40 100644 --- a/test/vfd_swmr_gperf_writer.c +++ b/test/vfd_swmr_gperf_writer.c @@ -35,10 +35,10 @@ * The program is run with max_lag = 8, tick_len = 4; * The page buffer size is 16384 bytes. The page size is 8192 bytes. * - * II. How to generate log message + * II. How to generate log message * - * ./vfd_swmr_gperf_writer -n 100000 -P -L -q - * will generate 100000 groups, each group has one attribute. It also writes the log message + * ./vfd_swmr_gperf_writer -n 100000 -P -L -q + * will generate 100000 groups, each group has one attribute. It also writes the log message * to file "log-test" under the same directory. * To turn on the log feature, one just needs to provide the log file path as * indicated by the line init_vfd_swmr_log(&config, "./log-test") in the main @@ -112,90 +112,91 @@ typedef struct { static void usage(const char *progname) { - fprintf(stderr, - "usage: ./%s -P -n 1000 -N 5 -q (create 1000 groups, each group has 5 attributes)\n" - "usage: ./%s -P -L -n 100000 -q (create 100000 groups and generate log message to file 'log-test')\n" - "Options: \n" - " [-P] [-S] [-G] [-L] [-t tick_len] [-m max_lag][-B pbs] [-s ps]\n" - " [-n ngroups] [-l ng_levels] [-O grp_op_pattern]\n" - " [-N num_attrs] [-V] [-b] [-A at_pattern] [-a steps] [-q]\n" - "\n" - "-P: carry out the performance test\n" - "-S: do not use VFD SWMR\n" - "-G: old-style type of group\n" - "-L: Turn on the logging feature.\n" - "-t tick_len: length of a tick in tenths of a second.\n" - "-m max_lag: maximum expected lag(in ticks) between writer and readers\n" - "-B pbs: page Buffer Size in bytes:\n" - " The default value is 4K(4096).\n" - "-s ps: page size used by page aggregation, page buffer and \n" - " the metadata file. \n" - "-n ngroups: the number of groups\n" - "-l ng_levels: the number of level of nested groups. \n" - " If all the groups are under the root group, \n" - " this number should be 0.\n" - "-N num_attrs: the number of attributes \n" - "-V use variable length string attributes for performance test\n" - "-b: write data in big-endian byte order\n" - " (For the performance test, -V overwrites -b)\n" - "-A at_pattern: `at_pattern' for different attribute tests\n" - " The value of `at_pattern` is one of the following:\n" - " `compact` - Attributes added in compact storage\n" - " `dense` - An attribute added in dense storage\n" - " `compact-del` - Attributes added and then one\n" - " attribute deleted, in compact \n" - " `dense-del` - Attributes added until the storage\n" - " is dense then an attribute deleted\n" - " the storge still in dense\n" - " `compact-add-to-dense` - Attributes added first in compact\n" - " then in dense storage\n" - " `dense-del-to-compact` - Attributes added until the storage\n" - " is dense, then several attributes \n" - " deleted, the storage changed to\n" - " compact\n" - " `modify` - An attribute added then modified\n" - " `add-vstr` - A VL string attribute added\n" - " `remove-vstr` - A VL string attribute added then\n" - " deleted\n" - " `modify-vstr` - A VL string attribute added then \n" - " modified \n" - " `add-ohr-block` - An attribute is added and this forces\n" - " the creation of object header\n" - " continuation block \n" - " `del-ohr-block` - An attribute is added and this forces\n" - " the creation of object header\n" - " continuation block and then this \n" - " attribute is deleted so the \n" - " object header continuation block is \n" - " removed. \n" - "-O grp_op_pattern: `grp_op_pattern' for different group operation tests\n" - " The value of `grp_op_pattern` is one of the following:\n" - " `grp-creation` - A group is created.\n" - " `grp-deletion` - An existing group is deleted.\n" - " `grp-move` - A group is moved to become \n" - " another group. \n" - " `grp-ins-links` - Links are inserted, including\n" - " both hard and soft links. \n" - " `grp-del-links` - Links are deleted, including\n" - " both hard ans soft links. \n" - " `grp-compact-t-dense` - Links are inserted to the group.\n" - " The link storage of this group \n" - " changed from compact to dense. \n" - " The links include both hard and\n" - " soft links. \n" - " `grp-dense-t-compact` - Links are inserted to the group\n" - " The link storage of this group \n" - " changed from compact to dense. \n" - " Then several links are deleted.\n" - " The link storage changed from \n" - " dense to compact again. \n" - " The links include both hard and\n" - " soft links. \n" - "-a steps: `steps` between adding attributes\n" - " (Don't recommend to use this option for performance test.)\n" - "-q: silence printouts, few messages\n" - "\n", - progname,progname); + fprintf( + stderr, + "usage: ./%s -P -n 1000 -N 5 -q (create 1000 groups, each group has 5 attributes)\n" + "usage: ./%s -P -L -n 100000 -q (create 100000 groups and generate log message to file 'log-test')\n" + "Options: \n" + " [-P] [-S] [-G] [-L] [-t tick_len] [-m max_lag][-B pbs] [-s ps]\n" + " [-n ngroups] [-l ng_levels] [-O grp_op_pattern]\n" + " [-N num_attrs] [-V] [-b] [-A at_pattern] [-a steps] [-q]\n" + "\n" + "-P: carry out the performance test\n" + "-S: do not use VFD SWMR\n" + "-G: old-style type of group\n" + "-L: Turn on the logging feature.\n" + "-t tick_len: length of a tick in tenths of a second.\n" + "-m max_lag: maximum expected lag(in ticks) between writer and readers\n" + "-B pbs: page Buffer Size in bytes:\n" + " The default value is 4K(4096).\n" + "-s ps: page size used by page aggregation, page buffer and \n" + " the metadata file. \n" + "-n ngroups: the number of groups\n" + "-l ng_levels: the number of level of nested groups. \n" + " If all the groups are under the root group, \n" + " this number should be 0.\n" + "-N num_attrs: the number of attributes \n" + "-V use variable length string attributes for performance test\n" + "-b: write data in big-endian byte order\n" + " (For the performance test, -V overwrites -b)\n" + "-A at_pattern: `at_pattern' for different attribute tests\n" + " The value of `at_pattern` is one of the following:\n" + " `compact` - Attributes added in compact storage\n" + " `dense` - An attribute added in dense storage\n" + " `compact-del` - Attributes added and then one\n" + " attribute deleted, in compact \n" + " `dense-del` - Attributes added until the storage\n" + " is dense then an attribute deleted\n" + " the storge still in dense\n" + " `compact-add-to-dense` - Attributes added first in compact\n" + " then in dense storage\n" + " `dense-del-to-compact` - Attributes added until the storage\n" + " is dense, then several attributes \n" + " deleted, the storage changed to\n" + " compact\n" + " `modify` - An attribute added then modified\n" + " `add-vstr` - A VL string attribute added\n" + " `remove-vstr` - A VL string attribute added then\n" + " deleted\n" + " `modify-vstr` - A VL string attribute added then \n" + " modified \n" + " `add-ohr-block` - An attribute is added and this forces\n" + " the creation of object header\n" + " continuation block \n" + " `del-ohr-block` - An attribute is added and this forces\n" + " the creation of object header\n" + " continuation block and then this \n" + " attribute is deleted so the \n" + " object header continuation block is \n" + " removed. \n" + "-O grp_op_pattern: `grp_op_pattern' for different group operation tests\n" + " The value of `grp_op_pattern` is one of the following:\n" + " `grp-creation` - A group is created.\n" + " `grp-deletion` - An existing group is deleted.\n" + " `grp-move` - A group is moved to become \n" + " another group. \n" + " `grp-ins-links` - Links are inserted, including\n" + " both hard and soft links. \n" + " `grp-del-links` - Links are deleted, including\n" + " both hard ans soft links. \n" + " `grp-compact-t-dense` - Links are inserted to the group.\n" + " The link storage of this group \n" + " changed from compact to dense. \n" + " The links include both hard and\n" + " soft links. \n" + " `grp-dense-t-compact` - Links are inserted to the group\n" + " The link storage of this group \n" + " changed from compact to dense. \n" + " Then several links are deleted.\n" + " The link storage changed from \n" + " dense to compact again. \n" + " The links include both hard and\n" + " soft links. \n" + "-a steps: `steps` between adding attributes\n" + " (Don't recommend to use this option for performance test.)\n" + "-q: silence printouts, few messages\n" + "\n", + progname, progname); exit(EXIT_FAILURE); } @@ -2789,10 +2790,9 @@ main(int argc, char **argv) init_vfd_swmr_config(&config, s.tick_len, s.max_lag, writer, FALSE, 128, "./group-shadow"); /* If the log flag is on, create the log file log-test under the current directory. */ - if(s.glog == true) + if (s.glog == true) init_vfd_swmr_log(&config, "./log-test"); - /* If old-style option is chosen, use the earliest file format(H5F_LIBVER_EARLIEST) * as the second parameter of H5Pset_libver_bound() that is called by * vfd_swmr_create_fapl. Otherwise, the latest file format(H5F_LIBVER_LATEST) -- cgit v0.12 From 0e3dc9ffedd3ab68f561803dbfb2d7c23210bb91 Mon Sep 17 00:00:00 2001 From: myang6 Date: Tue, 2 Nov 2021 15:41:28 -0500 Subject: Make entry log code as a #define macro as John suggests. --- src/H5Fint.c | 2 +- src/H5Fpkg.h | 9 +++++++++ src/H5Fvfd_swmr.c | 6 +++--- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/H5Fint.c b/src/H5Fint.c index c0579bd..c3fc346 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -2228,7 +2228,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) 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, 1, "File open ends"); + H5F_POST_VFD_SWMR_LOG_ENTRY(file, FILE_OPEN, "File open ends"); #endif done: if ((NULL == ret_value) && file) { diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 6dd896e..f8909b3 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -666,4 +666,13 @@ H5_DLL void H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log #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 b3c3ffe..8da238c 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -61,7 +61,7 @@ * 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, 0, log_msg) will put the log_msg attached to + * 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. @@ -358,7 +358,7 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing) } #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, 2, "VFD SWMR File close ends"); + H5F_POST_VFD_SWMR_LOG_ENTRY(f, FILE_CLOSE, "VFD SWMR File close ends"); #endif done: @@ -958,7 +958,7 @@ done: 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, 0, log_msg); + H5F_POST_VFD_SWMR_LOG_ENTRY(f, EOT_PROCESSING_TIME, log_msg); HDfree(log_msg); } } -- cgit v0.12 From ff024427f8ba18e896bbacbe61aa9b423c666df3 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Nov 2021 20:52:46 +0000 Subject: Committing clang-format changes --- src/H5Fpkg.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index f8909b3..706e41d 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -668,11 +668,11 @@ H5_DLL void H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log /* Macros for VFD SWMR log entry code * Note: this should be consistent with const char *H5Fvfd_swmr_log_tags[] declared at - * H5Fvfd_swmr.c . + * H5Fvfd_swmr.c . */ -#define EOT_PROCESSING_TIME 0 -#define FILE_OPEN 1 -#define FILE_CLOSE 2 -#define EOT_TRIGGER_TIME 3 +#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 */ -- cgit v0.12