diff options
-rw-r--r-- | test/cache_image.c | 30 | ||||
-rw-r--r-- | test/genall5.c | 271 | ||||
-rw-r--r-- | test/genall5.h | 22 | ||||
-rw-r--r-- | test/vfd_swmr_zoo_writer.c | 251 |
4 files changed, 472 insertions, 102 deletions
diff --git a/test/cache_image.c b/test/cache_image.c index f3db30b..d4002c7 100644 --- a/test/cache_image.c +++ b/test/cache_image.c @@ -4819,7 +4819,9 @@ cache_image_smoke_check_5(hbool_t single_file_vfd) /* 3) Construct a "zoo" in the above group, and validate it. */ if ( pass ) - pass = create_zoo(file_id, process_group_name, min_group, false); + pass = create_zoo(file_id, process_group_name, + (zoo_config_t){.proc_num = min_group, .skip_varlen = false, + .skip_compact = false}); #if H5C_COLLECT_CACHE_STATS if ( pass ) { @@ -4890,8 +4892,11 @@ cache_image_smoke_check_5(hbool_t single_file_vfd) /* 6) Validate the "zoo" created in the previous file open. */ - if ( pass ) - pass = validate_zoo(file_id, process_group_name, max_group, false); + if ( pass ) { + pass = validate_zoo(file_id, process_group_name, + (zoo_config_t){.proc_num = max_group, .skip_varlen = false, + .skip_compact = false}); + } #if H5C_COLLECT_CACHE_STATS if ( pass ) { @@ -4931,8 +4936,11 @@ cache_image_smoke_check_5(hbool_t single_file_vfd) /* 8) Construct a "zoo" in the above group, and validate it. */ - if ( pass ) - pass = create_zoo(file_id, process_group_name, max_group, false); + if ( pass ) { + pass = create_zoo(file_id, process_group_name, + (zoo_config_t){.proc_num = max_group, .skip_varlen = false, + .skip_compact = false}); + } if ( show_progress ) HDfprintf(stdout, "%s:L4 cp = %d, max_group = %d, pass = %d.\n", @@ -4993,7 +5001,9 @@ cache_image_smoke_check_5(hbool_t single_file_vfd) i = min_group; while(pass && i <= max_group) { HDsprintf(process_group_name, "/process_%d", i); - pass = validate_zoo(file_id, process_group_name, i++, false); + pass = validate_zoo(file_id, process_group_name, + (zoo_config_t){.proc_num = i++, .skip_varlen = false, + .skip_compact = false}); } #if H5C_COLLECT_CACHE_STATS @@ -5046,7 +5056,9 @@ cache_image_smoke_check_5(hbool_t single_file_vfd) while ( ( pass ) && ( i <= max_group ) ) { HDsprintf(process_group_name, "/process_%d", i); - pass = validate_zoo(file_id, process_group_name, i++, false); + pass = validate_zoo(file_id, process_group_name, + (zoo_config_t){.proc_num = i++, .skip_varlen = false, + .skip_compact = false}); } #if H5C_COLLECT_CACHE_STATS @@ -5110,7 +5122,9 @@ cache_image_smoke_check_5(hbool_t single_file_vfd) i = min_group; while ( ( pass ) && ( i <= max_group ) ) { HDsprintf(process_group_name, "/process_%d", i); - pass = validate_zoo(file_id, process_group_name, i++, false); + pass = validate_zoo(file_id, process_group_name, + (zoo_config_t){.proc_num = i++, .skip_varlen = false, + .skip_compact = false}); } #if H5C_COLLECT_CACHE_STATS diff --git a/test/genall5.c b/test/genall5.c index d9064d8..ec2849b 100644 --- a/test/genall5.c +++ b/test/genall5.c @@ -19,6 +19,8 @@ * of the same name. */ +#include <err.h> + #include "cache_common.h" #include "genall5.h" @@ -27,6 +29,45 @@ #define DSET_CHUNK_DIMS 1024 #define DSET_COMPACT_DIMS 4096 +typedef enum phase {PHASE_CREATE, PHASE_VALIDATE, PHASE_DELETE, + PHASE_VALIDATE_DELETION} phase_t; + +static bool rm_ns_grp_0(hid_t, const char *); +static bool rm_ns_grp_c(hid_t, const char *, unsigned); +static bool rm_ns_grp_d(hid_t, const char *, unsigned); +static bool rm_os_grp_0(hid_t, const char *); +static bool rm_os_grp_n(hid_t, const char *, int, unsigned); +static bool rm_ds_ctg_i(hid_t, const char *, hbool_t); +static bool rm_ds_chk_i(hid_t, const char *, hbool_t); +static bool rm_ds_cpt_i(hid_t, const char *, hbool_t); +static bool rm_ds_ctg_v(hid_t, const char *, hbool_t); + +static bool missing_ns_grp_0(hid_t, const char *); +static bool missing_ns_grp_c(hid_t, const char *, unsigned); +static bool missing_ns_grp_d(hid_t, const char *, unsigned); +static bool missing_os_grp_0(hid_t, const char *); +static bool missing_os_grp_n(hid_t, const char *, int, unsigned); +static bool missing_ds_ctg_i(hid_t, const char *, hbool_t); +static bool missing_ds_chk_i(hid_t, const char *, hbool_t); +static bool missing_ds_cpt_i(hid_t, const char *, hbool_t); +static bool missing_ds_ctg_v(hid_t, const char *, hbool_t); + +#define FN_ITEM_DEFN(__name, ...) \ + typedef bool (*__name##fn_t)(__VA_ARGS__); \ + static const __name##fn_t __name##_fntbl[] = \ + {__name, vrfy_##__name, rm_##__name, missing_##__name} + +FN_ITEM_DEFN(ns_grp_0, hid_t, const char *); +FN_ITEM_DEFN(ns_grp_c, hid_t, const char *, unsigned); +FN_ITEM_DEFN(ns_grp_d, hid_t, const char *, unsigned); +FN_ITEM_DEFN(os_grp_0, hid_t, const char *); +FN_ITEM_DEFN(os_grp_n, hid_t, const char *, int, unsigned); +FN_ITEM_DEFN(ds_ctg_i, hid_t, const char *, bool); +FN_ITEM_DEFN(ds_chk_i, hid_t, const char *, bool); +FN_ITEM_DEFN(ds_cpt_i, hid_t, const char *, bool); +FN_ITEM_DEFN(ds_ctg_v, hid_t, const char *, bool); + +#undef FN_ITEM_DEFN /*------------------------------------------------------------------------- * Function: ns_grp_0 @@ -45,6 +86,18 @@ *------------------------------------------------------------------------- */ +static bool +missing_ns_grp_0(hid_t fid, const char *group_name) +{ + return true; +} + +static bool +rm_ns_grp_0(hid_t fid, const char *group_name) +{ + return true; +} + bool ns_grp_0(hid_t fid, const char *group_name) { @@ -198,6 +251,18 @@ vrfy_ns_grp_0(hid_t fid, const char *group_name) *------------------------------------------------------------------------- */ +static bool +missing_ns_grp_c(hid_t fid, const char *group_name, unsigned nlinks) +{ + return true; +} + +static bool +rm_ns_grp_c(hid_t fid, const char *group_name, unsigned nlinks) +{ + return true; +} + bool ns_grp_c(hid_t fid, const char *group_name, unsigned nlinks) { @@ -530,6 +595,18 @@ vrfy_ns_grp_c(hid_t fid, const char *group_name, unsigned nlinks) *------------------------------------------------------------------------- */ +static bool +missing_ns_grp_d(hid_t fid, const char *group_name, unsigned nlinks) +{ + return true; +} + +static bool +rm_ns_grp_d(hid_t fid, const char *group_name, unsigned nlinks) +{ + return true; +} + bool ns_grp_d(hid_t fid, const char *group_name, unsigned nlinks) { @@ -857,6 +934,18 @@ vrfy_ns_grp_d(hid_t fid, const char *group_name, unsigned nlinks) *------------------------------------------------------------------------- */ +static bool +missing_os_grp_0(hid_t fid, const char *group_name) +{ + return true; +} + +static bool +rm_os_grp_0(hid_t fid, const char *group_name) +{ + return true; +} + bool os_grp_0(hid_t fid, const char *group_name) { @@ -1019,6 +1108,19 @@ vrfy_os_grp_0(hid_t fid, const char *group_name) *------------------------------------------------------------------------- */ +static bool +missing_os_grp_n(hid_t fid, const char *group_name, int proc_num, + unsigned nlinks) +{ + return true; +} + +static bool +rm_os_grp_n(hid_t fid, const char *group_name, int proc_num, unsigned nlinks) +{ + return true; +} + bool os_grp_n(hid_t fid, const char *group_name, int proc_num, unsigned nlinks) { @@ -1292,6 +1394,18 @@ vrfy_os_grp_n(hid_t fid, const char *group_name, int proc_num, unsigned nlinks) * *------------------------------------------------------------------------- */ +static bool +missing_ds_ctg_i(hid_t fid, const char *dset_name, hbool_t write_data) +{ + return true; +} + +static bool +rm_ds_ctg_i(hid_t fid, const char *dset_name, hbool_t write_data) +{ + return true; +} + bool ds_ctg_i(hid_t fid, const char *dset_name, hbool_t write_data) { @@ -1541,6 +1655,18 @@ vrfy_ds_ctg_i(hid_t fid, const char *dset_name, hbool_t write_data) * *------------------------------------------------------------------------- */ +static bool +missing_ds_chk_i(hid_t fid, const char *dset_name, hbool_t write_data) +{ + return true; +} + +static bool +rm_ds_chk_i(hid_t fid, const char *dset_name, hbool_t write_data) +{ + return true; +} + bool ds_chk_i(hid_t fid, const char *dset_name, hbool_t write_data) { @@ -1818,6 +1944,28 @@ vrfy_ds_chk_i(hid_t fid, const char *dset_name, hbool_t write_data) * *------------------------------------------------------------------------- */ +static bool +missing_ds_cpt_i(hid_t fid, const char *dset_name, hbool_t H5_ATTR_UNUSED write_data) +{ + if (H5Lexists(fid, dset_name, H5P_DEFAULT) >= 0) { + failure_mssg = "rm_ds_cpt_i: H5Lexists unexpectedly succeeded."; + return false; + } + + return true; +} + +static bool +rm_ds_cpt_i(hid_t fid, const char *dset_name, hbool_t H5_ATTR_UNUSED write_data) +{ + if (H5Ldelete(fid, dset_name, H5P_DEFAULT) < 0) { + failure_mssg = "rm_ds_cpt_i: H5Ldelete failed."; + return false; + } + + return true; +} + bool ds_cpt_i(hid_t fid, const char *dset_name, hbool_t write_data) { @@ -2084,6 +2232,18 @@ vrfy_ds_cpt_i(hid_t fid, const char *dset_name, hbool_t write_data) * *------------------------------------------------------------------------- */ +static bool +missing_ds_ctg_v(hid_t fid, const char *dset_name, hbool_t write_data) +{ + return true; +} + +static bool +rm_ds_ctg_v(hid_t fid, const char *dset_name, hbool_t write_data) +{ + return true; +} + bool ds_ctg_v(hid_t fid, const char *dset_name, hbool_t write_data) { @@ -2409,97 +2569,83 @@ vrfy_ds_ctg_v(hid_t fid, const char *dset_name, hbool_t write_data) * * Return `true` if the selector was valid, `false` if it was not. */ + static bool -create_or_validate_selection(hid_t fid, const char *full_path, int proc_num, - int selector, bool skip_varlen, bool validate, bool *okp) +create_or_validate_selection(hid_t fid, const char *full_path, + int selector, zoo_config_t config, phase_t phase, bool *okp) { - const bool wr = !validate; bool ok; switch (selector) { case 0: /* Add & verify an empty "new style" group */ - ok = wr ? ns_grp_0(fid, full_path) : vrfy_ns_grp_0(fid, full_path); + ok = ns_grp_0_fntbl[phase](fid, full_path); break; case 1: /* Add & verify a compact "new style" group (3 link messages) */ - ok = wr ? ns_grp_c(fid, full_path, 3) - : vrfy_ns_grp_c(fid, full_path, 3); + ok = ns_grp_c_fntbl[phase](fid, full_path, 3); break; case 2: /* Add & verify a dense "new style" group (w/300 links, * in v2 B-tree & fractal heap) */ - ok = wr ? ns_grp_d(fid, full_path, 300) - : vrfy_ns_grp_d(fid, full_path, 300); + ok = ns_grp_d_fntbl[phase](fid, full_path, 300); break; case 3: /* Add & verify an empty "old style" group to file */ - ok = wr ? os_grp_0(fid, full_path) : vrfy_os_grp_0(fid, full_path); + ok = os_grp_0_fntbl[phase](fid, full_path); break; case 4: /* Add & verify an "old style" group (w/300 links, in * v1 B-tree & local heap) to file */ - ok = wr ? os_grp_n(fid, full_path, proc_num, 300) - : vrfy_os_grp_n(fid, full_path, proc_num, 300); + ok = os_grp_n_fntbl[phase](fid, full_path, config.proc_num, 300); break; case 5: /* Add & verify a contiguous dataset w/integer datatype (but no data) * to file */ - ok = wr ? ds_ctg_i(fid, full_path, FALSE) - : vrfy_ds_ctg_i(fid, full_path, FALSE); + ok = ds_ctg_i_fntbl[phase](fid, full_path, false); break; case 6: /* Add & verify a contiguous dataset w/integer datatype (with data) * to file */ - ok = wr ? ds_ctg_i(fid, full_path, TRUE) - : vrfy_ds_ctg_i(fid, full_path, TRUE); + ok = ds_ctg_i_fntbl[phase](fid, full_path, true); break; case 7: /* Add & verify a chunked dataset w/integer datatype (but no data) * to file */ - ok = wr ? ds_chk_i(fid, full_path, FALSE) - : vrfy_ds_chk_i(fid, full_path, FALSE); + ok = ds_chk_i_fntbl[phase](fid, full_path, false); break; case 8: /* Add & verify a chunked dataset w/integer datatype (and data) * to file */ - ok = wr ? ds_chk_i(fid, full_path, TRUE) - : vrfy_ds_chk_i(fid, full_path, TRUE); + ok = ds_chk_i_fntbl[phase](fid, full_path, true); break; case 9: /* Add & verify a compact dataset w/integer datatype (but no data) * to file */ - ok = wr ? ds_cpt_i(fid, full_path, FALSE) - : vrfy_ds_cpt_i(fid, full_path, FALSE); + ok = config.skip_compact || + ds_cpt_i_fntbl[phase](fid, full_path, false); break; case 10: /* Add & verify a compact dataset w/integer datatype (and data) * to file */ - ok = wr ? ds_cpt_i(fid, full_path, TRUE) - : vrfy_ds_cpt_i(fid, full_path, TRUE); + ok = config.skip_compact || ds_cpt_i_fntbl[phase](fid, full_path, true); break; case 11: - if (skip_varlen) - return false; /* Add & verify a contiguous dataset w/variable-length datatype * (but no data) to file */ - ok = wr ? ds_ctg_v(fid, full_path, FALSE) - : vrfy_ds_ctg_v(fid, full_path, FALSE); + ok = config.skip_varlen || ds_ctg_v_fntbl[phase](fid, full_path, false); break; case 12: - if (skip_varlen) - return false; /* Add & verify a contiguous dataset w/variable-length datatype * (and data) to file */ - ok = wr ? ds_ctg_v(fid, full_path, TRUE) - : vrfy_ds_ctg_v(fid, full_path, TRUE); + ok = config.skip_varlen || ds_ctg_v_fntbl[phase](fid, full_path, true); break; default: return false; @@ -2509,47 +2655,50 @@ create_or_validate_selection(hid_t fid, const char *full_path, int proc_num, } /* Create and validate objects or, if `only_validate` is true, only - * validate objects in file `fid` under group `base_path`. `proc_num` - * tells the processor number the test runs on. If `skip_varlen` is + * validate objects in file `fid` under group `base_path`. `config.proc_num` + * tells the processor number the test runs on. If `config.skip_varlen` is * true, do NOT perform tests that use variable-length data. * * Return true if all tests pass, false if any test fails. */ + static bool -tend_zoo(hid_t fid, const char *base_path, int proc_num, bool skip_varlen, - bool only_validate) +tend_zoo(hid_t fid, const char *base_path, zoo_config_t config, + const phase_t *phase, size_t nphases) { - const bool create = !only_validate; + struct timespec delay = {.tv_sec = 0, .tv_nsec = 50 * 1000 * 1000}; char full_path[1024]; int i, nwritten; + size_t j; char *leafp; bool ok = true; nwritten = snprintf(full_path, sizeof(full_path), "%s/*", base_path); if (nwritten < 0 || (size_t)nwritten >= sizeof(full_path)) { - failure_mssg = "create_zoo: snprintf failed"; + failure_mssg = "tend_zoo: snprintf failed"; return false; } if ((leafp = strrchr(full_path, '*')) == NULL) { - failure_mssg = "create_zoo: strrchr failed"; + failure_mssg = "tend_zoo: strrchr failed"; return false; } for (i = 0; ok; i++) { assert('A' + i <= 'Z'); *leafp = (char)('A' + i); - if (create && - !create_or_validate_selection(fid, full_path, proc_num, i, - skip_varlen, false, &ok)) - break; - zoo_create_hook(fid); - if (!create_or_validate_selection(fid, full_path, proc_num, i, - skip_varlen, true, &ok)) - break; + for (j = 0; j < nphases; j++) { + if (!create_or_validate_selection(fid, full_path, i, config, + phase[j], &ok)) + goto out; + if (phase[j] == PHASE_CREATE || phase[j] == PHASE_DELETE) + zoo_create_hook(fid); + } } + nanosleep(&delay, NULL); +out: if (!ok) - fprintf(stderr, "%s: %s\n", __func__, failure_mssg); + warnx("%s: %s", __func__, failure_mssg); return ok; } @@ -2575,9 +2724,11 @@ tend_zoo(hid_t fid, const char *base_path, int proc_num, bool skip_varlen, */ bool -create_zoo(hid_t fid, const char *base_path, int proc_num, bool skip_varlen) +create_zoo(hid_t fid, const char *base_path, zoo_config_t config) { - return tend_zoo(fid, base_path, proc_num, skip_varlen, false); + const phase_t phase[] = {PHASE_CREATE, PHASE_VALIDATE}; + + return tend_zoo(fid, base_path, config, phase, NELMTS(phase)); } /*------------------------------------------------------------------------- @@ -2600,8 +2751,26 @@ create_zoo(hid_t fid, const char *base_path, int proc_num, bool skip_varlen) */ bool -validate_zoo(hid_t fid, const char *base_path, int proc_num, bool skip_varlen) +validate_zoo(hid_t fid, const char *base_path, zoo_config_t config) +{ + const phase_t phase[] = {PHASE_VALIDATE}; + + return tend_zoo(fid, base_path, config, phase, NELMTS(phase)); +} + +bool +delete_zoo(hid_t fid, const char *base_path, zoo_config_t config) { - return tend_zoo(fid, base_path, proc_num, skip_varlen, true); + const phase_t phase[] = {PHASE_DELETE}; + + return tend_zoo(fid, base_path, config, phase, NELMTS(phase)); +} + +bool +validate_deleted_zoo(hid_t fid, const char *base_path, zoo_config_t config) +{ + const phase_t phase[] = {PHASE_VALIDATE_DELETION}; + + return tend_zoo(fid, base_path, config, phase, NELMTS(phase)); } diff --git a/test/genall5.h b/test/genall5.h index 3878da1..4e5fbba 100644 --- a/test/genall5.h +++ b/test/genall5.h @@ -11,17 +11,21 @@ * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* Programmer: John Mainzer - * 9/4/15 - * - * This file contains declarations of all functions defined - * in genall5.c +/* + * This file contains declarations of all functions defined in genall5.c */ -bool create_zoo(hid_t fid, const char *base_path, int proc_num, - bool skip_varlen); -bool validate_zoo(hid_t fid, const char *base_path, int proc_num, - bool skip_varlen); +typedef struct _zoo_config { + int proc_num; + bool continue_on_failure; + bool skip_compact; + bool skip_varlen; +} zoo_config_t; + +bool create_zoo(hid_t, const char *, zoo_config_t); +bool validate_zoo(hid_t, const char *, zoo_config_t); +bool delete_zoo(hid_t, const char *, zoo_config_t); +bool validate_deleted_zoo(hid_t, const char *, zoo_config_t); bool ns_grp_0(hid_t fid, const char *group_name); bool vrfy_ns_grp_0(hid_t fid, const char *group_name); diff --git a/test/vfd_swmr_zoo_writer.c b/test/vfd_swmr_zoo_writer.c index d4f9cbe..a3e0a08 100644 --- a/test/vfd_swmr_zoo_writer.c +++ b/test/vfd_swmr_zoo_writer.c @@ -16,11 +16,13 @@ #include <time.h> /* nanosleep(2) */ #include <unistd.h> /* getopt(3) */ -#define H5C_FRIEND /*suppress error about including H5Cpkg */ -#define H5F_FRIEND /*suppress error about including H5Fpkg */ +#define H5C_FRIEND /* suppress error about including H5Cpkg */ +#define H5F_FRIEND /* suppress error about including H5Fpkg */ #include "hdf5.h" +#include "H5private.h" +#include "H5retry_private.h" #include "H5Cpkg.h" #include "H5Fpkg.h" // #include "H5Iprivate.h" @@ -31,14 +33,25 @@ #include "genall5.h" #include "vfd_swmr_common.h" -enum _step { - CREATE = 0 -, LENGTHEN -, SHORTEN -, DELETE -, NSTEPS -} step_t; - +typedef struct _shared_ticks { + uint64_t reader_tick; +} shared_ticks_t; + +typedef struct _tick_stats { + uint64_t writer_tried_increase; + uint64_t writer_aborted_increase; + uint64_t writer_read_shared_file; + uint64_t reader_tick_was_zero; // writer read reader tick equal to 0 + uint64_t reader_tick_lead_writer; // writer read reader tick greater than + // proposed writer tick + uint64_t writer_lead_reader_by[1]; // proposed writer tick lead reader + // tick by `lead` ticks + // `writer_lead_reader_by[lead]` + // times, for `0 <= lead <= max_lag - 1` +} tick_stats_t; + +static H5F_vfd_swmr_config_t swmr_config; +static tick_stats_t *tick_stats = NULL; static const hid_t badhid = H5I_INVALID_HID; static bool caught_out_of_bounds = false; static bool writer; @@ -66,10 +79,13 @@ zoo_create_hook(hid_t fid) static void usage(const char *progname) { - fprintf(stderr, "usage: %s [-W] [-V]\n", progname); - fprintf(stderr, "\n -W: do not wait for SIGINT or SIGUSR1\n"); - fprintf(stderr, "\n -S: do not use VFD SWMR\n"); + fprintf(stderr, "usage: %s [-C] [-S] [-W] [-a] [-e] [-n] [-q] [-v]\n", + progname); + fprintf(stderr, "\n -C: skip compact dataset tests\n"); + fprintf(stderr, " -S: do not use VFD SWMR\n"); + fprintf(stderr, " -W: do not wait for SIGINT or SIGUSR1\n"); fprintf(stderr, " -a: run all tests, including variable-length data\n"); + fprintf(stderr, " -e: print error stacks\n"); fprintf(stderr, " -n: number of test steps to perform\n"); fprintf(stderr, " -q: be quiet: few/no progress messages\n"); fprintf(stderr, " -v: be verbose: most progress messages\n"); @@ -86,6 +102,108 @@ H5HG_trap(const char *reason) return true; } +bool +vfd_swmr_writer_may_increase_tick_to(uint64_t new_tick, bool wait_for_reader) +{ + static int fd = -1; + shared_ticks_t shared; + ssize_t nread; + h5_retry_t retry; + bool do_try; + + fprintf(stderr, "%s: enter\n", __func__); + + if (fd == -1) { + fd = open("./shared_tick_num", O_RDONLY); + if (fd == -1) { + warn("%s: open", __func__); // TBD ratelimit/silence this warning + return true; + } + assert(tick_stats == NULL); + tick_stats = calloc(1, sizeof(*tick_stats) + + (swmr_config.max_lag - 1) * + sizeof(tick_stats->writer_lead_reader_by[0])); + if (tick_stats == NULL) + err(EXIT_FAILURE, "%s: calloc", __func__); + } + + tick_stats->writer_tried_increase++; + + for (do_try = h5_retry_init(&retry, 14, 10 * 1000 * 1000, + 100 * 1000 * 1000); + do_try; + do_try = wait_for_reader && h5_retry_next(&retry)) { + + tick_stats->writer_read_shared_file++; + + if ((nread = pread(fd, &shared, sizeof(shared), 0)) == -1) + err(EXIT_FAILURE, "%s: pread", __func__); + + if (nread != sizeof(shared)) + errx(EXIT_FAILURE, "%s: pread", __func__); + + // TBD convert endianness + + if (shared.reader_tick == 0) { + tick_stats->reader_tick_was_zero++; + return true; + } + + if (new_tick < shared.reader_tick) { + tick_stats->reader_tick_lead_writer++; + return true; + } + if (new_tick <= shared.reader_tick + swmr_config.max_lag - 1) { + uint64_t lead = new_tick - shared.reader_tick; + assert(lead <= swmr_config.max_lag - 1); + tick_stats->writer_lead_reader_by[lead]++; + return true; + } + } + if (wait_for_reader && !do_try) + errx(EXIT_FAILURE, "%s: timed out waiting for reader", __func__); + + tick_stats->writer_aborted_increase++; + + return false; +} + +void +vfd_swmr_reader_did_increase_tick_to(uint64_t new_tick) +{ + static int fd = -1; + shared_ticks_t shared; + ssize_t nwritten; + + fprintf(stderr, "%s: enter\n", __func__); + + if (fd == -1) { + // TBD create a temporary file, here, and move it to its final path + // after writing it. + fd = open("./shared_tick_num", O_RDWR|O_CREAT, 0600); + if (fd == -1) + err(EXIT_FAILURE, "%s: open", __func__); + } + + shared.reader_tick = new_tick; + + // TBD convert endianness + + if ((nwritten = pwrite(fd, &shared, sizeof(shared), 0)) == -1) + errx(EXIT_FAILURE, "%s: pwrite", __func__); + + if (nwritten != sizeof(shared)) + errx(EXIT_FAILURE, "%s: pwrite", __func__); + + if (new_tick == 0) { + if (unlink("./shared_tick_num") == -1) + warn("%s: unlink", __func__); + if (close(fd) == -1) + err(EXIT_FAILURE, "%s: close", __func__); + fd = -1; + } +} + int main(int argc, char **argv) { @@ -94,18 +212,26 @@ main(int argc, char **argv) H5C_t *cache; sigset_t oldsigs; herr_t ret; - bool skip_varlen = true, wait_for_signal; + zoo_config_t config = { + .proc_num = 0 + , .skip_compact = false + , .skip_varlen = true}; + bool wait_for_signal; int ch; bool use_vfd_swmr = true; + bool print_estack = false; #if 0 unsigned long tmp; char *end; - int i, ntimes = 100; + int i; const struct timespec delay = {.tv_sec = 0, .tv_nsec = 1000 * 1000 * 1000 / 10}; #endif const char *progname = basename(argv[0]); estack_state_t es; +#if 0 + char step[2] = "ab"; +#endif dbgf(1, "0th arg %s, personality `%s`\n", argv[0], progname); @@ -118,8 +244,11 @@ main(int argc, char **argv) "unknown personality, expected vfd_swmr_zoo_{reader,writer}"); } - while ((ch = getopt(argc, argv, "SWan:qv")) != -1) { + while ((ch = getopt(argc, argv, "CSWaen:qv")) != -1) { switch(ch) { + case 'C': + config.skip_compact = true; + break; case 'S': use_vfd_swmr = false; break; @@ -127,21 +256,11 @@ main(int argc, char **argv) wait_for_signal = false; break; case 'a': - skip_varlen = false; + config.skip_varlen = false; break; -#if 0 - case 'n': - errno = 0; - tmp = strtoul(optarg, &end, 0); - if (end == optarg || *end != '\0') - errx(EXIT_FAILURE, "couldn't parse `-n` argument `%s`", optarg); - else if (errno != 0) - err(EXIT_FAILURE, "couldn't parse `-n` argument `%s`", optarg); - else if (tmp > INT_MAX) - errx(EXIT_FAILURE, "`-n` argument `%lu` too large", tmp); - ntimes = (int)tmp; + case 'e': + print_estack = true; break; -#endif case 'q': verbosity = 1; break; @@ -161,9 +280,16 @@ main(int argc, char **argv) fapl = vfd_swmr_create_fapl(writer, true, use_vfd_swmr); + if (use_vfd_swmr && H5Pget_vfd_swmr_config(fapl, &swmr_config) < 0) + errx(EXIT_FAILURE, "H5Pget_vfd_swmr_config"); + if (fapl < 0) errx(EXIT_FAILURE, "vfd_swmr_create_fapl"); + if (H5Pset_libver_bounds(fapl, H5F_LIBVER_EARLIEST, H5F_LIBVER_LATEST) < 0){ + errx(EXIT_FAILURE, "%s.%d: H5Pset_libver_bounds", __func__, __LINE__); + } + if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) errx(EXIT_FAILURE, "H5Pcreate"); @@ -189,23 +315,77 @@ main(int argc, char **argv) print_cache_hits(cache); - es = disable_estack(); + es = print_estack ? estack_get_state() : disable_estack(); if (writer) { + +#if 0 + H5Fvfd_swmr_end_tick(fid); + + if (read(STDIN_FILENO, &step[0], sizeof(step[0])) == -1) + err(EXIT_FAILURE, "read"); + + if (step[0] != 'a') + errx(EXIT_FAILURE, "expected 'a' read '%c'", step[0]); +#endif + dbgf(1, "Writing zoo...\n"); - if (!create_zoo(fid, ".", 0, skip_varlen)) + + if (!create_zoo(fid, ".", config)) errx(EXIT_FAILURE, "create_zoo didn't pass self-check"); + +#if 1 + H5Fvfd_swmr_end_tick(fid); +#endif + +#if 0 + if (read(STDIN_FILENO, &step[1], sizeof(step[1])) == -1) + err(EXIT_FAILURE, "read"); + + if (step[1] != 'b') + errx(EXIT_FAILURE, "expected 'b' read '%c'", step[1]); + + if (!delete_zoo(fid, ".", config)) + errx(EXIT_FAILURE, "delete_zoo failed"); +#endif } else { dbgf(1, "Reading zoo...\n"); - while (!validate_zoo(fid, ".", 0, skip_varlen)) +#if 0 + if (write(STDOUT_FILENO, &step[0], sizeof(step[0])) == -1) + err(EXIT_FAILURE, "write"); +#endif + while (!validate_zoo(fid, ".", config)) + ; +#if 0 + if (write(STDOUT_FILENO, &step[1], sizeof(step[1])) == -1) + err(EXIT_FAILURE, "write"); + while (!validate_deleted_zoo(fid, ".", config)) ; +#endif } restore_estack(es); if (use_vfd_swmr && wait_for_signal) await_signal(fid); - if (wait_for_signal) - restore_signals(&oldsigs); + if (writer && tick_stats != NULL) { + uint64_t lead; + + dbgf(1, "writer tried tick increase %" PRIu64 "\n", + tick_stats->writer_tried_increase); + dbgf(1, "writer aborted tick increase %" PRIu64 "\n", + tick_stats->writer_aborted_increase); + dbgf(1, "writer read shared file %" PRIu64 "\n", + tick_stats->writer_read_shared_file); + dbgf(1, "writer read reader tick equal to 0 %" PRIu64 "\n", + tick_stats->reader_tick_was_zero); + dbgf(1, "writer read reader tick leading writer %" PRIu64 "\n", + tick_stats->reader_tick_lead_writer); + + for (lead = 0; lead < swmr_config.max_lag; lead++) { + dbgf(1, "writer tick lead writer by %" PRIu64 " %" PRIu64 "\n", + lead, tick_stats->writer_lead_reader_by[lead]); + } + } if (H5Pclose(fapl) < 0) errx(EXIT_FAILURE, "H5Pclose(fapl)"); @@ -216,5 +396,8 @@ main(int argc, char **argv) if (H5Fclose(fid) < 0) errx(EXIT_FAILURE, "H5Fclose"); + if (wait_for_signal) + restore_signals(&oldsigs); + return EXIT_SUCCESS; } |