From 79fc79c416e2650a0d28304cc5c09b85543b3b96 Mon Sep 17 00:00:00 2001 From: Songyu Lu Date: Thu, 3 Jun 2021 10:52:56 -0500 Subject: Some changes to the big set test: 1. changed the signal handling to named pipes for communication between the writer and reader; 2. the writer writes as many chunks within a tick then notify the reader to verify the data; 3. some refactoring work. --- test/testvfdswmr.sh.in | 30 +- test/vfd_swmr_bigset_writer.c | 1624 ++++++++++++++++++++++++++++++----------- 2 files changed, 1219 insertions(+), 435 deletions(-) diff --git a/test/testvfdswmr.sh.in b/test/testvfdswmr.sh.in index ea2fd7b..1fccfe6 100644 --- a/test/testvfdswmr.sh.in +++ b/test/testvfdswmr.sh.in @@ -53,7 +53,7 @@ fi ##Default setting BIGSET_n=25 # -n option: # of iterations BIGSET_few_s=20 # -s option: # of datasets (for few_big test) -BIGSET_many_s=500 # -s option: # of datasets (for many_small test) +BIGSET_many_s=200 # -s option: # of datasets (for many_small test) GROUP_n=40 # -n option: # of groups (for group test) GROUP_attr_n=1 # -n option: # of groups (for group attribute test) GROUP_op_n=1 # -n option: # of groups (for group attribute test) @@ -61,7 +61,7 @@ GROUP_op_n=1 # -n option: # of groups (for group attribut if [[ "$HDF5TestExpress" -eq 0 ]] ; then # Setting for exhaustive run BIGSET_n=50 BIGSET_few_s=40 - BIGSET_many_s=1000 + BIGSET_many_s=400 GROUP_n=400 GROUP_attr_n=2 GROUP_op_n=2 @@ -1032,8 +1032,7 @@ for options in ${os_grp_op_list[*]}; do rm -f vfd_swmr_group_reader.*.{out,rc} done - - +# bigset test for smaller chunks for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-d 1 -V" "-d 1 -M" "-d 1 -V -F" "-d 1 -M -F"; do if [ ${do_many_small:-no} = no ]; then continue @@ -1041,7 +1040,7 @@ for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-d 1 -V" "-d 1 -M" "-d 1 -V -F # # Test many small datasets of one and two dimensions. # - # Perform 50 iterations on 1000 extensible datasets configured with + # Perform 25 iterations on 200 extensible datasets configured with # 16x16 chunks of 32-bit unsigned integer elements, # expanding each dataset by a chunk in one dimension (up to 50x1 # 16x16 chunks) on each iteration. @@ -1051,19 +1050,18 @@ for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-d 1 -V" "-d 1 -M" "-d 1 -V -F # 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 -r 16 -c 16 -q & + ../vfd_swmr_bigset_writer -n $BIGSET_n $options -s $BIGSET_many_s -r 16 -c 16 -q -l 6 & pid_writer=$! catch_out_err_and_rc vfd_swmr_bigset_reader \ - ../vfd_swmr_bigset_reader -n $BIGSET_n $options -s $BIGSET_many_s -r 16 -c 16 -q -W & + ../vfd_swmr_bigset_reader -n $BIGSET_n $options -s $BIGSET_many_s -r 16 -c 16 -q -l 6 & pid_reader=$! - # Wait for the reader to finish before signalling the - # writer to quit: the writer holds the file open so that the + # Wait for the reader to finish before the + # writer quits: the writer holds the file open so that the # reader will find the shadow file when it opens # the .h5 file. wait $pid_reader - kill -USR1 $(cat vfd_swmr_bigset_writer.pid) wait $pid_writer # Collect exit code of the reader @@ -1083,11 +1081,12 @@ for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-d 1 -V" "-d 1 -M" "-d 1 -V -F rm -f vfd_swmr_bigset_reader.*.{out,rc} done +# bigset test for bigger chunks for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-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. # - # Perform 50 iterations on 5 extensible datasets configured with + # Perform 25 iterations on 20 extensible datasets configured with # 256x256 chunks of 32-bit unsigned integer elements, # expanding each dataset by a chunk in one dimension (up to 50x1 # 256x256 chunks) on each iteration. @@ -1100,19 +1099,18 @@ for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-d 1 -V" "-d 1 -M" "-d 1 -V -F fi echo launch vfd_swmr_bigset_writer few big, options $options catch_out_err_and_rc vfd_swmr_bigset_writer \ - ../vfd_swmr_bigset_writer -n $BIGSET_n $options -s $BIGSET_few_s -r 256 -c 256 -q & + ../vfd_swmr_bigset_writer -n $BIGSET_n $options -s $BIGSET_few_s -r 256 -c 256 -q -l 3 & pid_writer=$! catch_out_err_and_rc vfd_swmr_bigset_reader \ - ../vfd_swmr_bigset_reader -n $BIGSET_n $options -s $BIGSET_few_s -r 256 -c 256 -q -W & + ../vfd_swmr_bigset_reader -n $BIGSET_n $options -s $BIGSET_few_s -r 256 -c 256 -q -l 3 & pid_reader=$! - # Wait for the reader to finish before signalling the - # writer to quit: the writer holds the file open so that the + # Wait for the reader to finish before the + # writer quits: the writer holds the file open so that the # reader will find the shadow file when it opens # the .h5 file. wait $pid_reader - kill -USR1 $(cat vfd_swmr_bigset_writer.pid) wait $pid_writer # Collect exit code of the reader diff --git a/test/vfd_swmr_bigset_writer.c b/test/vfd_swmr_bigset_writer.c index 614a499..138b796 100644 --- a/test/vfd_swmr_bigset_writer.c +++ b/test/vfd_swmr_bigset_writer.c @@ -81,14 +81,13 @@ #ifndef H5_HAVE_WIN32_API -#include -#include - -#define ROWS 256 -#define COLS 512 -#define RANK 2 - -static const unsigned int hang_back = 3; +#define MAX_READ_LEN_IN_SECONDS 2 +#define TICK_LEN 4 +#define MAX_LAG 7 +#define ROWS 256 +#define COLS 512 +#define RANK 2 +#define NUM_ATTEMPTS 100 typedef struct _base { hsize_t row, col; @@ -121,7 +120,6 @@ typedef struct { unsigned ndatasets; const char * filename[MANY_FILES]; char progname[PATH_MAX]; - struct timespec update_interval; struct { quadrant_t ul, ur, bl, br, src; } quadrants; @@ -129,15 +127,41 @@ typedef struct { unsigned int asteps; unsigned int nsteps; bool two_dee; - bool wait_for_signal; enum { vds_off, vds_single, vds_multi } vds; bool use_vfd_swmr; + bool use_named_pipe; bool writer; bool fixed_array; hsize_t chunk_dims[RANK]; hsize_t one_dee_max_dims[RANK]; + struct timespec ival; } state_t; +/* Structure to hold info for named pipes */ +typedef struct { + const char *fifo_writer_to_reader; /* Name of fifo for writer to reader */ + const char *fifo_reader_to_writer; /* Name of fifo for reader to writer */ + int fd_writer_to_reader; /* File ID for fifo from writer to reader */ + int fd_reader_to_writer; /* File ID for fifo from reader to writer */ + int notify; /* Value to notify between writer and reader */ + int verify; /* Value to verify between writer and reader */ +} np_state_t; + +typedef struct { + unsigned step; + struct timespec time; +} exchange_info_t; + +/* Initializations for np_state_t */ +#define NP_INITIALIZER (np_state_t) { \ + .fifo_writer_to_reader = "./fifo_bigset_writer_to_reader" \ + , .fifo_reader_to_writer = "./fifo_bigset_reader_to_writer" \ + , .fd_writer_to_reader = -1 \ + , .fd_reader_to_writer = -1 \ + , .notify = 0 \ + , .verify = 0 \ +} + static inline state_t state_initializer(void) { @@ -154,18 +178,17 @@ state_initializer(void) .nsteps = 100, .filename = {"", "", "", ""}, .two_dee = false, - .wait_for_signal = true, .vds = vds_off, .use_vfd_swmr = true, + .use_named_pipe = true, .writer = true, .fixed_array = false, .one_dee_max_dims = {ROWS, H5S_UNLIMITED}, .chunk_dims = {ROWS, COLS}, - .update_interval = - (struct timespec){.tv_sec = 0, .tv_nsec = 1000000000UL / 30 /* 1/30 second */}}; + .ival = (struct timespec){.tv_sec = MAX_READ_LEN_IN_SECONDS, .tv_nsec = 0}}; } -static void state_init(state_t *, int, char **); +static bool state_init(state_t *, int, char **); static const hid_t badhid = H5I_INVALID_HID; @@ -174,17 +197,23 @@ static hsize_t two_dee_max_dims[RANK]; static uint32_t matget(const mat_t *mat, unsigned i, unsigned j) { - assert(i < mat->rows && j < mat->cols); - return mat->elt[i * mat->cols + j]; } -static void +static bool matset(mat_t *mat, unsigned i, unsigned j, uint32_t v) { - assert(i < mat->rows && j < mat->cols); + if (i >= mat->rows || j >= mat->cols) { + fprintf(stderr, "index out of boundary\n"); + TEST_ERROR; + } mat->elt[i * mat->cols + j] = v; + + return true; + +error: + return false; } static mat_t * @@ -192,15 +221,20 @@ newmat(unsigned rows, unsigned cols) { mat_t *mat; - mat = malloc(sizeof(*mat) + (rows * cols - 1) * sizeof(mat->elt[0])); + mat = HDmalloc(sizeof(*mat) + (rows * cols - 1) * sizeof(mat->elt[0])); - if (mat == NULL) - err(EXIT_FAILURE, "%s: malloc", __func__); + if (mat == NULL) { + fprintf(stderr, "HDmalloc failed\n"); + TEST_ERROR; + } mat->rows = rows; mat->cols = cols; return mat; + +error: + return NULL; } static void @@ -209,7 +243,7 @@ usage(const char *progname) fprintf(stderr, "usage: %s [-F] [-M] [-S] [-V] [-W] [-a steps] [-b] [-c cols]\n" " [-d dims]\n" - " [-n iterations] [-r rows] [-s datasets]\n" + " [-l tick_num] [-n iterations] [-r rows] [-s datasets]\n" " [-u milliseconds]\n" "\n" "-F: fixed maximal dimension for the chunked datasets\n" @@ -218,56 +252,72 @@ usage(const char *progname) "-S: do not use VFD SWMR\n" "-V: use virtual datasets and a single\n" " source file\n" - "-W: do not wait for a signal before\n" - " exiting\n" "-a steps: `steps` between adding attributes\n" "-b: write data in big-endian byte order\n" "-c cols: `cols` columns per chunk\n" "-d 1|one|2|two|both: select dataset expansion in one or\n" " both dimensions\n" + "-l tick_num: expected maximal number of ticks from\n" + " the writer's finishing creation to the reader's finishing validation\n" + "-N: do not use named pipes\n" "-n iterations: how many times to expand each dataset\n" "-r rows: `rows` rows per chunk\n" "-s datasets: number of datasets to create\n" - "-u ms: milliseconds interval between updates\n" - " to %s.h5\n" "\n", - progname, progname); + progname); exit(EXIT_FAILURE); } -static void +static bool make_quadrant_dataspace(state_t *s, quadrant_t *q) { - q->space = H5Screate_simple(NELMTS(s->chunk_dims), s->chunk_dims, - s->two_dee ? two_dee_max_dims : s->one_dee_max_dims); + if ((q->space = H5Screate_simple(NELMTS(s->chunk_dims), s->chunk_dims, + s->two_dee ? two_dee_max_dims : s->one_dee_max_dims)) < 0) { + fprintf(stderr, "H5Screate_simple failed\n"); + TEST_ERROR; + } - if (q->space < 0) { - errx(EXIT_FAILURE, "%s.%d: H5Screate_simple failed", __func__, __LINE__); + if (H5Sselect_hyperslab(q->space, H5S_SELECT_SET, q->start, q->stride, q->count, q->block) < 0) { + fprintf(stderr, "H5Sselect_hyperslab failed\n"); + TEST_ERROR; } - if (H5Sselect_hyperslab(q->space, H5S_SELECT_SET, q->start, q->stride, q->count, q->block) < 0) - errx(EXIT_FAILURE, "%s: H5Sselect_hyperslab failed", __func__); + return true; + +error: + H5E_BEGIN_TRY { + H5Sclose(q->space); + } H5E_END_TRY; + + return false; } -static void +static bool state_init(state_t *s, int argc, char **argv) { unsigned long tmp; int ch; unsigned i; const hsize_t dims = 1; - char tfile[PATH_MAX]; + char *tfile = NULL; char * end; - unsigned long millis; quadrant_t *const ul = &s->quadrants.ul, *const ur = &s->quadrants.ur, *const bl = &s->quadrants.bl, *const br = &s->quadrants.br, *const src = &s->quadrants.src; const char *personality; *s = state_initializer(); - esnprintf(tfile, sizeof(tfile), "%s", argv[0]); - esnprintf(s->progname, sizeof(s->progname), "%s", basename(tfile)); - while ((ch = getopt(argc, argv, "FMSVWa:bc:d:n:qr:s:u:")) != -1) { + if (H5_basename(argv[0], &tfile) < 0) { + fprintf(stderr, "H5_basename failed\n"); + TEST_ERROR; + } + + esnprintf(s->progname, sizeof(s->progname), "%s", tfile); + + if (tfile) + HDfree(tfile); + + while ((ch = getopt(argc, argv, "FMNSVa:bc:d:l:n:qr:s:")) != -1) { switch (ch) { case 'F': /* The flag to indicate whether the maximal dimension of the chunked datasets is fixed or @@ -283,8 +333,9 @@ state_init(state_t *s, int argc, char **argv) case 'V': s->vds = vds_single; break; - case 'W': - s->wait_for_signal = false; + case 'N': + /* Disable named pipes, mainly for running the writer and reader seperately */ + s->use_named_pipe = false; break; case 'd': if (strcmp(optarg, "1") == 0 || strcmp(optarg, "one") == 0) @@ -293,34 +344,49 @@ state_init(state_t *s, int argc, char **argv) strcmp(optarg, "both") == 0) s->two_dee = true; else { - errx(EXIT_FAILURE, "bad -d argument \"%s\"", optarg); + fprintf(stderr, "bad -d argument %s\n", optarg); + TEST_ERROR; } break; case 'a': case 'c': + case 'l': case 'n': case 'r': case 's': errno = 0; - tmp = strtoul(optarg, &end, 0); + tmp = HDstrtoul(optarg, &end, 0); if (end == optarg || *end != '\0') { - errx(EXIT_FAILURE, "couldn't parse `-%c` argument `%s`", ch, optarg); + fprintf(stderr, "couldn't parse -%c argument %s\n", ch, optarg); + TEST_ERROR; } else if (errno != 0) { - err(EXIT_FAILURE, "couldn't parse `-%c` argument `%s`", ch, optarg); + fprintf(stderr, "couldn't parse -%c argument %s\n", ch, optarg); + TEST_ERROR; + } + else if (tmp > UINT_MAX) { + fprintf(stderr, "-%c argument %lu too large", ch, tmp); + TEST_ERROR; } - else if (tmp > UINT_MAX) - errx(EXIT_FAILURE, "`-%c` argument `%lu` too large", ch, tmp); if ((ch == 'c' || ch == 'r') && tmp == 0) { - errx(EXIT_FAILURE, "`-%c` argument `%lu` must be >= 1", ch, tmp); + fprintf(stderr, "-%c argument %lu must be >= 1", ch, tmp); + TEST_ERROR; } if (ch == 'a') s->asteps = (unsigned)tmp; else if (ch == 'c') s->cols = (unsigned)tmp; - else if (ch == 'n') + else if (ch == 'l') { + /* Translate the tick number to time represented by the timespec struct */ + float time = (float)(((unsigned)tmp * TICK_LEN) / 10.0); + unsigned sec = (unsigned)time; + unsigned nsec = (unsigned)((time - sec) * 10 * 1000 * 1000); + + s->ival.tv_sec = sec; + s->ival.tv_nsec = nsec; + } else if (ch == 'n') s->nsteps = (unsigned)tmp; else if (ch == 'r') s->rows = (unsigned)tmp; @@ -333,18 +399,6 @@ state_init(state_t *s, int argc, char **argv) case 'q': verbosity = 0; break; - case 'u': - errno = 0; - millis = strtoul(optarg, &end, 0); - if (millis == ULONG_MAX && errno == ERANGE) { - err(EXIT_FAILURE, "option -p argument \"%s\"", optarg); - } - else if (*end != '\0') { - errx(EXIT_FAILURE, "garbage after -p argument \"%s\"", optarg); - } - s->update_interval.tv_sec = (time_t)(millis / 1000UL); - s->update_interval.tv_nsec = (long)((millis * 1000000UL) % 1000000000UL); - break; case '?': default: usage(s->progname); @@ -354,11 +408,14 @@ state_init(state_t *s, int argc, char **argv) argc -= optind; argv += optind; - if (argc > 0) - errx(EXIT_FAILURE, "unexpected command-line arguments"); + if (argc > 0) { + fprintf(stderr, "unexpected command-line arguments\n"); + TEST_ERROR; + } if (s->vds != vds_off && s->two_dee) { - errx(EXIT_FAILURE, "virtual datasets and 2D datasets are mutually exclusive"); + fprintf(stderr, "virtual datasets and 2D datasets are mutually exclusive\n"); + TEST_ERROR; } s->chunk_dims[0] = s->rows; @@ -388,11 +445,14 @@ state_init(state_t *s, int argc, char **argv) } if ((s->quadrant_dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) { - errx(EXIT_FAILURE, "%s.%d: H5Pcreate failed", __func__, __LINE__); + fprintf(stderr, "H5Pcreate failed\n"); + TEST_ERROR; } - if (H5Pset_chunk(s->quadrant_dcpl, RANK, half_chunk_dims) < 0) - errx(EXIT_FAILURE, "H5Pset_chunk failed"); + if (H5Pset_chunk(s->quadrant_dcpl, RANK, half_chunk_dims) < 0) { + fprintf(stderr, "H5Pset_chunk failed\n"); + TEST_ERROR; + } *ul = (quadrant_t){.start = {0, 0}, .stride = {s->rows, s->cols}, @@ -414,72 +474,86 @@ state_init(state_t *s, int argc, char **argv) .block = {s->rows / 2, s->cols / 2}, .count = {1, H5S_UNLIMITED}}; - make_quadrant_dataspace(s, ul); - make_quadrant_dataspace(s, ur); - make_quadrant_dataspace(s, bl); - make_quadrant_dataspace(s, br); + if (!make_quadrant_dataspace(s, ul)) { + fprintf(stderr, "make_quadrant_dataspace failed\n"); + TEST_ERROR; + } + + if (!make_quadrant_dataspace(s, ur)) { + fprintf(stderr, "make_quadrant_dataspace failed\n"); + TEST_ERROR; + } + + if (!make_quadrant_dataspace(s, bl)) { + fprintf(stderr, "make_quadrant_dataspace failed\n"); + TEST_ERROR; + } + + if (!make_quadrant_dataspace(s, br)) { + fprintf(stderr, "make_quadrant_dataspace failed\n"); + TEST_ERROR; + } *src = (quadrant_t){.start = {0, 0}, .stride = {s->rows / 2, s->cols / 2}, .block = {s->rows / 2, s->cols / 2}, .count = {1, H5S_UNLIMITED}}; - src->space = H5Screate_simple(RANK, half_chunk_dims, half_max_dims); - - if (src->space < 0) { - errx(EXIT_FAILURE, "%s.%d: H5Screate_simple failed", __func__, __LINE__); + if ((src->space = H5Screate_simple(RANK, half_chunk_dims, half_max_dims)) < 0) { + fprintf(stderr, "H5Screate_simple failed\n"); + TEST_ERROR; } - if (H5Sselect_hyperslab(src->space, H5S_SELECT_SET, src->start, src->stride, src->count, src->block) < - 0) - errx(EXIT_FAILURE, "%s: H5Sselect_hyperslab failed", __func__); - - ul->src_space = H5Screate_simple(RANK, half_chunk_dims, half_max_dims); - - if (ul->src_space < 0) { - errx(EXIT_FAILURE, "%s.%d: H5Screate_simple failed", __func__, __LINE__); + if (H5Sselect_hyperslab(src->space, H5S_SELECT_SET, src->start, src->stride, src->count, src->block) < 0) { + fprintf(stderr, "H5Sselect_hyperslab failed\n"); + TEST_ERROR; } - ur->src_space = H5Screate_simple(RANK, half_chunk_dims, half_max_dims); - - if (ur->src_space < 0) { - errx(EXIT_FAILURE, "%s.%d: H5Screate_simple failed", __func__, __LINE__); + if ((ul->src_space = H5Screate_simple(RANK, half_chunk_dims, half_max_dims)) < 0) { + fprintf(stderr, "H5Screate_simple failed\n"); + TEST_ERROR; } - bl->src_space = H5Screate_simple(RANK, half_chunk_dims, half_max_dims); - - if (bl->src_space < 0) { - errx(EXIT_FAILURE, "%s.%d: H5Screate_simple failed", __func__, __LINE__); + if ((ur->src_space = H5Screate_simple(RANK, half_chunk_dims, half_max_dims)) < 0) { + fprintf(stderr, "H5Screate_simple failed\n"); + TEST_ERROR; } - br->src_space = H5Screate_simple(RANK, half_chunk_dims, half_max_dims); + if ((bl->src_space = H5Screate_simple(RANK, half_chunk_dims, half_max_dims)) < 0) { + fprintf(stderr, "H5Screate_simple failed\n"); + TEST_ERROR; + } - if (br->src_space < 0) { - errx(EXIT_FAILURE, "%s.%d: H5Screate_simple failed", __func__, __LINE__); + if ((br->src_space = H5Screate_simple(RANK, half_chunk_dims, half_max_dims)) < 0) { + fprintf(stderr, "H5Screate_simple failed\n"); + TEST_ERROR; } } /* space for attributes */ - if ((s->one_by_one_sid = H5Screate_simple(1, &dims, &dims)) < 0) - errx(EXIT_FAILURE, "H5Screate_simple failed"); + if ((s->one_by_one_sid = H5Screate_simple(1, &dims, &dims)) < 0) { + fprintf(stderr, "H5Screate_simple failed\n"); + TEST_ERROR; + } - s->dataset = malloc(sizeof(*s->dataset) * s->ndatasets); - if (s->dataset == NULL) - err(EXIT_FAILURE, "could not allocate dataset handles"); + if ((s->dataset = HDmalloc(sizeof(*s->dataset) * s->ndatasets)) == NULL) { + fprintf(stderr, "HDmalloc failed\n"); + TEST_ERROR; + } - s->sources = malloc(sizeof(*s->sources) * s->ndatasets); - if (s->sources == NULL) - err(EXIT_FAILURE, "could not allocate quadrant dataset handles"); + if ((s->sources = HDmalloc(sizeof(*s->sources) * s->ndatasets)) == NULL) { + fprintf(stderr, "HDmalloc failed\n"); + TEST_ERROR; + } for (i = 0; i < s->ndatasets; i++) { s->dataset[i] = badhid; s->sources[i].ul = s->sources[i].ur = s->sources[i].bl = s->sources[i].br = badhid; } - s->memspace = H5Screate_simple(RANK, s->chunk_dims, NULL); - - if (s->memspace < 0) { - errx(EXIT_FAILURE, "%s.%d: H5Screate_simple failed", __func__, __LINE__); + if ((s->memspace = H5Screate_simple(RANK, s->chunk_dims, NULL)) < 0) { + fprintf(stderr, "H5Screate_simple failed\n"); + TEST_ERROR; } s->filename[0] = "vfd_swmr_bigset.h5"; @@ -494,52 +568,102 @@ state_init(state_t *s, int argc, char **argv) s->filename[3] = s->filename[0]; } - personality = strstr(s->progname, "vfd_swmr_bigset_"); + personality = HDstrstr(s->progname, "vfd_swmr_bigset_"); - if (personality != NULL && strcmp(personality, "vfd_swmr_bigset_writer") == 0) + if (personality != NULL && HDstrcmp(personality, "vfd_swmr_bigset_writer") == 0) s->writer = true; - else if (personality != NULL && strcmp(personality, "vfd_swmr_bigset_reader") == 0) + else if (personality != NULL && HDstrcmp(personality, "vfd_swmr_bigset_reader") == 0) s->writer = false; else { - errx(EXIT_FAILURE, "unknown personality, expected vfd_swmr_bigset_{reader,writer}"); + fprintf(stderr, "unknown personality, expected vfd_swmr_bigset_{reader,writer}\n"); + TEST_ERROR; + } + + if ((s->dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) { + fprintf(stderr, "H5Pcreate failed\n"); + TEST_ERROR; } - if ((s->dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) - errx(EXIT_FAILURE, "%s.%d: H5Pcreate failed", __func__, __LINE__); + if (H5Pset_chunk_cache(s->dapl, 0, 0, H5D_CHUNK_CACHE_W0_DEFAULT) < 0) { + fprintf(stderr, "H5Pset_chunk_cache failed\n"); + TEST_ERROR; + } - if (H5Pset_chunk_cache(s->dapl, 0, 0, H5D_CHUNK_CACHE_W0_DEFAULT) < 0) - errx(EXIT_FAILURE, "H5Pset_chunk_cache failed"); + if (s->vds != vds_off && H5Pset_virtual_view(s->dapl, H5D_VDS_FIRST_MISSING) < 0) { + fprintf(stderr, "H5Pset_virtual_view failed\n"); + TEST_ERROR; + } - if (s->vds != vds_off && H5Pset_virtual_view(s->dapl, H5D_VDS_FIRST_MISSING) < 0) - errx(EXIT_FAILURE, "H5Pset_virtual_view failed"); + return true; + +error: + H5E_BEGIN_TRY { + H5Pclose(s->quadrant_dcpl); + H5Sclose(ul->space); + H5Sclose(ur->space); + H5Sclose(bl->space); + H5Sclose(br->space); + H5Sclose(ul->src_space); + H5Sclose(ur->src_space); + H5Sclose(bl->src_space); + H5Sclose(br->src_space); + H5Sclose(src->space); + H5Sclose(s->one_by_one_sid); + H5Sclose(s->memspace); + } H5E_END_TRY; + + if (tfile) + HDfree(tfile); + + if (s->dataset) + HDfree(s->dataset); + + if (s->sources) + HDfree(s->sources); + + return false; } -static void +static bool state_destroy(state_t *s) { size_t i; - if (H5Pclose(s->dapl) < 0) - errx(EXIT_FAILURE, "H5Pclose(fapl)"); - - s->dapl = badhid; + if (H5Pclose(s->dapl) < 0) { + fprintf(stderr, "H5Pclose failed\n"); + TEST_ERROR; + } if (s->vds != vds_off) { quadrant_t *const ul = &s->quadrants.ul, *const ur = &s->quadrants.ur, *const bl = &s->quadrants.bl, *const br = &s->quadrants.br; if (H5Sclose(ul->src_space) < 0 || H5Sclose(ur->src_space) < 0 || H5Sclose(bl->src_space) < 0 || - H5Sclose(br->src_space) < 0) - errx(EXIT_FAILURE, "H5Sclose failed"); + H5Sclose(br->src_space) < 0) { + fprintf(stderr, "H5Sclose failed\n"); + TEST_ERROR; + } - ul->src_space = ur->src_space = bl->src_space = br->src_space = badhid; + if (H5Sclose(ul->space) < 0 || H5Sclose(ur->space) < 0 || H5Sclose(bl->space) < 0 || + H5Sclose(br->space) < 0) { + fprintf(stderr, "H5Sclose failed\n"); + TEST_ERROR; + } - if (H5Pclose(s->quadrant_dcpl) < 0) - errx(EXIT_FAILURE, "H5Pclose(dcpl)"); + if (H5Pclose(s->quadrant_dcpl) < 0) { + fprintf(stderr, "H5Pclose failed\n"); + TEST_ERROR; + } + } - s->quadrant_dcpl = badhid; + if (H5Sclose(s->one_by_one_sid) < 0) { + fprintf(stderr, "H5Sclose failed\n"); + TEST_ERROR; + } - /* TBD destroy spaces belonging to quadrants */ + if (H5Sclose(s->memspace) < 0) { + fprintf(stderr, "H5Sclose failed\n"); + TEST_ERROR; } for (i = 0; i < NELMTS(s->file); i++) { @@ -550,12 +674,265 @@ state_destroy(state_t *s) if (s->vds != vds_multi && i > 0) continue; - if (H5Fclose(fid) < 0) - errx(EXIT_FAILURE, "H5Fclose"); + if (H5Fclose(fid) < 0) { + fprintf(stderr, "H5Fclose failed\n"); + TEST_ERROR; + } } + + if (s->dataset) + HDfree(s->dataset); + + if (s->sources) + HDfree(s->sources); + + return true; + +error: + H5E_BEGIN_TRY { + H5Pclose(s->quadrant_dcpl); + H5Sclose(s->one_by_one_sid); + H5Sclose(s->memspace); + } H5E_END_TRY; + + if (s->dataset) + HDfree(s->dataset); + + if (s->sources) + HDfree(s->sources); + + return false; } -static void +/* + * Initialize the named pipes for test synchronization. + * (This function can go to vfd_swmr_common.c. It's the same as + * the one in vfd_swmr_attrdset_writer.c) + */ +static bool +np_init(np_state_t *np, bool writer) +{ + *np = NP_INITIALIZER; + + /* + * Use two named pipes(FIFO) to coordinate the writer and reader for + * two-way communication so that the two sides can move forward together. + * One is for the writer to write to the reader. + * The other one is for the reader to signal the writer. + */ + if (writer) { + /* If the named pipes are present at the start of the test, remove them */ + if (HDaccess(np->fifo_writer_to_reader, F_OK) == 0) + if(HDremove(np->fifo_writer_to_reader) != 0) { + fprintf(stderr, "HDremove fifo_writer_to_reader failed\n"); + TEST_ERROR; + } + + if (HDaccess(np->fifo_reader_to_writer, F_OK) == 0) + if(HDremove(np->fifo_reader_to_writer) != 0) { + fprintf(stderr, "HDremove fifo_reader_to_writer failed\n"); + TEST_ERROR; + } + + /* Writer creates two named pipes(FIFO) */ + if (HDmkfifo(np->fifo_writer_to_reader, 0600) < 0) { + fprintf(stderr, "HDmkfifo fifo_writer_to_reader failed\n"); + TEST_ERROR; + } + + if (HDmkfifo(np->fifo_reader_to_writer, 0600) < 0) { + fprintf(stderr, "HDmkfifo fifo_reader_to_writer failed\n"); + TEST_ERROR; + } + } + + /* Both the writer and reader open the pipes */ + if ((np->fd_writer_to_reader = HDopen(np->fifo_writer_to_reader, O_RDWR)) < 0) { + fprintf(stderr, "HDopen fifo_writer_to_reader failed\n"); + TEST_ERROR; + } + + if ((np->fd_reader_to_writer = HDopen(np->fifo_reader_to_writer, O_RDWR)) < 0) { + fprintf(stderr, "HDopen fifo_reader_to_writer failed\n"); + TEST_ERROR; + } + + return true; + +error: + return false; +} /* np_init() */ + +/* + * Close and remove the named pipes. + * (This function can go to vfd_swmr_common.c. It's the same as + * the one in vfd_swmr_attrdset_writer.c) + */ +static bool +np_close(np_state_t *np, bool writer) +{ + /* Both the writer and reader close the named pipes */ + if (HDclose(np->fd_writer_to_reader) < 0) { + fprintf(stderr, "HDclose fd_writer_to_reader failed\n"); + TEST_ERROR; + } + + if (HDclose(np->fd_reader_to_writer) < 0) { + fprintf(stderr, "HDclose fd_reader_to_writer failed\n"); + TEST_ERROR; + } + + /* Reader finishes last and deletes the named pipes */ + if(!writer) { + if(HDremove(np->fifo_writer_to_reader) != 0) { + fprintf(stderr, "HDremove fifo_writer_to_reader failed\n"); + TEST_ERROR; + } + + if(HDremove(np->fifo_reader_to_writer) != 0) { + fprintf(stderr, "HDremove fifo_reader_to_writer failed\n"); + TEST_ERROR; + } + } + return true; + +error: + return false; +} /* np_close() */ + +/* Wait for the writer's notice before starting to zoo validation */ +static int +reader_verify(np_state_t np, int verify) +{ + int notify; + + if (HDread(np.fd_writer_to_reader, ¬ify, sizeof(int)) < 0) { + fprintf(stderr, "HDread failed\n"); + TEST_ERROR; + } + + if (notify != verify) { + fprintf(stderr, "expected %d but read %d\n", verify, notify); + TEST_ERROR; + } + + return 0; + +error: + return -1; +} + +/* Notify the reader of finishing zoo creation by sending the timestamp + * and wait for the reader to finish validation before proceeding */ +static int +notify_and_wait_for_reader(state_t *s, np_state_t *np) +{ + int notify; + unsigned int i; + struct timespec last = {0, 0}; + + /* Get the time when finishing zoo creation */ + if (HDclock_gettime(CLOCK_MONOTONIC, &last) < 0) { + fprintf(stderr, "HDclock_gettime failed\n"); + TEST_ERROR; + } + + /* Notify the reader of finishing zoo creation by sending the timestamp */ + if (HDwrite(np->fd_writer_to_reader, &last, sizeof(last)) < 0) { + fprintf(stderr, "HDwrite failed\n"); + TEST_ERROR; + } + + /* During the wait, writer makes repeated HDF5 API calls so as to trigger + * EOT at approximately the correct time */ + for(i = 0; i < MAX_LAG + 1; i++) { + decisleep(TICK_LEN); + + H5E_BEGIN_TRY { + H5Aexists(s->file[0], "nonexistent"); + } H5E_END_TRY; + } + + /* Wait until the reader finishes validating zoo creation */ + if (HDread(np->fd_reader_to_writer, ¬ify, sizeof(int)) < 0) { + fprintf(stderr, "HDread failed\n"); + TEST_ERROR; + } + + if (notify != np->verify) { + fprintf(stderr, "expected %d but read %d\n", np->verify, notify); + TEST_ERROR; + } + + return 0; + +error: + return -1; +} + +/* Receive the notice of the writer finishing dataset creation (timestamp) + * Make sure the dataset validation doesn't take longer than the expected time. + * This time period is from the writer finishing dataset creation to the reader finishing + * the validation of dataset creation */ +static int +reader_check_time_and_notify_writer(np_state_t *np, state_t s) +{ + struct timespec last = {0, 0}; + + /* Receive the notice of the writer finishing zoo creation (timestamp) */ + if (HDread(np->fd_writer_to_reader, &last, sizeof(last)) < 0) { + fprintf(stderr, "HDread failed\n"); + TEST_ERROR; + } + + /* Make sure the dataset validation doesn't take longer than the expected time. + * This time period is from the writer finishing dataset creation to the reader finishing + * the validation of dataset creation */ + if (below_speed_limit(&last, &(s.ival))) { + AT(); + fprintf(stderr, "dataset validation took too long to finish\n"); + } + + /* Notify the writer that dataset validation is finished */ + if (HDwrite(np->fd_reader_to_writer, &(np->notify), sizeof(int)) < 0) { + fprintf(stderr, "HDwrite failed\n"); + TEST_ERROR; + } + + return 0; + +error: + return -1; +} + +/* Notify the reader by sending the timestamp and the number of chunks written */ +static int +notify_reader(np_state_t *np, unsigned step) +{ + exchange_info_t last; + + /* Get the time */ + if (HDclock_gettime(CLOCK_MONOTONIC, &(last.time)) < 0) { + fprintf(stderr, "HDclock_gettime failed\n"); + TEST_ERROR; + } + + last.step = step; + + /* Notify the reader by sending the timestamp and the number of chunks written */ + if (HDwrite(np->fd_writer_to_reader, &last, sizeof(last)) < 0) { + H5_FAILED(); AT(); + fprintf(stderr, "HDwrite failed"); + goto error; + } + + return 0; + +error: + return -1; +} + +static bool create_extensible_dset(state_t *s, unsigned int which) { quadrant_t *const ul = &s->quadrants.ul, *const ur = &s->quadrants.ur, *const bl = &s->quadrants.bl, @@ -563,19 +940,19 @@ create_extensible_dset(state_t *s, unsigned int which) char dname[sizeof("/dataset-9999999999")]; char ul_dname[sizeof("/ul-dataset-9999999999")], ur_dname[sizeof("/ur-dataset-9999999999")], bl_dname[sizeof("/bl-dataset-9999999999")], br_dname[sizeof("/br-dataset-9999999999")]; - hid_t dcpl, ds, filespace; - - assert(which < s->ndatasets); - assert(s->dataset[which] == badhid); + hid_t dcpl = H5I_INVALID_HID, dset_id = H5I_INVALID_HID, filespace = H5I_INVALID_HID; esnprintf(dname, sizeof(dname), "/dataset-%d", which); if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) { - errx(EXIT_FAILURE, "%s.%d: H5Pcreate failed", __func__, __LINE__); + fprintf(stderr, "H5Pcreate failed\n"); + TEST_ERROR; } - if (H5Pset_chunk(dcpl, RANK, s->chunk_dims) < 0) - errx(EXIT_FAILURE, "H5Pset_chunk failed"); + if (H5Pset_chunk(dcpl, RANK, s->chunk_dims) < 0) { + fprintf(stderr, "H5Pset_chunk failed\n"); + TEST_ERROR; + } if (s->vds != vds_off) { sources_t *const srcs = &s->sources[which]; @@ -585,78 +962,101 @@ create_extensible_dset(state_t *s, unsigned int which) esnprintf(bl_dname, sizeof(bl_dname), "/bl-dataset-%d", which); esnprintf(br_dname, sizeof(br_dname), "/br-dataset-%d", which); - srcs->ul = H5Dcreate2(s->file[0], ul_dname, s->filetype, ul->src_space, H5P_DEFAULT, s->quadrant_dcpl, - s->dapl); - - if (srcs->ul < 0) - errx(EXIT_FAILURE, "H5Dcreate(, \"%s\", ) failed", ul_dname); - - srcs->ur = H5Dcreate2(s->file[1], ur_dname, s->filetype, ur->src_space, H5P_DEFAULT, s->quadrant_dcpl, - s->dapl); - - if (srcs->ur < 0) - errx(EXIT_FAILURE, "H5Dcreate(, \"%s\", ) failed", ur_dname); + if ((srcs->ul = H5Dcreate2(s->file[0], ul_dname, s->filetype, ul->src_space, H5P_DEFAULT, s->quadrant_dcpl, s->dapl)) < 0) { + fprintf(stderr, "H5Dcreate2 failed\n"); + TEST_ERROR; + } - srcs->bl = H5Dcreate2(s->file[2], bl_dname, s->filetype, bl->src_space, H5P_DEFAULT, s->quadrant_dcpl, - s->dapl); + if ((srcs->ur = H5Dcreate2(s->file[1], ur_dname, s->filetype, ur->src_space, H5P_DEFAULT, s->quadrant_dcpl, s->dapl)) < 0) { + fprintf(stderr, "H5Dcreate2 failed\n"); + TEST_ERROR; + } - if (srcs->bl < 0) - errx(EXIT_FAILURE, "H5Dcreate(, \"%s\", ) failed", bl_dname); + if ((srcs->bl = H5Dcreate2(s->file[2], bl_dname, s->filetype, bl->src_space, H5P_DEFAULT, s->quadrant_dcpl, s->dapl)) < 0) { + fprintf(stderr, "H5Dcreate2 failed\n"); + TEST_ERROR; + } - srcs->br = H5Dcreate2(s->file[3], br_dname, s->filetype, br->src_space, H5P_DEFAULT, s->quadrant_dcpl, - s->dapl); + if ((srcs->br = H5Dcreate2(s->file[3], br_dname, s->filetype, br->src_space, H5P_DEFAULT, s->quadrant_dcpl, s->dapl)) < 0) { + fprintf(stderr, "H5Dcreate2 failed\n"); + TEST_ERROR; + } - if (srcs->br < 0) - errx(EXIT_FAILURE, "H5Dcreate(, \"%s\", ) failed", br_dname); + if (H5Pset_virtual(dcpl, ul->space, s->filename[0], ul_dname, src->space) < 0) { + fprintf(stderr, "H5Pset_virtual failed\n"); + TEST_ERROR; + } - if (H5Pset_virtual(dcpl, ul->space, s->filename[0], ul_dname, src->space) < 0) - errx(EXIT_FAILURE, "%s: H5Pset_virtual failed", __func__); + if (H5Pset_virtual(dcpl, ur->space, s->filename[1], ur_dname, src->space) < 0) { + fprintf(stderr, "H5Pset_virtual failed\n"); + TEST_ERROR; + } - if (H5Pset_virtual(dcpl, ur->space, s->filename[1], ur_dname, src->space) < 0) - errx(EXIT_FAILURE, "%s: H5Pset_virtual failed", __func__); + if (H5Pset_virtual(dcpl, bl->space, s->filename[2], bl_dname, src->space) < 0) { + fprintf(stderr, "H5Pset_virtual failed\n"); + TEST_ERROR; + } - if (H5Pset_virtual(dcpl, bl->space, s->filename[2], bl_dname, src->space) < 0) - errx(EXIT_FAILURE, "%s: H5Pset_virtual failed", __func__); + if (H5Pset_virtual(dcpl, br->space, s->filename[3], br_dname, src->space) < 0) { + fprintf(stderr, "H5Pset_virtual failed\n"); + TEST_ERROR; + } + } - if (H5Pset_virtual(dcpl, br->space, s->filename[3], br_dname, src->space) < 0) - errx(EXIT_FAILURE, "%s: H5Pset_virtual failed", __func__); + if ((filespace = H5Screate_simple(NELMTS(s->chunk_dims), s->chunk_dims, + s->two_dee ? two_dee_max_dims : s->one_dee_max_dims)) < 0) { + fprintf(stderr, "H5Screate_simple failed\n"); + TEST_ERROR; } - filespace = H5Screate_simple(NELMTS(s->chunk_dims), s->chunk_dims, - s->two_dee ? two_dee_max_dims : s->one_dee_max_dims); + if ((dset_id = H5Dcreate2(s->file[0], dname, s->filetype, filespace, H5P_DEFAULT, dcpl, s->dapl)) < 0) { + fprintf(stderr, "H5Dcreate2 failed\n"); + TEST_ERROR; + } - if (filespace < 0) { - errx(EXIT_FAILURE, "%s.%d: H5Screate_simple failed", __func__, __LINE__); + if (H5Sclose(filespace) < 0) { + fprintf(stderr, "H5Sclose failed\n"); + TEST_ERROR; } - ds = H5Dcreate2(s->file[0], dname, s->filetype, filespace, H5P_DEFAULT, dcpl, s->dapl); + if (H5Pclose(dcpl) < 0) { + fprintf(stderr, "H5Pclose failed\n"); + TEST_ERROR; + } - if (ds < 0) - errx(EXIT_FAILURE, "H5Dcreate(, \"%s\", ) failed", dname); + s->dataset[which] = dset_id; - if (H5Sclose(filespace) < 0) - errx(EXIT_FAILURE, "%s: H5Sclose failed", __func__); + return true; - if (H5Pclose(dcpl) < 0) - errx(EXIT_FAILURE, "%s: H5Pclose failed", __func__); +error: + H5E_BEGIN_TRY { + H5Dclose(dset_id); + H5Pclose(dcpl); + H5Sclose(filespace); + } H5E_END_TRY; - s->dataset[which] = ds; + return false; } -static void +static bool close_extensible_dset(state_t *s, unsigned int which) { char dname[sizeof("/dataset-9999999999")]; - hid_t ds; + hid_t dset_id = H5I_INVALID_HID; - assert(which < s->ndatasets); + if (which >= s->ndatasets) { + fprintf(stderr, "index is out of range\n"); + TEST_ERROR; + } esnprintf(dname, sizeof(dname), "/dataset-%d", which); - ds = s->dataset[which]; + dset_id = s->dataset[which]; - if (H5Dclose(ds) < 0) - errx(EXIT_FAILURE, "H5Dclose failed for \"%s\"", dname); + if (H5Dclose(dset_id) < 0) { + fprintf(stderr, "H5Dclose failed\n"); + TEST_ERROR; + } s->dataset[which] = badhid; @@ -664,86 +1064,114 @@ close_extensible_dset(state_t *s, unsigned int which) sources_t *const srcs = &s->sources[which]; if (H5Dclose(srcs->ul) < 0 || H5Dclose(srcs->ur) < 0 || H5Dclose(srcs->bl) < 0 || - H5Dclose(srcs->br) < 0) - errx(EXIT_FAILURE, "H5Dclose failed"); - - srcs->ul = srcs->ur = srcs->bl = srcs->br = badhid; + H5Dclose(srcs->br) < 0) { + fprintf(stderr, "H5Dclose failed\n"); + TEST_ERROR; + } } + + return true; + +error: + H5E_BEGIN_TRY { + H5Dclose(dset_id); + } H5E_END_TRY; + + return false; } -static void -open_extensible_dset(state_t *s, unsigned int which) +static bool +open_extensible_dset(state_t *s) { hsize_t dims[RANK], maxdims[RANK]; char dname[sizeof("/dataset-9999999999")]; - hid_t ds, filespace, ty; - const int tries = 10000; - int i; - struct timespec last = {0, 0}; - static const struct timespec ival = {5, 0}; - estack_state_t es; + hid_t dset_id, filespace, dtype; + unsigned int which, i; - assert(which < s->ndatasets); - assert(s->dataset[which] == badhid); + for (which = 0; which < s->ndatasets; which++) { + esnprintf(dname, sizeof(dname), "/dataset-%d", which); - esnprintf(dname, sizeof(dname), "/dataset-%d", which); + /* Tries to open the dataset repeatedly until successful. After trying + * NUM_ATTEMPTS times without success, report it as a failure + */ + for (i = 0; i < NUM_ATTEMPTS; i++) { + H5E_BEGIN_TRY { + dset_id = H5Dopen2(s->file[0], dname, s->dapl); + } H5E_END_TRY; - es = disable_estack(); - for (i = 0; i < tries; i++) { - struct timespec one_tenth = {.tv_sec = 0, .tv_nsec = 1000000000L / 10}; + if (dset_id >= 0) + break; + else + decisleep(1); + } - ds = H5Dopen2(s->file[0], dname, s->dapl); + if (i == NUM_ATTEMPTS) { + fprintf(stderr, "chunk verification reached the maximal number of attempts\n"); + TEST_ERROR; + } - if (ds >= 0) - break; + if ((dtype = H5Dget_type(dset_id)) < 0) { + fprintf(stderr, "H5Dget_type failed\n"); + TEST_ERROR; + } - if (below_speed_limit(&last, &ival)) { - warnx("H5Dopen(, \"%s\", ) transient failure, %d retries remain", dname, tries - i - 1); + if (H5Tequal(dtype, s->filetype) <= 0) { + fprintf(stderr, "Unexpected data type\n"); + TEST_ERROR; } - while (nanosleep(&one_tenth, &one_tenth) == -1 && errno == EINTR) - ; // do nothing - } - restore_estack(es); - if (i == tries) { - errx(EXIT_FAILURE, "H5Dopen(, \"%s\", ) failed after %d tries", dname, tries); - } + if ((filespace = H5Dget_space(dset_id)) < 0) { + fprintf(stderr, "H5Dget_space failed\n"); + TEST_ERROR; + } - if ((ty = H5Dget_type(ds)) < 0) - errx(EXIT_FAILURE, "H5Dget_type failed"); + if (H5Sget_simple_extent_ndims(filespace) != RANK) { + fprintf(stderr, "Unexpected data rank\n"); + TEST_ERROR; + } - if (H5Tequal(ty, s->filetype) <= 0) - errx(EXIT_FAILURE, "Unexpected data type"); + if (H5Sget_simple_extent_dims(filespace, dims, maxdims) < 0) { + fprintf(stderr, "H5Sget_simple_extent_dims failed\n"); + TEST_ERROR; + } - if ((filespace = H5Dget_space(ds)) < 0) - errx(EXIT_FAILURE, "H5Dget_space failed"); + if (H5Sclose(filespace) < 0) { + fprintf(stderr, "H5Sclose failed\n"); + TEST_ERROR; + } - if (H5Sget_simple_extent_ndims(filespace) != RANK) - errx(EXIT_FAILURE, "Unexpected rank"); + if (H5Tclose(dtype) < 0) { + fprintf(stderr, "H5Tclose failed\n"); + TEST_ERROR; + } - if (H5Sget_simple_extent_dims(filespace, dims, maxdims) < 0) - errx(EXIT_FAILURE, "H5Sget_simple_extent_dims failed"); + if (s->two_dee) { + if (maxdims[0] != two_dee_max_dims[0] || maxdims[1] != two_dee_max_dims[1] || + maxdims[0] != maxdims[1]) { + fprintf(stderr, "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE, maxdims[0], + maxdims[1]); + TEST_ERROR; + } + } else if (maxdims[0] != s->one_dee_max_dims[0] || maxdims[1] != s->one_dee_max_dims[1] || + dims[0] != s->chunk_dims[0]) { + fprintf(stderr, + "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE " or columns %" PRIuHSIZE, + maxdims[0], maxdims[1], dims[1]); + } - if (H5Sclose(filespace) < 0) - errx(EXIT_FAILURE, "H5Sclose failed"); + s->dataset[which] = dset_id; + } - filespace = badhid; + return true; - if (s->two_dee) { - if (maxdims[0] != two_dee_max_dims[0] || maxdims[1] != two_dee_max_dims[1] || - maxdims[0] != maxdims[1]) { - errx(EXIT_FAILURE, "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE, maxdims[0], - maxdims[1]); - } - } - else if (maxdims[0] != s->one_dee_max_dims[0] || maxdims[1] != s->one_dee_max_dims[1] || - dims[0] != s->chunk_dims[0]) { - errx(EXIT_FAILURE, - "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE " or columns %" PRIuHSIZE, - maxdims[0], maxdims[1], dims[1]); - } +error: + H5E_BEGIN_TRY { + H5Dclose(dset_id); + H5Tclose(dtype); + H5Sclose(filespace); + } H5E_END_TRY; - s->dataset[which] = ds; + return false; } /* Write or verify the dataset test pattern in the matrix `mat`. @@ -772,10 +1200,11 @@ open_extensible_dset(state_t *s, unsigned int which) * * In an actual pattern, the dataset number, `which`, is added to each integer. */ -static void +static bool set_or_verify_matrix(mat_t *mat, unsigned int which, base_t base, bool do_set) { unsigned row, col; + bool ret = true; for (row = 0; row < mat->rows; row++) { for (col = 0; col < mat->cols; col++) { @@ -787,85 +1216,138 @@ set_or_verify_matrix(mat_t *mat, unsigned int which, base_t base, bool do_set) else u = j * j + i; - assert(UINT32_MAX - u >= which); v = (uint32_t)(u + which); - if (do_set) - matset(mat, row, col, v); - else if (matget(mat, row, col) != v) { - errx(EXIT_FAILURE, - "matrix mismatch " - "at %" PRIuHSIZE ", %" PRIuHSIZE " (%u, %u), " - "read %" PRIu32 " expecting %" PRIu32, - i, j, row, col, matget(mat, row, col), v); + if (do_set) { + if (!matset(mat, row, col, v)) { + fprintf(stderr, "data initialization failed\n"); + ret = false; + break; + } + } else if (matget(mat, row, col) != v) { + /* If the data doesn't match, simply return false and + * let the caller repeat this step + */ + ret = false; + break; } } } + + return ret; } -static void +static bool init_matrix(mat_t *mat, unsigned int which, base_t base) { - set_or_verify_matrix(mat, which, base, true); + return set_or_verify_matrix(mat, which, base, true); } -static void +static bool verify_matrix(mat_t *mat, unsigned int which, base_t base) { - set_or_verify_matrix(mat, which, base, false); + return set_or_verify_matrix(mat, which, base, false); } -static void +static bool verify_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t base) { hsize_t offset[RANK] = {base.row, base.col}; herr_t status; - hid_t ds; + hid_t dset_id; - assert(which < s->ndatasets); + if (which >= s->ndatasets) { + fprintf(stderr, "the dataset order is bigger than the number of datasets"); + TEST_ERROR; + } dbgf(1, "verifying chunk %" PRIuHSIZE ", %" PRIuHSIZE "\n", base.row, base.col); - ds = s->dataset[which]; + dset_id = s->dataset[which]; - status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL, s->chunk_dims, NULL); + if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL, s->chunk_dims, NULL) < 0) { + fprintf(stderr, "H5Sselect_hyperslab failed\n"); + TEST_ERROR; + } + + /* A failure to read the data may indicate the data isn't ready yet. Instead of displaying the error stack, + * simply return false and let the caller repeat this step. + */ + H5E_BEGIN_TRY { + status = H5Dread(dset_id, H5T_NATIVE_UINT32, s->memspace, filespace, H5P_DEFAULT, mat->elt); + } H5E_END_TRY; if (status < 0) - errx(EXIT_FAILURE, "H5Sselect_hyperslab failed"); + TEST_ERROR; - status = H5Dread(ds, H5T_NATIVE_UINT32, s->memspace, filespace, H5P_DEFAULT, mat->elt); + return verify_matrix(mat, which, base); - if (status < 0) - errx(EXIT_FAILURE, "H5Dread failed"); +error: + return false; +} + +static bool +repeat_verify_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t base) +{ + hid_t dset_id = s->dataset[which]; + unsigned i; + + /* If the chunk data isn't good after reading it NUM_ATTEMPTS times, report it as a failure */ + for (i = 0; i < NUM_ATTEMPTS; i++) { + if (verify_chunk(s, filespace, mat, which, base)) + break; + else { + decisleep(1); + + /* Refresh the dataset and try it again */ + if (H5Drefresh(dset_id) < 0) { + fprintf(stderr, "H5Drefresh failed\n"); + TEST_ERROR; + } + } + } + + if (i == NUM_ATTEMPTS) { + fprintf(stderr, "chunk verification reached the maximal number of attempts\n"); + TEST_ERROR; + } + + return true; - verify_matrix(mat, which, base); +error: + return false; } -static void +static bool init_and_write_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t base) { hsize_t offset[RANK] = {base.row, base.col}; - herr_t status; - hid_t ds; - - assert(which < s->ndatasets); + hid_t dset_id; - ds = s->dataset[which]; + dset_id = s->dataset[which]; - init_matrix(mat, which, base); + if (!init_matrix(mat, which, base)) { + fprintf(stderr, "data initialization failed\n"); + TEST_ERROR; + } - status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL, s->chunk_dims, NULL); + if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL, s->chunk_dims, NULL) < 0) { + fprintf(stderr, "H5Sselect_hyperslab failed\n"); + TEST_ERROR; + } - if (status < 0) - errx(EXIT_FAILURE, "H5Sselect_hyperslab failed"); + if (H5Dwrite(dset_id, H5T_NATIVE_UINT32, s->memspace, filespace, H5P_DEFAULT, mat->elt) < 0) { + fprintf(stderr, "H5Dwrite failed\n"); + TEST_ERROR; + } - status = H5Dwrite(ds, H5T_NATIVE_UINT32, s->memspace, filespace, H5P_DEFAULT, mat->elt); + return true; - if (status < 0) - errx(EXIT_FAILURE, "H5Dwrite failed"); +error: + return false; } -static void -verify_dset_attribute(hid_t ds, unsigned int which, unsigned int step) +static bool +verify_dset_attribute(hid_t dset_id, unsigned int which, unsigned int step) { unsigned int read_step; hid_t aid; @@ -875,64 +1357,97 @@ verify_dset_attribute(hid_t ds, unsigned int which, unsigned int step) dbgf(1, "verifying attribute %s on dataset %u equals %u\n", name, which, step); - if ((aid = H5Aopen(ds, name, H5P_DEFAULT)) < 0) - errx(EXIT_FAILURE, "H5Aopen failed"); + if ((aid = H5Aopen(dset_id, name, H5P_DEFAULT)) < 0) { + fprintf(stderr, "H5Aopen failed\n"); + TEST_ERROR; + } + + if (H5Aread(aid, H5T_NATIVE_UINT, &read_step) < 0) { + fprintf(stderr, "H5Aread failed\n"); + TEST_ERROR; + } - if (H5Aread(aid, H5T_NATIVE_UINT, &read_step) < 0) - errx(EXIT_FAILURE, "H5Aread failed"); + if (H5Aclose(aid) < 0) { + fprintf(stderr, "H5Aclose failed\n"); + TEST_ERROR; + } - if (H5Aclose(aid) < 0) - errx(EXIT_FAILURE, "H5Aclose failed"); + if (read_step != step) { + fprintf(stderr, "expected %u read %u\n", step, read_step); + TEST_ERROR; + } - if (read_step != step) - errx(EXIT_FAILURE, "expected %u read %u", step, read_step); + return true; + +error: + H5E_BEGIN_TRY { + H5Aclose(aid); + } H5E_END_TRY; + + return false; } -static void -verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned *stepp) +static bool +verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned finished_step, unsigned last_step) { - hid_t ds, filespace; + hid_t dset_id = H5I_INVALID_HID, filespace = H5I_INVALID_HID; hsize_t size[RANK]; base_t base, last; - unsigned int ncols, last_step, step; + unsigned int ncols, step; + int i; - assert(which < s->ndatasets); - - ds = s->dataset[which]; + if (which >= s->ndatasets) { + fprintf(stderr, "the dataset order is bigger than the number of datasets"); + TEST_ERROR; + } - if (H5Drefresh(ds) < 0) - errx(EXIT_FAILURE, "H5Drefresh failed"); + dset_id = s->dataset[which]; - filespace = H5Dget_space(ds); + /* Attempt to check the availablity of the chunks for a number time before reporting it as a failure */ + for (i = 0; i < NUM_ATTEMPTS; i++) { + if (H5Drefresh(dset_id) < 0) { + fprintf(stderr, "H5Drefresh failed\n"); + TEST_ERROR; + } - if (filespace == badhid) - errx(EXIT_FAILURE, "H5Dget_space failed"); + if ((filespace = H5Dget_space(dset_id)) < 0) { + fprintf(stderr, "H5Dget_space failed\n"); + TEST_ERROR; + } - if (H5Sget_simple_extent_dims(filespace, size, NULL) < 0) - errx(EXIT_FAILURE, "H5Sget_simple_extent_dims failed"); + if (H5Sget_simple_extent_dims(filespace, size, NULL) < 0) { + fprintf(stderr, "H5Sget_simple_extent_dims failed\n"); + TEST_ERROR; + } - ncols = (unsigned)(size[1] / s->chunk_dims[1]); - if (ncols < hang_back) - goto out; + ncols = (unsigned)(size[1] / s->chunk_dims[1]); - last_step = ncols - hang_back; + /* Make sure the chunks show up on the reader side. Otherwise sleep a while and try again */ + if (ncols >= last_step) + break; + else + decisleep(1); + } - for (step = *stepp; step <= last_step; step++) { - const unsigned ofs = step % 2; + if (i == NUM_ATTEMPTS) { + fprintf(stderr, "chunk verification reached the maximal number of attempts"); + TEST_ERROR; + } + for (step = finished_step; step < last_step; step++) { dbgf(1, "%s: which %u step %u\n", __func__, which, step); if (s->two_dee) { size[0] = s->chunk_dims[0] * (1 + step); size[1] = s->chunk_dims[1] * (1 + step); - last.row = s->chunk_dims[0] * step + ofs; - last.col = s->chunk_dims[1] * step + ofs; + last.row = s->chunk_dims[0] * step; + last.col = s->chunk_dims[1] * step; } else { size[0] = s->chunk_dims[0]; size[1] = s->chunk_dims[1] * (1 + step); last.row = 0; - last.col = s->chunk_dims[1] * step + ofs; + last.col = s->chunk_dims[1] * step; } dbgf(1, "new size %" PRIuHSIZE ", %" PRIuHSIZE "\n", size[0], size[1]); @@ -942,33 +1457,108 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned *ste /* Down the right side, intersecting the bottom row. */ base.col = last.col; - for (base.row = ofs; base.row <= last.row; base.row += s->chunk_dims[0]) { - verify_chunk(s, filespace, mat, which, base); + for (base.row = 0; base.row <= last.row; base.row += s->chunk_dims[0]) { + if (!repeat_verify_chunk(s, filespace, mat, which, base)) { + fprintf(stderr, "chunk verification failed\n"); + TEST_ERROR; + } } /* Across the bottom, stopping before the last column to * avoid re-reading the bottom-right chunk. */ base.row = last.row; - for (base.col = ofs; base.col < last.col; base.col += s->chunk_dims[1]) { - verify_chunk(s, filespace, mat, which, base); + for (base.col = 0; base.col < last.col; base.col += s->chunk_dims[1]) { + if (!repeat_verify_chunk(s, filespace, mat, which, base)) { + fprintf(stderr, "chunk verification failed\n"); + TEST_ERROR; + } } } else { - verify_chunk(s, filespace, mat, which, last); + if (!repeat_verify_chunk(s, filespace, mat, which, last)) { + fprintf(stderr, "chunk verification failed\n"); + TEST_ERROR; + } + } + + if (s->asteps != 0 && step % s->asteps == 0) { + if (!verify_dset_attribute(dset_id, which, step)) { + fprintf(stderr, "verify_dset_attribute failed\n"); + TEST_ERROR; + } } - if (s->asteps != 0 && step % s->asteps == 0) - verify_dset_attribute(ds, which, step); } - *stepp = step; + return true; + +error: + H5E_BEGIN_TRY { + H5Sclose(filespace); + } H5E_END_TRY; -out: - if (H5Sclose(filespace) < 0) - errx(EXIT_FAILURE, "H5Sclose failed"); + return false; } -static void +static bool +verify_dsets(state_t s, np_state_t *np, mat_t *mat) +{ + unsigned *nextstep = NULL; + unsigned finished_step = 0; + unsigned which; + exchange_info_t last; + + if (!(nextstep = HDcalloc(s.ndatasets, sizeof(*nextstep)))) { + fprintf(stderr, "memory allocation failed\n"); + TEST_ERROR; + } + + do { + /* Receive the notice of the writer finishing zoo creation, + * including the number of chunks finished and the timestamp + */ + if (s.use_named_pipe && HDread(np->fd_writer_to_reader, &last, sizeof(last)) < 0) { + fprintf(stderr, "HDread failed\n"); + TEST_ERROR; + } + + for (which = 0; which < s.ndatasets; which++) { + dbgf(1, "step %d which %d\n", nextstep[which], which); + + /* Verify the chunks starting from the finished one in last round + * to the ones written in this round + */ + if (!verify_extensible_dset(&s, which, mat, finished_step, last.step)) { + fprintf(stderr, "verify_extensible_dset failed\n"); + TEST_ERROR; + } + + /* Reset the finished one */ + finished_step = last.step; + } + + /* Make sure the chunk verification doesn't take longer than the expected time. + * This time period is from the writer finishing chunks to the reader finishing + * the validation of the chunks */ + if (s.use_named_pipe && below_speed_limit(&(last.time), &(s.ival))) { + AT(); + fprintf(stderr, "verify_extensible_dset took too long to finish\n"); + } + } while (finished_step < s.nsteps); + + if (nextstep) + HDfree(nextstep); + + return true; + +error: + if (nextstep) + HDfree(nextstep); + + return false; +} + +static bool add_dset_attribute(const state_t *s, hid_t ds, hid_t sid, unsigned int which, unsigned int step) { hid_t aid; @@ -978,30 +1568,56 @@ add_dset_attribute(const state_t *s, hid_t ds, hid_t sid, unsigned int which, un dbgf(1, "setting attribute %s on dataset %u to %u\n", name, which, step); - if ((aid = H5Acreate2(ds, name, s->filetype, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) - errx(EXIT_FAILURE, "H5Acreate2 failed"); + if ((aid = H5Acreate2(ds, name, s->filetype, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + fprintf(stderr, "H5Acreate2 failed\n"); + TEST_ERROR; + } + + if (H5Awrite(aid, H5T_NATIVE_UINT, &step) < 0) { + fprintf(stderr, "H5Awrite failed\n"); + TEST_ERROR; + } + + if (H5Aclose(aid) < 0) { + fprintf(stderr, "H5Aclose failed\n"); + TEST_ERROR; + } + + return true; - if (H5Awrite(aid, H5T_NATIVE_UINT, &step) < 0) - errx(EXIT_FAILURE, "H5Awrite failed"); - if (H5Aclose(aid) < 0) - errx(EXIT_FAILURE, "H5Aclose failed"); +error: + H5E_BEGIN_TRY { + H5Aclose(aid); + } H5E_END_TRY; + + return false; } -static void +static bool write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t *mat) { - hid_t ds, filespace; + hid_t ds = H5I_INVALID_HID, filespace = H5I_INVALID_HID; hsize_t size[RANK]; base_t base, last; + char dname[sizeof("/dataset-9999999999")]; + + esnprintf(dname, sizeof(dname), "/dataset-%d", which); dbgf(1, "%s: which %u step %u\n", __func__, which, step); - assert(which < s->ndatasets); + if (which >= s->ndatasets) { + fprintf(stderr, "index is out of range\n"); + TEST_ERROR; + } ds = s->dataset[which]; - if (s->asteps != 0 && step % s->asteps == 0) - add_dset_attribute(s, ds, s->one_by_one_sid, which, step); + if (s->asteps != 0 && step % s->asteps == 0) { + if (!add_dset_attribute(s, ds, s->one_by_one_sid, which, step)) { + fprintf(stderr, "add_dset_attribute failed\n"); + TEST_ERROR; + } + } if (s->two_dee) { size[0] = s->chunk_dims[0] * (1 + step); @@ -1023,69 +1639,164 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * sources_t *const srcs = &s->sources[which]; if (H5Dset_extent(srcs->ul, half_size) < 0) { - errx(EXIT_FAILURE, "%s.%d: H5Dset_extent failed", __func__, __LINE__); + fprintf(stderr, "H5Dset_extent failed\n"); + TEST_ERROR; } + if (H5Dset_extent(srcs->ur, half_size) < 0) { - errx(EXIT_FAILURE, "%s.%d: H5Dset_extent failed", __func__, __LINE__); + fprintf(stderr, "H5Dset_extent failed\n"); + TEST_ERROR; } + if (H5Dset_extent(srcs->bl, half_size) < 0) { - errx(EXIT_FAILURE, "%s.%d: H5Dset_extent failed", __func__, __LINE__); + fprintf(stderr, "H5Dset_extent failed\n"); + TEST_ERROR; } + if (H5Dset_extent(srcs->br, half_size) < 0) { - errx(EXIT_FAILURE, "%s.%d: H5Dset_extent failed", __func__, __LINE__); + fprintf(stderr, "H5Dset_extent failed\n"); + TEST_ERROR; } + } else if (H5Dset_extent(ds, size) < 0) { + fprintf(stderr, "H5Dset_extent failed\n"); + TEST_ERROR; } - else if (H5Dset_extent(ds, size) < 0) - errx(EXIT_FAILURE, "H5Dset_extent failed"); - - filespace = H5Dget_space(ds); - if (filespace == badhid) - errx(EXIT_FAILURE, "H5Dget_space failed"); + if ((filespace = H5Dget_space(ds)) < 0) { + fprintf(stderr, "H5Dget_space failed\n"); + TEST_ERROR; + } if (s->two_dee) { base.col = last.col; for (base.row = 0; base.row <= last.row; base.row += s->chunk_dims[0]) { dbgf(1, "writing chunk %" PRIuHSIZE ", %" PRIuHSIZE "\n", base.row, base.col); - init_and_write_chunk(s, filespace, mat, which, base); + if (!init_and_write_chunk(s, filespace, mat, which, base)) { + fprintf(stderr, "init_and_write_chunk failed\n"); + TEST_ERROR; + } } base.row = last.row; for (base.col = 0; base.col < last.col; base.col += s->chunk_dims[1]) { dbgf(1, "writing chunk %" PRIuHSIZE ", %" PRIuHSIZE "\n", base.row, base.col); - init_and_write_chunk(s, filespace, mat, which, base); + if (!init_and_write_chunk(s, filespace, mat, which, base)) { + fprintf(stderr, "init_and_write_chunk failed\n"); + TEST_ERROR; + } } } else { - init_and_write_chunk(s, filespace, mat, which, last); + if (!init_and_write_chunk(s, filespace, mat, which, last)) { + fprintf(stderr, "init_and_write_chunk failed\n"); + TEST_ERROR; + } } - if (H5Sclose(filespace) < 0) - errx(EXIT_FAILURE, "H5Sclose failed"); + if (H5Sclose(filespace) < 0) { + fprintf(stderr, "H5Sclose failed\n"); + TEST_ERROR; + } + + return true; + +error: + H5E_BEGIN_TRY { + H5Sclose(filespace); + } H5E_END_TRY; + + return false; +} + +static bool +write_dsets(state_t s, np_state_t *np, mat_t *mat) +{ + unsigned last_step, step, which; + unsigned long long old_tick_num; + H5F_t *f = NULL; + + if (NULL == (f = (H5F_t *)H5VL_object(s.file[0]))) { + fprintf(stderr, "H5VL_object failed\n"); + TEST_ERROR; + } + + old_tick_num = f->shared->tick_num; + + /* Write as many as chunks within the same tick number before notifying + * the reader to verify them. + */ + for (step = 0; step < s.nsteps; step++) { + /* Write as many as chunks before the tick number changes */ + if (f->shared->tick_num == old_tick_num) { + for (which = 0; which < s.ndatasets; which++) { + dbgf(2, "step %d which %d\n", step, which); + if (!write_extensible_dset(&s, which, step, mat)) { + fprintf(stderr, "write_extensible_dset failed\n"); + TEST_ERROR; + } + } + } + + /* After finishing writing all the chunks, end the tick */ + if(s.use_vfd_swmr && step == (s.nsteps - 1)) { + unsigned long i; + + if (s.vds != vds_multi) + H5Fvfd_swmr_end_tick(s.file[0]); + else + for (i = 0; i < NELMTS(s.file); i++) + H5Fvfd_swmr_end_tick(s.file[i]); + } + + /* Notify the reader to start verification by + * sending the timestamp and the number of chunks written + */ + if (f->shared->tick_num > old_tick_num || step == (s.nsteps - 1)) { + last_step = step + 1; + if (s.use_named_pipe && notify_reader(np, last_step) < 0) { + fprintf(stderr, "notify_reader failed\n"); + TEST_ERROR; + } + + old_tick_num = f->shared->tick_num; + } + } + + return true; + +error: + return false; } int main(int argc, char **argv) { mat_t * mat; - hid_t fcpl; - sigset_t oldsigs; - herr_t ret; - unsigned step, which; + hid_t fcpl = H5I_INVALID_HID; + unsigned which; state_t s; + np_state_t np; size_t i; - state_init(&s, argc, argv); + if (!state_init(&s, argc, argv)) { + fprintf(stderr, "state_init failed\n"); + TEST_ERROR; + } - if ((mat = newmat(s.rows, s.cols)) == NULL) - err(EXIT_FAILURE, "%s: could not allocate matrix", __func__); + if ((mat = newmat(s.rows, s.cols)) == NULL) { + fprintf(stderr, "could not allocate matrix\n"); + TEST_ERROR; + } - if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) - errx(EXIT_FAILURE, "H5Pcreate"); + if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) { + fprintf(stderr, "H5Pcreate failed\n"); + TEST_ERROR; + } - ret = H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, false, 1); - if (ret < 0) - errx(EXIT_FAILURE, "H5Pset_file_space_strategy"); + if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, false, 1) < 0) { + fprintf(stderr, "H5Pset_file_space_strategy failed\n"); + TEST_ERROR; + } for (i = 0; i < NELMTS(s.file); i++) { hid_t fapl; @@ -1097,89 +1808,164 @@ 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, 4, 7, s.writer, FALSE, 128, "./bigset-shadow-%zu", i); + init_vfd_swmr_config(&config, TICK_LEN, MAX_LAG, s.writer, FALSE, 128, "./bigset-shadow-%zu", i); /* use_latest_format, use_vfd_swmr, only_meta_page, config */ - fapl = vfd_swmr_create_fapl(true, s.use_vfd_swmr, true, &config); - - if (fapl < 0) - errx(EXIT_FAILURE, "vfd_swmr_create_fapl"); + if ((fapl = vfd_swmr_create_fapl(true, s.use_vfd_swmr, true, &config)) < 0) { + fprintf(stderr, "vfd_swmr_create_fapl failed\n"); + TEST_ERROR; + } s.file[i] = s.writer ? H5Fcreate(s.filename[i], H5F_ACC_TRUNC, fcpl, fapl) : H5Fopen(s.filename[i], H5F_ACC_RDONLY, fapl); - if (s.file[i] == badhid) - errx(EXIT_FAILURE, s.writer ? "H5Fcreate" : "H5Fopen"); + if (s.file[i] == badhid) { + fprintf(stderr, s.writer ? "H5Fcreate failed" : "H5Fopen failed"); + TEST_ERROR; + } - if (H5Pclose(fapl) < 0) - errx(EXIT_FAILURE, "H5Pclose(fapl)"); + if (H5Pclose(fapl) < 0) { + fprintf(stderr, "H5Pclose failed\n"); + TEST_ERROR; + } } - block_signals(&oldsigs); + /* Initiailze named pipes */ + if(s.use_named_pipe && !np_init(&np, s.writer)) { + fprintf(stderr, "np_init() failed\n"); + TEST_ERROR; + } if (s.writer) { + /* Writer tells reader to start */ + np.notify = 1; + if (s.use_named_pipe && HDwrite(np.fd_writer_to_reader, &np.notify, sizeof(int)) < 0) { + fprintf(stderr, "HDwrite failed\n"); + TEST_ERROR; + } + + /* Create NDATASETS datasets as the reader is doing verification. So no communication with + * the reader during the creation of datasets. + */ for (which = 0; which < s.ndatasets; which++) - create_extensible_dset(&s, which); + if (!create_extensible_dset(&s, which)) { + fprintf(stderr, "create_extensible_dset failed: number %u\n", which); + TEST_ERROR; + } - for (step = 0; step < s.nsteps; step++) { - for (which = 0; which < s.ndatasets; which++) { - dbgf(2, "step %d which %d\n", step, which); - write_extensible_dset(&s, which, step, mat); - if (s.ndatasets <= s.nsteps) - nanosleep(&s.update_interval, NULL); - } - if (s.ndatasets > s.nsteps) - nanosleep(&s.update_interval, NULL); + /* Call H5Fvfd_swmr_end_tick to end the tick. No communication with the reader in this step */ + if(s.use_vfd_swmr && s.use_named_pipe) { + unsigned long j; + + if (s.vds != vds_multi) { + if (H5Fvfd_swmr_end_tick(s.file[0]) < 0) { + fprintf(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) { + fprintf(stderr, "H5Fvfd_swmr_end_tick failed\n"); + TEST_ERROR; + } + } + } + + /* Notify the reader of finishing dataset creation by sending the timestamp + * and wait for the reader to finish validation before proceeding */ + np.verify = 2; + if (s.use_named_pipe && notify_and_wait_for_reader(&s, &np) < 0) { + fprintf(stderr, "notify_and_wait_for_reader failed\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)) { + fprintf(stderr, "write_dsets failed"); + TEST_ERROR; + } + } else { + /* Wait for the writer's notice before starting the validation of dataset creation */ + np.verify = 1; + if (s.use_named_pipe && reader_verify(np, np.verify) < 0) { + fprintf(stderr, "reader_verify failed\n"); + TEST_ERROR; + } + + /* Open all the datasets as the writer is creating them. No communication with + * the writer during this step. + */ + if (!open_extensible_dset(&s)) { + fprintf(stderr, "open_extensible_dset failed\n"); + TEST_ERROR; } - } - else { - unsigned *nextstep = calloc(s.ndatasets, sizeof(*nextstep)); - unsigned finished_step; - - if (nextstep == NULL) - err(EXIT_FAILURE, "could not allocate `nextstep` array"); - - for (which = s.ndatasets; which > 0; which--) - open_extensible_dset(&s, which - 1); - - do { - finished_step = UINT_MAX; /* the greatest step finished on - * *all* datasets - */ - - for (which = s.ndatasets; which-- > 0;) { - dbgf(2, "step %d which %d\n", nextstep[which], which); - verify_extensible_dset(&s, which, mat, &nextstep[which]); - if (nextstep[which] < finished_step) - finished_step = nextstep[which]; - if (s.ndatasets <= s.nsteps) - nanosleep(&s.update_interval, NULL); - } - if (s.ndatasets > s.nsteps) - nanosleep(&s.update_interval, NULL); - } while (hang_back + finished_step < s.nsteps); - free(nextstep); + /* Receive the notice of the writer finishing dataset creation (timestamp) + * Make sure the dataset creation doesn't take longer than the expected time. + * This time period is from the writer finishing dataset creation to the reader finishing + * the validation of dataset creation */ + np.notify = 2; + if (s.use_named_pipe && reader_check_time_and_notify_writer(&np, s) < 0) { + fprintf(stderr, "reader_check_time_and_notify_writer failed\n"); + TEST_ERROR; + } + + /* Once the reader starts to verify the datasets, it doesn't notify the writer any info. + * Both the reader and writer finish by themselves. + */ + if (!verify_dsets(s, &np, mat)) { + fprintf(stderr, "verify_dsets failed\n"); + TEST_ERROR; + } } for (which = 0; which < s.ndatasets; which++) - close_extensible_dset(&s, which); - - if (s.use_vfd_swmr && s.wait_for_signal) - await_signal(s.file[0]); + if (!close_extensible_dset(&s, which)) { + fprintf(stderr, "close_extensible_dset failed\n"); + TEST_ERROR; + } - restore_signals(&oldsigs); + if (H5Pclose(fcpl) < 0) { + fprintf(stderr, "H5Pclose failed\n"); + TEST_ERROR; + } - if (H5Pclose(fcpl) < 0) - errx(EXIT_FAILURE, "H5Pclose(fcpl)"); + if(s.use_named_pipe && !np_close(&np, s.writer)) { + fprintf(stderr, "np_close() failed\n"); + TEST_ERROR; + } - state_destroy(&s); + if (!state_destroy(&s)) { + fprintf(stderr, "state_destroy failed\n"); + TEST_ERROR; + } - free(mat); + HDfree(mat); return EXIT_SUCCESS; -} +error: + H5E_BEGIN_TRY { + H5Pclose(fcpl); + + for (i = 0; i < NELMTS(s.file); i++) + H5Fclose(s.file[i]); + } H5E_END_TRY; + + if (s.use_named_pipe && np.fd_writer_to_reader >= 0) + HDclose(np.fd_writer_to_reader); + + if (s.use_named_pipe && np.fd_reader_to_writer >= 0) + HDclose(np.fd_reader_to_writer); + + if(s.use_named_pipe && !s.writer) { + HDremove(np.fifo_writer_to_reader); + HDremove(np.fifo_reader_to_writer); + } + + return EXIT_FAILURE; +} #else /* H5_HAVE_WIN32_API */ int -- cgit v0.12 From a30dbdea29ecae0d07cf9c49b76bf0951ed01a88 Mon Sep 17 00:00:00 2001 From: Songyu Lu Date: Mon, 7 Jun 2021 10:06:02 -0500 Subject: Some simple format changes. --- test/vfd_swmr_bigset_writer.c | 108 +++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 55 deletions(-) diff --git a/test/vfd_swmr_bigset_writer.c b/test/vfd_swmr_bigset_writer.c index 138b796..65e3881 100644 --- a/test/vfd_swmr_bigset_writer.c +++ b/test/vfd_swmr_bigset_writer.c @@ -84,10 +84,10 @@ #define MAX_READ_LEN_IN_SECONDS 2 #define TICK_LEN 4 #define MAX_LAG 7 -#define ROWS 256 -#define COLS 512 +#define ROWS 256 +#define COLS 512 #define RANK 2 -#define NUM_ATTEMPTS 100 +#define NUM_ATTEMPTS 100 typedef struct _base { hsize_t row, col; @@ -113,13 +113,13 @@ typedef struct _sources { #define MANY_FILES 4 typedef struct { - hid_t * dataset; - sources_t * sources; - hid_t file[MANY_FILES]; - hid_t dapl, filetype, memspace, one_by_one_sid, quadrant_dcpl; - unsigned ndatasets; - const char * filename[MANY_FILES]; - char progname[PATH_MAX]; + hid_t *dataset; + sources_t *sources; + hid_t file[MANY_FILES]; + hid_t dapl, filetype, memspace, one_by_one_sid, quadrant_dcpl; + unsigned ndatasets; + const char *filename[MANY_FILES]; + char progname[PATH_MAX]; struct { quadrant_t ul, ur, bl, br, src; } quadrants; @@ -141,10 +141,10 @@ typedef struct { typedef struct { const char *fifo_writer_to_reader; /* Name of fifo for writer to reader */ const char *fifo_reader_to_writer; /* Name of fifo for reader to writer */ - int fd_writer_to_reader; /* File ID for fifo from writer to reader */ - int fd_reader_to_writer; /* File ID for fifo from reader to writer */ - int notify; /* Value to notify between writer and reader */ - int verify; /* Value to verify between writer and reader */ + int fd_writer_to_reader; /* File ID for fifo from writer to reader */ + int fd_reader_to_writer; /* File ID for fifo from reader to writer */ + int notify; /* Value to notify between writer and reader */ + int verify; /* Value to verify between writer and reader */ } np_state_t; typedef struct { @@ -154,12 +154,12 @@ typedef struct { /* Initializations for np_state_t */ #define NP_INITIALIZER (np_state_t) { \ - .fifo_writer_to_reader = "./fifo_bigset_writer_to_reader" \ - , .fifo_reader_to_writer = "./fifo_bigset_reader_to_writer" \ - , .fd_writer_to_reader = -1 \ - , .fd_reader_to_writer = -1 \ - , .notify = 0 \ - , .verify = 0 \ + .fifo_writer_to_reader = "./fifo_bigset_writer_to_reader", \ + .fifo_reader_to_writer = "./fifo_bigset_reader_to_writer", \ + .fd_writer_to_reader = -1, \ + .fd_reader_to_writer = -1, \ + .notify = 0, \ + .verify = 0 \ } static inline state_t @@ -380,7 +380,7 @@ state_init(state_t *s, int argc, char **argv) s->cols = (unsigned)tmp; else if (ch == 'l') { /* Translate the tick number to time represented by the timespec struct */ - float time = (float)(((unsigned)tmp * TICK_LEN) / 10.0); + float time = (float)(((unsigned)tmp * TICK_LEN) / 10.0); unsigned sec = (unsigned)time; unsigned nsec = (unsigned)((time - sec) * 10 * 1000 * 1000); @@ -723,13 +723,13 @@ np_init(np_state_t *np, bool writer) if (writer) { /* If the named pipes are present at the start of the test, remove them */ if (HDaccess(np->fifo_writer_to_reader, F_OK) == 0) - if(HDremove(np->fifo_writer_to_reader) != 0) { + if (HDremove(np->fifo_writer_to_reader) != 0) { fprintf(stderr, "HDremove fifo_writer_to_reader failed\n"); TEST_ERROR; } if (HDaccess(np->fifo_reader_to_writer, F_OK) == 0) - if(HDremove(np->fifo_reader_to_writer) != 0) { + if (HDremove(np->fifo_reader_to_writer) != 0) { fprintf(stderr, "HDremove fifo_reader_to_writer failed\n"); TEST_ERROR; } @@ -827,8 +827,8 @@ error: static int notify_and_wait_for_reader(state_t *s, np_state_t *np) { - int notify; - unsigned int i; + int notify; + unsigned int i; struct timespec last = {0, 0}; /* Get the time when finishing zoo creation */ @@ -845,7 +845,7 @@ notify_and_wait_for_reader(state_t *s, np_state_t *np) /* During the wait, writer makes repeated HDF5 API calls so as to trigger * EOT at approximately the correct time */ - for(i = 0; i < MAX_LAG + 1; i++) { + for (i = 0; i < MAX_LAG + 1; i++) { decisleep(TICK_LEN); H5E_BEGIN_TRY { @@ -921,9 +921,8 @@ notify_reader(np_state_t *np, unsigned step) /* Notify the reader by sending the timestamp and the number of chunks written */ if (HDwrite(np->fd_writer_to_reader, &last, sizeof(last)) < 0) { - H5_FAILED(); AT(); fprintf(stderr, "HDwrite failed"); - goto error; + TEST_ERROR; } return 0; @@ -1083,10 +1082,10 @@ error: static bool open_extensible_dset(state_t *s) { - hsize_t dims[RANK], maxdims[RANK]; - char dname[sizeof("/dataset-9999999999")]; - hid_t dset_id, filespace, dtype; - unsigned int which, i; + hsize_t dims[RANK], maxdims[RANK]; + char dname[sizeof("/dataset-9999999999")]; + hid_t dset_id, filespace, dtype; + unsigned int which, i; for (which = 0; which < s->ndatasets; which++) { esnprintf(dname, sizeof(dname), "/dataset-%d", which); @@ -1204,7 +1203,7 @@ static bool set_or_verify_matrix(mat_t *mat, unsigned int which, base_t base, bool do_set) { unsigned row, col; - bool ret = true; + bool ret = true; for (row = 0; row < mat->rows; row++) { for (col = 0; col < mat->cols; col++) { @@ -1288,7 +1287,7 @@ error: static bool repeat_verify_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t base) { - hid_t dset_id = s->dataset[which]; + hid_t dset_id = s->dataset[which]; unsigned i; /* If the chunk data isn't good after reading it NUM_ATTEMPTS times, report it as a failure */ @@ -1503,9 +1502,9 @@ error: static bool verify_dsets(state_t s, np_state_t *np, mat_t *mat) { - unsigned *nextstep = NULL; - unsigned finished_step = 0; - unsigned which; + unsigned *nextstep = NULL; + unsigned finished_step = 0; + unsigned which; exchange_info_t last; if (!(nextstep = HDcalloc(s.ndatasets, sizeof(*nextstep)))) { @@ -1596,10 +1595,10 @@ error: static bool write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t *mat) { - hid_t ds = H5I_INVALID_HID, filespace = H5I_INVALID_HID; + hid_t dset_id = H5I_INVALID_HID, filespace = H5I_INVALID_HID; hsize_t size[RANK]; base_t base, last; - char dname[sizeof("/dataset-9999999999")]; + char dname[sizeof("/dataset-9999999999")]; esnprintf(dname, sizeof(dname), "/dataset-%d", which); @@ -1610,10 +1609,10 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * TEST_ERROR; } - ds = s->dataset[which]; + dset_id = s->dataset[which]; if (s->asteps != 0 && step % s->asteps == 0) { - if (!add_dset_attribute(s, ds, s->one_by_one_sid, which, step)) { + if (!add_dset_attribute(s, dset_id, s->one_by_one_sid, which, step)) { fprintf(stderr, "add_dset_attribute failed\n"); TEST_ERROR; } @@ -1624,8 +1623,7 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * size[1] = s->chunk_dims[1] * (1 + step); last.row = s->chunk_dims[0] * step; last.col = s->chunk_dims[1] * step; - } - else { + } else { size[0] = s->chunk_dims[0]; size[1] = s->chunk_dims[1] * (1 + step); last.row = 0; @@ -1657,12 +1655,12 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * fprintf(stderr, "H5Dset_extent failed\n"); TEST_ERROR; } - } else if (H5Dset_extent(ds, size) < 0) { + } else if (H5Dset_extent(dset_id, size) < 0) { fprintf(stderr, "H5Dset_extent failed\n"); TEST_ERROR; } - if ((filespace = H5Dget_space(ds)) < 0) { + if ((filespace = H5Dget_space(dset_id)) < 0) { fprintf(stderr, "H5Dget_space failed\n"); TEST_ERROR; } @@ -1738,7 +1736,7 @@ write_dsets(state_t s, np_state_t *np, mat_t *mat) } /* After finishing writing all the chunks, end the tick */ - if(s.use_vfd_swmr && step == (s.nsteps - 1)) { + if (s.use_vfd_swmr && step == (s.nsteps - 1)) { unsigned long i; if (s.vds != vds_multi) @@ -1771,12 +1769,12 @@ error: int main(int argc, char **argv) { - mat_t * mat; - hid_t fcpl = H5I_INVALID_HID; - unsigned which; - state_t s; + mat_t *mat; + hid_t fcpl = H5I_INVALID_HID; + unsigned which; + state_t s; np_state_t np; - size_t i; + size_t i; if (!state_init(&s, argc, argv)) { fprintf(stderr, "state_init failed\n"); @@ -1831,7 +1829,7 @@ main(int argc, char **argv) } /* Initiailze named pipes */ - if(s.use_named_pipe && !np_init(&np, s.writer)) { + if (s.use_named_pipe && !np_init(&np, s.writer)) { fprintf(stderr, "np_init() failed\n"); TEST_ERROR; } @@ -1854,7 +1852,7 @@ main(int argc, char **argv) } /* Call H5Fvfd_swmr_end_tick to end the tick. No communication with the reader in this step */ - if(s.use_vfd_swmr && s.use_named_pipe) { + if (s.use_vfd_swmr && s.use_named_pipe) { unsigned long j; if (s.vds != vds_multi) { @@ -1931,7 +1929,7 @@ main(int argc, char **argv) TEST_ERROR; } - if(s.use_named_pipe && !np_close(&np, s.writer)) { + if (s.use_named_pipe && !np_close(&np, s.writer)) { fprintf(stderr, "np_close() failed\n"); TEST_ERROR; } @@ -1959,7 +1957,7 @@ error: if (s.use_named_pipe && np.fd_reader_to_writer >= 0) HDclose(np.fd_reader_to_writer); - if(s.use_named_pipe && !s.writer) { + if (s.use_named_pipe && !s.writer) { HDremove(np.fifo_writer_to_reader); HDremove(np.fifo_reader_to_writer); } -- cgit v0.12 From da0ea555dff447a68bb6773d3e64888386fa692d Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 7 Jun 2021 15:09:33 +0000 Subject: Committing clang-format changes --- test/vfd_swmr_bigset_writer.c | 249 ++++++++++++++++++++++++------------------ 1 file changed, 144 insertions(+), 105 deletions(-) diff --git a/test/vfd_swmr_bigset_writer.c b/test/vfd_swmr_bigset_writer.c index 65e3881..e5fae1f 100644 --- a/test/vfd_swmr_bigset_writer.c +++ b/test/vfd_swmr_bigset_writer.c @@ -113,13 +113,13 @@ typedef struct _sources { #define MANY_FILES 4 typedef struct { - hid_t *dataset; - sources_t *sources; - hid_t file[MANY_FILES]; - hid_t dapl, filetype, memspace, one_by_one_sid, quadrant_dcpl; - unsigned ndatasets; + hid_t * dataset; + sources_t * sources; + hid_t file[MANY_FILES]; + hid_t dapl, filetype, memspace, one_by_one_sid, quadrant_dcpl; + unsigned ndatasets; const char *filename[MANY_FILES]; - char progname[PATH_MAX]; + char progname[PATH_MAX]; struct { quadrant_t ul, ur, bl, br, src; } quadrants; @@ -128,23 +128,23 @@ typedef struct { unsigned int nsteps; bool two_dee; enum { vds_off, vds_single, vds_multi } vds; - bool use_vfd_swmr; - bool use_named_pipe; - bool writer; - bool fixed_array; - hsize_t chunk_dims[RANK]; - hsize_t one_dee_max_dims[RANK]; + bool use_vfd_swmr; + bool use_named_pipe; + bool writer; + bool fixed_array; + hsize_t chunk_dims[RANK]; + hsize_t one_dee_max_dims[RANK]; struct timespec ival; } state_t; /* Structure to hold info for named pipes */ typedef struct { - const char *fifo_writer_to_reader; /* Name of fifo for writer to reader */ - const char *fifo_reader_to_writer; /* Name of fifo for reader to writer */ - int fd_writer_to_reader; /* File ID for fifo from writer to reader */ - int fd_reader_to_writer; /* File ID for fifo from reader to writer */ - int notify; /* Value to notify between writer and reader */ - int verify; /* Value to verify between writer and reader */ + const char *fifo_writer_to_reader; /* Name of fifo for writer to reader */ + const char *fifo_reader_to_writer; /* Name of fifo for reader to writer */ + int fd_writer_to_reader; /* File ID for fifo from writer to reader */ + int fd_reader_to_writer; /* File ID for fifo from reader to writer */ + int notify; /* Value to notify between writer and reader */ + int verify; /* Value to verify between writer and reader */ } np_state_t; typedef struct { @@ -153,14 +153,13 @@ typedef struct { } exchange_info_t; /* Initializations for np_state_t */ -#define NP_INITIALIZER (np_state_t) { \ - .fifo_writer_to_reader = "./fifo_bigset_writer_to_reader", \ - .fifo_reader_to_writer = "./fifo_bigset_reader_to_writer", \ - .fd_writer_to_reader = -1, \ - .fd_reader_to_writer = -1, \ - .notify = 0, \ - .verify = 0 \ -} +#define NP_INITIALIZER \ + (np_state_t) \ + { \ + .fifo_writer_to_reader = "./fifo_bigset_writer_to_reader", \ + .fifo_reader_to_writer = "./fifo_bigset_reader_to_writer", .fd_writer_to_reader = -1, \ + .fd_reader_to_writer = -1, .notify = 0, .verify = 0 \ + } static inline state_t state_initializer(void) @@ -272,7 +271,7 @@ static bool make_quadrant_dataspace(state_t *s, quadrant_t *q) { if ((q->space = H5Screate_simple(NELMTS(s->chunk_dims), s->chunk_dims, - s->two_dee ? two_dee_max_dims : s->one_dee_max_dims)) < 0) { + s->two_dee ? two_dee_max_dims : s->one_dee_max_dims)) < 0) { fprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; } @@ -285,9 +284,11 @@ make_quadrant_dataspace(state_t *s, quadrant_t *q) return true; error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Sclose(q->space); - } H5E_END_TRY; + } + H5E_END_TRY; return false; } @@ -298,8 +299,8 @@ state_init(state_t *s, int argc, char **argv) unsigned long tmp; int ch; unsigned i; - const hsize_t dims = 1; - char *tfile = NULL; + const hsize_t dims = 1; + char * tfile = NULL; char * end; quadrant_t *const ul = &s->quadrants.ul, *const ur = &s->quadrants.ur, *const bl = &s->quadrants.bl, *const br = &s->quadrants.br, *const src = &s->quadrants.src; @@ -381,12 +382,13 @@ state_init(state_t *s, int argc, char **argv) else if (ch == 'l') { /* Translate the tick number to time represented by the timespec struct */ float time = (float)(((unsigned)tmp * TICK_LEN) / 10.0); - unsigned sec = (unsigned)time; + unsigned sec = (unsigned)time; unsigned nsec = (unsigned)((time - sec) * 10 * 1000 * 1000); - s->ival.tv_sec = sec; + s->ival.tv_sec = sec; s->ival.tv_nsec = nsec; - } else if (ch == 'n') + } + else if (ch == 'n') s->nsteps = (unsigned)tmp; else if (ch == 'r') s->rows = (unsigned)tmp; @@ -504,7 +506,8 @@ state_init(state_t *s, int argc, char **argv) TEST_ERROR; } - if (H5Sselect_hyperslab(src->space, H5S_SELECT_SET, src->start, src->stride, src->count, src->block) < 0) { + if (H5Sselect_hyperslab(src->space, H5S_SELECT_SET, src->start, src->stride, src->count, src->block) < + 0) { fprintf(stderr, "H5Sselect_hyperslab failed\n"); TEST_ERROR; } @@ -597,7 +600,8 @@ state_init(state_t *s, int argc, char **argv) return true; error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Pclose(s->quadrant_dcpl); H5Sclose(ul->space); H5Sclose(ur->space); @@ -610,7 +614,8 @@ error: H5Sclose(src->space); H5Sclose(s->one_by_one_sid); H5Sclose(s->memspace); - } H5E_END_TRY; + } + H5E_END_TRY; if (tfile) HDfree(tfile); @@ -689,11 +694,13 @@ state_destroy(state_t *s) return true; error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Pclose(s->quadrant_dcpl); H5Sclose(s->one_by_one_sid); H5Sclose(s->memspace); - } H5E_END_TRY; + } + H5E_END_TRY; if (s->dataset) HDfree(s->dataset); @@ -783,13 +790,13 @@ np_close(np_state_t *np, bool writer) } /* Reader finishes last and deletes the named pipes */ - if(!writer) { - if(HDremove(np->fifo_writer_to_reader) != 0) { + if (!writer) { + if (HDremove(np->fifo_writer_to_reader) != 0) { fprintf(stderr, "HDremove fifo_writer_to_reader failed\n"); TEST_ERROR; } - if(HDremove(np->fifo_reader_to_writer) != 0) { + if (HDremove(np->fifo_reader_to_writer) != 0) { fprintf(stderr, "HDremove fifo_reader_to_writer failed\n"); TEST_ERROR; } @@ -848,9 +855,11 @@ notify_and_wait_for_reader(state_t *s, np_state_t *np) for (i = 0; i < MAX_LAG + 1; i++) { decisleep(TICK_LEN); - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Aexists(s->file[0], "nonexistent"); - } H5E_END_TRY; + } + H5E_END_TRY; } /* Wait until the reader finishes validating zoo creation */ @@ -961,22 +970,26 @@ create_extensible_dset(state_t *s, unsigned int which) esnprintf(bl_dname, sizeof(bl_dname), "/bl-dataset-%d", which); esnprintf(br_dname, sizeof(br_dname), "/br-dataset-%d", which); - if ((srcs->ul = H5Dcreate2(s->file[0], ul_dname, s->filetype, ul->src_space, H5P_DEFAULT, s->quadrant_dcpl, s->dapl)) < 0) { + if ((srcs->ul = H5Dcreate2(s->file[0], ul_dname, s->filetype, ul->src_space, H5P_DEFAULT, + s->quadrant_dcpl, s->dapl)) < 0) { fprintf(stderr, "H5Dcreate2 failed\n"); TEST_ERROR; } - if ((srcs->ur = H5Dcreate2(s->file[1], ur_dname, s->filetype, ur->src_space, H5P_DEFAULT, s->quadrant_dcpl, s->dapl)) < 0) { + if ((srcs->ur = H5Dcreate2(s->file[1], ur_dname, s->filetype, ur->src_space, H5P_DEFAULT, + s->quadrant_dcpl, s->dapl)) < 0) { fprintf(stderr, "H5Dcreate2 failed\n"); TEST_ERROR; } - if ((srcs->bl = H5Dcreate2(s->file[2], bl_dname, s->filetype, bl->src_space, H5P_DEFAULT, s->quadrant_dcpl, s->dapl)) < 0) { + if ((srcs->bl = H5Dcreate2(s->file[2], bl_dname, s->filetype, bl->src_space, H5P_DEFAULT, + s->quadrant_dcpl, s->dapl)) < 0) { fprintf(stderr, "H5Dcreate2 failed\n"); TEST_ERROR; } - if ((srcs->br = H5Dcreate2(s->file[3], br_dname, s->filetype, br->src_space, H5P_DEFAULT, s->quadrant_dcpl, s->dapl)) < 0) { + if ((srcs->br = H5Dcreate2(s->file[3], br_dname, s->filetype, br->src_space, H5P_DEFAULT, + s->quadrant_dcpl, s->dapl)) < 0) { fprintf(stderr, "H5Dcreate2 failed\n"); TEST_ERROR; } @@ -1003,7 +1016,7 @@ create_extensible_dset(state_t *s, unsigned int which) } if ((filespace = H5Screate_simple(NELMTS(s->chunk_dims), s->chunk_dims, - s->two_dee ? two_dee_max_dims : s->one_dee_max_dims)) < 0) { + s->two_dee ? two_dee_max_dims : s->one_dee_max_dims)) < 0) { fprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; } @@ -1028,11 +1041,13 @@ create_extensible_dset(state_t *s, unsigned int which) return true; error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Dclose(dset_id); H5Pclose(dcpl); H5Sclose(filespace); - } H5E_END_TRY; + } + H5E_END_TRY; return false; } @@ -1072,9 +1087,11 @@ close_extensible_dset(state_t *s, unsigned int which) return true; error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Dclose(dset_id); - } H5E_END_TRY; + } + H5E_END_TRY; return false; } @@ -1094,9 +1111,11 @@ open_extensible_dset(state_t *s) * NUM_ATTEMPTS times without success, report it as a failure */ for (i = 0; i < NUM_ATTEMPTS; i++) { - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { dset_id = H5Dopen2(s->file[0], dname, s->dapl); - } H5E_END_TRY; + } + H5E_END_TRY; if (dset_id >= 0) break; @@ -1148,14 +1167,15 @@ open_extensible_dset(state_t *s) if (maxdims[0] != two_dee_max_dims[0] || maxdims[1] != two_dee_max_dims[1] || maxdims[0] != maxdims[1]) { fprintf(stderr, "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE, maxdims[0], - maxdims[1]); + maxdims[1]); TEST_ERROR; } - } else if (maxdims[0] != s->one_dee_max_dims[0] || maxdims[1] != s->one_dee_max_dims[1] || - dims[0] != s->chunk_dims[0]) { + } + else if (maxdims[0] != s->one_dee_max_dims[0] || maxdims[1] != s->one_dee_max_dims[1] || + dims[0] != s->chunk_dims[0]) { fprintf(stderr, - "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE " or columns %" PRIuHSIZE, - maxdims[0], maxdims[1], dims[1]); + "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE " or columns %" PRIuHSIZE, + maxdims[0], maxdims[1], dims[1]); } s->dataset[which] = dset_id; @@ -1164,11 +1184,13 @@ open_extensible_dset(state_t *s) return true; error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Dclose(dset_id); H5Tclose(dtype); H5Sclose(filespace); - } H5E_END_TRY; + } + H5E_END_TRY; return false; } @@ -1222,7 +1244,8 @@ set_or_verify_matrix(mat_t *mat, unsigned int which, base_t base, bool do_set) ret = false; break; } - } else if (matget(mat, row, col) != v) { + } + else if (matget(mat, row, col) != v) { /* If the data doesn't match, simply return false and * let the caller repeat this step */ @@ -1268,12 +1291,14 @@ verify_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t bas TEST_ERROR; } - /* A failure to read the data may indicate the data isn't ready yet. Instead of displaying the error stack, - * simply return false and let the caller repeat this step. + /* A failure to read the data may indicate the data isn't ready yet. Instead of displaying the error + * stack, simply return false and let the caller repeat this step. */ - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { status = H5Dread(dset_id, H5T_NATIVE_UINT32, s->memspace, filespace, H5P_DEFAULT, mat->elt); - } H5E_END_TRY; + } + H5E_END_TRY; if (status < 0) TEST_ERROR; @@ -1379,9 +1404,11 @@ verify_dset_attribute(hid_t dset_id, unsigned int which, unsigned int step) return true; error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Aclose(aid); - } H5E_END_TRY; + } + H5E_END_TRY; return false; } @@ -1492,9 +1519,11 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini return true; error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Sclose(filespace); - } H5E_END_TRY; + } + H5E_END_TRY; return false; } @@ -1502,7 +1531,7 @@ error: static bool verify_dsets(state_t s, np_state_t *np, mat_t *mat) { - unsigned *nextstep = NULL; + unsigned * nextstep = NULL; unsigned finished_step = 0; unsigned which; exchange_info_t last; @@ -1585,9 +1614,11 @@ add_dset_attribute(const state_t *s, hid_t ds, hid_t sid, unsigned int which, un return true; error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Aclose(aid); - } H5E_END_TRY; + } + H5E_END_TRY; return false; } @@ -1623,7 +1654,8 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * size[1] = s->chunk_dims[1] * (1 + step); last.row = s->chunk_dims[0] * step; last.col = s->chunk_dims[1] * step; - } else { + } + else { size[0] = s->chunk_dims[0]; size[1] = s->chunk_dims[1] * (1 + step); last.row = 0; @@ -1655,7 +1687,8 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * fprintf(stderr, "H5Dset_extent failed\n"); TEST_ERROR; } - } else if (H5Dset_extent(dset_id, size) < 0) { + } + else if (H5Dset_extent(dset_id, size) < 0) { fprintf(stderr, "H5Dset_extent failed\n"); TEST_ERROR; } @@ -1699,9 +1732,11 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * return true; error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Sclose(filespace); - } H5E_END_TRY; + } + H5E_END_TRY; return false; } @@ -1709,9 +1744,9 @@ error: static bool write_dsets(state_t s, np_state_t *np, mat_t *mat) { - unsigned last_step, step, which; + unsigned last_step, step, which; unsigned long long old_tick_num; - H5F_t *f = NULL; + H5F_t * f = NULL; if (NULL == (f = (H5F_t *)H5VL_object(s.file[0]))) { fprintf(stderr, "H5VL_object failed\n"); @@ -1737,13 +1772,13 @@ write_dsets(state_t s, np_state_t *np, mat_t *mat) /* After finishing writing all the chunks, end the tick */ if (s.use_vfd_swmr && step == (s.nsteps - 1)) { - unsigned long i; + unsigned long i; - if (s.vds != vds_multi) - H5Fvfd_swmr_end_tick(s.file[0]); - else - for (i = 0; i < NELMTS(s.file); i++) - H5Fvfd_swmr_end_tick(s.file[i]); + if (s.vds != vds_multi) + H5Fvfd_swmr_end_tick(s.file[0]); + else + for (i = 0; i < NELMTS(s.file); i++) + H5Fvfd_swmr_end_tick(s.file[i]); } /* Notify the reader to start verification by @@ -1769,7 +1804,7 @@ error: int main(int argc, char **argv) { - mat_t *mat; + mat_t * mat; hid_t fcpl = H5I_INVALID_HID; unsigned which; state_t s; @@ -1849,24 +1884,25 @@ main(int argc, char **argv) if (!create_extensible_dset(&s, which)) { fprintf(stderr, "create_extensible_dset failed: number %u\n", which); TEST_ERROR; - } + } /* Call H5Fvfd_swmr_end_tick to end the tick. No communication with the reader in this step */ if (s.use_vfd_swmr && s.use_named_pipe) { - unsigned long j; - - if (s.vds != vds_multi) { - if (H5Fvfd_swmr_end_tick(s.file[0]) < 0) { - fprintf(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) { - fprintf(stderr, "H5Fvfd_swmr_end_tick failed\n"); - TEST_ERROR; - } - } + unsigned long j; + + if (s.vds != vds_multi) { + if (H5Fvfd_swmr_end_tick(s.file[0]) < 0) { + fprintf(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) { + fprintf(stderr, "H5Fvfd_swmr_end_tick failed\n"); + TEST_ERROR; + } + } } /* Notify the reader of finishing dataset creation by sending the timestamp @@ -1883,7 +1919,8 @@ main(int argc, char **argv) fprintf(stderr, "write_dsets failed"); TEST_ERROR; } - } else { + } + else { /* Wait for the writer's notice before starting the validation of dataset creation */ np.verify = 1; if (s.use_named_pipe && reader_verify(np, np.verify) < 0) { @@ -1944,12 +1981,14 @@ main(int argc, char **argv) return EXIT_SUCCESS; error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Pclose(fcpl); for (i = 0; i < NELMTS(s.file); i++) H5Fclose(s.file[i]); - } H5E_END_TRY; + } + H5E_END_TRY; if (s.use_named_pipe && np.fd_writer_to_reader >= 0) HDclose(np.fd_writer_to_reader); -- cgit v0.12 From 4f0a03189b6d92cdb6c893fa86e83a05953cae0e Mon Sep 17 00:00:00 2001 From: Songyu Lu Date: Thu, 8 Jul 2021 11:17:44 -0500 Subject: 1. Added the test for 3D datasets; 2. Added performance measurement. --- test/vfd_swmr_bigset_writer.c | 813 +++++++++++++++++++++++++++--------------- 1 file changed, 518 insertions(+), 295 deletions(-) diff --git a/test/vfd_swmr_bigset_writer.c b/test/vfd_swmr_bigset_writer.c index e5fae1f..48981d5 100644 --- a/test/vfd_swmr_bigset_writer.c +++ b/test/vfd_swmr_bigset_writer.c @@ -86,11 +86,20 @@ #define MAX_LAG 7 #define ROWS 256 #define COLS 512 -#define RANK 2 +#define DEPTHS 1 +#define RANK2 2 +#define RANK3 3 #define NUM_ATTEMPTS 100 +/* Calculate the time passed in seconds. + * X is the beginning time; Y is the ending time. + * Expects X, Y to be struct timespec from the function call HDclock_gettime. + */ +#define TIME_PASSED(X,Y) \ + ((double)((Y.tv_sec - X.tv_sec) * 1000000000 + (Y.tv_nsec - X.tv_nsec))) / 1000000000.0 + typedef struct _base { - hsize_t row, col; + hsize_t depth, row, col; } base_t; typedef struct _mat { @@ -99,10 +108,10 @@ typedef struct _mat { } mat_t; typedef struct _quadrant { - hsize_t start[RANK]; - hsize_t stride[RANK]; - hsize_t block[RANK]; - hsize_t count[RANK]; + hsize_t start[RANK2]; + hsize_t stride[RANK2]; + hsize_t block[RANK2]; + hsize_t count[RANK2]; hid_t space, src_space; } quadrant_t; @@ -113,38 +122,41 @@ typedef struct _sources { #define MANY_FILES 4 typedef struct { - hid_t * dataset; - sources_t * sources; - hid_t file[MANY_FILES]; - hid_t dapl, filetype, memspace, one_by_one_sid, quadrant_dcpl; - unsigned ndatasets; + hid_t *dataset; + sources_t *sources; + hid_t file[MANY_FILES]; + hid_t dapl, filetype, memspace, one_by_one_sid, quadrant_dcpl; + unsigned ndatasets; const char *filename[MANY_FILES]; - char progname[PATH_MAX]; + char progname[PATH_MAX]; struct { quadrant_t ul, ur, bl, br, src; } quadrants; unsigned int cols, rows; unsigned int asteps; unsigned int nsteps; - bool two_dee; + bool expand_2d; + bool test_3d; enum { vds_off, vds_single, vds_multi } vds; - bool use_vfd_swmr; - bool use_named_pipe; - bool writer; - bool fixed_array; - hsize_t chunk_dims[RANK]; - hsize_t one_dee_max_dims[RANK]; + bool use_vfd_swmr; + bool use_named_pipe; + bool do_perf; + bool cross_chunks; + bool writer; + bool fixed_array; + hsize_t chunk_dims[RANK2]; + hsize_t one_dee_max_dims[RANK2]; struct timespec ival; } state_t; /* Structure to hold info for named pipes */ typedef struct { - const char *fifo_writer_to_reader; /* Name of fifo for writer to reader */ - const char *fifo_reader_to_writer; /* Name of fifo for reader to writer */ - int fd_writer_to_reader; /* File ID for fifo from writer to reader */ - int fd_reader_to_writer; /* File ID for fifo from reader to writer */ - int notify; /* Value to notify between writer and reader */ - int verify; /* Value to verify between writer and reader */ + const char *fifo_writer_to_reader; /* Name of fifo for writer to reader */ + const char *fifo_reader_to_writer; /* Name of fifo for reader to writer */ + int fd_writer_to_reader; /* File ID for fifo from writer to reader */ + int fd_reader_to_writer; /* File ID for fifo from reader to writer */ + int notify; /* Value to notify between writer and reader */ + int verify; /* Value to verify between writer and reader */ } np_state_t; typedef struct { @@ -153,13 +165,14 @@ typedef struct { } exchange_info_t; /* Initializations for np_state_t */ -#define NP_INITIALIZER \ - (np_state_t) \ - { \ - .fifo_writer_to_reader = "./fifo_bigset_writer_to_reader", \ - .fifo_reader_to_writer = "./fifo_bigset_reader_to_writer", .fd_writer_to_reader = -1, \ - .fd_reader_to_writer = -1, .notify = 0, .verify = 0 \ - } +#define NP_INITIALIZER (np_state_t) { \ + .fifo_writer_to_reader = "./fifo_bigset_writer_to_reader", \ + .fifo_reader_to_writer = "./fifo_bigset_reader_to_writer", \ + .fd_writer_to_reader = -1, \ + .fd_reader_to_writer = -1, \ + .notify = 0, \ + .verify = 0 \ +} static inline state_t state_initializer(void) @@ -176,10 +189,13 @@ state_initializer(void) .asteps = 10, .nsteps = 100, .filename = {"", "", "", ""}, - .two_dee = false, + .expand_2d = false, + .test_3d = false, .vds = vds_off, .use_vfd_swmr = true, .use_named_pipe = true, + .do_perf = false, + .cross_chunks = false, .writer = true, .fixed_array = false, .one_dee_max_dims = {ROWS, H5S_UNLIMITED}, @@ -191,7 +207,7 @@ static bool state_init(state_t *, int, char **); static const hid_t badhid = H5I_INVALID_HID; -static hsize_t two_dee_max_dims[RANK]; +static hsize_t two_dee_max_dims[RANK2], three_dee_max_dims[RANK3]; static uint32_t matget(const mat_t *mat, unsigned i, unsigned j) @@ -240,28 +256,32 @@ static void usage(const char *progname) { fprintf(stderr, - "usage: %s [-F] [-M] [-S] [-V] [-W] [-a steps] [-b] [-c cols]\n" + "usage: %s [-C] [-F] [-M] [-P] [-S] [-V] [-W] [-a steps] [-b] [-c cols]\n" " [-d dims]\n" " [-l tick_num] [-n iterations] [-r rows] [-s datasets]\n" - " [-u milliseconds]\n" + " [-t] [-u milliseconds]\n" "\n" + "-C: cross-over chunks during chunk verification\n" "-F: fixed maximal dimension for the chunked datasets\n" - "-M: use virtual datasets and many source\n" + "-M: use virtual datasets and many source\n" " files\n" - "-S: do not use VFD SWMR\n" - "-V: use virtual datasets and a single\n" + "-P: do the performance measurement" + "-S: do not use VFD SWMR\n" + "-V: use virtual datasets and a single\n" " source file\n" - "-a steps: `steps` between adding attributes\n" - "-b: write data in big-endian byte order\n" - "-c cols: `cols` columns per chunk\n" + "-a steps: `steps` between adding attributes\n" + "-b: write data in big-endian byte order\n" + "-c cols: `cols` columns per chunk\n" "-d 1|one|2|two|both: select dataset expansion in one or\n" " both dimensions\n" "-l tick_num: expected maximal number of ticks from\n" " the writer's finishing creation to the reader's finishing validation\n" "-N: do not use named pipes\n" "-n iterations: how many times to expand each dataset\n" - "-r rows: `rows` rows per chunk\n" + "-r rows: `rows` rows per chunk\n" "-s datasets: number of datasets to create\n" + "-t: enable test for 3D datasets (dataset expansion is along one dimension)\n" + " currently, 3D datasets isn't tested with VDS\n" "\n", progname); exit(EXIT_FAILURE); @@ -271,7 +291,7 @@ static bool make_quadrant_dataspace(state_t *s, quadrant_t *q) { if ((q->space = H5Screate_simple(NELMTS(s->chunk_dims), s->chunk_dims, - s->two_dee ? two_dee_max_dims : s->one_dee_max_dims)) < 0) { + s->expand_2d ? two_dee_max_dims : s->one_dee_max_dims)) < 0) { fprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; } @@ -284,11 +304,9 @@ make_quadrant_dataspace(state_t *s, quadrant_t *q) return true; error: - H5E_BEGIN_TRY - { + H5E_BEGIN_TRY { H5Sclose(q->space); - } - H5E_END_TRY; + } H5E_END_TRY; return false; } @@ -299,8 +317,8 @@ state_init(state_t *s, int argc, char **argv) unsigned long tmp; int ch; unsigned i; - const hsize_t dims = 1; - char * tfile = NULL; + const hsize_t dims = 1; + char *tfile = NULL; char * end; quadrant_t *const ul = &s->quadrants.ul, *const ur = &s->quadrants.ur, *const bl = &s->quadrants.bl, *const br = &s->quadrants.br, *const src = &s->quadrants.src; @@ -315,11 +333,14 @@ state_init(state_t *s, int argc, char **argv) esnprintf(s->progname, sizeof(s->progname), "%s", tfile); - if (tfile) - HDfree(tfile); + HDfree(tfile); - while ((ch = getopt(argc, argv, "FMNSVa:bc:d:l:n:qr:s:")) != -1) { + while ((ch = getopt(argc, argv, "CFMNPSVa:bc:d:l:n:qr:s:t")) != -1) { switch (ch) { + case 'C': + /* This flag indicates cross-over chunk read during data validation */ + s->cross_chunks = true; + break; case 'F': /* The flag to indicate whether the maximal dimension of the chunked datasets is fixed or * unlimited */ @@ -328,6 +349,9 @@ state_init(state_t *s, int argc, char **argv) case 'M': s->vds = vds_multi; break; + case 'P': + s->do_perf = true; + break; case 'S': s->use_vfd_swmr = false; break; @@ -340,10 +364,10 @@ state_init(state_t *s, int argc, char **argv) break; case 'd': if (strcmp(optarg, "1") == 0 || strcmp(optarg, "one") == 0) - s->two_dee = false; + s->expand_2d = false; else if (strcmp(optarg, "2") == 0 || strcmp(optarg, "two") == 0 || strcmp(optarg, "both") == 0) - s->two_dee = true; + s->expand_2d = true; else { fprintf(stderr, "bad -d argument %s\n", optarg); TEST_ERROR; @@ -382,19 +406,21 @@ state_init(state_t *s, int argc, char **argv) else if (ch == 'l') { /* Translate the tick number to time represented by the timespec struct */ float time = (float)(((unsigned)tmp * TICK_LEN) / 10.0); - unsigned sec = (unsigned)time; + unsigned sec = (unsigned)time; unsigned nsec = (unsigned)((time - sec) * 10 * 1000 * 1000); - s->ival.tv_sec = sec; + s->ival.tv_sec = sec; s->ival.tv_nsec = nsec; - } - else if (ch == 'n') + } else if (ch == 'n') s->nsteps = (unsigned)tmp; else if (ch == 'r') s->rows = (unsigned)tmp; else s->ndatasets = (unsigned)tmp; break; + case 't': + s->test_3d = true; + break; case 'b': s->filetype = H5T_STD_U32BE; break; @@ -415,27 +441,56 @@ state_init(state_t *s, int argc, char **argv) TEST_ERROR; } - if (s->vds != vds_off && s->two_dee) { + if (s->vds != vds_off && s->expand_2d) { fprintf(stderr, "virtual datasets and 2D datasets are mutually exclusive\n"); TEST_ERROR; } + if (s->test_3d) { + if (s->expand_2d) { + fprintf(stderr, "3D dataset test doesn't support 2D expansion\n"); + TEST_ERROR; + } + + if (s->cross_chunks) { + fprintf(stderr, "3D dataset test doesn't support cross-over chunks during verification\n"); + TEST_ERROR; + } + + if (s->vds != vds_off) { + fprintf(stderr, "3D dataset test doesn't support VDS\n"); + TEST_ERROR; + } + } + s->chunk_dims[0] = s->rows; s->chunk_dims[1] = s->cols; + s->one_dee_max_dims[0] = s->rows; if (s->fixed_array) { s->one_dee_max_dims[1] = s->cols * s->nsteps; two_dee_max_dims[0] = s->rows * s->nsteps; two_dee_max_dims[1] = s->cols * s->nsteps; - } - else { + + if(s->test_3d) { + three_dee_max_dims[0] = s->nsteps; + three_dee_max_dims[1] = s->rows; + three_dee_max_dims[2] = s->cols; + } + } else { s->one_dee_max_dims[1] = H5S_UNLIMITED; two_dee_max_dims[0] = two_dee_max_dims[1] = H5S_UNLIMITED; + + if(s->test_3d) { + three_dee_max_dims[0] = H5S_UNLIMITED; + three_dee_max_dims[1] = s->rows; + three_dee_max_dims[2] = s->cols; + } } if (s->vds != vds_off) { - const hsize_t half_chunk_dims[RANK] = {s->rows / 2, s->cols / 2}; - hsize_t half_max_dims[RANK]; + const hsize_t half_chunk_dims[RANK2] = {s->rows / 2, s->cols / 2}; + hsize_t half_max_dims[RANK2]; if (s->fixed_array) { half_max_dims[0] = s->rows / 2; @@ -451,7 +506,7 @@ state_init(state_t *s, int argc, char **argv) TEST_ERROR; } - if (H5Pset_chunk(s->quadrant_dcpl, RANK, half_chunk_dims) < 0) { + if (H5Pset_chunk(s->quadrant_dcpl, RANK2, half_chunk_dims) < 0) { fprintf(stderr, "H5Pset_chunk failed\n"); TEST_ERROR; } @@ -501,33 +556,32 @@ state_init(state_t *s, int argc, char **argv) .block = {s->rows / 2, s->cols / 2}, .count = {1, H5S_UNLIMITED}}; - if ((src->space = H5Screate_simple(RANK, half_chunk_dims, half_max_dims)) < 0) { + if ((src->space = H5Screate_simple(RANK2, half_chunk_dims, half_max_dims)) < 0) { fprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; } - if (H5Sselect_hyperslab(src->space, H5S_SELECT_SET, src->start, src->stride, src->count, src->block) < - 0) { + if (H5Sselect_hyperslab(src->space, H5S_SELECT_SET, src->start, src->stride, src->count, src->block) < 0) { fprintf(stderr, "H5Sselect_hyperslab failed\n"); TEST_ERROR; } - if ((ul->src_space = H5Screate_simple(RANK, half_chunk_dims, half_max_dims)) < 0) { + if ((ul->src_space = H5Screate_simple(RANK2, half_chunk_dims, half_max_dims)) < 0) { fprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; } - if ((ur->src_space = H5Screate_simple(RANK, half_chunk_dims, half_max_dims)) < 0) { + if ((ur->src_space = H5Screate_simple(RANK2, half_chunk_dims, half_max_dims)) < 0) { fprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; } - if ((bl->src_space = H5Screate_simple(RANK, half_chunk_dims, half_max_dims)) < 0) { + if ((bl->src_space = H5Screate_simple(RANK2, half_chunk_dims, half_max_dims)) < 0) { fprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; } - if ((br->src_space = H5Screate_simple(RANK, half_chunk_dims, half_max_dims)) < 0) { + if ((br->src_space = H5Screate_simple(RANK2, half_chunk_dims, half_max_dims)) < 0) { fprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; } @@ -554,9 +608,18 @@ state_init(state_t *s, int argc, char **argv) s->sources[i].ul = s->sources[i].ur = s->sources[i].bl = s->sources[i].br = badhid; } - if ((s->memspace = H5Screate_simple(RANK, s->chunk_dims, NULL)) < 0) { - fprintf(stderr, "H5Screate_simple failed\n"); - TEST_ERROR; + if (s->test_3d) { + hsize_t dims3[RANK3] = {1, s->chunk_dims[0], s->chunk_dims[1]}; + + if ((s->memspace = H5Screate_simple(RANK3, dims3, NULL)) < 0) { + fprintf(stderr, "H5Screate_simple failed\n"); + TEST_ERROR; + } + } else { + if ((s->memspace = H5Screate_simple(RANK2, s->chunk_dims, NULL)) < 0) { + fprintf(stderr, "H5Screate_simple failed\n"); + TEST_ERROR; + } } s->filename[0] = "vfd_swmr_bigset.h5"; @@ -600,8 +663,7 @@ state_init(state_t *s, int argc, char **argv) return true; error: - H5E_BEGIN_TRY - { + H5E_BEGIN_TRY { H5Pclose(s->quadrant_dcpl); H5Sclose(ul->space); H5Sclose(ur->space); @@ -614,17 +676,13 @@ error: H5Sclose(src->space); H5Sclose(s->one_by_one_sid); H5Sclose(s->memspace); - } - H5E_END_TRY; + } H5E_END_TRY; - if (tfile) - HDfree(tfile); + HDfree(tfile); - if (s->dataset) - HDfree(s->dataset); + HDfree(s->dataset); - if (s->sources) - HDfree(s->sources); + HDfree(s->sources); return false; } @@ -633,6 +691,7 @@ static bool state_destroy(state_t *s) { size_t i; + struct timespec start_time, end_time; if (H5Pclose(s->dapl) < 0) { fprintf(stderr, "H5Pclose failed\n"); @@ -671,6 +730,14 @@ state_destroy(state_t *s) TEST_ERROR; } + /* For checking the time spent in file close. It's for running the writer alone */ + if (s->do_perf) { + if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { + fprintf(stderr, "HDclock_gettime failed"); + TEST_ERROR; + } + } + for (i = 0; i < NELMTS(s->file); i++) { hid_t fid = s->file[i]; @@ -685,28 +752,32 @@ state_destroy(state_t *s) } } - if (s->dataset) - HDfree(s->dataset); + /* For checking the time spent in file close. It's for running the writer alone */ + if (s->do_perf) { + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { + fprintf(stderr, "HDclock_gettime failed"); + TEST_ERROR; + } + + fprintf(stdout, "File close time (for running the writer alone) = %lf\n", TIME_PASSED(start_time, end_time)); + } + + HDfree(s->dataset); - if (s->sources) - HDfree(s->sources); + HDfree(s->sources); return true; error: - H5E_BEGIN_TRY - { + H5E_BEGIN_TRY { H5Pclose(s->quadrant_dcpl); H5Sclose(s->one_by_one_sid); H5Sclose(s->memspace); - } - H5E_END_TRY; + } H5E_END_TRY; - if (s->dataset) - HDfree(s->dataset); + HDfree(s->dataset); - if (s->sources) - HDfree(s->sources); + HDfree(s->sources); return false; } @@ -790,13 +861,13 @@ np_close(np_state_t *np, bool writer) } /* Reader finishes last and deletes the named pipes */ - if (!writer) { - if (HDremove(np->fifo_writer_to_reader) != 0) { + if(!writer) { + if(HDremove(np->fifo_writer_to_reader) != 0) { fprintf(stderr, "HDremove fifo_writer_to_reader failed\n"); TEST_ERROR; } - if (HDremove(np->fifo_reader_to_writer) != 0) { + if(HDremove(np->fifo_reader_to_writer) != 0) { fprintf(stderr, "HDremove fifo_reader_to_writer failed\n"); TEST_ERROR; } @@ -807,7 +878,7 @@ error: return false; } /* np_close() */ -/* Wait for the writer's notice before starting to zoo validation */ +/* Wait for the writer's notice before starting validation */ static int reader_verify(np_state_t np, int verify) { @@ -829,7 +900,7 @@ error: return -1; } -/* Notify the reader of finishing zoo creation by sending the timestamp +/* Notify the reader of finishing creation by sending the timestamp * and wait for the reader to finish validation before proceeding */ static int notify_and_wait_for_reader(state_t *s, np_state_t *np) @@ -838,13 +909,13 @@ notify_and_wait_for_reader(state_t *s, np_state_t *np) unsigned int i; struct timespec last = {0, 0}; - /* Get the time when finishing zoo creation */ + /* Get the time when finishing creation */ if (HDclock_gettime(CLOCK_MONOTONIC, &last) < 0) { fprintf(stderr, "HDclock_gettime failed\n"); TEST_ERROR; } - /* Notify the reader of finishing zoo creation by sending the timestamp */ + /* Notify the reader of finishing creation by sending the timestamp */ if (HDwrite(np->fd_writer_to_reader, &last, sizeof(last)) < 0) { fprintf(stderr, "HDwrite failed\n"); TEST_ERROR; @@ -855,14 +926,12 @@ notify_and_wait_for_reader(state_t *s, np_state_t *np) for (i = 0; i < MAX_LAG + 1; i++) { decisleep(TICK_LEN); - H5E_BEGIN_TRY - { + H5E_BEGIN_TRY { H5Aexists(s->file[0], "nonexistent"); - } - H5E_END_TRY; + } H5E_END_TRY; } - /* Wait until the reader finishes validating zoo creation */ + /* Wait until the reader finishes validating creation */ if (HDread(np->fd_reader_to_writer, ¬ify, sizeof(int)) < 0) { fprintf(stderr, "HDread failed\n"); TEST_ERROR; @@ -888,18 +957,18 @@ reader_check_time_and_notify_writer(np_state_t *np, state_t s) { struct timespec last = {0, 0}; - /* Receive the notice of the writer finishing zoo creation (timestamp) */ + /* Receive the notice of the writer finishing creation (timestamp) */ if (HDread(np->fd_writer_to_reader, &last, sizeof(last)) < 0) { fprintf(stderr, "HDread failed\n"); TEST_ERROR; } - /* Make sure the dataset validation doesn't take longer than the expected time. + /* If the dataset validation takes longer than the expected time, issue a warning. * This time period is from the writer finishing dataset creation to the reader finishing * the validation of dataset creation */ if (below_speed_limit(&last, &(s.ival))) { AT(); - fprintf(stderr, "dataset validation took too long to finish\n"); + fprintf(stderr, "Warning: dataset validation took too long to finish\n"); } /* Notify the writer that dataset validation is finished */ @@ -949,6 +1018,7 @@ create_extensible_dset(state_t *s, unsigned int which) char ul_dname[sizeof("/ul-dataset-9999999999")], ur_dname[sizeof("/ur-dataset-9999999999")], bl_dname[sizeof("/bl-dataset-9999999999")], br_dname[sizeof("/br-dataset-9999999999")]; hid_t dcpl = H5I_INVALID_HID, dset_id = H5I_INVALID_HID, filespace = H5I_INVALID_HID; + hsize_t dims3[3] = {1, s->chunk_dims[0], s->chunk_dims[1]}; esnprintf(dname, sizeof(dname), "/dataset-%d", which); @@ -957,9 +1027,17 @@ create_extensible_dset(state_t *s, unsigned int which) TEST_ERROR; } - if (H5Pset_chunk(dcpl, RANK, s->chunk_dims) < 0) { - fprintf(stderr, "H5Pset_chunk failed\n"); - TEST_ERROR; + if (s->test_3d) { + /* The chunk is 1 x M x N and grows along the first dimension */ + if (H5Pset_chunk(dcpl, RANK3, dims3) < 0) { + fprintf(stderr, "H5Pset_chunk for 3D dataset failed\n"); + TEST_ERROR; + } + } else { + if (H5Pset_chunk(dcpl, RANK2, s->chunk_dims) < 0) { + fprintf(stderr, "H5Pset_chunk for 2D dataset failed\n"); + TEST_ERROR; + } } if (s->vds != vds_off) { @@ -970,26 +1048,22 @@ create_extensible_dset(state_t *s, unsigned int which) esnprintf(bl_dname, sizeof(bl_dname), "/bl-dataset-%d", which); esnprintf(br_dname, sizeof(br_dname), "/br-dataset-%d", which); - if ((srcs->ul = H5Dcreate2(s->file[0], ul_dname, s->filetype, ul->src_space, H5P_DEFAULT, - s->quadrant_dcpl, s->dapl)) < 0) { + if ((srcs->ul = H5Dcreate2(s->file[0], ul_dname, s->filetype, ul->src_space, H5P_DEFAULT, s->quadrant_dcpl, s->dapl)) < 0) { fprintf(stderr, "H5Dcreate2 failed\n"); TEST_ERROR; } - if ((srcs->ur = H5Dcreate2(s->file[1], ur_dname, s->filetype, ur->src_space, H5P_DEFAULT, - s->quadrant_dcpl, s->dapl)) < 0) { + if ((srcs->ur = H5Dcreate2(s->file[1], ur_dname, s->filetype, ur->src_space, H5P_DEFAULT, s->quadrant_dcpl, s->dapl)) < 0) { fprintf(stderr, "H5Dcreate2 failed\n"); TEST_ERROR; } - if ((srcs->bl = H5Dcreate2(s->file[2], bl_dname, s->filetype, bl->src_space, H5P_DEFAULT, - s->quadrant_dcpl, s->dapl)) < 0) { + if ((srcs->bl = H5Dcreate2(s->file[2], bl_dname, s->filetype, bl->src_space, H5P_DEFAULT, s->quadrant_dcpl, s->dapl)) < 0) { fprintf(stderr, "H5Dcreate2 failed\n"); TEST_ERROR; } - if ((srcs->br = H5Dcreate2(s->file[3], br_dname, s->filetype, br->src_space, H5P_DEFAULT, - s->quadrant_dcpl, s->dapl)) < 0) { + if ((srcs->br = H5Dcreate2(s->file[3], br_dname, s->filetype, br->src_space, H5P_DEFAULT, s->quadrant_dcpl, s->dapl)) < 0) { fprintf(stderr, "H5Dcreate2 failed\n"); TEST_ERROR; } @@ -1015,10 +1089,17 @@ create_extensible_dset(state_t *s, unsigned int which) } } - if ((filespace = H5Screate_simple(NELMTS(s->chunk_dims), s->chunk_dims, - s->two_dee ? two_dee_max_dims : s->one_dee_max_dims)) < 0) { - fprintf(stderr, "H5Screate_simple failed\n"); - TEST_ERROR; + if (s->test_3d) { + if ((filespace = H5Screate_simple(RANK3, dims3, three_dee_max_dims)) < 0) { + fprintf(stderr, "H5Screate_simple 3D dataspace failed\n"); + TEST_ERROR; + } + } else { + if ((filespace = H5Screate_simple(RANK2, s->chunk_dims, + s->expand_2d ? two_dee_max_dims : s->one_dee_max_dims)) < 0) { + fprintf(stderr, "H5Screate_simple 2D dataspace failed\n"); + TEST_ERROR; + } } if ((dset_id = H5Dcreate2(s->file[0], dname, s->filetype, filespace, H5P_DEFAULT, dcpl, s->dapl)) < 0) { @@ -1041,13 +1122,11 @@ create_extensible_dset(state_t *s, unsigned int which) return true; error: - H5E_BEGIN_TRY - { + H5E_BEGIN_TRY { H5Dclose(dset_id); H5Pclose(dcpl); H5Sclose(filespace); - } - H5E_END_TRY; + } H5E_END_TRY; return false; } @@ -1087,11 +1166,9 @@ close_extensible_dset(state_t *s, unsigned int which) return true; error: - H5E_BEGIN_TRY - { + H5E_BEGIN_TRY { H5Dclose(dset_id); - } - H5E_END_TRY; + } H5E_END_TRY; return false; } @@ -1099,9 +1176,11 @@ error: static bool open_extensible_dset(state_t *s) { - hsize_t dims[RANK], maxdims[RANK]; + hsize_t dims2[RANK2], maxdims2[RANK2]; + hsize_t dims3[RANK3], maxdims3[RANK3]; char dname[sizeof("/dataset-9999999999")]; hid_t dset_id, filespace, dtype; + int rank; unsigned int which, i; for (which = 0; which < s->ndatasets; which++) { @@ -1111,11 +1190,9 @@ open_extensible_dset(state_t *s) * NUM_ATTEMPTS times without success, report it as a failure */ for (i = 0; i < NUM_ATTEMPTS; i++) { - H5E_BEGIN_TRY - { + H5E_BEGIN_TRY { dset_id = H5Dopen2(s->file[0], dname, s->dapl); - } - H5E_END_TRY; + } H5E_END_TRY; if (dset_id >= 0) break; @@ -1143,16 +1220,28 @@ open_extensible_dset(state_t *s) TEST_ERROR; } - if (H5Sget_simple_extent_ndims(filespace) != RANK) { - fprintf(stderr, "Unexpected data rank\n"); + if ((rank = H5Sget_simple_extent_ndims(filespace)) < 0) { + fprintf(stderr, "H5Sget_simple_extent_ndims failed\n"); TEST_ERROR; } - if (H5Sget_simple_extent_dims(filespace, dims, maxdims) < 0) { - fprintf(stderr, "H5Sget_simple_extent_dims failed\n"); + if ((s->test_3d && rank != RANK3) || (!s->test_3d && rank != RANK2)) { + fprintf(stderr, "Unexpected data rank: %d\n", rank); TEST_ERROR; } + if (s->test_3d) { + if (H5Sget_simple_extent_dims(filespace, dims3, maxdims3) < 0) { + fprintf(stderr, "H5Sget_simple_extent_dims failed\n"); + TEST_ERROR; + } + } else { + if (H5Sget_simple_extent_dims(filespace, dims2, maxdims2) < 0) { + fprintf(stderr, "H5Sget_simple_extent_dims failed\n"); + TEST_ERROR; + } + } + if (H5Sclose(filespace) < 0) { fprintf(stderr, "H5Sclose failed\n"); TEST_ERROR; @@ -1163,19 +1252,27 @@ open_extensible_dset(state_t *s) TEST_ERROR; } - if (s->two_dee) { - if (maxdims[0] != two_dee_max_dims[0] || maxdims[1] != two_dee_max_dims[1] || - maxdims[0] != maxdims[1]) { - fprintf(stderr, "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE, maxdims[0], - maxdims[1]); + 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]) { + fprintf(stderr, "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE " x %" PRIuHSIZE, + maxdims3[0], maxdims3[1], maxdims3[2]); TEST_ERROR; } - } - else if (maxdims[0] != s->one_dee_max_dims[0] || maxdims[1] != s->one_dee_max_dims[1] || - dims[0] != s->chunk_dims[0]) { - fprintf(stderr, - "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE " or columns %" PRIuHSIZE, - maxdims[0], maxdims[1], dims[1]); + } else { + if (s->expand_2d) { + if (maxdims2[0] != two_dee_max_dims[0] || maxdims2[1] != two_dee_max_dims[1] || + maxdims2[0] != maxdims2[1]) { + fprintf(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]) { + fprintf(stderr, + "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE " or columns %" PRIuHSIZE, + maxdims2[0], maxdims2[1], dims2[1]); + } } s->dataset[which] = dset_id; @@ -1184,14 +1281,51 @@ open_extensible_dset(state_t *s) return true; error: - H5E_BEGIN_TRY - { + H5E_BEGIN_TRY { H5Dclose(dset_id); H5Tclose(dtype); H5Sclose(filespace); + } H5E_END_TRY; + + return false; +} + +static bool +create_dsets(state_t s) +{ + struct timespec start_time, end_time; + unsigned int which; + + /* For checking the time spent in dataset creation. It's for running the writer alone */ + if (s.do_perf) { + if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { + fprintf(stderr, "HDclock_gettime failed"); + TEST_ERROR; + } + } + + /* Create NDATASETS datasets as the reader is doing verification. So no communication with + * the reader during the creation of datasets. + */ + for (which = 0; which < s.ndatasets; which++) + if (!create_extensible_dset(&s, which)) { + fprintf(stderr, "create_extensible_dset failed: number %u\n", which); + TEST_ERROR; + } + + /* For checking the time spent in dataset creation. It's for running the writer alone */ + if (s.do_perf) { + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { + fprintf(stderr, "HDclock_gettime failed"); + TEST_ERROR; + } + + fprintf(stdout, "Dataset creation time (for running the writer alone) = %lf\n", TIME_PASSED(start_time, end_time)); } - H5E_END_TRY; + return true; + +error: return false; } @@ -1244,8 +1378,7 @@ set_or_verify_matrix(mat_t *mat, unsigned int which, base_t base, bool do_set) ret = false; break; } - } - else if (matget(mat, row, col) != v) { + } else if (matget(mat, row, col) != v) { /* If the data doesn't match, simply return false and * let the caller repeat this step */ @@ -1273,7 +1406,9 @@ verify_matrix(mat_t *mat, unsigned int which, base_t base) static bool verify_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t base) { - hsize_t offset[RANK] = {base.row, base.col}; + hsize_t offset2[RANK2] = {base.row, base.col}; + hsize_t offset3[RANK3] = {base.depth, base.row, base.col}; + hsize_t count3[RANK3] = {1, s->chunk_dims[0], s->chunk_dims[1]}; herr_t status; hid_t dset_id; @@ -1282,23 +1417,31 @@ verify_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t bas TEST_ERROR; } - dbgf(1, "verifying chunk %" PRIuHSIZE ", %" PRIuHSIZE "\n", base.row, base.col); + if (s->test_3d) + dbgf(1, "verifying chunk %" PRIuHSIZE ", %" PRIuHSIZE ", %" PRIuHSIZE "\n", base.row, base.col, base.depth); + else + dbgf(1, "verifying chunk %" PRIuHSIZE ", %" PRIuHSIZE "\n", base.row, base.col); dset_id = s->dataset[which]; - if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL, s->chunk_dims, NULL) < 0) { - fprintf(stderr, "H5Sselect_hyperslab failed\n"); - TEST_ERROR; + if (s->test_3d) { + if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset3, NULL, count3, NULL) < 0) { + fprintf(stderr, "H5Sselect_hyperslab failed\n"); + TEST_ERROR; + } + } else { + if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset2, NULL, s->chunk_dims, NULL) < 0) { + fprintf(stderr, "H5Sselect_hyperslab failed\n"); + TEST_ERROR; + } } - /* A failure to read the data may indicate the data isn't ready yet. Instead of displaying the error - * stack, simply return false and let the caller repeat this step. + /* A failure to read the data may indicate the data isn't ready yet. Instead of displaying the error stack, + * simply return false and let the caller repeat this step. */ - H5E_BEGIN_TRY - { + H5E_BEGIN_TRY { status = H5Dread(dset_id, H5T_NATIVE_UINT32, s->memspace, filespace, H5P_DEFAULT, mat->elt); - } - H5E_END_TRY; + } H5E_END_TRY; if (status < 0) TEST_ERROR; @@ -1309,6 +1452,7 @@ error: return false; } +/* Try to verify a chunk NUM_ATTEMPTS times until the data is correct */ static bool repeat_verify_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t base) { @@ -1344,7 +1488,9 @@ error: static bool init_and_write_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t base) { - hsize_t offset[RANK] = {base.row, base.col}; + hsize_t offset2[RANK2] = {base.row, base.col}; + hsize_t offset3[RANK3] = {base.depth, base.row, base.col}; + hsize_t count3[RANK3] = {1, s->chunk_dims[0], s->chunk_dims[1]}; hid_t dset_id; dset_id = s->dataset[which]; @@ -1354,9 +1500,17 @@ init_and_write_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, ba TEST_ERROR; } - if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL, s->chunk_dims, NULL) < 0) { - fprintf(stderr, "H5Sselect_hyperslab failed\n"); - TEST_ERROR; + if (s->test_3d) { + /* The chunk dimensions are 1 x M x N. It grows along the first dimension */ + if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset3, NULL, count3, NULL) < 0) { + fprintf(stderr, "H5Sselect_hyperslab for 2D dataset failed\n"); + TEST_ERROR; + } + } else { + if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset2, NULL, s->chunk_dims, NULL) < 0) { + fprintf(stderr, "H5Sselect_hyperslab for 2D dataset failed\n"); + TEST_ERROR; + } } if (H5Dwrite(dset_id, H5T_NATIVE_UINT32, s->memspace, filespace, H5P_DEFAULT, mat->elt) < 0) { @@ -1404,11 +1558,9 @@ verify_dset_attribute(hid_t dset_id, unsigned int which, unsigned int step) return true; error: - H5E_BEGIN_TRY - { + H5E_BEGIN_TRY { H5Aclose(aid); - } - H5E_END_TRY; + } H5E_END_TRY; return false; } @@ -1417,9 +1569,9 @@ static bool verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned finished_step, unsigned last_step) { hid_t dset_id = H5I_INVALID_HID, filespace = H5I_INVALID_HID; - hsize_t size[RANK]; + hsize_t size2[RANK2], size3[RANK3]; base_t base, last; - unsigned int ncols, step; + unsigned int nchunks, step, ofs; int i; if (which >= s->ndatasets) { @@ -1441,15 +1593,24 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini TEST_ERROR; } - if (H5Sget_simple_extent_dims(filespace, size, NULL) < 0) { - fprintf(stderr, "H5Sget_simple_extent_dims failed\n"); - TEST_ERROR; - } + if (s->test_3d) { + if (H5Sget_simple_extent_dims(filespace, size3, NULL) < 0) { + fprintf(stderr, "H5Sget_simple_extent_dims failed\n"); + TEST_ERROR; + } - ncols = (unsigned)(size[1] / s->chunk_dims[1]); + nchunks = (unsigned)size3[0]; + } else { + if (H5Sget_simple_extent_dims(filespace, size2, NULL) < 0) { + fprintf(stderr, "H5Sget_simple_extent_dims failed\n"); + TEST_ERROR; + } + + nchunks = (unsigned)(size2[1] / s->chunk_dims[1]); + } /* Make sure the chunks show up on the reader side. Otherwise sleep a while and try again */ - if (ncols >= last_step) + if (nchunks >= last_step) break; else decisleep(1); @@ -1463,24 +1624,52 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini for (step = finished_step; step < last_step; step++) { dbgf(1, "%s: which %u step %u\n", __func__, which, step); - if (s->two_dee) { - size[0] = s->chunk_dims[0] * (1 + step); - size[1] = s->chunk_dims[1] * (1 + step); - last.row = s->chunk_dims[0] * step; - last.col = s->chunk_dims[1] * step; - } - else { - size[0] = s->chunk_dims[0]; - size[1] = s->chunk_dims[1] * (1 + step); + /* Read data that randomly crosses over chunks. But it should not happen to + * the last chunk being written + */ + if (s->cross_chunks) { + if (step == last_step - 1) + ofs = 0; + else + ofs = step % 2; + } else + ofs = 0; + + if (s->test_3d) { + size3[0] = 1 + step; + size3[1] = s->chunk_dims[0]; + size3[2] = s->chunk_dims[1]; + last.depth = step; last.row = 0; - last.col = s->chunk_dims[1] * step; + last.col = 0; + } else { + if (s->expand_2d) { + size2[0] = s->chunk_dims[0] * (1 + step); + size2[1] = s->chunk_dims[1] * (1 + step); + last.row = s->chunk_dims[0] * step + ofs; + last.col = s->chunk_dims[1] * step + ofs; + } else { + size2[0] = s->chunk_dims[0]; + size2[1] = s->chunk_dims[1] * (1 + step); + last.row = 0; + last.col = s->chunk_dims[1] * step + ofs; + } } - dbgf(1, "new size %" PRIuHSIZE ", %" PRIuHSIZE "\n", size[0], size[1]); - dbgf(1, "last row %" PRIuHSIZE " col %" PRIuHSIZE "\n", last.row, last.col); - - if (s->two_dee) { + if (s->test_3d) { + dbgf(1, "new size3 %" PRIuHSIZE ", %" PRIuHSIZE ", %" PRIuHSIZE "\n", size3[0], size3[1], size3[2]); + dbgf(1, "last row %" PRIuHSIZE " col %" PRIuHSIZE " depth %" PRIuHSIZE "\n", last.row, last.col, last.depth); + } else { + dbgf(1, "new size2 %" PRIuHSIZE ", %" PRIuHSIZE "\n", size2[0], size2[1]); + dbgf(1, "last row %" PRIuHSIZE " col %" PRIuHSIZE "\n", last.row, last.col); + } + if (s->test_3d || !s->expand_2d) { + if (!repeat_verify_chunk(s, filespace, mat, which, last)) { + fprintf(stderr, "chunk verification failed\n"); + TEST_ERROR; + } + } else { /* Down the right side, intersecting the bottom row. */ base.col = last.col; for (base.row = 0; base.row <= last.row; base.row += s->chunk_dims[0]) { @@ -1501,12 +1690,6 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini } } } - else { - if (!repeat_verify_chunk(s, filespace, mat, which, last)) { - fprintf(stderr, "chunk verification failed\n"); - TEST_ERROR; - } - } if (s->asteps != 0 && step % s->asteps == 0) { if (!verify_dset_attribute(dset_id, which, step)) { @@ -1519,11 +1702,9 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini return true; error: - H5E_BEGIN_TRY - { + H5E_BEGIN_TRY { H5Sclose(filespace); - } - H5E_END_TRY; + } H5E_END_TRY; return false; } @@ -1531,18 +1712,15 @@ error: static bool verify_dsets(state_t s, np_state_t *np, mat_t *mat) { - unsigned * nextstep = NULL; unsigned finished_step = 0; unsigned which; + unsigned counter = 0; + double passed_time = 0.0, total_time = 0.0, min_time = 1000000.0, max_time = 0.0; exchange_info_t last; - - if (!(nextstep = HDcalloc(s.ndatasets, sizeof(*nextstep)))) { - fprintf(stderr, "memory allocation failed\n"); - TEST_ERROR; - } + struct timespec end_time; do { - /* Receive the notice of the writer finishing zoo creation, + /* Receive the notice of the writer finishing creation, * including the number of chunks finished and the timestamp */ if (s.use_named_pipe && HDread(np->fd_writer_to_reader, &last, sizeof(last)) < 0) { @@ -1551,8 +1729,6 @@ verify_dsets(state_t s, np_state_t *np, mat_t *mat) } for (which = 0; which < s.ndatasets; which++) { - dbgf(1, "step %d which %d\n", nextstep[which], which); - /* Verify the chunks starting from the finished one in last round * to the ones written in this round */ @@ -1572,17 +1748,36 @@ verify_dsets(state_t s, np_state_t *np, mat_t *mat) AT(); fprintf(stderr, "verify_extensible_dset took too long to finish\n"); } + + /* For checking the time lapse between the writer's finishing writing a batch of chunks + * within a tick and the reader's finishing verifying those chunks + */ + if (s.use_named_pipe && s.do_perf) { + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { + fprintf(stderr, "HDclock_gettime failed"); + TEST_ERROR; + } + + counter++; + passed_time = TIME_PASSED(last.time, end_time); + + total_time += passed_time; + + if (passed_time > max_time) + max_time = passed_time; + + if (passed_time < min_time) + min_time = passed_time; + } } while (finished_step < s.nsteps); - if (nextstep) - HDfree(nextstep); + /* Print out the performance information */ + if (s.use_named_pipe && s.do_perf && counter) + fprintf(stdout, "Dataset verification: mean time = %lf, max time = %lf, min time = %lf\n", total_time / (double)counter, max_time, min_time); return true; error: - if (nextstep) - HDfree(nextstep); - return false; } @@ -1614,11 +1809,9 @@ add_dset_attribute(const state_t *s, hid_t ds, hid_t sid, unsigned int which, un return true; error: - H5E_BEGIN_TRY - { + H5E_BEGIN_TRY { H5Aclose(aid); - } - H5E_END_TRY; + } H5E_END_TRY; return false; } @@ -1627,7 +1820,7 @@ static bool write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t *mat) { hid_t dset_id = H5I_INVALID_HID, filespace = H5I_INVALID_HID; - hsize_t size[RANK]; + hsize_t size2[RANK2], size3[RANK3]; base_t base, last; char dname[sizeof("/dataset-9999999999")]; @@ -1649,23 +1842,35 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * } } - if (s->two_dee) { - size[0] = s->chunk_dims[0] * (1 + step); - size[1] = s->chunk_dims[1] * (1 + step); - last.row = s->chunk_dims[0] * step; - last.col = s->chunk_dims[1] * step; - } - else { - size[0] = s->chunk_dims[0]; - size[1] = s->chunk_dims[1] * (1 + step); + if (s->test_3d) { + size3[0] = 1 + step; + size3[1] = s->chunk_dims[0]; + size3[2] = s->chunk_dims[1]; + last.depth = step; last.row = 0; - last.col = s->chunk_dims[1] * step; + last.col = 0; + } else { + if (s->expand_2d) { + size2[0] = s->chunk_dims[0] * (1 + step); + size2[1] = s->chunk_dims[1] * (1 + step); + last.row = s->chunk_dims[0] * step; + last.col = s->chunk_dims[1] * step; + } else { + size2[0] = s->chunk_dims[0]; + size2[1] = s->chunk_dims[1] * (1 + step); + last.row = 0; + last.col = s->chunk_dims[1] * step; + } + last.depth = 0; } - dbgf(1, "new size %" PRIuHSIZE ", %" PRIuHSIZE "\n", size[0], size[1]); + if (s->test_3d) + dbgf(1, "new size %" PRIuHSIZE ", %" PRIuHSIZE ", %" PRIuHSIZE "\n", size3[0], size3[1], size3[2]); + else + dbgf(1, "new size %" PRIuHSIZE ", %" PRIuHSIZE "\n", size2[0], size2[1]); if (s->vds != vds_off) { - const hsize_t half_size[RANK] = {size[0] / 2, size[1] / 2}; + const hsize_t half_size[RANK2] = {size2[0] / 2, size2[1] / 2}; sources_t *const srcs = &s->sources[which]; if (H5Dset_extent(srcs->ul, half_size) < 0) { @@ -1687,10 +1892,18 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * fprintf(stderr, "H5Dset_extent failed\n"); TEST_ERROR; } - } - else if (H5Dset_extent(dset_id, size) < 0) { - fprintf(stderr, "H5Dset_extent failed\n"); - TEST_ERROR; + } else { + if (s->test_3d) { + if (H5Dset_extent(dset_id, size3) < 0) { + fprintf(stderr, "H5Dset_extent for 3D dataset failed\n"); + TEST_ERROR; + } + } else { + if (H5Dset_extent(dset_id, size2) < 0) { + fprintf(stderr, "H5Dset_extent for 2D dataset failed\n"); + TEST_ERROR; + } + } } if ((filespace = H5Dget_space(dset_id)) < 0) { @@ -1698,8 +1911,14 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * TEST_ERROR; } - if (s->two_dee) { + if (s->test_3d || !s->expand_2d) { + if (!init_and_write_chunk(s, filespace, mat, which, last)) { + fprintf(stderr, "init_and_write_chunk failed\n"); + TEST_ERROR; + } + } else if (s->expand_2d) { base.col = last.col; + base.depth = 0; for (base.row = 0; base.row <= last.row; base.row += s->chunk_dims[0]) { dbgf(1, "writing chunk %" PRIuHSIZE ", %" PRIuHSIZE "\n", base.row, base.col); if (!init_and_write_chunk(s, filespace, mat, which, base)) { @@ -1717,12 +1936,6 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * } } } - else { - if (!init_and_write_chunk(s, filespace, mat, which, last)) { - fprintf(stderr, "init_and_write_chunk failed\n"); - TEST_ERROR; - } - } if (H5Sclose(filespace) < 0) { fprintf(stderr, "H5Sclose failed\n"); @@ -1732,11 +1945,9 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * return true; error: - H5E_BEGIN_TRY - { + H5E_BEGIN_TRY { H5Sclose(filespace); - } - H5E_END_TRY; + } H5E_END_TRY; return false; } @@ -1744,15 +1955,24 @@ error: static bool write_dsets(state_t s, np_state_t *np, mat_t *mat) { - unsigned last_step, step, which; + unsigned last_step, step, which; unsigned long long old_tick_num; - H5F_t * f = NULL; + H5F_t *f = NULL; + struct timespec start_time, end_time; if (NULL == (f = (H5F_t *)H5VL_object(s.file[0]))) { fprintf(stderr, "H5VL_object failed\n"); TEST_ERROR; } + /* For checking the time spent in writing data. It's for running the writer alone */ + if (s.do_perf) { + if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { + fprintf(stderr, "HDclock_gettime failed"); + TEST_ERROR; + } + } + old_tick_num = f->shared->tick_num; /* Write as many as chunks within the same tick number before notifying @@ -1772,13 +1992,13 @@ write_dsets(state_t s, np_state_t *np, mat_t *mat) /* After finishing writing all the chunks, end the tick */ if (s.use_vfd_swmr && step == (s.nsteps - 1)) { - unsigned long i; + unsigned long i; - if (s.vds != vds_multi) - H5Fvfd_swmr_end_tick(s.file[0]); - else - for (i = 0; i < NELMTS(s.file); i++) - H5Fvfd_swmr_end_tick(s.file[i]); + if (s.vds != vds_multi) + H5Fvfd_swmr_end_tick(s.file[0]); + else + for (i = 0; i < NELMTS(s.file); i++) + H5Fvfd_swmr_end_tick(s.file[i]); } /* Notify the reader to start verification by @@ -1795,6 +2015,16 @@ write_dsets(state_t s, np_state_t *np, mat_t *mat) } } + /* For checking the time spent in writing data. It's for running the writer alone */ + if (s.do_perf) { + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { + fprintf(stderr, "HDclock_gettime failed"); + TEST_ERROR; + } + + fprintf(stdout, "Dataset write time (for running the writer alone) = %lf\n", TIME_PASSED(start_time, end_time)); + } + return true; error: @@ -1804,7 +2034,7 @@ error: int main(int argc, char **argv) { - mat_t * mat; + mat_t *mat; hid_t fcpl = H5I_INVALID_HID; unsigned which; state_t s; @@ -1877,32 +2107,28 @@ main(int argc, char **argv) TEST_ERROR; } - /* Create NDATASETS datasets as the reader is doing verification. So no communication with - * the reader during the creation of datasets. - */ - for (which = 0; which < s.ndatasets; which++) - if (!create_extensible_dset(&s, which)) { - fprintf(stderr, "create_extensible_dset failed: number %u\n", which); - TEST_ERROR; - } + /* Creates multiple datasets */ + if (!create_dsets(s)) { + fprintf(stderr, "create_dsets failed"); + TEST_ERROR; + } /* Call H5Fvfd_swmr_end_tick to end the tick. No communication with the reader in this step */ if (s.use_vfd_swmr && s.use_named_pipe) { - unsigned long j; - - if (s.vds != vds_multi) { - if (H5Fvfd_swmr_end_tick(s.file[0]) < 0) { - fprintf(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) { - fprintf(stderr, "H5Fvfd_swmr_end_tick failed\n"); - TEST_ERROR; - } - } + unsigned long j; + + if (s.vds != vds_multi) { + if (H5Fvfd_swmr_end_tick(s.file[0]) < 0) { + fprintf(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) { + fprintf(stderr, "H5Fvfd_swmr_end_tick failed\n"); + TEST_ERROR; + } + } } /* Notify the reader of finishing dataset creation by sending the timestamp @@ -1919,8 +2145,7 @@ main(int argc, char **argv) fprintf(stderr, "write_dsets failed"); TEST_ERROR; } - } - else { + } else { /* Wait for the writer's notice before starting the validation of dataset creation */ np.verify = 1; if (s.use_named_pipe && reader_verify(np, np.verify) < 0) { @@ -1981,14 +2206,12 @@ main(int argc, char **argv) return EXIT_SUCCESS; error: - H5E_BEGIN_TRY - { + H5E_BEGIN_TRY { H5Pclose(fcpl); for (i = 0; i < NELMTS(s.file); i++) H5Fclose(s.file[i]); - } - H5E_END_TRY; + } H5E_END_TRY; if (s.use_named_pipe && np.fd_writer_to_reader >= 0) HDclose(np.fd_writer_to_reader); -- cgit v0.12 From 082de1cb75edd1e63269c9c6e1953a2e418d770e Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 8 Jul 2021 16:20:33 +0000 Subject: Committing clang-format changes --- test/vfd_swmr_bigset_writer.c | 396 ++++++++++++++++++++++++------------------ 1 file changed, 230 insertions(+), 166 deletions(-) diff --git a/test/vfd_swmr_bigset_writer.c b/test/vfd_swmr_bigset_writer.c index 48981d5..2f86d64 100644 --- a/test/vfd_swmr_bigset_writer.c +++ b/test/vfd_swmr_bigset_writer.c @@ -95,7 +95,7 @@ * X is the beginning time; Y is the ending time. * Expects X, Y to be struct timespec from the function call HDclock_gettime. */ -#define TIME_PASSED(X,Y) \ +#define TIME_PASSED(X, Y) \ ((double)((Y.tv_sec - X.tv_sec) * 1000000000 + (Y.tv_nsec - X.tv_nsec))) / 1000000000.0 typedef struct _base { @@ -122,13 +122,13 @@ typedef struct _sources { #define MANY_FILES 4 typedef struct { - hid_t *dataset; - sources_t *sources; - hid_t file[MANY_FILES]; - hid_t dapl, filetype, memspace, one_by_one_sid, quadrant_dcpl; - unsigned ndatasets; + hid_t * dataset; + sources_t * sources; + hid_t file[MANY_FILES]; + hid_t dapl, filetype, memspace, one_by_one_sid, quadrant_dcpl; + unsigned ndatasets; const char *filename[MANY_FILES]; - char progname[PATH_MAX]; + char progname[PATH_MAX]; struct { quadrant_t ul, ur, bl, br, src; } quadrants; @@ -138,25 +138,25 @@ typedef struct { bool expand_2d; bool test_3d; enum { vds_off, vds_single, vds_multi } vds; - bool use_vfd_swmr; - bool use_named_pipe; - bool do_perf; - bool cross_chunks; - bool writer; - bool fixed_array; - hsize_t chunk_dims[RANK2]; - hsize_t one_dee_max_dims[RANK2]; + bool use_vfd_swmr; + bool use_named_pipe; + bool do_perf; + bool cross_chunks; + bool writer; + bool fixed_array; + hsize_t chunk_dims[RANK2]; + hsize_t one_dee_max_dims[RANK2]; struct timespec ival; } state_t; /* Structure to hold info for named pipes */ typedef struct { - const char *fifo_writer_to_reader; /* Name of fifo for writer to reader */ - const char *fifo_reader_to_writer; /* Name of fifo for reader to writer */ - int fd_writer_to_reader; /* File ID for fifo from writer to reader */ - int fd_reader_to_writer; /* File ID for fifo from reader to writer */ - int notify; /* Value to notify between writer and reader */ - int verify; /* Value to verify between writer and reader */ + const char *fifo_writer_to_reader; /* Name of fifo for writer to reader */ + const char *fifo_reader_to_writer; /* Name of fifo for reader to writer */ + int fd_writer_to_reader; /* File ID for fifo from writer to reader */ + int fd_reader_to_writer; /* File ID for fifo from reader to writer */ + int notify; /* Value to notify between writer and reader */ + int verify; /* Value to verify between writer and reader */ } np_state_t; typedef struct { @@ -165,14 +165,13 @@ typedef struct { } exchange_info_t; /* Initializations for np_state_t */ -#define NP_INITIALIZER (np_state_t) { \ - .fifo_writer_to_reader = "./fifo_bigset_writer_to_reader", \ - .fifo_reader_to_writer = "./fifo_bigset_reader_to_writer", \ - .fd_writer_to_reader = -1, \ - .fd_reader_to_writer = -1, \ - .notify = 0, \ - .verify = 0 \ -} +#define NP_INITIALIZER \ + (np_state_t) \ + { \ + .fifo_writer_to_reader = "./fifo_bigset_writer_to_reader", \ + .fifo_reader_to_writer = "./fifo_bigset_reader_to_writer", .fd_writer_to_reader = -1, \ + .fd_reader_to_writer = -1, .notify = 0, .verify = 0 \ + } static inline state_t state_initializer(void) @@ -291,7 +290,7 @@ static bool make_quadrant_dataspace(state_t *s, quadrant_t *q) { if ((q->space = H5Screate_simple(NELMTS(s->chunk_dims), s->chunk_dims, - s->expand_2d ? two_dee_max_dims : s->one_dee_max_dims)) < 0) { + s->expand_2d ? two_dee_max_dims : s->one_dee_max_dims)) < 0) { fprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; } @@ -304,9 +303,11 @@ make_quadrant_dataspace(state_t *s, quadrant_t *q) return true; error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Sclose(q->space); - } H5E_END_TRY; + } + H5E_END_TRY; return false; } @@ -317,8 +318,8 @@ state_init(state_t *s, int argc, char **argv) unsigned long tmp; int ch; unsigned i; - const hsize_t dims = 1; - char *tfile = NULL; + const hsize_t dims = 1; + char * tfile = NULL; char * end; quadrant_t *const ul = &s->quadrants.ul, *const ur = &s->quadrants.ur, *const bl = &s->quadrants.bl, *const br = &s->quadrants.br, *const src = &s->quadrants.src; @@ -406,12 +407,13 @@ state_init(state_t *s, int argc, char **argv) else if (ch == 'l') { /* Translate the tick number to time represented by the timespec struct */ float time = (float)(((unsigned)tmp * TICK_LEN) / 10.0); - unsigned sec = (unsigned)time; + unsigned sec = (unsigned)time; unsigned nsec = (unsigned)((time - sec) * 10 * 1000 * 1000); - s->ival.tv_sec = sec; + s->ival.tv_sec = sec; s->ival.tv_nsec = nsec; - } else if (ch == 'n') + } + else if (ch == 'n') s->nsteps = (unsigned)tmp; else if (ch == 'r') s->rows = (unsigned)tmp; @@ -463,8 +465,8 @@ state_init(state_t *s, int argc, char **argv) } } - s->chunk_dims[0] = s->rows; - s->chunk_dims[1] = s->cols; + s->chunk_dims[0] = s->rows; + s->chunk_dims[1] = s->cols; s->one_dee_max_dims[0] = s->rows; if (s->fixed_array) { @@ -472,16 +474,17 @@ state_init(state_t *s, int argc, char **argv) two_dee_max_dims[0] = s->rows * s->nsteps; two_dee_max_dims[1] = s->cols * s->nsteps; - if(s->test_3d) { + if (s->test_3d) { three_dee_max_dims[0] = s->nsteps; three_dee_max_dims[1] = s->rows; three_dee_max_dims[2] = s->cols; } - } else { + } + else { s->one_dee_max_dims[1] = H5S_UNLIMITED; two_dee_max_dims[0] = two_dee_max_dims[1] = H5S_UNLIMITED; - if(s->test_3d) { + if (s->test_3d) { three_dee_max_dims[0] = H5S_UNLIMITED; three_dee_max_dims[1] = s->rows; three_dee_max_dims[2] = s->cols; @@ -561,7 +564,8 @@ state_init(state_t *s, int argc, char **argv) TEST_ERROR; } - if (H5Sselect_hyperslab(src->space, H5S_SELECT_SET, src->start, src->stride, src->count, src->block) < 0) { + if (H5Sselect_hyperslab(src->space, H5S_SELECT_SET, src->start, src->stride, src->count, src->block) < + 0) { fprintf(stderr, "H5Sselect_hyperslab failed\n"); TEST_ERROR; } @@ -609,13 +613,14 @@ state_init(state_t *s, int argc, char **argv) } if (s->test_3d) { - hsize_t dims3[RANK3] = {1, s->chunk_dims[0], s->chunk_dims[1]}; + hsize_t dims3[RANK3] = {1, s->chunk_dims[0], s->chunk_dims[1]}; - if ((s->memspace = H5Screate_simple(RANK3, dims3, NULL)) < 0) { + if ((s->memspace = H5Screate_simple(RANK3, dims3, NULL)) < 0) { fprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; - } - } else { + } + } + else { if ((s->memspace = H5Screate_simple(RANK2, s->chunk_dims, NULL)) < 0) { fprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; @@ -663,7 +668,8 @@ state_init(state_t *s, int argc, char **argv) return true; error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Pclose(s->quadrant_dcpl); H5Sclose(ul->space); H5Sclose(ur->space); @@ -676,7 +682,8 @@ error: H5Sclose(src->space); H5Sclose(s->one_by_one_sid); H5Sclose(s->memspace); - } H5E_END_TRY; + } + H5E_END_TRY; HDfree(tfile); @@ -690,7 +697,7 @@ error: static bool state_destroy(state_t *s) { - size_t i; + size_t i; struct timespec start_time, end_time; if (H5Pclose(s->dapl) < 0) { @@ -759,7 +766,8 @@ state_destroy(state_t *s) TEST_ERROR; } - fprintf(stdout, "File close time (for running the writer alone) = %lf\n", TIME_PASSED(start_time, end_time)); + fprintf(stdout, "File close time (for running the writer alone) = %lf\n", + TIME_PASSED(start_time, end_time)); } HDfree(s->dataset); @@ -769,11 +777,13 @@ state_destroy(state_t *s) return true; error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Pclose(s->quadrant_dcpl); H5Sclose(s->one_by_one_sid); H5Sclose(s->memspace); - } H5E_END_TRY; + } + H5E_END_TRY; HDfree(s->dataset); @@ -861,13 +871,13 @@ np_close(np_state_t *np, bool writer) } /* Reader finishes last and deletes the named pipes */ - if(!writer) { - if(HDremove(np->fifo_writer_to_reader) != 0) { + if (!writer) { + if (HDremove(np->fifo_writer_to_reader) != 0) { fprintf(stderr, "HDremove fifo_writer_to_reader failed\n"); TEST_ERROR; } - if(HDremove(np->fifo_reader_to_writer) != 0) { + if (HDremove(np->fifo_reader_to_writer) != 0) { fprintf(stderr, "HDremove fifo_reader_to_writer failed\n"); TEST_ERROR; } @@ -926,9 +936,11 @@ notify_and_wait_for_reader(state_t *s, np_state_t *np) for (i = 0; i < MAX_LAG + 1; i++) { decisleep(TICK_LEN); - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Aexists(s->file[0], "nonexistent"); - } H5E_END_TRY; + } + H5E_END_TRY; } /* Wait until the reader finishes validating creation */ @@ -1017,7 +1029,7 @@ create_extensible_dset(state_t *s, unsigned int which) char dname[sizeof("/dataset-9999999999")]; char ul_dname[sizeof("/ul-dataset-9999999999")], ur_dname[sizeof("/ur-dataset-9999999999")], bl_dname[sizeof("/bl-dataset-9999999999")], br_dname[sizeof("/br-dataset-9999999999")]; - hid_t dcpl = H5I_INVALID_HID, dset_id = H5I_INVALID_HID, filespace = H5I_INVALID_HID; + hid_t dcpl = H5I_INVALID_HID, dset_id = H5I_INVALID_HID, filespace = H5I_INVALID_HID; hsize_t dims3[3] = {1, s->chunk_dims[0], s->chunk_dims[1]}; esnprintf(dname, sizeof(dname), "/dataset-%d", which); @@ -1033,7 +1045,8 @@ create_extensible_dset(state_t *s, unsigned int which) fprintf(stderr, "H5Pset_chunk for 3D dataset failed\n"); TEST_ERROR; } - } else { + } + else { if (H5Pset_chunk(dcpl, RANK2, s->chunk_dims) < 0) { fprintf(stderr, "H5Pset_chunk for 2D dataset failed\n"); TEST_ERROR; @@ -1048,22 +1061,26 @@ create_extensible_dset(state_t *s, unsigned int which) esnprintf(bl_dname, sizeof(bl_dname), "/bl-dataset-%d", which); esnprintf(br_dname, sizeof(br_dname), "/br-dataset-%d", which); - if ((srcs->ul = H5Dcreate2(s->file[0], ul_dname, s->filetype, ul->src_space, H5P_DEFAULT, s->quadrant_dcpl, s->dapl)) < 0) { + if ((srcs->ul = H5Dcreate2(s->file[0], ul_dname, s->filetype, ul->src_space, H5P_DEFAULT, + s->quadrant_dcpl, s->dapl)) < 0) { fprintf(stderr, "H5Dcreate2 failed\n"); TEST_ERROR; } - if ((srcs->ur = H5Dcreate2(s->file[1], ur_dname, s->filetype, ur->src_space, H5P_DEFAULT, s->quadrant_dcpl, s->dapl)) < 0) { + if ((srcs->ur = H5Dcreate2(s->file[1], ur_dname, s->filetype, ur->src_space, H5P_DEFAULT, + s->quadrant_dcpl, s->dapl)) < 0) { fprintf(stderr, "H5Dcreate2 failed\n"); TEST_ERROR; } - if ((srcs->bl = H5Dcreate2(s->file[2], bl_dname, s->filetype, bl->src_space, H5P_DEFAULT, s->quadrant_dcpl, s->dapl)) < 0) { + if ((srcs->bl = H5Dcreate2(s->file[2], bl_dname, s->filetype, bl->src_space, H5P_DEFAULT, + s->quadrant_dcpl, s->dapl)) < 0) { fprintf(stderr, "H5Dcreate2 failed\n"); TEST_ERROR; } - if ((srcs->br = H5Dcreate2(s->file[3], br_dname, s->filetype, br->src_space, H5P_DEFAULT, s->quadrant_dcpl, s->dapl)) < 0) { + if ((srcs->br = H5Dcreate2(s->file[3], br_dname, s->filetype, br->src_space, H5P_DEFAULT, + s->quadrant_dcpl, s->dapl)) < 0) { fprintf(stderr, "H5Dcreate2 failed\n"); TEST_ERROR; } @@ -1094,9 +1111,10 @@ create_extensible_dset(state_t *s, unsigned int which) fprintf(stderr, "H5Screate_simple 3D dataspace failed\n"); TEST_ERROR; } - } else { + } + else { if ((filespace = H5Screate_simple(RANK2, s->chunk_dims, - s->expand_2d ? two_dee_max_dims : s->one_dee_max_dims)) < 0) { + s->expand_2d ? two_dee_max_dims : s->one_dee_max_dims)) < 0) { fprintf(stderr, "H5Screate_simple 2D dataspace failed\n"); TEST_ERROR; } @@ -1122,11 +1140,13 @@ create_extensible_dset(state_t *s, unsigned int which) return true; error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Dclose(dset_id); H5Pclose(dcpl); H5Sclose(filespace); - } H5E_END_TRY; + } + H5E_END_TRY; return false; } @@ -1166,9 +1186,11 @@ close_extensible_dset(state_t *s, unsigned int which) return true; error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Dclose(dset_id); - } H5E_END_TRY; + } + H5E_END_TRY; return false; } @@ -1190,9 +1212,11 @@ open_extensible_dset(state_t *s) * NUM_ATTEMPTS times without success, report it as a failure */ for (i = 0; i < NUM_ATTEMPTS; i++) { - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { dset_id = H5Dopen2(s->file[0], dname, s->dapl); - } H5E_END_TRY; + } + H5E_END_TRY; if (dset_id >= 0) break; @@ -1235,7 +1259,8 @@ open_extensible_dset(state_t *s) fprintf(stderr, "H5Sget_simple_extent_dims failed\n"); TEST_ERROR; } - } else { + } + else { if (H5Sget_simple_extent_dims(filespace, dims2, maxdims2) < 0) { fprintf(stderr, "H5Sget_simple_extent_dims failed\n"); TEST_ERROR; @@ -1256,22 +1281,25 @@ open_extensible_dset(state_t *s) if (maxdims3[0] != three_dee_max_dims[0] || maxdims3[1] != three_dee_max_dims[1] || maxdims3[2] != three_dee_max_dims[2]) { fprintf(stderr, "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE " x %" PRIuHSIZE, - maxdims3[0], maxdims3[1], maxdims3[2]); + maxdims3[0], maxdims3[1], maxdims3[2]); TEST_ERROR; } - } else { + } + else { if (s->expand_2d) { if (maxdims2[0] != two_dee_max_dims[0] || maxdims2[1] != two_dee_max_dims[1] || maxdims2[0] != maxdims2[1]) { fprintf(stderr, "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE, maxdims2[0], - maxdims2[1]); + 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]) { + } + else if (maxdims2[0] != s->one_dee_max_dims[0] || maxdims2[1] != s->one_dee_max_dims[1] || + dims2[0] != s->chunk_dims[0]) { fprintf(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]); } } @@ -1281,11 +1309,13 @@ open_extensible_dset(state_t *s) return true; error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Dclose(dset_id); H5Tclose(dtype); H5Sclose(filespace); - } H5E_END_TRY; + } + H5E_END_TRY; return false; } @@ -1294,7 +1324,7 @@ static bool create_dsets(state_t s) { struct timespec start_time, end_time; - unsigned int which; + unsigned int which; /* For checking the time spent in dataset creation. It's for running the writer alone */ if (s.do_perf) { @@ -1320,7 +1350,8 @@ create_dsets(state_t s) TEST_ERROR; } - fprintf(stdout, "Dataset creation time (for running the writer alone) = %lf\n", TIME_PASSED(start_time, end_time)); + fprintf(stdout, "Dataset creation time (for running the writer alone) = %lf\n", + TIME_PASSED(start_time, end_time)); } return true; @@ -1378,7 +1409,8 @@ set_or_verify_matrix(mat_t *mat, unsigned int which, base_t base, bool do_set) ret = false; break; } - } else if (matget(mat, row, col) != v) { + } + else if (matget(mat, row, col) != v) { /* If the data doesn't match, simply return false and * let the caller repeat this step */ @@ -1408,7 +1440,7 @@ verify_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t bas { hsize_t offset2[RANK2] = {base.row, base.col}; hsize_t offset3[RANK3] = {base.depth, base.row, base.col}; - hsize_t count3[RANK3] = {1, s->chunk_dims[0], s->chunk_dims[1]}; + hsize_t count3[RANK3] = {1, s->chunk_dims[0], s->chunk_dims[1]}; herr_t status; hid_t dset_id; @@ -1418,7 +1450,8 @@ verify_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t bas } if (s->test_3d) - dbgf(1, "verifying chunk %" PRIuHSIZE ", %" PRIuHSIZE ", %" PRIuHSIZE "\n", base.row, base.col, base.depth); + dbgf(1, "verifying chunk %" PRIuHSIZE ", %" PRIuHSIZE ", %" PRIuHSIZE "\n", base.row, base.col, + base.depth); else dbgf(1, "verifying chunk %" PRIuHSIZE ", %" PRIuHSIZE "\n", base.row, base.col); @@ -1429,19 +1462,22 @@ verify_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t bas fprintf(stderr, "H5Sselect_hyperslab failed\n"); TEST_ERROR; } - } else { + } + else { if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset2, NULL, s->chunk_dims, NULL) < 0) { fprintf(stderr, "H5Sselect_hyperslab failed\n"); TEST_ERROR; } } - /* A failure to read the data may indicate the data isn't ready yet. Instead of displaying the error stack, - * simply return false and let the caller repeat this step. + /* A failure to read the data may indicate the data isn't ready yet. Instead of displaying the error + * stack, simply return false and let the caller repeat this step. */ - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { status = H5Dread(dset_id, H5T_NATIVE_UINT32, s->memspace, filespace, H5P_DEFAULT, mat->elt); - } H5E_END_TRY; + } + H5E_END_TRY; if (status < 0) TEST_ERROR; @@ -1490,7 +1526,7 @@ init_and_write_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, ba { hsize_t offset2[RANK2] = {base.row, base.col}; hsize_t offset3[RANK3] = {base.depth, base.row, base.col}; - hsize_t count3[RANK3] = {1, s->chunk_dims[0], s->chunk_dims[1]}; + hsize_t count3[RANK3] = {1, s->chunk_dims[0], s->chunk_dims[1]}; hid_t dset_id; dset_id = s->dataset[which]; @@ -1501,12 +1537,13 @@ init_and_write_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, ba } if (s->test_3d) { - /* The chunk dimensions are 1 x M x N. It grows along the first dimension */ + /* The chunk dimensions are 1 x M x N. It grows along the first dimension */ if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset3, NULL, count3, NULL) < 0) { fprintf(stderr, "H5Sselect_hyperslab for 2D dataset failed\n"); TEST_ERROR; } - } else { + } + else { if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset2, NULL, s->chunk_dims, NULL) < 0) { fprintf(stderr, "H5Sselect_hyperslab for 2D dataset failed\n"); TEST_ERROR; @@ -1558,9 +1595,11 @@ verify_dset_attribute(hid_t dset_id, unsigned int which, unsigned int step) return true; error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Aclose(aid); - } H5E_END_TRY; + } + H5E_END_TRY; return false; } @@ -1600,7 +1639,8 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini } nchunks = (unsigned)size3[0]; - } else { + } + else { if (H5Sget_simple_extent_dims(filespace, size2, NULL) < 0) { fprintf(stderr, "H5Sget_simple_extent_dims failed\n"); TEST_ERROR; @@ -1632,34 +1672,40 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini ofs = 0; else ofs = step % 2; - } else + } + else ofs = 0; if (s->test_3d) { - size3[0] = 1 + step; - size3[1] = s->chunk_dims[0]; - size3[2] = s->chunk_dims[1]; + size3[0] = 1 + step; + size3[1] = s->chunk_dims[0]; + size3[2] = s->chunk_dims[1]; last.depth = step; - last.row = 0; - last.col = 0; - } else { + last.row = 0; + last.col = 0; + } + else { if (s->expand_2d) { - size2[0] = s->chunk_dims[0] * (1 + step); - size2[1] = s->chunk_dims[1] * (1 + step); + size2[0] = s->chunk_dims[0] * (1 + step); + size2[1] = s->chunk_dims[1] * (1 + step); last.row = s->chunk_dims[0] * step + ofs; last.col = s->chunk_dims[1] * step + ofs; - } else { - size2[0] = s->chunk_dims[0]; - size2[1] = s->chunk_dims[1] * (1 + step); + } + else { + size2[0] = s->chunk_dims[0]; + size2[1] = s->chunk_dims[1] * (1 + step); last.row = 0; last.col = s->chunk_dims[1] * step + ofs; } } if (s->test_3d) { - dbgf(1, "new size3 %" PRIuHSIZE ", %" PRIuHSIZE ", %" PRIuHSIZE "\n", size3[0], size3[1], size3[2]); - dbgf(1, "last row %" PRIuHSIZE " col %" PRIuHSIZE " depth %" PRIuHSIZE "\n", last.row, last.col, last.depth); - } else { + dbgf(1, "new size3 %" PRIuHSIZE ", %" PRIuHSIZE ", %" PRIuHSIZE "\n", size3[0], size3[1], + size3[2]); + dbgf(1, "last row %" PRIuHSIZE " col %" PRIuHSIZE " depth %" PRIuHSIZE "\n", last.row, last.col, + last.depth); + } + else { dbgf(1, "new size2 %" PRIuHSIZE ", %" PRIuHSIZE "\n", size2[0], size2[1]); dbgf(1, "last row %" PRIuHSIZE " col %" PRIuHSIZE "\n", last.row, last.col); } @@ -1669,7 +1715,8 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini fprintf(stderr, "chunk verification failed\n"); TEST_ERROR; } - } else { + } + else { /* Down the right side, intersecting the bottom row. */ base.col = last.col; for (base.row = 0; base.row <= last.row; base.row += s->chunk_dims[0]) { @@ -1702,9 +1749,11 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini return true; error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Sclose(filespace); - } H5E_END_TRY; + } + H5E_END_TRY; return false; } @@ -1714,7 +1763,7 @@ verify_dsets(state_t s, np_state_t *np, mat_t *mat) { unsigned finished_step = 0; unsigned which; - unsigned counter = 0; + unsigned counter = 0; double passed_time = 0.0, total_time = 0.0, min_time = 1000000.0, max_time = 0.0; exchange_info_t last; struct timespec end_time; @@ -1773,7 +1822,8 @@ 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) - fprintf(stdout, "Dataset verification: mean time = %lf, max time = %lf, min time = %lf\n", total_time / (double)counter, max_time, min_time); + fprintf(stdout, "Dataset verification: mean time = %lf, max time = %lf, min time = %lf\n", + total_time / (double)counter, max_time, min_time); return true; @@ -1809,9 +1859,11 @@ add_dset_attribute(const state_t *s, hid_t ds, hid_t sid, unsigned int which, un return true; error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Aclose(aid); - } H5E_END_TRY; + } + H5E_END_TRY; return false; } @@ -1843,21 +1895,23 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * } if (s->test_3d) { - size3[0] = 1 + step; - size3[1] = s->chunk_dims[0]; - size3[2] = s->chunk_dims[1]; + size3[0] = 1 + step; + size3[1] = s->chunk_dims[0]; + size3[2] = s->chunk_dims[1]; last.depth = step; - last.row = 0; - last.col = 0; - } else { + last.row = 0; + last.col = 0; + } + else { if (s->expand_2d) { - size2[0] = s->chunk_dims[0] * (1 + step); - size2[1] = s->chunk_dims[1] * (1 + step); + size2[0] = s->chunk_dims[0] * (1 + step); + size2[1] = s->chunk_dims[1] * (1 + step); last.row = s->chunk_dims[0] * step; last.col = s->chunk_dims[1] * step; - } else { - size2[0] = s->chunk_dims[0]; - size2[1] = s->chunk_dims[1] * (1 + step); + } + else { + size2[0] = s->chunk_dims[0]; + size2[1] = s->chunk_dims[1] * (1 + step); last.row = 0; last.col = s->chunk_dims[1] * step; } @@ -1871,7 +1925,7 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * if (s->vds != vds_off) { const hsize_t half_size[RANK2] = {size2[0] / 2, size2[1] / 2}; - sources_t *const srcs = &s->sources[which]; + sources_t *const srcs = &s->sources[which]; if (H5Dset_extent(srcs->ul, half_size) < 0) { fprintf(stderr, "H5Dset_extent failed\n"); @@ -1892,13 +1946,15 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * fprintf(stderr, "H5Dset_extent failed\n"); TEST_ERROR; } - } else { + } + else { if (s->test_3d) { if (H5Dset_extent(dset_id, size3) < 0) { fprintf(stderr, "H5Dset_extent for 3D dataset failed\n"); TEST_ERROR; } - } else { + } + else { if (H5Dset_extent(dset_id, size2) < 0) { fprintf(stderr, "H5Dset_extent for 2D dataset failed\n"); TEST_ERROR; @@ -1916,8 +1972,9 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * fprintf(stderr, "init_and_write_chunk failed\n"); TEST_ERROR; } - } else if (s->expand_2d) { - base.col = last.col; + } + else if (s->expand_2d) { + base.col = last.col; base.depth = 0; for (base.row = 0; base.row <= last.row; base.row += s->chunk_dims[0]) { dbgf(1, "writing chunk %" PRIuHSIZE ", %" PRIuHSIZE "\n", base.row, base.col); @@ -1945,9 +2002,11 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * return true; error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Sclose(filespace); - } H5E_END_TRY; + } + H5E_END_TRY; return false; } @@ -1955,10 +2014,10 @@ error: static bool write_dsets(state_t s, np_state_t *np, mat_t *mat) { - unsigned last_step, step, which; + unsigned last_step, step, which; unsigned long long old_tick_num; - H5F_t *f = NULL; - struct timespec start_time, end_time; + H5F_t * f = NULL; + struct timespec start_time, end_time; if (NULL == (f = (H5F_t *)H5VL_object(s.file[0]))) { fprintf(stderr, "H5VL_object failed\n"); @@ -1992,13 +2051,13 @@ write_dsets(state_t s, np_state_t *np, mat_t *mat) /* After finishing writing all the chunks, end the tick */ if (s.use_vfd_swmr && step == (s.nsteps - 1)) { - unsigned long i; + unsigned long i; - if (s.vds != vds_multi) - H5Fvfd_swmr_end_tick(s.file[0]); - else - for (i = 0; i < NELMTS(s.file); i++) - H5Fvfd_swmr_end_tick(s.file[i]); + if (s.vds != vds_multi) + H5Fvfd_swmr_end_tick(s.file[0]); + else + for (i = 0; i < NELMTS(s.file); i++) + H5Fvfd_swmr_end_tick(s.file[i]); } /* Notify the reader to start verification by @@ -2022,7 +2081,8 @@ write_dsets(state_t s, np_state_t *np, mat_t *mat) TEST_ERROR; } - fprintf(stdout, "Dataset write time (for running the writer alone) = %lf\n", TIME_PASSED(start_time, end_time)); + fprintf(stdout, "Dataset write time (for running the writer alone) = %lf\n", + TIME_PASSED(start_time, end_time)); } return true; @@ -2034,7 +2094,7 @@ error: int main(int argc, char **argv) { - mat_t *mat; + mat_t * mat; hid_t fcpl = H5I_INVALID_HID; unsigned which; state_t s; @@ -2115,20 +2175,21 @@ main(int argc, char **argv) /* Call H5Fvfd_swmr_end_tick to end the tick. No communication with the reader in this step */ if (s.use_vfd_swmr && s.use_named_pipe) { - unsigned long j; - - if (s.vds != vds_multi) { - if (H5Fvfd_swmr_end_tick(s.file[0]) < 0) { - fprintf(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) { - fprintf(stderr, "H5Fvfd_swmr_end_tick failed\n"); - TEST_ERROR; - } - } + unsigned long j; + + if (s.vds != vds_multi) { + if (H5Fvfd_swmr_end_tick(s.file[0]) < 0) { + fprintf(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) { + fprintf(stderr, "H5Fvfd_swmr_end_tick failed\n"); + TEST_ERROR; + } + } } /* Notify the reader of finishing dataset creation by sending the timestamp @@ -2145,7 +2206,8 @@ main(int argc, char **argv) fprintf(stderr, "write_dsets failed"); TEST_ERROR; } - } else { + } + else { /* Wait for the writer's notice before starting the validation of dataset creation */ np.verify = 1; if (s.use_named_pipe && reader_verify(np, np.verify) < 0) { @@ -2206,12 +2268,14 @@ main(int argc, char **argv) return EXIT_SUCCESS; error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Pclose(fcpl); for (i = 0; i < NELMTS(s.file); i++) H5Fclose(s.file[i]); - } H5E_END_TRY; + } + H5E_END_TRY; if (s.use_named_pipe && np.fd_writer_to_reader >= 0) HDclose(np.fd_writer_to_reader); -- cgit v0.12 From cab2b3fc5fa4b430a55b75ac36649b3a484f74d2 Mon Sep 17 00:00:00 2001 From: Songyu Lu Date: Thu, 8 Jul 2021 12:06:26 -0500 Subject: Some minor corrections and adjustments. --- test/testvfdswmr.sh.in | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/test/testvfdswmr.sh.in b/test/testvfdswmr.sh.in index d187d97..6095c03 100644 --- a/test/testvfdswmr.sh.in +++ b/test/testvfdswmr.sh.in @@ -1006,9 +1006,6 @@ for options in ${os_grp_op_list[*]}; do rm -f vfd_swmr_group_reader.*.{out,rc} done -# bigset test for smaller chunks -======= - ############################################################################### # # Setting for bigset (few_big and many_small) tests @@ -1026,8 +1023,8 @@ BIGSET_many_s=100 # -s option: # of datasets (for many_small t # Setting for exhaustive and quick runs # if [[ "$HDF5TestExpress" -eq 0 ]] ; then # exhaustive run - BIGSET_n=50 - BIGSET_few_s=40 + BIGSET_n=200 + BIGSET_few_s=100 BIGSET_many_s=1000 elif [[ "$HDF5TestExpress" -gt 1 ]]; then # quick run BIGSET_n=10 @@ -1036,15 +1033,14 @@ elif [[ "$HDF5TestExpress" -gt 1 ]]; then # quick run fi # # - -for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-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" "-d 2 -F" "-d 1 -t" "-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. # - # Perform 25 iterations on 200 extensible datasets configured with + # Perform 25 iterations on 100 extensible datasets configured with # 16x16 chunks of 32-bit unsigned integer elements, # expanding each dataset by a chunk in one dimension (up to 50x1 # 16x16 chunks) on each iteration. @@ -1061,8 +1057,8 @@ for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-d 1 -V" "-d 1 -M" "-d 1 -V -F ../vfd_swmr_bigset_reader -n $BIGSET_n $options -s $BIGSET_many_s -r 16 -c 16 -q -l 6 & pid_reader=$! - # Wait for the reader to finish before the - # writer quits: the writer holds the file open so that the + # Wait for the reader to finish before signalling the + # writer to quit: the writer holds the file open so that the # reader will find the shadow file when it opens # the .h5 file. wait $pid_reader @@ -1086,11 +1082,11 @@ for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-d 1 -V" "-d 1 -M" "-d 1 -V -F done # bigset test for bigger chunks -for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-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" "-d 2 -F" "-d 1 -t" "-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. # - # Perform 25 iterations on 20 extensible datasets configured with + # Perform 25 iterations on 10 extensible datasets configured with # 256x256 chunks of 32-bit unsigned integer elements, # expanding each dataset by a chunk in one dimension (up to 50x1 # 256x256 chunks) on each iteration. @@ -1110,8 +1106,8 @@ for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-d 1 -V" "-d 1 -M" "-d 1 -V -F ../vfd_swmr_bigset_reader -n $BIGSET_n $options -s $BIGSET_few_s -r 256 -c 256 -q -l 3 & pid_reader=$! - # Wait for the reader to finish before the - # writer quits: the writer holds the file open so that the + # Wait for the reader to finish before signalling the + # writer to quit: the writer holds the file open so that the # reader will find the shadow file when it opens # the .h5 file. wait $pid_reader -- cgit v0.12 From 0bfc2b7f707f4f272e9a67c031ea96b9e7b63247 Mon Sep 17 00:00:00 2001 From: Songyu Lu Date: Thu, 15 Jul 2021 09:49:29 -0500 Subject: Minor change: move the end tick function to just before the file is closed. --- test/vfd_swmr_bigset_writer.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/test/vfd_swmr_bigset_writer.c b/test/vfd_swmr_bigset_writer.c index 23f2125..9c05fa6 100644 --- a/test/vfd_swmr_bigset_writer.c +++ b/test/vfd_swmr_bigset_writer.c @@ -737,6 +737,17 @@ state_destroy(state_t *s) TEST_ERROR; } + /* The writer ends the tick before closing the file to make the data visible to the reader */ + if (s->writer && s->use_vfd_swmr) { + unsigned long j; + + if (s->vds != vds_multi) + H5Fvfd_swmr_end_tick(s->file[0]); + else + for (j = 0; j < NELMTS(s->file); j++) + H5Fvfd_swmr_end_tick(s->file[j]); + } + /* For checking the time spent in file close. It's for running the writer alone */ if (s->do_perf) { if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { @@ -2049,17 +2060,6 @@ write_dsets(state_t s, np_state_t *np, mat_t *mat) } } - /* After finishing writing all the chunks, end the tick */ - if (s.use_vfd_swmr && step == (s.nsteps - 1)) { - unsigned long i; - - if (s.vds != vds_multi) - H5Fvfd_swmr_end_tick(s.file[0]); - else - for (i = 0; i < NELMTS(s.file); i++) - H5Fvfd_swmr_end_tick(s.file[i]); - } - /* Notify the reader to start verification by * sending the timestamp and the number of chunks written */ -- cgit v0.12 From 77321a55641a0520a887a6065cca9d335502f739 Mon Sep 17 00:00:00 2001 From: Songyu Lu Date: Wed, 1 Sep 2021 11:08:15 -0500 Subject: Some important updates to the test: added test for 3D datasets and several new command-line options. --- test/testvfdswmr.sh.in | 32 +- test/vfd_swmr_bigset_writer.c | 666 +++++++++++++++++++++++++++++------------- 2 files changed, 488 insertions(+), 210 deletions(-) diff --git a/test/testvfdswmr.sh.in b/test/testvfdswmr.sh.in index ac54968..5a3b0f7 100644 --- a/test/testvfdswmr.sh.in +++ b/test/testvfdswmr.sh.in @@ -1063,7 +1063,7 @@ elif [[ "$HDF5TestExpress" -gt 1 ]]; then # quick run fi # # -for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-d 1 -t" "-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" "-d 2 -F" "-d 1 -t" "-d 1 -t -F" "-d 1 -V" "-d 1 -M" "-d 1 -V -F" "-d 1 -M -F"; do if [ ${do_many_small:-no} = no ]; then continue fi @@ -1071,20 +1071,24 @@ for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-d 1 -t" "-d 1 -V" "-d 1 -M" " # Test many small datasets of one and two dimensions. # # Perform 25 iterations on 100 extensible datasets configured with - # 16x16 chunks of 32-bit unsigned integer elements, - # expanding each dataset by a chunk in one dimension (up to 50x1 + # 2D 16x16 chunks or 3D 8x16x16 chunks of 32-bit unsigned integer elements, + # expanding each dataset by a chunk in one dimension (up to 25x1 # 16x16 chunks) on each iteration. # # Perform the test again, extending each dataset - # in *two* dimensions (up to 50x50 16x16 chunks). + # 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) + # + 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 -r 16 -c 16 -q -l 6 & + ../vfd_swmr_bigset_writer -n $BIGSET_n $options -s $BIGSET_many_s -e 8 -r 16 -c 16 -q -l 6 & pid_writer=$! catch_out_err_and_rc vfd_swmr_bigset_reader \ - ../vfd_swmr_bigset_reader -n $BIGSET_n $options -s $BIGSET_many_s -r 16 -c 16 -q -l 6 & + ../vfd_swmr_bigset_reader -n $BIGSET_n $options -s $BIGSET_many_s -e 8 -r 16 -c 16 -q -l 6 & pid_reader=$! # Wait for the reader to finish before signalling the @@ -1112,28 +1116,32 @@ for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-d 1 -t" "-d 1 -V" "-d 1 -M" " done # bigset test for bigger chunks -for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-d 1 -t" "-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" "-d 2 -F" "-d 1 -t" "-d 1 -t -F" "-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. # # Perform 25 iterations on 10 extensible datasets configured with - # 256x256 chunks of 32-bit unsigned integer elements, - # expanding each dataset by a chunk in one dimension (up to 50x1 + # 2D 256x256 chunks or 3D 64x256x256 of 32-bit unsigned integer elements, + # expanding each dataset by a chunk in one dimension (up to 25x1 # 256x256 chunks) on each iteration. # # Perform the test again, extending each dataset - # in *two* dimensions (up to 50x50 256x256 chunks). + # 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) + # + if [ ${do_few_big:-no} = no ]; then continue 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 -r 256 -c 256 -q -l 3 & + ../vfd_swmr_bigset_writer -n $BIGSET_n $options -s $BIGSET_few_s -e 64 -r 256 -c 256 -q -l 3 & pid_writer=$! catch_out_err_and_rc vfd_swmr_bigset_reader \ - ../vfd_swmr_bigset_reader -n $BIGSET_n $options -s $BIGSET_few_s -r 256 -c 256 -q -l 3 & + ../vfd_swmr_bigset_reader -n $BIGSET_n $options -s $BIGSET_few_s -e 64 -r 256 -c 256 -q -l 3 & 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 61d552e..dc95cfb 100644 --- a/test/vfd_swmr_bigset_writer.c +++ b/test/vfd_swmr_bigset_writer.c @@ -38,9 +38,12 @@ * (or the width and height) of a chunk, and writes a test pattern to * the dataset on chunk boundaries. * + * For 3D dataset, the extension is always along the first dimension. + * It does not support VDS yet. + * * The reader should be started with the same user-selectable parameters * as the writer: iterations, number of datasets, chunk width and - * height, dimensions. + * height and depth, dimensions. * * The reader opens the same HDF5 file, reads and re-reads it until all * `n` datasets appear, and then reads and re-reads the datasets until @@ -72,7 +75,6 @@ #include "H5Cpkg.h" #include "H5Fpkg.h" -// #include "H5Iprivate.h" #include "H5HGprivate.h" #include "H5VLprivate.h" @@ -84,12 +86,15 @@ #define MAX_READ_LEN_IN_SECONDS 2 #define TICK_LEN 4 #define MAX_LAG 7 +#define FSP_SIZE 4096 +#define PAGE_BUF_SIZE 4096 #define ROWS 256 #define COLS 512 -#define DEPTHS 1 +#define DEPTH 1 #define RANK2 2 #define RANK3 3 #define NUM_ATTEMPTS 100 +#define SKIP_CHUNK 0 /* Calculate the time passed in seconds. * X is the beginning time; Y is the ending time. @@ -103,7 +108,7 @@ typedef struct _base { } base_t; typedef struct _mat { - unsigned rows, cols; + unsigned depth, rows, cols; uint32_t elt[1]; } mat_t; @@ -132,20 +137,31 @@ typedef struct { struct { quadrant_t ul, ur, bl, br, src; } quadrants; - unsigned int cols, rows; + unsigned int depth, cols, rows; unsigned int asteps; unsigned int nsteps; + unsigned int part_chunk; + unsigned int skip_chunk; + unsigned int over_extend; bool expand_2d; bool test_3d; enum { vds_off, vds_single, vds_multi } vds; bool use_vfd_swmr; bool use_named_pipe; bool do_perf; - bool cross_chunks; + bool cross_chunk_read; bool writer; bool fixed_array; + bool flush_raw_data; hsize_t chunk_dims[RANK2]; hsize_t one_dee_max_dims[RANK2]; + hsize_t fsp_size; + size_t page_buf_size; + uint32_t tick_len; + uint32_t max_lag; + unsigned mdc_init_size; + size_t chunk_cache_size; + unsigned int deflate_level; struct timespec ival; } state_t; @@ -182,11 +198,15 @@ state_initializer(void) .filetype = H5T_NATIVE_UINT32, .one_by_one_sid = H5I_INVALID_HID, .quadrant_dcpl = H5I_INVALID_HID, + .depth = DEPTH, .rows = ROWS, .cols = COLS, .ndatasets = 5, .asteps = 10, .nsteps = 100, + .part_chunk = 0, + .skip_chunk = SKIP_CHUNK, + .over_extend = 1, .filename = {"", "", "", ""}, .expand_2d = false, .test_3d = false, @@ -194,11 +214,19 @@ state_initializer(void) .use_vfd_swmr = true, .use_named_pipe = true, .do_perf = false, - .cross_chunks = false, + .cross_chunk_read = false, .writer = true, .fixed_array = false, .one_dee_max_dims = {ROWS, H5S_UNLIMITED}, .chunk_dims = {ROWS, COLS}, + .fsp_size = FSP_SIZE, + .page_buf_size = PAGE_BUF_SIZE, + .tick_len = TICK_LEN, + .max_lag = MAX_LAG, + .flush_raw_data = false, + .mdc_init_size = 0, + .chunk_cache_size = 0, + .deflate_level = 0, .ival = (struct timespec){.tv_sec = MAX_READ_LEN_IN_SECONDS, .tv_nsec = 0}}; } @@ -208,79 +236,48 @@ static const hid_t badhid = H5I_INVALID_HID; static hsize_t two_dee_max_dims[RANK2], three_dee_max_dims[RANK3]; -static uint32_t -matget(const mat_t *mat, unsigned i, unsigned j) -{ - return mat->elt[i * mat->cols + j]; -} - -static bool -matset(mat_t *mat, unsigned i, unsigned j, uint32_t v) -{ - if (i >= mat->rows || j >= mat->cols) { - fprintf(stderr, "index out of boundary\n"); - TEST_ERROR; - } - - mat->elt[i * mat->cols + j] = v; - - return true; - -error: - return false; -} - -static mat_t * -newmat(unsigned rows, unsigned cols) -{ - mat_t *mat; - - mat = HDmalloc(sizeof(*mat) + (rows * cols - 1) * sizeof(mat->elt[0])); - - if (mat == NULL) { - fprintf(stderr, "HDmalloc failed\n"); - TEST_ERROR; - } - - mat->rows = rows; - mat->cols = cols; - - return mat; - -error: - return NULL; -} - static void usage(const char *progname) { fprintf(stderr, - "usage: %s [-C] [-F] [-M] [-P] [-S] [-V] [-W] [-a steps] [-b] [-c cols]\n" - " [-d dims]\n" - " [-l tick_num] [-n iterations] [-r rows] [-s datasets]\n" - " [-t] [-u milliseconds]\n" + "usage: %s [-C] [-F] [-M] [-P] [-R] [-S] [-V] [-W] [-a steps] [-b] [-c cols]\n" + " [-d dims] [-e depth] [-f tick_len] [-g max_lag] [-j skip_chunk] [-k part_chunk]\n" + " [-l tick_num] [-n iterations] [-o page_buf_size] [-p fsp_size] [-r rows]\n" + " [-s datasets] [-t] [-u over_extend] [-v chunk_cache_size] [-w deflate_level]\n" "\n" - "-C: cross-over chunks during chunk verification\n" + "-C: cross-over chunk read during chunk verification\n" "-F: fixed maximal dimension for the chunked datasets\n" "-M: use virtual datasets and many source\n" " files\n" - "-P: do the performance measurement" + "-N: do not use named pipes\n" + "-P: do the performance measurement\n" + "-R: flush raw data\n" "-S: do not use VFD SWMR\n" "-V: use virtual datasets and a single\n" " source file\n" "-a steps: `steps` between adding attributes\n" "-b: write data in big-endian byte order\n" - "-c cols: `cols` columns per chunk\n" + "-c cols: `cols` columns of the chunk\n" "-d 1|one|2|two|both: select dataset expansion in one or\n" " both dimensions\n" + "-e depth: the first dimension of the 3D chunk\n" + "-f tick_len: tick length\n" + "-g max_lag: maximal lag\n" + "-j skip_chunk: skip the Nth (skip_chunk) chunks during chunk writing\n" + "-k part_chunk: the size for partial chunk write\n" "-l tick_num: expected maximal number of ticks from\n" " the writer's finishing creation to the reader's finishing validation\n" - "-N: do not use named pipes\n" + "-m mdc_init_size: the initial size of metadata cache in megabytes (must be between 1 and 32MB)\n" "-n iterations: how many times to expand each dataset\n" - "-r rows: `rows` rows per chunk\n" + "-o page_buf_size: page buffer size\n" + "-p fsp_size: file space page size\n" + "-r rows: `rows` rows of the chunk\n" "-s datasets: number of datasets to create\n" "-t: enable test for 3D datasets (dataset expansion is along one dimension)\n" " currently, 3D datasets isn't tested with VDS\n" + "-u over_extend: extend the size of the dataset in multiple chunks or partial chunks\n" + "-v chunk_cache_size: the size of raw data chunk cache in bytes\n" + "-w deflate_level: the level (0 - 9) of gzip compression\n" "\n", progname); exit(EXIT_FAILURE); @@ -321,6 +318,8 @@ state_init(state_t *s, int argc, char **argv) const hsize_t dims = 1; char * tfile = NULL; char * end; + size_t rdcc_nslots, rdcc_nbytes; + double rdcc_w0; quadrant_t *const ul = &s->quadrants.ul, *const ur = &s->quadrants.ur, *const bl = &s->quadrants.bl, *const br = &s->quadrants.br, *const src = &s->quadrants.src; const char *personality; @@ -336,11 +335,11 @@ state_init(state_t *s, int argc, char **argv) HDfree(tfile); - while ((ch = getopt(argc, argv, "CFMNPSVa:bc:d:l:n:qr:s:t")) != -1) { + while ((ch = getopt(argc, argv, "CFMNPRSVa: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 */ - s->cross_chunks = true; + s->cross_chunk_read = true; break; case 'F': /* The flag to indicate whether the maximal dimension of the chunked datasets is fixed or @@ -353,6 +352,9 @@ state_init(state_t *s, int argc, char **argv) case 'P': s->do_perf = true; break; + case 'R': + s->flush_raw_data = true; + break; case 'S': s->use_vfd_swmr = false; break; @@ -376,10 +378,21 @@ state_init(state_t *s, int argc, char **argv) break; case 'a': case 'c': + case 'e': + case 'f': + case 'g': + case 'j': + case 'k': case 'l': + case 'm': case 'n': + case 'o': + case 'p': case 'r': case 's': + case 'u': + case 'v': + case 'w': errno = 0; tmp = HDstrtoul(optarg, &end, 0); if (end == optarg || *end != '\0') { @@ -404,6 +417,16 @@ state_init(state_t *s, int argc, char **argv) s->asteps = (unsigned)tmp; else if (ch == 'c') s->cols = (unsigned)tmp; + else if (ch == 'e') + s->depth = (unsigned)tmp; + else if (ch == 'f') + s->tick_len = (unsigned)tmp; + else if (ch == 'g') + s->max_lag = (unsigned)tmp; + else if (ch == 'j') + s->skip_chunk = (unsigned)tmp; + else if (ch == 'k') + s->part_chunk = (unsigned)tmp; else if (ch == 'l') { /* Translate the tick number to time represented by the timespec struct */ float time = (float)(((unsigned)tmp * TICK_LEN) / 10.0); @@ -413,10 +436,22 @@ state_init(state_t *s, int argc, char **argv) s->ival.tv_sec = sec; s->ival.tv_nsec = nsec; } + else if (ch == 'm') + s->mdc_init_size = (unsigned)tmp; else if (ch == 'n') s->nsteps = (unsigned)tmp; + else if (ch == 'o') + s->page_buf_size = (unsigned)tmp; + else if (ch == 'p') + s->fsp_size = (unsigned)tmp; else if (ch == 'r') s->rows = (unsigned)tmp; + else if (ch == 'u') + s->over_extend = (unsigned)tmp; + else if (ch == 'v') + s->chunk_cache_size = (unsigned)tmp; + else if (ch == 'w') + s->deflate_level = (unsigned)tmp; else s->ndatasets = (unsigned)tmp; break; @@ -449,13 +484,13 @@ state_init(state_t *s, int argc, char **argv) } if (s->test_3d) { - if (s->expand_2d) { - fprintf(stderr, "3D dataset test doesn't support 2D expansion\n"); + if (s->depth < 1) { + fprintf(stderr, "The depth of 3D dataset can't be less than 1\n"); TEST_ERROR; } - if (s->cross_chunks) { - fprintf(stderr, "3D dataset test doesn't support cross-over chunks during verification\n"); + if (s->expand_2d) { + fprintf(stderr, "3D dataset test doesn't support 2D expansion\n"); TEST_ERROR; } @@ -475,7 +510,7 @@ state_init(state_t *s, int argc, char **argv) two_dee_max_dims[1] = s->cols * s->nsteps; if (s->test_3d) { - three_dee_max_dims[0] = s->nsteps; + three_dee_max_dims[0] = s->depth * s->nsteps; three_dee_max_dims[1] = s->rows; three_dee_max_dims[2] = s->cols; } @@ -597,7 +632,7 @@ state_init(state_t *s, int argc, char **argv) TEST_ERROR; } - if ((s->dataset = HDmalloc(sizeof(*s->dataset) * s->ndatasets)) == NULL) { + if ((s->dataset = HDmalloc(sizeof(hid_t) * s->ndatasets)) == NULL) { fprintf(stderr, "HDmalloc failed\n"); TEST_ERROR; } @@ -613,20 +648,46 @@ state_init(state_t *s, int argc, char **argv) } if (s->test_3d) { - hsize_t dims3[RANK3] = {1, s->chunk_dims[0], s->chunk_dims[1]}; + hsize_t dims3[RANK3] = {s->depth, s->chunk_dims[0], s->chunk_dims[1]}; + + if (s->part_chunk) + dims3[0] = s->part_chunk; if ((s->memspace = H5Screate_simple(RANK3, dims3, NULL)) < 0) { fprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; } - } - else { - if ((s->memspace = H5Screate_simple(RANK2, s->chunk_dims, NULL)) < 0) { + } else { + hsize_t dims2[RANK2]; + + if (s->expand_2d) { + dims2[0] = s->chunk_dims[0]; + dims2[1] = s->chunk_dims[1]; + } else { + dims2[0] = s->chunk_dims[0]; + + if (s->part_chunk) + dims2[1] = s->part_chunk; + else + dims2[1] = s->chunk_dims[1]; + } + + if ((s->memspace = H5Screate_simple(RANK2, dims2, NULL)) < 0) { fprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; } } + if (s->skip_chunk == 1) { + fprintf(stderr, "can't skip every chunk\n"); + TEST_ERROR; + } + + if (s->over_extend == 0) { + fprintf(stderr, "Extension of the dataset can't be zero\n"); + TEST_ERROR; + } + s->filename[0] = "vfd_swmr_bigset.h5"; if (s->vds == vds_multi) { s->filename[1] = "vfd_swmr_bigset-ur.h5"; @@ -655,8 +716,20 @@ state_init(state_t *s, int argc, char **argv) TEST_ERROR; } - if (H5Pset_chunk_cache(s->dapl, 0, 0, H5D_CHUNK_CACHE_W0_DEFAULT) < 0) { - fprintf(stderr, "H5Pset_chunk_cache failed\n"); + if (s->chunk_cache_size) { + if (H5Pget_chunk_cache(s->dapl, &rdcc_nslots, &rdcc_nbytes, &rdcc_w0) < 0) { + fprintf(stderr, "H5Pget_chunk_cache failed\n"); + TEST_ERROR; + } + + if (H5Pset_chunk_cache(s->dapl, rdcc_nslots, s->chunk_cache_size, rdcc_w0) < 0) { + fprintf(stderr, "H5Pset_chunk_cache failed\n"); + TEST_ERROR; + } + } + + if (s->deflate_level > 9) { + fprintf(stderr, "deflation level must be between 0 and 9\n"); TEST_ERROR; } @@ -1010,22 +1083,24 @@ error: static int notify_reader(np_state_t *np, unsigned step) { - exchange_info_t last; + exchange_info_t *last = HDcalloc(1, sizeof(exchange_info_t)); /* Get the time */ - if (HDclock_gettime(CLOCK_MONOTONIC, &(last.time)) < 0) { + if (HDclock_gettime(CLOCK_MONOTONIC, &(last->time)) < 0) { fprintf(stderr, "HDclock_gettime failed\n"); TEST_ERROR; } - last.step = step; + last->step = step; /* Notify the reader by sending the timestamp and the number of chunks written */ - if (HDwrite(np->fd_writer_to_reader, &last, sizeof(last)) < 0) { + if (HDwrite(np->fd_writer_to_reader, last, sizeof(exchange_info_t)) < 0) { fprintf(stderr, "HDwrite failed"); TEST_ERROR; } + HDfree(last); + return 0; error: @@ -1041,7 +1116,7 @@ create_extensible_dset(state_t *s, unsigned int which) char ul_dname[sizeof("/ul-dataset-9999999999")], ur_dname[sizeof("/ur-dataset-9999999999")], bl_dname[sizeof("/bl-dataset-9999999999")], br_dname[sizeof("/br-dataset-9999999999")]; hid_t dcpl = H5I_INVALID_HID, dset_id = H5I_INVALID_HID, filespace = H5I_INVALID_HID; - hsize_t dims3[3] = {1, s->chunk_dims[0], s->chunk_dims[1]}; + hsize_t dims3[3] = {s->depth, s->chunk_dims[0], s->chunk_dims[1]}; esnprintf(dname, sizeof(dname), "/dataset-%d", which); @@ -1051,7 +1126,7 @@ create_extensible_dset(state_t *s, unsigned int which) } if (s->test_3d) { - /* The chunk is 1 x M x N and grows along the first dimension */ + /* The chunk is L x M x N and grows along the first dimension */ if (H5Pset_chunk(dcpl, RANK3, dims3) < 0) { fprintf(stderr, "H5Pset_chunk for 3D dataset failed\n"); TEST_ERROR; @@ -1064,6 +1139,18 @@ create_extensible_dset(state_t *s, unsigned int which) } } + /* Never write fill value when new chunks are allocated */ + if (H5Pset_fill_time(dcpl, H5D_FILL_TIME_NEVER) < 0) { + fprintf(stderr, "H5Pset_fill_time failed\n"); + TEST_ERROR; + } + + /* GZIP compression */ + if (s->deflate_level && H5Pset_deflate(dcpl, s->deflate_level) < 0) { + fprintf(stderr, "H5Pset_deflate failed\n"); + TEST_ERROR; + } + if (s->vds != vds_off) { sources_t *const srcs = &s->sources[which]; @@ -1122,8 +1209,7 @@ create_extensible_dset(state_t *s, unsigned int which) fprintf(stderr, "H5Screate_simple 3D dataspace failed\n"); TEST_ERROR; } - } - else { + } else { if ((filespace = H5Screate_simple(RANK2, s->chunk_dims, s->expand_2d ? two_dee_max_dims : s->one_dee_max_dims)) < 0) { fprintf(stderr, "H5Screate_simple 2D dataspace failed\n"); @@ -1371,13 +1457,80 @@ error: return false; } +static uint32_t +matget(const mat_t *mat, unsigned k, unsigned i, unsigned j) +{ + return mat->elt[k * mat->rows * mat->cols + i * mat->cols + j]; +} + +static bool +matset(mat_t *mat, unsigned k, unsigned i, unsigned j, uint32_t v) +{ + if (k >= mat->depth || i >= mat->rows || j >= mat->cols) { + fprintf(stderr, "index out of boundary\n"); + TEST_ERROR; + } + + mat->elt[k * mat->rows * mat->cols + i * mat->cols + j] = v; + + return true; + +error: + return false; +} + +static mat_t * +newmat(state_t s) +{ + mat_t *mat; + + /* + * If partial chunk is enabled, the chunk size along the growing dimension + * is replaced with the partial size + */ + if (s.test_3d) { + if (s.part_chunk) { + mat = HDmalloc(sizeof(*mat) + (s.part_chunk * s.rows * s.cols - 1) * sizeof(mat->elt[0])); + mat->depth = s.part_chunk; + } else { + mat = HDmalloc(sizeof(*mat) + (s.depth * s.rows * s.cols - 1) * sizeof(mat->elt[0])); + mat->depth = s.depth; + } + + mat->rows = s.rows; + mat->cols = s.cols; + } else { + if (s.part_chunk && !s.expand_2d) { + mat = HDmalloc(sizeof(*mat) + (s.rows * s.part_chunk - 1) * sizeof(mat->elt[0])); + mat->depth = 1; + mat->rows = s.rows; + mat->cols = s.part_chunk; + } else { + mat = HDmalloc(sizeof(*mat) + (s.rows * s.cols - 1) * sizeof(mat->elt[0])); + mat->depth = 1; + mat->rows = s.rows; + mat->cols = s.cols; + } + } + + if (mat == NULL) { + fprintf(stderr, "HDmalloc failed\n"); + TEST_ERROR; + } + + return mat; + +error: + return NULL; +} + /* Write or verify the dataset test pattern in the matrix `mat`. * `mat` is a "subview" of the `which`th dataset with origin * `(base.row, base.col)`. * * If `do_set` is true, write the pattern; otherwise, verify. * - * The basic test pattern consists of increasing + * For 2D datasets, the basic test pattern consists of increasing * integers written in nested corners of the dataset * starting at element (0, 0): * @@ -1396,38 +1549,43 @@ error: * 15 14 13 12 * * In an actual pattern, the dataset number, `which`, is added to each integer. + * + * For 3D datasets, the increment of chunks is along the first dimension. */ static bool set_or_verify_matrix(mat_t *mat, unsigned int which, base_t base, bool do_set) { - unsigned row, col; + unsigned depth, row, col; bool ret = true; - for (row = 0; row < mat->rows; row++) { - for (col = 0; col < mat->cols; col++) { - uint32_t v; - hsize_t i = base.row + row, j = base.col + col, u; + /* For 2D datasets, `depth` is one */ + for (depth = 0; depth < mat->depth; depth++) { + for (row = 0; row < mat->rows; row++) { + for (col = 0; col < mat->cols; col++) { + uint32_t v; + hsize_t k = base.depth + depth, i = base.row + row, j = base.col + col, u; - if (j <= i) - u = (i + 1) * (i + 1) - 1 - j; - else - u = j * j + i; + if (j <= i) + u = k * 10 + (i + 1) * (i + 1) - 1 - j; + else + u = k * 10 + j * j + i; + + v = (uint32_t)(u + which); - v = (uint32_t)(u + which); - if (do_set) { - if (!matset(mat, row, col, v)) { - fprintf(stderr, "data initialization failed\n"); + if (do_set) { + if (!matset(mat, depth, row, col, v)) { + fprintf(stderr, "data initialization failed\n"); + ret = false; + break; + } + } else if (matget(mat, depth, row, col) != v) { + /* If the data doesn't match, simply return false and + * let the caller repeat this step + */ ret = false; break; } } - else if (matget(mat, row, col) != v) { - /* If the data doesn't match, simply return false and - * let the caller repeat this step - */ - ret = false; - break; - } } } @@ -1446,12 +1604,35 @@ verify_matrix(mat_t *mat, unsigned int which, base_t base) return set_or_verify_matrix(mat, which, base, false); } +static unsigned int +calc_total_steps(state_t s) { + unsigned int total_steps = 0; + + /* Calculate the number of steps depending on if partial chunk is enabled. + * e.g. the original number of steps is 10 and the size of the chunk along + * the growing dimension is 6. When the size of the partial chunk along the + * growing dimension is 5, the number of steps become 12. + */ + if (s.test_3d) { + if (s.part_chunk) + total_steps = s.nsteps * s.depth / s.part_chunk; + else + total_steps = s.nsteps; + } else if (s.expand_2d) { + total_steps = s.nsteps; + } else { + if (s.part_chunk) + total_steps = s.nsteps * s.cols / s.part_chunk; + else + total_steps = s.nsteps; + } + + return total_steps; +} + static bool verify_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t base) { - hsize_t offset2[RANK2] = {base.row, base.col}; - hsize_t offset3[RANK3] = {base.depth, base.row, base.col}; - hsize_t count3[RANK3] = {1, s->chunk_dims[0], s->chunk_dims[1]}; herr_t status; hid_t dset_id; @@ -1460,22 +1641,36 @@ verify_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t bas TEST_ERROR; } - if (s->test_3d) - dbgf(1, "verifying chunk %" PRIuHSIZE ", %" PRIuHSIZE ", %" PRIuHSIZE "\n", base.row, base.col, - base.depth); - else - dbgf(1, "verifying chunk %" PRIuHSIZE ", %" PRIuHSIZE "\n", base.row, base.col); - dset_id = s->dataset[which]; if (s->test_3d) { + hsize_t offset3[RANK3] = {base.depth, base.row, base.col}; + hsize_t count3[RANK3] = {s->depth, s->chunk_dims[0], s->chunk_dims[1]}; + + if (s->part_chunk) + count3[0] = s->part_chunk; + if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset3, NULL, count3, NULL) < 0) { fprintf(stderr, "H5Sselect_hyperslab failed\n"); TEST_ERROR; } - } - else { - if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset2, NULL, s->chunk_dims, NULL) < 0) { + } else { + hsize_t offset2[RANK2] = {base.row, base.col}; + hsize_t count2[RANK2]; + + if (s->expand_2d) { + count2[0] = s->chunk_dims[0]; + count2[1] = s->chunk_dims[1]; + } else { + count2[0] = s->chunk_dims[0]; + + if (s->part_chunk) + count2[1] = s->part_chunk; + else + count2[1] = s->chunk_dims[1]; + } + + if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset2, NULL, count2, NULL) < 0) { fprintf(stderr, "H5Sselect_hyperslab failed\n"); TEST_ERROR; } @@ -1484,8 +1679,7 @@ verify_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t bas /* A failure to read the data may indicate the data isn't ready yet. Instead of displaying the error * stack, simply return false and let the caller repeat this step. */ - H5E_BEGIN_TRY - { + H5E_BEGIN_TRY { status = H5Dread(dset_id, H5T_NATIVE_UINT32, s->memspace, filespace, H5P_DEFAULT, mat->elt); } H5E_END_TRY; @@ -1535,9 +1729,6 @@ error: static bool init_and_write_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t base) { - hsize_t offset2[RANK2] = {base.row, base.col}; - hsize_t offset3[RANK3] = {base.depth, base.row, base.col}; - hsize_t count3[RANK3] = {1, s->chunk_dims[0], s->chunk_dims[1]}; hid_t dset_id; dset_id = s->dataset[which]; @@ -1548,14 +1739,37 @@ init_and_write_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, ba } if (s->test_3d) { - /* The chunk dimensions are 1 x M x N. It grows along the first dimension */ + hsize_t offset3[RANK3] = {base.depth, base.row, base.col}; + hsize_t count3[RANK3] = {s->depth, s->chunk_dims[0], s->chunk_dims[1]}; + + /* Handling partial chunk */ + if (s->part_chunk) + count3[0] = s->part_chunk; + + /* The chunk dimensions are L x M x N. It grows along the first dimension */ if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset3, NULL, count3, NULL) < 0) { fprintf(stderr, "H5Sselect_hyperslab for 2D dataset failed\n"); TEST_ERROR; } } else { - if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset2, NULL, s->chunk_dims, NULL) < 0) { + hsize_t offset2[RANK2] = {base.row, base.col}; + hsize_t count2[RANK2]; + + if (s->expand_2d) { + count2[0] = s->chunk_dims[0]; + count2[1] = s->chunk_dims[1]; + } else { + count2[0] = s->chunk_dims[0]; + + /* Handling partial chunk */ + if (s->part_chunk) + count2[1] = s->part_chunk; + else + count2[1] = s->chunk_dims[1]; + } + + if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset2, NULL, count2, NULL) < 0) { fprintf(stderr, "H5Sselect_hyperslab for 2D dataset failed\n"); TEST_ERROR; } @@ -1631,7 +1845,8 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini dset_id = s->dataset[which]; - /* Attempt to check the availablity of the chunks for a number time before reporting it as a failure */ + /* Attempt to check the availablity of the chunks for a number times + * (NUM_ATTEMPTS) before reporting it as a failure */ for (i = 0; i < NUM_ATTEMPTS; i++) { if (H5Drefresh(dset_id) < 0) { fprintf(stderr, "H5Drefresh failed\n"); @@ -1649,15 +1864,22 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini TEST_ERROR; } - nchunks = (unsigned)size3[0]; - } - else { + /* Handling partial chunks */ + if (s->part_chunk) + nchunks = (unsigned)size3[0] / s->part_chunk; + else + nchunks = (unsigned)size3[0] / s->depth; + } else { if (H5Sget_simple_extent_dims(filespace, size2, NULL) < 0) { fprintf(stderr, "H5Sget_simple_extent_dims failed\n"); TEST_ERROR; } - nchunks = (unsigned)(size2[1] / s->chunk_dims[1]); + /* Handling partial chunks */ + if (s->part_chunk) + nchunks = (unsigned)(size2[1] / s->part_chunk); + else + nchunks = (unsigned)(size2[1] / s->chunk_dims[1]); } /* Make sure the chunks show up on the reader side. Otherwise sleep a while and try again */ @@ -1675,10 +1897,13 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini for (step = finished_step; step < last_step; step++) { dbgf(1, "%s: which %u step %u\n", __func__, which, step); + if (s->skip_chunk && step % s->skip_chunk == 0) + continue; + /* Read data that randomly crosses over chunks. But it should not happen to * the last chunk being written */ - if (s->cross_chunks) { + if (s->cross_chunk_read) { if (step == last_step - 1) ofs = 0; else @@ -1688,48 +1913,46 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini ofs = 0; if (s->test_3d) { - size3[0] = 1 + step; - size3[1] = s->chunk_dims[0]; - size3[2] = s->chunk_dims[1]; - last.depth = step; + if (s->part_chunk) { + last.depth = s->part_chunk * step + ofs; + } else { + last.depth = s->depth * step + ofs; + } + last.row = 0; last.col = 0; - } - else { + } else { + last.depth = 0; + if (s->expand_2d) { - size2[0] = s->chunk_dims[0] * (1 + step); - size2[1] = s->chunk_dims[1] * (1 + step); last.row = s->chunk_dims[0] * step + ofs; last.col = s->chunk_dims[1] * step + ofs; - } - else { - size2[0] = s->chunk_dims[0]; - size2[1] = s->chunk_dims[1] * (1 + step); + } else { last.row = 0; - last.col = s->chunk_dims[1] * step + ofs; + + if (s->part_chunk) { + last.col = s->part_chunk * step + ofs; + } else { + last.col = s->chunk_dims[1] * step + ofs; + } } } - if (s->test_3d) { - dbgf(1, "new size3 %" PRIuHSIZE ", %" PRIuHSIZE ", %" PRIuHSIZE "\n", size3[0], size3[1], - size3[2]); + if (s->test_3d) dbgf(1, "last row %" PRIuHSIZE " col %" PRIuHSIZE " depth %" PRIuHSIZE "\n", last.row, last.col, last.depth); - } - else { - dbgf(1, "new size2 %" PRIuHSIZE ", %" PRIuHSIZE "\n", size2[0], size2[1]); + else dbgf(1, "last row %" PRIuHSIZE " col %" PRIuHSIZE "\n", last.row, last.col); - } if (s->test_3d || !s->expand_2d) { if (!repeat_verify_chunk(s, filespace, mat, which, last)) { fprintf(stderr, "chunk verification failed\n"); TEST_ERROR; } - } - else { + } else { /* Down the right side, intersecting the bottom row. */ base.col = last.col; + base.depth = 0; for (base.row = 0; base.row <= last.row; base.row += s->chunk_dims[0]) { if (!repeat_verify_chunk(s, filespace, mat, which, base)) { fprintf(stderr, "chunk verification failed\n"); @@ -1775,10 +1998,13 @@ verify_dsets(state_t s, np_state_t *np, mat_t *mat) unsigned finished_step = 0; unsigned which; unsigned counter = 0; + unsigned total_steps = 0; double passed_time = 0.0, total_time = 0.0, min_time = 1000000.0, max_time = 0.0; exchange_info_t last; struct timespec end_time; + total_steps = calc_total_steps(s); + do { /* Receive the notice of the writer finishing creation, * including the number of chunks finished and the timestamp @@ -1829,7 +2055,7 @@ verify_dsets(state_t s, np_state_t *np, mat_t *mat) if (passed_time < min_time) min_time = passed_time; } - } while (finished_step < s.nsteps); + } while (finished_step < total_steps); /* Print out the performance information */ if (s.use_named_pipe && s.do_perf && counter) @@ -1898,33 +2124,50 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * dset_id = s->dataset[which]; - if (s->asteps != 0 && step % s->asteps == 0) { + if (s->asteps != 0 && step % s->asteps == 0) { if (!add_dset_attribute(s, dset_id, s->one_by_one_sid, which, step)) { fprintf(stderr, "add_dset_attribute failed\n"); TEST_ERROR; } } + /* Handling both over extension of the datasets and partial chunks. Datasets + * can be extended multiple chunks instead of one chunk at a time. + * e.g. if the over extension is set to 10 chunks, the datasets are extended + * 10 chunks along the growing dimension after every 10 chunks are written. + */ if (s->test_3d) { - size3[0] = 1 + step; + if (s->part_chunk) { + size3[0] = s->over_extend * s->part_chunk * (1 + step / s->over_extend); + last.depth = s->part_chunk * step; + } else { + size3[0] = s->over_extend * s->depth * (1 + step / s->over_extend); + last.depth = s->depth * step; + } + size3[1] = s->chunk_dims[0]; size3[2] = s->chunk_dims[1]; - last.depth = step; + last.row = 0; last.col = 0; - } - else { + } else { if (s->expand_2d) { - size2[0] = s->chunk_dims[0] * (1 + step); - size2[1] = s->chunk_dims[1] * (1 + step); + size2[0] = s->over_extend * s->chunk_dims[0] * (1 + step / s->over_extend); + size2[1] = s->over_extend * s->chunk_dims[1] * (1 + step / s->over_extend); + last.row = s->chunk_dims[0] * step; last.col = s->chunk_dims[1] * step; - } - else { + } else { size2[0] = s->chunk_dims[0]; - size2[1] = s->chunk_dims[1] * (1 + step); last.row = 0; - last.col = s->chunk_dims[1] * step; + + if (s->part_chunk) { + size2[1] = s->over_extend * s->part_chunk * (1 + step / s->over_extend); + last.col = s->part_chunk * step; + } else { + size2[1] = s->over_extend * s->chunk_dims[1] * (1 + step / s->over_extend); + last.col = s->chunk_dims[1] * step; + } } last.depth = 0; } @@ -1957,18 +2200,22 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * fprintf(stderr, "H5Dset_extent failed\n"); TEST_ERROR; } - } - else { - if (s->test_3d) { - if (H5Dset_extent(dset_id, size3) < 0) { - fprintf(stderr, "H5Dset_extent for 3D dataset failed\n"); - TEST_ERROR; - } - } - else { - if (H5Dset_extent(dset_id, size2) < 0) { - fprintf(stderr, "H5Dset_extent for 2D dataset failed\n"); - TEST_ERROR; + } else { + /* Handling over extension. Making sure the dataset size doesn't exceed the fixed maximal size */ + if (step % s->over_extend == 0) { + if (s->test_3d) { + if (size3[0] <= three_dee_max_dims[0] && H5Dset_extent(dset_id, size3) < 0) { + fprintf(stderr, "H5Dset_extent for 3D dataset failed\n"); + TEST_ERROR; + } + } else { + if ((s->expand_2d && size2[0] <= two_dee_max_dims[0] && size2[0] <= two_dee_max_dims[0]) + || (!s->expand_2d && size2[1] <= two_dee_max_dims[1])) { + if (H5Dset_extent(dset_id, size2) < 0) { + fprintf(stderr, "H5Dset_extent for 2D dataset failed\n"); + TEST_ERROR; + } + } } } } @@ -1983,8 +2230,7 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * fprintf(stderr, "init_and_write_chunk failed\n"); TEST_ERROR; } - } - else if (s->expand_2d) { + } else if (s->expand_2d) { base.col = last.col; base.depth = 0; for (base.row = 0; base.row <= last.row; base.row += s->chunk_dims[0]) { @@ -2025,7 +2271,7 @@ error: static bool write_dsets(state_t s, np_state_t *np, mat_t *mat) { - unsigned last_step, step, which; + unsigned last_step, step, total_steps, which; unsigned long long old_tick_num; H5F_t * f = NULL; struct timespec start_time, end_time; @@ -2046,16 +2292,22 @@ write_dsets(state_t s, np_state_t *np, mat_t *mat) old_tick_num = f->shared->tick_num; /* Write as many as chunks within the same tick number before notifying - * the reader to verify them. + * the reader to verify them. Take account of partial chunk write + * here by multiplying the dividing factor for partial chunk. Treat each + * partial chunk as if it's a chunk. */ - for (step = 0; step < s.nsteps; step++) { + total_steps = calc_total_steps(s); + + for (step = 0; step < total_steps; step++) { /* Write as many as chunks before the tick number changes */ if (f->shared->tick_num == old_tick_num) { - for (which = 0; which < s.ndatasets; which++) { - dbgf(2, "step %d which %d\n", step, which); - if (!write_extensible_dset(&s, which, step, mat)) { - fprintf(stderr, "write_extensible_dset failed\n"); - TEST_ERROR; + if (!s.skip_chunk || (s.skip_chunk && step % s.skip_chunk != 0)) { + for (which = 0; which < s.ndatasets; which++) { + dbgf(2, "step %d which %d\n", step, which); + if (!write_extensible_dset(&s, which, step, mat)) { + fprintf(stderr, "write_extensible_dset failed\n"); + TEST_ERROR; + } } } } @@ -2063,7 +2315,7 @@ write_dsets(state_t s, np_state_t *np, mat_t *mat) /* Notify the reader to start verification by * sending the timestamp and the number of chunks written */ - if (f->shared->tick_num > old_tick_num || step == (s.nsteps - 1)) { + if (f->shared->tick_num > old_tick_num || step == (total_steps - 1)) { last_step = step + 1; if (s.use_named_pipe && notify_reader(np, last_step) < 0) { fprintf(stderr, "notify_reader failed\n"); @@ -2106,18 +2358,21 @@ main(int argc, char **argv) TEST_ERROR; } - if ((mat = newmat(s.rows, s.cols)) == NULL) { + if ((mat = newmat(s)) == NULL) { fprintf(stderr, "could not allocate matrix\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, 4096)) < 0) - errx(EXIT_FAILURE, "H5Pcreate"); + if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, s.fsp_size)) < 0) { + fprintf(stderr, "vfd_swmr_create_fcpl failed\n"); + TEST_ERROR; + } for (i = 0; i < NELMTS(s.file); i++) { hid_t fapl; H5F_vfd_swmr_config_t config; + H5AC_cache_config_t mdc_config; if (s.vds != vds_multi && i > 0) { s.file[i] = s.file[0]; @@ -2125,13 +2380,34 @@ 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, TICK_LEN, MAX_LAG, s.writer, FALSE, 128, "./bigset-shadow-%zu", i); + init_vfd_swmr_config(&config, s.tick_len, s.max_lag, s.writer, s.flush_raw_data, 128, "./bigset-shadow-%zu", i); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ - fapl = vfd_swmr_create_fapl(true, s.use_vfd_swmr, true, 4096, &config); + if ((fapl = vfd_swmr_create_fapl(true, s.use_vfd_swmr, true, s.page_buf_size, &config)) < 0) { + fprintf(stderr, "vfd_swmr_create_fapl failed"); + TEST_ERROR; + } - if (fapl < 0) - errx(EXIT_FAILURE, "vfd_swmr_create_fapl"); + /* Set the initial size for the metadata cache between 1 and 32 in megabytes. + * Zero means using the default value, which is no-op. + */ + if (s.mdc_init_size) { + mdc_config.version = H5AC__CURR_CACHE_CONFIG_VERSION; + + if (H5Pget_mdc_config(fapl, &mdc_config) < 0) { + fprintf(stderr, "H5Pget_mdc_config failed"); + TEST_ERROR; + } + + /* Convert the value to megabytes */ + mdc_config.set_initial_size = TRUE; + mdc_config.initial_size = s.mdc_init_size * 1024 * 1024; + + if (H5Pset_mdc_config(fapl, &mdc_config) < 0) { + fprintf(stderr, "H5Pset_mdc_config failed"); + TEST_ERROR; + } + } s.file[i] = s.writer ? H5Fcreate(s.filename[i], H5F_ACC_TRUNC, fcpl, fapl) : H5Fopen(s.filename[i], H5F_ACC_RDONLY, fapl); @@ -2200,8 +2476,7 @@ main(int argc, char **argv) fprintf(stderr, "write_dsets failed"); TEST_ERROR; } - } - else { + } else { /* Wait for the writer's notice before starting the validation of dataset creation */ np.verify = 1; if (s.use_named_pipe && reader_verify(np, np.verify) < 0) { @@ -2259,11 +2534,6 @@ main(int argc, char **argv) HDfree(mat); - if (s.dataset) - HDfree(s.dataset); - if (s.sources) - HDfree(s.sources); - return EXIT_SUCCESS; error: -- cgit v0.12 From a95bf70967d8075263a86f11ef6047817ff3476a Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 1 Sep 2021 16:12:48 +0000 Subject: Committing clang-format changes --- test/vfd_swmr_bigset_writer.c | 212 ++++++++++++++++++++++++------------------ 1 file changed, 121 insertions(+), 91 deletions(-) diff --git a/test/vfd_swmr_bigset_writer.c b/test/vfd_swmr_bigset_writer.c index dc95cfb..891bfc9 100644 --- a/test/vfd_swmr_bigset_writer.c +++ b/test/vfd_swmr_bigset_writer.c @@ -239,47 +239,48 @@ static hsize_t two_dee_max_dims[RANK2], three_dee_max_dims[RANK3]; static void usage(const char *progname) { - fprintf(stderr, - "usage: %s [-C] [-F] [-M] [-P] [-R] [-S] [-V] [-W] [-a steps] [-b] [-c cols]\n" - " [-d dims] [-e depth] [-f tick_len] [-g max_lag] [-j skip_chunk] [-k part_chunk]\n" - " [-l tick_num] [-n iterations] [-o page_buf_size] [-p fsp_size] [-r rows]\n" - " [-s datasets] [-t] [-u over_extend] [-v chunk_cache_size] [-w deflate_level]\n" - "\n" - "-C: cross-over chunk read during chunk verification\n" - "-F: fixed maximal dimension for the chunked datasets\n" - "-M: use virtual datasets and many source\n" - " files\n" - "-N: do not use named pipes\n" - "-P: do the performance measurement\n" - "-R: flush raw data\n" - "-S: do not use VFD SWMR\n" - "-V: use virtual datasets and a single\n" - " source file\n" - "-a steps: `steps` between adding attributes\n" - "-b: write data in big-endian byte order\n" - "-c cols: `cols` columns of the chunk\n" - "-d 1|one|2|two|both: select dataset expansion in one or\n" - " both dimensions\n" - "-e depth: the first dimension of the 3D chunk\n" - "-f tick_len: tick length\n" - "-g max_lag: maximal lag\n" - "-j skip_chunk: skip the Nth (skip_chunk) chunks during chunk writing\n" - "-k part_chunk: the size for partial chunk write\n" - "-l tick_num: expected maximal number of ticks from\n" - " the writer's finishing creation to the reader's finishing validation\n" - "-m mdc_init_size: the initial size of metadata cache in megabytes (must be between 1 and 32MB)\n" - "-n iterations: how many times to expand each dataset\n" - "-o page_buf_size: page buffer size\n" - "-p fsp_size: file space page size\n" - "-r rows: `rows` rows of the chunk\n" - "-s datasets: number of datasets to create\n" - "-t: enable test for 3D datasets (dataset expansion is along one dimension)\n" - " currently, 3D datasets isn't tested with VDS\n" - "-u over_extend: extend the size of the dataset in multiple chunks or partial chunks\n" - "-v chunk_cache_size: the size of raw data chunk cache in bytes\n" - "-w deflate_level: the level (0 - 9) of gzip compression\n" - "\n", - progname); + fprintf( + stderr, + "usage: %s [-C] [-F] [-M] [-P] [-R] [-S] [-V] [-W] [-a steps] [-b] [-c cols]\n" + " [-d dims] [-e depth] [-f tick_len] [-g max_lag] [-j skip_chunk] [-k part_chunk]\n" + " [-l tick_num] [-n iterations] [-o page_buf_size] [-p fsp_size] [-r rows]\n" + " [-s datasets] [-t] [-u over_extend] [-v chunk_cache_size] [-w deflate_level]\n" + "\n" + "-C: cross-over chunk read during chunk verification\n" + "-F: fixed maximal dimension for the chunked datasets\n" + "-M: use virtual datasets and many source\n" + " files\n" + "-N: do not use named pipes\n" + "-P: do the performance measurement\n" + "-R: flush raw data\n" + "-S: do not use VFD SWMR\n" + "-V: use virtual datasets and a single\n" + " source file\n" + "-a steps: `steps` between adding attributes\n" + "-b: write data in big-endian byte order\n" + "-c cols: `cols` columns of the chunk\n" + "-d 1|one|2|two|both: select dataset expansion in one or\n" + " both dimensions\n" + "-e depth: the first dimension of the 3D chunk\n" + "-f tick_len: tick length\n" + "-g max_lag: maximal lag\n" + "-j skip_chunk: skip the Nth (skip_chunk) chunks during chunk writing\n" + "-k part_chunk: the size for partial chunk write\n" + "-l tick_num: expected maximal number of ticks from\n" + " the writer's finishing creation to the reader's finishing validation\n" + "-m mdc_init_size: the initial size of metadata cache in megabytes (must be between 1 and 32MB)\n" + "-n iterations: how many times to expand each dataset\n" + "-o page_buf_size: page buffer size\n" + "-p fsp_size: file space page size\n" + "-r rows: `rows` rows of the chunk\n" + "-s datasets: number of datasets to create\n" + "-t: enable test for 3D datasets (dataset expansion is along one dimension)\n" + " currently, 3D datasets isn't tested with VDS\n" + "-u over_extend: extend the size of the dataset in multiple chunks or partial chunks\n" + "-v chunk_cache_size: the size of raw data chunk cache in bytes\n" + "-w deflate_level: the level (0 - 9) of gzip compression\n" + "\n", + progname); exit(EXIT_FAILURE); } @@ -657,13 +658,15 @@ state_init(state_t *s, int argc, char **argv) fprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; } - } else { + } + else { hsize_t dims2[RANK2]; if (s->expand_2d) { dims2[0] = s->chunk_dims[0]; dims2[1] = s->chunk_dims[1]; - } else { + } + else { dims2[0] = s->chunk_dims[0]; if (s->part_chunk) @@ -1209,7 +1212,8 @@ create_extensible_dset(state_t *s, unsigned int which) fprintf(stderr, "H5Screate_simple 3D dataspace failed\n"); TEST_ERROR; } - } else { + } + else { if ((filespace = H5Screate_simple(RANK2, s->chunk_dims, s->expand_2d ? two_dee_max_dims : s->one_dee_max_dims)) < 0) { fprintf(stderr, "H5Screate_simple 2D dataspace failed\n"); @@ -1490,26 +1494,29 @@ newmat(state_t s) */ if (s.test_3d) { if (s.part_chunk) { - mat = HDmalloc(sizeof(*mat) + (s.part_chunk * s.rows * s.cols - 1) * sizeof(mat->elt[0])); + mat = HDmalloc(sizeof(*mat) + (s.part_chunk * s.rows * s.cols - 1) * sizeof(mat->elt[0])); mat->depth = s.part_chunk; - } else { - mat = HDmalloc(sizeof(*mat) + (s.depth * s.rows * s.cols - 1) * sizeof(mat->elt[0])); + } + else { + mat = HDmalloc(sizeof(*mat) + (s.depth * s.rows * s.cols - 1) * sizeof(mat->elt[0])); mat->depth = s.depth; } mat->rows = s.rows; mat->cols = s.cols; - } else { + } + else { if (s.part_chunk && !s.expand_2d) { - mat = HDmalloc(sizeof(*mat) + (s.rows * s.part_chunk - 1) * sizeof(mat->elt[0])); + mat = HDmalloc(sizeof(*mat) + (s.rows * s.part_chunk - 1) * sizeof(mat->elt[0])); mat->depth = 1; - mat->rows = s.rows; - mat->cols = s.part_chunk; - } else { - mat = HDmalloc(sizeof(*mat) + (s.rows * s.cols - 1) * sizeof(mat->elt[0])); + mat->rows = s.rows; + mat->cols = s.part_chunk; + } + else { + mat = HDmalloc(sizeof(*mat) + (s.rows * s.cols - 1) * sizeof(mat->elt[0])); mat->depth = 1; - mat->rows = s.rows; - mat->cols = s.cols; + mat->rows = s.rows; + mat->cols = s.cols; } } @@ -1578,7 +1585,8 @@ set_or_verify_matrix(mat_t *mat, unsigned int which, base_t base, bool do_set) ret = false; break; } - } else if (matget(mat, depth, row, col) != v) { + } + else if (matget(mat, depth, row, col) != v) { /* If the data doesn't match, simply return false and * let the caller repeat this step */ @@ -1605,7 +1613,8 @@ verify_matrix(mat_t *mat, unsigned int which, base_t base) } static unsigned int -calc_total_steps(state_t s) { +calc_total_steps(state_t s) +{ unsigned int total_steps = 0; /* Calculate the number of steps depending on if partial chunk is enabled. @@ -1618,9 +1627,11 @@ calc_total_steps(state_t s) { total_steps = s.nsteps * s.depth / s.part_chunk; else total_steps = s.nsteps; - } else if (s.expand_2d) { + } + else if (s.expand_2d) { total_steps = s.nsteps; - } else { + } + else { if (s.part_chunk) total_steps = s.nsteps * s.cols / s.part_chunk; else @@ -1633,8 +1644,8 @@ calc_total_steps(state_t s) { static bool verify_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t base) { - herr_t status; - hid_t dset_id; + herr_t status; + hid_t dset_id; if (which >= s->ndatasets) { fprintf(stderr, "the dataset order is bigger than the number of datasets"); @@ -1654,14 +1665,16 @@ verify_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t bas fprintf(stderr, "H5Sselect_hyperslab failed\n"); TEST_ERROR; } - } else { + } + else { hsize_t offset2[RANK2] = {base.row, base.col}; hsize_t count2[RANK2]; if (s->expand_2d) { count2[0] = s->chunk_dims[0]; count2[1] = s->chunk_dims[1]; - } else { + } + else { count2[0] = s->chunk_dims[0]; if (s->part_chunk) @@ -1679,7 +1692,8 @@ verify_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t bas /* A failure to read the data may indicate the data isn't ready yet. Instead of displaying the error * stack, simply return false and let the caller repeat this step. */ - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { status = H5Dread(dset_id, H5T_NATIVE_UINT32, s->memspace, filespace, H5P_DEFAULT, mat->elt); } H5E_END_TRY; @@ -1729,7 +1743,7 @@ error: static bool init_and_write_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t base) { - hid_t dset_id; + hid_t dset_id; dset_id = s->dataset[which]; @@ -1759,7 +1773,8 @@ init_and_write_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, ba if (s->expand_2d) { count2[0] = s->chunk_dims[0]; count2[1] = s->chunk_dims[1]; - } else { + } + else { count2[0] = s->chunk_dims[0]; /* Handling partial chunk */ @@ -1869,7 +1884,8 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini nchunks = (unsigned)size3[0] / s->part_chunk; else nchunks = (unsigned)size3[0] / s->depth; - } else { + } + else { if (H5Sget_simple_extent_dims(filespace, size2, NULL) < 0) { fprintf(stderr, "H5Sget_simple_extent_dims failed\n"); TEST_ERROR; @@ -1915,24 +1931,28 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini if (s->test_3d) { if (s->part_chunk) { last.depth = s->part_chunk * step + ofs; - } else { + } + else { last.depth = s->depth * step + ofs; } - last.row = 0; - last.col = 0; - } else { + last.row = 0; + last.col = 0; + } + else { last.depth = 0; if (s->expand_2d) { last.row = s->chunk_dims[0] * step + ofs; last.col = s->chunk_dims[1] * step + ofs; - } else { + } + else { last.row = 0; if (s->part_chunk) { last.col = s->part_chunk * step + ofs; - } else { + } + else { last.col = s->chunk_dims[1] * step + ofs; } } @@ -1949,9 +1969,10 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini fprintf(stderr, "chunk verification failed\n"); TEST_ERROR; } - } else { + } + else { /* Down the right side, intersecting the bottom row. */ - base.col = last.col; + base.col = last.col; base.depth = 0; for (base.row = 0; base.row <= last.row; base.row += s->chunk_dims[0]) { if (!repeat_verify_chunk(s, filespace, mat, which, base)) { @@ -2124,7 +2145,7 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * dset_id = s->dataset[which]; - if (s->asteps != 0 && step % s->asteps == 0) { + if (s->asteps != 0 && step % s->asteps == 0) { if (!add_dset_attribute(s, dset_id, s->one_by_one_sid, which, step)) { fprintf(stderr, "add_dset_attribute failed\n"); TEST_ERROR; @@ -2140,31 +2161,35 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * if (s->part_chunk) { size3[0] = s->over_extend * s->part_chunk * (1 + step / s->over_extend); last.depth = s->part_chunk * step; - } else { + } + else { size3[0] = s->over_extend * s->depth * (1 + step / s->over_extend); last.depth = s->depth * step; } - size3[1] = s->chunk_dims[0]; - size3[2] = s->chunk_dims[1]; + size3[1] = s->chunk_dims[0]; + size3[2] = s->chunk_dims[1]; - last.row = 0; - last.col = 0; - } else { + last.row = 0; + last.col = 0; + } + else { if (s->expand_2d) { size2[0] = s->over_extend * s->chunk_dims[0] * (1 + step / s->over_extend); size2[1] = s->over_extend * s->chunk_dims[1] * (1 + step / s->over_extend); last.row = s->chunk_dims[0] * step; last.col = s->chunk_dims[1] * step; - } else { + } + else { size2[0] = s->chunk_dims[0]; last.row = 0; if (s->part_chunk) { size2[1] = s->over_extend * s->part_chunk * (1 + step / s->over_extend); last.col = s->part_chunk * step; - } else { + } + else { size2[1] = s->over_extend * s->chunk_dims[1] * (1 + step / s->over_extend); last.col = s->chunk_dims[1] * step; } @@ -2200,7 +2225,8 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * fprintf(stderr, "H5Dset_extent failed\n"); TEST_ERROR; } - } else { + } + else { /* Handling over extension. Making sure the dataset size doesn't exceed the fixed maximal size */ if (step % s->over_extend == 0) { if (s->test_3d) { @@ -2208,9 +2234,10 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * fprintf(stderr, "H5Dset_extent for 3D dataset failed\n"); TEST_ERROR; } - } else { - if ((s->expand_2d && size2[0] <= two_dee_max_dims[0] && size2[0] <= two_dee_max_dims[0]) - || (!s->expand_2d && size2[1] <= two_dee_max_dims[1])) { + } + else { + if ((s->expand_2d && size2[0] <= two_dee_max_dims[0] && size2[0] <= two_dee_max_dims[0]) || + (!s->expand_2d && size2[1] <= two_dee_max_dims[1])) { if (H5Dset_extent(dset_id, size2) < 0) { fprintf(stderr, "H5Dset_extent for 2D dataset failed\n"); TEST_ERROR; @@ -2230,7 +2257,8 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * fprintf(stderr, "init_and_write_chunk failed\n"); TEST_ERROR; } - } else if (s->expand_2d) { + } + else if (s->expand_2d) { base.col = last.col; base.depth = 0; for (base.row = 0; base.row <= last.row; base.row += s->chunk_dims[0]) { @@ -2380,7 +2408,8 @@ 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, s.writer, s.flush_raw_data, 128, "./bigset-shadow-%zu", i); + init_vfd_swmr_config(&config, s.tick_len, s.max_lag, s.writer, s.flush_raw_data, 128, + "./bigset-shadow-%zu", i); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ if ((fapl = vfd_swmr_create_fapl(true, s.use_vfd_swmr, true, s.page_buf_size, &config)) < 0) { @@ -2476,7 +2505,8 @@ main(int argc, char **argv) fprintf(stderr, "write_dsets failed"); TEST_ERROR; } - } else { + } + else { /* Wait for the writer's notice before starting the validation of dataset creation */ np.verify = 1; if (s.use_named_pipe && reader_verify(np, np.verify) < 0) { -- cgit v0.12 From 9a9e4983a3f6569785356ebdd4ba496a91fe6ecd Mon Sep 17 00:00:00 2001 From: Songyu Lu Date: Wed, 1 Sep 2021 11:44:26 -0500 Subject: Minor adjustment to a parameter. --- test/testvfdswmr.sh.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/testvfdswmr.sh.in b/test/testvfdswmr.sh.in index 5a3b0f7..2852f24 100644 --- a/test/testvfdswmr.sh.in +++ b/test/testvfdswmr.sh.in @@ -1084,11 +1084,11 @@ for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-d 1 -t" "-d 1 -t -F" "-d 1 -V 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 6 & + ../vfd_swmr_bigset_writer -n $BIGSET_n $options -s $BIGSET_many_s -e 8 -r 16 -c 16 -q -l 3 & 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 6 & + ../vfd_swmr_bigset_reader -n $BIGSET_n $options -s $BIGSET_many_s -e 8 -r 16 -c 16 -q -l 3 & pid_reader=$! # Wait for the reader to finish before signalling the -- cgit v0.12 From 6685a58b8d31675ac8d36c82d79fffa56bd52a0c Mon Sep 17 00:00:00 2001 From: Songyu Lu Date: Fri, 3 Sep 2021 15:06:06 -0500 Subject: Add a function call to allocate space early during H5Dcreate and H5Dextend. --- test/vfd_swmr_bigset_writer.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/test/vfd_swmr_bigset_writer.c b/test/vfd_swmr_bigset_writer.c index 891bfc9..649cf38 100644 --- a/test/vfd_swmr_bigset_writer.c +++ b/test/vfd_swmr_bigset_writer.c @@ -248,20 +248,20 @@ usage(const char *progname) "\n" "-C: cross-over chunk read during chunk verification\n" "-F: fixed maximal dimension for the chunked datasets\n" - "-M: use virtual datasets and many source\n" + "-M: use virtual datasets and many source\n" " files\n" "-N: do not use named pipes\n" "-P: do the performance measurement\n" "-R: flush raw data\n" - "-S: do not use VFD SWMR\n" - "-V: use virtual datasets and a single\n" + "-S: do not use VFD SWMR\n" + "-V: use virtual datasets and a single\n" " source file\n" - "-a steps: `steps` between adding attributes\n" - "-b: write data in big-endian byte order\n" - "-c cols: `cols` columns of the chunk\n" + "-a steps: `steps` between adding attributes\n" + "-b: write data in big-endian byte order\n" + "-c cols: `cols` columns of the chunk\n" "-d 1|one|2|two|both: select dataset expansion in one or\n" " both dimensions\n" - "-e depth: the first dimension of the 3D chunk\n" + "-e depth: the first dimension of the 3D chunk\n" "-f tick_len: tick length\n" "-g max_lag: maximal lag\n" "-j skip_chunk: skip the Nth (skip_chunk) chunks during chunk writing\n" @@ -272,7 +272,7 @@ usage(const char *progname) "-n iterations: how many times to expand each dataset\n" "-o page_buf_size: page buffer size\n" "-p fsp_size: file space page size\n" - "-r rows: `rows` rows of the chunk\n" + "-r rows: `rows` rows of the chunk\n" "-s datasets: number of datasets to create\n" "-t: enable test for 3D datasets (dataset expansion is along one dimension)\n" " currently, 3D datasets isn't tested with VDS\n" @@ -1148,6 +1148,12 @@ create_extensible_dset(state_t *s, unsigned int which) TEST_ERROR; } + /* Early space allocation */ + if (H5Pset_alloc_time(dcpl, H5D_ALLOC_TIME_EARLY) < 0) { + fprintf(stderr, "H5Pset_alloc_time failed\n"); + TEST_ERROR; + } + /* GZIP compression */ if (s->deflate_level && H5Pset_deflate(dcpl, s->deflate_level) < 0) { fprintf(stderr, "H5Pset_deflate failed\n"); -- cgit v0.12 From 859dd4d975dcd5baee5b4305157381bcfbd7ecf7 Mon Sep 17 00:00:00 2001 From: myang6 Date: Fri, 10 Sep 2021 15:56:19 -0500 Subject: Add the expected design fail for the long running API on the reader side. --- test/Makefile.am | 3 + test/vfd_swmr_dsetops_writer.c | 2 +- test/vfd_swmr_gfail_writer.c | 740 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 744 insertions(+), 1 deletion(-) create mode 100644 test/vfd_swmr_gfail_writer.c diff --git a/test/Makefile.am b/test/Makefile.am index 3ae26bd..6df1653 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -55,6 +55,7 @@ SCRIPT_DEPEND = error_test$(EXEEXT) err_compat$(EXEEXT) links_env$(EXEEXT) \ vfd_swmr_vlstr_reader$(EXEEXT) vfd_swmr_vlstr_writer$(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) \ vds_env$(EXEEXT) \ vds_swmr_gen$(EXEEXT) vds_swmr_reader$(EXEEXT) vds_swmr_writer$(EXEEXT) if HAVE_SHARED_CONDITIONAL @@ -113,6 +114,7 @@ check_PROGRAMS=$(TEST_PROG) error_test err_compat tcheck_version \ vfd_swmr_zoo_reader vfd_swmr_zoo_writer \ 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_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 \ @@ -181,6 +183,7 @@ vfd_swmr_zoo_reader_SOURCES=vfd_swmr_zoo_writer.c genall5.c 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_dsetops_reader_SOURCES=vfd_swmr_dsetops_writer.c vfd_swmr_attrdset_writer_SOURCES=vfd_swmr_attrdset_writer.c diff --git a/test/vfd_swmr_dsetops_writer.c b/test/vfd_swmr_dsetops_writer.c index f98843d..3704c44 100644 --- a/test/vfd_swmr_dsetops_writer.c +++ b/test/vfd_swmr_dsetops_writer.c @@ -149,7 +149,7 @@ static bool verify_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_ static bool verify_dsets_action(unsigned action, const state_t *s, const dsets_state_t *ds, unsigned which, bool fileclosed); static bool verify_dset(hid_t did, hid_t tid, hid_t mem_sid, hid_t file_sid, hsize_t *start, hsize_t *stride, - size_t *count, hsize_t *block, unsigned int *vbuf, bool fileclosed, + hsize_t *count, hsize_t *block, unsigned int *vbuf, bool fileclosed, bool flush_raw_data); static bool verify_dset_compact(const state_t *s, const dsets_state_t *ds, bool fileclosed, bool flush_raw_data); diff --git a/test/vfd_swmr_gfail_writer.c b/test/vfd_swmr_gfail_writer.c new file mode 100644 index 0000000..5d47f8b --- /dev/null +++ b/test/vfd_swmr_gfail_writer.c @@ -0,0 +1,740 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Purpose: To demostrate the four issues uncovered during the test plan + * 1.4 part 1. + * + * Setup: + * Writer: + * 1) Create an HDF5 file + * 2) Create many groups + * 3) Use the named pipe to send the reader a message to start verifying + * 4) Call H5Fvfd_swmr_end_tick immeidately after sending out the message to the reader + * 5) Sleep for two ticks before receiving a message from the reader that the reader starts verifying + * 6) + * If the option to delete the group is off(by default), + * just sleep for a relatively long time, then close the HDF5 file. + * else + * delete the last 1000 groups that are just created if the total number of created groups is greater than 1000 + * call H5Fvfd_swmr_end_tick + * sleep for a relatively long time, then close the HDF5 file. + * + * Reader: + * 1) Open the HDF5 file + * 2) Wait for the writer's message that the writer finishes creating groups. + * 3) After receiving the message from the writer, send a message back to the writer, + * then call H5Literate to iterate through all the groups. The callback function just checks if the group name's prefix + * is valid. An #if 0 #endif block can help the user easily tune to check the iterated group names. + * 4) HDclock_gettime is used to check the total time of H5Literate call. + * 5) Close the HDF5 file if everything runs successfully. + * + * The number of groups, the tick length, the max lag, the page buffer size, the page size and the sleep duration on the writer + * side before closing the file are configurable. Users can also choose an option to delete 1000 groups. + * We only test to creat the groups with the latest file format. The option to create a group via the earlies file format is + * still there but it is not tested for our purpose. + * + * Add information on how to duplicate the four issues and the expected design fail. + */ + + +#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 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 nsteps; + bool use_vfd_swmr; + bool old_style_grp; + bool use_named_pipes; + uint32_t w_sleep_len; + uint32_t max_lag; + uint32_t tick_len; + unsigned int ps; + unsigned int pbs; + bool del_grp; + int np_fd_w_to_r; + int np_fd_r_to_w; + int np_notify; + int np_verify; +} state_t; + +#define ALL_HID_INITIALIZER \ + (state_t) \ + { \ + .file = H5I_INVALID_HID, .one_by_one_sid = H5I_INVALID_HID, .filename = "", \ + .filetype = H5T_NATIVE_UINT32, .nsteps = 10000, .use_vfd_swmr = true, .old_style_grp = false, \ + .use_named_pipes = true, .w_sleep_len = 112, .tick_len = 4, .max_lag = 7, .ps = 4096, .pbs = 4096, \ + .del_grp = false, .np_fd_w_to_r = -1, .np_fd_r_to_w = -1, .np_notify = 0, .np_verify = 0 \ + } + +/* + * Operator function to be called by H5Literate. + */ +herr_t op_func(hid_t loc_id, const char *name, const H5L_info_t *info, void *operator_data); + +static void +usage(const char *progname) +{ + HDfprintf(stderr, + "usage: %s [-S] [-G] [-n number_of_groups] \n" + " [-N] [-d] [-q] [-T w_sleep_len] [-t tick_len] [-m max_lag][-B pbs] [-s ps]\n" + "\n" + "-S: do not use VFD SWMR\n" + "-G: old-style type of group\n" + "-n ngroups: the number of groups\n" + "-N: do not use named pipes, \n" + " mainly for running the writer and reader seperately\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. The default value is 4K(4096).\n" + "-T w_sleep_len: Before closing the file, the sleep length in tenths of a second \n" + " on the writer side. The default is 112 tenths of a second \n" + " That is 4*max_lag*tick_len if tick_len is 4 and max_lag is 7. \n" + "-d del_grp: true: delete 1000 groups after creating >1000 groups. \n" + "-q: silence printouts, few messages\n" + "\n", + progname); + HDexit(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) { + HDprintf("H5_basename failed\n"); + TEST_ERROR; + } + + esnprintf(s->progname, sizeof(s->progname), "%s", tfile); + + if (tfile) { + HDfree(tfile); + tfile = NULL; + } + + while ((ch = getopt(argc, argv, "SGNn:T:t:m:B:s:dq")) != -1) { + switch (ch) { + case 'S': + s->use_vfd_swmr = false; + break; + case 'G': + s->old_style_grp = true; + break; + case 'N': + s->use_named_pipes = false; + break; + case 'd': + s->del_grp = true; + break; + case 'n': + case 'T': + case 't': + case 'm': + case 'B': + case 's': + + errno = 0; + tmp = HDstrtoul(optarg, &end, 0); + if (end == optarg || *end != '\0') { + HDprintf("couldn't parse `-%c` argument `%s`\n", ch, optarg); + TEST_ERROR; + } + else if (errno != 0) { + HDprintf("couldn't parse `-%c` argument `%s`\n", ch, optarg); + TEST_ERROR; + } + else if (tmp > UINT_MAX) { + HDprintf("`-%c` argument `%lu` too large\n", ch, tmp); + TEST_ERROR; + } + + if (ch == 'n') + s->nsteps = (unsigned)tmp; + else if (ch == 'T') + s->w_sleep_len = (unsigned)tmp; + else if (ch == 't') + s->tick_len = (unsigned)tmp; + else if (ch == 'm') + s->max_lag = (unsigned)tmp; + else if (ch == 'B') + s->pbs = (unsigned)tmp; + else if (ch == 's') + s->ps = (unsigned)tmp; + break; + case 'q': + verbosity = 0; + break; + case '?': + default: + usage(s->progname); + break; + } + } + argc -= optind; + argv += optind; + + if (argc > 0) { + HDprintf("unexpected command-line arguments\n"); + TEST_ERROR; + } + + /* space for attributes */ + if ((s->one_by_one_sid = H5Screate_simple(1, &dims, &dims)) < 0) { + HDprintf("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; +} + +/* Named Pipe Subroutine: np_wr_send_receive + * Description: + * The writer sends a message to the reader, + * then waits for max_lag ticks, + * then checks the returned message from the reader. + * Return: + * True if succeed + * False if an error occurs in any step above. + * An error is mostly caused by an unexpected + * notification number from the message sent + * by the reader. + */ +static bool +np_wr_send_receive(state_t *s) +{ + + /* Bump up the value of notify to notice the reader to start to read */ + s->np_notify++; + if (HDwrite(s->np_fd_w_to_r, &(s->np_notify), sizeof(int)) < 0) { + HDprintf("HDwrite failed\n"); + TEST_ERROR; + } + + /* Call the end tick */ + if (H5Fvfd_swmr_end_tick(s->file) < 0) + TEST_ERROR; + + /* Sleep for two ticks to wait for the reader's message */ + decisleep(2 * s->tick_len); + + /* Receive the same value from the reader and verify it before + * going to the next step */ + (s->np_verify)++; + if (HDread(s->np_fd_r_to_w, &(s->np_notify), sizeof(int)) < 0) { + HDprintf("HDread failed\n"); + TEST_ERROR; + } + + if (s->np_notify == -1) { + HDprintf("reader failed to verify group or attribute operation.\n"); + TEST_ERROR; + } + + if (s->np_notify != s->np_verify) { + HDprintf("received message %d, expecting %d\n", s->np_notify, s->np_verify); + TEST_ERROR; + } + + return true; + +error: + return false; +} + +/* Named Pipe Subroutine: np_rd_receive + * Description: + * The reader receives a message from the writer, + * then checks if the notification number from + * the writer is expected. + * Return: + * True if succeed + * False if an error occurs in any step above. + * An error is mostly caused by an unexpected + * notification number from the message sent + * by the writer. + */ +static bool +np_rd_receive(state_t *s) +{ + + /* The writer should have bumped up the value of notify. + * Do the same with verify and confirm it */ + s->np_verify++; + + /* Receive the notify that the writer bumped up the value */ + if (HDread(s->np_fd_w_to_r, &(s->np_notify), sizeof(int)) < 0) { + HDprintf("HDread failed\n"); + TEST_ERROR; + } + + if (s->np_notify == -1) { + HDprintf("writer failed to create group or carry out an attribute operation.\n"); + TEST_ERROR; + } + + if (s->np_notify != s->np_verify) { + HDprintf("received message %d, expecting %d\n", s->np_notify, s->np_verify); + TEST_ERROR; + } + + return true; + +error: + return false; +} + +/* Named Pipe Subroutine: np_rd_send + * Description: + * The reader sends an acknowledgement to the writer + * Return: + * True if succeed + * False if an error occurs in sending the message. + */ +static bool +np_rd_send(state_t *s) +{ + + if (HDwrite(s->np_fd_r_to_w, &(s->np_notify), sizeof(int)) < 0) { + H5_FAILED(); + AT(); + HDprintf("HDwrite failed\n"); + return false; + } + else + return true; +} + +/* Named Pipe Subroutine: np_send_error + * Description: + * An error (notification number is 1) message is sent + * either from the reader or the writer. + * A boolean input parameter is used to choose + * either reader or writer. + * Return: + * None + */ +static void +np_send_error(state_t *s, bool writer) +{ + s->np_notify = -1; + if (writer) + HDwrite(s->np_fd_w_to_r, &(s->np_notify), sizeof(int)); + else + HDwrite(s->np_fd_r_to_w, &(s->np_notify), sizeof(int)); +} + +/*------------------------------------------------------------------------- + * Function: create_group + * + * Purpose: Create a group and then close it. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file, named pipe + * 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 +create_group(state_t *s, unsigned int which) +{ + char name[sizeof("/group-9999999999")]; + hid_t g = H5I_INVALID_HID; + + esnprintf(name, sizeof(name), "/group-%u", which); + + if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + HDprintf("H5Gcreate2 failed\n"); + TEST_ERROR; + } + + if (H5Gclose(g) < 0) { + HDprintf("H5Gclose failed\n"); + TEST_ERROR; + } + + return true; + +error: + H5E_BEGIN_TRY + { + H5Gclose(g); + } + H5E_END_TRY; + + return false; +} + +/*------------------------------------------------------------------------- + * Function: delete_group + * + * Purpose: Delete a group + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file, named pipe + * 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 +delete_group(state_t *s, unsigned int which) +{ + char name[sizeof("/group-9999999999")]; + + esnprintf(name, sizeof(name), "/group-%u", which); + + if (H5Ldelete(s->file, name, H5P_DEFAULT) < 0) { + HDprintf("H5Ldelete failed\n"); + TEST_ERROR; + } + + return true; + +error: + + 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; + const char * fifo_writer_to_reader = "./fifo_group_writer_to_reader"; + const char * fifo_reader_to_writer = "./fifo_group_reader_to_writer"; + int fd_writer_to_reader = -1, fd_reader_to_writer = -1; + int notify = 0, verify = 0; + bool wg_ret = false; + + struct timespec start_time, end_time; + double temp_time; + + if (!state_init(&s, argc, argv)) { + HDprintf("state_init failed\n"); + TEST_ERROR; + } + + personality = HDstrstr(s.progname, "vfd_swmr_gfail_"); + + if (personality != NULL && HDstrcmp(personality, "vfd_swmr_gfail_writer") == 0) + writer = true; + else if (personality != NULL && HDstrcmp(personality, "vfd_swmr_gfail_reader") == 0) + writer = false; + else { + HDprintf("unknown personality, expected vfd_swmr_gfail_{reader,writer}\n"); + TEST_ERROR; + } + + /* 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, TRUE, 128, "./group-shadow"); + + /* 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_buf_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) { + HDprintf("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 (writer) + s.file = H5Fcreate(s.filename, H5F_ACC_TRUNC, fcpl, fapl); + else + s.file = H5Fopen(s.filename, H5F_ACC_RDONLY, fapl); + + if (s.file < 0) { + HDprintf("H5Fcreate/open failed\n"); + TEST_ERROR; + } + + /* Use two named pipes(FIFO) to coordinate the writer and reader for + * two-way communication. + * One is for the writer to write to the reader. + * The other one is for the reader to signal the writer. */ + if (s.use_named_pipes && writer) { + /* Writer creates two named pipes(FIFO) */ + if (HDmkfifo(fifo_writer_to_reader, 0600) < 0) { + HDprintf("HDmkfifo failed\n"); + TEST_ERROR; + } + + if (HDmkfifo(fifo_reader_to_writer, 0600) < 0) { + HDprintf("HDmkfifo failed\n"); + TEST_ERROR; + } + } + + /* Both the writer and reader open the pipes */ + if (s.use_named_pipes && (fd_writer_to_reader = HDopen(fifo_writer_to_reader, O_RDWR)) < 0) { + HDprintf("HDopen failed\n"); + TEST_ERROR; + } + + if (s.use_named_pipes && (fd_reader_to_writer = HDopen(fifo_reader_to_writer, O_RDWR)) < 0) { + HDprintf("HDopen failed\n"); + TEST_ERROR; + } + + /* Pass the named pipe information to the struct of state_t s, for attribute tests.*/ + if (s.use_named_pipes) { + s.np_fd_w_to_r = fd_writer_to_reader; + s.np_fd_r_to_w = fd_reader_to_writer; + s.np_notify = notify; + s.np_verify = verify; + } + + if (writer) { + + for (step = 0; step < s.nsteps; step++) { + dbgf(2, "writer: step %d\n", step); + + wg_ret = create_group(&s, step); + if (wg_ret == false) { + np_send_error(&s, true); + HDprintf("create groups failed\n"); + TEST_ERROR; + } + } + if (np_wr_send_receive(&s) == false) { + HDprintf("writer: write group - verification failed.\n"); + TEST_ERROR; + } + + /* Delete 1000 groups if the del_grp option is true. */ + if (s.del_grp && s.nsteps > 1000) { + printf("Deleting groups. \n"); + for (step = s.nsteps - 1; step >= (s.nsteps - 1000); step--) { + dbgf(2, "writer: deleting step %d\n", step); + + wg_ret = delete_group(&s, step); + if (wg_ret == false) { + HDprintf("delete group_operations failed\n"); + TEST_ERROR; + } + } + /* end tick,may be not necessary. */ + if (H5Fvfd_swmr_end_tick(s.file)<0) + TEST_ERROR; + } + + /* May be necessary for the writer to wait a longer time before + closing the file. + The default value is 112 tenths of a second(4*s.tick_len*s.max_lag) + if tick_len is 4 and max_lag is 7. + */ + decisleep(s.w_sleep_len); + } + else { /*Reader */ + if (false == np_rd_receive(&s)) { + TEST_ERROR; + } + + dbgf(2, "reader receives the message.\n"); + if (np_rd_send(&s) == false) { + TEST_ERROR; + } + dbgf(2, "reader sends the message.\n "); + if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { + fprintf(stderr, "HDclock_gettime failed"); + TEST_ERROR; + } + + printf("Reader: call back function: check group names.\n"); + if (H5Literate(s.file, H5_INDEX_NAME, H5_ITER_NATIVE, NULL, op_func, NULL) < 0) { + printf("H5Literate failed \n"); + TEST_ERROR; + } + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { + fprintf(stderr, "HDclock_gettime failed"); + TEST_ERROR; + } + temp_time = TIME_PASSED(start_time, end_time); + fprintf(stdout, "H5Literate: temp time = %lf\n", temp_time); + } + + if (H5Pclose(fapl) < 0) { + HDprintf("H5Pclose failed\n"); + TEST_ERROR; + } + + if (H5Pclose(fcpl) < 0) { + HDprintf("H5Pclose failed\n"); + TEST_ERROR; + } + + if (H5Sclose(s.one_by_one_sid) < 0) { + HDprintf("H5Sclose failed\n"); + TEST_ERROR; + } + + if (H5Fclose(s.file) < 0) { + HDprintf("H5Fclose failed\n"); + TEST_ERROR; + } + + /* Both the writer and reader close the named pipes */ + if (s.use_named_pipes && HDclose(fd_writer_to_reader) < 0) { + HDprintf("HDclose failed\n"); + TEST_ERROR; + } + + if (s.use_named_pipes && HDclose(fd_reader_to_writer) < 0) { + HDprintf("HDclose failed\n"); + TEST_ERROR; + } + + /* Reader finishes last and deletes the named pipes */ + if (s.use_named_pipes && !writer) { + if (HDremove(fifo_writer_to_reader) != 0) { + HDprintf("HDremove failed\n"); + TEST_ERROR; + } + + if (HDremove(fifo_reader_to_writer) != 0) { + HDprintf("HDremove failed\n"); + TEST_ERROR; + } + } + + return EXIT_SUCCESS; + +error: + H5E_BEGIN_TRY + { + H5Pclose(fapl); + H5Pclose(fcpl); + H5Sclose(s.one_by_one_sid); + H5Fclose(s.file); + } + H5E_END_TRY; + + if (s.use_named_pipes && fd_writer_to_reader >= 0) + HDclose(fd_writer_to_reader); + + if (s.use_named_pipes && fd_reader_to_writer >= 0) + HDclose(fd_reader_to_writer); + + if (s.use_named_pipes && !writer) { + HDremove(fifo_writer_to_reader); + HDremove(fifo_reader_to_writer); + } + + return EXIT_FAILURE; +} +/************************************************************ + + Operator function. Prints the name and type of the object + being examined. + + ************************************************************/ +herr_t +op_func(hid_t loc_id, const char *name, const H5L_info_t *info, void *operator_data) +{ + + /* avoid compiler warnings */ + (void)loc_id; + (void)info; + (void)operator_data; + +#if 0 /* Kent for debugging purpose. */ + char * subname; + int grp_num; +#endif + + if (strncmp(name, "group", (size_t)5) != 0) { + printf("Iteration failed: group name is %s\n", name); + return -1; + } + else { +#if 0 /* Kent for debugging purpose. */ + subname = name + 6; + grp_num = atoi((const char *)subname); + if (grp_num > 1450000 && grp_num % 5000 == 0) + dbgf(2, "Group name is %s\n", name); +#endif + return 0; + } +} + + +#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 e430c5ceab4d22a51f9a10b16f3dfdec8fcdd5e3 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 10 Sep 2021 21:00:18 +0000 Subject: Committing clang-format changes --- test/vfd_swmr_gfail_writer.c | 55 ++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/test/vfd_swmr_gfail_writer.c b/test/vfd_swmr_gfail_writer.c index 5d47f8b..f806c48 100644 --- a/test/vfd_swmr_gfail_writer.c +++ b/test/vfd_swmr_gfail_writer.c @@ -12,41 +12,37 @@ /* * Purpose: To demostrate the four issues uncovered during the test plan - * 1.4 part 1. + * 1.4 part 1. * * Setup: - * Writer: + * Writer: * 1) Create an HDF5 file - * 2) Create many groups - * 3) Use the named pipe to send the reader a message to start verifying + * 2) Create many groups + * 3) Use the named pipe to send the reader a message to start verifying * 4) Call H5Fvfd_swmr_end_tick immeidately after sending out the message to the reader - * 5) Sleep for two ticks before receiving a message from the reader that the reader starts verifying - * 6) - * If the option to delete the group is off(by default), - * just sleep for a relatively long time, then close the HDF5 file. - * else - * delete the last 1000 groups that are just created if the total number of created groups is greater than 1000 - * call H5Fvfd_swmr_end_tick - * sleep for a relatively long time, then close the HDF5 file. - * + * 5) Sleep for two ticks before receiving a message from the reader that the reader starts + * verifying 6) If the option to delete the group is off(by default), just sleep for a relatively long time, + * then close the HDF5 file. else delete the last 1000 groups that are just created if the total number of + * created groups is greater than 1000 call H5Fvfd_swmr_end_tick sleep for a relatively long time, then close + * the HDF5 file. + * * Reader: - * 1) Open the HDF5 file - * 2) Wait for the writer's message that the writer finishes creating groups. - * 3) After receiving the message from the writer, send a message back to the writer, - * then call H5Literate to iterate through all the groups. The callback function just checks if the group name's prefix - * is valid. An #if 0 #endif block can help the user easily tune to check the iterated group names. - * 4) HDclock_gettime is used to check the total time of H5Literate call. - * 5) Close the HDF5 file if everything runs successfully. - * - * The number of groups, the tick length, the max lag, the page buffer size, the page size and the sleep duration on the writer - * side before closing the file are configurable. Users can also choose an option to delete 1000 groups. - * We only test to creat the groups with the latest file format. The option to create a group via the earlies file format is - * still there but it is not tested for our purpose. + * 1) Open the HDF5 file + * 2) Wait for the writer's message that the writer finishes creating groups. + * 3) After receiving the message from the writer, send a message back to the writer, + * then call H5Literate to iterate through all the groups. The callback function just checks if + * the group name's prefix is valid. An #if 0 #endif block can help the user easily tune to check the iterated + * group names. 4) HDclock_gettime is used to check the total time of H5Literate call. 5) Close the HDF5 file + * if everything runs successfully. + * + * The number of groups, the tick length, the max lag, the page buffer size, the page size and the + * sleep duration on the writer side before closing the file are configurable. Users can also choose an option + * to delete 1000 groups. We only test to creat the groups with the latest file format. The option to create a + * group via the earlies file format is still there but it is not tested for our purpose. * * Add information on how to duplicate the four issues and the expected design fail. */ - #define H5F_FRIEND /*suppress error about including H5Fpkg */ #include "hdf5.h" @@ -88,8 +84,8 @@ typedef struct { { \ .file = H5I_INVALID_HID, .one_by_one_sid = H5I_INVALID_HID, .filename = "", \ .filetype = H5T_NATIVE_UINT32, .nsteps = 10000, .use_vfd_swmr = true, .old_style_grp = false, \ - .use_named_pipes = true, .w_sleep_len = 112, .tick_len = 4, .max_lag = 7, .ps = 4096, .pbs = 4096, \ - .del_grp = false, .np_fd_w_to_r = -1, .np_fd_r_to_w = -1, .np_notify = 0, .np_verify = 0 \ + .use_named_pipes = true, .w_sleep_len = 112, .tick_len = 4, .max_lag = 7, .ps = 4096, .pbs = 4096, \ + .del_grp = false, .np_fd_w_to_r = -1, .np_fd_r_to_w = -1, .np_notify = 0, .np_verify = 0 \ } /* @@ -584,7 +580,7 @@ main(int argc, char **argv) } } /* end tick,may be not necessary. */ - if (H5Fvfd_swmr_end_tick(s.file)<0) + if (H5Fvfd_swmr_end_tick(s.file) < 0) TEST_ERROR; } @@ -727,7 +723,6 @@ op_func(hid_t loc_id, const char *name, const H5L_info_t *info, void *operator_d } } - #else /* H5_HAVE_WIN32_API */ int -- cgit v0.12 From 54e7dd014bd6e9b57b5508f5bbf3eedbc749b5e0 Mon Sep 17 00:00:00 2001 From: Muqun Yang Date: Mon, 13 Sep 2021 13:39:06 -0500 Subject: 1. Revise the VFD SWMR reader side code to make the expected design fail. JRM will review the change in the future. 2. Add comments on how to repeat the issues discovered when testing the expected design fail. --- src/H5Fvfd_swmr.c | 20 ++++++++ test/vfd_swmr_gfail_writer.c | 113 +++++++++++++++++++++++++++++++++---------- 2 files changed, 108 insertions(+), 25 deletions(-) diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index d7cb830..57c2ecd 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -1014,7 +1014,19 @@ H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, hbool_t entering_api) /* This is ok if we're entering the API, but it should * not happen if we're exiting the API. */ + /* JRM review this */ + /* The following line is added for more meaningful error message when + * the long running API on the reader side exceeds the max_lag of ticks. + * KY 2021-09-02 + * */ + if (!entering_api && tmp_tick_num >= shared->tick_num + shared->vfd_swmr_config.max_lag) { + HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, + "Reader's API time exceeds max_lag of ticks, may increase the value of max_lag."); + } +#if 0 /* Kent */ + /* The original code */ HDassert(entering_api || tmp_tick_num < shared->tick_num + shared->vfd_swmr_config.max_lag); +#endif if (!entering_api) { H5FD_vfd_swmr_record_elapsed_ticks(shared->lf, tmp_tick_num - shared->tick_num); @@ -1102,7 +1114,15 @@ H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, hbool_t entering_api) * case where the new entry is *longer*, because the * extension could overlap with a second entry. */ + + /* JRM review this */ + /* Kent: need to comment out the line to make reader iterate + * a large number of groups + * */ +#if 0 /*Kent*/ HDassert(oent->length == nent->length); +#endif + /* the page has been altered -- evict it and * any contained metadata cache entries. diff --git a/test/vfd_swmr_gfail_writer.c b/test/vfd_swmr_gfail_writer.c index f806c48..4447343 100644 --- a/test/vfd_swmr_gfail_writer.c +++ b/test/vfd_swmr_gfail_writer.c @@ -19,28 +19,87 @@ * 1) Create an HDF5 file * 2) Create many groups * 3) Use the named pipe to send the reader a message to start verifying - * 4) Call H5Fvfd_swmr_end_tick immeidately after sending out the message to the reader - * 5) Sleep for two ticks before receiving a message from the reader that the reader starts - * verifying 6) If the option to delete the group is off(by default), just sleep for a relatively long time, - * then close the HDF5 file. else delete the last 1000 groups that are just created if the total number of - * created groups is greater than 1000 call H5Fvfd_swmr_end_tick sleep for a relatively long time, then close - * the HDF5 file. - * + * 4) Call H5Fvfd_swmr_end_tick immeidately after sending out the message to the reader + * 5) Sleep for two ticks before receiving a message from the reader that informs the reader + * started verifying + * 6) If the option to delete the group is off(by default), just sleep for a relatively long time, + * then close the HDF5 file. + * Else delete the last 1000 groups that are just created if the total number of + * created groups is greater than 1000. + * Call H5Fvfd_swmr_end_tick sleep for a relatively long time, + * then close HDF5 file. * Reader: * 1) Open the HDF5 file - * 2) Wait for the writer's message that the writer finishes creating groups. + * 2) Wait for the writer's message that informs the writer finished creating groups. * 3) After receiving the message from the writer, send a message back to the writer, * then call H5Literate to iterate through all the groups. The callback function just checks if - * the group name's prefix is valid. An #if 0 #endif block can help the user easily tune to check the iterated - * group names. 4) HDclock_gettime is used to check the total time of H5Literate call. 5) Close the HDF5 file - * if everything runs successfully. + * the group name's prefix is valid. + * An #if 0 #endif block can help the user easily tune to check the iterated group names. + * 4) HDclock_gettime is used to check the total time of H5Literate call. + * 5) Close the HDF5 file. * * The number of groups, the tick length, the max lag, the page buffer size, the page size and the - * sleep duration on the writer side before closing the file are configurable. Users can also choose an option - * to delete 1000 groups. We only test to creat the groups with the latest file format. The option to create a - * group via the earlies file format is still there but it is not tested for our purpose. + * sleep duration on the writer side before closing the file are configurable. + * Users can also choose an option to delete 1000 groups after creating a larger number of groups.. + * We only test to creat the groups with the latest file format. The option to create a + * group via the earlies file format is still there. + * + * Issues and expected design fail + * + * The parameter numbers that can reproduce the issues are tested at jelly. + * To duplicate the issues at other machines, the number of groups to be created should be different. + * + * Issue 1: HDassert(oent->length == nent->length) error. + * Need to UNCOMMENT out the HDassert(oent->length == nent->length) at ../src/H5Fvfd_swmr.c. + * May also modify the group number a bit to see the assertion error. + * + * GROUP_n=340000 + * ./vfd_swmr_gfail_writer -q -n $GROUP_n & + * ./vfd_swmr_gfail_reader -n $GROUP_n & + * + * Issue 2: H5C__load_entry(): incorrect metadata checksum after all read attempts addr + * Sometimes the expected + * "Reader's API time exceeds max_lag of ticks, may increase the value of max_lag." may appear + * You may need to modify the group number a bit to see the unexpected error message. + * + * GROUP_n=420000 + * ./vfd_swmr_gfail_writer -q -n $GROUP_n & + * ./vfd_swmr_gfail_reader -n $GROUP_n & + * + * Issue 3: Assertion `length == cache_ptr->page_size || page ......' failed + * This failure occurs when page size and page buffer size change from 4K to 8K. + * This issue seems to be always repeatable with the following number of groups. + * + * GROUP_n=320000 + * ./vfd_swmr_gfail_writer -q -B 8192 -s 8192 -n $GROUP_n & + * ./vfd_swmr_gfail_reader -B 8192 -s 8192 -n $GROUP_n & + + * Issue 4: not enough space to copy index + * To duplicate this failure, the number of groups should be much larger, 2 millions. + * The max_lag and tick_len should also be set to big numbers. + * This issue seems to be always repeatable with the following number of groups. + * + * GROUP_n=2000000 + * ./vfd_swmr_gfail_writer -q -m 40 -t 10 -n $GROUP_n & + * ./vfd_swmr_gfail_reader -m 40 -t 10 -n $GROUP_n & + + * Expected design fail + * + * Writer creates a large number of groups, then deletes the last 1000 groups, + * With the following settings, the expected + * "Reader's API time exceeds max_lag of ticks, may increase the value of max_lag." + * should appear. If not, increases the GROUP_n. + * + * GROUP_n=320000 + * ./vfd_swmr_gfail_writer -q -d -n $GROUP_n & + * ./vfd_swmr_gfail_reader -n $GROUP_n & * - * Add information on how to duplicate the four issues and the expected design fail. + * When increasing the max_lag, we may see the program run normally since + * the reader can finish iterating all the groups within the max_lag of ticks. + * The following program should end normally. If not, increase the max_lag. + * ./vfd_swmr_gfail_writer -m 9 -q -d -n $GROUP_n & + * ./vfd_swmr_gfail_reader -m 9 -n $GROUP_n & + */ #define H5F_FRIEND /*suppress error about including H5Fpkg */ @@ -107,7 +166,7 @@ usage(const char *progname) " mainly for running the writer and reader seperately\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" + "-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. The default value is 4K(4096).\n" @@ -557,12 +616,13 @@ main(int argc, char **argv) wg_ret = create_group(&s, step); if (wg_ret == false) { - np_send_error(&s, true); + if (s.use_named_pipes) + np_send_error(&s, true); HDprintf("create groups failed\n"); TEST_ERROR; } } - if (np_wr_send_receive(&s) == false) { + if (s.use_named_pipes && np_wr_send_receive(&s) == false) { HDprintf("writer: write group - verification failed.\n"); TEST_ERROR; } @@ -592,15 +652,18 @@ main(int argc, char **argv) decisleep(s.w_sleep_len); } else { /*Reader */ - if (false == np_rd_receive(&s)) { - TEST_ERROR; + if(s.use_named_pipes) { + if (false == np_rd_receive(&s)) { + TEST_ERROR; + } + + dbgf(2, "reader receives the message.\n"); + if (np_rd_send(&s) == false) { + TEST_ERROR; + } + dbgf(2, "reader sends the message.\n "); } - dbgf(2, "reader receives the message.\n"); - if (np_rd_send(&s) == false) { - TEST_ERROR; - } - dbgf(2, "reader sends the message.\n "); if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { fprintf(stderr, "HDclock_gettime failed"); TEST_ERROR; -- cgit v0.12 From 50db5f95720e74339b230055558ec9591ee46a74 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 13 Sep 2021 18:47:43 +0000 Subject: Committing clang-format changes --- src/H5Fvfd_swmr.c | 1 - test/vfd_swmr_gfail_writer.c | 42 +++++++++++++++++++++--------------------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index 57c2ecd..69e03a0 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -1122,7 +1122,6 @@ H5F_vfd_swmr_reader_end_of_tick(H5F_t *f, hbool_t entering_api) #if 0 /*Kent*/ HDassert(oent->length == nent->length); #endif - /* the page has been altered -- evict it and * any contained metadata cache entries. diff --git a/test/vfd_swmr_gfail_writer.c b/test/vfd_swmr_gfail_writer.c index 4447343..8635cef 100644 --- a/test/vfd_swmr_gfail_writer.c +++ b/test/vfd_swmr_gfail_writer.c @@ -20,49 +20,49 @@ * 2) Create many groups * 3) Use the named pipe to send the reader a message to start verifying * 4) Call H5Fvfd_swmr_end_tick immeidately after sending out the message to the reader - * 5) Sleep for two ticks before receiving a message from the reader that informs the reader + * 5) Sleep for two ticks before receiving a message from the reader that informs the reader * started verifying * 6) If the option to delete the group is off(by default), just sleep for a relatively long time, - * then close the HDF5 file. + * then close the HDF5 file. * Else delete the last 1000 groups that are just created if the total number of * created groups is greater than 1000. - * Call H5Fvfd_swmr_end_tick sleep for a relatively long time, + * Call H5Fvfd_swmr_end_tick sleep for a relatively long time, * then close HDF5 file. * Reader: * 1) Open the HDF5 file * 2) Wait for the writer's message that informs the writer finished creating groups. * 3) After receiving the message from the writer, send a message back to the writer, * then call H5Literate to iterate through all the groups. The callback function just checks if - * the group name's prefix is valid. + * the group name's prefix is valid. * An #if 0 #endif block can help the user easily tune to check the iterated group names. - * 4) HDclock_gettime is used to check the total time of H5Literate call. + * 4) HDclock_gettime is used to check the total time of H5Literate call. * 5) Close the HDF5 file. * * The number of groups, the tick length, the max lag, the page buffer size, the page size and the - * sleep duration on the writer side before closing the file are configurable. + * sleep duration on the writer side before closing the file are configurable. * Users can also choose an option to delete 1000 groups after creating a larger number of groups.. * We only test to creat the groups with the latest file format. The option to create a * group via the earlies file format is still there. * * Issues and expected design fail * - * The parameter numbers that can reproduce the issues are tested at jelly. + * The parameter numbers that can reproduce the issues are tested at jelly. * To duplicate the issues at other machines, the number of groups to be created should be different. * * Issue 1: HDassert(oent->length == nent->length) error. * Need to UNCOMMENT out the HDassert(oent->length == nent->length) at ../src/H5Fvfd_swmr.c. * May also modify the group number a bit to see the assertion error. * - * GROUP_n=340000 + * GROUP_n=340000 * ./vfd_swmr_gfail_writer -q -n $GROUP_n & * ./vfd_swmr_gfail_reader -n $GROUP_n & * - * Issue 2: H5C__load_entry(): incorrect metadata checksum after all read attempts addr - * Sometimes the expected + * Issue 2: H5C__load_entry(): incorrect metadata checksum after all read attempts addr + * Sometimes the expected * "Reader's API time exceeds max_lag of ticks, may increase the value of max_lag." may appear * You may need to modify the group number a bit to see the unexpected error message. * - * GROUP_n=420000 + * GROUP_n=420000 * ./vfd_swmr_gfail_writer -q -n $GROUP_n & * ./vfd_swmr_gfail_reader -n $GROUP_n & * @@ -70,36 +70,36 @@ * This failure occurs when page size and page buffer size change from 4K to 8K. * This issue seems to be always repeatable with the following number of groups. * - * GROUP_n=320000 + * GROUP_n=320000 * ./vfd_swmr_gfail_writer -q -B 8192 -s 8192 -n $GROUP_n & * ./vfd_swmr_gfail_reader -B 8192 -s 8192 -n $GROUP_n & * Issue 4: not enough space to copy index * To duplicate this failure, the number of groups should be much larger, 2 millions. - * The max_lag and tick_len should also be set to big numbers. + * The max_lag and tick_len should also be set to big numbers. * This issue seems to be always repeatable with the following number of groups. * - * GROUP_n=2000000 + * GROUP_n=2000000 * ./vfd_swmr_gfail_writer -q -m 40 -t 10 -n $GROUP_n & * ./vfd_swmr_gfail_reader -m 40 -t 10 -n $GROUP_n & * Expected design fail * * Writer creates a large number of groups, then deletes the last 1000 groups, - * With the following settings, the expected + * With the following settings, the expected * "Reader's API time exceeds max_lag of ticks, may increase the value of max_lag." - * should appear. If not, increases the GROUP_n. + * should appear. If not, increases the GROUP_n. * - * GROUP_n=320000 + * GROUP_n=320000 * ./vfd_swmr_gfail_writer -q -d -n $GROUP_n & * ./vfd_swmr_gfail_reader -n $GROUP_n & * - * When increasing the max_lag, we may see the program run normally since + * When increasing the max_lag, we may see the program run normally since * the reader can finish iterating all the groups within the max_lag of ticks. * The following program should end normally. If not, increase the max_lag. * ./vfd_swmr_gfail_writer -m 9 -q -d -n $GROUP_n & * ./vfd_swmr_gfail_reader -m 9 -n $GROUP_n & - + */ #define H5F_FRIEND /*suppress error about including H5Fpkg */ @@ -652,11 +652,11 @@ main(int argc, char **argv) decisleep(s.w_sleep_len); } else { /*Reader */ - if(s.use_named_pipes) { + if (s.use_named_pipes) { if (false == np_rd_receive(&s)) { TEST_ERROR; } - + dbgf(2, "reader receives the message.\n"); if (np_rd_send(&s) == false) { TEST_ERROR; -- cgit v0.12 From 7eab511b7a1f4a24e3f70c6de0bb4bc8f4d4a6ac Mon Sep 17 00:00:00 2001 From: Muqun Yang Date: Mon, 13 Sep 2021 15:19:46 -0500 Subject: Add options for users to choose max_lag, tick_len, page size and page buffer size. --- test/vfd_swmr_group_writer.c | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/test/vfd_swmr_group_writer.c b/test/vfd_swmr_group_writer.c index c240ee5..62e12f4 100644 --- a/test/vfd_swmr_group_writer.c +++ b/test/vfd_swmr_group_writer.c @@ -43,6 +43,8 @@ typedef struct { bool attr_test; uint32_t max_lag; uint32_t tick_len; + uint32_t ps; + uint32_t pbs; int np_fd_w_to_r; int np_fd_r_to_w; int np_notify; @@ -56,8 +58,8 @@ typedef struct { .filetype = H5T_NATIVE_UINT32, .asteps = 10, .csteps = 10, .nsteps = 100, \ .update_interval = READER_WAIT_TICKS, .use_vfd_swmr = true, .old_style_grp = false, \ .use_named_pipes = true, .grp_op_pattern = ' ', .grp_op_test = false, .at_pattern = ' ', \ - .attr_test = false, .tick_len = 4, .max_lag = 7, .np_fd_w_to_r = -1, .np_fd_r_to_w = -1, \ - .np_notify = 0, .np_verify = 0 \ + .attr_test = false, .tick_len = 4, .max_lag = 7, .ps = 4096, .pbs = 4096, \ + .np_fd_w_to_r = -1, .np_fd_r_to_w = -1, .np_notify = 0, .np_verify = 0 \ } static void @@ -66,6 +68,7 @@ usage(const char *progname) HDfprintf(stderr, "usage: %s [-S] [-G] [-a steps] [-b] [-c] [-n iterations]\n" " [-N] [-q] [-u numb_ticks] [-A at_pattern] [-O grp_op_pattern]\n" + " [-t tick_len] [-m max_lag][-B pbs] [-s ps] \n" "\n" "-S: do not use VFD SWMR\n" "-G: old-style type of group\n" @@ -76,6 +79,12 @@ usage(const char *progname) "-N: do not use named pipes, \n" " mainly for running the writer and reader seperately\n" "-u numb_ticks: `numb_ticks` for the reader to wait before verification\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. The default value is 4K(4096).\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" @@ -158,7 +167,7 @@ state_init(state_t *s, int argc, char **argv) tfile = NULL; } - while ((ch = getopt(argc, argv, "SGa:bc:n:Nqu:A:O:")) != -1) { + while ((ch = getopt(argc, argv, "SGa:bc:n:Nqu:t:m:B:s:A:O:")) != -1) { switch (ch) { case 'S': s->use_vfd_swmr = false; @@ -170,6 +179,10 @@ state_init(state_t *s, int argc, char **argv) case 'c': case 'n': case 'u': + case 't': + case 'm': + case 'B': + case 's': errno = 0; tmp = HDstrtoul(optarg, &end, 0); if (end == optarg || *end != '\0') { @@ -193,6 +206,14 @@ state_init(state_t *s, int argc, char **argv) s->nsteps = (unsigned)tmp; else if (ch == 'u') s->update_interval = (unsigned)tmp; + else if (ch == 't') + s->tick_len = (unsigned)tmp; + else if (ch == 'm') + s->max_lag = (unsigned)tmp; + else if (ch == 'B') + s->pbs = (unsigned)tmp; + else if (ch == 's') + s->ps = (unsigned)tmp; break; case 'b': s->filetype = H5T_STD_U32BE; @@ -284,6 +305,10 @@ state_init(state_t *s, int argc, char **argv) TEST_ERROR; } + if(s->pbs < s->ps) { + HDprintf("Page buffer size cannot be smaller than the page size.s\n"); + TEST_ERROR; + } if (argc > 0) { HDprintf("unexpected command-line arguments\n"); TEST_ERROR; @@ -4987,20 +5012,20 @@ 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, 4, 7, writer, TRUE, 128, "./group-shadow"); + init_vfd_swmr_config(&config, s.tick_len, s.max_lag, writer, TRUE, 128, "./group-shadow"); /* 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_buf_size, config to vfd_swmr_create_fapl().*/ - if ((fapl = vfd_swmr_create_fapl(!s.old_style_grp, s.use_vfd_swmr, true, 4096, &config)) < 0) { + if ((fapl = vfd_swmr_create_fapl(!s.old_style_grp, s.use_vfd_swmr, true, s.pbs, &config)) < 0) { HDprintf("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, 4096)) < 0) { + if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, s.ps)) < 0) { HDprintf("vfd_swmr_create_fcpl() failed"); TEST_ERROR; } @@ -5049,8 +5074,6 @@ main(int argc, char **argv) s.np_fd_r_to_w = fd_reader_to_writer; s.np_notify = notify; s.np_verify = verify; - s.tick_len = config.tick_len; - s.max_lag = config.max_lag; } /* For attribute test, force the named pipe to communicate in every step. -- cgit v0.12 From 54f414bd564bb7d9cab85b98f144b187ad77feaa Mon Sep 17 00:00:00 2001 From: Songyu Lu Date: Mon, 13 Sep 2021 15:22:57 -0500 Subject: Some minor changes and more comments. --- test/testvfdswmr.sh.in | 4 ++-- test/vfd_swmr_bigset_writer.c | 55 ++++++++++++++++++++++++++++++------------- 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/test/testvfdswmr.sh.in b/test/testvfdswmr.sh.in index 2852f24..4dc1e82 100644 --- a/test/testvfdswmr.sh.in +++ b/test/testvfdswmr.sh.in @@ -1063,7 +1063,7 @@ elif [[ "$HDF5TestExpress" -gt 1 ]]; then # quick run fi # # -for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-d 1 -t" "-d 1 -t -F" "-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" "-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 if [ ${do_many_small:-no} = no ]; then continue fi @@ -1116,7 +1116,7 @@ for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-d 1 -t" "-d 1 -t -F" "-d 1 -V 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 -V" "-d 1 -M" "-d 1 -V -F" "-d 1 -M -F"; do +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 # # Test a few big datasets of one and two dimensions. # diff --git a/test/vfd_swmr_bigset_writer.c b/test/vfd_swmr_bigset_writer.c index 649cf38..bcb3d24 100644 --- a/test/vfd_swmr_bigset_writer.c +++ b/test/vfd_swmr_bigset_writer.c @@ -39,7 +39,9 @@ * the dataset on chunk boundaries. * * For 3D dataset, the extension is always along the first dimension. - * It does not support VDS yet. + * e.g. the chunk size is `l` x `m` x `n`, after `i` iterations, the + * dataset size becomes `i x l` x `m` x `n`. + * It does not test VDS for 3D dataset. * * The reader should be started with the same user-selectable parameters * as the writer: iterations, number of datasets, chunk width and @@ -265,7 +267,7 @@ usage(const char *progname) "-f tick_len: tick length\n" "-g max_lag: maximal lag\n" "-j skip_chunk: skip the Nth (skip_chunk) chunks during chunk writing\n" - "-k part_chunk: the size for partial chunk write\n" + "-k part_chunk: the size for partial chunk write (only along the first dimension)\n" "-l tick_num: expected maximal number of ticks from\n" " the writer's finishing creation to the reader's finishing validation\n" "-m mdc_init_size: the initial size of metadata cache in megabytes (must be between 1 and 32MB)\n" @@ -334,7 +336,8 @@ state_init(state_t *s, int argc, char **argv) esnprintf(s->progname, sizeof(s->progname), "%s", tfile); - HDfree(tfile); + 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) { switch (ch) { @@ -681,6 +684,7 @@ state_init(state_t *s, int argc, char **argv) } } + /* The default is zero, meaning no skip */ if (s->skip_chunk == 1) { fprintf(stderr, "can't skip every chunk\n"); TEST_ERROR; @@ -761,11 +765,14 @@ error: } H5E_END_TRY; - HDfree(tfile); + if (tfile) + HDfree(tfile); - HDfree(s->dataset); + if (s->dataset) + HDfree(s->dataset); - HDfree(s->sources); + if (s->sources) + HDfree(s->sources); return false; } @@ -818,10 +825,16 @@ state_destroy(state_t *s) unsigned long j; if (s->vds != vds_multi) - H5Fvfd_swmr_end_tick(s->file[0]); + if (H5Fvfd_swmr_end_tick(s->file[0]) < 0) { + fprintf(stderr, "H5Fclose failed\n"); + TEST_ERROR; + } else for (j = 0; j < NELMTS(s->file); j++) - H5Fvfd_swmr_end_tick(s->file[j]); + if (H5Fvfd_swmr_end_tick(s->file[j]) < 0) { + fprintf(stderr, "H5Fclose failed\n"); + TEST_ERROR; + } } /* For checking the time spent in file close. It's for running the writer alone */ @@ -857,9 +870,11 @@ state_destroy(state_t *s) TIME_PASSED(start_time, end_time)); } - HDfree(s->dataset); + if (s->dataset) + HDfree(s->dataset); - HDfree(s->sources); + if (s->sources) + HDfree(s->sources); return true; @@ -872,9 +887,11 @@ error: } H5E_END_TRY; - HDfree(s->dataset); + if (s->dataset) + HDfree(s->dataset); - HDfree(s->sources); + if (s->sources) + HDfree(s->sources); return false; } @@ -1102,7 +1119,8 @@ notify_reader(np_state_t *np, unsigned step) TEST_ERROR; } - HDfree(last); + if (last) + HDfree(last); return 0; @@ -1625,8 +1643,9 @@ calc_total_steps(state_t s) /* Calculate the number of steps depending on if partial chunk is enabled. * e.g. the original number of steps is 10 and the size of the chunk along - * the growing dimension is 6. When the size of the partial chunk along the - * growing dimension is 5, the number of steps become 12. + * the growing dimension is 6. The number of elements for this dimension is + * 60. When the size of the partial chunk along the growing dimension is 5 + * (treated as the new chunk size), the number of steps becomes 12. */ if (s.test_3d) { if (s.part_chunk) @@ -2568,7 +2587,8 @@ main(int argc, char **argv) TEST_ERROR; } - HDfree(mat); + if (mat) + HDfree(mat); return EXIT_SUCCESS; @@ -2593,6 +2613,9 @@ error: HDremove(np.fifo_reader_to_writer); } + if (mat) + HDfree(mat); + return EXIT_FAILURE; } #else /* H5_HAVE_WIN32_API */ -- cgit v0.12 From 6c9dfa8c4b0c22da1a07726b1ee2d81898b6fd7d Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 13 Sep 2021 20:23:10 +0000 Subject: Committing clang-format changes --- test/vfd_swmr_group_writer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/vfd_swmr_group_writer.c b/test/vfd_swmr_group_writer.c index 62e12f4..5881300 100644 --- a/test/vfd_swmr_group_writer.c +++ b/test/vfd_swmr_group_writer.c @@ -58,8 +58,8 @@ typedef struct { .filetype = H5T_NATIVE_UINT32, .asteps = 10, .csteps = 10, .nsteps = 100, \ .update_interval = READER_WAIT_TICKS, .use_vfd_swmr = true, .old_style_grp = false, \ .use_named_pipes = true, .grp_op_pattern = ' ', .grp_op_test = false, .at_pattern = ' ', \ - .attr_test = false, .tick_len = 4, .max_lag = 7, .ps = 4096, .pbs = 4096, \ - .np_fd_w_to_r = -1, .np_fd_r_to_w = -1, .np_notify = 0, .np_verify = 0 \ + .attr_test = false, .tick_len = 4, .max_lag = 7, .ps = 4096, .pbs = 4096, .np_fd_w_to_r = -1, \ + .np_fd_r_to_w = -1, .np_notify = 0, .np_verify = 0 \ } static void @@ -305,7 +305,7 @@ state_init(state_t *s, int argc, char **argv) TEST_ERROR; } - if(s->pbs < s->ps) { + if (s->pbs < s->ps) { HDprintf("Page buffer size cannot be smaller than the page size.s\n"); TEST_ERROR; } -- cgit v0.12 From 8d3cf7eb46da53b08cdf694ee291fefacb6c15e3 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 13 Sep 2021 20:26:40 +0000 Subject: Committing clang-format changes --- test/vfd_swmr_bigset_writer.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/vfd_swmr_bigset_writer.c b/test/vfd_swmr_bigset_writer.c index bcb3d24..011440c 100644 --- a/test/vfd_swmr_bigset_writer.c +++ b/test/vfd_swmr_bigset_writer.c @@ -829,12 +829,12 @@ state_destroy(state_t *s) fprintf(stderr, "H5Fclose failed\n"); TEST_ERROR; } - else - for (j = 0; j < NELMTS(s->file); j++) - if (H5Fvfd_swmr_end_tick(s->file[j]) < 0) { - fprintf(stderr, "H5Fclose failed\n"); - TEST_ERROR; - } + else + for (j = 0; j < NELMTS(s->file); j++) + if (H5Fvfd_swmr_end_tick(s->file[j]) < 0) { + fprintf(stderr, "H5Fclose failed\n"); + TEST_ERROR; + } } /* For checking the time spent in file close. It's for running the writer alone */ @@ -1644,7 +1644,7 @@ calc_total_steps(state_t s) /* Calculate the number of steps depending on if partial chunk is enabled. * e.g. the original number of steps is 10 and the size of the chunk along * the growing dimension is 6. The number of elements for this dimension is - * 60. When the size of the partial chunk along the growing dimension is 5 + * 60. When the size of the partial chunk along the growing dimension is 5 * (treated as the new chunk size), the number of steps becomes 12. */ if (s.test_3d) { -- cgit v0.12 From f96583190cf39a35e7784d623252f2d0da6c72c5 Mon Sep 17 00:00:00 2001 From: Muqun Yang Date: Mon, 13 Sep 2021 16:23:07 -0500 Subject: Add vfd_swmr_gfail_writer.c for the "design to fail" test. --- MANIFEST | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST b/MANIFEST index 328d35d..dcdedef 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1421,6 +1421,7 @@ ./test/vfd_swmr_generator.c ./test/vfd_swmr_group_writer.c ./test/vfd_swmr_gperf_writer.c +./test/vfd_swmr_gfail_writer.c ./test/vfd_swmr_reader.c ./test/vfd_swmr_remove_reader.c ./test/vfd_swmr_remove_writer.c -- cgit v0.12 From db4a1755b3e9fb8a14018ec8a44cc9a92d830aac Mon Sep 17 00:00:00 2001 From: Songyu Lu Date: Tue, 14 Sep 2021 11:46:40 -0500 Subject: Changed fprintf to HDfprintf and also printed out the write speed for performance information. --- test/vfd_swmr_bigset_writer.c | 400 ++++++++++++++++++++++-------------------- 1 file changed, 207 insertions(+), 193 deletions(-) diff --git a/test/vfd_swmr_bigset_writer.c b/test/vfd_swmr_bigset_writer.c index 011440c..22ec3fb 100644 --- a/test/vfd_swmr_bigset_writer.c +++ b/test/vfd_swmr_bigset_writer.c @@ -241,7 +241,7 @@ static hsize_t two_dee_max_dims[RANK2], three_dee_max_dims[RANK3]; static void usage(const char *progname) { - fprintf( + HDfprintf( stderr, "usage: %s [-C] [-F] [-M] [-P] [-R] [-S] [-V] [-W] [-a steps] [-b] [-c cols]\n" " [-d dims] [-e depth] [-f tick_len] [-g max_lag] [-j skip_chunk] [-k part_chunk]\n" @@ -291,12 +291,12 @@ make_quadrant_dataspace(state_t *s, quadrant_t *q) { if ((q->space = H5Screate_simple(NELMTS(s->chunk_dims), s->chunk_dims, s->expand_2d ? two_dee_max_dims : s->one_dee_max_dims)) < 0) { - fprintf(stderr, "H5Screate_simple failed\n"); + HDfprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; } if (H5Sselect_hyperslab(q->space, H5S_SELECT_SET, q->start, q->stride, q->count, q->block) < 0) { - fprintf(stderr, "H5Sselect_hyperslab failed\n"); + HDfprintf(stderr, "H5Sselect_hyperslab failed\n"); TEST_ERROR; } @@ -330,7 +330,7 @@ state_init(state_t *s, int argc, char **argv) *s = state_initializer(); if (H5_basename(argv[0], &tfile) < 0) { - fprintf(stderr, "H5_basename failed\n"); + HDfprintf(stderr, "H5_basename failed\n"); TEST_ERROR; } @@ -376,7 +376,7 @@ state_init(state_t *s, int argc, char **argv) strcmp(optarg, "both") == 0) s->expand_2d = true; else { - fprintf(stderr, "bad -d argument %s\n", optarg); + HDfprintf(stderr, "bad -d argument %s\n", optarg); TEST_ERROR; } break; @@ -400,20 +400,20 @@ state_init(state_t *s, int argc, char **argv) errno = 0; tmp = HDstrtoul(optarg, &end, 0); if (end == optarg || *end != '\0') { - fprintf(stderr, "couldn't parse -%c argument %s\n", ch, optarg); + HDfprintf(stderr, "couldn't parse -%c argument %s\n", ch, optarg); TEST_ERROR; } else if (errno != 0) { - fprintf(stderr, "couldn't parse -%c argument %s\n", ch, optarg); + HDfprintf(stderr, "couldn't parse -%c argument %s\n", ch, optarg); TEST_ERROR; } else if (tmp > UINT_MAX) { - fprintf(stderr, "-%c argument %lu too large", ch, tmp); + HDfprintf(stderr, "-%c argument %lu too large", ch, tmp); TEST_ERROR; } if ((ch == 'c' || ch == 'r') && tmp == 0) { - fprintf(stderr, "-%c argument %lu must be >= 1", ch, tmp); + HDfprintf(stderr, "-%c argument %lu must be >= 1", ch, tmp); TEST_ERROR; } @@ -478,28 +478,28 @@ state_init(state_t *s, int argc, char **argv) argv += optind; if (argc > 0) { - fprintf(stderr, "unexpected command-line arguments\n"); + HDfprintf(stderr, "unexpected command-line arguments\n"); TEST_ERROR; } if (s->vds != vds_off && s->expand_2d) { - fprintf(stderr, "virtual datasets and 2D datasets are mutually exclusive\n"); + HDfprintf(stderr, "virtual datasets and 2D datasets are mutually exclusive\n"); TEST_ERROR; } if (s->test_3d) { if (s->depth < 1) { - fprintf(stderr, "The depth of 3D dataset can't be less than 1\n"); + HDfprintf(stderr, "The depth of 3D dataset can't be less than 1\n"); TEST_ERROR; } if (s->expand_2d) { - fprintf(stderr, "3D dataset test doesn't support 2D expansion\n"); + HDfprintf(stderr, "3D dataset test doesn't support 2D expansion\n"); TEST_ERROR; } if (s->vds != vds_off) { - fprintf(stderr, "3D dataset test doesn't support VDS\n"); + HDfprintf(stderr, "3D dataset test doesn't support VDS\n"); TEST_ERROR; } } @@ -544,12 +544,12 @@ state_init(state_t *s, int argc, char **argv) } if ((s->quadrant_dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) { - fprintf(stderr, "H5Pcreate failed\n"); + HDfprintf(stderr, "H5Pcreate failed\n"); TEST_ERROR; } if (H5Pset_chunk(s->quadrant_dcpl, RANK2, half_chunk_dims) < 0) { - fprintf(stderr, "H5Pset_chunk failed\n"); + HDfprintf(stderr, "H5Pset_chunk failed\n"); TEST_ERROR; } @@ -574,22 +574,22 @@ state_init(state_t *s, int argc, char **argv) .count = {1, H5S_UNLIMITED}}; if (!make_quadrant_dataspace(s, ul)) { - fprintf(stderr, "make_quadrant_dataspace failed\n"); + HDfprintf(stderr, "make_quadrant_dataspace failed\n"); TEST_ERROR; } if (!make_quadrant_dataspace(s, ur)) { - fprintf(stderr, "make_quadrant_dataspace failed\n"); + HDfprintf(stderr, "make_quadrant_dataspace failed\n"); TEST_ERROR; } if (!make_quadrant_dataspace(s, bl)) { - fprintf(stderr, "make_quadrant_dataspace failed\n"); + HDfprintf(stderr, "make_quadrant_dataspace failed\n"); TEST_ERROR; } if (!make_quadrant_dataspace(s, br)) { - fprintf(stderr, "make_quadrant_dataspace failed\n"); + HDfprintf(stderr, "make_quadrant_dataspace failed\n"); TEST_ERROR; } @@ -599,50 +599,50 @@ state_init(state_t *s, int argc, char **argv) .count = {1, H5S_UNLIMITED}}; if ((src->space = H5Screate_simple(RANK2, half_chunk_dims, half_max_dims)) < 0) { - fprintf(stderr, "H5Screate_simple failed\n"); + HDfprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; } if (H5Sselect_hyperslab(src->space, H5S_SELECT_SET, src->start, src->stride, src->count, src->block) < 0) { - fprintf(stderr, "H5Sselect_hyperslab failed\n"); + HDfprintf(stderr, "H5Sselect_hyperslab failed\n"); TEST_ERROR; } if ((ul->src_space = H5Screate_simple(RANK2, half_chunk_dims, half_max_dims)) < 0) { - fprintf(stderr, "H5Screate_simple failed\n"); + HDfprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; } if ((ur->src_space = H5Screate_simple(RANK2, half_chunk_dims, half_max_dims)) < 0) { - fprintf(stderr, "H5Screate_simple failed\n"); + HDfprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; } if ((bl->src_space = H5Screate_simple(RANK2, half_chunk_dims, half_max_dims)) < 0) { - fprintf(stderr, "H5Screate_simple failed\n"); + HDfprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; } if ((br->src_space = H5Screate_simple(RANK2, half_chunk_dims, half_max_dims)) < 0) { - fprintf(stderr, "H5Screate_simple failed\n"); + HDfprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; } } /* space for attributes */ if ((s->one_by_one_sid = H5Screate_simple(1, &dims, &dims)) < 0) { - fprintf(stderr, "H5Screate_simple failed\n"); + HDfprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; } if ((s->dataset = HDmalloc(sizeof(hid_t) * s->ndatasets)) == NULL) { - fprintf(stderr, "HDmalloc failed\n"); + HDfprintf(stderr, "HDmalloc failed\n"); TEST_ERROR; } if ((s->sources = HDmalloc(sizeof(*s->sources) * s->ndatasets)) == NULL) { - fprintf(stderr, "HDmalloc failed\n"); + HDfprintf(stderr, "HDmalloc failed\n"); TEST_ERROR; } @@ -658,7 +658,7 @@ state_init(state_t *s, int argc, char **argv) dims3[0] = s->part_chunk; if ((s->memspace = H5Screate_simple(RANK3, dims3, NULL)) < 0) { - fprintf(stderr, "H5Screate_simple failed\n"); + HDfprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; } } @@ -679,19 +679,19 @@ state_init(state_t *s, int argc, char **argv) } if ((s->memspace = H5Screate_simple(RANK2, dims2, NULL)) < 0) { - fprintf(stderr, "H5Screate_simple failed\n"); + HDfprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; } } /* The default is zero, meaning no skip */ if (s->skip_chunk == 1) { - fprintf(stderr, "can't skip every chunk\n"); + HDfprintf(stderr, "can't skip every chunk\n"); TEST_ERROR; } if (s->over_extend == 0) { - fprintf(stderr, "Extension of the dataset can't be zero\n"); + HDfprintf(stderr, "Extension of the dataset can't be zero\n"); TEST_ERROR; } @@ -714,34 +714,34 @@ state_init(state_t *s, int argc, char **argv) else if (personality != NULL && HDstrcmp(personality, "vfd_swmr_bigset_reader") == 0) s->writer = false; else { - fprintf(stderr, "unknown personality, expected vfd_swmr_bigset_{reader,writer}\n"); + HDfprintf(stderr, "unknown personality, expected vfd_swmr_bigset_{reader,writer}\n"); TEST_ERROR; } if ((s->dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) { - fprintf(stderr, "H5Pcreate failed\n"); + HDfprintf(stderr, "H5Pcreate failed\n"); TEST_ERROR; } if (s->chunk_cache_size) { if (H5Pget_chunk_cache(s->dapl, &rdcc_nslots, &rdcc_nbytes, &rdcc_w0) < 0) { - fprintf(stderr, "H5Pget_chunk_cache failed\n"); + HDfprintf(stderr, "H5Pget_chunk_cache failed\n"); TEST_ERROR; } if (H5Pset_chunk_cache(s->dapl, rdcc_nslots, s->chunk_cache_size, rdcc_w0) < 0) { - fprintf(stderr, "H5Pset_chunk_cache failed\n"); + HDfprintf(stderr, "H5Pset_chunk_cache failed\n"); TEST_ERROR; } } if (s->deflate_level > 9) { - fprintf(stderr, "deflation level must be between 0 and 9\n"); + HDfprintf(stderr, "deflation level must be between 0 and 9\n"); TEST_ERROR; } if (s->vds != vds_off && H5Pset_virtual_view(s->dapl, H5D_VDS_FIRST_MISSING) < 0) { - fprintf(stderr, "H5Pset_virtual_view failed\n"); + HDfprintf(stderr, "H5Pset_virtual_view failed\n"); TEST_ERROR; } @@ -784,7 +784,7 @@ state_destroy(state_t *s) struct timespec start_time, end_time; if (H5Pclose(s->dapl) < 0) { - fprintf(stderr, "H5Pclose failed\n"); + HDfprintf(stderr, "H5Pclose failed\n"); TEST_ERROR; } @@ -794,29 +794,29 @@ state_destroy(state_t *s) if (H5Sclose(ul->src_space) < 0 || H5Sclose(ur->src_space) < 0 || H5Sclose(bl->src_space) < 0 || H5Sclose(br->src_space) < 0) { - fprintf(stderr, "H5Sclose failed\n"); + HDfprintf(stderr, "H5Sclose failed\n"); TEST_ERROR; } if (H5Sclose(ul->space) < 0 || H5Sclose(ur->space) < 0 || H5Sclose(bl->space) < 0 || H5Sclose(br->space) < 0) { - fprintf(stderr, "H5Sclose failed\n"); + HDfprintf(stderr, "H5Sclose failed\n"); TEST_ERROR; } if (H5Pclose(s->quadrant_dcpl) < 0) { - fprintf(stderr, "H5Pclose failed\n"); + HDfprintf(stderr, "H5Pclose failed\n"); TEST_ERROR; } } if (H5Sclose(s->one_by_one_sid) < 0) { - fprintf(stderr, "H5Sclose failed\n"); + HDfprintf(stderr, "H5Sclose failed\n"); TEST_ERROR; } if (H5Sclose(s->memspace) < 0) { - fprintf(stderr, "H5Sclose failed\n"); + HDfprintf(stderr, "H5Sclose failed\n"); TEST_ERROR; } @@ -824,23 +824,25 @@ state_destroy(state_t *s) if (s->writer && s->use_vfd_swmr) { unsigned long j; - if (s->vds != vds_multi) + if (s->vds != vds_multi) { if (H5Fvfd_swmr_end_tick(s->file[0]) < 0) { - fprintf(stderr, "H5Fclose failed\n"); + HDfprintf(stderr, "H5Fclose failed\n"); TEST_ERROR; } - else - for (j = 0; j < NELMTS(s->file); j++) - if (H5Fvfd_swmr_end_tick(s->file[j]) < 0) { - fprintf(stderr, "H5Fclose 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"); + TEST_ERROR; + } + } } /* For checking the time spent in file close. It's for running the writer alone */ if (s->do_perf) { if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { - fprintf(stderr, "HDclock_gettime failed"); + HDfprintf(stderr, "HDclock_gettime failed"); TEST_ERROR; } } @@ -854,7 +856,7 @@ state_destroy(state_t *s) continue; if (H5Fclose(fid) < 0) { - fprintf(stderr, "H5Fclose failed\n"); + HDfprintf(stderr, "H5Fclose failed\n"); TEST_ERROR; } } @@ -862,11 +864,11 @@ state_destroy(state_t *s) /* For checking the time spent in file close. It's for running the writer alone */ if (s->do_perf) { if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { - fprintf(stderr, "HDclock_gettime failed"); + HDfprintf(stderr, "HDclock_gettime failed"); TEST_ERROR; } - fprintf(stdout, "File close time (for running the writer alone) = %lf\n", + HDfprintf(stdout, "File close time (for running the writer alone) = %lf seconds\n", TIME_PASSED(start_time, end_time)); } @@ -916,36 +918,36 @@ np_init(np_state_t *np, bool writer) /* If the named pipes are present at the start of the test, remove them */ if (HDaccess(np->fifo_writer_to_reader, F_OK) == 0) if (HDremove(np->fifo_writer_to_reader) != 0) { - fprintf(stderr, "HDremove fifo_writer_to_reader failed\n"); + HDfprintf(stderr, "HDremove fifo_writer_to_reader failed\n"); TEST_ERROR; } if (HDaccess(np->fifo_reader_to_writer, F_OK) == 0) if (HDremove(np->fifo_reader_to_writer) != 0) { - fprintf(stderr, "HDremove fifo_reader_to_writer failed\n"); + HDfprintf(stderr, "HDremove fifo_reader_to_writer failed\n"); TEST_ERROR; } /* Writer creates two named pipes(FIFO) */ if (HDmkfifo(np->fifo_writer_to_reader, 0600) < 0) { - fprintf(stderr, "HDmkfifo fifo_writer_to_reader failed\n"); + HDfprintf(stderr, "HDmkfifo fifo_writer_to_reader failed\n"); TEST_ERROR; } if (HDmkfifo(np->fifo_reader_to_writer, 0600) < 0) { - fprintf(stderr, "HDmkfifo fifo_reader_to_writer failed\n"); + HDfprintf(stderr, "HDmkfifo fifo_reader_to_writer failed\n"); TEST_ERROR; } } /* Both the writer and reader open the pipes */ if ((np->fd_writer_to_reader = HDopen(np->fifo_writer_to_reader, O_RDWR)) < 0) { - fprintf(stderr, "HDopen fifo_writer_to_reader failed\n"); + HDfprintf(stderr, "HDopen fifo_writer_to_reader failed\n"); TEST_ERROR; } if ((np->fd_reader_to_writer = HDopen(np->fifo_reader_to_writer, O_RDWR)) < 0) { - fprintf(stderr, "HDopen fifo_reader_to_writer failed\n"); + HDfprintf(stderr, "HDopen fifo_reader_to_writer failed\n"); TEST_ERROR; } @@ -965,24 +967,24 @@ np_close(np_state_t *np, bool writer) { /* Both the writer and reader close the named pipes */ if (HDclose(np->fd_writer_to_reader) < 0) { - fprintf(stderr, "HDclose fd_writer_to_reader failed\n"); + HDfprintf(stderr, "HDclose fd_writer_to_reader failed\n"); TEST_ERROR; } if (HDclose(np->fd_reader_to_writer) < 0) { - fprintf(stderr, "HDclose fd_reader_to_writer failed\n"); + HDfprintf(stderr, "HDclose fd_reader_to_writer failed\n"); TEST_ERROR; } /* Reader finishes last and deletes the named pipes */ if (!writer) { if (HDremove(np->fifo_writer_to_reader) != 0) { - fprintf(stderr, "HDremove fifo_writer_to_reader failed\n"); + HDfprintf(stderr, "HDremove fifo_writer_to_reader failed\n"); TEST_ERROR; } if (HDremove(np->fifo_reader_to_writer) != 0) { - fprintf(stderr, "HDremove fifo_reader_to_writer failed\n"); + HDfprintf(stderr, "HDremove fifo_reader_to_writer failed\n"); TEST_ERROR; } } @@ -999,12 +1001,12 @@ reader_verify(np_state_t np, int verify) int notify; if (HDread(np.fd_writer_to_reader, ¬ify, sizeof(int)) < 0) { - fprintf(stderr, "HDread failed\n"); + HDfprintf(stderr, "HDread failed\n"); TEST_ERROR; } if (notify != verify) { - fprintf(stderr, "expected %d but read %d\n", verify, notify); + HDfprintf(stderr, "expected %d but read %d\n", verify, notify); TEST_ERROR; } @@ -1025,13 +1027,13 @@ notify_and_wait_for_reader(state_t *s, np_state_t *np) /* Get the time when finishing creation */ if (HDclock_gettime(CLOCK_MONOTONIC, &last) < 0) { - fprintf(stderr, "HDclock_gettime failed\n"); + HDfprintf(stderr, "HDclock_gettime failed\n"); TEST_ERROR; } /* Notify the reader of finishing creation by sending the timestamp */ if (HDwrite(np->fd_writer_to_reader, &last, sizeof(last)) < 0) { - fprintf(stderr, "HDwrite failed\n"); + HDfprintf(stderr, "HDwrite failed\n"); TEST_ERROR; } @@ -1049,12 +1051,12 @@ notify_and_wait_for_reader(state_t *s, np_state_t *np) /* Wait until the reader finishes validating creation */ if (HDread(np->fd_reader_to_writer, ¬ify, sizeof(int)) < 0) { - fprintf(stderr, "HDread failed\n"); + HDfprintf(stderr, "HDread failed\n"); TEST_ERROR; } if (notify != np->verify) { - fprintf(stderr, "expected %d but read %d\n", np->verify, notify); + HDfprintf(stderr, "expected %d but read %d\n", np->verify, notify); TEST_ERROR; } @@ -1075,7 +1077,7 @@ reader_check_time_and_notify_writer(np_state_t *np, state_t s) /* Receive the notice of the writer finishing creation (timestamp) */ if (HDread(np->fd_writer_to_reader, &last, sizeof(last)) < 0) { - fprintf(stderr, "HDread failed\n"); + HDfprintf(stderr, "HDread failed\n"); TEST_ERROR; } @@ -1084,12 +1086,12 @@ reader_check_time_and_notify_writer(np_state_t *np, state_t s) * the validation of dataset creation */ if (below_speed_limit(&last, &(s.ival))) { AT(); - fprintf(stderr, "Warning: dataset validation took too long to finish\n"); + HDfprintf(stderr, "Warning: dataset validation took too long to finish\n"); } /* Notify the writer that dataset validation is finished */ if (HDwrite(np->fd_reader_to_writer, &(np->notify), sizeof(int)) < 0) { - fprintf(stderr, "HDwrite failed\n"); + HDfprintf(stderr, "HDwrite failed\n"); TEST_ERROR; } @@ -1107,7 +1109,7 @@ notify_reader(np_state_t *np, unsigned step) /* Get the time */ if (HDclock_gettime(CLOCK_MONOTONIC, &(last->time)) < 0) { - fprintf(stderr, "HDclock_gettime failed\n"); + HDfprintf(stderr, "HDclock_gettime failed\n"); TEST_ERROR; } @@ -1115,7 +1117,7 @@ notify_reader(np_state_t *np, unsigned step) /* Notify the reader by sending the timestamp and the number of chunks written */ if (HDwrite(np->fd_writer_to_reader, last, sizeof(exchange_info_t)) < 0) { - fprintf(stderr, "HDwrite failed"); + HDfprintf(stderr, "HDwrite failed"); TEST_ERROR; } @@ -1142,39 +1144,39 @@ create_extensible_dset(state_t *s, unsigned int which) esnprintf(dname, sizeof(dname), "/dataset-%d", which); if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) { - fprintf(stderr, "H5Pcreate failed\n"); + HDfprintf(stderr, "H5Pcreate failed\n"); TEST_ERROR; } if (s->test_3d) { /* The chunk is L x M x N and grows along the first dimension */ if (H5Pset_chunk(dcpl, RANK3, dims3) < 0) { - fprintf(stderr, "H5Pset_chunk for 3D dataset failed\n"); + HDfprintf(stderr, "H5Pset_chunk for 3D dataset failed\n"); TEST_ERROR; } } else { if (H5Pset_chunk(dcpl, RANK2, s->chunk_dims) < 0) { - fprintf(stderr, "H5Pset_chunk for 2D dataset failed\n"); + HDfprintf(stderr, "H5Pset_chunk for 2D dataset failed\n"); TEST_ERROR; } } /* Never write fill value when new chunks are allocated */ if (H5Pset_fill_time(dcpl, H5D_FILL_TIME_NEVER) < 0) { - fprintf(stderr, "H5Pset_fill_time failed\n"); + HDfprintf(stderr, "H5Pset_fill_time failed\n"); TEST_ERROR; } /* Early space allocation */ if (H5Pset_alloc_time(dcpl, H5D_ALLOC_TIME_EARLY) < 0) { - fprintf(stderr, "H5Pset_alloc_time failed\n"); + HDfprintf(stderr, "H5Pset_alloc_time failed\n"); TEST_ERROR; } /* GZIP compression */ if (s->deflate_level && H5Pset_deflate(dcpl, s->deflate_level) < 0) { - fprintf(stderr, "H5Pset_deflate failed\n"); + HDfprintf(stderr, "H5Pset_deflate failed\n"); TEST_ERROR; } @@ -1188,75 +1190,75 @@ create_extensible_dset(state_t *s, unsigned int which) if ((srcs->ul = H5Dcreate2(s->file[0], ul_dname, s->filetype, ul->src_space, H5P_DEFAULT, s->quadrant_dcpl, s->dapl)) < 0) { - fprintf(stderr, "H5Dcreate2 failed\n"); + HDfprintf(stderr, "H5Dcreate2 failed\n"); TEST_ERROR; } if ((srcs->ur = H5Dcreate2(s->file[1], ur_dname, s->filetype, ur->src_space, H5P_DEFAULT, s->quadrant_dcpl, s->dapl)) < 0) { - fprintf(stderr, "H5Dcreate2 failed\n"); + HDfprintf(stderr, "H5Dcreate2 failed\n"); TEST_ERROR; } if ((srcs->bl = H5Dcreate2(s->file[2], bl_dname, s->filetype, bl->src_space, H5P_DEFAULT, s->quadrant_dcpl, s->dapl)) < 0) { - fprintf(stderr, "H5Dcreate2 failed\n"); + HDfprintf(stderr, "H5Dcreate2 failed\n"); TEST_ERROR; } if ((srcs->br = H5Dcreate2(s->file[3], br_dname, s->filetype, br->src_space, H5P_DEFAULT, s->quadrant_dcpl, s->dapl)) < 0) { - fprintf(stderr, "H5Dcreate2 failed\n"); + HDfprintf(stderr, "H5Dcreate2 failed\n"); TEST_ERROR; } if (H5Pset_virtual(dcpl, ul->space, s->filename[0], ul_dname, src->space) < 0) { - fprintf(stderr, "H5Pset_virtual failed\n"); + HDfprintf(stderr, "H5Pset_virtual failed\n"); TEST_ERROR; } if (H5Pset_virtual(dcpl, ur->space, s->filename[1], ur_dname, src->space) < 0) { - fprintf(stderr, "H5Pset_virtual failed\n"); + HDfprintf(stderr, "H5Pset_virtual failed\n"); TEST_ERROR; } if (H5Pset_virtual(dcpl, bl->space, s->filename[2], bl_dname, src->space) < 0) { - fprintf(stderr, "H5Pset_virtual failed\n"); + HDfprintf(stderr, "H5Pset_virtual failed\n"); TEST_ERROR; } if (H5Pset_virtual(dcpl, br->space, s->filename[3], br_dname, src->space) < 0) { - fprintf(stderr, "H5Pset_virtual failed\n"); + HDfprintf(stderr, "H5Pset_virtual failed\n"); TEST_ERROR; } } if (s->test_3d) { if ((filespace = H5Screate_simple(RANK3, dims3, three_dee_max_dims)) < 0) { - fprintf(stderr, "H5Screate_simple 3D dataspace failed\n"); + HDfprintf(stderr, "H5Screate_simple 3D dataspace failed\n"); TEST_ERROR; } } else { if ((filespace = H5Screate_simple(RANK2, s->chunk_dims, s->expand_2d ? two_dee_max_dims : s->one_dee_max_dims)) < 0) { - fprintf(stderr, "H5Screate_simple 2D dataspace failed\n"); + HDfprintf(stderr, "H5Screate_simple 2D dataspace failed\n"); TEST_ERROR; } } if ((dset_id = H5Dcreate2(s->file[0], dname, s->filetype, filespace, H5P_DEFAULT, dcpl, s->dapl)) < 0) { - fprintf(stderr, "H5Dcreate2 failed\n"); + HDfprintf(stderr, "H5Dcreate2 failed\n"); TEST_ERROR; } if (H5Sclose(filespace) < 0) { - fprintf(stderr, "H5Sclose failed\n"); + HDfprintf(stderr, "H5Sclose failed\n"); TEST_ERROR; } if (H5Pclose(dcpl) < 0) { - fprintf(stderr, "H5Pclose failed\n"); + HDfprintf(stderr, "H5Pclose failed\n"); TEST_ERROR; } @@ -1283,7 +1285,7 @@ close_extensible_dset(state_t *s, unsigned int which) hid_t dset_id = H5I_INVALID_HID; if (which >= s->ndatasets) { - fprintf(stderr, "index is out of range\n"); + HDfprintf(stderr, "index is out of range\n"); TEST_ERROR; } @@ -1292,7 +1294,7 @@ close_extensible_dset(state_t *s, unsigned int which) dset_id = s->dataset[which]; if (H5Dclose(dset_id) < 0) { - fprintf(stderr, "H5Dclose failed\n"); + HDfprintf(stderr, "H5Dclose failed\n"); TEST_ERROR; } @@ -1303,7 +1305,7 @@ close_extensible_dset(state_t *s, unsigned int which) if (H5Dclose(srcs->ul) < 0 || H5Dclose(srcs->ur) < 0 || H5Dclose(srcs->bl) < 0 || H5Dclose(srcs->br) < 0) { - fprintf(stderr, "H5Dclose failed\n"); + HDfprintf(stderr, "H5Dclose failed\n"); TEST_ERROR; } } @@ -1350,62 +1352,62 @@ open_extensible_dset(state_t *s) } if (i == NUM_ATTEMPTS) { - fprintf(stderr, "chunk verification reached the maximal number of attempts\n"); + HDfprintf(stderr, "chunk verification reached the maximal number of attempts\n"); TEST_ERROR; } if ((dtype = H5Dget_type(dset_id)) < 0) { - fprintf(stderr, "H5Dget_type failed\n"); + HDfprintf(stderr, "H5Dget_type failed\n"); TEST_ERROR; } if (H5Tequal(dtype, s->filetype) <= 0) { - fprintf(stderr, "Unexpected data type\n"); + HDfprintf(stderr, "Unexpected data type\n"); TEST_ERROR; } if ((filespace = H5Dget_space(dset_id)) < 0) { - fprintf(stderr, "H5Dget_space failed\n"); + HDfprintf(stderr, "H5Dget_space failed\n"); TEST_ERROR; } if ((rank = H5Sget_simple_extent_ndims(filespace)) < 0) { - fprintf(stderr, "H5Sget_simple_extent_ndims failed\n"); + HDfprintf(stderr, "H5Sget_simple_extent_ndims failed\n"); TEST_ERROR; } if ((s->test_3d && rank != RANK3) || (!s->test_3d && rank != RANK2)) { - fprintf(stderr, "Unexpected data rank: %d\n", rank); + HDfprintf(stderr, "Unexpected data rank: %d\n", rank); TEST_ERROR; } if (s->test_3d) { if (H5Sget_simple_extent_dims(filespace, dims3, maxdims3) < 0) { - fprintf(stderr, "H5Sget_simple_extent_dims failed\n"); + HDfprintf(stderr, "H5Sget_simple_extent_dims failed\n"); TEST_ERROR; } } else { if (H5Sget_simple_extent_dims(filespace, dims2, maxdims2) < 0) { - fprintf(stderr, "H5Sget_simple_extent_dims failed\n"); + HDfprintf(stderr, "H5Sget_simple_extent_dims failed\n"); TEST_ERROR; } } if (H5Sclose(filespace) < 0) { - fprintf(stderr, "H5Sclose failed\n"); + HDfprintf(stderr, "H5Sclose failed\n"); TEST_ERROR; } if (H5Tclose(dtype) < 0) { - fprintf(stderr, "H5Tclose failed\n"); + HDfprintf(stderr, "H5Tclose failed\n"); TEST_ERROR; } 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]) { - fprintf(stderr, "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE " x %" PRIuHSIZE, + HDfprintf(stderr, "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE " x %" PRIuHSIZE, maxdims3[0], maxdims3[1], maxdims3[2]); TEST_ERROR; } @@ -1414,14 +1416,14 @@ 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]) { - fprintf(stderr, "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE, maxdims2[0], + 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]) { - fprintf(stderr, + HDfprintf(stderr, "Unexpected maximum dimensions %" PRIuHSIZE " x %" PRIuHSIZE " or columns %" PRIuHSIZE, maxdims2[0], maxdims2[1], dims2[1]); @@ -1454,7 +1456,7 @@ create_dsets(state_t s) /* For checking the time spent in dataset creation. It's for running the writer alone */ if (s.do_perf) { if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { - fprintf(stderr, "HDclock_gettime failed"); + HDfprintf(stderr, "HDclock_gettime failed"); TEST_ERROR; } } @@ -1464,18 +1466,18 @@ create_dsets(state_t s) */ for (which = 0; which < s.ndatasets; which++) if (!create_extensible_dset(&s, which)) { - fprintf(stderr, "create_extensible_dset failed: number %u\n", which); + HDfprintf(stderr, "create_extensible_dset failed: number %u\n", which); TEST_ERROR; } /* For checking the time spent in dataset creation. It's for running the writer alone */ if (s.do_perf) { if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { - fprintf(stderr, "HDclock_gettime failed"); + HDfprintf(stderr, "HDclock_gettime failed"); TEST_ERROR; } - fprintf(stdout, "Dataset creation time (for running the writer alone) = %lf\n", + HDfprintf(stdout, "Dataset creation time (for running the writer alone) = %lf seconds\n", TIME_PASSED(start_time, end_time)); } @@ -1495,7 +1497,7 @@ static bool matset(mat_t *mat, unsigned k, unsigned i, unsigned j, uint32_t v) { if (k >= mat->depth || i >= mat->rows || j >= mat->cols) { - fprintf(stderr, "index out of boundary\n"); + HDfprintf(stderr, "index out of boundary\n"); TEST_ERROR; } @@ -1545,7 +1547,7 @@ newmat(state_t s) } if (mat == NULL) { - fprintf(stderr, "HDmalloc failed\n"); + HDfprintf(stderr, "HDmalloc failed\n"); TEST_ERROR; } @@ -1605,7 +1607,7 @@ set_or_verify_matrix(mat_t *mat, unsigned int which, base_t base, bool do_set) if (do_set) { if (!matset(mat, depth, row, col, v)) { - fprintf(stderr, "data initialization failed\n"); + HDfprintf(stderr, "data initialization failed\n"); ret = false; break; } @@ -1673,7 +1675,7 @@ verify_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t bas hid_t dset_id; if (which >= s->ndatasets) { - fprintf(stderr, "the dataset order is bigger than the number of datasets"); + HDfprintf(stderr, "the dataset order is bigger than the number of datasets"); TEST_ERROR; } @@ -1687,7 +1689,7 @@ verify_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t bas count3[0] = s->part_chunk; if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset3, NULL, count3, NULL) < 0) { - fprintf(stderr, "H5Sselect_hyperslab failed\n"); + HDfprintf(stderr, "H5Sselect_hyperslab failed\n"); TEST_ERROR; } } @@ -1709,7 +1711,7 @@ verify_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, base_t bas } if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset2, NULL, count2, NULL) < 0) { - fprintf(stderr, "H5Sselect_hyperslab failed\n"); + HDfprintf(stderr, "H5Sselect_hyperslab failed\n"); TEST_ERROR; } } @@ -1748,14 +1750,14 @@ repeat_verify_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, bas /* Refresh the dataset and try it again */ if (H5Drefresh(dset_id) < 0) { - fprintf(stderr, "H5Drefresh failed\n"); + HDfprintf(stderr, "H5Drefresh failed\n"); TEST_ERROR; } } } if (i == NUM_ATTEMPTS) { - fprintf(stderr, "chunk verification reached the maximal number of attempts\n"); + HDfprintf(stderr, "chunk verification reached the maximal number of attempts\n"); TEST_ERROR; } @@ -1773,7 +1775,7 @@ init_and_write_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, ba dset_id = s->dataset[which]; if (!init_matrix(mat, which, base)) { - fprintf(stderr, "data initialization failed\n"); + HDfprintf(stderr, "data initialization failed\n"); TEST_ERROR; } @@ -1787,7 +1789,7 @@ init_and_write_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, ba /* The chunk dimensions are L x M x N. It grows along the first dimension */ if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset3, NULL, count3, NULL) < 0) { - fprintf(stderr, "H5Sselect_hyperslab for 2D dataset failed\n"); + HDfprintf(stderr, "H5Sselect_hyperslab for 2D dataset failed\n"); TEST_ERROR; } } @@ -1810,13 +1812,13 @@ init_and_write_chunk(state_t *s, hid_t filespace, mat_t *mat, unsigned which, ba } if (H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset2, NULL, count2, NULL) < 0) { - fprintf(stderr, "H5Sselect_hyperslab for 2D dataset failed\n"); + HDfprintf(stderr, "H5Sselect_hyperslab for 2D dataset failed\n"); TEST_ERROR; } } if (H5Dwrite(dset_id, H5T_NATIVE_UINT32, s->memspace, filespace, H5P_DEFAULT, mat->elt) < 0) { - fprintf(stderr, "H5Dwrite failed\n"); + HDfprintf(stderr, "H5Dwrite failed\n"); TEST_ERROR; } @@ -1838,22 +1840,22 @@ verify_dset_attribute(hid_t dset_id, unsigned int which, unsigned int step) dbgf(1, "verifying attribute %s on dataset %u equals %u\n", name, which, step); if ((aid = H5Aopen(dset_id, name, H5P_DEFAULT)) < 0) { - fprintf(stderr, "H5Aopen failed\n"); + HDfprintf(stderr, "H5Aopen failed\n"); TEST_ERROR; } if (H5Aread(aid, H5T_NATIVE_UINT, &read_step) < 0) { - fprintf(stderr, "H5Aread failed\n"); + HDfprintf(stderr, "H5Aread failed\n"); TEST_ERROR; } if (H5Aclose(aid) < 0) { - fprintf(stderr, "H5Aclose failed\n"); + HDfprintf(stderr, "H5Aclose failed\n"); TEST_ERROR; } if (read_step != step) { - fprintf(stderr, "expected %u read %u\n", step, read_step); + HDfprintf(stderr, "expected %u read %u\n", step, read_step); TEST_ERROR; } @@ -1879,7 +1881,7 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini int i; if (which >= s->ndatasets) { - fprintf(stderr, "the dataset order is bigger than the number of datasets"); + HDfprintf(stderr, "the dataset order is bigger than the number of datasets"); TEST_ERROR; } @@ -1889,18 +1891,18 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini * (NUM_ATTEMPTS) before reporting it as a failure */ for (i = 0; i < NUM_ATTEMPTS; i++) { if (H5Drefresh(dset_id) < 0) { - fprintf(stderr, "H5Drefresh failed\n"); + HDfprintf(stderr, "H5Drefresh failed\n"); TEST_ERROR; } if ((filespace = H5Dget_space(dset_id)) < 0) { - fprintf(stderr, "H5Dget_space failed\n"); + HDfprintf(stderr, "H5Dget_space failed\n"); TEST_ERROR; } if (s->test_3d) { if (H5Sget_simple_extent_dims(filespace, size3, NULL) < 0) { - fprintf(stderr, "H5Sget_simple_extent_dims failed\n"); + HDfprintf(stderr, "H5Sget_simple_extent_dims failed\n"); TEST_ERROR; } @@ -1912,7 +1914,7 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini } else { if (H5Sget_simple_extent_dims(filespace, size2, NULL) < 0) { - fprintf(stderr, "H5Sget_simple_extent_dims failed\n"); + HDfprintf(stderr, "H5Sget_simple_extent_dims failed\n"); TEST_ERROR; } @@ -1931,7 +1933,7 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini } if (i == NUM_ATTEMPTS) { - fprintf(stderr, "chunk verification reached the maximal number of attempts"); + HDfprintf(stderr, "chunk verification reached the maximal number of attempts"); TEST_ERROR; } @@ -1991,7 +1993,7 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini if (s->test_3d || !s->expand_2d) { if (!repeat_verify_chunk(s, filespace, mat, which, last)) { - fprintf(stderr, "chunk verification failed\n"); + HDfprintf(stderr, "chunk verification failed\n"); TEST_ERROR; } } @@ -2001,7 +2003,7 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini base.depth = 0; for (base.row = 0; base.row <= last.row; base.row += s->chunk_dims[0]) { if (!repeat_verify_chunk(s, filespace, mat, which, base)) { - fprintf(stderr, "chunk verification failed\n"); + HDfprintf(stderr, "chunk verification failed\n"); TEST_ERROR; } } @@ -2012,7 +2014,7 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini base.row = last.row; for (base.col = 0; base.col < last.col; base.col += s->chunk_dims[1]) { if (!repeat_verify_chunk(s, filespace, mat, which, base)) { - fprintf(stderr, "chunk verification failed\n"); + HDfprintf(stderr, "chunk verification failed\n"); TEST_ERROR; } } @@ -2020,7 +2022,7 @@ verify_extensible_dset(state_t *s, unsigned int which, mat_t *mat, unsigned fini if (s->asteps != 0 && step % s->asteps == 0) { if (!verify_dset_attribute(dset_id, which, step)) { - fprintf(stderr, "verify_dset_attribute failed\n"); + HDfprintf(stderr, "verify_dset_attribute failed\n"); TEST_ERROR; } } @@ -2056,7 +2058,7 @@ verify_dsets(state_t s, np_state_t *np, mat_t *mat) * including the number of chunks finished and the timestamp */ if (s.use_named_pipe && HDread(np->fd_writer_to_reader, &last, sizeof(last)) < 0) { - fprintf(stderr, "HDread failed\n"); + HDfprintf(stderr, "HDread failed\n"); TEST_ERROR; } @@ -2065,7 +2067,7 @@ verify_dsets(state_t s, np_state_t *np, mat_t *mat) * to the ones written in this round */ if (!verify_extensible_dset(&s, which, mat, finished_step, last.step)) { - fprintf(stderr, "verify_extensible_dset failed\n"); + HDfprintf(stderr, "verify_extensible_dset failed\n"); TEST_ERROR; } @@ -2078,7 +2080,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(); - fprintf(stderr, "verify_extensible_dset took too long to finish\n"); + HDfprintf(stderr, "verify_extensible_dset took too long to finish\n"); } /* For checking the time lapse between the writer's finishing writing a batch of chunks @@ -2086,7 +2088,7 @@ verify_dsets(state_t s, np_state_t *np, mat_t *mat) */ if (s.use_named_pipe && s.do_perf) { if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { - fprintf(stderr, "HDclock_gettime failed"); + HDfprintf(stderr, "HDclock_gettime failed"); TEST_ERROR; } @@ -2105,7 +2107,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) - fprintf(stdout, "Dataset verification: mean time = %lf, max time = %lf, min time = %lf\n", + HDfprintf(stdout, "Dataset verification: mean time = %lf, max time = %lf, min time = %lf\n", total_time / (double)counter, max_time, min_time); return true; @@ -2125,17 +2127,17 @@ add_dset_attribute(const state_t *s, hid_t ds, hid_t sid, unsigned int which, un dbgf(1, "setting attribute %s on dataset %u to %u\n", name, which, step); if ((aid = H5Acreate2(ds, name, s->filetype, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) { - fprintf(stderr, "H5Acreate2 failed\n"); + HDfprintf(stderr, "H5Acreate2 failed\n"); TEST_ERROR; } if (H5Awrite(aid, H5T_NATIVE_UINT, &step) < 0) { - fprintf(stderr, "H5Awrite failed\n"); + HDfprintf(stderr, "H5Awrite failed\n"); TEST_ERROR; } if (H5Aclose(aid) < 0) { - fprintf(stderr, "H5Aclose failed\n"); + HDfprintf(stderr, "H5Aclose failed\n"); TEST_ERROR; } @@ -2164,7 +2166,7 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * dbgf(1, "%s: which %u step %u\n", __func__, which, step); if (which >= s->ndatasets) { - fprintf(stderr, "index is out of range\n"); + HDfprintf(stderr, "index is out of range\n"); TEST_ERROR; } @@ -2172,7 +2174,7 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * if (s->asteps != 0 && step % s->asteps == 0) { if (!add_dset_attribute(s, dset_id, s->one_by_one_sid, which, step)) { - fprintf(stderr, "add_dset_attribute failed\n"); + HDfprintf(stderr, "add_dset_attribute failed\n"); TEST_ERROR; } } @@ -2232,22 +2234,22 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * sources_t *const srcs = &s->sources[which]; if (H5Dset_extent(srcs->ul, half_size) < 0) { - fprintf(stderr, "H5Dset_extent failed\n"); + HDfprintf(stderr, "H5Dset_extent failed\n"); TEST_ERROR; } if (H5Dset_extent(srcs->ur, half_size) < 0) { - fprintf(stderr, "H5Dset_extent failed\n"); + HDfprintf(stderr, "H5Dset_extent failed\n"); TEST_ERROR; } if (H5Dset_extent(srcs->bl, half_size) < 0) { - fprintf(stderr, "H5Dset_extent failed\n"); + HDfprintf(stderr, "H5Dset_extent failed\n"); TEST_ERROR; } if (H5Dset_extent(srcs->br, half_size) < 0) { - fprintf(stderr, "H5Dset_extent failed\n"); + HDfprintf(stderr, "H5Dset_extent failed\n"); TEST_ERROR; } } @@ -2256,7 +2258,7 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * if (step % s->over_extend == 0) { if (s->test_3d) { if (size3[0] <= three_dee_max_dims[0] && H5Dset_extent(dset_id, size3) < 0) { - fprintf(stderr, "H5Dset_extent for 3D dataset failed\n"); + HDfprintf(stderr, "H5Dset_extent for 3D dataset failed\n"); TEST_ERROR; } } @@ -2264,7 +2266,7 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * if ((s->expand_2d && size2[0] <= two_dee_max_dims[0] && size2[0] <= two_dee_max_dims[0]) || (!s->expand_2d && size2[1] <= two_dee_max_dims[1])) { if (H5Dset_extent(dset_id, size2) < 0) { - fprintf(stderr, "H5Dset_extent for 2D dataset failed\n"); + HDfprintf(stderr, "H5Dset_extent for 2D dataset failed\n"); TEST_ERROR; } } @@ -2273,13 +2275,13 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * } if ((filespace = H5Dget_space(dset_id)) < 0) { - fprintf(stderr, "H5Dget_space failed\n"); + HDfprintf(stderr, "H5Dget_space failed\n"); TEST_ERROR; } if (s->test_3d || !s->expand_2d) { if (!init_and_write_chunk(s, filespace, mat, which, last)) { - fprintf(stderr, "init_and_write_chunk failed\n"); + HDfprintf(stderr, "init_and_write_chunk failed\n"); TEST_ERROR; } } @@ -2289,7 +2291,7 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * for (base.row = 0; base.row <= last.row; base.row += s->chunk_dims[0]) { dbgf(1, "writing chunk %" PRIuHSIZE ", %" PRIuHSIZE "\n", base.row, base.col); if (!init_and_write_chunk(s, filespace, mat, which, base)) { - fprintf(stderr, "init_and_write_chunk failed\n"); + HDfprintf(stderr, "init_and_write_chunk failed\n"); TEST_ERROR; } } @@ -2298,14 +2300,14 @@ write_extensible_dset(state_t *s, unsigned int which, unsigned int step, mat_t * for (base.col = 0; base.col < last.col; base.col += s->chunk_dims[1]) { dbgf(1, "writing chunk %" PRIuHSIZE ", %" PRIuHSIZE "\n", base.row, base.col); if (!init_and_write_chunk(s, filespace, mat, which, base)) { - fprintf(stderr, "init_and_write_chunk failed\n"); + HDfprintf(stderr, "init_and_write_chunk failed\n"); TEST_ERROR; } } } if (H5Sclose(filespace) < 0) { - fprintf(stderr, "H5Sclose failed\n"); + HDfprintf(stderr, "H5Sclose failed\n"); TEST_ERROR; } @@ -2330,14 +2332,14 @@ write_dsets(state_t s, np_state_t *np, mat_t *mat) struct timespec start_time, end_time; if (NULL == (f = (H5F_t *)H5VL_object(s.file[0]))) { - fprintf(stderr, "H5VL_object failed\n"); + HDfprintf(stderr, "H5VL_object failed\n"); TEST_ERROR; } /* For checking the time spent in writing data. It's for running the writer alone */ if (s.do_perf) { if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { - fprintf(stderr, "HDclock_gettime failed"); + HDfprintf(stderr, "HDclock_gettime failed"); TEST_ERROR; } } @@ -2358,7 +2360,7 @@ write_dsets(state_t s, np_state_t *np, mat_t *mat) for (which = 0; which < s.ndatasets; which++) { dbgf(2, "step %d which %d\n", step, which); if (!write_extensible_dset(&s, which, step, mat)) { - fprintf(stderr, "write_extensible_dset failed\n"); + HDfprintf(stderr, "write_extensible_dset failed\n"); TEST_ERROR; } } @@ -2371,7 +2373,7 @@ write_dsets(state_t s, np_state_t *np, mat_t *mat) if (f->shared->tick_num > old_tick_num || step == (total_steps - 1)) { last_step = step + 1; if (s.use_named_pipe && notify_reader(np, last_step) < 0) { - fprintf(stderr, "notify_reader failed\n"); + HDfprintf(stderr, "notify_reader failed\n"); TEST_ERROR; } @@ -2381,13 +2383,25 @@ write_dsets(state_t s, np_state_t *np, mat_t *mat) /* For checking the time spent in writing data. It's for running the writer alone */ if (s.do_perf) { + double throughput; + double time_passed; + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { - fprintf(stderr, "HDclock_gettime failed"); + HDfprintf(stderr, "HDclock_gettime failed"); TEST_ERROR; } - fprintf(stdout, "Dataset write time (for running the writer alone) = %lf\n", - TIME_PASSED(start_time, end_time)); + time_passed = TIME_PASSED(start_time, end_time); + + /* 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; + else + 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); } return true; @@ -2407,18 +2421,18 @@ main(int argc, char **argv) size_t i; if (!state_init(&s, argc, argv)) { - fprintf(stderr, "state_init failed\n"); + HDfprintf(stderr, "state_init failed\n"); TEST_ERROR; } if ((mat = newmat(s)) == NULL) { - fprintf(stderr, "could not allocate matrix\n"); + HDfprintf(stderr, "could not allocate matrix\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.fsp_size)) < 0) { - fprintf(stderr, "vfd_swmr_create_fcpl failed\n"); + HDfprintf(stderr, "vfd_swmr_create_fcpl failed\n"); TEST_ERROR; } @@ -2438,7 +2452,7 @@ main(int argc, char **argv) /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ if ((fapl = vfd_swmr_create_fapl(true, s.use_vfd_swmr, true, s.page_buf_size, &config)) < 0) { - fprintf(stderr, "vfd_swmr_create_fapl failed"); + HDfprintf(stderr, "vfd_swmr_create_fapl failed"); TEST_ERROR; } @@ -2449,7 +2463,7 @@ main(int argc, char **argv) mdc_config.version = H5AC__CURR_CACHE_CONFIG_VERSION; if (H5Pget_mdc_config(fapl, &mdc_config) < 0) { - fprintf(stderr, "H5Pget_mdc_config failed"); + HDfprintf(stderr, "H5Pget_mdc_config failed"); TEST_ERROR; } @@ -2458,7 +2472,7 @@ main(int argc, char **argv) mdc_config.initial_size = s.mdc_init_size * 1024 * 1024; if (H5Pset_mdc_config(fapl, &mdc_config) < 0) { - fprintf(stderr, "H5Pset_mdc_config failed"); + HDfprintf(stderr, "H5Pset_mdc_config failed"); TEST_ERROR; } } @@ -2467,19 +2481,19 @@ main(int argc, char **argv) : H5Fopen(s.filename[i], H5F_ACC_RDONLY, fapl); if (s.file[i] == badhid) { - fprintf(stderr, s.writer ? "H5Fcreate failed" : "H5Fopen failed"); + HDfprintf(stderr, s.writer ? "H5Fcreate failed" : "H5Fopen failed"); TEST_ERROR; } if (H5Pclose(fapl) < 0) { - fprintf(stderr, "H5Pclose failed\n"); + HDfprintf(stderr, "H5Pclose failed\n"); TEST_ERROR; } } /* Initiailze named pipes */ if (s.use_named_pipe && !np_init(&np, s.writer)) { - fprintf(stderr, "np_init() failed\n"); + HDfprintf(stderr, "np_init() failed\n"); TEST_ERROR; } @@ -2487,13 +2501,13 @@ main(int argc, char **argv) /* Writer tells reader to start */ np.notify = 1; if (s.use_named_pipe && HDwrite(np.fd_writer_to_reader, &np.notify, sizeof(int)) < 0) { - fprintf(stderr, "HDwrite failed\n"); + HDfprintf(stderr, "HDwrite failed\n"); TEST_ERROR; } /* Creates multiple datasets */ if (!create_dsets(s)) { - fprintf(stderr, "create_dsets failed"); + HDfprintf(stderr, "create_dsets failed"); TEST_ERROR; } @@ -2503,14 +2517,14 @@ main(int argc, char **argv) if (s.vds != vds_multi) { if (H5Fvfd_swmr_end_tick(s.file[0]) < 0) { - fprintf(stderr, "H5Fvfd_swmr_end_tick 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) { - fprintf(stderr, "H5Fvfd_swmr_end_tick failed\n"); + HDfprintf(stderr, "H5Fvfd_swmr_end_tick failed\n"); TEST_ERROR; } } @@ -2520,7 +2534,7 @@ main(int argc, char **argv) * and wait for the reader to finish validation before proceeding */ np.verify = 2; if (s.use_named_pipe && notify_and_wait_for_reader(&s, &np) < 0) { - fprintf(stderr, "notify_and_wait_for_reader failed\n"); + HDfprintf(stderr, "notify_and_wait_for_reader failed\n"); TEST_ERROR; } @@ -2535,7 +2549,7 @@ main(int argc, char **argv) /* Wait for the writer's notice before starting the validation of dataset creation */ np.verify = 1; if (s.use_named_pipe && reader_verify(np, np.verify) < 0) { - fprintf(stderr, "reader_verify failed\n"); + HDfprintf(stderr, "reader_verify failed\n"); TEST_ERROR; } @@ -2543,7 +2557,7 @@ main(int argc, char **argv) * the writer during this step. */ if (!open_extensible_dset(&s)) { - fprintf(stderr, "open_extensible_dset failed\n"); + HDfprintf(stderr, "open_extensible_dset failed\n"); TEST_ERROR; } @@ -2553,7 +2567,7 @@ main(int argc, char **argv) * the validation of dataset creation */ np.notify = 2; if (s.use_named_pipe && reader_check_time_and_notify_writer(&np, s) < 0) { - fprintf(stderr, "reader_check_time_and_notify_writer failed\n"); + HDfprintf(stderr, "reader_check_time_and_notify_writer failed\n"); TEST_ERROR; } @@ -2561,29 +2575,29 @@ main(int argc, char **argv) * Both the reader and writer finish by themselves. */ if (!verify_dsets(s, &np, mat)) { - fprintf(stderr, "verify_dsets failed\n"); + HDfprintf(stderr, "verify_dsets failed\n"); TEST_ERROR; } } for (which = 0; which < s.ndatasets; which++) if (!close_extensible_dset(&s, which)) { - fprintf(stderr, "close_extensible_dset failed\n"); + HDfprintf(stderr, "close_extensible_dset failed\n"); TEST_ERROR; } if (H5Pclose(fcpl) < 0) { - fprintf(stderr, "H5Pclose failed\n"); + HDfprintf(stderr, "H5Pclose failed\n"); TEST_ERROR; } if (s.use_named_pipe && !np_close(&np, s.writer)) { - fprintf(stderr, "np_close() failed\n"); + HDfprintf(stderr, "np_close() failed\n"); TEST_ERROR; } if (!state_destroy(&s)) { - fprintf(stderr, "state_destroy failed\n"); + HDfprintf(stderr, "state_destroy failed\n"); TEST_ERROR; } -- cgit v0.12 From 03f90ee196d02ef45e3a570e483d65c407133bd4 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 14 Sep 2021 16:49:15 +0000 Subject: Committing clang-format changes --- test/vfd_swmr_bigset_writer.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/test/vfd_swmr_bigset_writer.c b/test/vfd_swmr_bigset_writer.c index 22ec3fb..956973a 100644 --- a/test/vfd_swmr_bigset_writer.c +++ b/test/vfd_swmr_bigset_writer.c @@ -829,7 +829,7 @@ state_destroy(state_t *s) HDfprintf(stderr, "H5Fclose failed\n"); TEST_ERROR; } - } + } else { for (j = 0; j < NELMTS(s->file); j++) if (H5Fvfd_swmr_end_tick(s->file[j]) < 0) { @@ -869,7 +869,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,8 +1407,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; } } @@ -1416,17 +1417,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]); } } @@ -1478,7 +1479,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; @@ -2108,7 +2109,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; @@ -2395,13 +2396,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 34478970510246c45ffa76d2b868aff90727eda1 Mon Sep 17 00:00:00 2001 From: myang6 Date: Fri, 1 Oct 2021 14:55:16 -0500 Subject: Correct typos for the design-to-fail test. --- test/vfd_swmr_gfail_writer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/vfd_swmr_gfail_writer.c b/test/vfd_swmr_gfail_writer.c index 8635cef..430ed89 100644 --- a/test/vfd_swmr_gfail_writer.c +++ b/test/vfd_swmr_gfail_writer.c @@ -40,9 +40,9 @@ * * The number of groups, the tick length, the max lag, the page buffer size, the page size and the * sleep duration on the writer side before closing the file are configurable. - * Users can also choose an option to delete 1000 groups after creating a larger number of groups.. + * Users can also choose an option to delete 1000 groups after creating a larger number of groups. * We only test to creat the groups with the latest file format. The option to create a - * group via the earlies file format is still there. + * group via the earliest file format is still there. * * Issues and expected design fail * -- cgit v0.12 From a45b73e4275b26505d8b659d1d807a654bb60df7 Mon Sep 17 00:00:00 2001 From: Dana Robinson <43805+derobins@users.noreply.github.com> Date: Tue, 5 Oct 2021 22:37:12 -0700 Subject: VFD SWMR: Normalization with develop (#1078) Brings many changes from develop, particularly VOL changes for async --- CMakeFilters.cmake | 18 +- CMakeLists.txt | 29 +- MANIFEST | 62 +- bin/release | 11 +- bin/trace | 2 - c++/src/H5DataType.cpp | 5 +- c++/src/H5IdComponent.cpp | 5 +- c++/src/H5PropList.cpp | 5 +- c++/src/h5c++.in | 6 +- c++/test/tattr.cpp | 18 +- c++/test/ttypes.cpp | 2 +- config/cmake/ConfigureChecks.cmake | 14 +- config/cmake/H5pubconf.h.in | 15 +- config/cmake/HDF5_Examples.cmake.in | 2 +- config/cmake/HDF5_Examples_options.cmake | 7 +- config/cmake/HDFCXXCompilerFlags.cmake | 316 ++- config/cmake/HDFCompilerFlags.cmake | 303 ++- config/cmake/HDFFortranCompilerFlags.cmake | 7 +- config/cmake/README.txt.cmake.in | 2 +- config/cmake/UseJava.cmake | 838 +++--- config/cmake/UseJavaClassFilelist.cmake | 17 +- config/cmake/UseJavaSymlinks.cmake | 11 +- config/cmake/hdf5-config.cmake.in | 1 + config/cmake/javaTargets.cmake.in | 39 + config/cmake/libh5cc.in | 2 +- config/cmake/libhdf5.settings.cmake.in | 1 + config/cmake/scripts/HDF5config.cmake | 6 +- config/cmake/scripts/HDF5options.cmake | 2 +- config/cmake_ext_mod/ConfigureChecks.cmake | 2 +- config/gnu-fflags | 8 +- config/intel-warnings/18 | 6 - config/intel-warnings/general-19 | 2 - config/intel-warnings/win-developer-general | 1 + config/intel-warnings/win-general | 1 + config/sanitizer/sanitizers.cmake | 8 +- config/toolchain/clang.cmake | 9 +- configure.ac | 35 +- doc/contributing.md | 35 +- doxygen/CMakeLists.txt | 46 + doxygen/Doxyfile.in | 18 +- doxygen/aliases | 100 +- doxygen/dox/APIVersions.dox | 173 ++ doxygen/dox/About.dox | 14 +- doxygen/dox/Cookbook.dox | 16 +- doxygen/dox/H5Acreate.dox | 9 - doxygen/dox/H5Aiterate.dox | 9 - doxygen/dox/H5Fget_info.dox | 44 - doxygen/dox/H5Lget_info.dox | 17 - doxygen/dox/H5Lget_info_by_idx.dox | 17 - doxygen/dox/H5Literate.dox | 20 - doxygen/dox/H5Literate_by_name.dox | 21 - doxygen/dox/H5Lvisit.dox | 20 - doxygen/dox/H5Lvisit_by_name.dox | 20 - doxygen/dox/H5Oget_info.dox | 72 - doxygen/dox/H5Oget_info_by_idx.dox | 55 - doxygen/dox/H5Oget_info_by_name.dox | 58 - doxygen/dox/H5Ovisit.dox | 55 - doxygen/dox/H5Ovisit_by_name.dox | 54 - doxygen/dox/H5Sencode.dox | 5 - doxygen/dox/MetadataCachingInHDF5.dox | 6 +- doxygen/dox/RFC.dox | 91 + doxygen/dox/ReferenceManual.dox | 116 +- doxygen/dox/cookbook/Accessibility.c | 48 + doxygen/dox/cookbook/Accessibility.dox | 39 + doxygen/dox/cookbook/Attributes.c | 61 + doxygen/dox/cookbook/Attributes.dox | 38 + doxygen/dox/cookbook/Files.c | 87 + doxygen/dox/cookbook/Files.dox | 71 + doxygen/dox/cookbook/Performance.dox | 21 + doxygen/dox/maybe_metadata_reads.dox | 68 +- doxygen/dox/rm-template.dox | 171 +- doxygen/examples/H5D_examples.c | 81 +- doxygen/examples/H5E_examples.c | 97 + doxygen/examples/H5F_examples.c | 55 +- doxygen/examples/H5G_examples.c | 186 ++ doxygen/examples/H5I_examples.c | 242 ++ doxygen/examples/H5L_examples.c | 156 ++ doxygen/examples/H5O_examples.c | 193 ++ doxygen/examples/H5PL_examples.c | 97 + doxygen/examples/H5P_examples.c | 227 ++ doxygen/examples/H5R_examples.c | 171 ++ doxygen/examples/H5S_examples.c | 132 + doxygen/examples/H5T_examples.c | 136 + doxygen/examples/H5Z_examples.c | 108 + doxygen/examples/H5_examples.c | 85 + doxygen/hdf5_header.html | 2 +- doxygen/hdf5doxy_layout.xml | 1 + examples/CMakeTests.cmake | 7 +- fortran/src/CMakeLists.txt | 13 + fortran/src/H5Fff.F90 | 4 +- fortran/test/fortranlib_test.F90 | 4 + fortran/test/tH5F.F90 | 122 +- fortran/test/tH5Z.F90 | 7 +- hl/CMakeLists.txt | 12 +- hl/Makefile.am | 5 +- hl/c++/src/H5PacketTable.cpp | 25 +- hl/c++/src/H5PacketTable.h | 20 +- hl/c++/test/ptableTest.cpp | 2 +- hl/examples/ex_table_01.c | 8 +- hl/examples/ex_table_02.c | 10 +- hl/examples/ex_table_03.c | 6 +- hl/examples/ex_table_04.c | 10 +- hl/examples/ex_table_05.c | 4 +- hl/examples/ex_table_06.c | 2 +- hl/examples/ex_table_07.c | 10 +- hl/examples/ex_table_08.c | 10 +- hl/examples/ex_table_09.c | 10 +- hl/examples/ex_table_10.c | 8 +- hl/examples/ex_table_11.c | 10 +- hl/examples/ex_table_12.c | 10 +- hl/src/CMakeLists.txt | 29 + hl/src/H5LT.c | 63 +- hl/src/H5LTpublic.h | 6 + hl/test/gen_test_ds.c | 2 +- hl/test/test_ds.c | 2 + hl/test/test_lite.c | 109 +- hl/test/test_packet.c | 8 +- hl/test/test_table.c | 46 +- hl/tools/h5watch/h5watchgentest.c | 4 +- java/src/hdf/hdf5lib/HDFArray.java | 52 +- java/src/hdf/hdf5lib/HDFNativeData.java | 30 +- java/src/hdf/hdf5lib/structs/H5FD_hdfs_fapl_t.java | 15 +- java/src/hdf/hdf5lib/structs/H5FD_ros3_fapl_t.java | 15 +- java/src/jni/h5Constants.c | 12 +- java/src/jni/h5util.c | 19 +- java/test/TestH5Arw.java | 2 +- java/test/TestH5Pfapl.java | 2 +- release_docs/INSTALL_CMake.txt | 1 + release_docs/README_HDF5_CMake | 17 +- release_docs/RELEASE.txt | 125 +- release_docs/USING_CMake_Examples.txt | 1 + release_docs/USING_HDF5_CMake.txt | 32 +- src/CMakeLists.txt | 3 + src/H5.c | 253 +- src/H5A.c | 355 ++- src/H5ACprivate.h | 16 +- src/H5Adeprec.c | 35 +- src/H5Aint.c | 40 +- src/H5Amodule.h | 24 +- src/H5Apkg.h | 16 +- src/H5Apublic.h | 267 +- src/H5CS.c | 14 +- src/H5CX.c | 453 ++-- src/H5D.c | 391 ++- src/H5Dchunk.c | 83 +- src/H5Ddeprec.c | 31 +- src/H5Dint.c | 27 +- src/H5Dio.c | 91 +- src/H5Dmodule.h | 8 +- src/H5Dpkg.h | 4 +- src/H5Dpublic.h | 567 ++-- src/H5Dvirtual.c | 2 +- src/H5E.c | 35 +- src/H5ES.c | 407 ++- src/H5ESdevelop.h | 50 + src/H5ESevent.c | 16 +- src/H5ESint.c | 434 +++- src/H5ESmodule.h | 6 +- src/H5ESpkg.h | 18 +- src/H5ESprivate.h | 5 +- src/H5ESpublic.h | 70 +- src/H5Eint.c | 22 +- src/H5Emodule.h | 75 +- src/H5Epublic.h | 36 +- src/H5F.c | 794 ++++-- src/H5FDfamily.c | 8 +- src/H5FDhdfs.c | 18 +- src/H5FDhdfs.h | 15 +- src/H5FDlog.c | 2 - src/H5FDmirror.c | 4 +- src/H5FDmulti.c | 8 +- src/H5FDros3.c | 2 + src/H5FDsplitter.c | 22 +- src/H5FL.c | 56 +- src/H5Faccum.c | 2 +- src/H5Fdeprec.c | 53 +- src/H5Fefc.c | 8 +- src/H5Fint.c | 77 +- src/H5Fmodule.h | 19 +- src/H5Fmount.c | 25 +- src/H5Fmpi.c | 45 +- src/H5Fpkg.h | 38 +- src/H5Fprivate.h | 94 +- src/H5Fpublic.h | 4 +- src/H5G.c | 83 +- src/H5Gcompact.c | 18 +- src/H5Gdense.c | 39 +- src/H5Gdeprec.c | 291 ++- src/H5Gloc.c | 62 +- src/H5Gmodule.h | 25 +- src/H5Gname.c | 55 +- src/H5Gobj.c | 21 +- src/H5Gpkg.h | 79 +- src/H5Gprivate.h | 73 +- src/H5Gpublic.h | 2 + src/H5Gstab.c | 26 +- src/H5Gtest.c | 6 +- src/H5I.c | 20 +- src/H5Idbg.c | 4 +- src/H5Iint.c | 36 +- src/H5Imodule.h | 81 +- src/H5Ipublic.h | 33 +- src/H5Itest.c | 10 +- src/H5L.c | 425 ++- src/H5Ldeprec.c | 146 +- src/H5Lexternal.c | 14 +- src/H5Lint.c | 69 +- src/H5Lmodule.h | 25 +- src/H5Lpkg.h | 43 +- src/H5Lprivate.h | 44 - src/H5Lpublic.h | 2 + src/H5M.c | 346 ++- src/H5MF.c | 22 +- src/H5MFprivate.h | 3 +- src/H5Mmodule.h | 6 +- src/H5Mprivate.h | 7 +- src/H5Mpublic.h | 112 + src/H5O.c | 443 ++-- src/H5Ocache.c | 21 +- src/H5Odeprec.c | 155 +- src/H5Oflush.c | 29 +- src/H5Ofsinfo.c | 15 +- src/H5Omodule.h | 41 +- src/H5Opkg.h | 5 + src/H5Oprivate.h | 10 +- src/H5Opublic.h | 679 +---- src/H5PL.c | 2 +- src/H5PLint.c | 6 +- src/H5PLmodule.h | 30 +- src/H5PLplugin_cache.c | 84 +- src/H5Pdapl.c | 4 +- src/H5Pdxpl.c | 8 +- src/H5Pencdec.c | 2 +- src/H5Pfapl.c | 58 + src/H5Pint.c | 3 +- src/H5Plapl.c | 2 +- src/H5Pmodule.h | 164 +- src/H5Ppublic.h | 142 +- src/H5R.c | 199 +- src/H5RS.c | 10 +- src/H5RSprivate.h | 2 +- src/H5Rdeprec.c | 133 +- src/H5Rint.c | 13 +- src/H5Rmodule.h | 29 +- src/H5Rpublic.h | 10 +- src/H5SL.c | 4 +- src/H5SM.c | 2 +- src/H5Smodule.h | 45 +- src/H5Spublic.h | 112 +- src/H5T.c | 19 +- src/H5Tcommit.c | 119 +- src/H5Tconv.c | 120 +- src/H5Tmodule.h | 36 +- src/H5Tprivate.h | 7 +- src/H5Tref.c | 125 +- src/H5Tvlen.c | 50 +- src/H5VL.c | 180 +- src/H5VLcallback.c | 1752 +++++++------ src/H5VLconnector.h | 883 ++++++- src/H5VLconnector_passthru.h | 101 +- src/H5VLdyn_ops.c | 334 +++ src/H5VLint.c | 270 +- src/H5VLmodule.h | 8 +- src/H5VLnative.c | 45 +- src/H5VLnative.h | 387 ++- src/H5VLnative_attr.c | 213 +- src/H5VLnative_blob.c | 34 +- src/H5VLnative_dataset.c | 240 +- src/H5VLnative_datatype.c | 46 +- src/H5VLnative_file.c | 365 +-- src/H5VLnative_group.c | 129 +- src/H5VLnative_introspect.c | 5 +- src/H5VLnative_link.c | 135 +- src/H5VLnative_object.c | 174 +- src/H5VLnative_private.h | 72 +- src/H5VLpassthru.c | 682 ++--- src/H5VLpkg.h | 12 + src/H5VLprivate.h | 116 +- src/H5VLpublic.h | 8 +- src/H5VLtest.c | 96 + src/H5Zmodule.h | 109 +- src/H5Zscaleoffset.c | 58 +- src/H5Ztrans.c | 18 +- src/H5detect.c | 12 +- src/H5module.h | 27 +- src/H5mpi.c | 2 +- src/H5private.h | 52 +- src/H5public.h | 36 +- src/H5system.c | 28 +- src/H5trace.c | 86 +- src/H5win32defs.h | 2 +- src/Makefile.am | 6 +- src/hdf5.h | 2 + test/CMakeTests.cmake | 4 +- test/Makefile.am | 2 +- test/ShellTests.cmake | 118 +- test/big.c | 8 +- test/cache.c | 1118 ++++---- test/chunk_info.c | 52 +- test/cmpd_dset.c | 4 +- test/cve_2020_10810.h5 | Bin 0 -> 1808 bytes test/dsets.c | 378 ++- test/dt_arith.c | 8 +- test/dtransform.c | 97 +- test/dtypes.c | 10 +- test/enc_dec_plist.c | 4 +- test/error_test.c | 4 +- test/event_set.c | 66 + test/fheap.c | 4 +- test/file_image.c | 4 +- test/fillval.c | 6 +- test/gheap.c | 2 +- test/h5test.c | 4 +- test/hyperslab.c | 6 +- test/null_vol_connector.c | 1 + test/ohdr.c | 58 +- test/pool.c | 2 +- test/set_extent.c | 6 +- test/swmr_common.c | 2 +- test/swmr_common.h | 2 +- test/tattr.c | 7 +- test/tconfig.c | 5 +- test/test_usecases.sh.in | 22 +- test/testcheck_version.sh.in | 106 +- test/testhdf5.h | 2 +- test/testswmr.sh.in | 40 +- test/testvdsswmr.sh.in | 16 +- test/tfile.c | 2 +- test/timer.c | 18 +- test/tmeta.c | 4 +- test/tmisc.c | 2 +- test/tsohm.c | 2 +- test/tunicode.c | 2 +- test/tvltypes.c | 8 +- test/vds.c | 12 +- test/vfd.c | 12 +- test/vol.c | 926 ++++++- testpar/t_filters_parallel.c | 403 ++- testpar/t_filters_parallel.h | 20 + tools/lib/h5diff_array.c | 8 +- tools/lib/h5tools_str.c | 3 +- tools/libtest/Makefile.am | 18 +- tools/libtest/h5tools_test_utils.c | 4 +- tools/src/CMakeLists.txt | 5 +- tools/src/Makefile.am | 2 +- tools/src/h5dump/h5dump.c | 78 - tools/src/h5dump/h5dump_ddl.c | 20 +- tools/src/h5dump/h5dump_xml.c | 39 +- tools/src/h5format_convert/h5format_convert.c | 23 +- tools/src/h5import/h5import.c | 7 +- tools/src/h5jam/h5jam.c | 12 +- tools/src/h5jam/h5unjam.c | 10 +- tools/src/h5perf/CMakeLists.txt | 103 + tools/src/h5perf/Makefile.am | 63 + tools/src/h5perf/perf.c | 796 ++++++ tools/src/h5perf/pio_engine.c | 2745 ++++++++++++++++++++ tools/src/h5perf/pio_perf.c | 1718 ++++++++++++ tools/src/h5perf/pio_perf.h | 109 + tools/src/h5perf/sio_engine.c | 1328 ++++++++++ tools/src/h5perf/sio_perf.c | 1301 ++++++++++ tools/src/h5perf/sio_perf.h | 104 + tools/src/h5repack/h5repack_copy.c | 25 +- tools/src/h5stat/h5stat.c | 83 - tools/src/misc/h5clear.c | 39 +- tools/test/h5diff/CMakeTests.cmake | 63 +- tools/test/h5dump/h5dumpgentest.c | 4 +- tools/test/h5jam/h5jamgentest.c | 447 ++-- tools/test/h5repack/h5repacktst.c | 4 +- tools/test/h5stat/CMakeTests.cmake | 2 +- tools/test/h5stat/h5stat_gentest.c | 145 +- tools/test/h5stat/testh5stat.sh.in | 2 +- tools/test/misc/CMakeTestsClear.cmake | 4 +- tools/test/misc/testh5clear.sh.in | 4 +- tools/test/perform/CMakeLists.txt | 81 +- tools/test/perform/Makefile.am | 23 +- tools/test/perform/chunk_cache.c | 6 +- tools/test/perform/perf.c | 471 ---- tools/test/perform/pio_engine.c | 2745 -------------------- tools/test/perform/pio_perf.c | 1699 ------------ tools/test/perform/pio_perf.h | 100 - tools/test/perform/pio_standalone.c | 140 - tools/test/perform/pio_standalone.h | 17 +- tools/test/perform/sio_engine.c | 1328 ---------- tools/test/perform/sio_perf.c | 1437 ---------- tools/test/perform/sio_perf.h | 104 - tools/test/perform/sio_standalone.c | 5 - tools/test/perform/sio_standalone.h | 17 +- tools/test/perform/zip_perf.c | 53 +- 388 files changed, 26663 insertions(+), 17892 deletions(-) create mode 100644 config/cmake/javaTargets.cmake.in delete mode 100644 config/intel-warnings/general-19 create mode 100644 config/intel-warnings/win-developer-general create mode 100644 config/intel-warnings/win-general create mode 100644 doxygen/CMakeLists.txt create mode 100644 doxygen/dox/APIVersions.dox delete mode 100644 doxygen/dox/H5Acreate.dox delete mode 100644 doxygen/dox/H5Aiterate.dox delete mode 100644 doxygen/dox/H5Fget_info.dox delete mode 100644 doxygen/dox/H5Lget_info.dox delete mode 100644 doxygen/dox/H5Lget_info_by_idx.dox delete mode 100644 doxygen/dox/H5Literate.dox delete mode 100644 doxygen/dox/H5Literate_by_name.dox delete mode 100644 doxygen/dox/H5Lvisit.dox delete mode 100644 doxygen/dox/H5Lvisit_by_name.dox delete mode 100644 doxygen/dox/H5Oget_info.dox delete mode 100644 doxygen/dox/H5Oget_info_by_idx.dox delete mode 100644 doxygen/dox/H5Oget_info_by_name.dox delete mode 100644 doxygen/dox/H5Ovisit.dox delete mode 100644 doxygen/dox/H5Ovisit_by_name.dox delete mode 100644 doxygen/dox/H5Sencode.dox create mode 100644 doxygen/dox/RFC.dox create mode 100644 doxygen/dox/cookbook/Accessibility.c create mode 100644 doxygen/dox/cookbook/Accessibility.dox create mode 100644 doxygen/dox/cookbook/Attributes.c create mode 100644 doxygen/dox/cookbook/Attributes.dox create mode 100644 doxygen/dox/cookbook/Files.c create mode 100644 doxygen/dox/cookbook/Files.dox create mode 100644 doxygen/dox/cookbook/Performance.dox create mode 100644 doxygen/examples/H5E_examples.c create mode 100644 doxygen/examples/H5G_examples.c create mode 100644 doxygen/examples/H5I_examples.c create mode 100644 doxygen/examples/H5L_examples.c create mode 100644 doxygen/examples/H5O_examples.c create mode 100644 doxygen/examples/H5PL_examples.c create mode 100644 doxygen/examples/H5P_examples.c create mode 100644 doxygen/examples/H5R_examples.c create mode 100644 doxygen/examples/H5S_examples.c create mode 100644 doxygen/examples/H5T_examples.c create mode 100644 doxygen/examples/H5Z_examples.c create mode 100644 doxygen/examples/H5_examples.c create mode 100644 src/H5ESdevelop.h create mode 100644 src/H5VLdyn_ops.c create mode 100644 src/H5VLtest.c create mode 100644 test/cve_2020_10810.h5 create mode 100644 tools/src/h5perf/CMakeLists.txt create mode 100644 tools/src/h5perf/Makefile.am create mode 100644 tools/src/h5perf/perf.c create mode 100644 tools/src/h5perf/pio_engine.c create mode 100644 tools/src/h5perf/pio_perf.c create mode 100644 tools/src/h5perf/pio_perf.h create mode 100644 tools/src/h5perf/sio_engine.c create mode 100644 tools/src/h5perf/sio_perf.c create mode 100644 tools/src/h5perf/sio_perf.h delete mode 100644 tools/test/perform/perf.c delete mode 100644 tools/test/perform/pio_engine.c delete mode 100644 tools/test/perform/pio_perf.c delete mode 100644 tools/test/perform/pio_perf.h delete mode 100644 tools/test/perform/sio_engine.c delete mode 100644 tools/test/perform/sio_perf.c delete mode 100644 tools/test/perform/sio_perf.h diff --git a/CMakeFilters.cmake b/CMakeFilters.cmake index d5f801e..51ac61c 100644 --- a/CMakeFilters.cmake +++ b/CMakeFilters.cmake @@ -10,6 +10,7 @@ # help@hdfgroup.org. # option (USE_LIBAEC "Use AEC library as SZip Filter" OFF) +option (USE_LIBAEC_STATIC "Use static AEC library " OFF) include (ExternalProject) include (FetchContent) @@ -110,13 +111,24 @@ option (HDF5_ENABLE_SZIP_SUPPORT "Use SZip Filter" OFF) if (HDF5_ENABLE_SZIP_SUPPORT) option (HDF5_ENABLE_SZIP_ENCODING "Use SZip Encoding" OFF) if (NOT SZIP_USE_EXTERNAL) - find_package (SZIP NAMES ${SZIP_PACKAGE_NAME}${HDF_PACKAGE_EXT} COMPONENTS static shared) - if (NOT SZIP_FOUND) - find_package (SZIP) # Legacy find + set(SZIP_FOUND FALSE) + if (USE_LIBAEC) + set(libaec_USE_STATIC_LIBS ${USE_LIBAEC_STATIC}) + find_package (libaec 1.0.5 CONFIG) if (SZIP_FOUND) set (LINK_COMP_LIBS ${LINK_COMP_LIBS} ${SZIP_LIBRARIES}) endif () endif () + + if (NOT SZIP_FOUND) + find_package (SZIP NAMES ${SZIP_PACKAGE_NAME}${HDF_PACKAGE_EXT} COMPONENTS static shared) + if (NOT SZIP_FOUND) + find_package (SZIP) # Legacy find + if (SZIP_FOUND) + set (LINK_COMP_LIBS ${LINK_COMP_LIBS} ${SZIP_LIBRARIES}) + endif () + endif () + endif () endif () if (SZIP_FOUND) set (H5_HAVE_FILTER_SZIP 1) diff --git a/CMakeLists.txt b/CMakeLists.txt index 734d945..11644b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -572,20 +572,6 @@ endif () # endif () #----------------------------------------------------------------------------- -# Option to build documentation -#----------------------------------------------------------------------------- -option (HDF5_BUILD_DOC "Build documentation" OFF) -if (HDF5_BUILD_DOC AND EXISTS "${HDF5_DOXYGEN_DIR}" AND IS_DIRECTORY "${HDF5_DOXYGEN_DIR}") -# check if Doxygen is installed - find_package(Doxygen) - if (DOXYGEN_FOUND) - message(STATUS "Doxygen version: ${DOXYGEN_VERSION}") - else () - message(STATUS "Doxygen needs to be installed to generate the doxygen documentation") - endif () -endif () - -#----------------------------------------------------------------------------- # Option to indicate using a memory checker #----------------------------------------------------------------------------- option (HDF5_ENABLE_USING_MEMCHECKER "Indicate that a memory checker is used" OFF) @@ -931,6 +917,21 @@ if (HDF5_ALLOW_EXTERNAL_SUPPORT MATCHES "GIT" OR HDF5_ALLOW_EXTERNAL_SUPPORT MAT endif () #----------------------------------------------------------------------------- +# Option to build documentation +#----------------------------------------------------------------------------- +option (HDF5_BUILD_DOC "Build documentation" OFF) +if (HDF5_BUILD_DOC AND EXISTS "${HDF5_DOXYGEN_DIR}" AND IS_DIRECTORY "${HDF5_DOXYGEN_DIR}") +# check if Doxygen is installed + find_package(Doxygen) + if (DOXYGEN_FOUND) + message(STATUS "Doxygen version: ${DOXYGEN_VERSION}") + add_subdirectory (doxygen) + else () + message(STATUS "Doxygen needs to be installed to generate the doxygen documentation") + endif () +endif () + +#----------------------------------------------------------------------------- # Dashboard and Testing Settings #----------------------------------------------------------------------------- option (BUILD_TESTING "Build HDF5 Unit Testing" ON) diff --git a/MANIFEST b/MANIFEST index dcdedef..ca1a58c 100644 --- a/MANIFEST +++ b/MANIFEST @@ -202,7 +202,8 @@ ./config/intel-warnings/18 ./config/intel-warnings/developer-general ./config/intel-warnings/general -./config/intel-warnings/general-19 +./config/intel-warnings/win-developer-general +./config/intel-warnings/win-general ./config/intel-warnings/ifort-general ./config/site-specific/BlankForm @@ -219,7 +220,9 @@ ./doc/contributing.md ./doxygen/aliases +./doxygen/CMakeLists.txt ./doxygen/Doxyfile.in +./doxygen/dox/APIVersions.dox ./doxygen/dox/About.dox ./doxygen/dox/Cookbook.dox ./doxygen/dox/DDLBNF110.dox @@ -227,30 +230,23 @@ ./doxygen/dox/FileFormatSpec.dox ./doxygen/dox/GettingStarted.dox ./doxygen/dox/H5AC_cache_config_t.dox -./doxygen/dox/H5Acreate.dox -./doxygen/dox/H5Aiterate.dox -./doxygen/dox/H5Fget_info.dox -./doxygen/dox/H5Lget_info_by_idx.dox -./doxygen/dox/H5Lget_info.dox -./doxygen/dox/H5Literate_by_name.dox -./doxygen/dox/H5Literate.dox -./doxygen/dox/H5Lvisit_by_name.dox -./doxygen/dox/H5Lvisit.dox -./doxygen/dox/H5Oget_info_by_idx.dox -./doxygen/dox/H5Oget_info_by_name.dox -./doxygen/dox/H5Oget_info.dox -./doxygen/dox/H5Ovisit_by_name.dox -./doxygen/dox/H5Ovisit.dox -./doxygen/dox/H5Sencode.dox ./doxygen/dox/MetadataCachingInHDF5.dox ./doxygen/dox/OtherSpecs.dox ./doxygen/dox/Overview.dox ./doxygen/dox/ReferenceManual.dox +./doxygen/dox/RFC.dox ./doxygen/dox/Specifications.dox ./doxygen/dox/TechnicalNotes.dox ./doxygen/dox/api-compat-macros.dox ./doxygen/dox/maybe_metadata_reads.dox ./doxygen/dox/rm-template.dox +./doxygen/dox/cookbook/Accessibility.c +./doxygen/dox/cookbook/Accessibility.dox +./doxygen/dox/cookbook/Attributes.c +./doxygen/dox/cookbook/Attributes.dox +./doxygen/dox/cookbook/Files.c +./doxygen/dox/cookbook/Files.dox +./doxygen/dox/cookbook/Performance.dox ./doxygen/examples/FF-IH_FileGroup.gif ./doxygen/examples/FF-IH_FileObject.gif ./doxygen/examples/FileFormatSpecChunkDiagram.jpg @@ -262,13 +258,25 @@ ./doxygen/examples/H5.format.html ./doxygen/examples/H5A_examples.c ./doxygen/examples/H5D_examples.c +./doxygen/examples/H5E_examples.c ./doxygen/examples/H5Fclose.c ./doxygen/examples/H5Fcreate.c ./doxygen/examples/H5F_examples.c +./doxygen/examples/H5G_examples.c +./doxygen/examples/H5I_examples.c +./doxygen/examples/H5L_examples.c +./doxygen/examples/H5O_examples.c +./doxygen/examples/H5PL_examples.c ./doxygen/examples/H5Pget_metadata_read_attempts.1.c ./doxygen/examples/H5Pget_metadata_read_attempts.2.c ./doxygen/examples/H5Pget_metadata_read_attempts.3.c ./doxygen/examples/H5Pget_object_flush_cb.c +./doxygen/examples/H5P_examples.c +./doxygen/examples/H5R_examples.c +./doxygen/examples/H5S_examples.c +./doxygen/examples/H5T_examples.c +./doxygen/examples/H5Z_examples.c +./doxygen/examples/H5_examples.c ./doxygen/examples/ImageSpec.html ./doxygen/examples/PaletteExample1.gif ./doxygen/examples/Palettes.fm.anc.gif @@ -750,6 +758,7 @@ ./src/H5EAstat.c ./src/H5EAtest.c ./src/H5ES.c +./src/H5ESdevelop.h ./src/H5ESevent.c ./src/H5ESint.c ./src/H5ESlist.c @@ -1106,6 +1115,7 @@ ./src/H5VLcallback.c ./src/H5VLconnector.h ./src/H5VLconnector_passthru.h +./src/H5VLdyn_ops.c ./src/H5VLint.c ./src/H5VLmodule.h ./src/H5VLnative.c @@ -1126,6 +1136,7 @@ ./src/H5VLpkg.h ./src/H5VLprivate.h ./src/H5VLpublic.h +./src/H5VLtest.c ./src/H5VM.c ./src/H5VMprivate.h ./src/H5WB.c @@ -1188,6 +1199,7 @@ ./test/cork.c ./test/corrupt_stab_msg.h5 ./test/cross_read.c +./test/cve_2020_10810.h5 ./test/dangle.c ./test/deflate.h5 ./test/del_many_dense_attrs.c @@ -2992,6 +3004,15 @@ ./tools/testfiles/h5mkgrp_single_p.ls ./tools/testfiles/h5mkgrp_single_l.ls +./tools/src/h5perf/Makefile.am +./tools/src/h5perf/perf.c +./tools/src/h5perf/pio_engine.c +./tools/src/h5perf/pio_perf.c +./tools/src/h5perf/pio_perf.h +./tools/src/h5perf/sio_engine.c +./tools/src/h5perf/sio_perf.c +./tools/src/h5perf/sio_perf.h + ./tools/test/perform/Makefile.am ./tools/test/perform/build_h5perf_alone.sh ./tools/test/perform/build_h5perf_serial_alone.sh @@ -3001,16 +3022,9 @@ ./tools/test/perform/gen_report.pl ./tools/test/perform/iopipe.c ./tools/test/perform/overhead.c -./tools/test/perform/perf.c ./tools/test/perform/perf_meta.c -./tools/test/perform/pio_engine.c -./tools/test/perform/pio_perf.c -./tools/test/perform/pio_perf.h ./tools/test/perform/pio_standalone.c ./tools/test/perform/pio_standalone.h -./tools/test/perform/sio_engine.c -./tools/test/perform/sio_perf.c -./tools/test/perform/sio_perf.h ./tools/test/perform/sio_standalone.c ./tools/test/perform/sio_standalone.h ./tools/test/perform/zip_perf.c @@ -3615,6 +3629,7 @@ ./config/cmake/HDF5PluginMacros.cmake ./config/cmake/HDF5PluginCache.cmake ./config/cmake/HDF5UseFortran.cmake +./config/cmake/javaTargets.cmake.in ./config/cmake/jrunTest.cmake ./config/cmake/jvolTest.cmake ./config/cmake/libh5cc.in @@ -3753,6 +3768,7 @@ ./tools/test/h5stat/CMakeLists.txt ./tools/test/h5stat/CMakeTests.cmake ./tools/src/misc/CMakeLists.txt +./tools/src/h5perf/CMakeLists.txt ./tools/test/misc/CMakeLists.txt ./tools/test/misc/CMakeTestsClear.cmake ./tools/test/misc/CMakeTestsMkgrp.cmake diff --git a/bin/release b/bin/release index 2570b38..8774851 100755 --- a/bin/release +++ b/bin/release @@ -229,11 +229,14 @@ tar2cmakezip() (cd $cmziptmpsubdir; echo "ctest -S HDF5config.cmake,BUILD_GENERATOR=VS201564 -C Release -V -O hdf5.log" > build-VS2015-64.bat; chmod 755 build-VS2015-64.bat) (cd $cmziptmpsubdir; echo "ctest -S HDF5config.cmake,BUILD_GENERATOR=VS2017 -C Release -V -O hdf5.log" > build-VS2017-32.bat; chmod 755 build-VS2017-32.bat) (cd $cmziptmpsubdir; echo "ctest -S HDF5config.cmake,BUILD_GENERATOR=VS201764 -C Release -V -O hdf5.log" > build-VS2017-64.bat; chmod 755 build-VS2017-64.bat) + (cd $cmziptmpsubdir; echo "ctest -S HDF5config.cmake,BUILD_GENERATOR=VS2019 -C Release -V -O hdf5.log" > build-VS2019-32.bat; chmod 755 build-VS2019-32.bat) + (cd $cmziptmpsubdir; echo "ctest -S HDF5config.cmake,BUILD_GENERATOR=VS201964 -C Release -V -O hdf5.log" > build-VS2019-64.bat; chmod 755 build-VS2019-64.bat) # step 3: add LIBAEC.tar.gz, ZLib.tar.gz and cmake files cp /mnt/scr1/pre-release/hdf5/CMake/LIBAEC.tar.gz $cmziptmpsubdir cp /mnt/scr1/pre-release/hdf5/CMake/ZLib.tar.gz $cmziptmpsubdir - cp /mnt/scr1/pre-release/hdf5/CMake/HDF5Examples-1.14.1-Source.zip $cmziptmpsubdir + cp /mnt/scr1/pre-release/hdf5/CMake/HDF5Examples-1.14.4-Source.zip $cmziptmpsubdir + cp /mnt/scr1/pre-release/hdf5/CMake/hdf5_plugins-master.zip $cmziptmpsubdir cp $cmziptmpsubdir/$version/config/cmake/scripts/CTestScript.cmake $cmziptmpsubdir cp $cmziptmpsubdir/$version/config/cmake/scripts/HDF5config.cmake $cmziptmpsubdir cp $cmziptmpsubdir/$version/config/cmake/scripts/HDF5options.cmake $cmziptmpsubdir @@ -328,7 +331,8 @@ tar2cmaketgz() # step 3: add LIBAEC.tar.gz, ZLib.tar.gz and cmake files cp /mnt/scr1/pre-release/hdf5/CMake/LIBAEC.tar.gz $cmgztmpsubdir cp /mnt/scr1/pre-release/hdf5/CMake/ZLib.tar.gz $cmgztmpsubdir - cp /mnt/scr1/pre-release/hdf5/CMake/HDF5Examples-1.14.1-Source.tar.gz $cmgztmpsubdir + cp /mnt/scr1/pre-release/hdf5/CMake/HDF5Examples-1.14.4-Source.tar.gz $cmgztmpsubdir + cp /mnt/scr1/pre-release/hdf5/CMake/hdf5_plugins-master.tar.gz $cmgztmpsubdir cp $cmgztmpsubdir/$version/config/cmake/scripts/CTestScript.cmake $cmgztmpsubdir cp $cmgztmpsubdir/$version/config/cmake/scripts/HDF5config.cmake $cmgztmpsubdir cp $cmgztmpsubdir/$version/config/cmake/scripts/HDF5options.cmake $cmgztmpsubdir @@ -411,7 +415,8 @@ tar2hpccmaketgz() # step 3: add LIBAEC.tar.gz, ZLib.tar.gz and cmake files cp /mnt/scr1/pre-release/hdf5/CMake/LIBAEC.tar.gz $cmgztmpsubdir cp /mnt/scr1/pre-release/hdf5/CMake/ZLib.tar.gz $cmgztmpsubdir - cp /mnt/scr1/pre-release/hdf5/CMake/HDF5Examples-1.14.1-Source.tar.gz $cmgztmpsubdir + cp /mnt/scr1/pre-release/hdf5/CMake/HDF5Examples-1.14.4-Source.tar.gz $cmgztmpsubdir + cp /mnt/scr1/pre-release/hdf5/CMake/hdf5_plugins-master.tar.gz $cmgztmpsubdir cp $cmgztmpsubdir/$version/config/cmake/scripts/CTestScript.cmake $cmgztmpsubdir cp $cmgztmpsubdir/$version/config/cmake/scripts/HDF5config.cmake $cmgztmpsubdir diff --git a/bin/trace b/bin/trace index ba2fcf7..cc26f86 100755 --- a/bin/trace +++ b/bin/trace @@ -162,8 +162,6 @@ $Source = ""; "H5VL_group_get_t" => "Vi", "H5VL_group_specific_t" => "Vj", "H5VL_link_create_t" => "Vk", -# XXX: DELETE LATER - part of combo branch merge - "H5VL_link_create_type_t" => "Vk", "H5VL_link_get_t" => "Vl", "H5VL_get_conn_lvl_t" => "VL", "H5VL_link_specific_t" => "Vm", diff --git a/c++/src/H5DataType.cpp b/c++/src/H5DataType.cpp index b00a526..af58a90 100644 --- a/c++/src/H5DataType.cpp +++ b/c++/src/H5DataType.cpp @@ -338,10 +338,7 @@ DataType::encode() bool DataType::hasBinaryDesc() const { - if (encoded_buf != NULL) - return true; - else - return false; + return encoded_buf != NULL; } //-------------------------------------------------------------------------- diff --git a/c++/src/H5IdComponent.cpp b/c++/src/H5IdComponent.cpp index d546d32..e1fc687 100644 --- a/c++/src/H5IdComponent.cpp +++ b/c++/src/H5IdComponent.cpp @@ -432,10 +432,7 @@ IdComponent::p_valid_id(const hid_t obj_id) return false; H5I_type_t id_type = H5Iget_type(obj_id); - if (id_type <= H5I_BADID || id_type >= H5I_NTYPES) - return false; - else - return true; + return (id_type > H5I_BADID && id_type < H5I_NTYPES); } // Notes about IdComponent::id diff --git a/c++/src/H5PropList.cpp b/c++/src/H5PropList.cpp index 7dca716..7ee8395 100644 --- a/c++/src/H5PropList.cpp +++ b/c++/src/H5PropList.cpp @@ -543,7 +543,7 @@ PropList::getPropSize(const H5std_string &name) const // Function: PropList::getClassName ///\brief Return the name of a generic property list class. ///\return A string containing the class name, if success, otherwise, -/// a NULL string. +/// an empty string. // Programmer: Binh-Minh Ribler - April, 2004 //-------------------------------------------------------------------------- H5std_string @@ -557,8 +557,9 @@ PropList::getClassName() const return (class_name); } else - return 0; + return ""; } + //-------------------------------------------------------------------------- // Function: PropList::getNumProps ///\brief Returns the number of properties in this property list or class. diff --git a/c++/src/h5c++.in b/c++/src/h5c++.in index cf993b9..573d20d 100644 --- a/c++/src/h5c++.in +++ b/c++/src/h5c++.in @@ -35,10 +35,10 @@ HL="@HL@" ## (Advanced usage - know what you're doing - you're on your own here.) ## ## The four variables below can be used to insert paths and flags in ## ## CPPFLAGS, CXXFLAGS, LDFLAGS, or LIBS in the h5cc compile line: ## -## $CLINKER $H5BLD_CPPFLAGS $CPPFLAGS $H5BLD_CXXFLAGS $CXXFLAGS ## +## $CXXLINKER $H5BLD_CPPFLAGS $CPPFLAGS $H5BLD_CXXFLAGS $CXXFLAGS ## ## $LDFLAGS $LIBS $clibpath $link_objs $link_args $shared_link ## ## ## -## These settings can be overridden by setting HDF5_CXXFLAGS, ## +## These settings can be overridden by setting HDF5_CXXFLAGS, ## ## HDF5_CPPFLAGS, HDF5_LDFLAGS, or HDF5_LIBS in the environment. ## ## ## ############################################################################ @@ -93,7 +93,7 @@ H5BLD_LDFLAGS="@AM_LDFLAGS@ @LDFLAGS@" H5BLD_LIBS="@LIBS@" CXX="${HDF5_CXX:-$CXXBASE}" -CXXLINKER="${HDF5_CLINKER:-$CXXLINKERBASE}" +CXXLINKER="${HDF5_CXXLINKER:-$CXXLINKERBASE}" CXXFLAGS="${HDF5_CXXFLAGS:-$CXXFLAGSBASE}" CPPFLAGS="${HDF5_CPPFLAGS:-$CPPFLAGSBASE}" LDFLAGS="${HDF5_LDFLAGS:-$LDFLAGSBASE}" diff --git a/c++/test/tattr.cpp b/c++/test/tattr.cpp index 35db334..26699d2 100644 --- a/c++/test/tattr.cpp +++ b/c++/test/tattr.cpp @@ -285,7 +285,7 @@ test_attr_getname() // Check for existence of attribute FATTR1_NAME bool attr_exists = fid1.attrExists(FATTR1_NAME); - if (attr_exists == false) + if (!attr_exists) throw InvalidActionException("H5File::attrExists", "Attribute should exist but does not"); // Open attribute @@ -361,7 +361,7 @@ test_attr_getname() // Check for existence of attribute attr_exists = dataset.attrExists(ATTR1_NAME); - if (attr_exists == false) + if (!attr_exists) throw InvalidActionException("H5File::attrExists", "Attribute should exist but does not"); // Open attribute @@ -410,7 +410,7 @@ test_attr_rename() // Check for existence of attribute bool attr_exists = fid1.attrExists(FATTR1_NAME); - if (attr_exists == false) + if (!attr_exists) throw InvalidActionException("H5File::attrExists", "Attribute should exist but does not"); // Change attribute name @@ -436,7 +436,7 @@ test_attr_rename() // Check for existence of attribute attr_exists = dataset.attrExists(ATTR1_NAME); - if (attr_exists == false) + if (!attr_exists) throw InvalidActionException("H5File::attrExists", "Attribute should exist but does not"); // Change attribute name @@ -464,7 +464,7 @@ test_attr_rename() // Check for existence of second attribute attr_exists = dataset.attrExists(ATTR2_NAME); - if (attr_exists == false) + if (!attr_exists) throw InvalidActionException("H5File::attrExists", "Attribute should exist but does not"); // Open the second attribute @@ -492,7 +492,7 @@ test_attr_rename() // Check for existence of attribute after renaming attr_exists = dataset.attrExists(ATTR1_NAME); - if (attr_exists == false) + if (!attr_exists) throw InvalidActionException("H5File::attrExists", "Attribute should exist but does not"); PASSED(); @@ -1681,13 +1681,13 @@ test_attr_exists() // Check for existence of attribute bool attr_exists = fid1.attrExists(ATTR1_FL_STR_NAME); - if (attr_exists == false) + if (!attr_exists) throw InvalidActionException("H5File::attrExists", "fid1, ATTR1_FL_STR_NAMEAttribute should exist but does not"); // Check for existence of attribute attr_exists = fid1.attrExists(FATTR1_NAME); - if (attr_exists == false) + if (!attr_exists) throw InvalidActionException("H5File::attrExists", "fid1,FATTR2_NAMEAttribute should exist but does not"); @@ -1696,7 +1696,7 @@ test_attr_exists() // Check for existence of attribute attr_exists = group.attrExists(ATTR2_NAME); - if (attr_exists == false) + if (!attr_exists) throw InvalidActionException("H5File::attrExists", "group, ATTR2_NAMEAttribute should exist but does not"); diff --git a/c++/test/ttypes.cpp b/c++/test/ttypes.cpp index 1cedef6..69c93d1 100644 --- a/c++/test/ttypes.cpp +++ b/c++/test/ttypes.cpp @@ -699,7 +699,7 @@ test_named() } // Check that it is committed. - if (itype.committed() == false) + if (!itype.committed()) cerr << "IntType::committed() returned false" << endl; // We should not be able to modify a type after it has been committed. diff --git a/config/cmake/ConfigureChecks.cmake b/config/cmake/ConfigureChecks.cmake index 7baf77b..263cedf 100644 --- a/config/cmake/ConfigureChecks.cmake +++ b/config/cmake/ConfigureChecks.cmake @@ -149,7 +149,7 @@ if (NOT WINDOWS) OUTPUT_VARIABLE OUTPUT ) if (TEST_DIRECT_VFD_WORKS_COMPILE) - if (TEST_DIRECT_VFD_WORKS_RUN MATCHES 0) + if (TEST_DIRECT_VFD_WORKS_RUN EQUAL "0") HDF_FUNCTION_TEST (HAVE_DIRECT) set (CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_GNU_SOURCE") add_definitions ("-D_GNU_SOURCE") @@ -259,9 +259,9 @@ macro (C_RUN FUNCTION_NAME SOURCE_CODE RETURN_VAR) message (VERBOSE "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ") endif () - if (${COMPILE_RESULT_VAR}) - if (${RUN_RESULT_VAR} MATCHES 0) - set (${RUN_RESULT_VAR} 1 CACHE INTERNAL "Have C function ${FUNCTION_NAME}") + if (COMPILE_RESULT_VAR) + if (RUN_RESULT_VAR EQUAL "0") + set (${RETURN_VAR} 1 CACHE INTERNAL "Have C function ${FUNCTION_NAME}") if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") message (VERBOSE "Testing C ${FUNCTION_NAME} - OK") endif () @@ -273,7 +273,7 @@ macro (C_RUN FUNCTION_NAME SOURCE_CODE RETURN_VAR) if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") message (VERBOSE "Testing C ${FUNCTION_NAME} - Fail") endif () - set (${RUN_RESULT_VAR} 0 CACHE INTERNAL "Have C function ${FUNCTION_NAME}") + set (${RETURN_VAR} 0 CACHE INTERNAL "Have C function ${FUNCTION_NAME}") file (APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if the C ${FUNCTION_NAME} exists failed with the following output:\n" "${OUTPUT_VAR}\n\n") @@ -318,7 +318,7 @@ message (STATUS "Testing maximum decimal precision for C - ${PROG_OUTPUT4}") list (GET PROG_OUTPUT4 0 H5_LDBL_DIG) list (GET PROG_OUTPUT4 1 H5_FLT128_DIG) -if (${HDF_PREFIX}_SIZEOF___FLOAT128 EQUAL 0 OR FLT128_DIG EQUAL 0) +if (${HDF_PREFIX}_SIZEOF___FLOAT128 EQUAL "0" OR FLT128_DIG EQUAL "0") set (${HDF_PREFIX}_HAVE_FLOAT128 0) set (${HDF_PREFIX}_SIZEOF___FLOAT128 0) set (_PAC_C_MAX_REAL_PRECISION ${H5_LDBL_DIG}) @@ -344,7 +344,7 @@ macro (H5ConversionTests TEST msg) OUTPUT_VARIABLE OUTPUT ) if (${TEST}_COMPILE) - if (${TEST}_RUN MATCHES 0) + if (${TEST}_RUN EQUAL "0") set (${TEST} 1 CACHE INTERNAL ${msg}) if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") message (VERBOSE "${msg}... yes") diff --git a/config/cmake/H5pubconf.h.in b/config/cmake/H5pubconf.h.in index 740a0cf..8fd1331 100644 --- a/config/cmake/H5pubconf.h.in +++ b/config/cmake/H5pubconf.h.in @@ -271,6 +271,9 @@ /* Define to 1 if you have the header file. */ #cmakedefine H5_HAVE_PTHREAD_H @H5_HAVE_PTHREAD_H@ +/* Define to 1 if you have the header file. */ +#cmakedefine H5_HAVE_PWD_H @H5_HAVE_PWD_H@ + /* Define to 1 if you have the header file. */ #cmakedefine H5_HAVE_QUADMATH_H @H5_HAVE_QUADMATH_H@ @@ -637,6 +640,12 @@ PTHREAD_SCOPE_SYSTEM) call. */ #cmakedefine H5_SYSTEM_SCOPE_THREADS @H5_SYSTEM_SCOPE_THREADS@ +/* Define using v1.6 public API symbols by default */ +#cmakedefine H5_USE_16_API_DEFAULT @H5_USE_16_API_DEFAULT@ + +/* Define using v1.8 public API symbols by default */ +#cmakedefine H5_USE_18_API_DEFAULT @H5_USE_18_API_DEFAULT@ + /* Define using v1.10 public API symbols by default */ #cmakedefine H5_USE_110_API_DEFAULT @H5_USE_110_API_DEFAULT@ @@ -646,12 +655,6 @@ /* Define using v1.14 public API symbols by default */ #cmakedefine H5_USE_114_API_DEFAULT @H5_USE_114_API_DEFAULT@ -/* Define using v1.6 public API symbols by default */ -#cmakedefine H5_USE_16_API_DEFAULT @H5_USE_16_API_DEFAULT@ - -/* Define using v1.8 public API symbols by default */ -#cmakedefine H5_USE_18_API_DEFAULT @H5_USE_18_API_DEFAULT@ - /* Define if the library will use file locking */ #cmakedefine H5_USE_FILE_LOCKING @H5_USE_FILE_LOCKING@ diff --git a/config/cmake/HDF5_Examples.cmake.in b/config/cmake/HDF5_Examples.cmake.in index 3eea743..2d8dc58 100644 --- a/config/cmake/HDF5_Examples.cmake.in +++ b/config/cmake/HDF5_Examples.cmake.in @@ -77,7 +77,7 @@ set(ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DSITE:STRING=${CTEST_SITE} -DBUILDN #TAR_SOURCE - name of tarfile #if(NOT DEFINED TAR_SOURCE) -# set(CTEST_USE_TAR_SOURCE "HDF5Examples-1.14.1-Source") +# set(CTEST_USE_TAR_SOURCE "HDF5Examples-1.14.4-Source") #endif() ############################################################################################################### diff --git a/config/cmake/HDF5_Examples_options.cmake b/config/cmake/HDF5_Examples_options.cmake index b639b19..cdd49eb 100644 --- a/config/cmake/HDF5_Examples_options.cmake +++ b/config/cmake/HDF5_Examples_options.cmake @@ -42,19 +42,24 @@ ### enable JAVA builds #set(ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DHDF_BUILD_JAVA:BOOL=ON") +############################################################################################# ### enable FILTERS builds #set(ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DHDF_BUILD_FILTERS:BOOL=ON") +### default HDF5_PLUGIN_PATH to where the filter libraries are located +#set(ENV{HDF5_PLUGIN_PATH} "${INSTALLDIR}/lib/plugin") ############################################################################################# ### enable parallel program builds #set(ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DHDF_ENABLE_PARALLEL:BOOL=ON") +############################################################################################# +### match the hdf5 library namespace +set(ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DHDF5_NAMESPACE:STRING=hdf5::") ############################################################################################# ### enable threadsafe program builds #set(ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DHDF_ENABLE_THREADSAFE:BOOL=ON") - ############################################################################################# ### enable test program builds, requires reference files in testfiles subdirectory #set(ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DBUILD_TESTING:BOOL=ON") diff --git a/config/cmake/HDFCXXCompilerFlags.cmake b/config/cmake/HDFCXXCompilerFlags.cmake index bd14a0d..a121d0a 100644 --- a/config/cmake/HDFCXXCompilerFlags.cmake +++ b/config/cmake/HDFCXXCompilerFlags.cmake @@ -9,17 +9,49 @@ # If you do not have access to either file, you may request a copy from # help@hdfgroup.org. # -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED TRUE) -set(CMAKE_CXX_EXTENSIONS OFF) +ENABLE_LANGUAGE (CXX) + +set (CMAKE_CXX_STANDARD 11) +set (CMAKE_CXX_STANDARD_REQUIRED TRUE) + +set (CMAKE_CXX_EXTENSIONS OFF) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_SANITIZER_FLAGS} ${CMAKE_CXX_FLAGS}") if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") - message (VERBOSE "Warnings Configuration: CXX default: ${CMAKE_CXX_FLAGS}") + message (VERBOSE "Warnings Configuration: CXX default: ${CMAKE_CXX_FLAGS}") endif () #----------------------------------------------------------------------------- # Compiler specific flags : Shouldn't there be compiler tests for these #----------------------------------------------------------------------------- +if (WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL "Intel") + set (_INTEL_WINDOWS 1) +endif () + +if (WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang" + AND "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") + set (_CLANG_MSVC_WINDOWS 1) +endif() + +# MSVC 14.28 enables C5105, but the Windows SDK 10.0.18362.0 triggers it. +if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND CMAKE_CXX_COMPILER_LOADED) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc") + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.28) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -wd5105") + endif () +endif () + +if (CMAKE_CXX_COMPILER_ID STREQUAL SunPro AND CMAKE_CXX_COMPILER_LOADED) + if (NOT DEFINED CMAKE_CXX${CMAKE_CXX_STANDARD}_STANDARD_COMPILE_OPTION) + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13) + if (NOT CMAKE_CXX_STANDARD OR CMAKE_CXX_STANDARD EQUAL 98) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++03") + endif () + else () + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=stlport4") + endif () + endif () +endif () + if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_LOADED) set (CMAKE_CXX_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_CXX_FLAGS}") if (${HDF_CFG_NAME} MATCHES "Debug") @@ -71,163 +103,167 @@ endif () # HDF5 library compile options #----------------------------------------------------------------------------- -if (NOT MSVC AND NOT MINGW) - if (${CMAKE_SYSTEM_NAME} MATCHES "SunOS") - list (APPEND HDF5_CMAKE_CXX_FLAGS "-erroff=%none -DBSD_COMP") - else () - # General flags - # - # Note that some of the flags listed here really should be developer - # flags (listed in a separate variable, below) but we put them here - # because they are not raised by the current code and we'd like to - # know if they do start showing up. - # - # NOTE: Don't add -Wpadded here since we can't/won't fix the (many) - # warnings that are emitted. If you need it, add it at configure time. - if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") +if (${CMAKE_SYSTEM_NAME} MATCHES "SunOS") + list (APPEND HDF5_CMAKE_CXX_FLAGS "-erroff=%none -DBSD_COMP") +else () + # General flags + # + # Note that some of the flags listed here really should be developer + # flags (listed in a separate variable, below) but we put them here + # because they are not raised by the current code and we'd like to + # know if they do start showing up. + # + # NOTE: Don't add -Wpadded here since we can't/won't fix the (many) + # warnings that are emitted. If you need it, add it at configure time. + if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") + if (_INTEL_WINDOWS) + ADD_H5_FLAGS (HDF5_CMAKE_CXX_FLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/win-general") + else () ADD_H5_FLAGS (HDF5_CMAKE_CXX_FLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/general") + endif() + if (NOT _INTEL_WINDOWS) if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 15.0) ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/15") endif() if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0) ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/18") endif() - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_LOADED - AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) - # add the general CXX flags for g++ compiler versions 4.8 and above. - ADD_H5_FLAGS (HDF5_CMAKE_CXX_FLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-general") - if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-error-general") - else () - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-noerror-general") - endif () + endif() + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_LOADED + AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) + # add the general CXX flags for g++ compiler versions 4.8 and above. + ADD_H5_FLAGS (HDF5_CMAKE_CXX_FLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-general") + if (HDF5_ENABLE_WARNINGS_AS_ERRORS) + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-error-general") + else () + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-noerror-general") endif () - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - ADD_H5_FLAGS (HDF5_CMAKE_CXX_FLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/general") - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "PGI") - list (APPEND HDF5_CMAKE_CXX_FLAGS "-Minform=inform") - endif () - if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") - message (VERBOSE "CMAKE_CXX_FLAGS_GENERAL=${HDF5_CMAKE_CXX_FLAGS}") endif () + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + ADD_H5_FLAGS (HDF5_CMAKE_CXX_FLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/general") + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "PGI") + list (APPEND HDF5_CMAKE_CXX_FLAGS "-Minform=inform") endif () - - #----------------------------------------------------------------------------- - # Option to allow the user to enable developer warnings - # Developer warnings (suggestions from gcc, not code problems) - #----------------------------------------------------------------------------- - if (HDF5_ENABLE_DEV_WARNINGS) - message (STATUS "....HDF5 developer group warnings are enabled") - if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/developer-general") - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-general") - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/developer-general") - endif () - else () - if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-general") - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/no-developer-general") - endif () + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") + message (VERBOSE "CMAKE_CXX_FLAGS_GENERAL=${HDF5_CMAKE_CXX_FLAGS}") endif () +endif () +#----------------------------------------------------------------------------- +# Option to allow the user to enable developer warnings +# Developer warnings (suggestions from gcc, not code problems) +#----------------------------------------------------------------------------- +if (HDF5_ENABLE_DEV_WARNINGS) + message (STATUS "....HDF5 developer group warnings are enabled") + if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/developer-general") + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + # Use the C warnings as CXX warnings are the same + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-general") + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/developer-general") + endif () +else () if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - # Technically, variable-length arrays are part of the C99 standard, but - # we should approach them a bit cautiously... Only needed for gcc 4.X - if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0 AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) - # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/4.8-4.last") - endif () + # Use the C warnings as CXX warnings are the same + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-general") + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/no-developer-general") + endif () +endif () - # Append more extra warning flags that only gcc 4.8+ knows about - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-4.8") - if (HDF5_ENABLE_DEV_WARNINGS) - # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-4.8") - else () - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-4.8") - endif () - endif () +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + # Technically, variable-length arrays are part of the C99 standard, but + # we should approach them a bit cautiously... Only needed for gcc 4.X + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0 AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) + # Use the C warnings as CXX warnings are the same + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/4.8-4.last") + endif () - # Append more extra warning flags that only gcc 4.9+ knows about - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9) + # Append more extra warning flags that only gcc 4.8+ knows about + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-4.8") + if (HDF5_ENABLE_DEV_WARNINGS) # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-4.9") + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-4.8") + else () + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-4.8") endif () + endif () - # Append more extra warning flags that only gcc 5.1+ knows about - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) - # autotools always add the C flags with the CXX flags - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-5") - if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-error-5") - else () - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-noerror-5") - endif () - endif () + # Append more extra warning flags that only gcc 4.9+ knows about + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9) + # Use the C warnings as CXX warnings are the same + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-4.9") + endif () - # Append more extra warning flags that only gcc 6.x+ knows about - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) - # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/6") + # Append more extra warning flags that only gcc 5.1+ knows about + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) + # autotools always add the C flags with the CXX flags + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-5") + if (HDF5_ENABLE_WARNINGS_AS_ERRORS) + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-error-5") + else () + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-noerror-5") endif () + endif () - # Append more extra warning flags that only gcc 7.x+ knows about - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0) - # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXxFLAGS2 "${HDF5_SOURCE_DIR}/config/gnu-warnings/7") - if (HDF5_ENABLE_DEV_WARNINGS) - # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-7") - #else () - # ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-7") - endif () - endif () + # Append more extra warning flags that only gcc 6.x+ knows about + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) + # Use the C warnings as CXX warnings are the same + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/6") + endif () - # Append more extra warning flags that only gcc 8.x+ knows about - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0) - # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/8") - if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-8") - else () - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/noerror-8") - endif () - if (HDF5_ENABLE_DEV_WARNINGS) - # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-8") - else () - # autotools always add the C flags with the CXX flags - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-8") - endif () + # Append more extra warning flags that only gcc 7.x+ knows about + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0) + # Use the C warnings as CXX warnings are the same + ADD_H5_FLAGS (H5_CXxFLAGS2 "${HDF5_SOURCE_DIR}/config/gnu-warnings/7") + if (HDF5_ENABLE_DEV_WARNINGS) + # Use the C warnings as CXX warnings are the same + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-7") + #else () + # ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-7") endif () + endif () - # Append more extra warning flags that only gcc 9.x+ knows about - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0) + # Append more extra warning flags that only gcc 8.x+ knows about + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0) + # Use the C warnings as CXX warnings are the same + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/8") + if (HDF5_ENABLE_WARNINGS_AS_ERRORS) + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-8") + else () + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/noerror-8") + endif () + if (HDF5_ENABLE_DEV_WARNINGS) # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-9") + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-8") + else () + # autotools always add the C flags with the CXX flags + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-8") endif () + endif () - # Append more extra warning flags that only gcc 9.3+ knows about - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.3) - # do not use C warnings, gnu-warnings 9.3, no cxx warniings - # ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/9.3") - endif () + # Append more extra warning flags that only gcc 9.x+ knows about + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0) + # Use the C warnings as CXX warnings are the same + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-9") + endif () - # Append more extra warning flags that only gcc 10.x+ knows about - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.0) - if (HDF5_ENABLE_DEV_WARNINGS) - # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-10") - #else () - # ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-10") - endif () + # Append more extra warning flags that only gcc 9.3+ knows about + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.3) + # do not use C warnings, gnu-warnings 9.3, no cxx warniings + # ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/9.3") + endif () + + # Append more extra warning flags that only gcc 10.x+ knows about + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.0) + if (HDF5_ENABLE_DEV_WARNINGS) + # Use the C warnings as CXX warnings are the same + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-10") + #else () + # ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-10") endif () endif () endif () @@ -269,17 +305,17 @@ endif () # This option will force/override the default setting for all configurations #----------------------------------------------------------------------------- if (HDF5_ENABLE_SYMBOLS MATCHES "YES") - if(CMAKE_CXX_COMPILER_LOADED) - if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") + if (CMAKE_CXX_COMPILER_LOADED) + if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel" AND NOT _INTEL_WINDOWS) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") endif () endif () elseif (HDF5_ENABLE_SYMBOLS MATCHES "NO") - if(CMAKE_CXX_COMPILER_LOADED) - if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") - set (CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -Wl,-s") + if (CMAKE_CXX_COMPILER_LOADED) + if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel" AND NOT _INTEL_WINDOWS) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,-s") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s") endif () @@ -291,7 +327,7 @@ endif () # This option will force/override the default setting for all configurations #----------------------------------------------------------------------------- if (HDF5_ENABLE_PROFILING) - if(CMAKE_CXX_COMPILER_LOADED) + if (CMAKE_CXX_COMPILER_LOADED) list (APPEND HDF5_CMAKE_CXX_FLAGS "${PROFILE_CXXFLAGS}") endif () endif () @@ -301,7 +337,7 @@ endif () # This option will force/override the default setting for all configurations #----------------------------------------------------------------------------- if (HDF5_ENABLE_OPTIMIZATION) - if(CMAKE_CXX_COMPILER_LOADED) + if (CMAKE_CXX_COMPILER_LOADED) list (APPEND HDF5_CMAKE_CXX_FLAGS "${OPTIMIZE_CXXFLAGS}") endif () endif () diff --git a/config/cmake/HDFCompilerFlags.cmake b/config/cmake/HDFCompilerFlags.cmake index e38a92b..de5b563 100644 --- a/config/cmake/HDFCompilerFlags.cmake +++ b/config/cmake/HDFCompilerFlags.cmake @@ -14,14 +14,43 @@ set(CMAKE_C_STANDARD_REQUIRED TRUE) set (CMAKE_C_FLAGS "${CMAKE_C99_STANDARD_COMPILE_OPTION} ${CMAKE_C_FLAGS}") set (CMAKE_C_FLAGS "${CMAKE_C_SANITIZER_FLAGS} ${CMAKE_C_FLAGS}") -set (CMAKE_CXX_FLAGS "${CMAKE_CXX_SANITIZER_FLAGS} ${CMAKE_CXX_FLAGS}") - if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") - message (VERBOSE "Warnings Configuration: default: ${CMAKE_C_FLAGS} : ${CMAKE_CXX_FLAGS}") + message (VERBOSE "Warnings Configuration: C default: ${CMAKE_C_FLAGS}") endif () #----------------------------------------------------------------------------- # Compiler specific flags : Shouldn't there be compiler tests for these #----------------------------------------------------------------------------- +if(WIN32 AND CMAKE_C_COMPILER_ID STREQUAL "Intel") + set(_INTEL_WINDOWS 1) +endif() + +if(WIN32 AND CMAKE_C_COMPILER_ID STREQUAL "Clang" + AND "x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC") + set(_CLANG_MSVC_WINDOWS 1) +endif() + +# Disable deprecation warnings for standard C functions. +# really only needed for newer versions of VS, but should +# not hurt other versions, and this will work into the +# future +if(MSVC OR _INTEL_WINDOWS OR _CLANG_MSVC_WINDOWS) + add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE) +else() +endif() + +if(MSVC) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stack:10000000") +endif() + +# MSVC 14.28 enables C5105, but the Windows SDK 10.0.18362.0 triggers it. +if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 19.28) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -wd5105") +endif() + +if(_CLANG_MSVC_WINDOWS AND "x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Xlinker -stack:20000000") +endif() + if (CMAKE_COMPILER_IS_GNUCC) set (CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}") if (${HDF_CFG_NAME} MATCHES "Debug") @@ -81,33 +110,37 @@ endif () # HDF5 library compile options #----------------------------------------------------------------------------- -if (NOT MSVC AND NOT MINGW) - #----------------------------------------------------------------------------- - # Option to allow the user to interpret certain warnings as errors - # - # This should NOT be on by default as it can cause a lot of conflicts with - # new operating systems and compiler versions. Header files that are out of - # our control (MPI, HDFS, etc.) can also raise warnings. - #----------------------------------------------------------------------------- - option (HDF5_ENABLE_WARNINGS_AS_ERRORS "Interpret some warnings as errors" OFF) - if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - message (STATUS "...some warnings will be interpreted as errors") - endif () +#----------------------------------------------------------------------------- +# Option to allow the user to interpret certain warnings as errors +# +# This should NOT be on by default as it can cause a lot of conflicts with +# new operating systems and compiler versions. Header files that are out of +# our control (MPI, HDFS, etc.) can also raise warnings. +#----------------------------------------------------------------------------- +option (HDF5_ENABLE_WARNINGS_AS_ERRORS "Interpret some warnings as errors" OFF) +if (HDF5_ENABLE_WARNINGS_AS_ERRORS) + message (STATUS "...some warnings will be interpreted as errors") +endif () - if (${CMAKE_SYSTEM_NAME} MATCHES "SunOS") - list (APPEND HDF5_CMAKE_C_FLAGS "-erroff=%none -DBSD_COMP") - else () - # General flags - # - # Note that some of the flags listed here really should be developer - # flags (listed in a separate variable, below) but we put them here - # because they are not raised by the current code and we'd like to - # know if they do start showing up. - # - # NOTE: Don't add -Wpadded here since we can't/won't fix the (many) - # warnings that are emitted. If you need it, add it at configure time. - if (CMAKE_C_COMPILER_ID STREQUAL "Intel") +if (${CMAKE_SYSTEM_NAME} MATCHES "SunOS") + list (APPEND HDF5_CMAKE_C_FLAGS "-erroff=%none -DBSD_COMP") +else () + # General flags + # + # Note that some of the flags listed here really should be developer + # flags (listed in a separate variable, below) but we put them here + # because they are not raised by the current code and we'd like to + # know if they do start showing up. + # + # NOTE: Don't add -Wpadded here since we can't/won't fix the (many) + # warnings that are emitted. If you need it, add it at configure time. + if (CMAKE_C_COMPILER_ID STREQUAL "Intel") + if (_INTEL_WINDOWS) + ADD_H5_FLAGS (HDF5_CMAKE_C_FLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/win-general") + else () ADD_H5_FLAGS (HDF5_CMAKE_C_FLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/general") + endif() + if (NOT _INTEL_WINDOWS) if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 15.0) ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/15") endif() @@ -116,133 +149,137 @@ if (NOT MSVC AND NOT MINGW) if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 18.0) ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/18") endif() - elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU") - # Add general CFlags for GCC versions 4.8 and above - if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) - ADD_H5_FLAGS (HDF5_CMAKE_C_FLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/general") - if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-general") - else () - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/noerror-general") - endif () - endif () - # gcc automatically inlines based on the optimization level - # this is just a failsafe - list (APPEND H5_CFLAGS "-finline-functions") - elseif (CMAKE_C_COMPILER_ID MATCHES "[Cc]lang") - ADD_H5_FLAGS (HDF5_CMAKE_C_FLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/general") + endif() + elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU") + # Add general CFlags for GCC versions 4.8 and above + if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) + ADD_H5_FLAGS (HDF5_CMAKE_C_FLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/general") if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/error-general") + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-general") else () - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/noerror-general") + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/noerror-general") endif () - elseif (CMAKE_C_COMPILER_ID STREQUAL "PGI") - list (APPEND HDF5_CMAKE_C_FLAGS "-Minform=inform") endif () - if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") - message (VERBOSE "CMAKE_C_FLAGS_GENERAL=${HDF5_CMAKE_C_FLAGS}") + # gcc automatically inlines based on the optimization level + # this is just a failsafe + list (APPEND H5_CFLAGS "-finline-functions") + elseif (CMAKE_C_COMPILER_ID MATCHES "[Cc]lang") + ADD_H5_FLAGS (HDF5_CMAKE_C_FLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/general") + if (HDF5_ENABLE_WARNINGS_AS_ERRORS) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/error-general") + else () + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/noerror-general") endif () + elseif (CMAKE_C_COMPILER_ID STREQUAL "PGI") + list (APPEND HDF5_CMAKE_C_FLAGS "-Minform=inform") endif () + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") + message (VERBOSE "CMAKE_C_FLAGS_GENERAL=${HDF5_CMAKE_C_FLAGS}") + endif () +endif () - #----------------------------------------------------------------------------- - # Option to allow the user to enable developer warnings - # Developer warnings (suggestions from gcc, not code problems) - #----------------------------------------------------------------------------- - option (HDF5_ENABLE_DEV_WARNINGS "Enable HDF5 developer group warnings" OFF) - if (HDF5_ENABLE_DEV_WARNINGS) - message (STATUS "....HDF5 developer group warnings are enabled") - if (CMAKE_C_COMPILER_ID STREQUAL "Intel") +#----------------------------------------------------------------------------- +# Option to allow the user to enable developer warnings +# Developer warnings (suggestions from gcc, not code problems) +#----------------------------------------------------------------------------- +option (HDF5_ENABLE_DEV_WARNINGS "Enable HDF5 developer group warnings" OFF) +if (HDF5_ENABLE_DEV_WARNINGS) + message (STATUS "....HDF5 developer group warnings are enabled") + if (CMAKE_C_COMPILER_ID STREQUAL "Intel") + if (_INTEL_WINDOWS) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/win-developer-general") + else () ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/developer-general") - elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-general") - elseif (CMAKE_C_COMPILER_ID MATCHES "[Cc]lang") - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/developer-general") - endif () - else () - if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-general") - elseif (CMAKE_C_COMPILER_ID MATCHES "[Cc]lang") - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/no-developer-general") endif () + elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-general") + elseif (CMAKE_C_COMPILER_ID MATCHES "[Cc]lang") + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/developer-general") endif () +else () + if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-general") + elseif (CMAKE_C_COMPILER_ID MATCHES "[Cc]lang") + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/no-developer-general") + endif () +endif () - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - # Technically, variable-length arrays are part of the C99 standard, but - # we should approach them a bit cautiously... Only needed for gcc 4.X - if (CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0 AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/4.8-4.last") - endif () +if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + # Technically, variable-length arrays are part of the C99 standard, but + # we should approach them a bit cautiously... Only needed for gcc 4.X + if (CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0 AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/4.8-4.last") + endif () - # Append more extra warning flags that only gcc 4.8+ knows about - if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.8) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/4.8") - if (HDF5_ENABLE_DEV_WARNINGS) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-4.8") - else () - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-4.8") - endif () + # Append more extra warning flags that only gcc 4.8+ knows about + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.8) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/4.8") + if (HDF5_ENABLE_DEV_WARNINGS) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-4.8") + else () + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-4.8") endif () + endif () - # Append more extra warning flags that only gcc 4.9+ knows about - if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.9) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/4.9") - endif () + # Append more extra warning flags that only gcc 4.9+ knows about + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.9) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/4.9") + endif () - # Append more extra warning flags that only gcc 5.x+ knows about - if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/5") - if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-5") - else () - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-5") - endif () + # Append more extra warning flags that only gcc 5.x+ knows about + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/5") + if (HDF5_ENABLE_WARNINGS_AS_ERRORS) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-5") + else () + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-5") endif () + endif () - # Append more extra warning flags that only gcc 6.x+ knows about - if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.0) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/6") - endif () + # Append more extra warning flags that only gcc 6.x+ knows about + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.0) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/6") + endif () - # Append more extra warning flags that only gcc 7.x+ knows about - if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/7") - if (HDF5_ENABLE_DEV_WARNINGS) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-7") - #else () - # ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-7") - endif () + # Append more extra warning flags that only gcc 7.x+ knows about + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/7") + if (HDF5_ENABLE_DEV_WARNINGS) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-7") + #else () + # ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-7") endif () + endif () - # Append more extra warning flags that only gcc 8.x+ knows about - if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.0) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/8") - if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-8") - endif () - if (HDF5_ENABLE_DEV_WARNINGS) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-8") - else () - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-8") - endif () + # Append more extra warning flags that only gcc 8.x+ knows about + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.0) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/8") + if (HDF5_ENABLE_WARNINGS_AS_ERRORS) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-8") endif () - - # Append more extra warning flags that only gcc 9.x+ knows about - if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.0) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/9") + if (HDF5_ENABLE_DEV_WARNINGS) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-8") + else () + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-8") endif () + endif () - # Append more extra warning flags that only gcc 9.3+ knows about - if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.3) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/9.3") - endif () + # Append more extra warning flags that only gcc 9.x+ knows about + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.0) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/9") + endif () - # Append more extra warning flags that only gcc 10.x+ knows about - if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.0) - if (HDF5_ENABLE_DEV_WARNINGS) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-10") - #else () - # ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-10") - endif () + # Append more extra warning flags that only gcc 9.3+ knows about + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.3) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/9.3") + endif () + + # Append more extra warning flags that only gcc 10.x+ knows about + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.0) + if (HDF5_ENABLE_DEV_WARNINGS) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-10") + #else () + # ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-10") endif () endif () endif () @@ -297,13 +334,13 @@ MARK_AS_ADVANCED (HDF5_ENABLE_ASSERTS) set (HDF5_ENABLE_SYMBOLS "OFF" CACHE STRING "Add debug symbols to the library independent of the build mode and optimization level (OFF NO YES)") set_property (CACHE HDF5_ENABLE_SYMBOLS PROPERTY STRINGS OFF NO YES) if (HDF5_ENABLE_SYMBOLS MATCHES "YES") - if (CMAKE_C_COMPILER_ID STREQUAL "Intel") + if (CMAKE_C_COMPILER_ID STREQUAL "Intel" AND NOT _INTEL_WINDOWS) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g") elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU") set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -fno-omit-frame-pointer") endif () elseif (HDF5_ENABLE_SYMBOLS MATCHES "NO") - if (CMAKE_C_COMPILER_ID STREQUAL "Intel") + if (CMAKE_C_COMPILER_ID STREQUAL "Intel" AND NOT _INTEL_WINDOWS) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-s") elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU") set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s") diff --git a/config/cmake/HDFFortranCompilerFlags.cmake b/config/cmake/HDFFortranCompilerFlags.cmake index 18ab621..94c40aa 100644 --- a/config/cmake/HDFFortranCompilerFlags.cmake +++ b/config/cmake/HDFFortranCompilerFlags.cmake @@ -91,9 +91,10 @@ if (NOT MSVC AND NOT MINGW) #endif () # Append more extra warning flags that only gcc 5.x+ knows about - if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 5.0) - ADD_H5_FLAGS (HDF5_CMAKE_Fortran_FLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/gfort-5") - endif () + # do not include -Wuse-without-only + #if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 5.0) + # ADD_H5_FLAGS (HDF5_CMAKE_Fortran_FLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/gfort-5") + #endif () # Append more extra warning flags that only gcc 6.x+ knows about if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 6.0) diff --git a/config/cmake/README.txt.cmake.in b/config/cmake/README.txt.cmake.in index f621515..9289870 100644 --- a/config/cmake/README.txt.cmake.in +++ b/config/cmake/README.txt.cmake.in @@ -75,6 +75,6 @@ For more information see USING_CMake_Examples.txt in the install folder. =========================================================================== Documentation for this release can be found at the following URL: - https://portal.hdfgroup.org/display/support + https://portal.hdfgroup.org/display/HDF5/HDF5 Bugs should be reported to help@hdfgroup.org. diff --git a/config/cmake/UseJava.cmake b/config/cmake/UseJava.cmake index 375004e..2351ce8 100644 --- a/config/cmake/UseJava.cmake +++ b/config/cmake/UseJava.cmake @@ -4,369 +4,516 @@ UseJava ------- -Use Module for Java - -This file provides functions for Java. It is assumed that +This file provides support for ``Java``. It is assumed that :module:`FindJava` has already been loaded. See :module:`FindJava` for -information on how to load Java into your CMake project. +information on how to load Java into your ``CMake`` project. + +Synopsis +^^^^^^^^ + +.. parsed-literal:: + + `Creating and Installing JARS`_ + `add_jar`_ ( [SOURCES] [...] ...) + `install_jar`_ ( DESTINATION [COMPONENT ]) + `install_jni_symlink`_ ( DESTINATION [COMPONENT ]) + + `Header Generation`_ + `create_javah`_ ((TARGET | GENERATED_FILES ) CLASSES ... ...) + + `Exporting JAR Targets`_ + `install_jar_exports`_ (TARGETS ... FILE DESTINATION ...) + `export_jars`_ (TARGETS ... [NAMESPACE ] FILE ) + + `Finding JARs`_ + `find_jar`_ ( NAMES [...] [PATHS [... ENV ]] ...) + + `Creating Java Documentation`_ + `create_javadoc`_ ( (PACKAGES [...] | FILES [...]) ...) Creating And Installing JARs ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. code-block:: cmake +.. _add_jar: - add_jar( - [SOURCES] [...] [...] - [INCLUDE_JARS [...]] - [ENTRY_POINT ] - [VERSION ] - [OUTPUT_NAME ] - [OUTPUT_DIR ] - [GENERATE_NATIVE_HEADERS [DESTINATION ]] - ) +.. command:: add_jar -This command creates a ``.jar``. It compiles the given -```` files and adds the given ```` files to -the jar file. Source files can be java files or listing files -(prefixed by ``@``). If only resource files are given then just a jar file -is created. The list of ``INCLUDE_JARS`` are added to the classpath when -compiling the java sources and also to the dependencies of the target. -``INCLUDE_JARS`` also accepts other target names created by ``add_jar()``. -For backwards compatibility, jar files listed as sources are ignored (as -they have been since the first version of this module). + Creates a jar file containing java objects and, optionally, resources:: -The default ``OUTPUT_DIR`` can also be changed by setting the variable -``CMAKE_JAVA_TARGET_OUTPUT_DIR``. + add_jar( + [SOURCES] [...] [...] + [INCLUDE_JARS [...]] + [ENTRY_POINT ] + [VERSION ] + [MANIFEST ] + [OUTPUT_NAME ] + [OUTPUT_DIR ] + [GENERATE_NATIVE_HEADERS + [DESTINATION (|INSTALL [BUILD ])]] + ) -Optionally, using option ``GENERATE_NATIVE_HEADERS``, native header files can -be generated for methods declared as native. These files provide the -connective glue that allow your Java and C code to interact. An INTERFACE -target will be created for an easy usage of generated files. Sub-option -``DESTINATION`` can be used to specify the output directory for generated -header files. + This command creates a ``.jar``. It compiles the given + ```` files and adds the given ```` files to + the jar file. Source files can be java files or listing files + (prefixed by ``@``). If only resource files are given then just a jar file + is created. -``GENERATE_NATIVE_HEADERS`` option requires, at least, version 1.8 of the JDK. + ``SOURCES`` + Compiles the specified source files and adds the result in the jar file. -The ``add_jar()`` function sets the following target properties on -````: + .. versionadded:: 3.4 + Support for response files, prefixed by ``@``. -``INSTALL_FILES`` - The files which should be installed. This is used by ``install_jar()``. -``JNI_SYMLINK`` - The JNI symlink which should be installed. This is used by - ``install_jni_symlink()``. -``JAR_FILE`` - The location of the jar file so that you can include it. -``CLASSDIR`` - The directory where the class files can be found. For example to use them - with ``javah``. + ``INCLUDE_JARS`` + The list of jars are added to the classpath when compiling the java sources + and also to the dependencies of the target. ``INCLUDE_JARS`` also accepts + other target names created by ``add_jar()``. For backwards compatibility, + jar files listed as sources are ignored (as they have been since the first + version of this module). -.. code-block:: cmake + ``ENTRY_POINT`` + Defines an entry point in the jar file. - install_jar( ) - install_jar( DESTINATION [COMPONENT ]) + ``VERSION`` + Adds a version to the target output name. -This command installs the ```` files to the given -````. It should be called in the same scope as ``add_jar()`` or -it will fail. + The following example will create a jar file with the name + ``shibboleet-1.2.0.jar`` and will create a symlink ``shibboleet.jar`` + pointing to the jar with the version information. -The ``install_jar()`` function sets the ``INSTALL_DESTINATION`` target -property on jars so installed. This property holds the ```` as -described above, and is used by ``install_jar_exports()``. You can get this -information with :command:`get_property` and the ``INSTALL_DESTINATION`` -property key. + .. code-block:: cmake -.. code-block:: cmake + add_jar(shibboleet shibbotleet.java VERSION 1.2.0) - install_jni_symlink( ) - install_jni_symlink( DESTINATION [COMPONENT ]) + ``MANIFEST`` + Defines a custom manifest for the jar. -This command installs the ```` JNI symlinks to the given -````. It should be called in the same scope as ``add_jar()`` or -it will fail. + ``OUTPUT_NAME`` + Specify a different output name for the target. -.. code-block:: cmake + ``OUTPUT_DIR`` + Sets the directory where the jar file will be generated. If not specified, + :variable:`CMAKE_CURRENT_BINARY_DIR` is used as the output directory. - install_jar_exports(TARGETS ... - [NAMESPACE ] - FILE - DESTINATION [COMPONENT ]) + ``GENERATE_NATIVE_HEADERS`` + .. versionadded:: 3.11 -This command installs a target export file ```` for the named jar -targets to the given ```` directory. Its function is similar to -that of :command:`install(EXPORTS)`. + Generates native header files for methods declared as native. These files + provide the connective glue that allow your Java and C code to interact. + An INTERFACE target will be created for an easy usage of generated files. + Sub-option ``DESTINATION`` can be used to specify the output directory for + generated header files. -.. code-block:: cmake + This option requires, at least, version 1.8 of the JDK. - export_jars(TARGETS ... - [NAMESPACE ] - FILE ) + For an optimum usage of this option, it is recommended to include module + JNI before any call to ``add_jar()``. The produced target for native + headers can then be used to compile C/C++ sources with the + :command:`target_link_libraries` command. -This command writes a target export file ```` for the named ```` -targets. Its function is similar to that of :command:`export`. + .. code-block:: cmake + find_package(JNI) + add_jar(foo foo.java GENERATE_NATIVE_HEADERS foo-native) + add_library(bar bar.cpp) + target_link_libraries(bar PRIVATE foo-native) -Examples -"""""""" + .. versionadded:: 3.20 + ``DESTINATION`` sub-option now supports the possibility to specify + different output directories for ``BUILD`` and ``INSTALL`` steps. If + ``BUILD`` directory is not specified, a default directory will be used. -To add compile flags to the target you can set these flags with the following -variable: + To export the interface target generated by ``GENERATE_NATIVE_HEADERS`` + option, sub-option ``INSTALL`` of ``DESTINATION`` is required: -.. code-block:: cmake + .. code-block:: cmake - set(CMAKE_JAVA_COMPILE_FLAGS -nowarn) + add_jar(foo foo.java GENERATE_NATIVE_HEADERS foo-native + DESTINATION INSTALL include) + install(TARGETS foo-native EXPORT native) + install(DIRECTORY "$/" + DESTINATION include) + install(EXPORT native DESTINATION /to/export NAMESPACE foo) + Some variables can be set to customize the behavior of ``add_jar()`` as well + as the java compiler: -To add a path or a jar file to the class path you can do this with the -``CMAKE_JAVA_INCLUDE_PATH`` variable. + ``CMAKE_JAVA_COMPILE_FLAGS`` + Specify additional flags to java compiler. -.. code-block:: cmake + ``CMAKE_JAVA_INCLUDE_PATH`` + Specify additional paths to the class path. - set(CMAKE_JAVA_INCLUDE_PATH /usr/share/java/shibboleet.jar) + ``CMAKE_JNI_TARGET`` + If the target is a JNI library, sets this boolean variable to ``TRUE`` to + enable creation of a JNI symbolic link (see also + :ref:`install_jni_symlink() `). -To use a different output name for the target you can set it with: + ``CMAKE_JAR_CLASSES_PREFIX`` + If multiple jars should be produced from the same java source filetree, + to prevent the accumulation of duplicate class files in subsequent jars, + set/reset ``CMAKE_JAR_CLASSES_PREFIX`` prior to calling the ``add_jar()``: -.. code-block:: cmake + .. code-block:: cmake - add_jar(foobar foobar.java OUTPUT_NAME shibboleet.jar) + set(CMAKE_JAR_CLASSES_PREFIX com/redhat/foo) + add_jar(foo foo.java) -To use a different output directory than ``CMAKE_CURRENT_BINARY_DIR`` you can -set it with: + set(CMAKE_JAR_CLASSES_PREFIX com/redhat/bar) + add_jar(bar bar.java) -.. code-block:: cmake + The ``add_jar()`` function sets the following target properties on + ````: - add_jar(foobar foobar.java OUTPUT_DIR ${PROJECT_BINARY_DIR}/bin) + ``INSTALL_FILES`` + The files which should be installed. This is used by + :ref:`install_jar() `. + ``JNI_SYMLINK`` + The JNI symlink which should be installed. This is used by + :ref:`install_jni_symlink() `. + ``JAR_FILE`` + The location of the jar file so that you can include it. + ``CLASSDIR`` + The directory where the class files can be found. For example to use them + with ``javah``. + ``NATIVE_HEADERS_DIRECTORY`` + .. versionadded:: 3.20 -To define an entry point in your jar you can set it with the ``ENTRY_POINT`` -named argument: + The directory where native headers are generated. Defined when option + ``GENERATE_NATIVE_HEADERS`` is specified. -.. code-block:: cmake +.. _install_jar: - add_jar(example ENTRY_POINT com/examples/MyProject/Main) +.. command:: install_jar -To define a custom manifest for the jar, you can set it with the ``MANIFEST`` -named argument: + This command installs the jar file to the given destination:: -.. code-block:: cmake + install_jar( ) + install_jar( DESTINATION [COMPONENT ]) - add_jar(example MANIFEST /path/to/manifest) + This command installs the ```` file to the given + ````. It should be called in the same scope as + :ref:`add_jar() ` or it will fail. -To add a version to the target output name you can set it using the ``VERSION`` -named argument to ``add_jar()``. The following example will create a jar file -with the name ``shibboleet-1.0.0.jar`` and will create a symlink -``shibboleet.jar`` pointing to the jar with the version information. + .. versionadded:: 3.4 + The second signature with ``DESTINATION`` and ``COMPONENT`` options. -.. code-block:: cmake + ``DESTINATION`` + Specify the directory on disk to which a file will be installed. - add_jar(shibboleet shibbotleet.java VERSION 1.2.0) + ``COMPONENT`` + Specify an installation component name with which the install rule is + associated, such as "runtime" or "development". -If the target is a JNI library, utilize the following commands to -create a JNI symbolic link: + The ``install_jar()`` command sets the following target properties + on ````: -.. code-block:: cmake + ``INSTALL_DESTINATION`` + Holds the ```` as described above, and is used by + :ref:`install_jar_exports() `. - set(CMAKE_JNI_TARGET TRUE) - add_jar(shibboleet shibbotleet.java VERSION 1.2.0) - install_jar(shibboleet ${LIB_INSTALL_DIR}/shibboleet) - install_jni_symlink(shibboleet ${JAVA_LIB_INSTALL_DIR}) +.. _install_jni_symlink: -If a single target needs to produce more than one jar from its -java source code, to prevent the accumulation of duplicate class -files in subsequent jars, set/reset ``CMAKE_JAR_CLASSES_PREFIX`` prior -to calling the ``add_jar()`` function: +.. command:: install_jni_symlink -.. code-block:: cmake + Installs JNI symlinks for target generated by :ref:`add_jar() `:: - set(CMAKE_JAR_CLASSES_PREFIX com/redhat/foo) - add_jar(foo foo.java) + install_jni_symlink( ) + install_jni_symlink( DESTINATION [COMPONENT ]) - set(CMAKE_JAR_CLASSES_PREFIX com/redhat/bar) - add_jar(bar bar.java) + This command installs the ```` JNI symlinks to the given + ````. It should be called in the same scope as + :ref:`add_jar() ` or it will fail. -For an optimum usage of option ``GENERATE_NATIVE_HEADERS``, it is recommended to -include module JNI before any call to ``add_jar()``. The produced target for -native headers can then be used to compile C/C++ sources with the -:command:`target_link_libraries` command. + .. versionadded:: 3.4 + The second signature with ``DESTINATION`` and ``COMPONENT`` options. -.. code-block:: cmake + ``DESTINATION`` + Specify the directory on disk to which a file will be installed. - find_package(JNI) - add_jar(foo foo.java GENERATE_NATIVE_HEADERS foo-native) - add_library(bar bar.cpp) - target_link_libraries(bar PRIVATE foo-native) + ``COMPONENT`` + Specify an installation component name with which the install rule is + associated, such as "runtime" or "development". + Utilize the following commands to create a JNI symbolic link: -Finding JARs -^^^^^^^^^^^^ + .. code-block:: cmake -.. code-block:: cmake - - find_jar( - | NAMES [...] - [PATHS [... ENV ]] - [VERSIONS []] - [DOC "cache documentation string"] - ) - -This command is used to find a full path to the named jar. A cache -entry named by ```` is created to store the result of this command. -If the full path to a jar is found the result is stored in the -variable and the search will not repeated unless the variable is -cleared. If nothing is found, the result will be ``-NOTFOUND``, and -the search will be attempted again next time ``find_jar()`` is invoked with -the same variable. The name of the full path to a file that is -searched for is specified by the names listed after ``NAMES`` argument. -Additional search locations can be specified after the ``PATHS`` argument. -If you require special a version of a jar file you can specify it with -the ``VERSIONS`` argument. The argument after ``DOC`` will be used for the -documentation string in the cache. - - -Javadoc -^^^^^^^ - -The ``create_javadoc()`` command can be used to create java documentation -based on files or packages. For more details please read the javadoc manpage. - -There are two main signatures for ``create_javadoc()``. The first signature -works with package names on a path with source files. - -.. code-block:: cmake - - create_javadoc( - PACKAGES [...] - [SOURCEPATH ] - [CLASSPATH ] - [INSTALLPATH ] - [DOCTITLE "the documentation title"] - [WINDOWTITLE "the title of the document"] - [AUTHOR TRUE|FALSE] - [USE TRUE|FALSE] - [VERSION TRUE|FALSE] - ) + set(CMAKE_JNI_TARGET TRUE) + add_jar(shibboleet shibbotleet.java VERSION 1.2.0) + install_jar(shibboleet ${LIB_INSTALL_DIR}/shibboleet) + install_jni_symlink(shibboleet ${JAVA_LIB_INSTALL_DIR}) + +Header Generation +^^^^^^^^^^^^^^^^^ + +.. _create_javah: + +.. command:: create_javah -For example: - -.. code-block:: cmake - - create_javadoc(my_example_doc - PACKAGES com.example.foo com.example.bar - SOURCEPATH "${CMAKE_CURRENT_SOURCE_DIR}" - CLASSPATH ${CMAKE_JAVA_INCLUDE_PATH} - WINDOWTITLE "My example" - DOCTITLE "

My example

" - AUTHOR TRUE - USE TRUE - VERSION TRUE - ) - -The second signature for ``create_javadoc()`` works on a given list of -files. - -.. code-block:: cmake - - create_javadoc( - FILES [...] - [CLASSPATH ] - [INSTALLPATH ] - [DOCTITLE "the documentation title"] - [WINDOWTITLE "the title of the document"] - [AUTHOR TRUE|FALSE] - [USE TRUE|FALSE] - [VERSION TRUE|FALSE] + .. versionadded:: 3.4 + + Generates C header files for java classes:: + + create_javah(TARGET | GENERATED_FILES + CLASSES ... + [CLASSPATH ...] + [DEPENDS ...] + [OUTPUT_NAME |OUTPUT_DIR ] ) -For example: + .. deprecated:: 3.11 + This command will no longer be supported starting with version 10 of the JDK + due to the `suppression of javah tool `_. + The :ref:`add_jar(GENERATE_NATIVE_HEADERS) ` command should be + used instead. + + Create C header files from java classes. These files provide the connective + glue that allow your Java and C code to interact. + + There are two main signatures for ``create_javah()``. The first signature + returns generated files through variable specified by the ``GENERATED_FILES`` + option. For example: -.. code-block:: cmake + .. code-block:: cmake - create_javadoc(my_example_doc - FILES ${example_SRCS} - CLASSPATH ${CMAKE_JAVA_INCLUDE_PATH} - WINDOWTITLE "My example" - DOCTITLE "

My example

" - AUTHOR TRUE - USE TRUE - VERSION TRUE - ) + create_javah(GENERATED_FILES files_headers + CLASSES org.cmake.HelloWorld + CLASSPATH hello.jar + ) -Both signatures share most of the options. These options are the same -as what you can find in the javadoc manpage. Please look at the -manpage for ``CLASSPATH``, ``DOCTITLE``, ``WINDOWTITLE``, ``AUTHOR``, ``USE`` -and ``VERSION``. + The second signature for ``create_javah()`` creates a target which + encapsulates header files generation. E.g. -If you don't set the ``INSTALLPATH``, then by default the documentation will -be installed to : + .. code-block:: cmake -:: + create_javah(TARGET target_headers + CLASSES org.cmake.HelloWorld + CLASSPATH hello.jar + ) - ${CMAKE_INSTALL_PREFIX}/share/javadoc/ + Both signatures share same options. + ``CLASSES`` + Specifies Java classes used to generate headers. -Header Generation -^^^^^^^^^^^^^^^^^ + ``CLASSPATH`` + Specifies various paths to look up classes. Here ``.class`` files, jar + files or targets created by command add_jar can be used. + + ``DEPENDS`` + Targets on which the javah target depends. + + ``OUTPUT_NAME`` + Concatenates the resulting header files for all the classes listed by + option ``CLASSES`` into ````. Same behavior as option ``-o`` of + ``javah`` tool. + + ``OUTPUT_DIR`` + Sets the directory where the header files will be generated. Same behavior + as option ``-d`` of ``javah`` tool. If not specified, + :variable:`CMAKE_CURRENT_BINARY_DIR` is used as the output directory. + +Exporting JAR Targets +^^^^^^^^^^^^^^^^^^^^^ + +.. _install_jar_exports: + +.. command:: install_jar_exports + + .. versionadded:: 3.7 + + Installs a target export file:: -.. code-block:: cmake + install_jar_exports(TARGETS ... + [NAMESPACE ] + FILE + DESTINATION [COMPONENT ]) - create_javah(TARGET | GENERATED_FILES - CLASSES ... - [CLASSPATH ...] - [DEPENDS ...] - [OUTPUT_NAME |OUTPUT_DIR ] - ) + This command installs a target export file ```` for the named jar + targets to the given ```` directory. Its function is similar to + that of :command:`install(EXPORT)`. -Create C header files from java classes. These files provide the connective glue -that allow your Java and C code to interact. + ``TARGETS`` + List of targets created by :ref:`add_jar() ` command. -.. deprecated:: 3.11 + ``NAMESPACE`` + .. versionadded:: 3.9 -.. note:: + The ```` value will be prepend to the target names as they are + written to the import file. - This command will no longer be supported starting with version 10 of the JDK - due to the `suppression of javah tool `_. - The ``add_jar(GENERATE_NATIVE_HEADERS)`` command should be used instead. + ``FILE`` + Specify name of the export file. -There are two main signatures for ``create_javah()``. The first signature -returns generated files through variable specified by the ``GENERATED_FILES`` -option. For example: -.. code-block:: cmake + ``DESTINATION`` + Specify the directory on disk to which a file will be installed. - create_javah(GENERATED_FILES files_headers - CLASSES org.cmake.HelloWorld - CLASSPATH hello.jar - ) + ``COMPONENT`` + Specify an installation component name with which the install rule is + associated, such as "runtime" or "development". -The second signature for ``create_javah()`` creates a target which encapsulates -header files generation. E.g. +.. _export_jars: -.. code-block:: cmake +.. command:: export_jars - create_javah(TARGET target_headers - CLASSES org.cmake.HelloWorld - CLASSPATH hello.jar - ) + .. versionadded:: 3.7 -Both signatures share same options. + Writes a target export file:: -``CLASSES ...`` - Specifies Java classes used to generate headers. + export_jars(TARGETS ... + [NAMESPACE ] + FILE ) -``CLASSPATH ...`` - Specifies various paths to look up classes. Here .class files, jar files or - targets created by command add_jar can be used. + This command writes a target export file ```` for the named ```` + targets. Its function is similar to that of :command:`export`. -``DEPENDS ...`` - Targets on which the javah target depends. + ``TARGETS`` + List of targets created by :ref:`add_jar() ` command. -``OUTPUT_NAME `` - Concatenates the resulting header files for all the classes listed by option - ``CLASSES`` into ````. Same behavior as option ``-o`` of javah tool. + ``NAMESPACE`` + .. versionadded:: 3.9 -``OUTPUT_DIR `` - Sets the directory where the header files will be generated. Same behavior - as option ``-d`` of javah tool. If not specified, - :variable:`CMAKE_CURRENT_BINARY_DIR` is used as the output directory. + The ```` value will be prepend to the target names as they are + written to the import file. + + ``FILE`` + Specify name of the export file. + +Finding JARs +^^^^^^^^^^^^ + +.. _find_jar: + +.. command:: find_jar + + Finds the specified jar file:: + + find_jar( + | NAMES [...] + [PATHS [... ENV ]] + [VERSIONS []] + [DOC "cache documentation string"] + ) + + This command is used to find a full path to the named jar. A cache + entry named by ```` is created to store the result of this command. + If the full path to a jar is found the result is stored in the + variable and the search will not repeated unless the variable is + cleared. If nothing is found, the result will be ``-NOTFOUND``, and + the search will be attempted again next time ``find_jar()`` is invoked with + the same variable. + + ``NAMES`` + Specify one or more possible names for the jar file. + + ``PATHS`` + Specify directories to search in addition to the default locations. + The ``ENV`` var sub-option reads paths from a system environment variable. + + ``VERSIONS`` + Specify jar versions. + + ``DOC`` + Specify the documentation string for the ```` cache entry. + +Creating Java Documentation +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. _create_javadoc: + +.. command:: create_javadoc + + Creates java documentation based on files and packages:: + + create_javadoc( + (PACKAGES [...] | FILES [...]) + [SOURCEPATH ] + [CLASSPATH ] + [INSTALLPATH ] + [DOCTITLE ] + [WINDOWTITLE ] + [AUTHOR (TRUE|FALSE)] + [USE (TRUE|FALSE)] + [VERSION (TRUE|FALSE)] + ) + + The ``create_javadoc()`` command can be used to create java documentation. + There are two main signatures for ``create_javadoc()``. + + The first signature works with package names on a path with source files: + + .. code-block:: cmake + + create_javadoc(my_example_doc + PACKAGES com.example.foo com.example.bar + SOURCEPATH "${CMAKE_CURRENT_SOURCE_DIR}" + CLASSPATH ${CMAKE_JAVA_INCLUDE_PATH} + WINDOWTITLE "My example" + DOCTITLE "

My example

" + AUTHOR TRUE + USE TRUE + VERSION TRUE + ) + + The second signature for ``create_javadoc()`` works on a given list of files: + + .. code-block:: cmake + + create_javadoc(my_example_doc + FILES java/A.java java/B.java + CLASSPATH ${CMAKE_JAVA_INCLUDE_PATH} + WINDOWTITLE "My example" + DOCTITLE "

My example

" + AUTHOR TRUE + USE TRUE + VERSION TRUE + ) + + Both signatures share most of the options. For more details please read the + javadoc manpage. + + ``PACKAGES`` + Specify java packages. + + ``FILES`` + Specify java source files. If relative paths are specified, they are + relative to :variable:`CMAKE_CURRENT_SOURCE_DIR`. + + ``SOURCEPATH`` + Specify the directory where to look for packages. By default, + :variable:`CMAKE_CURRENT_SOURCE_DIR` directory is used. + + ``CLASSPATH`` + Specify where to find user class files. Same behavior as option + ``-classpath`` of ``javadoc`` tool. + + ``INSTALLPATH`` + Specify where to install the java documentation. If you specified, the + documentation will be installed to + ``${CMAKE_INSTALL_PREFIX}/share/javadoc/``. + + ``DOCTITLE`` + Specify the title to place near the top of the overview summary file. + Same behavior as option ``-doctitle`` of ``javadoc`` tool. + + ``WINDOWTITLE`` + Specify the title to be placed in the HTML ```` tag. Same behavior + as option ``-windowtitle`` of ``javadoc`` tool. + + ``AUTHOR`` + When value ``TRUE`` is specified, includes the ``@author`` text in the + generated docs. Same behavior as option ``-author`` of ``javadoc`` tool. + + ``USE`` + When value ``TRUE`` is specified, creates class and package usage pages. + Includes one Use page for each documented class and package. Same behavior + as option ``-use`` of ``javadoc`` tool. + + ``VERSION`` + When value ``TRUE`` is specified, includes the version text in the + generated docs. Same behavior as option ``-version`` of ``javadoc`` tool. #]=======================================================================] include(CMakeParseArguments) @@ -378,7 +525,8 @@ function (__java_copy_file src dest comment) ARGS ${src} ${dest} DEPENDS ${src} - COMMENT ${comment}) + COMMENT ${comment} + ) endfunction () function(__java_lcat VAR) @@ -409,6 +557,12 @@ set(_JAVA_EXPORT_TARGETS_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/javaTargets.cmake.in) set(_JAVA_CLASS_FILELIST_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJavaClassFilelist.cmake) set(_JAVA_SYMLINK_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJavaSymlinks.cmake) +if (CMAKE_HOST_WIN32 AND NOT CYGWIN AND CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") + set(_UseJava_PATH_SEP "$<SEMICOLON>") +else () + set(_UseJava_PATH_SEP ":") +endif() + function(add_jar _TARGET_NAME) cmake_parse_arguments(_add_jar @@ -440,6 +594,9 @@ function(add_jar _TARGET_NAME) set(_add_jar_ENTRY_POINT "${CMAKE_JAVA_JAR_ENTRY_POINT}") endif() + # This *should* still work if <resources1>... are included without a + # named RESOURCES argument. In that case, the old behavior of potentially + # misplacing the within the Jar will behave as previously (incorrectly) set(_JAVA_SOURCE_FILES ${_add_jar_SOURCES} ${_add_jar_UNPARSED_ARGUMENTS}) if (NOT DEFINED _add_jar_OUTPUT_DIR) @@ -467,7 +624,10 @@ function(add_jar _TARGET_NAME) if (Java_VERSION VERSION_LESS 1.8) message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS is not supported with this version of Java.") endif() - cmake_parse_arguments (_add_jar_GENERATE_NATIVE_HEADERS "" "DESTINATION" "" ${_add_jar_GENERATE_NATIVE_HEADERS}) + + unset (_GENERATE_NATIVE_HEADERS_OUTPUT_DESC) + + cmake_parse_arguments (_add_jar_GENERATE_NATIVE_HEADERS "" "" "DESTINATION" ${_add_jar_GENERATE_NATIVE_HEADERS}) if (NOT _add_jar_GENERATE_NATIVE_HEADERS_UNPARSED_ARGUMENTS) message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS: missing required argument.") endif() @@ -478,11 +638,30 @@ function(add_jar _TARGET_NAME) endif() if (NOT _add_jar_GENERATE_NATIVE_HEADERS_DESTINATION) set (_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_TARGET_NAME}.dir/native_headers") + else() + list (LENGTH _add_jar_GENERATE_NATIVE_HEADERS_DESTINATION length) + if (NOT length EQUAL 1) + cmake_parse_arguments (_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION "" "BUILD;INSTALL" "" "${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION}") + if (_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_UNPARSED_ARGUMENTS) + message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS: DESTINATION: ${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_UNPARSED_ARGUMENTS}: unexpected argument(s).") + endif() + if (NOT _add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_INSTALL) + message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS: DESTINATION: INSTALL sub-option is required.") + endif() + if (NOT _add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_BUILD) + set(_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_BUILD "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_TARGET_NAME}.dir/native_headers") + endif() + set(_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION "${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_BUILD}") + set(_GENERATE_NATIVE_HEADERS_OUTPUT_DESC "$<BUILD_INTERFACE:${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_BUILD}>" "$<INSTALL_INTERFACE:${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_INSTALL}>") + endif() endif() set (_GENERATE_NATIVE_HEADERS_TARGET ${_add_jar_GENERATE_NATIVE_HEADERS_UNPARSED_ARGUMENTS}) set (_GENERATE_NATIVE_HEADERS_OUTPUT_DIR "${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION}") set (_GENERATE_NATIVE_HEADERS -h "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}") + if(NOT _GENERATE_NATIVE_HEADERS_OUTPUT_DESC) + set(_GENERATE_NATIVE_HEADERS_OUTPUT_DESC "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}") + endif() endif() if (LIBRARY_OUTPUT_PATH) @@ -498,14 +677,8 @@ function(add_jar _TARGET_NAME) ${CMAKE_JAVA_LIBRARY_OUTPUT_PATH} ) - if (CMAKE_HOST_WIN32 AND NOT CYGWIN AND CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") - set(CMAKE_JAVA_INCLUDE_FLAG_SEP ";") - else () - set(CMAKE_JAVA_INCLUDE_FLAG_SEP ":") - endif() - foreach (JAVA_INCLUDE_DIR IN LISTS CMAKE_JAVA_INCLUDE_PATH) - string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${CMAKE_JAVA_INCLUDE_FLAG_SEP}${JAVA_INCLUDE_DIR}") + string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${_UseJava_PATH_SEP}${JAVA_INCLUDE_DIR}") endforeach() set(CMAKE_JAVA_CLASS_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_TARGET_NAME}.dir") @@ -536,7 +709,7 @@ function(add_jar _TARGET_NAME) if (_JAVA_SOURCE_FILE MATCHES "^@(.+)$") get_filename_component(_JAVA_FULL ${CMAKE_MATCH_1} ABSOLUTE) - list (APPEND _JAVA_COMPILE_FILELISTS ${_JAVA_FULL}) + list(APPEND _JAVA_COMPILE_FILELISTS ${_JAVA_FULL}) elseif (_JAVA_EXT MATCHES ".java") file(RELATIVE_PATH _JAVA_REL_BINARY_PATH ${CMAKE_CURRENT_BINARY_DIR} ${_JAVA_FULL}) @@ -550,7 +723,7 @@ function(add_jar _TARGET_NAME) endif () get_filename_component(_JAVA_REL_PATH ${_JAVA_REL_PATH} PATH) - list (APPEND _JAVA_COMPILE_FILES ${_JAVA_SOURCE_FILE}) + list(APPEND _JAVA_COMPILE_FILES ${_JAVA_SOURCE_FILE}) set(_JAVA_CLASS_FILE "${CMAKE_JAVA_CLASS_OUTPUT_PATH}/${_JAVA_REL_PATH}/${_JAVA_FILE}.class") set(_JAVA_CLASS_FILES ${_JAVA_CLASS_FILES} ${_JAVA_CLASS_FILE}) @@ -561,15 +734,15 @@ function(add_jar _TARGET_NAME) # Ignored for backward compatibility elseif (_JAVA_EXT STREQUAL "") - list (APPEND CMAKE_JAVA_INCLUDE_PATH ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}} ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}_CLASSPATH}) - list (APPEND _JAVA_DEPENDS ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}}) + list(APPEND CMAKE_JAVA_INCLUDE_PATH ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}} ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}_CLASSPATH}) + list(APPEND _JAVA_DEPENDS ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}}) else () __java_copy_file(${CMAKE_CURRENT_SOURCE_DIR}/${_JAVA_SOURCE_FILE} ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/${_JAVA_SOURCE_FILE} "Copying ${_JAVA_SOURCE_FILE} to the build directory") - list (APPEND _JAVA_RESOURCE_FILES ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/${_JAVA_SOURCE_FILE}) - list (APPEND _JAVA_RESOURCE_FILES_RELATIVE ${_JAVA_SOURCE_FILE}) + list(APPEND _JAVA_RESOURCE_FILES ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/${_JAVA_SOURCE_FILE}) + list(APPEND _JAVA_RESOURCE_FILES_RELATIVE ${_JAVA_SOURCE_FILE}) endif () endforeach() @@ -577,18 +750,18 @@ function(add_jar _TARGET_NAME) if (TARGET ${_JAVA_INCLUDE_JAR}) get_target_property(_JAVA_JAR_PATH ${_JAVA_INCLUDE_JAR} JAR_FILE) if (_JAVA_JAR_PATH) - string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${CMAKE_JAVA_INCLUDE_FLAG_SEP}${_JAVA_JAR_PATH}") - list (APPEND CMAKE_JAVA_INCLUDE_PATH ${_JAVA_JAR_PATH}) - list (APPEND _JAVA_DEPENDS ${_JAVA_INCLUDE_JAR}) - list (APPEND _JAVA_COMPILE_DEPENDS ${_JAVA_JAR_PATH}) + string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${_UseJava_PATH_SEP}${_JAVA_JAR_PATH}") + list(APPEND CMAKE_JAVA_INCLUDE_PATH ${_JAVA_JAR_PATH}) + list(APPEND _JAVA_DEPENDS ${_JAVA_INCLUDE_JAR}) + list(APPEND _JAVA_COMPILE_DEPENDS ${_JAVA_JAR_PATH}) else () message(SEND_ERROR "add_jar: INCLUDE_JARS target ${_JAVA_INCLUDE_JAR} is not a jar") endif () else () - string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${CMAKE_JAVA_INCLUDE_FLAG_SEP}${_JAVA_INCLUDE_JAR}") - list (APPEND CMAKE_JAVA_INCLUDE_PATH "${_JAVA_INCLUDE_JAR}") - list (APPEND _JAVA_DEPENDS "${_JAVA_INCLUDE_JAR}") - list (APPEND _JAVA_COMPILE_DEPENDS "${_JAVA_INCLUDE_JAR}") + string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${_UseJava_PATH_SEP}${_JAVA_INCLUDE_JAR}") + list(APPEND CMAKE_JAVA_INCLUDE_PATH "${_JAVA_INCLUDE_JAR}") + list(APPEND _JAVA_DEPENDS "${_JAVA_INCLUDE_JAR}") + list(APPEND _JAVA_COMPILE_DEPENDS "${_JAVA_INCLUDE_JAR}") endif () endforeach() @@ -627,14 +800,14 @@ function(add_jar _TARGET_NAME) OUTPUT ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist COMMAND ${CMAKE_COMMAND} -DCMAKE_JAVA_CLASS_OUTPUT_PATH=${CMAKE_JAVA_CLASS_OUTPUT_PATH} - -DCMAKE_JAR_CLASSES_PREFIX="${CMAKE_JAR_CLASSES_PREFIX}" + -DCMAKE_JAR_CLASSES_PREFIX=${CMAKE_JAR_CLASSES_PREFIX} -P ${_JAVA_CLASS_FILELIST_SCRIPT} DEPENDS ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) else () # create an empty java_class_filelist - if (NOT EXISTS "${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist") + if (NOT EXISTS ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist) file(WRITE ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist "") endif() endif () @@ -731,8 +904,9 @@ function(add_jar _TARGET_NAME) # create an INTERFACE library encapsulating include directory for generated headers add_library (${_GENERATE_NATIVE_HEADERS_TARGET} INTERFACE) target_include_directories (${_GENERATE_NATIVE_HEADERS_TARGET} INTERFACE - "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}" + "${_GENERATE_NATIVE_HEADERS_OUTPUT_DESC}" ${JNI_INCLUDE_DIRS}) + set_property(TARGET ${_GENERATE_NATIVE_HEADERS_TARGET} PROPERTY NATIVE_HEADERS_DIRECTORY "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}") # this INTERFACE library depends on jar generation add_dependencies (${_GENERATE_NATIVE_HEADERS_TARGET} ${_TARGET_NAME}) @@ -985,7 +1159,7 @@ function(create_javadoc _target) elseif (arg STREQUAL "VERSION") set(_state "version") else () - list (APPEND _javadoc_packages ${arg}) + list(APPEND _javadoc_packages ${arg}) endif () elseif (_state STREQUAL "files") if (arg STREQUAL "PACKAGES") @@ -1009,7 +1183,7 @@ function(create_javadoc _target) elseif (arg STREQUAL "VERSION") set(_state "version") else () - list (APPEND _javadoc_files ${arg}) + list(APPEND _javadoc_files ${arg}) endif () elseif (_state STREQUAL "sourcepath") if (arg STREQUAL "PACKAGES") @@ -1033,7 +1207,7 @@ function(create_javadoc _target) elseif (arg STREQUAL "VERSION") set(_state "version") else () - list (APPEND _javadoc_sourcepath ${arg}) + list(APPEND _javadoc_sourcepath ${arg}) endif () elseif (_state STREQUAL "classpath") if (arg STREQUAL "PACKAGES") @@ -1057,7 +1231,7 @@ function(create_javadoc _target) elseif (arg STREQUAL "VERSION") set(_state "version") else () - list (APPEND _javadoc_classpath ${arg}) + list(APPEND _javadoc_classpath ${arg}) endif () elseif (_state STREQUAL "installpath") if (arg STREQUAL "PACKAGES") @@ -1238,68 +1412,45 @@ function(create_javadoc _target) set(_javadoc_options -d ${_javadoc_builddir}) if (_javadoc_sourcepath) - set(_start TRUE) - foreach(_path IN LISTS _javadoc_sourcepath) - if (_start) - set(_sourcepath ${_path}) - set(_start FALSE) - else () - set(_sourcepath ${_sourcepath}:${_path}) - endif () - endforeach() - set(_javadoc_options ${_javadoc_options} -sourcepath ${_sourcepath}) + list(JOIN _javadoc_sourcepath "${_UseJava_PATH_SEP}" _javadoc_sourcepath) + list(APPEND _javadoc_options -sourcepath "\"${_javadoc_sourcepath}\"") endif () if (_javadoc_overview) - set(_start TRUE) - foreach(_path IN LISTS _javadoc_overview) - if (_start) - set(_overview ${_path}) - set(_start FALSE) - else () - set(_overview ${_overview}:${_path}) - endif () - endforeach () - set(_javadoc_options ${_javadoc_options} -overview ${_overview}) + list(JOIN _javadoc_overview "${_UseJava_PATH_SEP}" _javadoc_overview) + list(APPEND _javadoc_options -overview "\"${_javadoc_overview}\"") endif () if (_javadoc_classpath) - set(_start TRUE) - foreach(_path IN LISTS _javadoc_classpath) - if (_start) - set(_classpath ${_path}) - set(_start FALSE) - else () - set(_classpath ${_classpath}:${_path}) - endif () - endforeach() - set(_javadoc_options ${_javadoc_options} -classpath "${_classpath}") + list(JOIN _javadoc_classpath "${_UseJava_PATH_SEP}" _javadoc_classpath) + list(APPEND _javadoc_options -classpath "\"${_javadoc_classpath}\"") endif () if (_javadoc_doctitle) - set(_javadoc_options ${_javadoc_options} -doctitle '${_javadoc_doctitle}') + list(APPEND _javadoc_options -doctitle '${_javadoc_doctitle}') endif () if (_javadoc_windowtitle) - set(_javadoc_options ${_javadoc_options} -windowtitle '${_javadoc_windowtitle}') + list(APPEND _javadoc_options -windowtitle '${_javadoc_windowtitle}') endif () if (_javadoc_author) - set(_javadoc_options ${_javadoc_options} -author) + list(APPEND _javadoc_options -author) endif () if (_javadoc_use) - set(_javadoc_options ${_javadoc_options} -use) + list(APPEND _javadoc_options -use) endif () if (_javadoc_version) - set(_javadoc_options ${_javadoc_options} -version) + list(APPEND _javadoc_options -version) endif () add_custom_target(${_target}_javadoc ALL - COMMAND ${Java_JAVADOC_EXECUTABLE} ${_javadoc_options} - ${_javadoc_files} - ${_javadoc_packages} + COMMAND ${Java_JAVADOC_EXECUTABLE} + ${_javadoc_options} + ${_javadoc_files} + ${_javadoc_packages} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) @@ -1335,11 +1486,6 @@ function (create_javah) endif() set (_output_files) - if (WIN32 AND NOT CYGWIN AND CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") - set(_classpath_sep "$<SEMICOLON>") - else () - set(_classpath_sep ":") - endif() # handle javah options set (_javah_options) @@ -1365,7 +1511,7 @@ function (create_javah) message(SEND_ERROR "create_javah: CLASSPATH entry ${_path} does not exist.") endif() endforeach() - string (REPLACE ";" "${_classpath_sep}" _classpath "${_classpath}") + string (REPLACE ";" "${_UseJava_PATH_SEP}" _classpath "${_classpath}") list (APPEND _javah_options -classpath "${_classpath}") endif() diff --git a/config/cmake/UseJavaClassFilelist.cmake b/config/cmake/UseJavaClassFilelist.cmake index 8348e4c..d90ca48 100644 --- a/config/cmake/UseJavaClassFilelist.cmake +++ b/config/cmake/UseJavaClassFilelist.cmake @@ -1,17 +1,8 @@ # Distributed under the OSI-approved BSD 3-Clause License. See https://cmake.org/licensing for details. -#[=======================================================================[.rst: -UseJavaClassFilelist --------------------- - - - - - -This script create a list of compiled Java class files to be added to -a jar file. This avoids including cmake files which get created in -the binary directory. -#]=======================================================================] +# This script creates a list of compiled Java class files to be added to +# a jar file. This avoids including cmake files which get created in +# the binary directory. if (CMAKE_JAVA_CLASS_OUTPUT_PATH) if (EXISTS "${CMAKE_JAVA_CLASS_OUTPUT_PATH}") @@ -23,7 +14,7 @@ if (CMAKE_JAVA_CLASS_OUTPUT_PATH) file(GLOB_RECURSE _JAVA_GLOBBED_TMP_FILES "${CMAKE_JAVA_CLASS_OUTPUT_PATH}/${JAR_CLASS_PREFIX}/*.class") if (_JAVA_GLOBBED_TMP_FILES) - list (APPEND _JAVA_GLOBBED_FILES ${_JAVA_GLOBBED_TMP_FILES}) + list(APPEND _JAVA_GLOBBED_FILES ${_JAVA_GLOBBED_TMP_FILES}) endif () endforeach() else() diff --git a/config/cmake/UseJavaSymlinks.cmake b/config/cmake/UseJavaSymlinks.cmake index a4db5c1..cb2e282 100644 --- a/config/cmake/UseJavaSymlinks.cmake +++ b/config/cmake/UseJavaSymlinks.cmake @@ -1,15 +1,6 @@ # Distributed under the OSI-approved BSD 3-Clause License. See https://cmake.org/licensing for details. -#[=======================================================================[.rst: -UseJavaSymlinks ---------------- - - - - - -Helper script for UseJava.cmake -#]=======================================================================] +# Helper script for UseJava.cmake if (UNIX AND _JAVA_TARGET_OUTPUT_LINK) if (_JAVA_TARGET_OUTPUT_NAME) diff --git a/config/cmake/hdf5-config.cmake.in b/config/cmake/hdf5-config.cmake.in index 4d02c9c..8faa2fe 100644 --- a/config/cmake/hdf5-config.cmake.in +++ b/config/cmake/hdf5-config.cmake.in @@ -38,6 +38,7 @@ set (${HDF5_PACKAGE_NAME}_BUILD_CPP_LIB @HDF5_BUILD_CPP_LIB@) set (${HDF5_PACKAGE_NAME}_BUILD_JAVA @HDF5_BUILD_JAVA@) set (${HDF5_PACKAGE_NAME}_BUILD_TOOLS @HDF5_BUILD_TOOLS@) set (${HDF5_PACKAGE_NAME}_BUILD_HL_LIB @HDF5_BUILD_HL_LIB@) +set (${HDF5_PACKAGE_NAME}_BUILD_HL_TOOLS @HDF5_BUILD_HL_TOOLS@) set (${HDF5_PACKAGE_NAME}_ENABLE_THREADSAFE @HDF5_ENABLE_THREADSAFE@) set (${HDF5_PACKAGE_NAME}_ENABLE_PLUGIN_SUPPORT @HDF5_ENABLE_PLUGIN_SUPPORT@) set (${HDF5_PACKAGE_NAME}_ENABLE_Z_LIB_SUPPORT @HDF5_ENABLE_Z_LIB_SUPPORT@) diff --git a/config/cmake/javaTargets.cmake.in b/config/cmake/javaTargets.cmake.in new file mode 100644 index 0000000..6e14256 --- /dev/null +++ b/config/cmake/javaTargets.cmake.in @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 2.8.12) +cmake_policy(PUSH) +cmake_policy(VERSION 2.8) + +#---------------------------------------------------------------- +# Generated CMake Java target import file. +#---------------------------------------------------------------- + +# Protect against multiple inclusion, which would fail when already imported targets are added once more. +set(_targetsDefined) +set(_targetsNotDefined) +set(_expectedTargets) +foreach(_expectedTarget @__targets__@) + list(APPEND _expectedTargets ${_expectedTarget}) + if(TARGET ${_expectedTarget}) + list(APPEND _targetsDefined ${_expectedTarget}) + else() + list(APPEND _targetsNotDefined ${_expectedTarget}) + endif() +endforeach() +if("%${_targetsDefined}" STREQUAL "%${_expectedTargets}") + unset(_targetsDefined) + unset(_targetsNotDefined) + unset(_expectedTargets) + cmake_policy(POP) + return() +endif() +if(NOT "${_targetsDefined}" STREQUAL "") + message(FATAL_ERROR + "Some (but not all) targets in this export set were already defined.\n" + "Targets Defined: ${_targetsDefined}\n" + "Targets not yet defined: ${_targetsNotDefined}\n") +endif() +unset(_targetsDefined) +unset(_targetsNotDefined) +unset(_expectedTargets) + +@__targetdefs__@ +cmake_policy(POP) diff --git a/config/cmake/libh5cc.in b/config/cmake/libh5cc.in index c98d9ca..ecdd13e 100644 --- a/config/cmake/libh5cc.in +++ b/config/cmake/libh5cc.in @@ -29,4 +29,4 @@ printf 'dir is %s\n' "$dir" export PKG_CONFIG_PATH=$dir/lib/pkgconfig -@_PKG_CONFIG_COMPILER@ `pkg-config --define-variable=prefix=$dir --cflags --libs @_PKG_CONFIG_LIBNAME@` $@ +@_PKG_CONFIG_COMPILER@ $@ `pkg-config --define-variable=prefix=$dir --cflags --libs @_PKG_CONFIG_LIBNAME@` diff --git a/config/cmake/libhdf5.settings.cmake.in b/config/cmake/libhdf5.settings.cmake.in index ebcbd61..eb83c3a 100644 --- a/config/cmake/libhdf5.settings.cmake.in +++ b/config/cmake/libhdf5.settings.cmake.in @@ -70,6 +70,7 @@ Parallel Filtered Dataset Writes: @PARALLEL_FILTERED_WRITES@ High-level library: @HDF5_BUILD_HL_LIB@ Build HDF5 Tests: @BUILD_TESTING@ Build HDF5 Tools: @HDF5_BUILD_TOOLS@ + Build High-level HDF5 Tools: @HDF5_BUILD_HL_TOOLS@ Threadsafety: @HDF5_ENABLE_THREADSAFE@ Default API mapping: @DEFAULT_API_VERSION@ With deprecated public symbols: @HDF5_ENABLE_DEPRECATED_SYMBOLS@ diff --git a/config/cmake/scripts/HDF5config.cmake b/config/cmake/scripts/HDF5config.cmake index 08e38e8..8df7dd4 100644 --- a/config/cmake/scripts/HDF5config.cmake +++ b/config/cmake/scripts/HDF5config.cmake @@ -11,7 +11,7 @@ # ############################################################################################# ### ${CTEST_SCRIPT_ARG} is of the form OPTION=VALUE ### -### BUILD_GENERATOR required [Unix, VS2017, VS201764, VS2015, VS201564, VS2013, VS201364] ### +### BUILD_GENERATOR required [Unix, VS2019, VS201964, VS2017, VS201764, VS2015, VS201564] ### ### ctest -S HDF5config.cmake,BUILD_GENERATOR=VS201764 -C Release -VV -O hdf5.log ### ############################################################################################# @@ -68,7 +68,7 @@ endif () # build generator must be defined if (NOT DEFINED BUILD_GENERATOR) - message (FATAL_ERROR "BUILD_GENERATOR must be defined - Unix, VS2017, or VS201764, VS2015, VS201564, VS2013, VS201364") + message (FATAL_ERROR "BUILD_GENERATOR must be defined - Unix, VS2019, VS201964, VS2017, or VS201764, VS2015, VS201564") endif () ################################################################### @@ -163,7 +163,7 @@ if (NOT DEFINED HPC) set (SITE_COMPILER_NAME "vs2012") set (SITE_COMPILER_VERSION "11") else () - message (FATAL_ERROR "Invalid BUILD_GENERATOR must be - Unix, VS2017, or VS201764, VS2015, VS201564, VS2013, VS201364") + message (FATAL_ERROR "Invalid BUILD_GENERATOR must be - Unix, VS2019, VS201964, VS2017, or VS201764, VS2015, VS201564") endif () ## Set the following to unique id your computer ## set (CTEST_SITE "WIN7${BUILD_GENERATOR}.XXXX") diff --git a/config/cmake/scripts/HDF5options.cmake b/config/cmake/scripts/HDF5options.cmake index 7133e6c..136f55d 100644 --- a/config/cmake/scripts/HDF5options.cmake +++ b/config/cmake/scripts/HDF5options.cmake @@ -69,7 +69,7 @@ set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DHDF5_ALLOW_EXTERNAL_SUPPORT:STRIN #set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DHDF5_ENABLE_SZIP_ENCODING:BOOL=OFF") #### package examples #### -#set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DHDF5_PACK_EXAMPLES:BOOL=ON -DHDF5_EXAMPLES_COMPRESSED:STRING=HDF5Examples-1.14.1-Source.tar.gz -DHDF5_EXAMPLES_COMPRESSED_DIR:PATH=${CTEST_SCRIPT_DIRECTORY}") +#set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DHDF5_PACK_EXAMPLES:BOOL=ON -DHDF5_EXAMPLES_COMPRESSED:STRING=HDF5Examples-1.14.4-Source.tar.gz -DHDF5_EXAMPLES_COMPRESSED_DIR:PATH=${CTEST_SCRIPT_DIRECTORY}") ############################################################################################# ### enable parallel builds diff --git a/config/cmake_ext_mod/ConfigureChecks.cmake b/config/cmake_ext_mod/ConfigureChecks.cmake index 61cec8b..53cc2d1 100644 --- a/config/cmake_ext_mod/ConfigureChecks.cmake +++ b/config/cmake_ext_mod/ConfigureChecks.cmake @@ -115,7 +115,7 @@ CHECK_INCLUDE_FILE_CONCAT ("sys/types.h" ${HDF_PREFIX}_HAVE_SYS_TYPES_H) CHECK_INCLUDE_FILE_CONCAT ("features.h" ${HDF_PREFIX}_HAVE_FEATURES_H) CHECK_INCLUDE_FILE_CONCAT ("dirent.h" ${HDF_PREFIX}_HAVE_DIRENT_H) CHECK_INCLUDE_FILE_CONCAT ("unistd.h" ${HDF_PREFIX}_HAVE_UNISTD_H) - +CHECK_INCLUDE_FILE_CONCAT ("pwd.h" ${HDF_PREFIX}_HAVE_PWD_H) CHECK_INCLUDE_FILE_CONCAT ("globus/common.h" ${HDF_PREFIX}_HAVE_GLOBUS_COMMON_H) CHECK_INCLUDE_FILE_CONCAT ("pdb.h" ${HDF_PREFIX}_HAVE_PDB_H) CHECK_INCLUDE_FILE_CONCAT ("pthread.h" ${HDF_PREFIX}_HAVE_PTHREAD_H) diff --git a/config/gnu-fflags b/config/gnu-fflags index ec4fcab..ce12561 100644 --- a/config/gnu-fflags +++ b/config/gnu-fflags @@ -161,10 +161,10 @@ if test "X-gfortran" = "X-$f9x_vendor"; then # gfortran 4.9 (nothing new) - # gfortran >= 5 - if test $f9x_vers_major -ge 5; then - H5_FCFLAGS="$H5_FCFLAGS $(load_gnu_arguments gfort-5)" - fi + # gfortran >= 5 (do not include -Wuse-without-only) + #if test $f9x_vers_major -ge 5; then + # H5_FCFLAGS="$H5_FCFLAGS $(load_gnu_arguments gfort-5)" + #fi # gfortran >= 6 if test $f9x_vers_major -ge 6; then diff --git a/config/intel-warnings/18 b/config/intel-warnings/18 index 565b47a..02bcdea 100644 --- a/config/intel-warnings/18 +++ b/config/intel-warnings/18 @@ -1,8 +1,2 @@ --Wextra-tokens --Wformat --Wformat-security -Wic-pointer --Wshadow -Wsign-compare --Wtrigraphs --Wwrite-strings diff --git a/config/intel-warnings/general-19 b/config/intel-warnings/general-19 deleted file mode 100644 index e35af30..0000000 --- a/config/intel-warnings/general-19 +++ /dev/null @@ -1,2 +0,0 @@ -# this is only available before oneapi versions --Wcheck diff --git a/config/intel-warnings/win-developer-general b/config/intel-warnings/win-developer-general new file mode 100644 index 0000000..6cd7ed7 --- /dev/null +++ b/config/intel-warnings/win-developer-general @@ -0,0 +1 @@ +/Wport diff --git a/config/intel-warnings/win-general b/config/intel-warnings/win-general new file mode 100644 index 0000000..ef54b2b --- /dev/null +++ b/config/intel-warnings/win-general @@ -0,0 +1 @@ +/Wall diff --git a/config/sanitizer/sanitizers.cmake b/config/sanitizer/sanitizers.cmake index 0803279..58c4050 100644 --- a/config/sanitizer/sanitizers.cmake +++ b/config/sanitizer/sanitizers.cmake @@ -33,10 +33,10 @@ if(USE_SANITIZER) if(INTEL_CLANG OR "${CMAKE_C_COMPILER_ID}" MATCHES "Clang") set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - append("-fno-omit-frame-pointer" CMAKE_C_SANITIZER_FLAGS CMAKE_CXX_SANITIZER_FLAGS) - message(STATUS "Building with sanitize, base flags=${CMAKE_C_SANITIZER_FLAGS}") - if(UNIX) + append("-fno-omit-frame-pointer" CMAKE_C_SANITIZER_FLAGS CMAKE_CXX_SANITIZER_FLAGS) + message(STATUS "Building with sanitize, base flags=${CMAKE_C_SANITIZER_FLAGS}") + if(uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG") append("-O1" CMAKE_C_SANITIZER_FLAGS CMAKE_CXX_SANITIZER_FLAGS) endif() @@ -83,7 +83,7 @@ if(USE_SANITIZER) elseif(MSVC) if(USE_SANITIZER MATCHES "([Aa]ddress)") message(STATUS "Building with Address sanitizer") - append("-fsanitize=address" CMAKE_C_SANITIZER_FLAGS CMAKE_CXX_SANITIZER_FLAGS) + append("/fsanitize=address" CMAKE_C_SANITIZER_FLAGS CMAKE_CXX_SANITIZER_FLAGS) else() message(FATAL_ERROR "This sanitizer not yet supported in the MSVC environment: ${USE_SANITIZER}") endif() diff --git a/config/toolchain/clang.cmake b/config/toolchain/clang.cmake index 5e3b13a..af176aa 100644 --- a/config/toolchain/clang.cmake +++ b/config/toolchain/clang.cmake @@ -3,8 +3,13 @@ set(CMAKE_COMPILER_VENDOR "clang") -set(CMAKE_C_COMPILER clang) -set(CMAKE_CXX_COMPILER clang++) +if(WIN32) + set(CMAKE_C_COMPILER clang-cl) + set(CMAKE_CXX_COMPILER clang-cl) +else() + set(CMAKE_C_COMPILER clang) + set(CMAKE_CXX_COMPILER clang++) +endif() set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # the following is used if cross-compiling diff --git a/configure.ac b/configure.ac index a7366eb..3290de4 100644 --- a/configure.ac +++ b/configure.ac @@ -786,6 +786,7 @@ AC_LANG_POP(C++) ## This needs to be exposed for the library info file even if the HL ## library is disabled. AC_SUBST([HDF5_HL]) +AC_SUBST([HDF5_HL_TOOLS]) ## The high-level library is enabled unless the build mode is clean. if test "X-$BUILD_MODE" = "X-clean" ; then @@ -802,6 +803,9 @@ HL="" ## Fortran high-level library AC_SUBST(HL_FOR) HL_FOR="" +## Tools high-level library +AC_SUBST(HL_TOOLS) +HL_TOOLS="" AC_MSG_CHECKING([if the high-level library is enabled]) AC_ARG_ENABLE([hl], @@ -820,6 +824,21 @@ else AC_MSG_RESULT([no]) fi +AC_MSG_CHECKING([if the high-level tools are enabled]) +AC_ARG_ENABLE([hltools], + [AS_HELP_STRING([--enable-hltools], + [Enable the high-level tools. + [default=yes)] + ])], + [HDF5_HL_TOOLS=$enableval]) + +if test "X${HDF5_HL}" = "Xyes" -a "X-$HDF5_HL_TOOLS" = "X-yes"; then + AC_MSG_RESULT([yes]) + HL_TOOLS="tools" +else + AC_MSG_RESULT([no]) +fi + ## ---------------------------------------------------------------------- ## Check which archiving tool to use. This needs to be done before @@ -1102,29 +1121,35 @@ if test "X$HDF5_DOXYGEN" = "Xyes"; then AC_SUBST([DOXYGEN_HTML_FOOTER]) AC_SUBST([DOXYGEN_HTML_EXTRA_STYLESHEET]) AC_SUBST([DOXYGEN_HTML_EXTRA_FILES]) + AC_SUBST([DOXYGEN_TAG_FILE]) AC_SUBST([DOXYGEN_SERVER_BASED_SEARCH]) AC_SUBST([DOXYGEN_EXTERNAL_SEARCH]) AC_SUBST([DOXYGEN_SEARCHENGINE_URL]) + AC_SUBST([DOXYGEN_STRIP_FROM_PATH]) + AC_SUBST([DOXYGEN_PREDEFINED]) # SRCDIR Environment variables used inside doxygen macro for the source location: DOXYGEN_PACKAGE=${PACKAGE_NAME} DOXYGEN_VERSION_STRING=${PACKAGE_VERSION} DOXYGEN_INCLUDE_ALIASES='$(SRCDIR)/doxygen/aliases' DOXYGEN_PROJECT_LOGO='$(SRCDIR)/doxygen/img/HDFG-logo.png' - DOXYGEN_PROJECT_BRIEF= + DOXYGEN_PROJECT_BRIEF='C-API Reference' DOXYGEN_INPUT_DIRECTORY='$(SRCDIR) $(SRCDIR)/doxygen/dox' DOXYGEN_OPTIMIZE_OUTPUT_FOR_C=YES DOXYGEN_MACRO_EXPANSION=YES DOXYGEN_OUTPUT_DIRECTORY=hdf5lib_docs - DOXYGEN_EXAMPLES_DIRECTORY='$(SRCDIR)/doxygen/examples $(SRCDIR)/src $(SRCDIR)/examples $(SRCDIR)/test' + DOXYGEN_EXAMPLES_DIRECTORY='$(SRCDIR)/doxygen/dox/cookbook $(SRCDIR)/doxygen/examples $(SRCDIR)/src $(SRCDIR)/examples $(SRCDIR)/test' DOXYGEN_LAYOUT_FILE='$(SRCDIR)/doxygen/hdf5doxy_layout.xml' DOXYGEN_HTML_HEADER='$(SRCDIR)/doxygen/hdf5_header.html' DOXYGEN_HTML_FOOTER='$(SRCDIR)/doxygen/hdf5_footer.html' DOXYGEN_HTML_EXTRA_STYLESHEET='$(SRCDIR)/doxygen/hdf5doxy.css' DOXYGEN_HTML_EXTRA_FILES='$(SRCDIR)/doxygen/hdf5_navtree_hacks.js $(SRCDIR)/doxygen/img/ftv2node.png $(SRCDIR)/doxygen/img/ftv2pnode.png' + DOXYGEN_TAG_FILE=hdf5.tag DOXYGEN_SERVER_BASED_SEARCH=NO DOXYGEN_EXTERNAL_SEARCH=NO DOXYGEN_SEARCHENGINE_URL= + DOXYGEN_STRIP_FROM_PATH='$(SRCDIR)' + DOXYGEN_PREDEFINED='H5_HAVE_DIRECT H5_HAVE_LIBHDFS H5_HAVE_MAP_API H5_HAVE_PARALLEL H5_HAVE_ROS3_VFD' DX_INIT_DOXYGEN([HDF5], [./doxygen/Doxyfile], [hdf5lib_docs]) @@ -1225,7 +1250,7 @@ AC_CHECK_LIB([dl], [dlopen]) ## ## Unix -AC_CHECK_HEADERS([dirent.h features.h unistd.h]) +AC_CHECK_HEADERS([dirent.h features.h pwd.h unistd.h]) AC_CHECK_HEADERS([sys/file.h sys/ioctl.h sys/resource.h]) AC_CHECK_HEADERS([sys/stat.h sys/time.h sys/types.h]) @@ -1240,8 +1265,6 @@ case $host_os in esac ## Windows -## The winsock header is needed for gethostname -AC_CHECK_HEADERS([winsock2.h]) case "`uname`" in MINGW*) AC_HAVE_LIBRARY([ws2_32]) @@ -3868,6 +3891,7 @@ AM_CONDITIONAL([BUILD_HDF5_HL_CONDITIONAL], [test "X$HDF5_HL" = "Xyes"]) AM_CONDITIONAL([BUILD_TESTS_CONDITIONAL], [test "X$HDF5_TESTS" = "Xyes"]) AM_CONDITIONAL([BUILD_TESTS_PARALLEL_CONDITIONAL], [test -n "$TESTPARALLEL"]) AM_CONDITIONAL([BUILD_TOOLS_CONDITIONAL], [test "X$HDF5_TOOLS" = "Xyes"]) +AM_CONDITIONAL([BUILD_TOOLS_HL_CONDITIONAL], [test "X$HDF5_HL_TOOLS" = "Xyes"]) AM_CONDITIONAL([BUILD_DOXYGEN_CONDITIONAL], [test "X$HDF5_DOXYGEN" = "Xyes"]) ## ---------------------------------------------------------------------- @@ -4044,6 +4068,7 @@ AC_CONFIG_FILES([src/libhdf5.settings tools/test/misc/vds/Makefile tools/test/h5stat/Makefile tools/test/h5stat/testh5stat.sh + tools/src/h5perf/Makefile tools/test/perform/Makefile examples/Makefile examples/run-c-ex.sh diff --git a/doc/contributing.md b/doc/contributing.md index 7f9e8d3..d32ab4d 100644 --- a/doc/contributing.md +++ b/doc/contributing.md @@ -1,10 +1,10 @@ # How to contribute to HDF5 -The HDF Group encourages community members to contribute to the HDF5 project. We accept and are very grateful for any contributions, +The HDF Group encourages community members to contribute to the HDF5 project. We accept and are very grateful for any contributions, from minor typos and bug fixes to new features. The HDF Group is committed to work with the code contributors and make contribution process enjoyable and straightforward. -This document describes guiding principles for the HDF5 code contributors and does not pretend to address any possible -contribution. If in doubt, please do not hesitate to ask us for guidance. +This document describes guiding principles for the HDF5 code contributors and does not pretend to address any possible +contribution. If in doubt, please do not hesitate to ask us for guidance. ***Note that no contribution may be accepted unless the donor agrees with the HDF Group software license terms found in the COPYING file in every branch's top source directory.*** @@ -23,38 +23,38 @@ The process for contributing code to HDF5 is as follows: * Open an issue on [HDF5 GitHub](https://github.com/HDFGroup/hdf5/issues). -> This step is ***required*** unless the change is minor (e.g., typo fix). +> This step is ***required*** unless the change is minor (e.g., typo fix). * Fork the [HDF5](https://github.com/HDFGroup/hdf5) repository. * Make the desired changes to the HDF5 software. * New features should always go to _develop_ branch first and later should be merged to the appropriate maintenance branches. - * Bug fixes should go to all appropriate branches (_develop_ and maintenance). + * Bug fixes should go to all appropriate branches (_develop_ and maintenance). * Build and test your changes. Detailed instructions on building and testing HDF5 can be found in the `INSTALL*` files in the `release_docs` directory. * Push your changes to GitHub. * Issue a pull request and address any code formatting and testing issues reported. Once a pull request is correctly formatted and passes **ALL** CI tests, it will be reviewed and evaluated by The HDF Group developers and HDF5 community members who can approve pull requests. -The HDF Group developers will work with you to ensure that the pull request satisfies the acceptance criteria described in the next section. +The HDF Group developers will work with you to ensure that the pull request satisfies the acceptance criteria described in the next section. # Acceptance criteria for a pull request <A NAME="criteria"></A> We appreciate every contribution we receive, but we may not accept them all. Those that we *do* satisfy the following criteria: -* **The pull request has a clear purpose** - What does the pull request address? How does it benefit the HDF5 community? -If the pull request does not have a clear purpose and benefits, it will not be accepted. +* **The pull request has a clear purpose** - What does the pull request address? How does it benefit the HDF5 community? +If the pull request does not have a clear purpose and benefits, it will not be accepted. * **The pull request is documented** - The HDF5 developers must understand not only *what* a change is doing, but *how* it is doing it. - Documenting the code makes it easier for us to understand your patch and maintain the code in the future. + Documenting the code makes it easier for us to understand your patch and maintain the code in the future. -* **The pull request passes HDF5 regression testing** - Any issue fixed or functionality added should be accompanied by the corresponding -tests and pass HDF5 regression testing run by The HDF Group. We do not expect you to perform comprehensive testing across multiple platforms -before we accept the pull request. If the pull request does not pass regression testing after the merge, The HDF Group developers will work with you on the fixes. +* **The pull request passes HDF5 regression testing** - Any issue fixed or functionality added should be accompanied by the corresponding +tests and pass HDF5 regression testing run by The HDF Group. We do not expect you to perform comprehensive testing across multiple platforms +before we accept the pull request. If the pull request does not pass regression testing after the merge, The HDF Group developers will work with you on the fixes. -* **The pull request does not compromise the principles behind HDF5** - HDF5 has a 100% commitment to backward compatibility. +* **The pull request does not compromise the principles behind HDF5** - HDF5 has a 100% commitment to backward compatibility. * Any file ever created with HDF5 must be readable by any future version of HDF5. If your patch's purpose is to modify the HDF5 data model or file format, - **please** discuss this with us first. File format changes and features required by those changes can be introduced only in a new major release. - * HDF5 has a commitment to remaining *machine-independent*; data created on one platform/environment/architecture **must** remain readable by HDF5 on any other. + **please** discuss this with us first. File format changes and features required by those changes can be introduced only in a new major release. + * HDF5 has a commitment to remaining *machine-independent*; data created on one platform/environment/architecture **must** remain readable by HDF5 on any other. * For binary compatibility, no changes are allowed to public APIs and data structures in the maintenance releases; new APIs can be added. * **New features are documented** - Any new features should have proper documentation; talk to us if you have any questions. @@ -64,7 +64,7 @@ before we accept the pull request. If the pull request does not pass regression Please make sure that you check the items applicable to your pull request: -* Code +* Code * [ ] Does the pull request have a corresponding GitHub issue and clear purpose? * [ ] Does the pull request follow HDF5 best practices (naming conventions, code portability, code structure, etc.)? <<TODO: link to the document>> * [ ] If changes were done to Autotools build, were they added to CMake and vice versa? @@ -74,7 +74,7 @@ Please make sure that you check the items applicable to your pull request: * Documentation * [ ] Was the change described in the release_docs/RELEASE.txt file? * [ ] Was MANIFEST updated if new files had been added to the source? - * [ ] Was the new function documented in the corresponding public header file using Doxygen? <<TODO: link to Doxygen instructions>> + * [ ] Was the new function documented in the corresponding public header file using [Doxygen](https://docs.hdfgroup.org/hdf5/develop/_r_m_t.html)? * [ ] Was new functionality documented for the HDF5 community (the level of documentation depends on the feature; ask us what would be appropriate) * Testing * [ ] Does the pull request have tests? @@ -83,4 +83,3 @@ Please make sure that you check the items applicable to your pull request: We want as many contributions as we can get, and we are here to help. Feel free to reach out to us if you have any questions Thank you for your contribution! - diff --git a/doxygen/CMakeLists.txt b/doxygen/CMakeLists.txt new file mode 100644 index 0000000..36ce590 --- /dev/null +++ b/doxygen/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required (VERSION 3.12) +project (HDF5_DOXYGEN C) + +#----------------------------------------------------------------------------- +# Option to build documentation +#----------------------------------------------------------------------------- +if (DOXYGEN_FOUND) + set (DOXYGEN_PACKAGE ${HDF5_PACKAGE_NAME}) + set (DOXYGEN_VERSION_STRING ${HDF5_PACKAGE_VERSION_STRING}) + set (DOXYGEN_INCLUDE_ALIASES_PATH ${HDF5_DOXYGEN_DIR}) + set (DOXYGEN_INCLUDE_ALIASES aliases) + set (DOXYGEN_VERBATIM_VARS DOXYGEN_INCLUDE_ALIASES) + set (DOXYGEN_PROJECT_LOGO ${HDF5_DOXYGEN_DIR}/img/HDFG-logo.png) + set (DOXYGEN_PROJECT_BRIEF "C-API Reference") + set (DOXYGEN_INPUT_DIRECTORY "${HDF5_SOURCE_DIR} ${HDF5_DOXYGEN_DIR}/dox ${HDF5_GENERATED_SOURCE_DIR}") + set (DOXYGEN_OPTIMIZE_OUTPUT_FOR_C YES) + set (DOXYGEN_MACRO_EXPANSION YES) + set (DOXYGEN_OUTPUT_DIRECTORY ${HDF5_BINARY_DIR}/hdf5lib_docs) + set (DOXYGEN_EXAMPLES_DIRECTORY "${HDF5_DOXYGEN_DIR}/dox/cookbook ${HDF5_DOXYGEN_DIR}/examples ${HDF5_SRC_DIR} ${HDF5_SOURCE_DIR}/examples ${HDF5_TEST_SRC_DIR}") + set (DOXYGEN_LAYOUT_FILE ${HDF5_DOXYGEN_DIR}/hdf5doxy_layout.xml) + set (DOXYGEN_HTML_HEADER ${HDF5_DOXYGEN_DIR}/hdf5_header.html) + set (DOXYGEN_HTML_FOOTER ${HDF5_DOXYGEN_DIR}/hdf5_footer.html) + set (DOXYGEN_HTML_EXTRA_STYLESHEET ${HDF5_DOXYGEN_DIR}/hdf5doxy.css) + set (DOXYGEN_HTML_EXTRA_FILES "${HDF5_DOXYGEN_DIR}/hdf5_navtree_hacks.js ${HDF5_DOXYGEN_DIR}/img/ftv2node.png ${HDF5_DOXYGEN_DIR}/img/ftv2pnode.png") + set (DOXYGEN_TAG_FILE ${HDF5_BINARY_DIR}/hdf5.tag) + set (DOXYGEN_SERVER_BASED_SEARCH NO) + set (DOXYGEN_EXTERNAL_SEARCH NO) + set (DOXYGEN_SEARCHENGINE_URL) + set (DOXYGEN_STRIP_FROM_PATH ${HDF5_SOURCE_DIR}) + set (DOXYGEN_PREDEFINED "H5_HAVE_DIRECT H5_HAVE_LIBHDFS H5_HAVE_MAP_API H5_HAVE_PARALLEL H5_HAVE_ROS3_VFD") + +# This configure and individual custom targets work together + # Replace variables inside @@ with the current values + configure_file (${HDF5_DOXYGEN_DIR}/Doxyfile.in ${HDF5_BINARY_DIR}/Doxyfile @ONLY) + + install ( + DIRECTORY ${HDF5_BINARY_DIR}/hdf5lib_docs/html + DESTINATION ${HDF5_INSTALL_DATA_DIR} + COMPONENT Documents + ) + + if (NOT TARGET doxygen) + add_custom_target (doxygen) + endif () + +endif () diff --git a/doxygen/Doxyfile.in b/doxygen/Doxyfile.in index 29f3028..44d9974 100644 --- a/doxygen/Doxyfile.in +++ b/doxygen/Doxyfile.in @@ -170,7 +170,7 @@ FULL_PATH_NAMES = YES # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. -STRIP_FROM_PATH = +STRIP_FROM_PATH = @DOXYGEN_STRIP_FROM_PATH@ # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which @@ -858,16 +858,21 @@ FILE_PATTERNS = H5*public.h \ H5FDcore.h \ H5FDdirect.h \ H5FDfamily.h \ + H5FDhdfs.h \ H5FDlog.h \ + H5FDmirror.h \ H5FDmpi.h \ H5FDmpio.h \ H5FDmulti.h \ + H5FDros3.h \ H5FDsec2.h \ + H5FDsplitter.h \ H5FDstdio.h \ H5FDwindows.h \ H5VLconnector.h \ H5VLconnector_passthru.h \ H5VLnative.h \ + H5Zdevelop.h \ H5version.h \ *.dox @@ -1121,13 +1126,6 @@ CLANG_DATABASE_PATH = ALPHABETICAL_INDEX = YES -# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in -# which the alphabetical index list will be split. -# Minimum value: 1, maximum value: 20, default value: 5. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -COLS_IN_ALPHA_INDEX = 5 - # In case all classes in a project start with a common prefix, all classes will # be put under the same header in the alphabetical index. The IGNORE_PREFIX tag # can be used to specify a prefix (or a list of prefixes) that should be ignored @@ -2177,7 +2175,7 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = H5_HAVE_PARALLEL +PREDEFINED = @DOXYGEN_PREDEFINED@ # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The @@ -2221,7 +2219,7 @@ TAGFILES = # tag file that is based on the input files it reads. See section "Linking to # external documentation" for more information about the usage of tag files. -GENERATE_TAGFILE = +GENERATE_TAGFILE = @DOXYGEN_TAG_FILE@ # If the ALLEXTERNALS tag is set to YES, all external class will be listed in # the class index. If set to NO, only the inherited external classes will be diff --git a/doxygen/aliases b/doxygen/aliases index af43902..06c3445 100644 --- a/doxygen/aliases +++ b/doxygen/aliases @@ -16,11 +16,17 @@ ALIASES += success{1}="\Bold{Success:} \1" ALIASES += failure{1}="\Bold{Failure:} \1" ALIASES += herr_t="Returns a non-negative value if successful; otherwise returns a negative value." +ALIASES += herr_t_iter="\li Zero causes the iterator to continue, returning zero when the iteration is complete. \li A positive value causes the iterator to immediately return that positive value, indicating short-circuit success. \li A negative value causes the iterator to immediately return that value, indicating failure." ALIASES += hid_t{1}="Returns a \1 identifier if successful; otherwise returns #H5I_INVALID_HID. " ALIASES += hid_ti{1}="Returns an \1 identifier if successful; otherwise returns #H5I_INVALID_HID. " ALIASES += hid_tv{1}="Returns an \1 identifier if successful; otherwise returns a negative value. " ALIASES += htri_t="Returns zero (false), a positive (true) or a negative (failure) value." +ALIASES += api_vers_2{3}="\1() is a macro that is mapped to either \2() or \3().\n\see \ref api-compat-macros" +ALIASES += api_vers_3{4}="\1() is a macro that is mapped to either \2() or \3() or \4().\n\see \ref api-compat-macros" + +ALIASES += deprecation_note{1}="\deprecated Superseded by \1." + ################################################################################ # General ################################################################################ @@ -131,6 +137,8 @@ ALIASES += map_id{1}="\param[in] \1 Map identifier" # Property lists ################################################################################ +ALIASES += plist_unused{1}="\note The \p \1 parameter is currently not used; specify #H5P_DEFAULT." + ALIASES += aapl_id="\param[in] aapl_id Attribute access property list identifier" ALIASES += aapl_id{1}="\param[in] \1 Attribute access property list identifier" @@ -217,9 +225,8 @@ ALIASES += es_id{1}="\param[in] \1 Event set identifier" # Others ################################################################################ -ALIASES += estack_id="\param[in] estack_id Error stack identifier" -ALIASES += estack_id{1}="\param[in] \1 Error stack identifier" ALIASES += cpp_c_api_note="\attention \Bold{C++ Developers using HDF5 C-API functions beware:}\n Several functions in this C-API take function pointers or callbacks as arguments. Examples include H5Pset_elink_cb(), H5Pset_type_conv_cb(), H5Tconvert(), and H5Ewalk2(). Application code must ensure that those callback functions return normally such to allow the HDF5 to manage its resources and maintain a consistent state. For instance, those functions must not use the C \c setjmp / \c longjmp mechanism to leave those callback functions. Within the context of C++, any exceptions thrown within the callback function must be caught, such as with a \Code{catch(…)} statement. Any exception state can be placed within the provided user data function call arguments, and may be thrown again once the calling function has returned. Exceptions raised and not handled inside the callback are not supported as it might leave the HDF5 library in an inconsistent state. Similarly, using C++20 coroutines cannot be used as callbacks, since they do not support plain return statements. If a callback function yields execution to another C++20 coroutine calling HDF5 functions as well, this may lead to undefined behavior." +ALIASES += par_compr_note="\attention If you are planning to use compression with parallel HDF5, ensure that calls to H5Dwrite() occur in collective mode. In other words, all MPI ranks (in the relevant communicator) call H5Dwrite() and pass a dataset transfer property list with the MPI-IO collective option property set to #H5FD_MPIO_COLLECTIVE_IO.\n Note that data transformations are currently \Bold{not} supported when writing to datasets in parallel and with compression enabled." ALIASES += sa_metadata_ops="\sa \li H5Pget_all_coll_metadata_ops() \li H5Pget_coll_metadata_write() \li H5Pset_all_coll_metadata_ops() \li H5Pset_coll_metadata_write() \li \ref maybe_metadata_reads" ################################################################################ @@ -241,6 +248,95 @@ ALIASES += ref_vlen_strings="\Emph{Creating variable-length string datatypes}" ALIASES += ref_vol_doc="VOL documentation" ################################################################################ +# RFCs +################################################################################ + +ALIASES += ref_rfc20210528="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_multi_thread.pdf\">Multi-Thread HDF5</a>" +ALIASES += ref_rfc20190923="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/2019-09-23-RFC_VOL_feature_flags.pdf\">Virtual Object Layer (VOL) API Compatibility</a>" +ALIASES += ref_rfc20190410="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_VFD_Plugin.docx.pdf\">A Plugin Interface for HDF5 Virtual File Drivers</a>" +ALIASES += ref_rfc20181231="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_Min_Obj_Headers_181231.pdf\">Dataset Object Header Size</a>" +ALIASES += ref_rfc20181220="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/3.2.1_3.2.2_deliverable_181220_v4.pdf\">MS 3.2 – Addressing Scalability: Scalability of open, close, flush CASE STUDY: CGNS Hotspot analysis of CGNS cgp_open</a>" +ALIASES += ref_rfc20180620="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-Chunking%20Functions-2018-06-20-v3.docx.pdf\">Chunk query functionality in HDF5</a>" +ALIASES += ref_rfc20180610="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/VFD_SWMR_RFC_200916.pdf\">VFD SWMR</a>" +ALIASES += ref_rfc20180321="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-API_Contexts-2018-03-21.docx.pdf\">API Contexts</a>" +ALIASES += ref_rfc20180125="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/enhance_h5clear.docx.pdf\">Enhancement to the tool <tt>h5clear</tt></a>" +ALIASES += ref_rfc20170707="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/H5Sencode_format.docx.pdf\"><tt>H5Sencode/H5Sdecode</tt> Format Change</a>" +ALIASES += ref_rfc20160105="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-bounds.pdf\">Setting Bounds for Object Creation in HDF5 1.10.0</a>" +ALIASES += ref_rfc20150915="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/2015-09-28-RFC-HDF5-1.10.0-File-Format-Superblock-Changes-EP.docx.pdf\">File Format Changes in HDF5 1.10.0</a>" +ALIASES += ref_rfc20150709="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-Page_Buffering.pdf\">Page Buffering</a>" +ALIASES += ref_rfc20150615="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/cache_image_RFC_150929-QAK.docx.pdf\">Metadata Cache Image</a>" +ALIASES += ref_rfc20150429="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/new_datatypes.pdf\">New Datatypes</a>" +ALIASES += ref_rfc20150424="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-CollectiveMetadataWrites.pdf\">Collective Metadata Writes</a>" +ALIASES += ref_rfc20150423="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-CollectiveMetadataReads.pdf\">Enabling Collective Metadata Reads</a>" +ALIASES += ref_rfc20150301="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/sent_RFC_format_convert-v3.docx.pdf\">The Tool to Handle HDF5 File Format Compatibility for Chunked Datasets</a>" +ALIASES += ref_rfc20150212="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_H5LTget_hardlinkds.docx.pdf\"><tt>H5LTget_hardlinks</tt> – High-level API to list all the hard links to an object</a>" +ALIASES += ref_rfc20150205="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_F2003_v6.docx.pdf\">HDF5 Fortran Wrappers Maintenance: Dropping Support for Non-Fortran 2003 Standard Compliant Compilers</a>" +ALIASES += ref_rfc20150202="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC%20New%20Autotools%20Behavior.docx.pdf\">New Autotools Behavior</a>" +ALIASES += ref_rfc20141210="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/HDF5-VDS-requirements-use-cases-2014-12-10.pdf\">HDF5 Virtual Dataset</a>" +ALIASES += ref_rfc20141201="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC%20filter%20memory%20issues%20on%20Windows.docx.pdf\">Allocate/Free Mismatches in HDF5 Filter Code on Windows</a>" +ALIASES += ref_rfc20140916="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_VOL.pdf\">Virtual Object Layer</a>" +ALIASES += ref_rfc20140827="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/CompressNChunk_RFC.pdf\">Chunking and Compression Performance Tool Requirements</a>" +ALIASES += ref_rfc20140729="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/h5fis_accessible.pdf\">Replacing H5Fis_hdf5() with H5Fis_accessible()</a>" +ALIASES += ref_rfc20140722="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/64bit_hid_t-v1.docx.pdf\">Switching to a 64-bit <tt>hid_t</tt> Space in HDF5</a>" +ALIASES += ref_rfc20140717="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/analysis_ext.pdf\">Data Analysis Extensions</a>" +ALIASES += ref_rfc20140707="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/2014-08-28-RFC_VOL.pdf\">Virtual Object Layer</a>" +ALIASES += ref_rfc20140524="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-Why%20does%20not%20compression%20work-GH-EP.docx.pdf\">HDF5 Compression Demystified</a>" +ALIASES += ref_rfc20140318="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC%20H5free_memory%20v2.pdf\">Freeing Memory Allocated by the HDF5 Library</a>" +ALIASES += ref_rfc20140313="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-Compat-Tool-v2.docx.pdf\">Options to handle compatibility issues for HDF5 files</a>" +ALIASES += ref_rfc20140224="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/Design-MetadataCache-Logging-THG20140224-v4.pdf\">Design: Metadata Cache Logging</a>" +ALIASES += ref_rfc20131211="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC%20H5Ocork%20v5%20new%20fxn%20names.pdf\">Fine-Grained Control of Metadata Cache Flushes</a>" +ALIASES += ref_rfc20130930="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-Read-Attempts-for-Metadata-with-Checksum-v3.pdf\">Read Attempts for Metadata with Checksum</a>" +ALIASES += ref_rfc20130919="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/core%20CFD%20paging%20v5.docx.pdf\">Core VFD Backing Store Paged Writes</a>" +ALIASES += ref_rfc20130630="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/Design-HDF5-FlushDependencyTesting-20130630-v1.1.pdf\">Flush Dependency Testing</a>" +ALIASES += ref_rfc20130316="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/HDF5DynamicallyLoadedFilters.pdf\">HDF5 Dynamically Loaded Filters</a>" +ALIASES += ref_rfc20121114="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/DECTRIS%20Integration%20RFC%202012-11-29.pdf\">Direct Chunk Write</a>" +ALIASES += ref_rfc20121024="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/FileSpaceManagement.pdf\">HDF5 File Space Management</a>" +ALIASES += ref_rfc20120828="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/H5HPC_MultiDset_RW_IO_RFC_v4_20130320.docx.pdf\">New HDF5 API Routines for HPC Applications</a>" +ALIASES += ref_rfc20120523="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/paged_aggregation.pdf\">HDF5 File Space Management: Paged Aggregation</a>" +ALIASES += ref_rfc20120501="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/HDF5FileImageOperations.pdf\">HDF5 File Image Operations</a>" +ALIASES += ref_rfc20120305="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC%20PHDF5%20Consistency%20Semantics%20MC%20120328.docx.pdf\">Enabling a Strict Consistency Semantics Model in Parallel HDF5</a>" +ALIASES += ref_rfc20120220="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/h5repack_improve_hyperslab_over_chunked_dataset_v1.pdf\"><tt>h5repack</tt>: Improved Hyperslab selections for Large Chunked Datasets</a>" +ALIASES += ref_rfc20120120="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/2012-1-25-Maintainers-guide-for-datatype.docx.pdf\">A Maintainer’s Guide for the Datatype Module in HDF5 Library</a>" +ALIASES += ref_rfc20120104="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_actual_io_v4-1_done.docx.pdf\">Actual I/O Mode</a>" +ALIASES += ref_rfc20111119="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-H5Ocompare-review_v6.pdf\">New public functions to handle comparison</a>" +ALIASES += ref_rfc20110825="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/2011-08-31-RFC_H5Ocopy_Named_DT_v2.docx.pdf\">Merging Named Datatypes in H5Ocopy()</a>" +ALIASES += ref_rfc20110811="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_Enhancement_Hyperslab_Selection-1.4.docx.pdf\">Expanding the HDF5 Hyperslab Selection Interface</a>" +ALIASES += ref_rfc20110726="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/metadata_aggregation_RFC_v03.docx.pdf\">HDF5 File Space Allocation and Aggregation</a>" +ALIASES += ref_rfc20110614="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_h5dump_refactor_v3.docx.pdf\"> Refactor <tt>h5dump</tt> to Improve Maintenance</a>" +ALIASES += ref_rfc20110329="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_Tools_Extlink_Cache_v3_r2.docx.pdf\">Support External Link Open File Cache in HDF5 Tools</a>" +ALIASES += ref_rfc20110118="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC%20for%20h5diff%20Attribute%20Comparisons_v7.docx.pdf\"><tt>h5diff</tt> Attribute Comparisons</a>" +ALIASES += ref_rfc20101122="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_swmr_timeouts_v2.docx.pdf\">SWMR Timeouts</a>" +ALIASES += ref_rfc20101104="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/CacheExternalLinkFileOpens.pdf\">Caching Files Opened Through External Links</a>" +ALIASES += ref_rfc20101018="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/HDF5-comparisons_v3-RFC-2011-08-03.pdf\">HDF5 File and Object Comparison Specification</a>" +ALIASES += ref_rfc20100902="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/H5edit-RFC-Draft-v5.pdf\"><tt>h5edit</tt> – An HDF5 File Editing Tool</a>" +ALIASES += ref_rfc20100727="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_HDF5_reservedCharacters-v2.pdf\">Reserved Characters for HDF5 Applications</a>" +ALIASES += ref_rfc20100726="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/H5HPC_RFC-2010-09-28.pdf\">High-Level HDF5 API routines for HPC Applications</a>" +ALIASES += ref_rfc20100511="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_h5diff_exclude_obj_v1_3.pdf\"><tt>h5diff</tt> – Exclude Object(s) from Comparison</a>" +ALIASES += ref_rfc20100422="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_gen_attribute_tool_v2_f.pdf\">Generating attributes into an object with a tool</a>" +ALIASES += ref_rfc20100312="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_Support_HDF518_in_Tools.pdf\">Supporting HDF5 1.8 in HDF5 Command Line Tools</a>" +ALIASES += ref_rfc20091218="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RCF_h5diff_link_v1.2.docx.pdf\">Supporting soft-link and external-link for <tt>h5diff</tt></a>" +ALIASES += ref_rfc20090907="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_Tools_Lib_v2.pdf\">HDF5 Tools Library Functions</a>" +ALIASES += ref_rfc20090612="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_h5diff_default_epsilon.pdf\">Default EPSILON values for comparing floating point data</a>" +ALIASES += ref_rfc20081218="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_h5diff_NonComparable.pdf\">Reporting of Non-Comparable Datasets by <tt>h5diff</tt></a>" +ALIASES += ref_rfc20080915="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/FileFreeSpacePerformance.pdf\">Performance Report for Free-space Manager</a>" +ALIASES += ref_rfc20080904="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/ExternalLinkFileAccessProperty.pdf\">Setting File Access Property List for accessing External Link</a>" +ALIASES += ref_rfc20080301="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/DynamicTransformations_RFC.pdf\">Dynamic Transformations to HDF5 Data</a>" +ALIASES += ref_rfc20080209="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-Using-SVN-branching-Feb9.pdf\">Using SVN branching to improve software development process at THG</a>" +ALIASES += ref_rfc20080206="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-HIS-REL-1.8_Feb6.pdf\">Maintaining the <tt>HISTORY.txt</tt> and <tt>RELEASE.txt</tt> files in HDF5</a>" +ALIASES += ref_rfc20071111="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/AURA-corruption-2007-11-12.pdf\">Addressing HDF5 file corruption issue</a>" +ALIASES += ref_rfc20071018="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_NaNsHDF5.pdf\"><tt>NaN</tt> detection in HDF5</a>" +ALIASES += ref_rfc20070801="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/Metadata_Journaling_RFC.pdf\">Metadata Journaling to Improve Crash Survivability</a>" +ALIASES += ref_rfc20070413="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/API_Compatibility_RFC.txt.pdf\">API Compatibility Strategies for HDF5</a>" +ALIASES += ref_rfc20070115="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/PrivateHeap.pdf\">A 'Private' Heap for HDF5</a>" +ALIASES += ref_rfc20060623="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/coll_ind_dd6.pdf\">Performance Comparison of Collective I/O and Independent I/O with Derived Datatypes</a>" +ALIASES += ref_rfc20060604="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/h5stat_spec_v3_2006-06-04.pdf\"><tt>h5stat</tt> tool</a>" +ALIASES += ref_rfc20060505="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/Simple%20Performance%20Test%20on%20Fletcher32%20Filter.pdf\">Simple Performance Test on Fletcher32 Filter</a>" +ALIASES += ref_rfc20060410="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/h5chk_Requirements.pdf\">Requirement Specifications of an HDF5 File Format Validation Tool</a>" +ALIASES += ref_rfc20060317="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/sec2driver-RFC.pdf\">Proposed changes to the <tt>sec2</tt> driver </a>" +ALIASES += ref_rfc20060124="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/FITS%20to%20HDF5%20mapping.pdf\">Mapping FITS data to HDF5</a>" +ALIASES += ref_rfc20040811="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/text-dtype.htm.pdf\">Conversion Between Text and Datatype</a>" + +################################################################################ # The Usual Suspects ################################################################################ diff --git a/doxygen/dox/APIVersions.dox b/doxygen/dox/APIVersions.dox new file mode 100644 index 0000000..3658f06 --- /dev/null +++ b/doxygen/dox/APIVersions.dox @@ -0,0 +1,173 @@ +/** + * \ingroup H5A + * \def H5Acreate + * \api_vers_2{H5Acreate,H5Acreate1,H5Acreate2} + */ + +/** + * \ingroup H5A + * \def H5Aiterate + * \api_vers_2{H5Aiterate,H5Aiterate1,H5Aiterate2} + */ + +/** + * \ingroup H5D + * \def H5Dcreate + * \api_vers_2{H5Dcreate,H5Dcreate1,H5Dcreate2} + */ + +/** + * \ingroup H5E + * \def H5Eget_auto + * \api_vers_2{H5Eget_auto,H5Eget_auto1,H5Eget_auto2} + */ + +/** + * \ingroup H5E + * \def H5Eprint + * \api_vers_2{H5Eprint,H5Eprint1,H5Eprint2} + */ + +/** + * \ingroup H5E + * \def H5Epush + * \api_vers_2{H5Epush,H5Epush1,H5Epush2} + */ + +/** + * \ingroup H5E + * \def H5Eset_auto + * \api_vers_2{H5Eset_auto,H5Eset_auto1,H5Eset_auto2} + */ + +/** + * \ingroup H5E + * \def H5Ewalk + * \api_vers_2{H5Ewalk,H5Ewalk1,H5Ewalk2} + */ + +/** + * \ingroup H5F + * \def H5Fget_info + * \api_vers_2{H5Fget_info,H5Fget_info1,H5Fget_info2} + */ + +/** + * \ingroup H5G + * \def H5Gcreate + * \api_vers_2{H5Gcreate,H5Gcreate1,H5Gcreate2} + */ + +/** + * \ingroup H5G + * \def H5Gopen + * \api_vers_2{H5Gopen,H5Gopen1,H5Gopen2} + */ + +/** + * \ingroup H5L + * \def H5Lget_info + * \api_vers_2{H5Lget_info,H5Lget_info1,H5Lget_info2} + */ + +/** + * \ingroup H5L + * \def H5Lget_info_by_idx + * \api_vers_2{H5Lget_info_by_idx,H5Lget_info_by_idx1,H5Lget_info_by_idx2} + */ + +/** + * \ingroup TRAV + * \def H5Literate + * \api_vers_2{H5Literate,H5Literate1,H5Literate2} + */ + +/** + * \ingroup TRAV + * \def H5Literate_by_name + * \api_vers_2{H5Literate_by_name,H5Literate_by_name1,H5Literate_by_name2} + */ + +/** + * \ingroup TRAV + * \def H5Lvisit + * \api_vers_2{H5Lvisit,H5Lvisit1,H5Lvisit2} + */ + +/** + * \ingroup TRAV + * \def H5Lvisit_by_name + * \api_vers_2{H5Lvisit_by_name,H5Lvisit_by_name1,H5Lvisit_by_name2} + */ + +/** + * \ingroup H5O + * \def H5Oget_info + * \api_vers_3{H5Oget_info,H5Oget_info1,H5Oget_info2,H5Oget_info3} + */ + +/** + * \ingroup H5O + * \def H5Oget_info_by_idx + * \api_vers_3{H5Oget_info_by_idx,H5Oget_info_by_idx1,H5Oget_info_by_idx2,H5Oget_info_by_idx3} + */ + +/** + * \ingroup H5O + * \def H5Oget_info_by_name + * \api_vers_3{H5Oget_info_by_name,H5Oget_info_by_name1,H5Oget_info_by_name2,H5Oget_info_by_name3} + */ + +/** + * \ingroup H5O + * \def H5Ovisit + * \api_vers_3{H5Ovisit,H5Ovisit1,H5Ovisit2,H5Ovisit3} + */ + +/** + * \ingroup H5O + * \def H5Ovisit_by_name + * \api_vers_3{H5Ovisit_by_name,H5Ovisit_by_name1,H5Ovisit_by_name2,H5Ovisit_by_name3} + */ + +/** + * \ingroup H5R + * \def H5Rdereference + * \api_vers_2{H5Rdereference,H5Rdereference1,H5Rdereference2} + */ + +/** + * \ingroup H5R + * \def H5Rget_obj_type + * \api_vers_3{H5Rget_obj_type,H5Rget_obj_type1,H5Rget_obj_type2,H5R_get_obj_type3} + */ + +/** + * \ingroup H5S + * \def H5Sencode + * \api_vers_2{H5Sencode,H5Sencode1,H5Sencode2} + */ + +/** + * \ingroup H5T + * \def H5Tcommit + * \api_vers_2{H5Tcommit,H5Tcommit1,H5Tcommit2} + */ + +/** + * \ingroup H5T + * \def H5Topen + * \api_vers_2{H5Topen,H5Topen1,H5Topen2} + */ + +/** + * \ingroup ARRAY + * \def H5Tarray_create + * \api_vers_2{H5Tarray_create,H5Tarray_create1,H5Tarray_create2} + */ + +/** + * \ingroup ARRAY + * \def H5Tget_array_dims + * \api_vers_2{H5Tget_array_dims,H5Tget_array_dims1,H5Tget_array_dims2} + */ diff --git a/doxygen/dox/About.dox b/doxygen/dox/About.dox index 3be9202..d315566 100644 --- a/doxygen/dox/About.dox +++ b/doxygen/dox/About.dox @@ -1,5 +1,7 @@ /** \page About About +\section about_history History + The implementation of this documentation set is based on the fantastic work of the <a href="https://eigen.tuxfamily.org/index.php?title=Main_Page">Eigen project</a>. Please refer to their <a href="https://gitlab.com/libeigen/eigen">GitLab repository</a> @@ -8,4 +10,14 @@ and the online version of their Not only does Eigen set a standard as a piece of software, but also as an example of <em>documentation done right</em>. -*/ \ No newline at end of file +\section about_documentation Documentation about Documentation + +\li \todo Describe how to add a reference or a new RFC +\li \todo Describe how to add an example +\li \todo Describe how to include plain HTML +\li \todo Describe how to add an API macro +\li \todo Describe the custom commands +\li \todo Describe the S3 bucket layout and update routine +\li \todo Link the RM template + +*/ diff --git a/doxygen/dox/Cookbook.dox b/doxygen/dox/Cookbook.dox index 4abc896..666cfa1 100644 --- a/doxygen/dox/Cookbook.dox +++ b/doxygen/dox/Cookbook.dox @@ -2,4 +2,18 @@ Healthy, everyday recipes for every taste and budget... - */ \ No newline at end of file +\ref Files +\li \ref CB_FreeSpace +\li \ref CB_RemoveUnusedSpace +\li \ref CB_UserBlock + +\ref Attributes +\li \ref CB_LargeAttributes + +\ref Accessibility +\li \ref CB_MaintainCompat + +\ref Performance +\li \ref CB_MDCPerf + + */ diff --git a/doxygen/dox/H5Acreate.dox b/doxygen/dox/H5Acreate.dox deleted file mode 100644 index 18d648f..0000000 --- a/doxygen/dox/H5Acreate.dox +++ /dev/null @@ -1,9 +0,0 @@ -/** - * \ingroup H5A - * \def H5Acreate() - * H5Acreate() is a macro that is mapped to either H5Acreate1() or - * H5Acreate2(). - * - * - * \todo Standardize the way we describe these macros! - */ diff --git a/doxygen/dox/H5Aiterate.dox b/doxygen/dox/H5Aiterate.dox deleted file mode 100644 index 46b9bb4..0000000 --- a/doxygen/dox/H5Aiterate.dox +++ /dev/null @@ -1,9 +0,0 @@ -/** - * \ingroup H5A - * \def H5Aiterate() - * H5Aiterate() is a macro that is mapped to either H5Aiterate1() or - * H5Aiterate2(). - * - * - * \todo Standardize the way we describe these macros! - */ diff --git a/doxygen/dox/H5Fget_info.dox b/doxygen/dox/H5Fget_info.dox deleted file mode 100644 index 9b02752..0000000 --- a/doxygen/dox/H5Fget_info.dox +++ /dev/null @@ -1,44 +0,0 @@ -/** - * \ingroup H5F - * \def H5Fget_info() - * H5Fget_info() is a macro that is mapped to either H5Fget_info1() - * or H5Fget_info2(), depending on the needs of the application. - * Similarly, the macro for the \ref H5F_info_t struct is mapped to either - * H5F_info1_t or H5F_info2_t. - * - * Such macros are provided to facilitate application compatibility. - * Their use and mappings are fully described in \ref api-compat-macros. - * - * When both the HDF5 library and the application are built and installed with - * no specific compatibility flags, H5Fget_info() is mapped to the most recent - * version of the function, currently H5Fget_info2(). If the library and/or - * application is compiled for Release 1.8 emulation, H5Fget_info() will be - * mapped to H5Fget_info1(). Since there was no H5Fget_info() function in - * Release 1.6, if the library and/or application is compiled for Release 1.6 - * emulation, H5Fget_info() will be mapped to the most recent version of the - * function, currently H5Fget_info2(). Function-specific flags are available to - * override these settings on a function-by-function basis when the application - * is compiled. - * - * Specific compile-time compatibility flags and the resulting - * mappings are as follows: - * - * \Bold{Global settings}\n - * \li No compatibility flag: H5Fget_info2() and H5F_info2_t - * \li Enable deprecated symbols: H5Fget_info2() and H5F_info2_t - * \li Disable deprecated symbols: H5Fget_info2() and H5F_info2_t - * \li Emulate Release 1.6 interface: H5Fget_info2() and H5F_info2_t - * \li Emulate Release 1.8 interface: H5Fget_info1() and H5F_info1_t - * - * \Bold{Function- and struct-level macros}\n - * \li \Code{H5Fget_info_vers=2}: H5Fget_info2() - * \li \Code{H5Fget_info_vers=1}: H5Fget_info1() - * \li \Code{H5F_info_t_vers=2}: H5F_info2_t - * \li \Code{H5F_info_t_vers=1}: H5F_info1_t - * - * \version 1.10.0 The C function H5Fget_info() and H5F_info_t renamed to - * H5Fget_info1() and H5F_info1_t, respectively, and deprecated - * in this release. The C macro #H5Fget_info, the C function - * H5Fget_info2(), and the struct H5F_info2_t introduced in this - * release. - */ diff --git a/doxygen/dox/H5Lget_info.dox b/doxygen/dox/H5Lget_info.dox deleted file mode 100644 index 2c0971e..0000000 --- a/doxygen/dox/H5Lget_info.dox +++ /dev/null @@ -1,17 +0,0 @@ - /** - * \ingroup LMGT - * \def H5Lget_info() - * H5Lget_info() is a macro that is mapped to either H5Lget_info1() - * or H5Lget_info2() Such macros are provided to facilitate application - * compatibility. Their use and mappings are fully described in \ref api-compat-macros. - * If the library and/or application is compiled for Release - * 1.12 emulation, H5Lget_info() will be mapped to H5Lget_info2() and - * H5Lget_info1() is deprecated. With earlier versions, H5Lget_info() is mapped to - * H5Lget_info1(). Specific compile-time compatibility flags and the resulting - * mappings are as follows: - * \li No compatibility flag: H5Lget_info2() (using 1.12 source) H5Lget_info1() - * (using 1.10 or 1.8 source) - * \li Emulate Release 1.12: H5Lget_info2() - * \li Emulate Release 1.8 or 1.10 interface: H5Lget_info1() - * - */ diff --git a/doxygen/dox/H5Lget_info_by_idx.dox b/doxygen/dox/H5Lget_info_by_idx.dox deleted file mode 100644 index bf76822..0000000 --- a/doxygen/dox/H5Lget_info_by_idx.dox +++ /dev/null @@ -1,17 +0,0 @@ - /** - * \ingroup LMGT - * \def H5Lget_info_by_idx() - * H5Lget_info_by_idx() is a macro that is mapped to either H5Lget_info_by_idx1() - * or H5Lget_info_by_idx2() Such macros are provided to facilitate application - * compatibility. Their use and mappings are fully described in \ref api-compat-macros. - * If the library and/or application is compiled for Release - * 1.12 emulation, H5Lget_info_by_idx() will be mapped to H5Lget_info_by_idx2() and - * H5Lget_info_by_idx1() is deprecated. With earlier versions, H5Lget_infoby_idx() is mapped to - * H5Lget_info_by_idx1(). Specific compile-time compatibility flags and the resulting - * mappings are as follows: - * \li No compatibility flag: H5Lget_info_by_idx2() (using 1.12 source) H5Lget_info_by_idx1() - * (using 1.10 or 1.8 source) - * \li Emulate Release 1.12: H5Lget_info_by_idx2() - * \li Emulate Release 1.8 or 1.10 interface: H5Lget_info_by_idx1() - * - */ diff --git a/doxygen/dox/H5Literate.dox b/doxygen/dox/H5Literate.dox deleted file mode 100644 index eaaf2fe..0000000 --- a/doxygen/dox/H5Literate.dox +++ /dev/null @@ -1,20 +0,0 @@ -/** - * \ingroup TRAV - * \def H5Literate() - * H5Literate() is a macro that is mapped to either H5Literate1() or - * H5Literate2() Such macros are provided to facilitate application - * compatibility. Their use and mappings are fully described in - * \ref api-compat-macros. If the library and/or application is - * compiled for Release 1.12 emulation, H5Literate() will be mapped to - * H5Literate2() and H5Literate1() is deprecated. With earlier versions, - * H5Literate() is mapped to H5Literate1(). Specific compile-time compatibility - * flags and the resulting mappings are as follows: - * \li No compatibility flag: H5Literate2() (using 1.12 source) H5Literate1() - * (using 1.10 or 1.8 source) - * \li Emulate Release 1.12: H5Literate2() - * \li Emulate Release 1.8 or 1.10 interface: H5Literate1() - * - * \version 1.12.0 The function H5Literate() was renamed to H5Literate1() and - * deprecated in this release. The macro H5Literate() and the - * function H5Literate2() were introduced in this release. - */ diff --git a/doxygen/dox/H5Literate_by_name.dox b/doxygen/dox/H5Literate_by_name.dox deleted file mode 100644 index 5ffd7c6..0000000 --- a/doxygen/dox/H5Literate_by_name.dox +++ /dev/null @@ -1,21 +0,0 @@ -/** - * \ingroup TRAV - * \def H5Literate_by_name() - * H5Literate_by_name() is a macro that is mapped to either - * H5Literate_by_name1() or H5Literate_by_name2() Such macros are provided to - * facilitate application compatibility. Their use and mappings are fully - * described in \ref api-compat-macros. If the library and/or application is - * compiled for Release 1.12 emulation, H5Literate_by_name() will be mapped to - * H5Literate_by_name2() and H5Literate_by_name1() is deprecated. With earlier - * versions, H5Literate_by_name() is mapped to H5Literate_by_name1(). - * Specific compile-time compatibility flags and the resulting mappings are as - * follows: - * \li No compatibility flag: H5Literate_by_name2() (using 1.12 source) - * H5Literate_by_name1() (using 1.10 or 1.8 source) - * \li Emulate Release 1.12: H5Literate_by_name2() - * \li Emulate Release 1.8 or 1.10 interface: H5Literate_by_name1() - * - * \version 1.12.0 The function H5Literate_by_name() was renamed to H5Literate_by_name1() and - * deprecated in this release. The macro H5Literate_by_name() and the - * function H5Literate_by_name2() were introduced in this release. - */ diff --git a/doxygen/dox/H5Lvisit.dox b/doxygen/dox/H5Lvisit.dox deleted file mode 100644 index 2dc547f..0000000 --- a/doxygen/dox/H5Lvisit.dox +++ /dev/null @@ -1,20 +0,0 @@ -/** - * \ingroup TRAV - * \def H5Lvisit() - * H5Lvisit() is a macro that is mapped to either H5Lvisit1() or - * H5Lvisit2() Such macros are provided to facilitate application - * compatibility. Their use and mappings are fully described in - * \ref api-compat-macros. If the library and/or application is - * compiled for Release 1.12 emulation, H5Lvisit() will be mapped to - * H5Lvisit2() and H5Lvisit1() is deprecated. With earlier versions, - * H5Lvisit() is mapped to H5Lvisit1(). Specific compile-time compatibility - * flags and the resulting mappings are as follows: - * \li No compatibility flag: H5Lvisit2() (using 1.12 source) H5Lvisit1() - * (using 1.10 or 1.8 source) - * \li Emulate Release 1.12: H5Lvisit2() - * \li Emulate Release 1.8 or 1.10 interface: H5Lvisit1() - * - * \version 1.12.0 The function H5Lvisit() was renamed to H5Lvisit1() and - * deprecated in this release. The macro H5Lvisit() and the - * function H5Lvisit2() were introduced in this release. - */ diff --git a/doxygen/dox/H5Lvisit_by_name.dox b/doxygen/dox/H5Lvisit_by_name.dox deleted file mode 100644 index 691787f..0000000 --- a/doxygen/dox/H5Lvisit_by_name.dox +++ /dev/null @@ -1,20 +0,0 @@ -/** - * \ingroup TRAV - * \def H5Lvisit_by_name() - * H5Lvisit_by_name() is a macro that is mapped to either H5Lvisit_by_name1() or - * H5Lvisit_by_name2() Such macros are provided to facilitate application - * compatibility. Their use and mappings are fully described in - * \ref api-compat-macros. If the library and/or application is - * compiled for Release 1.12 emulation, H5Lvisit_by_name() will be mapped to - * H5Lvisit_by_name2() and H5Lvisit_by_name1() is deprecated. With earlier versions, - * H5Lvisit_by_name() is mapped to H5Lvisit_by_name1(). Specific compile-time - * compatibility flags and the resulting mappings are as follows: - * \li No compatibility flag: H5Lvisit_by_name2() (using 1.12 source) H5Lvisit_by_name1() - * (using 1.10 or 1.8 source) - * \li Emulate Release 1.12: H5Lvisit_by_name2() - * \li Emulate Release 1.8 or 1.10 interface: H5Lvisit_by_name1() - * - * \version 1.12.0 The function H5Lvisit_by_name() was renamed to H5Lvisit_by_name1() and - * deprecated in this release. The macro H5Lvisit_by_name() and the - * function H5Lvisit_by_name2() were introduced in this release. - */ diff --git a/doxygen/dox/H5Oget_info.dox b/doxygen/dox/H5Oget_info.dox deleted file mode 100644 index ee4cd1c..0000000 --- a/doxygen/dox/H5Oget_info.dox +++ /dev/null @@ -1,72 +0,0 @@ -/** - * \ingroup H5O - * \def H5Oget_info - * - * #H5Oget_info is a macro that is mapped to: - * \li #H5Oget_info3 - * \li #H5Oget_info1 - * - * \details Such macros are provided to facilitate application - * compatibility. Their use and mappings are fully described in - * API Compatibility Macros in HDF5; we urge you to read that - * document closely. - * - * In HDF5 versions 1.12 and after, #H5Oget_info is mapped to - * #H5Oget_info3 and #H5Oget_info1 is deprecated. - * In version 1.10 #H5Oget_info is identical to #H5Oget_info1. - * - * Specific compile-time compatibility flags and the resulting - * mappings are as follows: - * \par - * <table> - * <tr> - * <th>Compatibility setting</th> - * <th>H5Oget_info</th> - * </tr> - * <tr> - * <td>No compatibility flag \n  </td> - * <td>#H5Oget_info3 (in release 1.12) \n - * #H5Oget_info1 (in 1.8 or 1.10)</td> - * </tr> - * <tr> - * <td>Emulate Release 1.12</td> - * <td>#H5Oget_info3</td> - * </tr> - * <tr> - * <td>Emulate Release 1.10/1.8 interface</td> - * <td>#H5Oget_info1</td> - * </tr> - * </table> - * - * \note If you are iterating through a lot of different objects to - * retrieve information via the #H5Oget_info family of routines, - * you may see memory building up. This can be due to memory - * allocation for metadata such as object headers and messages - * when the iterated objects are put into the metadata cache. - * \note - * If the memory buildup is not desirable, you can configure a - * smaller cache via #H5Fset_mdc_config or set the file access - * property list via #H5Pset_mdc_config. A smaller sized cache - * will force metadata entries to be evicted from the cache, - * thus freeing the memory associated with the entries. - * - * \version 1.12.0 The macro #H5Oget_info and the function #H5Oget_info3 - * were added, and #H5Oget_info1 was deprecated. - * \version 1.10.5 The macro #H5Oget_info was removed. The functions - * #H5Oget_info1 and #H5Oget_info are identical - * in this release. This change was added to restore the - * broken API compatibility introduced in HDF5-1.10.3. - * \version 1.10.3 The function #H5Oget_info was renamed - * #H5Oget_info1. The macro #H5Oget_info and the function - * #H5Oget_info2 were introduced in this release. - * \version 1.8.15 Added a note about the valid values for the \c version field - * in the H5O_hdr_info_t structure. - * \version 1.8.11 Fortran subroutine introduced in this release. - * \version 1.8.10 Added #H5O_type_t structure to the Description section. - * Separated H5O_hdr_info_t structure from - * #H5O_info_t in the Description section. Clarified the - * definition and implementation of the time fields. - * - * \since 1.8.0 - * - */ diff --git a/doxygen/dox/H5Oget_info_by_idx.dox b/doxygen/dox/H5Oget_info_by_idx.dox deleted file mode 100644 index 49b8031..0000000 --- a/doxygen/dox/H5Oget_info_by_idx.dox +++ /dev/null @@ -1,55 +0,0 @@ -/** - * \ingroup H5O - * \def H5Oget_info_by_idx - * - * #H5Oget_info_by_idx is a macro that is mapped to: - * \li #H5Oget_info_by_idx3 - * \li #H5Oget_info_by_idx1 - * - * \details Such macros are provided to facilitate application - * compatibility. Their use and mappings are fully described in - * API Compatibility Macros in HDF5; we urge you to read that - * document closely. - * - * In HDF5 versions 1.12 and after, #H5Oget_info_by_idx is mapped to - * #H5Oget_info_by_idx3 and #H5Oget_info_by_idx1 is deprecated. - * In version 1.10 #H5Oget_info_by_idx is identical to #H5Oget_info_by_idx1. - * - * Specific compile-time compatibility flags and the resulting - * mappings are as follows: - * - * \par - * <table> - * <tr> - * <th>Compatibility setting</th> - * <th>H5Oget_info_by_idx</th> - * </tr> - * <tr> - * <td>No compatibility flag \n  </td> - * <td>#H5Oget_info_by_idx3 for 1.12 \n - * #H5Oget_info_by_idx1 for 1.8/1.10</td> - * </tr> - * <tr> - * <td>Emulate Release 1.12</td> - * <td>#H5Oget_info_by_idx3</td> - * </tr> - * <tr> - * <td>Emulate Release 1.10/1.8 interface</td> - * <td>#H5Oget_info_by_idx1</td> - * </tr> - * </table> - * - * \version 1.12.0 The macro #H5Oget_info_by_idx and function #H5Oget_info_by_idx3 were added, - * and #H5Oget_info_by_idx1 was deprecated. - * \version 1.10.5 The macro #H5Oget_info_by_idx was removed. The functions - * #H5Oget_info_by_idx and #H5Oget_info_by_idx1 are - * identical in this release. This change was added to restore the - * broken API compatibility introduced in HDF5-1.10.3. - * \version 1.10.3 The function #H5Oget_info_by_idx was renamed #H5Oget_info_by_idx1. - * The macro #H5Oget_info_by_idx and the function #H5Oget_info_by_idx2 - * were introduced in this release. - * \version 1.8.11 Fortran subroutine introduced in this release. - * - * \since 1.8.0 - * - */ diff --git a/doxygen/dox/H5Oget_info_by_name.dox b/doxygen/dox/H5Oget_info_by_name.dox deleted file mode 100644 index 18f7d28..0000000 --- a/doxygen/dox/H5Oget_info_by_name.dox +++ /dev/null @@ -1,58 +0,0 @@ -/** - * \ingroup H5O - * \def H5Oget_info_by_name - * - * #H5Oget_info_by_name is a macro that is mapped to: - * \li #H5Oget_info_by_name3 - * \li #H5Oget_info_by_name1 - * - * \details Such macros are provided to facilitate application - * compatibility. Their use and mappings are fully described in - * API Compatibility Macros in HDF5; we urge you to read that - * document closely. - * - * In HDF5 versions 1.12 and after, #H5Oget_info_by_name is mapped to - * #H5Oget_info_by_name3. In version 1.10 #H5Oget_info_by_name is - * identical to #H5Oget_info_by_name1. - * - * Specific compile-time compatibility flags and the resulting - * mappings are as follows: - * - * \par - * <table> - * <tr> - * <th>Compatibility setting</th> - * <th>H5Oget_info_by_name</th> - * </tr> - * <tr> - * <td>No compatibility flag \n  </td> - * <td>#H5Oget_info_by_name3 for 1.12 and above \n - * #H5Oget_info_by_name1 for 1.8 or 1.10</td> - * </tr> - * <tr> - * <td>Emulate Release 1.12</td> - * <td>#H5Oget_info_by_name3</td> - * </tr> - * <tr> - * <td>Emulate Release 1.10 or 1.8 interface</td> - * <td>#H5Oget_info_by_name1</td> - * </tr> - * </table> - * - * \version 1.12.0 The macro #H5Oget_info_by_name and function - * #H5Oget_info_by_name3 were added and - * #H5Oget_info_by_name1 was deprecated. - * \version 1.10.5 The macro #H5Oget_info_by_name was removed. The functions - * #H5Oget_info_by_name and #H5Oget_info_by_name1 are - * identical in this release. This change was added to restore - * the broken API compatibility introduced in HDF5-1.10.3. - * \version 1.10.3 The function #H5Oget_info_by_name was renamed - * to #H5Oget_info_by_name1. The macro #H5Oget_info_by_name - * and the function #H5Oget_info_by_name2 were introduced - * in this release. - * \version 1.8.8 Fortran 2003 subroutine and \c h5o_info_t derived - * type introduced in this release.</td> - * - * \since 1.8.0 - * - */ diff --git a/doxygen/dox/H5Ovisit.dox b/doxygen/dox/H5Ovisit.dox deleted file mode 100644 index 1e2a3ea..0000000 --- a/doxygen/dox/H5Ovisit.dox +++ /dev/null @@ -1,55 +0,0 @@ -/** - * \ingroup H5O - * \def H5Ovisit - * - * #H5Ovisit is a macro that is mapped to one of the following: - * \li #H5Ovisit3 - * \li #H5Ovisit1 - * - * \details Such macros are provided to facilitate application - * compatibility. Their use and mappings are fully described in - * API Compatibility Macros in HDF5; we urge you to read that - * document closely. - * - * In HDF5 versions 1.12 and after, #H5Ovisit is mapped to - * #H5Ovisit3. In version 1.10, #H5Ovisit is identical - * to #H5Ovisit1. - * - * Specific compile-time compatibility flags and the resulting - * mappings are as follows: - * - * \par - * <table> - * <tr> - * <th>Compatibility settings</th> - * <th>H5Ovisit</th> - * </tr> - * <tr> - * <td>No compatibility flag \n  </td> - * <td>#H5Ovisit3 in 1.12 or after \n - * #H5Ovisit1 for 1.8 and 1.10</td> - * </tr> - * <tr> - * <td>Emulate Release 1.12</td> - * <td>#H5Ovisit3</td> - * </tr> - * <tr> - * <td>Emulate Release 1.10 or 1.8 interface</td> - * <td>#H5Ovisit1</td> - * </tr> - * </table> - * - * \version 1.12.0 The macro #H5Ovisit and function #H5Ovisit3 were added, - * and #H5Ovisit1 was deprecated. - * \version 1.10.5 The macro #H5Ovisit was removed. The functions - * #H5Ovisit and #H5Ovisit1 are identical in this release. - * This change was added to restore the broken API compatibility - * introduced in HDF5-1.10.3. - * \version 1.10.3 The function #H5Ovisit was renamed to #H5Ovisit1. - * The macro #H5Ovisit and the function #H5Ovisit2 were - * introduced in this release. - * \version 1.8.8 Fortran subroutine and data structure added. - * - * \since 1.8.0 - * - */ diff --git a/doxygen/dox/H5Ovisit_by_name.dox b/doxygen/dox/H5Ovisit_by_name.dox deleted file mode 100644 index 2ba4846..0000000 --- a/doxygen/dox/H5Ovisit_by_name.dox +++ /dev/null @@ -1,54 +0,0 @@ -/** - * \ingroup H5O - * \def H5Ovisit_by_name - * - * #H5Ovisit_by_name is a macro that is mapped to one of the following: - * \li #H5Ovisit_by_name3 - * \li #H5Ovisit_by_name1 - * - * \details Such macros are provided to facilitate application - * compatibility. Their use and mappings are fully described in - * API Compatibility Macros in HDF5; we urge you to read that - * document closely. - * - * In HDF5 versions 1.12 and after, #H5Ovisit_by_name is mapped to - * #H5Ovisit_by_name3. In version 1.10, #H5Ovisit_by_name - * is identical to #H5Ovisit_by_name1. - * - * Specific compile-time compatibility flags and the resulting - * mappings are as follows: - * - * \par - * <table> - * <tr> - * <th>Compatibility settings</th> - * <th>H5Ovisit_by_name</th> - * </tr> - * <tr> - * <td>No compatibility flag \n  </td> - * <td>#H5Ovisit_by_name3 for 1.12 and above \n - * #H5Ovisit_by_name1 for 1.10 or 1.8</td> - * </tr> - * <tr> - * <td>Emulate Release 1.12 interface</td> - * <td>#H5Ovisit_by_name3</td> - * </tr> - * <tr> - * <td>Emulate Release 1.10 or 1.8 interface</td> - * <td>#H5Ovisit_by_name1</td> - * </tr> - * </table> - * - * \version 1.12.0 The macro #H5Ovisit_by_name and function #H5Ovisit_by_name3 were added. - * \version 1.10.5 The macro #H5Ovisit_by_name was removed. The functions - * #H5Ovisit_by_name and #H5Ovisit_by_name1 are identical - * in this release. This change was added to restore the - * broken API compatibility introduced in HDF5-1.10.3. - * \version 1.10.3 The function #H5Ovisit_by_name was renamed to #H5Ovisit_by_name1. - * The macro #H5Ovisit_by_name and the function #H5Ovisit_by_name2 - * were introduced in this release. - * \version 1.8.8 Fortran subroutine introduced in this release. - * - * \since 1.8.0 - * - */ diff --git a/doxygen/dox/H5Sencode.dox b/doxygen/dox/H5Sencode.dox deleted file mode 100644 index fe0995c..0000000 --- a/doxygen/dox/H5Sencode.dox +++ /dev/null @@ -1,5 +0,0 @@ -/** - * \ingroup H5S - * \def H5Sencode() - * H5Sencode() is a macro that is mapped to either H5Sencode1() or H5Sencode2(). -*/ diff --git a/doxygen/dox/MetadataCachingInHDF5.dox b/doxygen/dox/MetadataCachingInHDF5.dox index 9ba0fab..9b8e446 100644 --- a/doxygen/dox/MetadataCachingInHDF5.dox +++ b/doxygen/dox/MetadataCachingInHDF5.dox @@ -668,7 +668,7 @@ reduction. With the hit rate threshold cache size decrement algorithm, the remaining fields in the section are ignored. -\subsubsection acsr Ageout Cache Size Reduction +\subsubsection dacsr Ageout Cache Size Reduction If \ref H5AC_cache_config_t.decr_mode "decr_mode" is #H5C_decr__age_out the cache size is decreased by the ageout algorithm, and the remaining fields of the @@ -692,7 +692,7 @@ The \ref H5AC_cache_config_t.decrement "decrement" and \ref H5AC_cache_config_t.upper_hr_threshold "upper_hr_threshold" fields are ignored in this case. -\subsubsection awhrtcsr Ageout With Hit Rate Threshold Cache Size Reduction +\subsubsection dawhrtcsr Ageout With Hit Rate Threshold Cache Size Reduction If \ref H5AC_cache_config_t.decr_mode "decr_mode" is #H5C_decr__age_out_with_threshold, the cache size is decreased by the ageout @@ -1017,4 +1017,4 @@ and the average successful and unsuccessful search depths in the hash table. If these latter figures are significantly above 1, you should increase the size of the hash table. - */ \ No newline at end of file + */ diff --git a/doxygen/dox/RFC.dox b/doxygen/dox/RFC.dox new file mode 100644 index 0000000..c16dcea --- /dev/null +++ b/doxygen/dox/RFC.dox @@ -0,0 +1,91 @@ +/** \page RFC RFCs + +<table> +<tr><th>RFC ID</th><th>Title</th><th>Comments</th></tr> +<tr> <td>2021-05-28</td> <td>\ref_rfc20210528</td> <td></td></tr> +<tr> <td>2019-09-23</td> <td>\ref_rfc20190923</td> <td></td></tr> +<tr> <td>2019-04-10</td> <td>\ref_rfc20190410</td> <td></td> </tr> +<tr> <td>2018-12-31</td> <td>\ref_rfc20181231</td> <td></td> </tr> +<tr> <td>2018-12-20</td> <td>\ref_rfc20181220</td> <td></td> </tr> +<tr> <td>2018-06-20</td> <td>\ref_rfc20180620</td> <td></td> </tr> +<tr> <td>2018-06-10</td> <td>\ref_rfc20180610</td> <td></td> </tr> +<tr> <td>2018-03-21</td> <td>\ref_rfc20180321</td> <td></td> </tr> +<tr> <td>2018-01-25</td> <td>\ref_rfc20180125</td> <td></td> </tr> +<tr> <td>2017-07-07</td> <td>\ref_rfc20170707</td> <td></td> </tr> +<tr> <td>2016-01-05</td> <td>\ref_rfc20160105</td> <td></td> </tr> +<tr> <td>2015-09-15</td> <td>\ref_rfc20150915</td> <td></td> </tr> +<tr> <td>2015-07-09</td> <td>\ref_rfc20150709</td> <td></td> </tr> +<tr> <td>2015-06-15</td> <td>\ref_rfc20150615</td> <td></td> </tr> +<tr> <td>2015-04-29</td> <td>\ref_rfc20150429</td> <td></td> </tr> +<tr> <td>2015-04-24</td> <td>\ref_rfc20150424</td> <td></td> </tr> +<tr> <td>2015-04-23</td> <td>\ref_rfc20150423</td> <td></td> </tr> +<tr> <td>2015-03-01</td> <td>\ref_rfc20150301</td> <td></td> </tr> +<tr> <td>2015-02-12</td> <td>\ref_rfc20150212</td> <td></td> </tr> +<tr> <td>2015-02-05</td> <td>\ref_rfc20150205</td> <td></td> </tr> +<tr> <td>2015-02-02</td> <td>\ref_rfc20150202</td> <td></td> </tr> +<tr> <td>2014-12-10</td> <td>\ref_rfc20141210</td> <td></td> </tr> +<tr> <td>2014-12-01</td> <td>\ref_rfc20141201</td> <td></td> </tr> +<tr> <td>2014-09-16</td> <td>\ref_rfc20140916</td> <td></td> </tr> +<tr> <td>2014-08-27</td> <td>\ref_rfc20140827</td> <td></td> </tr> +<tr> <td>2014-07-29</td> <td>\ref_rfc20140729</td> <td></td> </tr> +<tr> <td>2014-07-22</td> <td>\ref_rfc20140722</td> <td></td> </tr> +<tr> <td>2014-07-17</td> <td>\ref_rfc20140717</td> <td></td> </tr> +<tr> <td>2014-07-07</td> <td>\ref_rfc20140707</td> <td></td> </tr> +<tr> <td>2014-05-24</td> <td>\ref_rfc20140524</td> <td></td> </tr> +<tr> <td>2014-03-18</td> <td>\ref_rfc20140318</td> <td></td> </tr> +<tr> <td>2014-03-13</td> <td>\ref_rfc20140313</td> <td></td> </tr> +<tr> <td>2014-02-24</td> <td>\ref_rfc20140224</td> <td></td> </tr> +<tr> <td>2013-12-11</td> <td>\ref_rfc20131211</td> <td></td> </tr> +<tr> <td>2013-09-30</td> <td>\ref_rfc20130930</td> <td></td> </tr> +<tr> <td>2013-09-19</td> <td>\ref_rfc20130919</td> <td></td> </tr> +<tr> <td>2013-06-30</td> <td>\ref_rfc20130630</td> <td></td> </tr> +<tr> <td>2013-03-16</td> <td>\ref_rfc20130316</td> <td></td> </tr> +<tr> <td>2012-11-14</td> <td>\ref_rfc20121114</td> <td></td> </tr> +<tr> <td>2012-10-24</td> <td>\ref_rfc20121024</td> <td></td> </tr> +<tr> <td>2012-08-28</td> <td>\ref_rfc20120828</td> <td></td> </tr> +<tr> <td>2012-05-23</td> <td>\ref_rfc20120523</td> <td></td> </tr> +<tr> <td>2012-05-01</td> <td>\ref_rfc20120501</td> <td></td> </tr> +<tr> <td>2012-03-05</td> <td>\ref_rfc20120305</td> <td></td> </tr> +<tr> <td>2012-02-20</td> <td>\ref_rfc20120220</td> <td></td> </tr> +<tr> <td>2012-01-20</td> <td>\ref_rfc20120120</td> <td></td> </tr> +<tr> <td>2012-01-04</td> <td>\ref_rfc20120104</td> <td></td> </tr> +<tr> <td>2011-11-19</td> <td>\ref_rfc20111119</td> <td></td> </tr> +<tr> <td>2011-08-25</td> <td>\ref_rfc20110825</td> <td></td> </tr> +<tr> <td>2011-08-11</td> <td>\ref_rfc20110811</td> <td></td> </tr> +<tr> <td>2011-07-26</td> <td>\ref_rfc20110726</td> <td></td> </tr> +<tr> <td>2011-06-14</td> <td>\ref_rfc20110614</td> <td></td> </tr> +<tr> <td>2011-03-29</td> <td>\ref_rfc20110329</td> <td></td> </tr> +<tr> <td>2011-01-18</td> <td>\ref_rfc20110118</td> <td></td> </tr> +<tr> <td>2010-11-22</td> <td>\ref_rfc20101122</td> <td></td> </tr> +<tr> <td>2010-11-04</td> <td>\ref_rfc20101104</td> <td></td> </tr> +<tr> <td>2010-10-18</td> <td>\ref_rfc20101018</td> <td></td> </tr> +<tr> <td>2010-09-02</td> <td>\ref_rfc20100902</td> <td></td> </tr> +<tr> <td>2010-07-27</td> <td>\ref_rfc20100727</td> <td></td> </tr> +<tr> <td>2010-07-26</td> <td>\ref_rfc20100726</td> <td></td> </tr> +<tr> <td>2010-05-11</td> <td>\ref_rfc20100511</td> <td></td> </tr> +<tr> <td>2010-04-22</td> <td>\ref_rfc20100422</td> <td></td> </tr> +<tr> <td>2010-03-12</td> <td>\ref_rfc20100312</td> <td></td> </tr> +<tr> <td>2009-12-18</td> <td>\ref_rfc20091218</td> <td></td> </tr> +<tr> <td>2009-09-07</td> <td>\ref_rfc20090907</td> <td></td> </tr> +<tr> <td>2009-06-12</td> <td>\ref_rfc20090612</td> <td></td> </tr> +<tr> <td>2008-12-18</td> <td>\ref_rfc20081218</td> <td></td> </tr> +<tr> <td>2008-09-15</td> <td>\ref_rfc20080915</td> <td></td> </tr> +<tr> <td>2008-09-04</td> <td>\ref_rfc20080904</td> <td></td> </tr> +<tr> <td>2008-03-01</td> <td>\ref_rfc20080301</td> <td></td> </tr> +<tr> <td>2008-02-09</td> <td>\ref_rfc20080209</td> <td></td> </tr> +<tr> <td>2008-02-06</td> <td>\ref_rfc20080206</td> <td></td> </tr> +<tr> <td>2007-11-11</td> <td>\ref_rfc20071111</td> <td></td> </tr> +<tr> <td>2007-10-18</td> <td>\ref_rfc20071018</td> <td></td> </tr> +<tr> <td>2007-08-01</td> <td>\ref_rfc20070801</td> <td></td> </tr> +<tr> <td>2007-04-13</td> <td>\ref_rfc20070413</td> <td></td> </tr> +<tr> <td>2007-01-15</td> <td>\ref_rfc20070115</td> <td></td> </tr> +<tr> <td>2006-06-23</td> <td>\ref_rfc20060623</td> <td></td> </tr> +<tr> <td>2006-06-04</td> <td>\ref_rfc20060604</td> <td></td> </tr> +<tr> <td>2006-05-05</td> <td>\ref_rfc20060505</td> <td></td> </tr> +<tr> <td>2006-04-10</td> <td>\ref_rfc20060410</td> <td></td> </tr> +<tr> <td>2006-03-17</td> <td>\ref_rfc20060317</td> <td></td> </tr> +<tr> <td>2006-01-24</td> <td>\ref_rfc20060124</td> <td></td> </tr> +<tr> <td>2004-08-11</td> <td>\ref_rfc20040811</td> <td></td> </tr> +</table> + +*/ \ No newline at end of file diff --git a/doxygen/dox/ReferenceManual.dox b/doxygen/dox/ReferenceManual.dox index 596a224..1de53f2 100644 --- a/doxygen/dox/ReferenceManual.dox +++ b/doxygen/dox/ReferenceManual.dox @@ -3,41 +3,87 @@ The functions provided by the HDF5 C-API are grouped into the following \Emph{modules}: -\li \ref H5A "Attributes" — Management of HDF5 attributes (\ref H5A) -\li \ref H5D "Datasets" — Management of HDF5 datasets (\ref H5D) -\li \ref H5S "Dataspaces" — Management of HDF5 dataspaces which describe the shape of datasets and attributes (\ref H5S) -\li \ref H5T "Datatypes" — Management of datatypes which describe elements of datasets and attributes (\ref H5T) -\li \ref H5E "Error Handling" — Functions for handling HDF5 errors (\ref H5E) -\li \ref H5ES "Event Sets" — Functions for handling HDF5 event sets (\ref H5ES) -\li \ref H5F "Files" — Management of HDF5 files (\ref H5F) -\li \ref H5Z "Filters" — Configuration of filters that process data during I/O operation (\ref H5Z) -\li \ref H5G "Groups" — Management of groups in HDF5 files (\ref H5G) -\li \ref H5I "Identifiers" — Management of object identifiers and object names (\ref H5I) -\li \ref H5 "Library" — General purpose library functions (\ref H5) -\li \ref H5L "Links" — Management of links in HDF5 groups (\ref H5L) -\li \ref H5M "Maps" — Management of HDF5 maps (\ref H5M) -\li \ref H5O "Objects" — Management of objects in HDF5 files (\ref H5O) -\li \ref H5PL "Plugins" — Programmatic control over dynamically loaded plugins (\ref H5PL) -\li \ref H5P "Property Lists" — Management of property lists to control HDF5 library behavior (\ref H5P) -\li \ref H5R "References" — Management of references to specific objects and data regions in an HDF5 file (\ref H5R) -\li \ref H5VL "Virtual Object Layer" — Management of the Virtual Object Layer (\ref H5VL) - -\par Asynchronous Functions - A subset of functions has \ref ASYNC "asynchronous variants". - -\par API Versioning - See \ref api-compat-macros - -\par Deprecated Functions and Types - A list of deprecated functions and types can be found - <a href="./deprecated.html">here</a>. - -\par Etiquette - Here are a few simple rules to follow: - \li \Bold{Handle discipline:} If you acquire a handle (by creation or copy), \Emph{you own it!} (..., i.e., you have to close it.) - \li \Bold{Dynamic memory allocation:} ... - \li \Bold{Use of locations:} Identifier + name combo +<table> +<tr><th>Modules</th></tr> +<tr valign="top"> +<td> + +<table> +<tr><td style="border: none;"> +\li \ref H5A "Attributes (H5A)" +\li \ref H5D "Datasets (H5D)" +\li \ref H5S "Dataspaces (H5S)" +\li \ref H5T "Datatypes (H5T)" +\li \ref H5E "Error Handling (H5E)" +\li \ref H5ES "Event Sets (H5ES)" +\li \ref H5F "Files (H5F)" +\li \ref H5Z "Filters (H5Z)" +\li \ref H5G "Groups (H5G)" +</td><td style="border: none;"> +\li \ref H5I "Identifiers (H5I)" +\li \ref H5 "Library General (H5)" +\li \ref H5L "Links (H5L)" +\li \ref H5M "Maps (H5M)" +\li \ref H5O "Objects (H5O)" +\li \ref H5P "Property Lists (H5P)" +\li \ref H5PL "Dynamically-loaded Plugins (H5PL)" +\li \ref H5R "References (H5R)" +\li \ref H5VL "Virtual Object Layer (H5VL)" +</td><td style="border: none;vertical-align: top;"> +\li Functions with \ref ASYNC "asynchronous variants" +\li \ref api-compat-macros +\li <a href="./deprecated.html">Deprecated functions</a> +\li High-level Extensions + <ul> + <li><a href="https://portal.hdfgroup.org/display/HDF5/Lite">\Bold{HDF5 Lite} (H5LT)</a></li> + <li><a href="https://portal.hdfgroup.org/display/HDF5/Images">\Bold{HDF5 Image} (H5IM)</a></li> + <li><a href="https://portal.hdfgroup.org/display/HDF5/Tables">\Bold{HDF5 Table} (H5TB)</a></li> + <li><a href="https://portal.hdfgroup.org/display/HDF5/Packet+Tables">\Bold{HDF5 Packet Table} (H5TB)</a></li> + <li><a href="https://portal.hdfgroup.org/display/HDF5/Dimension+Scales">\Bold{HDF5 Dimension Scale} (H5DS)</a></li> + </ul> +</td></tr> +<tr><td colspan="3" style="border: none;"> +\ref H5 \ref H5A \ref H5D \ref H5E \ref H5ES \ref H5F \ref H5G \ref H5I \ref H5L +\ref H5M \ref H5O \ref H5P \ref H5PL \ref H5R \ref H5S \ref H5T \ref H5VL \ref H5Z +</td></tr> +</table> + +</td></tr> +<tr><th>Mind the gap</th></tr> +<tr><td> +Follow these simple rules and stay out of trouble: + +\li \Bold{Handle discipline:} The HDF5 C-API is rife with handles or + identifiers, which you typically obtain by creating new HDF5 items, copying + items, or retrieving facets of items. \Emph{You acquire a handle, you own it!} + (Colin Powell) In other words, you are responsible for releasing the underlying + resources via the matching \Code{H5*close()} call, or deal with the consequences + of resource leakage. +\li \Bold{Closed means closed:} Do not pass identifiers that were previously + \Code{H5*close()}-d to other API functions! It will generate an error. +\li \Bold{Dynamic memory allocation:} The API contains a few functions in which the + HDF5 library dynamically allocates memory on the caller's behalf. The caller owns + this memory and eventually must free it by calling H5free_memory(). (\Bold{Not} + the `free` function \Emph{du jour}!) +\li \Bold{Be careful with that saw:} Do not modify the underlying collection when an + iteration is in progress! +\li \Bold{Use of locations:} Certain API functions, typically called \Code{H5***_by_name} + use a combination of identifiers and path names to refer to HDF5 objects. + If the identifier fully specifies the object in question, pass \Code{'.'} (a dot) + for the name! + +Break a leg! +</td> +</tr> +</table> \cpp_c_api_note -*/ \ No newline at end of file +\par Don't like what you see? - You can help to improve this Reference Manual + Complete the survey linked near the top of this page!\n + We treat documentation like code: Fork the + <a href="https://github.com/HDFGroup/hdf5">HDF5 repo</a>, make changes, and create a + <a href="https://github.com/HDFGroup/hdf5/pulls">pull request</a> !\n + See the \ref RMT for general guidance. + +*/ diff --git a/doxygen/dox/cookbook/Accessibility.c b/doxygen/dox/cookbook/Accessibility.c new file mode 100644 index 0000000..f4cc905 --- /dev/null +++ b/doxygen/dox/cookbook/Accessibility.c @@ -0,0 +1,48 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [set_libver_bounds] --> + { + __label__ fail_fapl, fail_file; + hid_t fapl, file, aspace, attr; + + if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_fapl; + } +#if H5_VERSION_GE(1, 10, 0) + if (H5Pset_libver_bounds(fapl, H5F_LIBVER_V18, H5F_LIBVER_V18) < 0) { +#elif H5_VERSION_GE(1, 8, 0) + if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) { +#else +#error Only HDF5 1.8.x and later supported. +#endif + ret_val = EXIT_FAILURE; + goto fail_file; + } + if ((file = H5Fcreate("set_libver_bounds.h5", H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + H5Fclose(file); +fail_file: + H5Pclose(fapl); +fail_fapl:; + } + //! <!-- [set_libver_bounds] --> + + assert(ret_val == EXIT_SUCCESS); + + return ret_val; +} diff --git a/doxygen/dox/cookbook/Accessibility.dox b/doxygen/dox/cookbook/Accessibility.dox new file mode 100644 index 0000000..f100283 --- /dev/null +++ b/doxygen/dox/cookbook/Accessibility.dox @@ -0,0 +1,39 @@ +/** \page Accessibility + +\section Accessibility + +\subsection CB_MaintainCompat Maintaining Compatibility with other HDF5 Library Versions + +\par Problem +You want to ensure that the HDF5 files you produce or modify are accessible by all +releavnt tools and applications + +\par Solution +For HDF5 items (objects, attributes, etc.) that you would like to +create in new or existing HDF5 files, ascertain the supported range of HDF5 +library versions as lower and upper bounds. When creating new or opening +existing HDF5 files, use a file access property list and configure the supported +range via the H5Pset_libver_bounds() function.\n +In the example below, we restrict HDF5 item creation to the HDF5 1.8.x family of +library versions. +\snippet{lineno} Accessibility.c set_libver_bounds + +\par Discussion +See RFC \ref_rfc20160105 for a detailed and comprehensive account of HDF5 +versioning (library, file format spec., etc.) and the H5Pset_libver_bounds() +function.\n +The default range #H5F_LIBVER_EARLIEST (low) - #H5F_LIBVER_LATEST (high) offers the +widest compatibility range, but may not be suitable for certain (feature-)use +cases.\n +The HDF5 library comes with a \Emph{forward-} and \Emph{backward-compatibility} +guarantee: This means that the latest version of the library can always read +HDF5 files created by a version realesed earlier (backward compatibility). +It also means that a given release of the library can read the contents of +HDF5 files created with later versions of the library as long as the files +do not contain features introduced in later versions (forward compatibility). + +\par See Also +See the recipe \ref CB_LargeAttributes for an example where we use HDF5 +compatibility settings to enable the creation of large HDF5 attributes. + +*/ \ No newline at end of file diff --git a/doxygen/dox/cookbook/Attributes.c b/doxygen/dox/cookbook/Attributes.c new file mode 100644 index 0000000..f4e894f --- /dev/null +++ b/doxygen/dox/cookbook/Attributes.c @@ -0,0 +1,61 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [large_attribute] --> + { + __label__ fail_attr, fail_aspace, fail_fapl, fail_file; + hid_t fapl, file, aspace, attr; + + if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_fapl; + } +#if H5_VERSION_GE(1, 10, 0) + if (H5Pset_libver_bounds(fapl, H5F_LIBVER_V18, H5F_LIBVER_LATEST) < 0) { +#elif H5_VERSION_GE(1, 8, 0) + if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) { +#else +#error Only HDF5 1.8.x and later supported. +#endif + ret_val = EXIT_FAILURE; + goto fail_file; + } + if ((file = H5Fcreate("large_attribute.h5", H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + if ((aspace = H5Screate_simple(1, (hsize_t[]){1024 * 1024}, NULL)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_aspace; + } + if ((attr = H5Acreate(file, "4MiB", H5T_IEEE_F32LE, aspace, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_attr; + } + + H5Aclose(attr); +fail_attr: + H5Sclose(aspace); +fail_aspace: + H5Fclose(file); +fail_file: + H5Pclose(fapl); +fail_fapl:; + } + //! <!-- [large_attribute] --> + + assert(ret_val == EXIT_SUCCESS); + + return ret_val; +} diff --git a/doxygen/dox/cookbook/Attributes.dox b/doxygen/dox/cookbook/Attributes.dox new file mode 100644 index 0000000..68fd159 --- /dev/null +++ b/doxygen/dox/cookbook/Attributes.dox @@ -0,0 +1,38 @@ +/** \page Attributes + +\section Attributes + +\subsection CB_LargeAttributes Creating "Large" HDF5 Attributes + +\par Problem +You would like to use HDF5 attributes the size of whose values +exceeds a few dozen kilobytes + +\par Solution +A file format change in the HDF5 1.8.x family of library releases made it +possible to have attributes larger than about 64 KiB. Ensure that the lower +library version bound for new HDF5 item creation is at least 1.8.x, and create +larger attributes as usual.\n +In the example below, we create an attribute whose value occupies 4 MiB. + +\note This feature is only supported in HDF5 1.8.x+ + +\snippet{lineno} Attributes.c large_attribute + +\par Discussion +Large attributes are supported only in HDF5 versions 1.8.x and higher. +This has implications for the accessibility of your HDF5 files and +is your call.\n +Since there are no size limitations for large attributes, it might +seem tempting to mistake them for dataset stand-ins. This is not the +case, for at least two reasons: +1. Attributes decorate HDF5 objects, have their own local namespace, + and can't be link targets. +2. Attribute I/O treats the attribute value as atomic, i.e., there + is no support for partial I/O. A large attribute will always be + read or written in its entirety. + +\par See Also +See \ref CB_MaintainCompat for HDF5 compatibility implications. + + */ \ No newline at end of file diff --git a/doxygen/dox/cookbook/Files.c b/doxygen/dox/cookbook/Files.c new file mode 100644 index 0000000..b824933 --- /dev/null +++ b/doxygen/dox/cookbook/Files.c @@ -0,0 +1,87 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [free_space] --> + { + __label__ fail_fcpl, fail_fapl, fail_file; + hid_t fcpl, fapl, file; + + if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_fcpl; + } +#if H5_VERSION_GE(1, 10, 1) + if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_FSM_AGGR, 1, 4096) < 0) { +#else +#error HDF5 1.10.1+ required +#endif + ret_val = EXIT_FAILURE; + goto fail_fapl; + } + + if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_fapl; + } +#if H5_VERSION_GE(1, 10, 1) + if (H5Pset_libver_bounds(fapl, H5F_LIBVER_V110, H5F_LIBVER_LATEST) < 0) { +#else +#error HDF5 1.10.x+ required +#endif + ret_val = EXIT_FAILURE; + goto fail_file; + } + + if ((file = H5Fcreate("free_space.h5", H5F_ACC_TRUNC, fcpl, fapl)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + H5Fclose(file); + +fail_file: + H5Pclose(fapl); +fail_fapl: + H5Pclose(fcpl); +fail_fcpl:; + } + //! <!-- [free_space] --> + + //! <!-- [user_block] --> + { + __label__ fail_fcpl, fail_file; + hid_t fcpl, file; + + if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_fcpl; + } + if (H5Pset_userblock(fcpl, 8192 * 1024) < 0) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + if ((file = H5Fcreate("userblock.h5", H5F_ACC_TRUNC, fcpl, H5P_DEFAULT)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + H5Fclose(file); + +fail_file: + H5Pclose(fcpl); +fail_fcpl:; + } + //! <!-- [user_block] --> + + assert(ret_val == EXIT_SUCCESS); + + return ret_val; +} diff --git a/doxygen/dox/cookbook/Files.dox b/doxygen/dox/cookbook/Files.dox new file mode 100644 index 0000000..169d638 --- /dev/null +++ b/doxygen/dox/cookbook/Files.dox @@ -0,0 +1,71 @@ +/** \page Files + +\section Files + +\subsection CB_FreeSpace Tracking Free Space in HDF5 Files + +\par Problem +You sometimes delete objects in HDF5 files and don't have new content to use the +free space, but would like to reuse it in the future. + +\par Solution +At file creation time, set the file space management strategy and persistence of +free space tracking information via H5Pset_file_space_strategy(). + +\note This feature is only supported in HDF5 1.10.1+. + +\snippet{lineno} Files.c free_space + +\par Discussion +Free space tracking is supported only in HDF5 versions 1.10.x and higher. +This has implications for the accessibility of your HDF5 files and +should be considered carefully. If compatibility with previous versions of +HDF5 must be maintained, space reclamation via \Code{h5repack} might be an option.\n +The file space strategy #H5F_FSPACE_STRATEGY_FSM_AGGR is not the only option +that supports free-space tracking. #H5F_FSPACE_STRATEGY_PAGE is another option, +which adds paged allocation and is used most effectively with page buffering.\n +For an in-depth account of HDF5 file space management, paged-allocation, and +page buffering, see the following documents: +\li \ref_rfc20121024 +\li \ref_rfc20120523 +\li \ref_rfc20150709 + +\par See Also +See \ref CB_MaintainCompat for HDF5 compatibility implications. + + +\subsection CB_RemoveUnusedSpace Removing Unused Space from HDF5 Files + +\par Problem +Based on estimates or \Code{h5stat} output you know that a large portion +of an HDF5 file consists of free or unaccounted space, and you would like +to remove it. + + +\subsection CB_UserBlock Creating an HDF5 File User Block + +\par Problem +You would like to include certain ancillary, non-HDF5 content in an +HDF5 file such that it can be accessed without the HDF5 library. + +\par Solution +Use a file creation property list in which the user block size is set via +H5Pset_userblock(). In the example below, we create an 8 MiB user block. +\snippet{lineno} Files.c user_block + +\par Discussion +The user block begins at offset 0 and must be at least 512 bytes and a power +of 2. The HDF5 library ignores any content between the beginning of the +file and the end of the user block.\n +You can add or strip a user block to/from an existing HDF5 file with the +\Code{h5jam}/\Code{h5unjam} tool, respectively. +\warning +If you try to embed content into the user block for use by other applications, +pay close attention to how they handle space beyond the last used byte in the +user block or the user block in general. In the worst case, applications might +try to truncate the rest of the file and destroy the HDF5 portion of the file. + +\par See Also +References to related recipes + + */ \ No newline at end of file diff --git a/doxygen/dox/cookbook/Performance.dox b/doxygen/dox/cookbook/Performance.dox new file mode 100644 index 0000000..7ac3a18 --- /dev/null +++ b/doxygen/dox/cookbook/Performance.dox @@ -0,0 +1,21 @@ +/** \page Performance + +\section Performance + +\subsection CB_MDCPerf Assessing HDF5 Metadata Cache Performance + +\par Problem +You are trying to diagnose and improve the I/O performance of an application +and would like to understand if a simple metadata cache adjustment might +yield substantial performance gains + +\par Solution +The to-the-point solution, i.e., the solution w/o any background or explanation + +\par Discussion +A discussion of the fine points and variants of the solution + +\par See Also +References to related recipes + + */ \ No newline at end of file diff --git a/doxygen/dox/maybe_metadata_reads.dox b/doxygen/dox/maybe_metadata_reads.dox index 25c905f..1bb53e0 100644 --- a/doxygen/dox/maybe_metadata_reads.dox +++ b/doxygen/dox/maybe_metadata_reads.dox @@ -13,62 +13,30 @@ * The following is a list of those functions in the HDF5 library. This list is * integral to the discussion in the H5Pset_all_coll_metadata_ops() entry: * - * <pre> - * - * H5Awrite() - * H5Aread() - * H5Arename() - * H5Aiterate2() - * H5Adelete() - * H5Aexists() - * - * H5Dget_space_status() - * H5Dget_storage_size() - * H5Dset_extent() - * H5Ddebug() - * H5Dclose() - * H5Dget_create_plist() - * H5Dget_space() (when dataset is a virtual dataset) - * - * H5Gget_create_plist() - * H5Gget_info() - * H5Gclose() - * - * H5Literate() - * H5Lvisit() - * - * H5Rcreate() - * H5Rdereference2() (when reference is an object reference) - * H5Rget_region() - * H5Rget_obj_type2() - * H5Rget_name() - * - * H5Ocopy() - * H5Oopen_by_addr() - * H5Oincr_refcount() - * H5Odecr_refcount() - * H5Oget_info() - * H5Oset_comment() - * H5Ovisit() - * - * H5Fis_hdf5() - * H5Fflush() - * H5Fclose() - * H5Fget_file_image() - * H5Freopen() - * H5Fget_freespace() - * H5Fget_info2() - * H5Fget_free_sections() - * H5Fmount() + * H5Awrite(), H5Aread(), H5Arename(), H5Aiterate2(), H5Adelete(), H5Aexists() + * + * H5Dget_space_status(), H5Dget_storage_size(), H5Dset_extent(), H5Ddebug(), + * H5Dclose(), H5Dget_create_plist(), H5Dget_space() (for virtual datasets) + * + * H5Gget_create_plist(), H5Gget_info(), H5Gclose() + * + * H5Literate(), H5Lvisit() + * + * H5Rcreate(), H5Rdereference2() (for object references), + * H5Rget_region(), H5Rget_obj_type2(), H5Rget_name() + * + * H5Ocopy(), H5Oopen_by_addr(), H5Oincr_refcount(), H5Odecr_refcount(), + * H5Oget_info(), H5Oset_comment(), H5Ovisit() + * + * H5Fis_hdf5(), H5Fflush(), H5Fclose(), H5Fget_file_image(), H5Freopen(), + * H5Fget_freespace(), H5Fget_info2(), H5Fget_free_sections(), H5Fmount(), * H5Funmount() * * H5Iget_name() * - * H5Tget_create_plist() - * H5Tclose() + * H5Tget_create_plist(), H5Tclose() * * H5Zunregister() - * </pre> * * In addition, \b most deprecated functions fall into this category. * diff --git a/doxygen/dox/rm-template.dox b/doxygen/dox/rm-template.dox index 64e4770..070a0a1 100644 --- a/doxygen/dox/rm-template.dox +++ b/doxygen/dox/rm-template.dox @@ -1,72 +1,99 @@ -/**\ingroup H5XYZ - * - * \brief A synopsis of what H5XYZgreat_function does - * - * \param[in] name1 Description of IN parameter \p name1 - * \param[out] name2 Description of OUT parameter \p name2 - * \param[in,out] name3 Description of INOUT parameter \p name3 - * - * \return Returns what you always wanted - * - * \pre Describe preconditions for an entity. Can be repreated. - * - * \invariant Describe invariants for an entity. Can be repeated. - * - * \post Describe postconditions for an entity. Can be repreated. - * - * \deprecated This was my favorite function while it lasted. - * - * \details Describe the normal behavior flow of the function here. Try to be - * helpful! - * - * Make reference to other functions like this: H5Fopen(). - * - * Make reference to formal parameters like this: \p name1 - * - * Make reference to macros like this: #H5P_DEFAULT. - * - * Make reference to enumeration constants like this: #H5F_CLOSE_WEAK. - * - * Include code snippets like this: - * \snippet H5Zpublic.h H5Z_class2_t_snip - * - * Lists are supported: - * - mouse events - * -# mouse move event - * -# mouse click event\n - * More info about the click event. - * -# mouse double click event - * - keyboard events - * 1. key down event - * 2. key up event - * - * The distance between \f$(x_1,y_1)\f$ and \f$(x_2,y_2)\f$ is - * \f$\sqrt{(x_2-x_1)^2+(y_2-y_1)^2}\f$.\n - * For tables, see - * <a href="https://www.doxygen.nl/manual/tables.html">this example</a>. - * - * This is an example of how to use the H5XYZgreat_function().\n - * The contents of the file hello_hdf5.c will be included. - * \include hello_hdf5.c - * - * \note Dear reader, ... - * - * \attention Colorless green ideas sleep furiously. - * - * \warning Don't do this at home! - * - * \author This function was written by an esteemed author. Repeat this - * command for multiple authors. - * - * \date Record the function's birthdate! - * - * \since 1.MAJOR.MINOR The 'since' command can also be used to record a - * function's introduction (via its initial release - * version). - * - * \version 1.MAJOR.MINOR An important event in the version history of this - * function. There can be multiple such events. - * - * \see H5XYZanother_great_function(), H5XYZnot_so_great_a_function() - * - */ +/** \page RMT Reference Manual (RM) Page Template + +We treat documentation like code and use +<a href="https://www.doxygen.nl/index.html">Doxygen</a> to +<a href="https://github.com/HDFGroup/hdf5/blob/develop/src/H5Fpublic.h">markup +comments in the code</a> or create +<a href="https://github.com/HDFGroup/hdf5/blob/develop/doxygen/dox/Overview.dox">stand-alone pages</a>. + +Every RM entry consists of a subset of the elements listed below. Not every RM +entry warrants the full set. More is better, and we can, perhaps, distinguish +minimal, typical, and great RM entries. + +A minimal RM entry must include elements 1-3, 8, 11, and 7 if applicable. + +A \Emph{typical} RM entry is a minimal RM entry that in addition has elements +9, 10, and 12. + +A \Bold{great} RM entry is a typical RM entry plus everything else. + +The current RM is a mixed bag. Take what's there with a pinch of salt and apply +the <a href="https://www.oreilly.com/library/view/97-things-every/9780596809515/ch08.html">Scout Rule</a>! + +\par RM entry elements + +1. Module indication + - Indicate the HDF5 module in which the function will appear. + \verbatim + * \ingroup H5XYZ + \endverbatim +2. Synopsis + - A phrase or sentence that summarizes the function's purpose + \verbatim + * \brief Simplifies your life + \endverbatim +3. Prototype (parameters and return value) + - A description of the function parameters and return value + \verbatim + * \param[in] name1 Description of IN parameter \p name1 + * \param[out] name2 Description of OUT parameter \p name2 + * \param[in,out] name3 Description of INOUT parameter \p name3 + * \return Returns what you always wanted + \endverbatim + - Clearly indicate the parameter direction as \c in, \c out, or + \Code{in,out} + - Make reference to other parameters using \Code{\\p} +4. Preconditions + - A set of preconditions that must be met. + \verbatim + * \pre The argmument supplied in parameter \p name2 must be even. + \endverbatim +5. Invariants + - A set of invariants. + \verbatim + * \invariant The mouse pointer will always be visible. + \endverbatim +6. Postconditions + - What will be true when the function returns. + \verbatim + * \post On error, the output parameters will be unmodified. + \endverbatim +7. Deprecation note + - If a function was deprecated, list the version in which the function was + deprecated (below), why it was deprecated, and which function(s) succeed it. + \verbatim + * \deprecated Deprecated in favor of another great function. + \endverbatim +8. Details + - A detailed description of the function's behavior + \verbatim + * \details This is the heart of the matter. Try to be helpful! + \endverbatim +9. Example + - The function in context and action, usually a (Doxygen) snippet. + \verbatim + * \par Example + * \snippet H5F_examples.c minimal + \endverbatim +10. Instruction (attention, note, warning) + - Behaviors, features, side-effects, etc. the user should be aware of + \verbatim + * \note Dear reader, ... + * + * \attention Colorless green ideas sleep furiously. + * + * \warning Don't do this at home! + \endverbatim +11. Since + - The HDF5 library version in which the function was introduced + \verbatim + * \since 1.MAJOR.MINOR + \endverbatim +12. Version + - Use this element to record a deprecation version, a change in parameter + types, changes in behavior, etc. + \verbatim + * \version 1.MAJOR.MINOR Function was deprecated in this release + \endverbatim + +*/ diff --git a/doxygen/examples/H5D_examples.c b/doxygen/examples/H5D_examples.c index aad057d..4e54c1d 100644 --- a/doxygen/examples/H5D_examples.c +++ b/doxygen/examples/H5D_examples.c @@ -5,6 +5,86 @@ #include <stdio.h> #include <stdlib.h> +//! <!-- [H5Dchunk_iter_cb] --> +int +chunk_cb(const hsize_t *offset, uint32_t filter_mask, haddr_t addr, uint32_t nbytes, void *op_data) +{ + // only print the allocated chunk size only + printf("%d\n", nbytes); + return EXIT_SUCCESS; +} +//! <!-- [H5Dchunk_iter_cb] --> + +//! <!-- [H5Ovisit_cb] --> +herr_t +H5Ovisit_cb(hid_t obj, const char *name, const H5O_info2_t *info, void *op_data) +{ + herr_t retval = 0; + char * base_path = (char *)op_data; + + if (info->type == H5O_TYPE_DATASET) // current object is a dataset + { + hid_t dset, dcpl; + if ((dset = H5Dopen(obj, name, H5P_DEFAULT)) == H5I_INVALID_HID) { + retval = -1; + goto func_leave; + } + if ((dcpl = H5Dget_create_plist(dset)) == H5I_INVALID_HID) { + retval = -1; + goto fail_dcpl; + } + if (H5Pget_layout(dcpl) == H5D_CHUNKED) // dataset is chunked + { + __label__ fail_dtype, fail_dspace, fail_shape; + hid_t dspace, dtype; + size_t size, i; + int rank; + hsize_t cdims[H5S_MAX_RANK]; + + // get resources + if ((dtype = H5Dget_type(dset)) < 0) { + retval = -1; + goto fail_dtype; + } + if ((dspace = H5Dget_space(dset)) < 0) { + retval = -1; + goto fail_dspace; + } + // get the shape + if ((size = H5Tget_size(dtype)) == 0 || (rank = H5Sget_simple_extent_ndims(dspace)) < 0 || + H5Pget_chunk(dcpl, H5S_MAX_RANK, cdims) < 0) { + retval = -1; + goto fail_shape; + } + // calculate the nominal chunk size + size = 1; + for (i = 0; i < (size_t)rank; ++i) + size *= cdims[i]; + // print dataset info + printf("%s%s : nominal chunk size %lu [B] \n", base_path, name, size); + // get the allocated chunk sizes + if (H5Dchunk_iter(dset, H5P_DEFAULT, &chunk_cb, NULL) < 0) { + retval = -1; + goto fail_fig; + } + +fail_shape: + H5Sclose(dspace); +fail_dspace: + H5Tclose(dtype); +fail_dtype:; + } + + H5Pclose(dcpl); +fail_dcpl: + H5Dclose(dset); + } + +func_leave: + return retval; +} +//! <!-- [H5Ovisit_cb] --> + int main(void) { @@ -166,7 +246,6 @@ fail_delete: H5Fclose(file); fail_file:; } - //! <!-- [delete] --> return ret_val; diff --git a/doxygen/examples/H5E_examples.c b/doxygen/examples/H5E_examples.c new file mode 100644 index 0000000..deea838 --- /dev/null +++ b/doxygen/examples/H5E_examples.c @@ -0,0 +1,97 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + __label__ fail_push, fail_minor, fail_major, fail_class; + hid_t cls, major, minor; + + // register a new error class for this "application" + if ((cls = H5Eregister_class("Custom error class", "H5E_examples", "0.1")) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_class; + } + + // create custom major and minor error codes + if ((major = H5Ecreate_msg(cls, H5E_MAJOR, "Okay, Houston, we've had a problem here")) == + H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_major; + } + if ((minor = H5Ecreate_msg(cls, H5E_MINOR, "Oops!")) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_minor; + } + + // push a custom error message onto the default stack + if (H5Epush2(H5E_DEFAULT, __FILE__, __FUNCTION__, __LINE__, cls, major, minor, "Hello, Error!\n") < + 0) { + ret_val = EXIT_FAILURE; + goto fail_push; + } + + // print the default error stack + if (H5Eprint(H5E_DEFAULT, stderr) < 0) { + ret_val = EXIT_FAILURE; + } + +fail_push: + H5Eclose_msg(minor); +fail_minor: + H5Eclose_msg(major); +fail_major: + H5Eunregister_class(cls); +fail_class:; + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_count; + + // check the number of error messages on the default stack + // and print what's there + ssize_t count = H5Eget_num(H5E_DEFAULT); + if (count < 0) { + ret_val = EXIT_FAILURE; + goto fail_count; + } + else if (H5Eprint(H5E_DEFAULT, stderr) < 0) { + ret_val = EXIT_FAILURE; + } + +fail_count:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + // pop 10 error messages off the default error stack + // popping off non-existent messages is OK, but might be confusing + if (H5Epop(H5E_DEFAULT, 10) < 0) + ret_val = EXIT_FAILURE; + } + //! <!-- [update] --> + + //! <!-- [delete] --> + { + // clear the default error stack (for the current thread) + if (H5Eclear2(H5E_DEFAULT) < 0) + ret_val = EXIT_FAILURE; + } + //! <!-- [delete] --> + + assert(ret_val == EXIT_SUCCESS); + + return ret_val; +} diff --git a/doxygen/examples/H5F_examples.c b/doxygen/examples/H5F_examples.c index a7ce6fb..4e89fde 100644 --- a/doxygen/examples/H5F_examples.c +++ b/doxygen/examples/H5F_examples.c @@ -10,7 +10,7 @@ main(void) { int ret_val = EXIT_SUCCESS; - //! <!-- [life_cycle] --> + //! <!-- [create] --> { __label__ fail_fapl, fail_fcpl, fail_file; hid_t fcpl, fapl, file; @@ -48,12 +48,13 @@ fail_fapl: H5Pclose(fcpl); fail_fcpl:; } - //! <!-- [life_cycle] --> + //! <!-- [create] --> - //! <!-- [life_cycle_w_open] --> + //! <!-- [read] --> { __label__ fail_fapl, fail_file; - hid_t fapl, file; + hid_t fapl, file; + hsize_t size; if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) == H5I_INVALID_HID) { ret_val = EXIT_FAILURE; @@ -63,7 +64,7 @@ fail_fcpl:; // adjust the file access properties } - unsigned mode = H5F_ACC_RDWR; + unsigned mode = H5F_ACC_RDONLY; char name[] = "f1.h5"; if ((file = H5Fopen(name, mode, fapl)) == H5I_INVALID_HID) { @@ -71,14 +72,41 @@ fail_fcpl:; goto fail_file; } - // do something useful with FILE + if (H5Fget_filesize(file, &size) < 0) { + ret_val = EXIT_FAILURE; + } + + printf("File size: %llu bytes\n", size); H5Fclose(file); fail_file: H5Pclose(fapl); fail_fapl:; } - //! <!-- [life_cycle_w_open] --> + //! <!-- [read] --> + + //! <!-- [update] --> + { + __label__ fail_file; + hid_t file; + + unsigned mode = H5F_ACC_RDWR; + char name[] = "f1.h5"; + + if ((file = H5Fopen(name, mode, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + // create a cycle by hard linking the root group in the root group + if (H5Lcreate_hard(file, ".", file, "loopback", H5P_DEFAULT, H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + } + + H5Fclose(file); +fail_file:; + } + //! <!-- [update] --> //! <!-- [minimal] --> { @@ -183,5 +211,18 @@ fail_fapl:; } //! <!-- [mount] --> + //! <!-- [delete] --> + { +#if H5_VERSION_GE(1, 12, 0) + + // this function is only available in HDF5 1.12.x + if (H5Fdelete("f1.h5", H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + } + +#endif + } + //! <!-- [delete] --> + return ret_val; } diff --git a/doxygen/examples/H5G_examples.c b/doxygen/examples/H5G_examples.c new file mode 100644 index 0000000..3109efb --- /dev/null +++ b/doxygen/examples/H5G_examples.c @@ -0,0 +1,186 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + __label__ fail_group, fail_prop, fail_lcpl, fail_file; + hid_t file, lcpl, group; + char fname[] = "g1.h5"; + char path[] = "/αυτή/είναι/μια/νέα/ομάδα"; + + if ((file = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + if ((lcpl = H5Pcreate(H5P_LINK_CREATE)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_lcpl; + } + // ensure that intermediate groups are created automatically + if (H5Pset_create_intermediate_group(lcpl, 1) < 0) { + ret_val = EXIT_FAILURE; + goto fail_prop; + } + // use UTF-8 encoding for link names + if (H5Pset_char_encoding(lcpl, H5T_CSET_UTF8) < 0) { + ret_val = EXIT_FAILURE; + goto fail_prop; + } + // create five groups + if ((group = H5Gcreate(file, path, lcpl, H5P_DEFAULT, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_group; + } + + H5Gclose(group); +fail_group: +fail_prop: + H5Pclose(lcpl); +fail_lcpl: + H5Fclose(file); +fail_file:; + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_file; + char fname[] = "g1.h5"; + char path[] = "/αυτή/είναι"; + hid_t file; + H5G_info_t info; + + if ((file = H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + // open one of the intermediate groups + if (H5Gget_info_by_name(file, path, &info, H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + goto fail_info; + } + + printf("Link count: %llu\n", info.nlinks); + switch (info.storage_type) { + case H5G_STORAGE_TYPE_COMPACT: + printf("Compact storage\n"); + break; + case H5G_STORAGE_TYPE_DENSE: + printf("Compact storage\n"); + break; + case H5G_STORAGE_TYPE_SYMBOL_TABLE: + printf("Symbol table\n"); + break; + default: + printf("UFO\n"); + break; + } + +fail_info: + H5Fclose(file); +fail_file:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + __label__ fail_group, fail_prop, fail_lcpl, fail_file; + hid_t file, lcpl, group; + char fname[] = "g1.h5"; + char path[] = "/αυτή/είναι/μια/άλλη/νέα/ομάδα"; + + if ((file = H5Fopen(fname, H5F_ACC_RDWR, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + if ((lcpl = H5Pcreate(H5P_LINK_CREATE)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_lcpl; + } + // ensure that intermediate groups are created automatically + if (H5Pset_create_intermediate_group(lcpl, 1) < 0) { + ret_val = EXIT_FAILURE; + goto fail_prop; + } + // use UTF-8 encoding for link names + if (H5Pset_char_encoding(lcpl, H5T_CSET_UTF8) < 0) { + ret_val = EXIT_FAILURE; + goto fail_prop; + } + // create an anonymous group + if ((group = H5Gcreate_anon(file, H5P_DEFAULT, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_group; + } + // link the new group to existing the group at "/αυτή/είναι/μια" + if (H5Lcreate_hard(group, ".", file, path, lcpl, H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + } + + H5Gclose(group); +fail_group: +fail_prop: + H5Pclose(lcpl); +fail_lcpl: + H5Fclose(file); +fail_file:; + } + //! <!-- [update] --> + + //! <!-- [delete] --> + { + __label__ fail_info, fail_object, fail_file; + hid_t file, obj; + char fname[] = "g1.h5"; + char path[] = "/αυτή/είναι/μια/άλλη/νέα/ομάδα"; + char delete_path[] = "/αυτή/είναι/μια"; + H5O_info_t info; + + if ((file = H5Fopen(fname, H5F_ACC_RDWR, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + // open a "leaf" group as object + if ((obj = H5Oopen(file, path, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_object; + } + // delete the link to an intermediate group on the path to the leaf + if (H5Ldelete(file, delete_path, H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + } + // link deletion will propagate along hard links along all paths + // reachable from the intermediate group and cause reference counts to + // be decremented, freeing the objects if the count reaches 0 + if (H5Oget_info(obj, &info, H5O_INFO_BASIC) < 0) { + ret_val = EXIT_FAILURE; + goto fail_info; + } + + printf("Leaf reference count: %d\n", info.rc); + +fail_info: + H5Oclose(obj); +fail_object: + H5Fclose(file); +fail_file:; + } + //! <!-- [delete] --> + + assert(ret_val == EXIT_SUCCESS); + + return ret_val; +} diff --git a/doxygen/examples/H5I_examples.c b/doxygen/examples/H5I_examples.c new file mode 100644 index 0000000..4aa4783 --- /dev/null +++ b/doxygen/examples/H5I_examples.c @@ -0,0 +1,242 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + __label__ fail_dcpl; + hid_t dcpl; + + // create an ID of a pre-defined ID type + if ((dcpl = H5Pcreate(H5P_DATASET_XFER)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dcpl; + } + + // we can reliably predict the ID type + assert(H5Iget_type(dcpl) == H5I_GENPROP_LST); + printf("%d\n", H5Iget_type(dcpl)); + + H5Pclose(dcpl); +fail_dcpl:; + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_dcpl; + hid_t dcpl; + + // create an ID of a pre-defined ID type + if ((dcpl = H5Pcreate(H5P_DATASET_XFER)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dcpl; + } + + // this better be valid + assert(H5Iis_valid(dcpl) > 0); + + // this ID is NOT associated with any HDF5 file; + // see the error message + assert(H5Iget_file_id(dcpl) == H5I_INVALID_HID); + + H5Pclose(dcpl); +fail_dcpl:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + __label__ fail_rc, fail_dcpl; + hid_t dcpl; + int rc; + + // create an ID of a pre-defined ID type + if ((dcpl = H5Pcreate(H5P_DATASET_XFER)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dcpl; + } + + // retrieve the IDs reference count + if ((rc = H5Iget_ref(dcpl)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_rc; + } + printf("Reference count: %d\n", rc); + + // bump its reference count (by 1) + if ((rc = H5Iinc_ref(dcpl)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_rc; + } + printf("Reference count: %d\n", rc); + +fail_rc: + H5Pclose(dcpl); +fail_dcpl:; + } + //! <!-- [update] --> + + //! <!-- [delete] --> + { + __label__ fail_rc, fail_dcpl; + hid_t dcpl; + int rc; + + // create an ID of a pre-defined ID type + if ((dcpl = H5Pcreate(H5P_DATASET_XFER)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dcpl; + } + + // decrease its reference count (from 1) to 0 + if ((rc = H5Idec_ref(dcpl)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_rc; + } + printf("Reference count: %d\n", rc); + + // at this point, the ID is no longer valid + assert(H5Iis_valid(dcpl) == 0); + + // dropping the ref. count to 0 has the side-effect of closing + // the associated item, and calling H5Pclose would create an error + goto fail_dcpl; + +fail_rc: + H5Pclose(dcpl); +fail_dcpl:; + } + //! <!-- [delete] --> + + //! <!-- [create_ud] --> + herr_t free_func(void *obj) + { + printf("Calling free_func...\n"); + H5free_memory(obj); + return 0; + } + + { + __label__ fail_id, fail_obj, fail_register; + H5I_type_t type; + int * obj; + hid_t obj_id; + + // register a new ID type + if ((type = H5Iregister_type(128, 1024, &free_func)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_register; + } + printf("New identifier type ID: %d\n", type); + + // create a new object + if ((obj = H5allocate_memory(10 * sizeof(int), 0)) == NULL) { + ret_val = EXIT_FAILURE; + goto fail_obj; + } + + // obtain an ID for the new object + if ((obj_id = H5Iregister(type, obj)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_id; + } + printf("New object identifier: %ld\n", obj_id); + +fail_id: + H5Iclear_type(type, 1); +fail_obj: + H5Idestroy_type(type); +fail_register:; + } + //! <!-- [create_ud] --> + + //! <!-- [read_ud] --> + { + __label__ fail_query, fail_register; + H5I_type_t type; + hsize_t count; + + // register a new ID type + if ((type = H5Iregister_type(128, 1024, NULL)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_register; + } + printf("New FOO identifier type ID: %d\n", type); + + // return the number of identifiers of TYPE currently in use + if (H5Inmembers(type, &count) < 0) { + ret_val = EXIT_FAILURE; + goto fail_query; + } + printf("%llu FOO identifiers in use\n", count); + +fail_query: + H5Idestroy_type(type); +fail_register:; + } + //! <!-- [read_ud] --> + + //! <!-- [update_ud] --> + { + __label__ fail_id, fail_register; + H5I_type_t type; + int obj = 42; + hid_t obj_id; + + // register a new ID type + if ((type = H5Iregister_type(128, 1024, NULL)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_register; + } + printf("New identifier type ID: %d\n", type); + + // obtain an ID for the new object + if ((obj_id = H5Iregister(type, &obj)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_id; + } + printf("New object identifier: %ld\n", obj_id); + + // bump the reference count + assert(H5Iinc_ref(obj_id) == 2); + + // force the deletion of all IDs regardless of reference count + H5Iclear_type(type, 1); +fail_id: + H5Idestroy_type(type); +fail_register:; + } + //! <!-- [update_ud] --> + + //! <!-- [delete_ud] --> + { + __label__ fail_register; + H5I_type_t type; + + // register a new ID type + if ((type = H5Iregister_type(128, 1024, NULL)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_register; + } + printf("New identifier type ID: %d\n", type); + + // decrementing the identifier type's ref. count to 0 triggers + // the type to be destroyed + assert(H5Idec_type_ref(type) == 0); + +fail_register:; + } + //! <!-- [delete_ud] --> + + return ret_val; +} diff --git a/doxygen/examples/H5L_examples.c b/doxygen/examples/H5L_examples.c new file mode 100644 index 0000000..63f54fe --- /dev/null +++ b/doxygen/examples/H5L_examples.c @@ -0,0 +1,156 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +//! <!-- [iter_cb] --> +herr_t +iter_cb(hid_t group, const char *name, const H5L_info_t *info, void *op_data) +{ + printf("Link \"%s\" is a", name); + switch (info->type) { + case H5L_TYPE_HARD: + printf(" hard link.\n"); + break; + case H5L_TYPE_SOFT: + printf(" soft link.\n"); + break; + case H5L_TYPE_EXTERNAL: + printf("n external link.\n"); + break; + default: + printf(" UFO link.\n"); + break; + } + + return 0; +} +//! <!-- [iter_cb] --> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + __label__ fail_link, fail_prop, fail_lcpl, fail_create; + + hid_t file, lcpl; + + if ((file = H5Fcreate("l1.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_create; + } + + // make link creation easier by auto-creating intermediate + // groups and UTF-8 encoding of link names + if ((lcpl = H5Pcreate(H5P_LINK_CREATE)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_lcpl; + } + if (H5Pset_create_intermediate_group(lcpl, 1) < 0 || H5Pset_char_encoding(lcpl, H5T_CSET_UTF8) < 0) { + ret_val = EXIT_FAILURE; + goto fail_prop; + } + + // create a loop by hard linking the root group + if (H5Lcreate_hard(file, ".", file, "√", lcpl, H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + goto fail_link; + } + // create a soft link to nowhere + if (H5Lcreate_soft("e1 62 80 87 04 09 43 ba 02 d3", file, "/path/to/nowhere", lcpl, H5P_DEFAULT) < + 0) { + ret_val = EXIT_FAILURE; + goto fail_link; + } + // create an external link to nowhere in a non-existent file + if (H5Lcreate_external("non-existent-file.h5", "???", file, "external", lcpl, H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + goto fail_link; + } + +fail_link: +fail_prop: + H5Pclose(lcpl); +fail_lcpl: + H5Fclose(file); +fail_create:; + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_iterate, fail_read; + hid_t file; + hsize_t idx = 0; + + if ((file = H5Fopen("l1.h5", H5F_ACC_RDONLY, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_read; + } + + if (H5Literate(file, H5_INDEX_NAME, H5_ITER_NATIVE, &idx, iter_cb, NULL) < 0) { + ret_val = EXIT_FAILURE; + goto fail_iterate; + } + +fail_iterate: + H5Fclose(file); +fail_read:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + __label__ fail_move, fail_update; + hid_t file; + + if ((file = H5Fopen("l1.h5", H5F_ACC_RDWR, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_update; + } + + // move the "√" link to the group at "/path/to" + // the cycle remains! + if (H5Lmove(file, "√", file, "path/to/√", H5P_DEFAULT, H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + goto fail_move; + } + +fail_move: + H5Fclose(file); +fail_update:; + } + //! <!-- [update] --> + + //! <!-- [delete] --> + { + __label__ fail_delete, fail_file; + hid_t file; + + if ((file = H5Fopen("l1.h5", H5F_ACC_RDWR, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + // delete the "external" link + if (H5Ldelete(file, "external", H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + goto fail_delete; + } + +fail_delete: + H5Fclose(file); +fail_file:; + } + //! <!-- [delete] --> + + assert(ret_val == EXIT_SUCCESS); + + return ret_val; +} diff --git a/doxygen/examples/H5O_examples.c b/doxygen/examples/H5O_examples.c new file mode 100644 index 0000000..296acd1 --- /dev/null +++ b/doxygen/examples/H5O_examples.c @@ -0,0 +1,193 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <stdio.h> +#include <stdlib.h> + +#define H5P_DEFAULTx2 H5P_DEFAULT, H5P_DEFAULT + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + __label__ fail_file; + hid_t file, group; + char src_path[] = "/a/few/groups"; + + if ((file = H5Fcreate("o1.h5", H5F_ACC_TRUNC, H5P_DEFAULTx2)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + // create a few groups + { + __label__ fail_group, fail_lcpl; + hid_t lcpl; + if ((lcpl = H5Pcreate(H5P_LINK_CREATE)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_lcpl; + } + if (H5Pset_create_intermediate_group(lcpl, 1) < 0) { + ret_val = EXIT_FAILURE; + goto fail_group; + } + if ((group = H5Gcreate(file, src_path, lcpl, H5P_DEFAULTx2)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_group; + } + + H5Gclose(group); +fail_group: + H5Pclose(lcpl); +fail_lcpl:; + } + + // create a copy + if (H5Ocopy(file, ".", file, "copy of", H5P_DEFAULTx2) < 0) { + ret_val = EXIT_FAILURE; + } + + H5Fclose(file); +fail_file:; + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_info, fail_file; + hid_t file; + char path[] = "/a/few/groups"; + H5O_info2_t info; + + if ((file = H5Fopen("o1.h5", H5F_ACC_RDONLY, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + // retrieve information about the object + if (H5Oget_info_by_name(file, path, &info, H5O_INFO_BASIC | H5O_INFO_NUM_ATTRS, H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + goto fail_info; + } + + // determine the object type + switch (info.type) { + case H5O_TYPE_GROUP: + printf("HDF5 group\n"); + break; + case H5O_TYPE_DATASET: + printf("HDF5 dataset\n"); + break; + case H5O_TYPE_NAMED_DATATYPE: + printf("HDF5 datatype\n"); + break; + default: + printf("UFO?\n"); + break; + } + // print basic information + printf("Reference count: %u\n", info.rc); + printf("Attribute count: %lld\n", info.num_attrs); + +fail_info: + H5Fclose(file); +fail_file:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + __label__ fail_obj, fail_incr, fail_file; + hid_t file, obj; + char path[] = "/a/few/groups"; + H5O_info2_t info; + + if ((file = H5Fopen("o1.h5", H5F_ACC_RDWR, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + // open an object by path name + if ((obj = H5Oopen(file, path, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_obj; + } + + // bump its reference count (by 1) + if (H5Oincr_refcount(obj) < 0) { + ret_val = EXIT_FAILURE; + goto fail_incr; + } + + // confirm the new reference count + if (H5Oget_info(obj, &info, H5O_INFO_BASIC) < 0) { + ret_val = EXIT_FAILURE; + goto fail_incr; + } + printf("Reference count: %u\n", info.rc); + +fail_incr: + H5Oclose(obj); +fail_obj: + H5Fclose(file); +fail_file:; + } + //! <!-- [update] --> + + //! <!-- [delete] --> + { + __label__ fail_obj, fail_delete, fail_file; + hid_t file, obj; + char path[] = "/a/few/groups"; + H5O_info2_t info; + + if ((file = H5Fopen("o1.h5", H5F_ACC_RDWR, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + // open an object by path name + if ((obj = H5Oopen(file, path, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_obj; + } + + // render it inaccessible from the root group by deleting the one and + // only link to it; this drops the reference count by 1 + if (H5Ldelete(file, path, H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + goto fail_delete; + } + + // confirm the new reference count + if (H5Oget_info(obj, &info, H5O_INFO_BASIC) < 0) { + ret_val = EXIT_FAILURE; + goto fail_delete; + } + printf("Reference count: %u\n", info.rc); + + // if we close the file at this point, we'd be creating a tombstone, + // an object that cannot be reached and that cannot be reclaimed by the + // freespace manager; decrement the reference count to zero to prevent that + if (H5Idec_ref(obj) < 0) { + ret_val = EXIT_FAILURE; + goto fail_delete; + } + else + // attempting to close the object would be like a double H5Oclose and fail + goto fail_obj; + +fail_delete: + H5Oclose(obj); +fail_obj: + H5Fclose(file); +fail_file:; + } + //! <!-- [delete] --> + + return ret_val; +} diff --git a/doxygen/examples/H5PL_examples.c b/doxygen/examples/H5PL_examples.c new file mode 100644 index 0000000..d012d1b --- /dev/null +++ b/doxygen/examples/H5PL_examples.c @@ -0,0 +1,97 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + __label__ fail_set; + // enable ONLY filter plugins + if (H5PLset_loading_state(H5PL_FILTER_PLUGIN) < 0) { + ret_val = EXIT_FAILURE; + goto fail_set; + } + + // ensure that "/tmp" is at the front of the search path list + if (H5PLprepend("/tmp") < 0) { + ret_val = EXIT_FAILURE; + } + +fail_set:; + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_read; + unsigned size, mask; + char buf[255]; + + // retrieve the number of entries in the plugin path list + if (H5PLsize(&size) < 0) { + ret_val = EXIT_FAILURE; + goto fail_read; + } + printf("Number of stored plugin paths: %d\n", size); + + // check the plugin state mask + if (H5PLget_loading_state(&mask) < 0) { + ret_val = EXIT_FAILURE; + goto fail_read; + } + printf("Filter plugins %s be loaded.\n", (mask & H5PL_FILTER_PLUGIN) == 1 ? "can" : "can't"); + printf("VOL plugins %s be loaded.\n", (mask & H5PL_VOL_PLUGIN) == 2 ? "can" : "can't"); + + // print the paths in the plugin path list + for (unsigned i = 0; i < size; ++i) { + if (H5PLget(i, buf, 255) < 0) { + ret_val = EXIT_FAILURE; + break; + } + printf("%s\n", buf); + } + +fail_read:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + // replace "/tmp" with something more sensible + if (H5PLreplace("/foo/bar", 0) < 0) { + ret_val = EXIT_FAILURE; + } + } + //! <!-- [update] --> + + //! <!-- [delete] --> + { + __label__ fail_delete; + unsigned size; + + if (H5PLsize(&size) < 0) { + ret_val = EXIT_FAILURE; + goto fail_delete; + } + + // clean out the list of plugin paths + for (int i = size - 1; i >= 0; --i) { + if (H5PLremove(i) < 0) { + ret_val = EXIT_FAILURE; + break; + } + } + +fail_delete:; + } + //! <!-- [delete] --> + + return ret_val; +} diff --git a/doxygen/examples/H5P_examples.c b/doxygen/examples/H5P_examples.c new file mode 100644 index 0000000..cdfc03b --- /dev/null +++ b/doxygen/examples/H5P_examples.c @@ -0,0 +1,227 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + __label__ fail_dcpl; + hid_t dcpl; + + // every property list is created as an instance of a suitable + // property list class + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dcpl; + } + + // ... + + H5Pclose(dcpl); +fail_dcpl:; + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_dcpl, fail_plist_cls_id; + hid_t dcpl, plist_cls_id; + + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dcpl; + } + // to perform introspection on any kind of property list, + // we need to determine its property list class by obtaining a handle + if ((plist_cls_id = H5Pget_class(dcpl)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_plist_cls_id; + } + // Compare the handle to the handles of built-in or user-defined + // property list classes + assert(H5Pequal(plist_cls_id, H5P_DATASET_CREATE) > 0); + +fail_plist_cls_id: + H5Pclose(dcpl); +fail_dcpl:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + __label__ fail_dcpl, fail_prop; + hid_t dcpl; + + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dcpl; + } + + // a property list is updated by adding (or removing) properties + if (H5Pset_fill_time(dcpl, H5D_FILL_TIME_NEVER) < 0) { + ret_val = EXIT_FAILURE; + goto fail_prop; + } + +fail_prop: + H5Pclose(dcpl); +fail_dcpl:; + } + //! <!-- [update] --> + + //! <!-- [delete] --> + { + __label__ fail_dcpl; + hid_t dcpl; + + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dcpl; + } + + // a property list is "deleted" by closing it + H5Pclose(dcpl); +fail_dcpl:; + } + //! <!-- [delete] --> + + //! <!-- [create_class] --> + { + __label__ fail_cls, fail_prop; + hid_t plist_cls, plist; + int izero = 0; + double dzero = 0.0; + + // create a new property list class + if ((plist_cls = H5Pcreate_class(H5P_ROOT, "int & double", NULL, NULL, NULL, NULL, NULL, NULL)) == + H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_cls; + } + // add a permanent integer property + if (H5Pregister2(plist_cls, "int", sizeof(int), &izero, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < + 0) { + ret_val = EXIT_FAILURE; + goto fail_prop; + } + // add a permanent double property + if (H5Pregister2(plist_cls, "double", sizeof(double), &dzero, NULL, NULL, NULL, NULL, NULL, NULL, + NULL) < 0) { + ret_val = EXIT_FAILURE; + goto fail_prop; + } + // create an instance of this user-defined property list class + if ((plist = H5Pcreate(plist_cls)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_prop; + } + + // ... + + H5Pclose(plist); +fail_prop: + H5Pclose_class(plist_cls); +fail_cls:; + } + //! <!-- [create_class] --> + + //! <!-- [read_class] --> + { + __label__ fail_cls, fail_prop, fail_plist; + hid_t plist_cls, plist; + size_t nprops; + + if ((plist_cls = H5Pcreate_class(H5P_ROOT, "ud_plist", NULL, NULL, NULL, NULL, NULL, NULL)) == + H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_cls; + } + if ((plist = H5Pcreate(plist_cls)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_prop; + } + if (H5Pinsert2(plist, "temp", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) { + ret_val = EXIT_FAILURE; + goto fail_plist; + } + // count the registered properties of this class + if (H5Pget_nprops(plist_cls, &nprops) < 0) { + ret_val = EXIT_FAILURE; + goto fail_plist; + } + // this will be 0 as there are no registered properties + printf("Property list class has %lu registered properties.\n", nprops); + + // count the properties in this property list + if (H5Pget_nprops(plist, &nprops) < 0) { + ret_val = EXIT_FAILURE; + goto fail_plist; + } + // will be 1 as there is one temporary property + printf("Property list has %lu property.\n", nprops); + +fail_plist: + H5Pclose(plist); +fail_prop: + H5Pclose_class(plist_cls); +fail_cls:; + } + //! <!-- [read_class] --> + + //! <!-- [update_class] --> + { + __label__ fail_cls, fail_prop, fail_plist; + hid_t plist_cls, plist; + + if ((plist_cls = H5Pcreate_class(H5P_ROOT, "ud_plist", NULL, NULL, NULL, NULL, NULL, NULL)) == + H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_cls; + } + // create an instance of this user-defined property list class + if ((plist = H5Pcreate(plist_cls)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_prop; + } + // insert a temporary property + if (H5Pinsert2(plist, "temp", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) { + ret_val = EXIT_FAILURE; + goto fail_plist; + } + +fail_plist: + H5Pclose(plist); +fail_prop: + H5Pclose_class(plist_cls); +fail_cls:; + } + //! <!-- [update_class] --> + + //! <!-- [delete_class] --> + { + __label__ fail_cls; + hid_t plist_cls; + + if ((plist_cls = H5Pcreate_class(H5P_ROOT, "int & double", NULL, NULL, NULL, NULL, NULL, NULL)) == + H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_cls; + } + // ... + + // a user defined property list class is destroyed by closing the handle + H5Pclose_class(plist_cls); +fail_cls:; + } + //! <!-- [delete_class] --> + + return ret_val; +} diff --git a/doxygen/examples/H5R_examples.c b/doxygen/examples/H5R_examples.c new file mode 100644 index 0000000..b40b992 --- /dev/null +++ b/doxygen/examples/H5R_examples.c @@ -0,0 +1,171 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + __label__ fail_file, fail_fspace, fail_dset, fail_sel, fail_aspace, fail_attr, fail_awrite; + hid_t file, fspace, dset, aspace, attr; + H5R_ref_t ref; + + if ((file = H5Fcreate("reference.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + // create a region reference which selects all elements of the dataset at "/data" + if ((fspace = H5Screate_simple(2, (hsize_t[]){10, 20}, NULL)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_fspace; + } + if ((dset = H5Dcreate(file, "data", H5T_STD_I32LE, fspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) == + H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dset; + } + if (H5Sselect_all(fspace) < 0 || H5Rcreate_region(file, "data", fspace, H5P_DEFAULT, &ref) < 0) { + ret_val = EXIT_FAILURE; + goto fail_sel; + } + // store the region reference in a scalar attribute of the root group called "region" + if ((aspace = H5Screate(H5S_SCALAR)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_aspace; + } + if ((attr = H5Acreate(file, "region", H5T_STD_REF, aspace, H5P_DEFAULT, H5P_DEFAULT)) == + H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_attr; + } + if (H5Awrite(attr, H5T_STD_REF, &ref) < 0) { + ret_val = EXIT_FAILURE; + goto fail_awrite; + } + +fail_awrite: + H5Aclose(attr); +fail_attr: + H5Sclose(aspace); +fail_aspace: + H5Rdestroy(&ref); +fail_sel: + H5Dclose(dset); +fail_dset: + H5Sclose(fspace); +fail_fspace: + H5Fclose(file); +fail_file:; + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_file, fail_attr, fail_aread; + hid_t file, attr; + H5R_ref_t ref; + + if ((file = H5Fopen("reference.h5", H5F_ACC_RDONLY, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + // read the dataset region reference from the attribute + if ((attr = H5Aopen(file, "region", H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_attr; + } + if (H5Aread(attr, H5T_STD_REF, &ref) < 0) { + ret_val = EXIT_FAILURE; + goto fail_aread; + } + assert(H5Rget_type(&ref) == H5R_DATASET_REGION2); + + // get an HDF5 path name for the dataset of the region reference + { + char buf[255]; + if (H5Rget_obj_name(&ref, H5P_DEFAULT, buf, 255) < 0) { + ret_val = EXIT_FAILURE; + } + printf("Object name: \"%s\"\n", buf); + } + + H5Rdestroy(&ref); +fail_aread: + H5Aclose(attr); +fail_attr: + H5Fclose(file); +fail_file:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + __label__ fail_file, fail_attr, fail_ref; + hid_t file, attr; + H5R_ref_t ref; + + if ((file = H5Fopen("reference.h5", H5F_ACC_RDWR, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + // H5T_STD_REF is a generic reference type + // we can "update" the attribute value to refer to the attribute itself + if ((attr = H5Aopen(file, "region", H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_attr; + } + if (H5Rcreate_attr(file, "data", "region", H5P_DEFAULT, &ref) < 0) { + ret_val = EXIT_FAILURE; + goto fail_ref; + } + + assert(H5Rget_type(&ref) == H5R_ATTR); + + if (H5Awrite(attr, H5T_STD_REF, &ref) < 0) { + ret_val = EXIT_FAILURE; + } + + H5Rdestroy(&ref); +fail_ref: + H5Aclose(attr); +fail_attr: + H5Fclose(file); +fail_file:; + } + //! <!-- [update] --> + + //! <!-- [delete] --> + { + __label__ fail_file, fail_ref; + hid_t file; + H5R_ref_t ref; + + // create an HDF5 object reference to the root group + if ((file = H5Fopen("reference.h5", H5F_ACC_RDONLY, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + if (H5Rcreate_object(file, ".", H5P_DEFAULT, &ref) < 0) { + ret_val = EXIT_FAILURE; + goto fail_ref; + } + + // H5Rdestroy() releases all resources associated with an HDF5 reference + H5Rdestroy(&ref); +fail_ref: + H5Fclose(file); +fail_file:; + } + //! <!-- [delete] --> + + return ret_val; +} diff --git a/doxygen/examples/H5S_examples.c b/doxygen/examples/H5S_examples.c new file mode 100644 index 0000000..c542ec0 --- /dev/null +++ b/doxygen/examples/H5S_examples.c @@ -0,0 +1,132 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + __label__ fail_dspace; + hid_t dspace; + + // create a 2D chess board shape (8x8) + if ((dspace = H5Screate_simple(2, (hsize_t[]){8, 8}, NULL)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dspace; + } + + H5Sclose(dspace); +fail_dspace:; + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_dspace; + hid_t dspace; + + if ((dspace = H5Screate(H5S_NULL)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dspace; + } + + // make changes to the selection on DSPACE + // ... + // parse the resulting selection + + switch (H5Sget_select_type(dspace)) { + case H5S_SEL_HYPERSLABS: + // we are dealing with a hyperslab selection + // determine the regularity and block structure + break; + case H5S_SEL_POINTS: + // we are dealing with a point selection + // for example, retrieve the point list + break; + case H5S_SEL_ALL: + // all dataset elements are selected + break; + case H5S_SEL_NONE: + // the selection is empty + break; + default: + ret_val = EXIT_FAILURE; + break; + } + + if (dspace != H5S_ALL) + H5Sclose(dspace); + +fail_dspace:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + __label__ fail_select, fail_dspace; + hid_t dspace; + + // create a 2D chess board shape (8x8) + if ((dspace = H5Screate_simple(2, (hsize_t[]){8, 8}, NULL)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dspace; + } + // select all black fields: do this w/ a hyperslab union in two steps + + // select the black fields on even rows + if (H5Sselect_hyperslab(dspace, H5S_SELECT_SET, (hsize_t[]){0, 0}, (hsize_t[]){2, 2}, + (hsize_t[]){4, 4}, NULL) < 0) { + ret_val = EXIT_FAILURE; + goto fail_select; + } + // select the black fields on odd rows + // notice the H5S_SELECT_OR operator + if (H5Sselect_hyperslab(dspace, H5S_SELECT_OR, (hsize_t[]){1, 1}, (hsize_t[]){2, 2}, + (hsize_t[]){4, 4}, NULL) < 0) { + ret_val = EXIT_FAILURE; + goto fail_select; + } + + // should be 32 + printf("%lld elements selected.\n", H5Sget_select_npoints(dspace)); + +fail_select: + H5Sclose(dspace); +fail_dspace:; + } + //! <!-- [update] --> + + //! <!-- [delete] --> + { + __label__ fail_select, fail_dspace; + hid_t dspace; + + if ((dspace = H5Screate(H5S_NULL)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dspace; + } + + // make changes to and work with the selection on DSPACE + // ... + // finally, clear the selection + + if (H5Sselect_none(dspace) < 0) { + ret_val = EXIT_FAILURE; + goto fail_select; + } + +fail_select: + if (dspace != H5S_ALL) + H5Sclose(dspace); +fail_dspace:; + } + //! <!-- [delete] --> + + return ret_val; +} diff --git a/doxygen/examples/H5T_examples.c b/doxygen/examples/H5T_examples.c new file mode 100644 index 0000000..7cfa7d4 --- /dev/null +++ b/doxygen/examples/H5T_examples.c @@ -0,0 +1,136 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + __label__ fail_insert, fail_dtype, fail_file; + hid_t file, dtype; + + if ((file = H5Fcreate("t1.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + // create a compound datatype with room for real and imaginary parts + if ((dtype = H5Tcreate(H5T_COMPOUND, 2 * sizeof(double))) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dtype; + } + // add the real part now and the imaginary part later + if (H5Tinsert(dtype, "re", 0, H5T_IEEE_F64LE) < 0) { + ret_val = EXIT_FAILURE; + goto fail_insert; + } + // commit the datatype definition to the file + if (H5Tcommit(file, "pre-complex", dtype, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + } + +fail_insert: + H5Tclose(dtype); +fail_dtype: + H5Fclose(file); +fail_file:; + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_dtype, fail_file; + hid_t file, dtype; + + if ((file = H5Fopen("t1.h5", H5F_ACC_RDONLY, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + // open the datatype object stored in the file + if ((dtype = H5Topen(file, "pre-complex", H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dtype; + } + + switch (H5Tget_class(dtype)) { // this time we are only interested in compounds + case H5T_COMPOUND: + printf("Record size: %lu bytes\n", H5Tget_size(dtype)); + printf("Record has %d field(s).\n", H5Tget_nmembers(dtype)); + break; + default: + break; + } + + H5Tclose(dtype); +fail_dtype: + H5Fclose(file); +fail_file:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + __label__ fail_insert, fail_clone, fail_dtype, fail_file; + hid_t file, dtype, clone; + + if ((file = H5Fopen("t1.h5", H5F_ACC_RDWR, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + // open the datatype object stored in the file + if ((dtype = H5Topen(file, "pre-complex", H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dtype; + } + // the original datatype object is immutable and we need to clone it + if ((clone = H5Tcopy(dtype)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_clone; + } + // remember that the original has enough room for real and imaginary parts + // add the imaginary part + if (H5Tinsert(clone, "im", sizeof(double), H5T_IEEE_F64LE) < 0) { + ret_val = EXIT_FAILURE; + goto fail_insert; + } + // commit the "updated" datatype definition to the file + if (H5Tcommit(file, "complex", clone, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + } + +fail_insert: + H5Tclose(clone); +fail_clone: + H5Tclose(dtype); +fail_dtype: + H5Fclose(file); +fail_file:; + } + //! <!-- [update] --> + + //! <!-- [delete] --> + { + __label__ fail_file; + hid_t file; + + if ((file = H5Fopen("t1.h5", H5F_ACC_RDWR, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + // delete the "pre-complex" datatype by unlinking + if (H5Ldelete(file, "pre-complex", H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + } + + H5Fclose(file); +fail_file:; + } + //! <!-- [delete] --> + + return ret_val; +} diff --git a/doxygen/examples/H5Z_examples.c b/doxygen/examples/H5Z_examples.c new file mode 100644 index 0000000..28a1ea2 --- /dev/null +++ b/doxygen/examples/H5Z_examples.c @@ -0,0 +1,108 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +//! <!-- [filter] --> +size_t +filter(unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[], size_t nbytes, size_t *buf_size, + void **buf) +{ + buf_size = 0; + + if (flags & H5Z_FLAG_REVERSE) { + // read data, e.g., decompress data + // ... + } + else { + // write data, e.g., compress data + // ... + } + + return nbytes; +} +//! <!-- [filter] --> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + __label__ fail_register; + H5Z_class_t cls; + cls.version = H5Z_CLASS_T_VERS; + cls.id = 256; + cls.encoder_present = 1; + cls.decoder_present = 1; + cls.name = "Identity filter"; + cls.can_apply = NULL; + cls.set_local = NULL; + cls.filter = &filter; + + // register the filter + if (H5Zregister(&cls) < 0) { + ret_val = EXIT_FAILURE; + goto fail_register; + } + + // do something with filter + // ... + + // unregister the filter if no longer required + // ... + +fail_register:; + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_avail; + + H5Z_filter_t flt = H5Z_FILTER_DEFLATE; + unsigned flags = 0; + + // check if the deflate filter is available + if (H5Zfilter_avail(flt) < 0) { + ret_val = EXIT_FAILURE; + goto fail_avail; + } + // retrieve the deflate filter info + if (H5Zget_filter_info(flt, &flags) < 0) { + ret_val = EXIT_FAILURE; + goto fail_avail; + } + + // check if the deflate encoder or decoder is enabled + if (H5Z_FILTER_CONFIG_ENCODE_ENABLED & flags) + printf("Deflate encoder enabled.\n"); + if (H5Z_FILTER_CONFIG_DECODE_ENABLED & flags) + printf("Deflate decoder enabled.\n"); + +fail_avail:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + // N/A + } //! <!-- [update] --> + + //! <!-- [delete] --> + { + // unregister the identity filter + if (H5Zunregister(256) < 0) { + ret_val = EXIT_FAILURE; + } + } + //! <!-- [delete] --> + + assert(ret_val == EXIT_SUCCESS); + + return ret_val; +} diff --git a/doxygen/examples/H5_examples.c b/doxygen/examples/H5_examples.c new file mode 100644 index 0000000..ef52ed0 --- /dev/null +++ b/doxygen/examples/H5_examples.c @@ -0,0 +1,85 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +//! <!-- [closing_shop] --> +void +closing_shop(void *ctx) +{ + printf("GoodBye, Cruel World!\n"); +} +//! <!-- [closing_shop] --> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + // an HDF5 library instance is automatically initialized as + // part of the first HDF5 API call, but there's no harm in + // calling H5open(). + if (H5open() < 0) { + ret_val = EXIT_FAILURE; + } + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_read; + unsigned majnum, minnum, relnum; + hbool_t flag; + + // retrieve the library version + if (H5get_libversion(&majnum, &minnum, &relnum) < 0) { + ret_val = EXIT_FAILURE; + goto fail_read; + } + // is this a thread-safe library build? + if (H5is_library_threadsafe(&flag) < 0) { + ret_val = EXIT_FAILURE; + goto fail_read; + } + + printf("Welcome to HDF5 %d.%d.%d\n", majnum, minnum, relnum); + printf("Thread-safety %s\n", (flag > 0) ? "enabled" : "disabled"); + +fail_read:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + // update the library instance free list limits + if (H5set_free_list_limits(512 * 1024, 32 * 1024, 2048 * 1024, 128 * 1024, 8192 * 1024, 512 * 1024) < + 0) { + ret_val = EXIT_FAILURE; + } + } + //! <!-- [update] --> + + //! <!-- [delete] --> + { +#if H5_VERSION_GE(1, 13, 0) + // install a finalization routine + if (H5atclose(&closing_shop, NULL) < 0) { + ret_val = EXIT_FAILURE; + } +#endif + // close shop + if (H5close() < 0) { + ret_val = EXIT_FAILURE; + } + } + //! <!-- [delete] --> + + assert(ret_val == EXIT_SUCCESS); + + return ret_val; +} diff --git a/doxygen/hdf5_header.html b/doxygen/hdf5_header.html index 4a575d6..23f41f9 100644 --- a/doxygen/hdf5_header.html +++ b/doxygen/hdf5_header.html @@ -21,7 +21,7 @@ $mathjax </head> <body> -<div style="background:#FFDDDD;font-size:120%;text-align:center;margin:0;padding:5px">Please, help us to better know about our user community by answering the following short survey: <a href="https://www.hdfgroup.org/">https://www.hdfgroup.org/</a></div> +<div style="background:#FFDDDD;font-size:120%;text-align:center;margin:0;padding:5px">Please, help us to better know about our user community by answering the following short survey: <a href="https://www.hdfgroup.org/website-survey/">https://www.hdfgroup.org/website-survey/</a></div> <div id="top"><!-- do not remove this div, it is closed by doxygen! --> diff --git a/doxygen/hdf5doxy_layout.xml b/doxygen/hdf5doxy_layout.xml index 7f71c24..fc20aa1 100644 --- a/doxygen/hdf5doxy_layout.xml +++ b/doxygen/hdf5doxy_layout.xml @@ -11,6 +11,7 @@ <tab type="user" url="@ref RM" title="Reference Manual" /> <tab type="user" url="@ref TN" title="Technical Notes" /> <tab type="user" url="@ref SPEC" title="Specifications" /> + <tab type="user" url="@ref RFC" title="RFCs" /> <tab type="user" url="@ref About" title="About" /> </navindex> diff --git a/examples/CMakeTests.cmake b/examples/CMakeTests.cmake index b422078..70142c8 100644 --- a/examples/CMakeTests.cmake +++ b/examples/CMakeTests.cmake @@ -98,11 +98,14 @@ endif () ### Windows pops up a modal permission dialog on this test if (H5_HAVE_PARALLEL AND HDF5_TEST_PARALLEL AND NOT WIN32) + # Ensure that 24 is a multiple of the number of processes. + # The number 24 corresponds to SPACE1_DIM1 and SPACE1_DIM2 defined in ph5example.c + math(EXPR NUMPROCS "24 / ((24 + ${MPIEXEC_MAX_NUMPROCS} - 1) / ${MPIEXEC_MAX_NUMPROCS})") if (HDF5_ENABLE_USING_MEMCHECKER) - add_test (NAME MPI_TEST_EXAMPLES-ph5example COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $<TARGET_FILE:ph5example> ${MPIEXEC_POSTFLAGS}) + add_test (NAME MPI_TEST_EXAMPLES-ph5example COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${NUMPROCS} ${MPIEXEC_PREFLAGS} $<TARGET_FILE:ph5example> ${MPIEXEC_POSTFLAGS}) else () add_test (NAME MPI_TEST_EXAMPLES-ph5example COMMAND "${CMAKE_COMMAND}" - -D "TEST_PROGRAM=${MPIEXEC_EXECUTABLE};${MPIEXEC_NUMPROC_FLAG};${MPIEXEC_MAX_NUMPROCS};${MPIEXEC_PREFLAGS};$<TARGET_FILE:ph5example>;${MPIEXEC_POSTFLAGS}" + -D "TEST_PROGRAM=${MPIEXEC_EXECUTABLE};${MPIEXEC_NUMPROC_FLAG};${NUMPROCS};${MPIEXEC_PREFLAGS};$<TARGET_FILE:ph5example>;${MPIEXEC_POSTFLAGS}" -D "TEST_ARGS:STRING=" -D "TEST_EXPECT=0" -D "TEST_OUTPUT=ph5example.out" diff --git a/fortran/src/CMakeLists.txt b/fortran/src/CMakeLists.txt index e59a829..316d3c7 100644 --- a/fortran/src/CMakeLists.txt +++ b/fortran/src/CMakeLists.txt @@ -582,4 +582,17 @@ if (NOT WIN32 AND NOT MINGW) PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE COMPONENT fortlibraries ) + if (HDF5_ENABLE_PARALLEL AND MPI_Fortran_FOUND) + configure_file ( + ${HDF_RESOURCES_DIR}/libh5cc.in + ${HDF5_BINARY_DIR}/CMakeFiles/h5pfc + @ONLY + ) + install ( + FILES ${HDF5_BINARY_DIR}/CMakeFiles/h5pfc + DESTINATION ${HDF5_INSTALL_BIN_DIR} + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE + COMPONENT fortlibraries + ) + endif () endif () diff --git a/fortran/src/H5Fff.F90 b/fortran/src/H5Fff.F90 index f772558..a273431 100644 --- a/fortran/src/H5Fff.F90 +++ b/fortran/src/H5Fff.F90 @@ -824,7 +824,7 @@ CONTAINS SUBROUTINE h5fget_name_f(obj_id, buf, size, hdferr) IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: obj_id ! Object identifier - CHARACTER(LEN=*), INTENT(INOUT) :: buf + CHARACTER(LEN=*), INTENT(OUT) :: buf ! Buffer to hold file name INTEGER(SIZE_T), INTENT(OUT) :: size ! Size of the file name INTEGER, INTENT(OUT) :: hdferr ! Error code: 0 on success, @@ -844,7 +844,7 @@ CONTAINS CHARACTER(KIND=C_CHAR), DIMENSION(*), INTENT(OUT) :: buf END FUNCTION h5fget_name_c END INTERFACE - buflen = LEN_TRIM(buf) + buflen = LEN(buf) hdferr = h5fget_name_c(obj_id, size, buf, buflen) END SUBROUTINE h5fget_name_f !****s* H5F/h5fget_filesize_f diff --git a/fortran/test/fortranlib_test.F90 b/fortran/test/fortranlib_test.F90 index eff4657..1640a8f 100644 --- a/fortran/test/fortranlib_test.F90 +++ b/fortran/test/fortranlib_test.F90 @@ -74,6 +74,10 @@ PROGRAM fortranlibtest CALL write_test_status(ret_total_error, ' Reopen test', total_error) ret_total_error = 0 + CALL get_name_test(cleanup, ret_total_error) + CALL write_test_status(ret_total_error, ' Get name test', total_error) + + ret_total_error = 0 CALL file_close(cleanup, ret_total_error) CALL write_test_status(ret_total_error, ' File open/close test', total_error) diff --git a/fortran/test/tH5F.F90 b/fortran/test/tH5F.F90 index f4a3232..06dc6de 100644 --- a/fortran/test/tH5F.F90 +++ b/fortran/test/tH5F.F90 @@ -21,7 +21,8 @@ ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ! ! CONTAINS SUBROUTINES -! mountingtest, reopentest, plisttest, file_close, file_space +! mountingtest, reopentest, get_name_test, plisttest, +! file_close, file_space ! !***** ! @@ -580,6 +581,125 @@ CONTAINS END SUBROUTINE reopentest +! The following subroutine checks that h5fget_name_f produces +! correct output for a given obj_id and filename. +! + SUBROUTINE check_get_name(obj_id, fix_filename, total_error) + USE HDF5 ! This module contains all necessary modules + USE TH5_MISC + IMPLICIT NONE + INTEGER(HID_T) :: obj_id ! Object identifier + CHARACTER(LEN=80), INTENT(IN) :: fix_filename ! Expected filename + INTEGER, INTENT(INOUT) :: total_error ! Error count + + CHARACTER(LEN=80):: file_name ! Filename buffer + INTEGER:: error ! HDF5 error code + INTEGER(SIZE_T):: name_size ! Filename length + ! + !Get file name from the dataset identifier + ! + + ! Use an uninitialized buffer + CALL h5fget_name_f(obj_id, file_name, name_size, error) + CALL check("h5fget_name_f",error,total_error) + IF(name_size .NE. LEN_TRIM(fix_filename))THEN + WRITE(*,*) " file name size obtained from the object id is incorrect" + total_error = total_error + 1 + ENDIF + IF(file_name(1:name_size) .NE. TRIM(fix_filename)) THEN + WRITE(*,*) " file name obtained from the object id is incorrect" + total_error = total_error + 1 + END IF + + ! Use a buffer initialized with spaces + file_name(:) = " " + CALL h5fget_name_f(obj_id, file_name, name_size, error) + CALL check("h5fget_name_f",error,total_error) + IF(name_size .NE. LEN_TRIM(fix_filename))THEN + WRITE(*,*) " file name size obtained from the object id is incorrect" + total_error = total_error + 1 + ENDIF + IF(file_name(1:name_size) .NE. TRIM(fix_filename)) THEN + WRITE(*,*) " file name obtained from the object id is incorrect" + total_error = total_error + 1 + END IF + + ! Use a buffer initialized with non-whitespace characters + file_name(:) = "a" + CALL h5fget_name_f(obj_id, file_name, name_size, error) + CALL check("h5fget_name_f",error,total_error) + IF(name_size .NE. LEN_TRIM(fix_filename))THEN + WRITE(*,*) " file name size obtained from the object id is incorrect" + total_error = total_error + 1 + ENDIF + IF(file_name(1:name_size) .NE. TRIM(fix_filename)) THEN + WRITE(*,*) " file name obtained from the object id is incorrect" + total_error = total_error + 1 + END IF + + END SUBROUTINE check_get_name + +! The following subroutine tests h5fget_name_f. +! It creates the file which has name "filename.h5" and +! tests that h5fget_name_f also returns the name "filename.h5" +! + + SUBROUTINE get_name_test(cleanup, total_error) + USE HDF5 ! This module contains all necessary modules + USE TH5_MISC + IMPLICIT NONE + LOGICAL, INTENT(IN) :: cleanup + INTEGER, INTENT(INOUT) :: total_error + + CHARACTER(LEN=*), PARAMETER :: filename = "filename" + CHARACTER(LEN=80) :: fix_filename + + INTEGER(HID_T) :: file_id ! File identifier + INTEGER(HID_T) :: g_id ! Group identifier + + ! + ! Flag to check operation success + ! + INTEGER :: error + + ! + ! Create file "filename.h5" using default properties. + ! + CALL h5_fixname_f(filename, fix_filename, H5P_DEFAULT_F, error) + IF (error .NE. 0) THEN + WRITE(*,*) "Cannot modify filename" + STOP + ENDIF + CALL h5fcreate_f(fix_filename, H5F_ACC_TRUNC_F, file_id, error) + CALL check("h5fcreate_f",error,total_error) + + ! + ! Create group. + ! + CALL h5gopen_f(file_id,"/",g_id, error) + CALL check("h5gopen_f",error,total_error) + + CALL check_get_name(file_id, fix_filename, total_error) + CALL check_get_name(g_id, fix_filename, total_error) + + ! Close the group. + ! + CALL h5gclose_f(g_id, error) + CALL check("h5gclose_f",error,total_error) + + ! + ! Close the file identifiers. + ! + CALL h5fclose_f(file_id, error) + CALL check("h5fclose_f",error,total_error) + + IF(cleanup) CALL h5_cleanup_f(filename, H5P_DEFAULT_F, error) + CALL check("h5_cleanup_f", error, total_error) + RETURN + + END SUBROUTINE get_name_test + + ! ! The following example demonstrates how to get creation property list, ! and access property list. diff --git a/fortran/test/tH5Z.F90 b/fortran/test/tH5Z.F90 index 0eaa941..8c39fea 100644 --- a/fortran/test/tH5Z.F90 +++ b/fortran/test/tH5Z.F90 @@ -192,7 +192,8 @@ CONTAINS INTEGER(HSIZE_T), DIMENSION(2) :: chunk_dims = (/NN, MM/) INTEGER :: rank = 2 ! Dataset rank - INTEGER, DIMENSION(N,M) :: dset_data, data_out ! Data buffers + INTEGER, DIMENSION(N,M) :: dset_data ! Data buffers + INTEGER, DIMENSION(:,:), ALLOCATABLE :: data_out ! Data buffers INTEGER :: error ! Error flag INTEGER :: num_errors = 0 ! Number of data errors @@ -363,8 +364,9 @@ CONTAINS ! ! Read the dataset. ! + ALLOCATE(data_out(1:N,1:M)) CALL h5dread_f (dset_id, H5T_NATIVE_INTEGER, data_out, data_dims, error) - CALL check("h5dread_f", error, total_error) + CALL check("h5dread_f", error, total_error) ! !Compare the data. @@ -385,6 +387,7 @@ CONTAINS 100 IF (num_errors .GT. 0) THEN total_error=total_error + 1 END IF + DEALLOCATE(data_out) ! ! End access to the dataset and release resources used by it. diff --git a/hl/CMakeLists.txt b/hl/CMakeLists.txt index 083c60e..5061c6c 100644 --- a/hl/CMakeLists.txt +++ b/hl/CMakeLists.txt @@ -7,9 +7,17 @@ project (HDF5_HL C) add_subdirectory (src) -#-- Build the High level Tools +# Build HDF5 Tools if (HDF5_BUILD_TOOLS) - add_subdirectory (tools) + #----------------------------------------------------------------------------- + #-- Option to build the High level Tools + #----------------------------------------------------------------------------- + if (EXISTS "${HDF5_HL_SOURCE_DIR}/tools" AND IS_DIRECTORY "${HDF5_HL_SOURCE_DIR}/tools") + option (HDF5_BUILD_HL_TOOLS "Build HDF5 HL Tools" ON) + if (HDF5_BUILD_HL_TOOLS) + add_subdirectory (tools) + endif () + endif () endif () #-- Add High Level Examples diff --git a/hl/Makefile.am b/hl/Makefile.am index 9bf209e..8c427d3 100644 --- a/hl/Makefile.am +++ b/hl/Makefile.am @@ -37,16 +37,19 @@ else TEST_DIR = endif if BUILD_TOOLS_CONDITIONAL +if BUILD_TOOLS_HL_CONDITIONAL TOOLS_DIR = tools else TOOLS_DIR = endif +else + TOOLS_DIR = +endif ## Don't recurse into any subdirectories if HDF5 is not configured to ## use the HL library if BUILD_HDF5_HL_CONDITIONAL SUBDIRS=src $(TEST_DIR) $(TOOLS_DIR) $(CXX_DIR) $(FORTRAN_DIR) - endif DIST_SUBDIRS=src test tools c++ fortran examples diff --git a/hl/c++/src/H5PacketTable.cpp b/hl/c++/src/H5PacketTable.cpp index 2908626..086c702 100644 --- a/hl/c++/src/H5PacketTable.cpp +++ b/hl/c++/src/H5PacketTable.cpp @@ -62,12 +62,9 @@ PacketTable::~PacketTable() * any trouble making or opening the packet table. */ bool -PacketTable::IsValid() +PacketTable::IsValid() const { - if (H5PTis_valid(table_id) == 0) - return true; - else - return false; + return H5PTis_valid(table_id) == 0; } /* IsVariableLength @@ -75,7 +72,7 @@ PacketTable::IsValid() * and 0, otherwise. Returns -1 if the table is invalid (not open). */ int -PacketTable::IsVariableLength() +PacketTable::IsVariableLength() const { return H5PTis_varlen(table_id); } @@ -84,7 +81,7 @@ PacketTable::IsVariableLength() * Sets the index to point to the first packet in the packet table */ void -PacketTable::ResetIndex() +PacketTable::ResetIndex() const { H5PTcreate_index(table_id); } @@ -94,7 +91,7 @@ PacketTable::ResetIndex() * Returns 0 on success, negative on failure (if index is out of bounds) */ int -PacketTable::SetIndex(hsize_t index) +PacketTable::SetIndex(hsize_t index) const { return H5PTset_index(table_id, index); } @@ -104,7 +101,7 @@ PacketTable::SetIndex(hsize_t index) * Returns 0 on success, negative on failure (if index is out of bounds) */ hsize_t -PacketTable::GetIndex(int &error) +PacketTable::GetIndex(int &error) const { hsize_t index; @@ -121,7 +118,7 @@ PacketTable::GetIndex(int &error) * error is set to negative. */ hsize_t -PacketTable::GetPacketCount(int &error) +PacketTable::GetPacketCount(int &error) const { hsize_t npackets; @@ -133,7 +130,7 @@ PacketTable::GetPacketCount(int &error) * Returns the identifier of the packet table */ hid_t -PacketTable::GetTableId() +PacketTable::GetTableId() const { return table_id; } @@ -145,7 +142,7 @@ PacketTable::GetTableId() * the desired functionality cannot be performed via the packet table ID. */ hid_t -PacketTable::GetDatatype() +PacketTable::GetDatatype() const { return H5PTget_type(table_id); } @@ -157,7 +154,7 @@ PacketTable::GetDatatype() * the desired functionality cannot be performed via the packet table ID. */ hid_t -PacketTable::GetDataset() +PacketTable::GetDataset() const { return H5PTget_dataset(table_id); } @@ -169,7 +166,7 @@ PacketTable::GetDataset() * Returns 0 on success, negative on error. */ int -PacketTable::FreeBuff(size_t numStructs, hvl_t *buffer) +PacketTable::FreeBuff(size_t numStructs, hvl_t *buffer) const { return H5PTfree_vlen_buff(table_id, numStructs, buffer); } diff --git a/hl/c++/src/H5PacketTable.h b/hl/c++/src/H5PacketTable.h index eae66f1..c1f1eb5 100644 --- a/hl/c++/src/H5PacketTable.h +++ b/hl/c++/src/H5PacketTable.h @@ -54,39 +54,39 @@ class H5_HLCPPDLL PacketTable { * Use this after the constructor to ensure HDF did not have * any trouble making or opening the packet table. */ - bool IsValid(); + bool IsValid() const; /* IsVariableLength * Return 1 if this packet table uses variable-length datatype, * return 0 if it is Fixed Length. Returns -1 if the table is * invalid (not open). */ - int IsVariableLength(); + int IsVariableLength() const; /* ResetIndex * Sets the "current packet" index to point to the first packet in the * packet table */ - void ResetIndex(); + void ResetIndex() const; /* SetIndex * Sets the current packet to point to the packet specified by index. * Returns 0 on success, negative on failure (if index is out of bounds) */ - int SetIndex(hsize_t index); + int SetIndex(hsize_t index) const; /* GetIndex * Returns the position of the current packet. * On failure, returns 0 and error is set to negative. */ - hsize_t GetIndex(int &error); + hsize_t GetIndex(int &error) const; /* GetPacketCount * Returns the number of packets in the packet table. Error * is set to 0 on success. On failure, returns 0 and * error is set to negative. */ - hsize_t GetPacketCount(int &error); + hsize_t GetPacketCount(int &error) const; hsize_t GetPacketCount() @@ -98,7 +98,7 @@ class H5_HLCPPDLL PacketTable { /* GetTableId * Returns the identifier of the packet table. */ - hid_t GetTableId(); + hid_t GetTableId() const; /* GetDatatype * Returns the datatype identifier used by the packet table, on success, @@ -106,7 +106,7 @@ class H5_HLCPPDLL PacketTable { * Note: it is best to avoid using this identifier in applications, unless * the desired functionality cannot be performed via the packet table ID. */ - hid_t GetDatatype(); + hid_t GetDatatype() const; /* GetDataset * Returns the dataset identifier associated with the packet table, on @@ -114,7 +114,7 @@ class H5_HLCPPDLL PacketTable { * Note: it is best to avoid using this identifier in applications, unless * the desired functionality cannot be performed via the packet table ID. */ - hid_t GetDataset(); + hid_t GetDataset() const; /* FreeBuff * Frees the buffers created when variable-length packets are read. @@ -122,7 +122,7 @@ class H5_HLCPPDLL PacketTable { * location in memory. * Returns 0 on success, negative on error. */ - int FreeBuff(size_t numStructs, hvl_t *buffer); + int FreeBuff(size_t numStructs, hvl_t *buffer) const; protected: hid_t table_id; diff --git a/hl/c++/test/ptableTest.cpp b/hl/c++/test/ptableTest.cpp index 6deb24d..ab49303 100644 --- a/hl/c++/test/ptableTest.cpp +++ b/hl/c++/test/ptableTest.cpp @@ -620,7 +620,7 @@ TestHDFFV_9758() for (hsize_t i = 0; i < NUM_PACKETS; i++) { s1[i].a = static_cast<int>(i); - s1[i].b = 1.0f * static_cast<float>(i * i); + s1[i].b = 1.0F * static_cast<float>(i * i); s1[i].c = 1.0 / static_cast<double>(i + 1); HDsprintf(s1[i].d, "string%" PRIuHSIZE "", i); s1[i].e = static_cast<int>(100 + i); diff --git a/hl/examples/ex_table_01.c b/hl/examples/ex_table_01.c index 8635acf..3294ef4 100644 --- a/hl/examples/ex_table_01.c +++ b/hl/examples/ex_table_01.c @@ -50,10 +50,10 @@ main(void) sizeof(dst_buf[0].pressure), sizeof(dst_buf[0].temperature)}; /* Define an array of Particles */ - Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0f, 0.0}, {"one", 10, 10, 1.0f, 10.0}, - {"two", 20, 20, 2.0f, 20.0}, {"three", 30, 30, 3.0f, 30.0}, - {"four", 40, 40, 4.0f, 40.0}, {"five", 50, 50, 5.0f, 50.0}, - {"six", 60, 60, 6.0f, 60.0}, {"seven", 70, 70, 7.0f, 70.0}}; + Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0F, 0.0}, {"one", 10, 10, 1.0F, 10.0}, + {"two", 20, 20, 2.0F, 20.0}, {"three", 30, 30, 3.0F, 30.0}, + {"four", 40, 40, 4.0F, 40.0}, {"five", 50, 50, 5.0F, 50.0}, + {"six", 60, 60, 6.0F, 60.0}, {"seven", 70, 70, 7.0F, 70.0}}; /* Define field information */ const char *field_names[NFIELDS] = {"Name", "Latitude", "Longitude", "Pressure", "Temperature"}; diff --git a/hl/examples/ex_table_02.c b/hl/examples/ex_table_02.c index 9c476b3..fb2cad6 100644 --- a/hl/examples/ex_table_02.c +++ b/hl/examples/ex_table_02.c @@ -42,10 +42,10 @@ main(void) Particle dst_buf[NRECORDS + NRECORDS_ADD]; /* Define an array of Particles */ - Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0f, 0.0}, {"one", 10, 10, 1.0f, 10.0}, - {"two", 20, 20, 2.0f, 20.0}, {"three", 30, 30, 3.0f, 30.0}, - {"four", 40, 40, 4.0f, 40.0}, {"five", 50, 50, 5.0f, 50.0}, - {"six", 60, 60, 6.0f, 60.0}, {"seven", 70, 70, 7.0f, 70.0}}; + Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0F, 0.0}, {"one", 10, 10, 1.0F, 10.0}, + {"two", 20, 20, 2.0F, 20.0}, {"three", 30, 30, 3.0F, 30.0}, + {"four", 40, 40, 4.0F, 40.0}, {"five", 50, 50, 5.0F, 50.0}, + {"six", 60, 60, 6.0F, 60.0}, {"seven", 70, 70, 7.0F, 70.0}}; /* Calculate the size and the offsets of our struct members in memory */ size_t dst_size = sizeof(Particle); @@ -66,7 +66,7 @@ main(void) int i; /* Append particles */ - Particle particle_in[NRECORDS_ADD] = {{"eight", 80, 80, 8.0f, 80.0}, {"nine", 90, 90, 9.0f, 90.0}}; + Particle particle_in[NRECORDS_ADD] = {{"eight", 80, 80, 8.0F, 80.0}, {"nine", 90, 90, 9.0F, 90.0}}; /* Initialize the field field_type */ string_type = H5Tcopy(H5T_C_S1); diff --git a/hl/examples/ex_table_03.c b/hl/examples/ex_table_03.c index 31cf970..3caa45e 100644 --- a/hl/examples/ex_table_03.c +++ b/hl/examples/ex_table_03.c @@ -46,14 +46,14 @@ main(void) size_t dst_offset[NFIELDS] = {HOFFSET(Particle, name), HOFFSET(Particle, lati), HOFFSET(Particle, longi), HOFFSET(Particle, pressure), HOFFSET(Particle, temperature)}; - Particle p = {"zero", 0, 0, 0.0f, 0.0}; + Particle p = {"zero", 0, 0, 0.0F, 0.0}; size_t dst_sizes[NFIELDS] = {sizeof(p.name), sizeof(p.lati), sizeof(p.longi), sizeof(p.pressure), sizeof(p.temperature)}; /* Define field information */ const char *field_names[NFIELDS] = {"Name", "Latitude", "Longitude", "Pressure", "Temperature"}; /* Fill value particle */ - Particle fill_data[1] = {{"no data", -1, -1, -99.0f, -99.0}}; + Particle fill_data[1] = {{"no data", -1, -1, -99.0F, -99.0}}; hid_t field_type[NFIELDS]; hid_t string_type; hid_t file_id; @@ -63,7 +63,7 @@ main(void) int i; /* Define 2 new particles to write */ - Particle particle_in[NRECORDS_WRITE] = {{"zero", 0, 0, 0.0f, 0.0}, {"one", 10, 10, 1.0f, 10.0}}; + Particle particle_in[NRECORDS_WRITE] = {{"zero", 0, 0, 0.0F, 0.0}, {"one", 10, 10, 1.0F, 10.0}}; /* Initialize the field field_type */ string_type = H5Tcopy(H5T_C_S1); diff --git a/hl/examples/ex_table_04.c b/hl/examples/ex_table_04.c index 863fe15..9b39ef7 100644 --- a/hl/examples/ex_table_04.c +++ b/hl/examples/ex_table_04.c @@ -65,23 +65,23 @@ main(void) hid_t string_type; hid_t file_id; hsize_t chunk_size = 10; - Particle fill_data[1] = {{"no data", -1, -1, -99.0f, -99.0}}; /* Fill value particle */ + Particle fill_data[1] = {{"no data", -1, -1, -99.0F, -99.0}}; /* Fill value particle */ hsize_t start; /* Record to start reading/writing */ hsize_t nrecords; /* Number of records to read/write */ int compress = 0; int i; Particle *p_data = NULL; /* Initially no data */ float pressure_in[NRECORDS_ADD] = /* Define new values for the field "Pressure" */ - {0.0f, 1.0f, 2.0f}; + {0.0F, 1.0F, 2.0F}; Position position_in[NRECORDS_ADD] = {/* Define new values for "Latitude,Longitude" */ {0, 0}, {10, 10}, {20, 20}}; NamePressure namepre_in[NRECORDS_ADD] = /* Define new values for "Name,Pressure" */ { - {"zero", 0.0f}, - {"one", 1.0f}, - {"two", 2.0f}, + {"zero", 0.0F}, + {"one", 1.0F}, + {"two", 2.0F}, }; size_t field_sizes_pos[2] = {sizeof(position_in[0].longi), sizeof(position_in[0].lati)}; size_t field_sizes_pre[1] = {sizeof(namepre_in[0].pressure)}; diff --git a/hl/examples/ex_table_05.c b/hl/examples/ex_table_05.c index 337bfb6..cac406b 100644 --- a/hl/examples/ex_table_05.c +++ b/hl/examples/ex_table_05.c @@ -64,7 +64,7 @@ main(void) hid_t string_type; hid_t file_id; hsize_t chunk_size = 10; - Particle fill_data[1] = {{"no data", -1, -1, -99.0f, -99.0}}; /* Fill value particle */ + Particle fill_data[1] = {{"no data", -1, -1, -99.0F, -99.0}}; /* Fill value particle */ int compress = 0; hsize_t nfields; hsize_t start; /* Record to start reading/writing */ @@ -72,7 +72,7 @@ main(void) int i; /* Define new values for the field "Pressure" */ - float pressure_in[NRECORDS_ADD] = {0.0f, 1.0f, 2.0f}; + float pressure_in[NRECORDS_ADD] = {0.0F, 1.0F, 2.0F}; int field_index_pre[1] = {3}; int field_index_pos[2] = {1, 2}; diff --git a/hl/examples/ex_table_06.c b/hl/examples/ex_table_06.c index f6b67c8..cc1bc01 100644 --- a/hl/examples/ex_table_06.c +++ b/hl/examples/ex_table_06.c @@ -49,7 +49,7 @@ main(void) hid_t string_type; hid_t file_id; hsize_t chunk_size = 10; - Particle fill_data[1] = {{"no data", -1, -1, -99.0f, -99.0}}; /* Fill value particle */ + Particle fill_data[1] = {{"no data", -1, -1, -99.0F, -99.0}}; /* Fill value particle */ int compress = 0; hsize_t nfields_out; hsize_t nrecords_out; diff --git a/hl/examples/ex_table_07.c b/hl/examples/ex_table_07.c index ab36613..e05a681 100644 --- a/hl/examples/ex_table_07.c +++ b/hl/examples/ex_table_07.c @@ -44,10 +44,10 @@ main(void) HOFFSET(Particle, pressure), HOFFSET(Particle, temperature)}; /* Define an array of Particles */ - Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0f, 0.0}, {"one", 10, 10, 1.0f, 10.0}, - {"two", 20, 20, 2.0f, 20.0}, {"three", 30, 30, 3.0f, 30.0}, - {"four", 40, 40, 4.0f, 40.0}, {"five", 50, 50, 5.0f, 50.0}, - {"six", 60, 60, 6.0f, 60.0}, {"seven", 70, 70, 7.0f, 70.0}}; + Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0F, 0.0}, {"one", 10, 10, 1.0F, 10.0}, + {"two", 20, 20, 2.0F, 20.0}, {"three", 30, 30, 3.0F, 30.0}, + {"four", 40, 40, 4.0F, 40.0}, {"five", 50, 50, 5.0F, 50.0}, + {"six", 60, 60, 6.0F, 60.0}, {"seven", 70, 70, 7.0F, 70.0}}; const char *field_names[NFIELDS] = /* Define field information */ {"Name", "Latitude", "Longitude", "Pressure", "Temperature"}; @@ -56,7 +56,7 @@ main(void) hid_t file_id; hsize_t chunk_size = 10; int compress = 0; - Particle fill_data[1] = {{"no data", -1, -1, -99.0f, -99.0}}; + Particle fill_data[1] = {{"no data", -1, -1, -99.0F, -99.0}}; hsize_t start; /* Record to start reading */ hsize_t nrecords; /* Number of records to insert/delete */ hsize_t nfields_out; diff --git a/hl/examples/ex_table_08.c b/hl/examples/ex_table_08.c index 5d447dd..1063172 100644 --- a/hl/examples/ex_table_08.c +++ b/hl/examples/ex_table_08.c @@ -41,10 +41,10 @@ main(void) Particle dst_buf[NRECORDS + NRECORDS_INS]; /* Define an array of Particles */ - Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0f, 0.0}, {"one", 10, 10, 1.0f, 10.0}, - {"two", 20, 20, 2.0f, 20.0}, {"three", 30, 30, 3.0f, 30.0}, - {"four", 40, 40, 4.0f, 40.0}, {"five", 50, 50, 5.0f, 50.0}, - {"six", 60, 60, 6.0f, 60.0}, {"seven", 70, 70, 7.0f, 70.0}}; + Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0F, 0.0}, {"one", 10, 10, 1.0F, 10.0}, + {"two", 20, 20, 2.0F, 20.0}, {"three", 30, 30, 3.0F, 30.0}, + {"four", 40, 40, 4.0F, 40.0}, {"five", 50, 50, 5.0F, 50.0}, + {"six", 60, 60, 6.0F, 60.0}, {"seven", 70, 70, 7.0F, 70.0}}; /* Calculate the size and the offsets of our struct members in memory */ size_t dst_size = sizeof(Particle); @@ -54,7 +54,7 @@ main(void) sizeof(p_data[0].pressure), sizeof(p_data[0].temperature)}; /* Define an array of Particles to insert */ - Particle p_data_insert[NRECORDS_INS] = {{"new", 30, 30, 3.0f, 30.0}, {"new", 40, 40, 4.0f, 40.0}}; + Particle p_data_insert[NRECORDS_INS] = {{"new", 30, 30, 3.0F, 30.0}, {"new", 40, 40, 4.0F, 40.0}}; /* Define field information */ const char *field_names[NFIELDS] = {"Name", "Latitude", "Longitude", "Pressure", "Temperature"}; diff --git a/hl/examples/ex_table_09.c b/hl/examples/ex_table_09.c index 381925f..171de2e 100644 --- a/hl/examples/ex_table_09.c +++ b/hl/examples/ex_table_09.c @@ -49,10 +49,10 @@ main(void) sizeof(dst_buf[0].pressure), sizeof(dst_buf[0].temperature)}; /* Define an array of Particles */ - Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0f, 0.0}, {"one", 10, 10, 1.0f, 10.0}, - {"two", 20, 20, 2.0f, 20.0}, {"three", 30, 30, 3.0f, 30.0}, - {"four", 40, 40, 4.0f, 40.0}, {"five", 50, 50, 5.0f, 50.0}, - {"six", 60, 60, 6.0f, 60.0}, {"seven", 70, 70, 7.0f, 70.0}}; + Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0F, 0.0}, {"one", 10, 10, 1.0F, 10.0}, + {"two", 20, 20, 2.0F, 20.0}, {"three", 30, 30, 3.0F, 30.0}, + {"four", 40, 40, 4.0F, 40.0}, {"five", 50, 50, 5.0F, 50.0}, + {"six", 60, 60, 6.0F, 60.0}, {"seven", 70, 70, 7.0F, 70.0}}; /* Define field information */ const char *field_names[NFIELDS] = {"Name", "Latitude", "Longitude", "Pressure", "Temperature"}; @@ -61,7 +61,7 @@ main(void) hid_t file_id; hsize_t chunk_size = 10; int compress = 0; - Particle fill_data[1] = {{"no data", -1, -1, -99.0f, -99.0}}; /* Fill value particle */ + Particle fill_data[1] = {{"no data", -1, -1, -99.0F, -99.0}}; /* Fill value particle */ hsize_t start1; /* Record to start reading from 1st table */ hsize_t nrecords; /* Number of records to insert */ hsize_t start2; /* Record to start writing in 2nd table */ diff --git a/hl/examples/ex_table_10.c b/hl/examples/ex_table_10.c index 4ba5d64..c974e84 100644 --- a/hl/examples/ex_table_10.c +++ b/hl/examples/ex_table_10.c @@ -40,10 +40,10 @@ main(void) } Particle; /* Define an array of Particles */ - Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0f, 0.0}, {"one", 10, 10, 1.0f, 10.0}, - {"two", 20, 20, 2.0f, 20.0}, {"three", 30, 30, 3.0f, 30.0}, - {"four", 40, 40, 4.0f, 40.0}, {"five", 50, 50, 5.0f, 50.0}, - {"six", 60, 60, 6.0f, 60.0}, {"seven", 70, 70, 7.0f, 70.0}}; + Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0F, 0.0}, {"one", 10, 10, 1.0F, 10.0}, + {"two", 20, 20, 2.0F, 20.0}, {"three", 30, 30, 3.0F, 30.0}, + {"four", 40, 40, 4.0F, 40.0}, {"five", 50, 50, 5.0F, 50.0}, + {"six", 60, 60, 6.0F, 60.0}, {"seven", 70, 70, 7.0F, 70.0}}; Particle dst_buf[2 * NRECORDS]; /* Calculate the size and the offsets of our struct members in memory */ diff --git a/hl/examples/ex_table_11.c b/hl/examples/ex_table_11.c index 9bf3927..6b38b95 100644 --- a/hl/examples/ex_table_11.c +++ b/hl/examples/ex_table_11.c @@ -38,10 +38,10 @@ main(void) } Particle1; /* Define an array of Particles */ - Particle1 p_data[NRECORDS] = {{"zero", 0, 0, 0.0f, 0.0}, {"one", 10, 10, 1.0f, 10.0}, - {"two", 20, 20, 2.0f, 20.0}, {"three", 30, 30, 3.0f, 30.0}, - {"four", 40, 40, 4.0f, 40.0}, {"five", 50, 50, 5.0f, 50.0}, - {"six", 60, 60, 6.0f, 60.0}, {"seven", 70, 70, 7.0f, 70.0}}; + Particle1 p_data[NRECORDS] = {{"zero", 0, 0, 0.0F, 0.0}, {"one", 10, 10, 1.0F, 10.0}, + {"two", 20, 20, 2.0F, 20.0}, {"three", 30, 30, 3.0F, 30.0}, + {"four", 40, 40, 4.0F, 40.0}, {"five", 50, 50, 5.0F, 50.0}, + {"six", 60, 60, 6.0F, 60.0}, {"seven", 70, 70, 7.0F, 70.0}}; /* Calculate the size and the offsets of our struct members in memory */ size_t dst_size1 = sizeof(Particle1); @@ -56,7 +56,7 @@ main(void) hid_t file_id; hsize_t chunk_size = 10; int compress = 0; - Particle1 fill_data[1] = {{"no data", -1, -1, -99.0f, -99.0}}; + Particle1 fill_data[1] = {{"no data", -1, -1, -99.0F, -99.0}}; int fill_data_new[1] = {-100}; hsize_t position; hsize_t nfields_out; diff --git a/hl/examples/ex_table_12.c b/hl/examples/ex_table_12.c index 3e7c27a..a1a2c54 100644 --- a/hl/examples/ex_table_12.c +++ b/hl/examples/ex_table_12.c @@ -44,10 +44,10 @@ main(void) HOFFSET(Particle, pressure), HOFFSET(Particle, temperature)}; /* Define an array of Particles */ - Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0f, 0.0}, {"one", 10, 10, 1.0f, 10.0}, - {"two", 20, 20, 2.0f, 20.0}, {"three", 30, 30, 3.0f, 30.0}, - {"four", 40, 40, 4.0f, 40.0}, {"five", 50, 50, 5.0f, 50.0}, - {"six", 60, 60, 6.0f, 60.0}, {"seven", 70, 70, 7.0f, 70.0}}; + Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0F, 0.0}, {"one", 10, 10, 1.0F, 10.0}, + {"two", 20, 20, 2.0F, 20.0}, {"three", 30, 30, 3.0F, 30.0}, + {"four", 40, 40, 4.0F, 40.0}, {"five", 50, 50, 5.0F, 50.0}, + {"six", 60, 60, 6.0F, 60.0}, {"seven", 70, 70, 7.0F, 70.0}}; /* Define field information */ const char *field_names[NFIELDS] = {"Name", "Latitude", "Longitude", "Pressure", "Temperature"}; @@ -56,7 +56,7 @@ main(void) hid_t file_id; hsize_t chunk_size = 10; int compress = 0; - Particle fill_data[1] = {{"no data", -1, -1, -99.0f, -99.0}}; + Particle fill_data[1] = {{"no data", -1, -1, -99.0F, -99.0}}; hsize_t nfields_out; hsize_t nrecords_out; diff --git a/hl/src/CMakeLists.txt b/hl/src/CMakeLists.txt index 7678de8..a97d6fa 100644 --- a/hl/src/CMakeLists.txt +++ b/hl/src/CMakeLists.txt @@ -169,3 +169,32 @@ if (NOT WIN32 AND NOT MINGW) COMPONENT hllibraries ) endif () + +#----------------------------------------------------------------------------- +# Option to build documentation +#----------------------------------------------------------------------------- +if (DOXYGEN_FOUND) +# This cmake function requires that the non-default doxyfile settings are provided with set (DOXYGEN_xxx) commands +# In addition the doxyfile aliases @INCLUDE option is not supported and would need to be provided in a set (DOXYGEN_ALIASES) command. +# doxygen_add_docs (hdf5lib_doc +## ${HL_SOURCES} ${HL_HEADERS} ${HDF5_DOXYGEN_DIR}/dox +# ${DOXYGEN_INPUT_DIRECTORY} +# ALL +# WORKING_DIRECTORY ${HDF5_HL_SRC_DIR} +# COMMENT "Generating HDF5 HL library Source Documentation" +# ) + +# This custom target and doxygen/configure work together + # Replace variables inside @@ with the current values + add_custom_target (hdf5hllib_doc ALL + COMMAND ${DOXYGEN_EXECUTABLE} ${HDF5_BINARY_DIR}/Doxyfile + WORKING_DIRECTORY ${HDF5_HL_SRC_DIR} + COMMENT "Generating HDF5 HL library Source API documentation with Doxygen" + VERBATIM ) + + if (NOT TARGET doxygen) + add_custom_target (doxygen) + endif () + + add_dependencies (doxygen hdf5hllib_doc) +endif () diff --git a/hl/src/H5LT.c b/hl/src/H5LT.c index 1ef0f9d..8f2b33f 100644 --- a/hl/src/H5LT.c +++ b/hl/src/H5LT.c @@ -1352,13 +1352,13 @@ find_dataset(H5_ATTR_UNUSED hid_t loc_id, const char *name, H5_ATTR_UNUSED const * modify the op_data buffer (i.e.: dset_name) during the traversal, and the * library never modifies that buffer. */ -H5_GCC_DIAG_OFF("cast-qual") +H5_GCC_CLANG_DIAG_OFF("cast-qual") herr_t H5LTfind_dataset(hid_t loc_id, const char *dset_name) { return H5Literate2(loc_id, H5_INDEX_NAME, H5_ITER_INC, 0, find_dataset, (void *)dset_name); } -H5_GCC_DIAG_ON("cast-qual") +H5_GCC_CLANG_DIAG_ON("cast-qual") /*------------------------------------------------------------------------- * @@ -1776,6 +1776,32 @@ H5LTset_attribute_ulong(hid_t loc_id, const char *obj_name, const char *attr_nam } /*------------------------------------------------------------------------- + * Function: H5LTset_attribute_ullong + * + * Purpose: Create and write an attribute. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Alessandro Felder + * + * Date: August 27, 2021 + * + * Comments: + * + *------------------------------------------------------------------------- + */ +herr_t +H5LTset_attribute_ullong(hid_t loc_id, const char *obj_name, const char *attr_name, + const unsigned long long *data, size_t size) +{ + + if (H5LT_set_attribute_numerical(loc_id, obj_name, attr_name, size, H5T_NATIVE_ULLONG, data) < 0) + return -1; + + return 0; +} + +/*------------------------------------------------------------------------- * Function: H5LTset_attribute_float * * Purpose: Create and write an attribute. @@ -1919,13 +1945,13 @@ H5LTfind_attribute(hid_t loc_id, const char *attr_name) * modify the op_data buffer (i.e.: attr_name) during the traversal, and the * library never modifies that buffer. */ -H5_GCC_DIAG_OFF("cast-qual") +H5_GCC_CLANG_DIAG_OFF("cast-qual") herr_t H5LT_find_attribute(hid_t loc_id, const char *attr_name) { return H5Aiterate2(loc_id, H5_INDEX_NAME, H5_ITER_INC, NULL, find_attr, (void *)attr_name); } -H5_GCC_DIAG_ON("cast-qual") +H5_GCC_CLANG_DIAG_ON("cast-qual") /*------------------------------------------------------------------------- * Function: H5LTget_attribute_ndims @@ -2180,7 +2206,7 @@ realloc_and_append(hbool_t _no_user_buf, size_t *len, char *buf, const char *str */ if (size_str < *len - 1) { if (size_str + size_str_to_add < *len - 1) { - HDstrncat(buf, str_to_add, size_str_to_add); + HDstrcat(buf, str_to_add); } else { HDstrncat(buf, str_to_add, (*len - 1) - size_str); @@ -3317,6 +3343,33 @@ H5LTget_attribute_ulong(hid_t loc_id, const char *obj_name, const char *attr_nam } /*------------------------------------------------------------------------- + * Function: H5LTget_attribute_ullong + * + * Purpose: Reads an attribute named attr_name + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Alessandro Felder + * + * Date: August 27, 2021 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5LTget_attribute_ullong(hid_t loc_id, const char *obj_name, const char *attr_name, unsigned long long *data) +{ + /* Get the attribute */ + if (H5LT_get_attribute_mem(loc_id, obj_name, attr_name, H5T_NATIVE_ULLONG, data) < 0) + return -1; + + return 0; +} + +/*------------------------------------------------------------------------- * Function: H5LTget_attribute_float * * Purpose: Reads an attribute named attr_name diff --git a/hl/src/H5LTpublic.h b/hl/src/H5LTpublic.h index 2af9b07..f19d353 100644 --- a/hl/src/H5LTpublic.h +++ b/hl/src/H5LTpublic.h @@ -139,6 +139,9 @@ H5_HLDLL herr_t H5LTset_attribute_long_long(hid_t loc_id, const char *obj_name, H5_HLDLL herr_t H5LTset_attribute_ulong(hid_t loc_id, const char *obj_name, const char *attr_name, const unsigned long *buffer, size_t size); +H5_HLDLL herr_t H5LTset_attribute_ullong(hid_t loc_id, const char *obj_name, const char *attr_name, + const unsigned long long *buffer, size_t size); + H5_HLDLL herr_t H5LTset_attribute_float(hid_t loc_id, const char *obj_name, const char *attr_name, const float *buffer, size_t size); @@ -182,6 +185,9 @@ H5_HLDLL herr_t H5LTget_attribute_long_long(hid_t loc_id, const char *obj_name, H5_HLDLL herr_t H5LTget_attribute_ulong(hid_t loc_id, const char *obj_name, const char *attr_name, unsigned long *data); +H5_HLDLL herr_t H5LTget_attribute_ullong(hid_t loc_id, const char *obj_name, const char *attr_name, + unsigned long long *data); + H5_HLDLL herr_t H5LTget_attribute_float(hid_t loc_id, const char *obj_name, const char *attr_name, float *data); diff --git a/hl/test/gen_test_ds.c b/hl/test/gen_test_ds.c index 368c083..a56e6cf 100644 --- a/hl/test/gen_test_ds.c +++ b/hl/test/gen_test_ds.c @@ -75,7 +75,7 @@ main(int argc, char **argv) int nerrors = 0; char filename[65]; - if (argc < 2) { + if (argc < 2 || !argv[0] || !argv[1]) { HDprintf("Usage: gen_test [le | be]\n"); return 1; } diff --git a/hl/test/test_ds.c b/hl/test/test_ds.c index 8c6ef91..964e13f 100644 --- a/hl/test/test_ds.c +++ b/hl/test/test_ds.c @@ -5210,6 +5210,8 @@ test_attach_detach(void) HL_TESTING2("permutations of attaching and detaching"); + gid = var1_id = var2_id = var3_id = H5I_INVALID_HID; + if ((fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto out; diff --git a/hl/test/test_lite.c b/hl/test/test_lite.c index cae91ff..53f834a 100644 --- a/hl/test/test_lite.c +++ b/hl/test/test_lite.c @@ -43,8 +43,9 @@ #define ATTR7_NAME "attr ushort" #define ATTR8_NAME "attr uint" #define ATTR9_NAME "attr ulong" -#define ATTR10_NAME "attr float" -#define ATTR11_NAME "attr double" +#define ATTR10_NAME "attr ullong" +#define ATTR11_NAME "attr float" +#define ATTR12_NAME "attr double" static herr_t make_attributes(hid_t loc_id, const char *obj_name); @@ -472,28 +473,30 @@ make_attributes(hid_t loc_id, const char *obj_name) size_t type_size; int i; - char attr_str_in[] = {"My attribute"}; - char attr_str_out[20]; - char attr_char_in[5] = {1, 2, 3, 4, 5}; - char attr_char_out[5]; - short attr_short_in[5] = {1, 2, 3, 4, 5}; - short attr_short_out[5]; - int attr_int_in[5] = {1, 2, 3, 4, 5}; - int attr_int_out[5]; - long attr_long_in[5] = {1, 2, 3, 4, 5}; - long attr_long_out[5]; - float attr_float_in[5] = {1, 2, 3, 4, 5}; - float attr_float_out[5]; - double attr_double_in[5] = {1, 2, 3, 4, 5}; - double attr_double_out[5]; - unsigned char attr_uchar_in[5] = {1, 2, 3, 4, 5}; - unsigned char attr_uchar_out[5]; - unsigned short attr_ushort_in[5] = {1, 2, 3, 4, 5}; - unsigned short attr_ushort_out[5]; - unsigned int attr_uint_in[5] = {1, 2, 3, 4, 5}; - unsigned int attr_uint_out[5]; - unsigned long attr_ulong_in[5] = {1, 2, 3, 4, 5}; - unsigned long attr_ulong_out[5]; + char attr_str_in[] = {"My attribute"}; + char attr_str_out[20]; + char attr_char_in[5] = {1, 2, 3, 4, 5}; + char attr_char_out[5]; + short attr_short_in[5] = {1, 2, 3, 4, 5}; + short attr_short_out[5]; + int attr_int_in[5] = {1, 2, 3, 4, 5}; + int attr_int_out[5]; + long attr_long_in[5] = {1, 2, 3, 4, 5}; + long attr_long_out[5]; + float attr_float_in[5] = {1, 2, 3, 4, 5}; + float attr_float_out[5]; + double attr_double_in[5] = {1, 2, 3, 4, 5}; + double attr_double_out[5]; + unsigned char attr_uchar_in[5] = {1, 2, 3, 4, 5}; + unsigned char attr_uchar_out[5]; + unsigned short attr_ushort_in[5] = {1, 2, 3, 4, 5}; + unsigned short attr_ushort_out[5]; + unsigned int attr_uint_in[5] = {1, 2, 3, 4, 5}; + unsigned int attr_uint_out[5]; + unsigned long attr_ulong_in[5] = {1, 2, 3, 4, 5}; + unsigned long attr_ulong_out[5]; + unsigned long long attr_ullong_in[5] = {1, 2, 3, 4, 5}; + unsigned long long attr_ullong_out[5]; /*------------------------------------------------------------------------- * H5LTset_attribute_string test @@ -509,7 +512,7 @@ make_attributes(hid_t loc_id, const char *obj_name) PASSED(); /*------------------------------------------------------------------------- - * H5LTset_attribute_string test + * H5LTget_attribute_string test *------------------------------------------------------------------------- */ @@ -859,7 +862,7 @@ make_attributes(hid_t loc_id, const char *obj_name) PASSED(); /*------------------------------------------------------------------------- - * H5LTget_attribute_long test + * H5LTget_attribute_ulong test *------------------------------------------------------------------------- */ @@ -888,6 +891,48 @@ make_attributes(hid_t loc_id, const char *obj_name) PASSED(); /*------------------------------------------------------------------------- + * H5LTset_attribute_ullong test + *------------------------------------------------------------------------- + */ + + HL_TESTING2("H5LTset_attribute_ullong"); + + /* Set the attribute */ + if (H5LTset_attribute_ullong(loc_id, obj_name, ATTR10_NAME, attr_ullong_in, (size_t)5) < 0) + return -1; + + PASSED(); + + /*------------------------------------------------------------------------- + * H5LTget_attribute_ullong test + *------------------------------------------------------------------------- + */ + + HL_TESTING2("H5LTget_attribute_ullong"); + + /* Get the attribute */ + if (H5LTget_attribute_ullong(loc_id, obj_name, ATTR10_NAME, attr_ullong_out) < 0) + return -1; + + for (i = 0; i < 5; i++) { + if (attr_ullong_in[i] != attr_ullong_out[i]) { + return -1; + } + } + + /* Get the attribute */ + if (H5LTget_attribute(loc_id, obj_name, ATTR10_NAME, H5T_NATIVE_ULLONG, attr_ullong_out) < 0) + return -1; + + for (i = 0; i < 5; i++) { + if (attr_ullong_in[i] != attr_ullong_out[i]) { + return -1; + } + } + + PASSED(); + + /*------------------------------------------------------------------------- * H5LTset_attribute_float test *------------------------------------------------------------------------- */ @@ -895,7 +940,7 @@ make_attributes(hid_t loc_id, const char *obj_name) HL_TESTING2("H5LTset_attribute_float"); /* Set the attribute */ - if (H5LTset_attribute_float(loc_id, obj_name, ATTR10_NAME, attr_float_in, (size_t)5) < 0) + if (H5LTset_attribute_float(loc_id, obj_name, ATTR11_NAME, attr_float_in, (size_t)5) < 0) return -1; PASSED(); @@ -908,7 +953,7 @@ make_attributes(hid_t loc_id, const char *obj_name) HL_TESTING2("H5LTget_attribute_float"); /* Get the attribute */ - if (H5LTget_attribute_float(loc_id, obj_name, ATTR10_NAME, attr_float_out) < 0) + if (H5LTget_attribute_float(loc_id, obj_name, ATTR11_NAME, attr_float_out) < 0) return -1; for (i = 0; i < 5; i++) { @@ -918,7 +963,7 @@ make_attributes(hid_t loc_id, const char *obj_name) } /* Get the attribute */ - if (H5LTget_attribute(loc_id, obj_name, ATTR10_NAME, H5T_NATIVE_FLOAT, attr_float_out) < 0) + if (H5LTget_attribute(loc_id, obj_name, ATTR11_NAME, H5T_NATIVE_FLOAT, attr_float_out) < 0) return -1; for (i = 0; i < 5; i++) { @@ -937,7 +982,7 @@ make_attributes(hid_t loc_id, const char *obj_name) HL_TESTING2("H5LTset_attribute_double"); /* Set the attribute */ - if (H5LTset_attribute_double(loc_id, obj_name, ATTR11_NAME, attr_double_in, (size_t)5) < 0) + if (H5LTset_attribute_double(loc_id, obj_name, ATTR12_NAME, attr_double_in, (size_t)5) < 0) return -1; PASSED(); @@ -950,7 +995,7 @@ make_attributes(hid_t loc_id, const char *obj_name) HL_TESTING2("H5LTget_attribute_double"); /* Get the attribute */ - if (H5LTget_attribute_double(loc_id, obj_name, ATTR11_NAME, attr_double_out) < 0) + if (H5LTget_attribute_double(loc_id, obj_name, ATTR12_NAME, attr_double_out) < 0) return -1; for (i = 0; i < 5; i++) { @@ -960,7 +1005,7 @@ make_attributes(hid_t loc_id, const char *obj_name) } /* Get the attribute */ - if (H5LTget_attribute(loc_id, obj_name, ATTR11_NAME, H5T_NATIVE_DOUBLE, attr_double_out) < 0) + if (H5LTget_attribute(loc_id, obj_name, ATTR12_NAME, H5T_NATIVE_DOUBLE, attr_double_out) < 0) return -1; for (i = 0; i < 5; i++) { diff --git a/hl/test/test_packet.c b/hl/test/test_packet.c index 1d3a569..5f30d4b 100644 --- a/hl/test/test_packet.c +++ b/hl/test/test_packet.c @@ -45,10 +45,10 @@ typedef struct particle_t { * a static array of particles for writing and checking reads *------------------------------------------------------------------------- */ -static particle_t testPart[NRECORDS] = {{"zero", 0, 0, 0.0f, 0.0f}, {"one", 10, 10, 1.0f, 10.0f}, - {"two", 20, 20, 2.0f, 20.0f}, {"three", 30, 30, 3.0f, 30.0f}, - {"four", 40, 40, 4.0f, 40.0f}, {"five", 50, 50, 5.0f, 50.0f}, - {"six", 60, 60, 6.0f, 60.0f}, {"seven", 70, 70, 7.0f, 70.0f}}; +static particle_t testPart[NRECORDS] = {{"zero", 0, 0, 0.0F, 0.0}, {"one", 10, 10, 1.0F, 10.0}, + {"two", 20, 20, 2.0F, 20.0}, {"three", 30, 30, 3.0F, 30.0}, + {"Four", 40, 40, 4.0F, 40.0}, {"Five", 50, 50, 5.0F, 50.0}, + {"six", 60, 60, 6.0F, 60.0}, {"seven", 70, 70, 7.0F, 70.0}}; /*------------------------------------------------------------------------- * function that compares one particle diff --git a/hl/test/test_table.c b/hl/test/test_table.c index 0d4a72a..6199e27 100644 --- a/hl/test/test_table.c +++ b/hl/test/test_table.c @@ -199,7 +199,7 @@ test_table(hid_t fid, int do_write) hsize_t chunk_size = 10; int compress = 0; int * fill = NULL; - particle_t fill1[1] = {{"no data", -1, -99.0f, -99.0f, -1}}; + particle_t fill1[1] = {{"no data", -1, -99.0, -99.0, -1}}; int fill1_new[1] = {-100}; hsize_t position; char tname[20]; @@ -227,25 +227,25 @@ test_table(hid_t fid, int do_write) particle2_t rbuf2[NRECORDS]; particle3_t rbuf3[NRECORDS]; particle_t rbufc[NRECORDS * 2]; - particle_t abuf[2] = {{"eight", 80, 8.0f, 80.0f, 80}, {"nine", 90, 9.0f, 90.0f, 90}}; - particle_t ibuf[2] = {{"zero", 0, 0.0f, 0.0f, 0}, {"zero", 0, 0.0f, 0.0f, 0}}; + particle_t abuf[2] = {{"eight", 80, 8.0, 80.0, 80}, {"nine", 90, 9.0, 90.0, 90}}; + particle_t ibuf[2] = {{"zero", 0, 0.0, 0.0, 0}, {"zero", 0, 0.0, 0.0, 0}}; particle_t wbufd[NRECORDS]; particle_t wbuf[NRECORDS] = {{ "zero", 0, - 0.0f, - 0.0f, + 0.0, + 0.0, 0, }, - {"one", 10, 1.0f, 10.0f, 10}, - {"two", 20, 2.0f, 20.0f, 20}, - {"three", 30, 3.0f, 30.0f, 30}, - {"four", 40, 4.0f, 40.0f, 40}, - {"five", 50, 5.0f, 50.0f, 50}, - {"six", 60, 6.0f, 60.0f, 60}, - {"seven", 70, 7.0f, 70.0f, 70}}; + {"one", 10, 1.0, 10.0, 10}, + {"two", 20, 2.0, 20.0, 20}, + {"three", 30, 3.0, 30.0, 30}, + {"four", 40, 4.0, 40.0, 40}, + {"five", 50, 5.0, 50.0, 50}, + {"six", 60, 6.0, 60.0, 60}, + {"seven", 70, 7.0, 70.0, 70}}; /* buffers for the field "Pressure" and "New_field" */ - float pressure_in[NRECORDS] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f}; + float pressure_in[NRECORDS] = {0.0F, 1.0F, 2.0F, 3.0F, 4.0F, 5.0F, 6.0F, 7.0F}; float pressure_out[NRECORDS]; int buf_new[NRECORDS] = {0, 1, 2, 3, 4, 5, 6, 7}; /* buffers for the fields "Latitude,Longitude" */ @@ -254,8 +254,8 @@ test_table(hid_t fid, int do_write) /* buffers for the fields "Name,Pressure" */ namepressure_t namepre_out[NRECORDS]; namepressure_t namepre_in[NRECORDS] = { - {"zero", 0.0f}, {"one", 1.0f}, {"two", 2.0f}, {"three", 3.0f}, - {"four", 4.0f}, {"five", 5.0f}, {"six", 6.0f}, {"seven", 7.0f}, + {"zero", 0.0F}, {"one", 1.0F}, {"two", 2.0F}, {"three", 3.0F}, + {"four", 4.0F}, {"five", 5.0F}, {"six", 6.0F}, {"seven", 7.0F}, }; /*------------------------------------------------------------------------- @@ -332,14 +332,14 @@ test_table(hid_t fid, int do_write) HOFFSET(particle4_t, aty), HOFFSET(particle4_t, rro)}; /* Define an array of Particles */ - particle4_t p_data[NRECORDS] = {{12112, 1.4f, 2.5f, {1, 2, 3}, {4, 5, 6}, {99, 100}}, - {12113, 1.4f, 2.5f, {1, 2, 3}, {4, 5, 6}, {99, 100}}, - {12114, 1.4f, 2.5f, {1, 2, 3}, {4, 5, 6}, {99, 100}}, - {12115, 1.4f, 2.5f, {1, 2, 3}, {4, 5, 6}, {99, 100}}, - {12116, 1.4f, 2.5f, {1, 2, 3}, {4, 5, 6}, {99, 100}}, - {12117, 1.4f, 2.5f, {1, 2, 3}, {4, 5, 6}, {99, 100}}, - {12118, 1.4f, 2.5f, {1, 2, 3}, {4, 5, 6}, {99, 100}}, - {12119, 1.4f, 2.5f, {1, 2, 3}, {4, 5, 6}, {99, 100}}}; + particle4_t p_data[NRECORDS] = {{12112, 1.4, 2.5, {1, 2, 3}, {4, 5, 6}, {99, 100}}, + {12113, 1.4, 2.5, {1, 2, 3}, {4, 5, 6}, {99, 100}}, + {12114, 1.4, 2.5, {1, 2, 3}, {4, 5, 6}, {99, 100}}, + {12115, 1.4, 2.5, {1, 2, 3}, {4, 5, 6}, {99, 100}}, + {12116, 1.4, 2.5, {1, 2, 3}, {4, 5, 6}, {99, 100}}, + {12117, 1.4, 2.5, {1, 2, 3}, {4, 5, 6}, {99, 100}}, + {12118, 1.4, 2.5, {1, 2, 3}, {4, 5, 6}, {99, 100}}, + {12119, 1.4, 2.5, {1, 2, 3}, {4, 5, 6}, {99, 100}}}; /*------------------------------------------------------------------------- * initialize table parameters diff --git a/hl/tools/h5watch/h5watchgentest.c b/hl/tools/h5watch/h5watchgentest.c index c83e485..44cb0cb 100644 --- a/hl/tools/h5watch/h5watchgentest.c +++ b/hl/tools/h5watch/h5watchgentest.c @@ -224,7 +224,7 @@ main(void) one_cbuf[i].field2.b.a = 20; one_cbuf[i].field2.b.b = 40; one_cbuf[i].field2.b.c = 80; - one_cbuf[i].field3 = 3.0F; + one_cbuf[i].field3 = 3.0; one_cbuf[i].field4.a = 4; one_cbuf[i].field4.b = 8; } /* end for */ @@ -313,7 +313,7 @@ main(void) two_cbuf[i].field2.b.a = 20; two_cbuf[i].field2.b.b = 40; two_cbuf[i].field2.b.c = 80; - two_cbuf[i].field3 = 3.0F; + two_cbuf[i].field3 = 3.0; two_cbuf[i].field4.a = 4; two_cbuf[i].field4.b = 8; } /* end for */ diff --git a/java/src/hdf/hdf5lib/HDFArray.java b/java/src/hdf/hdf5lib/HDFArray.java index bb9357e..21e2b02 100644 --- a/java/src/hdf/hdf5lib/HDFArray.java +++ b/java/src/hdf/hdf5lib/HDFArray.java @@ -46,10 +46,10 @@ public class HDFArray { * * @param anArray * The array object. - * @exception hdf.hdf5lib.exceptions.HDF5Exception - * object is not an array. + * @exception hdf.hdf5lib.exceptions.HDF5JavaException + * object is not an array. */ - public HDFArray(Object anArray) throws HDF5Exception + public HDFArray(Object anArray) throws HDF5JavaException { if (anArray == null) { HDF5JavaException ex = new HDF5JavaException("HDFArray: array is null?: "); @@ -76,16 +76,14 @@ public class HDFArray { * @return A one-D array of bytes, filled with zeroes. The bytes are sufficient to hold the data of the Array passed * to the constructor. * @exception hdf.hdf5lib.exceptions.HDF5JavaException - * Allocation failed. + * Allocation failed. */ - public byte[] emptyBytes() - throws HDF5JavaException + public byte[] emptyBytes() throws HDF5JavaException { byte[] b = null; - if ((ArrayDescriptor.dims == 1) - && (ArrayDescriptor.NT == 'B')) { + if ((ArrayDescriptor.dims == 1) && (ArrayDescriptor.NT == 'B')) { b = (byte[]) _theArray; } else { @@ -103,10 +101,9 @@ public class HDFArray { * * @return A one-D array of bytes, constructed from the Array passed to the constructor. * @exception hdf.hdf5lib.exceptions.HDF5JavaException - * the object not an array or other internal error. + * the object not an array or other internal error. */ - public byte[] byteify() - throws HDF5JavaException + public byte[] byteify() throws HDF5JavaException { if (_barray != null) { return _barray; @@ -224,8 +221,6 @@ public class HDFArray { if (ArrayDescriptor.NT == 'J') { arow = HDFNativeData.longToByte(0, ArrayDescriptor.dimlen[ArrayDescriptor.dims], (long[]) ArrayDescriptor.objs[ArrayDescriptor.dims - 1]); - arow = HDFNativeData.longToByte(0, ArrayDescriptor.dimlen[ArrayDescriptor.dims], - (long[]) ArrayDescriptor.objs[ArrayDescriptor.dims - 1]); } else if (ArrayDescriptor.NT == 'I') { arow = HDFNativeData.intToByte(0, ArrayDescriptor.dimlen[ArrayDescriptor.dims], @@ -552,8 +547,7 @@ public class HDFArray { + "?")); } } - if (ArrayDescriptor.currentindex[ArrayDescriptor.dims - 1] != ArrayDescriptor.dimlen[ArrayDescriptor.dims - - 1]) { + if (ArrayDescriptor.currentindex[ArrayDescriptor.dims - 1] != ArrayDescriptor.dimlen[ArrayDescriptor.dims - 1]) { throw new java.lang.InternalError( new String("HDFArray::arrayify Panic didn't complete all data: currentindex[" + i + "] = " + ArrayDescriptor.currentindex[i] + " (should be " + (ArrayDescriptor.dimlen[i]) + "?")); @@ -580,7 +574,7 @@ public class HDFArray { Integer[] out = new Integer[nelems]; for (int i = 0; i < nelems; i++) { - out[i] = new Integer(in[i]); + out[i] = Integer.valueOf(in[i]); } return out; } @@ -592,7 +586,7 @@ public class HDFArray { Integer[] out = new Integer[nelems]; for (int i = 0; i < nelems; i++) { - out[i] = new Integer(in[i]); + out[i] = Integer.valueOf(in[i]); } return out; } @@ -615,7 +609,7 @@ public class HDFArray { Short[] out = new Short[nelems]; for (int i = 0; i < nelems; i++) { - out[i] = new Short(in[i]); + out[i] = Short.valueOf(in[i]); } return out; } @@ -627,7 +621,7 @@ public class HDFArray { Short[] out = new Short[nelems]; for (int i = 0; i < nelems; i++) { - out[i] = new Short(in[i]); + out[i] = Short.valueOf(in[i]); } return out; } @@ -649,7 +643,7 @@ public class HDFArray { Byte[] out = new Byte[nelems]; for (int i = 0; i < nelems; i++) { - out[i] = new Byte(bin[i]); + out[i] = Byte.valueOf(bin[i]); } return out; } @@ -659,7 +653,7 @@ public class HDFArray { Byte[] out = new Byte[len]; for (int i = 0; i < len; i++) { - out[i] = new Byte(bin[i]); + out[i] = Byte.valueOf(bin[i]); } return out; } @@ -682,7 +676,7 @@ public class HDFArray { Float[] out = new Float[nelems]; for (int i = 0; i < nelems; i++) { - out[i] = new Float(in[i]); + out[i] = Float.valueOf(in[i]); } return out; } @@ -694,7 +688,7 @@ public class HDFArray { Float[] out = new Float[nelems]; for (int i = 0; i < nelems; i++) { - out[i] = new Float(in[i]); + out[i] = Float.valueOf(in[i]); } return out; } @@ -717,7 +711,7 @@ public class HDFArray { Double[] out = new Double[nelems]; for (int i = 0; i < nelems; i++) { - out[i] = new Double(in[i]); + out[i] = Double.valueOf(in[i]); } return out; } @@ -729,7 +723,7 @@ public class HDFArray { Double[] out = new Double[nelems]; for (int i = 0; i < nelems; i++) { - out[i] = new Double(in[i]); + out[i] = Double.valueOf(in[i]); } return out; } @@ -752,7 +746,7 @@ public class HDFArray { Long[] out = new Long[nelems]; for (int i = 0; i < nelems; i++) { - out[i] = new Long(in[i]); + out[i] = Long.valueOf(in[i]); } return out; } @@ -764,7 +758,7 @@ public class HDFArray { Long[] out = new Long[nelems]; for (int i = 0; i < nelems; i++) { - out[i] = new Long(in[i]); + out[i] = Long.valueOf(in[i]); } return out; } @@ -790,12 +784,12 @@ class ArrayDescriptor { static int dims = 0; static String className; - public ArrayDescriptor(Object anArray) throws HDF5Exception + public ArrayDescriptor(Object anArray) throws HDF5JavaException { Class tc = anArray.getClass(); if (tc.isArray() == false) { /* exception: not an array */ - HDF5Exception ex = new HDF5JavaException("ArrayDescriptor: not an array?: "); + HDF5JavaException ex = new HDF5JavaException("ArrayDescriptor: not an array?: "); throw (ex); } diff --git a/java/src/hdf/hdf5lib/HDFNativeData.java b/java/src/hdf/hdf5lib/HDFNativeData.java index 5b29050..85378db 100644 --- a/java/src/hdf/hdf5lib/HDFNativeData.java +++ b/java/src/hdf/hdf5lib/HDFNativeData.java @@ -153,8 +153,7 @@ public class HDFNativeData { * The input array of bytes * @return an array of 'len' float */ - public synchronized static native float[] byteToFloat(int start, int len, - byte[] data); + public synchronized static native float[] byteToFloat(int start, int len, byte[] data); /** * Convert 4 bytes from an array of bytes into a single float @@ -437,41 +436,38 @@ public class HDFNativeData { * - Error unsupported type. */ public synchronized static Object byteToNumber(byte[] barray, Object obj) - throws HDF5Exception { + throws HDF5Exception + { Class theClass = obj.getClass(); String type = theClass.getName(); Object retobj = null; if (type.equals("java.lang.Integer")) { int[] i = hdf.hdf5lib.HDFNativeData.byteToInt(0, 1, barray); - retobj = new Integer(i[0]); + retobj = Integer.valueOf(i[0]); } else if (type.equals("java.lang.Byte")) { - retobj = new Byte(barray[0]); + retobj = Byte.valueOf(barray[0]); } else if (type.equals("java.lang.Short")) { - short[] f = hdf.hdf5lib.HDFNativeData - .byteToShort(0, 1, barray); - retobj = new Short(f[0]); + short[] f = hdf.hdf5lib.HDFNativeData.byteToShort(0, 1, barray); + retobj = Short.valueOf(f[0]); } else if (type.equals("java.lang.Float")) { - float[] f = hdf.hdf5lib.HDFNativeData - .byteToFloat(0, 1, barray); - retobj = new Float(f[0]); + float[] f = hdf.hdf5lib.HDFNativeData.byteToFloat(0, 1, barray); + retobj = Float.valueOf(f[0]); } else if (type.equals("java.lang.Long")) { long[] f = hdf.hdf5lib.HDFNativeData.byteToLong(0, 1, barray); - retobj = new Long(f[0]); + retobj = Long.valueOf(f[0]); } else if (type.equals("java.lang.Double")) { - double[] f = hdf.hdf5lib.HDFNativeData.byteToDouble(0, 1, - barray); - retobj = new Double(f[0]); + double[] f = hdf.hdf5lib.HDFNativeData.byteToDouble(0, 1, barray); + retobj = Double.valueOf(f[0]); } else { /* exception: unsupported type */ - HDF5Exception ex = new HDF5JavaException( - "byteToNumber: setfield bad type: " + obj + " " + type); + HDF5Exception ex = new HDF5JavaException("byteToNumber: setfield bad type: " + obj + " " + type); throw (ex); } return (retobj); diff --git a/java/src/hdf/hdf5lib/structs/H5FD_hdfs_fapl_t.java b/java/src/hdf/hdf5lib/structs/H5FD_hdfs_fapl_t.java index 5da4abd..95a9254 100644 --- a/java/src/hdf/hdf5lib/structs/H5FD_hdfs_fapl_t.java +++ b/java/src/hdf/hdf5lib/structs/H5FD_hdfs_fapl_t.java @@ -1,15 +1,14 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Read-Only HDFS Virtual File Driver (VFD) * - * Copyright (c) 2018, The HDF Group. * + * Copyright by The HDF Group. * * * * All rights reserved. * * * - * NOTICE: * - * All information contained herein is, and remains, the property of The HDF * - * Group. The intellectual and technical concepts contained herein are * - * proprietary to The HDF Group. Dissemination of this information or * - * reproduction of this material is strictly forbidden unless prior written * - * permission is obtained from The HDF Group. * + * 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. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ package hdf.hdf5lib.structs; diff --git a/java/src/hdf/hdf5lib/structs/H5FD_ros3_fapl_t.java b/java/src/hdf/hdf5lib/structs/H5FD_ros3_fapl_t.java index 39f5424..ad02979 100644 --- a/java/src/hdf/hdf5lib/structs/H5FD_ros3_fapl_t.java +++ b/java/src/hdf/hdf5lib/structs/H5FD_ros3_fapl_t.java @@ -1,15 +1,14 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Read-Only S3 Virtual File Driver (VFD) * - * Copyright (c) 2017-2018, The HDF Group. * + * Copyright by The HDF Group. * * * * All rights reserved. * * * - * NOTICE: * - * All information contained herein is, and remains, the property of The HDF * - * Group. The intellectual and technical concepts contained herein are * - * proprietary to The HDF Group. Dissemination of this information or * - * reproduction of this material is strictly forbidden unless prior written * - * permission is obtained from The HDF Group. * + * 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. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ package hdf.hdf5lib.structs; diff --git a/java/src/jni/h5Constants.c b/java/src/jni/h5Constants.c index 7354e95..bdffdbd 100644 --- a/java/src/jni/h5Constants.c +++ b/java/src/jni/h5Constants.c @@ -26,8 +26,8 @@ extern "C" { #include <stdlib.h> #include "h5jni.h" -H5_GCC_DIAG_OFF("missing-prototypes") -H5_GCC_DIAG_OFF("unused-parameter") +H5_GCC_CLANG_DIAG_OFF("missing-prototypes") +H5_GCC_CLANG_DIAG_OFF("unused-parameter") JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_HDF5Constants_H5_1QUARTER_1HADDR_1MAX(JNIEnv *env, jclass cls) @@ -1212,7 +1212,7 @@ Java_hdf_hdf5lib_HDF5Constants_H5ES_1STATUS_1FAIL(JNIEnv *env, jclass cls) } /* Java does not have unsigned native types */ -H5_GCC_DIAG_OFF("sign-conversion") +H5_GCC_CLANG_DIAG_OFF("sign-conversion") JNIEXPORT jint JNICALL Java_hdf_hdf5lib_HDF5Constants_H5F_1ACC_1CREAT(JNIEnv *env, jclass cls) { @@ -1253,7 +1253,7 @@ Java_hdf_hdf5lib_HDF5Constants_H5F_1ACC_1SWMR_1WRITE(JNIEnv *env, jclass cls) { return H5F_ACC_SWMR_WRITE; } -H5_GCC_DIAG_ON("sign-conversion") +H5_GCC_CLANG_DIAG_ON("sign-conversion") JNIEXPORT jint JNICALL Java_hdf_hdf5lib_HDF5Constants_H5F_1CLOSE_1DEFAULT(JNIEnv *env, jclass cls) @@ -3724,8 +3724,8 @@ Java_hdf_hdf5lib_HDF5Constants_H5Z_1FILTER_1ALL(JNIEnv *env, jclass cls) return H5Z_FILTER_ALL; } -H5_GCC_DIAG_ON("missing-prototypes") -H5_GCC_DIAG_ON("unused-parameter") +H5_GCC_CLANG_DIAG_ON("missing-prototypes") +H5_GCC_CLANG_DIAG_ON("unused-parameter") #ifdef __cplusplus } /* end extern "C" */ diff --git a/java/src/jni/h5util.c b/java/src/jni/h5util.c index 8021438..4272205 100644 --- a/java/src/jni/h5util.c +++ b/java/src/jni/h5util.c @@ -870,11 +870,8 @@ h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *i } else { if (typeSize > 0) { - if (NULL == (this_str = (char *)HDmalloc(typeSize + 1))) + if (NULL == (this_str = HDstrdup(tmp_str))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); - - HDstrncpy(this_str, tmp_str, typeSize); - this_str[typeSize] = '\0'; } } @@ -3664,19 +3661,14 @@ obj_info_all(hid_t loc_id, const char *name, const H5L_info2_t *info, void *op_d info_all_t *datainfo = (info_all_t *)op_data; H5O_info2_t object_info; htri_t object_exists; - size_t str_len; datainfo->otype[datainfo->count] = -1; datainfo->ltype[datainfo->count] = -1; datainfo->obj_token[datainfo->count] = H5O_TOKEN_UNDEF; - str_len = HDstrlen(name); - if (NULL == (datainfo->objname[datainfo->count] = (char *)HDmalloc(str_len + 1))) + if (NULL == (datainfo->objname[datainfo->count] = HDstrdup(name))) goto done; - HDstrncpy(datainfo->objname[datainfo->count], name, str_len); - (datainfo->objname[datainfo->count])[str_len] = '\0'; - if ((object_exists = H5Oexists_by_name(loc_id, name, H5P_DEFAULT)) < 0) goto done; @@ -3702,7 +3694,6 @@ obj_info_max(hid_t loc_id, const char *name, const H5L_info2_t *info, void *op_d { info_all_t *datainfo = (info_all_t *)op_data; H5O_info2_t object_info; - size_t str_len; datainfo->otype[datainfo->count] = -1; datainfo->ltype[datainfo->count] = -1; @@ -3710,13 +3701,9 @@ obj_info_max(hid_t loc_id, const char *name, const H5L_info2_t *info, void *op_d datainfo->obj_token[datainfo->count] = H5O_TOKEN_UNDEF; /* This will be freed by h5str_array_free(oName, n) */ - str_len = HDstrlen(name); - if (NULL == (datainfo->objname[datainfo->count] = (char *)HDmalloc(str_len + 1))) + if (NULL == (datainfo->objname[datainfo->count] = HDstrdup(name))) goto done; - HDstrncpy(datainfo->objname[datainfo->count], name, str_len); - (datainfo->objname[datainfo->count])[str_len] = '\0'; - if (H5Oget_info3(loc_id, &object_info, H5O_INFO_ALL) < 0) goto done; diff --git a/java/test/TestH5Arw.java b/java/test/TestH5Arw.java index 282b736..8ce2fee 100644 --- a/java/test/TestH5Arw.java +++ b/java/test/TestH5Arw.java @@ -100,7 +100,7 @@ public class TestH5Arw { if (H5aid >= 0) try {H5.H5Aclose(H5aid);} catch (Exception ex) {} if (H5did >= 0) - try {H5.H5Aclose(H5did);} catch (Exception ex) {} + try {H5.H5Dclose(H5did);} catch (Exception ex) {} if (H5fid > 0) try {H5.H5Fclose(H5fid);} catch (Exception ex) {} H5fid = HDF5Constants.H5I_INVALID_HID; diff --git a/java/test/TestH5Pfapl.java b/java/test/TestH5Pfapl.java index cc674e2..a65b52e 100644 --- a/java/test/TestH5Pfapl.java +++ b/java/test/TestH5Pfapl.java @@ -102,7 +102,7 @@ public class TestH5Pfapl { for(int indx = 0; ;indx++) { java.text.DecimalFormat myFormat = new java.text.DecimalFormat("00000"); try { - file = new File("test"+myFormat.format(new Integer(indx))+".h5"); + file = new File("test"+myFormat.format(Integer.valueOf(indx))+".h5"); } catch (Throwable err) {} diff --git a/release_docs/INSTALL_CMake.txt b/release_docs/INSTALL_CMake.txt index 5d11957..91eb593 100644 --- a/release_docs/INSTALL_CMake.txt +++ b/release_docs/INSTALL_CMake.txt @@ -740,6 +740,7 @@ HDF5_BUILD_FORTRAN "Build FORTRAN support" OFF HDF5_BUILD_JAVA "Build JAVA support" OFF HDF5_BUILD_HL_LIB "Build HIGH Level HDF5 Library" ON HDF5_BUILD_TOOLS "Build HDF5 Tools" ON +HDF5_BUILD_HL_TOOLS "Build HIGH Level HDF5 Tools" ON ---------------- HDF5 Advanced Options --------------------- ONLY_SHARED_LIBS "Only Build Shared Libraries" OFF diff --git a/release_docs/README_HDF5_CMake b/release_docs/README_HDF5_CMake index cf0ab6f..c575320 100644 --- a/release_docs/README_HDF5_CMake +++ b/release_docs/README_HDF5_CMake @@ -1,15 +1,16 @@ This tar file contains - build-unix.sh script to build HDF5 with CMake on unix machines - build-unix-hpc.sh script to build HDF5 with CMake on unix machines and run - tests with batch scripts (sbatch). + build-unix.sh script to build HDF5 with CMake on unix machines + build-unix-hpc.sh script to build HDF5 with CMake on unix machines and run + tests with batch scripts (sbatch). CTestScript.cmake - HDF5config.cmake CMake scripts for building HDF5 + HDF5config.cmake CMake scripts for building HDF5 HDF5options.cmake - hdf5-1.13.0 HDF5 1.13.0 source - LIBAEC.tar.gz source for building SZIP replacement - ZLib.tar.gz source for building ZLIB - hdf5_plugins.tar.gz source for building compression plugins + hdf5-1.13.0 HDF5 1.13.0 source + LIBAEC.tar.gz source for building SZIP replacement + ZLib.tar.gz source for building ZLIB + hdf5_plugins.tar.gz source for building compression plugins + HDF5Examples-1.14.4-Source.tar.gz source for building examples For more information about building HDF5 with CMake, see USING_HDF5_CMake.txt in hdf5-1.13.0/release_docs, or diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 1e69f54..ed12c5e 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -49,6 +49,14 @@ New Features Configuration: ------------- + - Added new option to control the build of High-Level tools + that default ON/enabled. + + Add configure options (autotools - CMake): + enable-hltools HDF5_BUILD_HL_TOOLS + + (ADB - 2021/09/16, HDFFV-11266) + - Adds C++ Autotools configuration file for Intel * Checks for icpc as the compiler @@ -463,6 +471,25 @@ New Features Library: -------- + - Change how the release part of version, in major.minor.release is checked + for compatibility + + The HDF5 library uses a function, H5check_version, to check that + the version defined in the header files, which is used to compile an + application is compatible with the version codified in the library, which + the application loads at runtime. This previously required an exact match + or the library would print a warning, dump the build settings and then + abort or continue. An environment variable controlled the logic. + + Now the function first checks that the library release version, in + major.minor.release, is not older than the version in the headers. + Secondly, if the release version is different, it checks if either + the library version or the header version is in the exception list, in + which case the release part of version, in major.minor.release, must + be exact. An environment variable still controls the logic. + + (ADB - 2021/07/27) + - gcc warning suppression macros were moved out of H5public.h The HDF5 library uses a set of macros to suppress warnings on gcc. @@ -726,6 +753,11 @@ New Features Fortran Library: ---------------- + - H5Fget_name_f fixed to handle correctly trailing whitespaces and + newly allocated buffers. + + (MSB - 2021/08/30, github-826,972) + - Add wrappers for H5Pset/get_file_locking() API calls h5pget_file_locking_f() @@ -801,6 +833,26 @@ New Features Tools: ------ + - Refactored the perform tools and removed depends on test library. + + Moved the perf and h5perf tools from tools/test/perform to + tools/src/h5perf so that they can be installed. This required + that the test library dependency be removed by copying the + needed functions from h5test.c. + The standalone scripts and other perform tools remain in the + tools/test/perform folder. + + (ADB - 2021/08/10) + + - Removed partial long exceptions + + Some of the tools accepted shortened versions of the long options + (ex: --datas instead of --dataset). These were implemented inconsistently, + are difficult to maintian, and occasionally block useful long option + names. These partial long options have been removed from all the tools. + + (DER - 2021/08/03) + - h5repack added help text for user-defined filters. Added help text line that states the valid values of the filter flag @@ -863,7 +915,13 @@ New Features High-Level APIs: ---------------- - - + - added set/get for unsigned long long attributes + + the attribute writing high-level API has been expanded to include + public set/get functions for ULL attributes, analogously to the + existing set/get for other types. + + (AF - 2021/09/08) C Packet Table API: ------------------- @@ -885,6 +943,35 @@ Bug Fixes since HDF5-1.12.0 release =================================== Library ------- + - Detection of simple data transform function "x" + + In the case of the simple data transform function "x" the (parallel) + library recognizes this is the same as not applying this data transform + function. This improves the I/O performance. In the case of the parallel + library, it also avoids breaking to independent I/O, which makes it + possible to apply a filter when writing or reading data to or from + teh HDF5 file. + + (JWSB - 2021/09/13) + + - Fixed an invalid read and memory leak when parsing corrupt file space + info messages + + When the corrupt file from CVE-2020-10810 was parsed by the library, + the code that imports the version 0 file space info object header + message to the version 1 struct could read past the buffer read from + the disk, causing an invalid memory read. Not catching this error would + cause downstream errors that eventually resulted in a previously + allocated buffer to be unfreed when the library shut down. In builds + where the free lists are in use, this could result in an infinite loop + and SIGABRT when the library shuts down. + + We now track the buffer size and raise an error on attempts to read + past the end of it. + + (DER - 2021/08/12, HDFFV-11053) + + - Fixed CVE-2018-14460 The tool h5repack produced a segfault when the rank in dataspace @@ -1060,6 +1147,38 @@ Bug Fixes since HDF5-1.12.0 release Configuration ------------- + - Corrected pkg-config compile script + + It was discovered that the position of the "$@" argument for the command + in the compile script may fail on some platforms and configurations. The + position of the "$@"command argument was moved before the pkg-config sub command. + + (ADB - 2021/08/30) + + - Fixed CMake C++ compiler flags + + A recent refactoring of the C++ configure files accidently removed the + file that executed the enable_language command for C++ needed by the + HDFCXXCompilerFlags.cmake file. Also updated the intel warnings files, + including adding support for windows platforms. + + (ADB - 2021/08/10) + + - Better support for libaec (open-source Szip library) in CMake + + Implemented better support for libaec 1.0.5 (or later) library. This version + of libaec contains improvements for better integration with HDF5. Furthermore, + the variable USE_LIBAEC_STATIC has been introduced to allow to make use of + static version of libaec library. Use libaec_DIR or libaec_ROOT to set + the location in which libaec can be found. + + Be aware, the Szip library of libaec 1.0.4 depends on another library within + libaec library. This dependency is not specified in the current CMake + configuration which means that one can not use the static Szip library of + libaec 1.0.4 when building HDF5. This has been resolved in libaec 1.0.5. + + (JWSB - 2021/06/22) + - Refactor CMake configure for Fortran The Fortran configure tests for KINDs reused a single output file that was @@ -1421,6 +1540,10 @@ The following platforms are not supported but have been tested for this release. Known Problems ============== + Setting a variable-length dataset fill value will leak the memory allocated + for the p field of the hvl_t struct. A fix is in progress for this. + HDFFV-10840 + CMake files do not behave correctly with paths containing spaces. Do not use spaces in paths because the required escaping for handling spaces results in very complex and fragile build files. diff --git a/release_docs/USING_CMake_Examples.txt b/release_docs/USING_CMake_Examples.txt index bd089a6..a12a952 100644 --- a/release_docs/USING_CMake_Examples.txt +++ b/release_docs/USING_CMake_Examples.txt @@ -83,6 +83,7 @@ III. Defaults in the HDF5_Examples_options.cmake file #### HDF_BUILD_CXX:BOOL=OFF ### #### HDF_BUILD_FORTRAN:BOOL=OFF ### #### HDF_BUILD_JAVA:BOOL=OFF ### +#### HDF_BUILD_FILTERS:BOOL=OFF ### #### BUILD_TESTING:BOOL=OFF ### #### HDF_ENABLE_PARALLEL:BOOL=OFF ### #### HDF_ENABLE_THREADSAFE:BOOL=OFF ### diff --git a/release_docs/USING_HDF5_CMake.txt b/release_docs/USING_HDF5_CMake.txt index f2d7754..792c719 100644 --- a/release_docs/USING_HDF5_CMake.txt +++ b/release_docs/USING_HDF5_CMake.txt @@ -41,13 +41,30 @@ I. Preconditions 2. You have installed the HDF5 library built with CMake, by executing the HDF Install Utility (the *.msi file in the binary package for - Windows). If you are using a Windows platform, you can obtain a - pre-built Windows binary from The HDF Group's website at + Windows). You can obtain pre-built binaries from The HDF Group's website at www.hdfgroup.org. 3. Set the environment variable HDF5_DIR to the installed location of - the config files for HDF5. On Windows: + the config files for HDF5. + On Windows: HDF5_DIR=C:/Program Files/HDF_Group/HDF5/1.13.x/cmake + On unix: + HDF5_DIR=<install root folder>/HDF_Group/HDF5/1.13.x/cmake + + If you are using shared libraries, you may need to add to the path + environment variable. Set the path environment variable to the + installed location of the library files for HDF5. + On Windows (*.dll): + PATH=%PATH%;C:/Program Files/HDF_Group/HDF5/1.13.x/bin + On unix (*.so): + LD_LIBRARY_PATH=$LD_LIBRARY_PATH:<install root folder>/HDF_Group/HDF5/1.13.x/lib + + If you are using filter plugin libraries, you will need to set the + HDF5_PLUGIN_PATH environment variable. + On Windows: + HDF5_PLUGIN_PATH=C:/Program Files/HDF_Group/HDF5/1.13.x/lib/plugin + On unix: + HDF5_PLUGIN_PATH=<install root folder>/HDF_Group/HDF5/1.13.x/lib/plugin (Note there are no quote characters used on Windows and all platforms use forward slashes) @@ -99,12 +116,13 @@ These steps are described in more detail below. * MinGW Makefiles * NMake Makefiles * Unix Makefiles - * Visual Studio 12 2013 - * Visual Studio 12 2013 Win64 * Visual Studio 14 2015 * Visual Studio 14 2015 Win64 * Visual Studio 15 2017 * Visual Studio 15 2017 Win64 + * Visual Studio 16 2019 + * ... in addition VS2019 will need to set the "-A" option, + * ... [Win32, x64, ARM, ARM64] <options> is: * BUILD_TESTING:BOOL=ON @@ -114,7 +132,7 @@ These steps are described in more detail below. 2.1 Visual CMake users, click the Configure button. If this is the first time you are running cmake-gui in this directory, you will be prompted for the - generator you wish to use (for example on Windows, Visual Studio 12 2013). + generator you wish to use (for example on Windows, Visual Studio 14 2015 Win64). CMake will read in the CMakeLists.txt files from the source directory and display options for the HDF5 project. After the first configure you can adjust the cache settings and/or specify locations of other programs. @@ -132,7 +150,7 @@ These steps are described in more detail below. 2.2 Alternative command line example on Windows in c:\MyHDFstuff\hdf5\build directory: - cmake -G "Visual Studio 12 2013" -DBUILD_TESTING:BOOL=ON .. + cmake -G "Visual Studio 14 2015 Win64" -DBUILD_TESTING:BOOL=ON .. 3. Build HDF5 Applications diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a055271..955a394 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -180,6 +180,7 @@ set (H5ES_SOURCES ${HDF5_SRC_DIR}/H5ESlist.c ) set (H5ES_HDRS + ${HDF5_SRC_DIR}/H5ESdevelop.h ${HDF5_SRC_DIR}/H5ESpublic.h ) IDE_GENERATED_PROPERTIES ("H5ES" "${H5ES_HDRS}" "${H5ES_SOURCES}" ) @@ -669,6 +670,7 @@ IDE_GENERATED_PROPERTIES ("H5UC" "${H5UC_HDRS}" "${H5UC_SOURCES}" ) set (H5VL_SOURCES ${HDF5_SRC_DIR}/H5VL.c ${HDF5_SRC_DIR}/H5VLcallback.c + ${HDF5_SRC_DIR}/H5VLdyn_ops.c ${HDF5_SRC_DIR}/H5VLint.c ${HDF5_SRC_DIR}/H5VLnative.c ${HDF5_SRC_DIR}/H5VLnative_attr.c @@ -682,6 +684,7 @@ set (H5VL_SOURCES ${HDF5_SRC_DIR}/H5VLnative_object.c ${HDF5_SRC_DIR}/H5VLnative_token.c ${HDF5_SRC_DIR}/H5VLpassthru.c + ${HDF5_SRC_DIR}/H5VLtest.c ) set (H5VL_HDRS ${HDF5_SRC_DIR}/H5VLconnector.h diff --git a/src/H5.c b/src/H5.c index 3454786..69c81ea 100644 --- a/src/H5.c +++ b/src/H5.c @@ -70,6 +70,10 @@ hbool_t H5_PKG_INIT_VAR = FALSE; /* Library Private Variables */ /*****************************/ +/* Library incompatible release versions */ +const unsigned VERS_RELEASE_EXCEPTIONS[] = {0}; +const unsigned VERS_RELEASE_EXCEPTIONS_SIZE = 0; + /* statically initialize block for pthread_once call used in initializing */ /* the first global mutex */ #ifdef H5_HAVE_THREADSAFE @@ -285,13 +289,13 @@ done: } /* end H5_init_library() */ /*------------------------------------------------------------------------- - * Function: H5_term_library + * Function: H5_term_library * - * Purpose: Terminate interfaces in a well-defined order due to - * dependencies among the interfaces, then terminate - * library-specific data. + * Purpose: Terminate interfaces in a well-defined order due to + * dependencies among the interfaces, then terminate + * library-specific data. * - * Return: void + * Return: void * *------------------------------------------------------------------------- */ @@ -509,22 +513,22 @@ done: } /* end H5_term_library() */ /*------------------------------------------------------------------------- - * Function: H5dont_atexit + * Function: H5dont_atexit * - * Purpose: Indicates that the library is not to clean up after itself - * when the application exits by calling exit() or returning - * from main(). This function must be called before any other - * HDF5 function or constant is used or it will have no effect. + * Purpose: Indicates that the library is not to clean up after itself + * when the application exits by calling exit() or returning + * from main(). This function must be called before any other + * HDF5 function or constant is used or it will have no effect. * - * If this function is used then certain memory buffers will not - * be de-allocated nor will open files be flushed automatically. - * The application may still call H5close() explicitly to - * accomplish these things. + * If this function is used then certain memory buffers will not + * be de-allocated nor will open files be flushed automatically. + * The application may still call H5close() explicitly to + * accomplish these things. * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative if this function is called more than - * once or if it is called too late. + * Failure: negative if this function is called more than + * once or if it is called too late. * *------------------------------------------------------------------------- */ @@ -545,19 +549,19 @@ H5dont_atexit(void) } /* end H5dont_atexit() */ /*------------------------------------------------------------------------- - * Function: H5garbage_collect + * Function: H5garbage_collect * - * Purpose: Walks through all the garbage collection routines for the - * library, which are supposed to free any unused memory they have - * allocated. + * Purpose: Walks through all the garbage collection routines for the + * library, which are supposed to free any unused memory they have + * allocated. * * These should probably be registered dynamically in a linked list of * functions to call, but there aren't that many right now, so we * hard-wire them... * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * *------------------------------------------------------------------------- */ @@ -578,9 +582,9 @@ done: } /* end H5garbage_collect() */ /*------------------------------------------------------------------------- - * Function: H5set_free_list_limits + * Function: H5set_free_list_limits * - * Purpose: Sets limits on the different kinds of free lists. Setting a value + * Purpose: Sets limits on the different kinds of free lists. Setting a value * of -1 for a limit means no limit of that type. These limits are global * for the entire library. Each "global" limit only applies to free lists * of that type, so if an application sets a limit of 1 MB on each of the @@ -598,9 +602,9 @@ done: * int blk_global_lim; IN: The limit on all "block" free list memory used * int blk_list_lim; IN: The limit on memory used in each "block" free list * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * *------------------------------------------------------------------------- */ @@ -624,11 +628,11 @@ done: } /* end H5set_free_list_limits() */ /*------------------------------------------------------------------------- - * Function: H5get_free_list_sizes + * Function: H5get_free_list_sizes * - * Purpose: Gets the current size of the different kinds of free lists that - * the library uses to manage memory. The free list sizes can be set with - * H5set_free_list_limits and garbage collected with H5garbage_collect. + * Purpose: Gets the current size of the different kinds of free lists that + * the library uses to manage memory. The free list sizes can be set with + * H5set_free_list_limits and garbage collected with H5garbage_collect. * These lists are global for the entire library. * * Parameters: @@ -637,8 +641,8 @@ done: * size_t *blk_size; OUT: The current size of all "block" free list memory used * size_t *fac_size; OUT: The current size of all "factory" free list memory used * - * Return: Success: non-negative - * Failure: negative + * Return: Success: non-negative + * Failure: negative * * Programmer: Quincey Koziol * Friday, March 6, 2020 @@ -663,23 +667,23 @@ done: } /* end H5get_free_list_sizes() */ /*------------------------------------------------------------------------- - * Function: H5get_alloc_stats + * Function: H5get_alloc_stats * - * Purpose: Gets the memory allocation statistics for the library, if the - * --enable-memory-alloc-sanity-check option was given when building the + * Purpose: Gets the memory allocation statistics for the library, if the + * --enable-memory-alloc-sanity-check option was given when building the * library. Applications can check whether this option was enabled by - * detecting if the 'H5_MEMORY_ALLOC_SANITY_CHECK' macro is defined. This - * option is enabled by default for debug builds of the library and - * disabled by default for non-debug builds. If the option is not enabled, - * all the values returned with be 0. These statistics are global for the - * entire library, but don't include allocations from chunked dataset I/O - * filters or non-native VOL connectors. + * detecting if the 'H5_MEMORY_ALLOC_SANITY_CHECK' macro is defined. This + * option is enabled by default for debug builds of the library and + * disabled by default for non-debug builds. If the option is not enabled, + * all the values returned with be 0. These statistics are global for the + * entire library, but don't include allocations from chunked dataset I/O + * filters or non-native VOL connectors. * * Parameters: * H5_alloc_stats_t *stats; OUT: Memory allocation statistics * - * Return: Success: non-negative - * Failure: negative + * Return: Success: non-negative + * Failure: negative * * Programmer: Quincey Koziol * Saturday, March 7, 2020 @@ -812,12 +816,12 @@ H5__debug_mask(const char *s) #ifdef H5_HAVE_PARALLEL /*------------------------------------------------------------------------- - * Function: H5__mpi_delete_cb + * Function: H5__mpi_delete_cb * - * Purpose: Callback attribute on MPI_COMM_SELF to terminate the HDF5 + * Purpose: Callback attribute on MPI_COMM_SELF to terminate the HDF5 * library when the communicator is destroyed, i.e. on MPI_Finalize. * - * Return: MPI_SUCCESS + * Return: MPI_SUCCESS * *------------------------------------------------------------------------- */ @@ -831,18 +835,18 @@ H5__mpi_delete_cb(MPI_Comm H5_ATTR_UNUSED comm, int H5_ATTR_UNUSED keyval, void #endif /*H5_HAVE_PARALLEL*/ /*------------------------------------------------------------------------- - * Function: H5get_libversion + * Function: H5get_libversion * - * Purpose: Returns the library version numbers through arguments. MAJNUM - * will be the major revision number of the library, MINNUM the - * minor revision number, and RELNUM the release revision number. + * Purpose: Returns the library version numbers through arguments. MAJNUM + * will be the major revision number of the library, MINNUM the + * minor revision number, and RELNUM the release revision number. * - * Note: When printing an HDF5 version number it should be printed as + * Note: When printing an HDF5 version number it should be printed as * - * printf("%u.%u.%u", maj, min, rel) or - * printf("version %u.%u release %u", maj, min, rel) + * printf("%u.%u.%u", maj, min, rel) or + * printf("version %u.%u release %u", maj, min, rel) * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * *------------------------------------------------------------------------- */ @@ -867,17 +871,20 @@ done: } /* end H5get_libversion() */ /*------------------------------------------------------------------------- - * Function: H5check_version + * Function: H5check_version * - * Purpose: Verifies that the arguments match the version numbers - * compiled into the library. This function is intended to be - * called from user to verify that the versions of header files - * compiled into the application match the version of the hdf5 - * library. + * Purpose: Verifies that the arguments match the version numbers + * compiled into the library. This function is intended to be + * called from user to verify that the versions of header files + * compiled into the application match the version of the hdf5 + * library. + * Within major.minor.release version, the expectation + * is that all release versions are compatible, exceptions to + * this rule must be added to the VERS_RELEASE_EXCEPTIONS list. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: abort() + * Failure: abort() * *------------------------------------------------------------------------- */ @@ -890,6 +897,15 @@ done: "linked with a different version of static or shared HDF5 library.\n" \ "You should recompile the application or check your shared library related\n" \ "settings such as 'LD_LIBRARY_PATH'.\n" +#define RELEASE_MISMATCH_WARNING \ + "Warning! ***HDF5 library release mismatched error***\n" \ + "The HDF5 header files used to compile this application are not compatible with\n" \ + "the version used by the HDF5 library to which this application is linked.\n" \ + "Data corruption or segmentation faults may occur if the application continues.\n" \ + "This can happen when an application was compiled by one version of HDF5 but\n" \ + "linked with an incompatible version of static or shared HDF5 library.\n" \ + "You should recompile the application or check your shared library related\n" \ + "settings such as 'LD_LIBRARY_PATH'.\n" herr_t H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) @@ -918,7 +934,11 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) disable_version_check = (unsigned int)HDstrtol(s, NULL, 0); } - if (H5_VERS_MAJOR != majnum || H5_VERS_MINOR != minnum || H5_VERS_RELEASE != relnum) { + /* H5_VERS_MAJOR and H5_VERS_MINOR must match */ + /* Cast relnum to int to avoid warning for unsigned < 0 comparison + * in first release versions */ + if (H5_VERS_MAJOR != majnum || H5_VERS_MINOR != minnum || H5_VERS_RELEASE > (int)relnum) { + switch (disable_version_check) { case 0: HDfprintf(stderr, "%s%s", version_mismatch_warning, @@ -953,7 +973,51 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) break; } /* end switch */ - } /* end if */ + } /* end if (H5_VERS_MAJOR != majnum || H5_VERS_MINOR != minnum || H5_VERS_RELEASE > relnum) */ + + /* H5_VERS_RELEASE should be compatible, we will only add checks for exceptions */ + if (H5_VERS_RELEASE != relnum) { + for (unsigned i = 0; i < VERS_RELEASE_EXCEPTIONS_SIZE; i++) { + /* Check for incompatible headers or incompatible library */ + if (VERS_RELEASE_EXCEPTIONS[i] == relnum || VERS_RELEASE_EXCEPTIONS[i] == H5_VERS_RELEASE) { + switch (disable_version_check) { + case 0: + HDfprintf( + stderr, "%s%s", version_mismatch_warning, + "You can, at your own risk, disable this warning by setting the environment\n" + "variable 'HDF5_DISABLE_VERSION_CHECK' to a value of '1'.\n" + "Setting it to 2 or higher will suppress the warning messages totally.\n"); + /* Mention the versions we are referring to */ + HDfprintf(stderr, "Headers are %u.%u.%u, library is %u.%u.%u\n", majnum, minnum, + relnum, (unsigned)H5_VERS_MAJOR, (unsigned)H5_VERS_MINOR, + (unsigned)H5_VERS_RELEASE); + + /* Bail out now. */ + HDfputs("Bye...\n", stderr); + HDabort(); + case 1: + /* continue with a warning */ + /* Note that the warning message is embedded in the format string.*/ + HDfprintf(stderr, + "%s'HDF5_DISABLE_VERSION_CHECK' " + "environment variable is set to %d, application will\n" + "continue at your own risk.\n", + version_mismatch_warning, disable_version_check); + /* Mention the versions we are referring to */ + HDfprintf(stderr, "Headers are %u.%u.%u, library is %u.%u.%u\n", majnum, minnum, + relnum, (unsigned)H5_VERS_MAJOR, (unsigned)H5_VERS_MINOR, + (unsigned)H5_VERS_RELEASE); + break; + default: + /* 2 or higher: continue silently */ + break; + } /* end switch */ + + } /* end if */ + + } /* end for */ + + } /* end if (H5_VERS_RELEASE != relnum) */ /* Indicate that the version check has been performed */ checked = 1; @@ -964,12 +1028,9 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) * Check only the first sizeof(lib_str) char. Assume the information * will fit within this size or enough significance. */ - HDsnprintf(lib_str, sizeof(lib_str), "HDF5 library version: %d.%d.%d", H5_VERS_MAJOR, H5_VERS_MINOR, - H5_VERS_RELEASE); - if (*substr) { - HDstrncat(lib_str, "-", (size_t)1); - HDstrncat(lib_str, substr, (sizeof(lib_str) - HDstrlen(lib_str)) - 1); - } /* end if */ + HDsnprintf(lib_str, sizeof(lib_str), "HDF5 library version: %d.%d.%d%s%s", H5_VERS_MAJOR, + H5_VERS_MINOR, H5_VERS_RELEASE, (*substr ? "-" : ""), substr); + if (HDstrcmp(lib_str, H5_lib_vers_info_g) != 0) { HDfputs("Warning! Library version information error.\n" "The HDF5 library version information are not " @@ -998,7 +1059,7 @@ done: * is failing inexplicably, then try calling this function * first. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * *------------------------------------------------------------------------- */ @@ -1017,12 +1078,12 @@ done: } /* end H5open() */ /*------------------------------------------------------------------------- - * Function: H5atclose + * Function: H5atclose * - * Purpose: Register a callback for the library to invoke when it's - * closing. Callbacks are invoked in LIFO order. + * Purpose: Register a callback for the library to invoke when it's + * closing. Callbacks are invoked in LIFO order. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * *------------------------------------------------------------------------- */ @@ -1056,11 +1117,11 @@ done: } /* end H5atclose() */ /*------------------------------------------------------------------------- - * Function: H5close + * Function: H5close * - * Purpose: Terminate the library and release all resources. + * Purpose: Terminate the library and release all resources. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * *------------------------------------------------------------------------- */ @@ -1081,9 +1142,9 @@ H5close(void) } /* end H5close() */ /*------------------------------------------------------------------------- - * Function: H5allocate_memory + * Function: H5allocate_memory * - * Purpose: Allocate a memory buffer with the semantics of malloc(). + * Purpose: Allocate a memory buffer with the semantics of malloc(). * * NOTE: This function is intended for use with filter * plugins so that all allocation and free operations @@ -1121,9 +1182,9 @@ H5allocate_memory(size_t size, hbool_t clear) } /* end H5allocate_memory() */ /*------------------------------------------------------------------------- - * Function: H5resize_memory + * Function: H5resize_memory * - * Purpose: Resize a memory buffer with the semantics of realloc(). + * Purpose: Resize a memory buffer with the semantics of realloc(). * * NOTE: This function is intended for use with filter * plugins so that all allocation and free operations @@ -1158,14 +1219,14 @@ H5resize_memory(void *mem, size_t size) } /* end H5resize_memory() */ /*------------------------------------------------------------------------- - * Function: H5free_memory + * Function: H5free_memory * - * Purpose: Frees memory allocated by the library that it is the user's + * Purpose: Frees memory allocated by the library that it is the user's * responsibility to free. Ensures that the same library * that was used to allocate the memory frees it. Passing * NULL pointers is allowed. * - * Return: SUCCEED/FAIL + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ @@ -1182,12 +1243,12 @@ H5free_memory(void *mem) } /* end H5free_memory() */ /*------------------------------------------------------------------------- - * Function: H5is_library_threadsafe + * Function: H5is_library_threadsafe * - * Purpose: Checks to see if the library was built with thread-safety + * Purpose: Checks to see if the library was built with thread-safety * enabled. * - * Return: SUCCEED/FAIL + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ @@ -1213,16 +1274,16 @@ H5is_library_threadsafe(hbool_t *is_ts /*out*/) } /* end H5is_library_threadsafe() */ /*------------------------------------------------------------------------- - * Function: H5is_library_terminating + * Function: H5is_library_terminating * - * Purpose: Checks to see if the library is shutting down. + * Purpose: Checks to see if the library is shutting down. * - * Note: Useful for plugins to detect when the library is terminating. - * For example, a VOL connector could check if a "file close" - * callback was the result of the library shutdown process, or - * an API action from the application. + * Note: Useful for plugins to detect when the library is terminating. + * For example, a VOL connector could check if a "file close" + * callback was the result of the library shutdown process, or + * an API action from the application. * - * Return: SUCCEED/FAIL + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ diff --git a/src/H5A.c b/src/H5A.c index 4c1f5f1..c986d1f 100644 --- a/src/H5A.c +++ b/src/H5A.c @@ -320,7 +320,7 @@ H5A__create_by_name_api_common(hid_t loc_id, const char *obj_name, const char *a /* obj_name is verified in H5VL_setup_name_args() */ /* Set up object access arguments */ - if (H5VL_setup_name_args(loc_id, obj_name, H5P_CLS_LACC, TRUE, lapl_id, vol_obj_ptr, &loc_params) < 0) + if (H5VL_setup_name_args(loc_id, obj_name, TRUE, lapl_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") /* Verify access property list and set up collective metadata if appropriate */ @@ -630,7 +630,7 @@ H5A__open_by_name_api_common(hid_t loc_id, const char *obj_name, const char *att /* obj_name is verified in H5VL_setup_name_args() */ /* Set up object access arguments */ - if (H5VL_setup_name_args(loc_id, obj_name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) + if (H5VL_setup_name_args(loc_id, obj_name, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") /* Verify access property list and set up collective metadata if appropriate */ @@ -764,8 +764,8 @@ H5A__open_by_idx_api_common(hid_t loc_id, const char *obj_name, H5_index_t idx_t HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid iteration order specified") /* Set up object access arguments */ - if (H5VL_setup_idx_args(loc_id, obj_name, idx_type, order, n, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, - &loc_params) < 0) + if (H5VL_setup_idx_args(loc_id, obj_name, idx_type, order, n, FALSE, lapl_id, vol_obj_ptr, &loc_params) < + 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") /* Verify access property list and set up collective metadata if appropriate */ @@ -1057,7 +1057,7 @@ done: *--------------------------------------------------------------------------*/ herr_t H5Aread_async(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id, hid_t dtype_id, - void *buf, hid_t es_id) + void *buf /*out*/, hid_t es_id) { H5VL_object_t *vol_obj = NULL; /* Object for attr_id */ void * token = NULL; /* Request token for async operation */ @@ -1065,7 +1065,7 @@ H5Aread_async(const char *app_file, const char *app_func, unsigned app_line, hid herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE7("e", "*s*sIuii*xi", app_file, app_func, app_line, attr_id, dtype_id, buf, es_id); + H5TRACE7("e", "*s*sIuiixi", app_file, app_func, app_line, attr_id, dtype_id, buf, es_id); /* Set up request token pointer for asynchronous operation */ if (H5ES_NONE != es_id) @@ -1079,7 +1079,7 @@ H5Aread_async(const char *app_file, const char *app_func, unsigned app_line, hid if (NULL != token) /* clang-format off */ if (H5ES_insert(es_id, vol_obj->connector, token, - H5ARG_TRACE7(__func__, "*s*sIuii*xi", app_file, app_func, app_line, attr_id, dtype_id, buf, es_id)) < 0) + H5ARG_TRACE7(__func__, "*s*sIuiixi", app_file, app_func, app_line, attr_id, dtype_id, buf, es_id)) < 0) /* clang-format on */ HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set") @@ -1106,8 +1106,9 @@ done: hid_t H5Aget_space(hid_t attr_id) { - H5VL_object_t *vol_obj = NULL; /* Attribute object for ID */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Attribute object for ID */ + H5VL_attr_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", attr_id); @@ -1116,11 +1117,17 @@ H5Aget_space(hid_t attr_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not an attribute") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_GET_SPACE; + vol_cb_args.args.get_space.space_id = H5I_INVALID_HID; + /* Get the dataspace */ - if (H5VL_attr_get(vol_obj, H5VL_ATTR_GET_SPACE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &ret_value) < - 0) + if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, H5I_INVALID_HID, "unable to get dataspace of attribute") + /* Set the return value */ + ret_value = vol_cb_args.args.get_space.space_id; + done: FUNC_LEAVE_API(ret_value) } /* H5Aget_space() */ @@ -1144,8 +1151,9 @@ done: hid_t H5Aget_type(hid_t attr_id) { - H5VL_object_t *vol_obj = NULL; /* Attribute object for ID */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Attribute object for ID */ + H5VL_attr_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", attr_id); @@ -1154,10 +1162,17 @@ H5Aget_type(hid_t attr_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not an attribute") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_GET_TYPE; + vol_cb_args.args.get_type.type_id = H5I_INVALID_HID; + /* Get the datatype */ - if (H5VL_attr_get(vol_obj, H5VL_ATTR_GET_TYPE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &ret_value) < 0) + if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, H5I_INVALID_HID, "unable to get datatype of attribute") + /* Set the return value */ + ret_value = vol_cb_args.args.get_type.type_id; + done: FUNC_LEAVE_API(ret_value) } /* H5Aget_type() */ @@ -1184,8 +1199,9 @@ done: hid_t H5Aget_create_plist(hid_t attr_id) { - H5VL_object_t *vol_obj = NULL; /* Attribute object for ID */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Attribute object for ID */ + H5VL_attr_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", attr_id); @@ -1196,11 +1212,18 @@ H5Aget_create_plist(hid_t attr_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not an attribute") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_GET_ACPL; + vol_cb_args.args.get_acpl.acpl_id = H5I_INVALID_HID; + /* Get the acpl */ - if (H5VL_attr_get(vol_obj, H5VL_ATTR_GET_ACPL, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &ret_value) < 0) + if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, H5I_INVALID_HID, "unable to get creation property list for attribute") + /* Set the return value */ + ret_value = vol_cb_args.args.get_acpl.acpl_id; + done: FUNC_LEAVE_API(ret_value) } /* end H5Aget_create_plist() */ @@ -1229,9 +1252,10 @@ done: ssize_t H5Aget_name(hid_t attr_id, size_t buf_size, char *buf /*out*/) { - H5VL_object_t * vol_obj = NULL; /* Attribute object for ID */ - H5VL_loc_params_t loc_params; - ssize_t ret_value = -1; + H5VL_object_t * vol_obj = NULL; /* Attribute object for ID */ + H5VL_attr_get_args_t vol_cb_args; /* Arguments to VOL callback */ + size_t attr_name_len = 0; /* Length of attribute name */ + ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE3("Zs", "izx", attr_id, buf_size, buf); @@ -1242,15 +1266,21 @@ H5Aget_name(hid_t attr_id, size_t buf_size, char *buf /*out*/) if (!buf && buf_size) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "buf cannot be NULL if buf_size is non-zero") - /* Set location struct parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(attr_id); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_GET_NAME; + vol_cb_args.args.get_name.loc_params.type = H5VL_OBJECT_BY_SELF; + vol_cb_args.args.get_name.loc_params.obj_type = H5I_get_type(attr_id); + vol_cb_args.args.get_name.buf_size = buf_size; + vol_cb_args.args.get_name.buf = buf; + vol_cb_args.args.get_name.attr_name_len = &attr_name_len; /* Get the attribute name */ - if (H5VL_attr_get(vol_obj, H5VL_ATTR_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, - buf_size, buf, &ret_value) < 0) + if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, (-1), "unable to get attribute name") + /* Set the return value */ + ret_value = (ssize_t)attr_name_len; + done: FUNC_LEAVE_API(ret_value) } /* H5Aget_name() */ @@ -1276,9 +1306,10 @@ ssize_t H5Aget_name_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, char *name /*out*/, size_t size, hid_t lapl_id) { - H5VL_object_t * vol_obj; - H5VL_loc_params_t loc_params; - ssize_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Attribute object for ID */ + H5VL_attr_get_args_t vol_cb_args; /* Arguments to VOL callback */ + size_t attr_name_len = 0; /* Length of attribute name */ + ssize_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("Zs", "i*sIiIohxzi", loc_id, obj_name, idx_type, order, n, name, size, lapl_id); @@ -1303,19 +1334,26 @@ H5Aget_name_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_i if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") - loc_params.type = H5VL_OBJECT_BY_IDX; - loc_params.loc_data.loc_by_idx.name = obj_name; - loc_params.loc_data.loc_by_idx.idx_type = idx_type; - loc_params.loc_data.loc_by_idx.order = order; - loc_params.loc_data.loc_by_idx.n = n; - loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(loc_id); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_GET_NAME; + vol_cb_args.args.get_name.loc_params.type = H5VL_OBJECT_BY_IDX; + vol_cb_args.args.get_name.loc_params.loc_data.loc_by_idx.name = obj_name; + vol_cb_args.args.get_name.loc_params.loc_data.loc_by_idx.idx_type = idx_type; + vol_cb_args.args.get_name.loc_params.loc_data.loc_by_idx.order = order; + vol_cb_args.args.get_name.loc_params.loc_data.loc_by_idx.n = n; + vol_cb_args.args.get_name.loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; + vol_cb_args.args.get_name.loc_params.obj_type = H5I_get_type(loc_id); + vol_cb_args.args.get_name.buf_size = size; + vol_cb_args.args.get_name.buf = name; + vol_cb_args.args.get_name.attr_name_len = &attr_name_len; /* Get the name */ - if (H5VL_attr_get(vol_obj, H5VL_ATTR_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, - size, name, &ret_value) < 0) + if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get name") + /* Set the return value */ + ret_value = (ssize_t)attr_name_len; + done: FUNC_LEAVE_API(ret_value) } /* end H5Aget_name_by_idx() */ @@ -1340,8 +1378,10 @@ done: hsize_t H5Aget_storage_size(hid_t attr_id) { - H5VL_object_t *vol_obj; - hsize_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Attribute object for ID */ + H5VL_attr_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hsize_t storage_size = 0; /* Storage size of attribute */ + hsize_t ret_value; /* Return value */ FUNC_ENTER_API(0) H5TRACE1("h", "i", attr_id); @@ -1350,10 +1390,16 @@ H5Aget_storage_size(hid_t attr_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not an attribute") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_GET_STORAGE_SIZE; + vol_cb_args.args.get_storage_size.data_size = &storage_size; + /* Get the storage size */ - if (H5VL_attr_get(vol_obj, H5VL_ATTR_GET_STORAGE_SIZE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &ret_value) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, 0, "unable to get acpl") + if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, 0, "unable to get storage size") + + /* Set the return value */ + ret_value = storage_size; done: FUNC_LEAVE_API(ret_value) @@ -1375,9 +1421,9 @@ done: herr_t H5Aget_info(hid_t attr_id, H5A_info_t *ainfo /*out*/) { - H5VL_object_t * vol_obj; - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Attribute object for ID */ + H5VL_attr_get_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", attr_id, ainfo); @@ -1388,12 +1434,15 @@ H5Aget_info(hid_t attr_id, H5A_info_t *ainfo /*out*/) if (!ainfo) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "attribute_info parameter cannot be NULL") - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(attr_id); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_GET_INFO; + vol_cb_args.args.get_info.loc_params.type = H5VL_OBJECT_BY_SELF; + vol_cb_args.args.get_info.loc_params.obj_type = H5I_get_type(attr_id); + vol_cb_args.args.get_info.attr_name = NULL; + vol_cb_args.args.get_info.ainfo = ainfo; /* Get the attribute information */ - if (H5VL_attr_get(vol_obj, H5VL_ATTR_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, - ainfo) < 0) + if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info") done: @@ -1417,9 +1466,9 @@ herr_t H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, H5A_info_t *ainfo /*out*/, hid_t lapl_id) { - H5VL_object_t * vol_obj; - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Attribute object for ID */ + H5VL_attr_get_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "i*s*sxi", loc_id, obj_name, attr_name, ainfo, lapl_id); @@ -1438,18 +1487,21 @@ H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, H if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set access property list info") - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.loc_data.loc_by_name.name = obj_name; - loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(loc_id); - /* Get the object */ if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_GET_INFO; + vol_cb_args.args.get_info.loc_params.type = H5VL_OBJECT_BY_NAME; + vol_cb_args.args.get_info.loc_params.loc_data.loc_by_name.name = obj_name; + vol_cb_args.args.get_info.loc_params.loc_data.loc_by_name.lapl_id = lapl_id; + vol_cb_args.args.get_info.loc_params.obj_type = H5I_get_type(loc_id); + vol_cb_args.args.get_info.attr_name = attr_name; + vol_cb_args.args.get_info.ainfo = ainfo; + /* Get the attribute information */ - if (H5VL_attr_get(vol_obj, H5VL_ATTR_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, - ainfo, attr_name) < 0) + if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info") done: @@ -1474,9 +1526,9 @@ herr_t H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5A_info_t *ainfo /*out*/, hid_t lapl_id) { - H5VL_object_t * vol_obj; - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Attribute object for ID */ + H5VL_attr_get_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE7("e", "i*sIiIohxi", loc_id, obj_name, idx_type, order, n, ainfo, lapl_id); @@ -1497,21 +1549,24 @@ H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_i if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set access property list info") - loc_params.type = H5VL_OBJECT_BY_IDX; - loc_params.loc_data.loc_by_idx.name = obj_name; - loc_params.loc_data.loc_by_idx.idx_type = idx_type; - loc_params.loc_data.loc_by_idx.order = order; - loc_params.loc_data.loc_by_idx.n = n; - loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(loc_id); - /* Get the object */ if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_GET_INFO; + vol_cb_args.args.get_info.loc_params.type = H5VL_OBJECT_BY_IDX; + vol_cb_args.args.get_info.loc_params.loc_data.loc_by_idx.name = obj_name; + vol_cb_args.args.get_info.loc_params.loc_data.loc_by_idx.idx_type = idx_type; + vol_cb_args.args.get_info.loc_params.loc_data.loc_by_idx.order = order; + vol_cb_args.args.get_info.loc_params.loc_data.loc_by_idx.n = n; + vol_cb_args.args.get_info.loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; + vol_cb_args.args.get_info.loc_params.obj_type = H5I_get_type(loc_id); + vol_cb_args.args.get_info.attr_name = NULL; + vol_cb_args.args.get_info.ainfo = ainfo; + /* Get the attribute information */ - if (H5VL_attr_get(vol_obj, H5VL_ATTR_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, - ainfo) < 0) + if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info") done: @@ -1541,12 +1596,19 @@ H5A__rename_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const HDassert(new_name); /* Avoid thrashing things if the names are the same */ - if (HDstrcmp(old_name, new_name) != 0) + if (HDstrcmp(old_name, new_name) != 0) { + H5VL_attr_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_RENAME; + vol_cb_args.args.rename.old_name = old_name; + vol_cb_args.args.rename.new_name = new_name; + /* Rename the attribute */ - if (H5VL_attr_specific(vol_obj, loc_params, H5VL_ATTR_RENAME, H5P_DATASET_XFER_DEFAULT, token_ptr, - old_name, new_name) < 0) + if (H5VL_attr_specific(vol_obj, loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute from '%s' to '%s'", old_name, new_name) + } done: FUNC_LEAVE_NOAPI(ret_value) @@ -1700,7 +1762,7 @@ H5A__rename_by_name_api_common(hid_t loc_id, const char *obj_name, const char *o /* obj_name is verified in H5VL_setup_name_args() */ /* Set up object access arguments */ - if (H5VL_setup_name_args(loc_id, obj_name, H5P_CLS_LACC, TRUE, lapl_id, vol_obj_ptr, &loc_params) < 0) + if (H5VL_setup_name_args(loc_id, obj_name, TRUE, lapl_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set object access arguments") /* Rename the attribute */ @@ -1830,14 +1892,15 @@ herr_t H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx /*in,out */, H5A_operator2_t op, void *op_data) { - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5VL_attr_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "iIiIo*hAO*x", loc_id, idx_type, order, idx, op, op_data); - /* check arguments */ + /* Check arguments */ if (H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) @@ -1845,16 +1908,25 @@ H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *i if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") + /* Get the loc object */ + if (NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Set the location access parameters */ loc_params.type = H5VL_OBJECT_BY_SELF; loc_params.obj_type = H5I_get_type(loc_id); - /* get the loc object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_ITER; + vol_cb_args.args.iterate.idx_type = idx_type; + vol_cb_args.args.iterate.order = order; + vol_cb_args.args.iterate.idx = idx; + vol_cb_args.args.iterate.op = op; + vol_cb_args.args.iterate.op_data = op_data; /* Iterate over attributes */ - if ((ret_value = H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_ITER, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, (int)idx_type, (int)order, idx, op, op_data)) < 0) + if ((ret_value = H5VL_attr_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HERROR(H5E_ATTR, H5E_BADITER, "error iterating over attributes"); done: @@ -1908,9 +1980,10 @@ herr_t H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx /*in,out */, H5A_operator2_t op, void *op_data, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* Object location */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5VL_attr_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("e", "i*sIiIo*hAO*xi", loc_id, obj_name, idx_type, order, idx, op, op_data, lapl_id); @@ -1929,18 +2002,27 @@ H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_i if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set access property list info") + /* get the loc object */ + if (NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Set the location access parameters */ loc_params.type = H5VL_OBJECT_BY_NAME; loc_params.obj_type = H5I_get_type(loc_id); loc_params.loc_data.loc_by_name.name = obj_name; loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - /* get the loc object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_ITER; + vol_cb_args.args.iterate.idx_type = idx_type; + vol_cb_args.args.iterate.order = order; + vol_cb_args.args.iterate.idx = idx; + vol_cb_args.args.iterate.op = op; + vol_cb_args.args.iterate.op_data = op_data; /* Iterate over attributes */ - if ((ret_value = H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_ITER, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, (int)idx_type, (int)order, idx, op, op_data)) < 0) + if ((ret_value = H5VL_attr_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HERROR(H5E_ATTR, H5E_BADITER, "attribute iteration failed"); done: @@ -1964,9 +2046,10 @@ done: herr_t H5Adelete(hid_t loc_id, const char *name) { - H5VL_object_t * vol_obj = NULL; - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5VL_attr_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*s", loc_id, name); @@ -1983,17 +2066,20 @@ H5Adelete(hid_t loc_id, const char *name) if (H5CX_set_loc(loc_id) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set collective metadata read") - /* Fill in location struct fields */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(loc_id); - /* Get the object */ if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Set the location access parameters */ + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_DELETE; + vol_cb_args.args.del.name = name; + /* Delete the attribute */ - if (H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_DELETE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - name) < 0) + if (H5VL_attr_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") done: @@ -2019,9 +2105,10 @@ done: herr_t H5Adelete_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t lapl_id) { - H5VL_object_t * vol_obj; - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5VL_attr_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "i*s*si", loc_id, obj_name, attr_name, lapl_id); @@ -2038,19 +2125,22 @@ H5Adelete_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set access property list info") - /* Fill in location struct fields */ + /* Get the object */ + if (NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + + /* Set the location access parameters */ loc_params.type = H5VL_OBJECT_BY_NAME; loc_params.loc_data.loc_by_name.name = obj_name; loc_params.loc_data.loc_by_name.lapl_id = lapl_id; loc_params.obj_type = H5I_get_type(loc_id); - /* Get the object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_DELETE; + vol_cb_args.args.del.name = attr_name; /* Delete the attribute */ - if (H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_DELETE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - attr_name) < 0) + if (H5VL_attr_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") done: @@ -2085,9 +2175,10 @@ herr_t H5Adelete_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t lapl_id) { - H5VL_object_t * vol_obj; - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5VL_attr_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "i*sIiIohi", loc_id, obj_name, idx_type, order, n, lapl_id); @@ -2106,21 +2197,24 @@ H5Adelete_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_ite if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set access property list info") - loc_params.type = H5VL_OBJECT_BY_IDX; - loc_params.loc_data.loc_by_idx.name = obj_name; - loc_params.loc_data.loc_by_idx.idx_type = idx_type; - loc_params.loc_data.loc_by_idx.order = order; - loc_params.loc_data.loc_by_idx.n = n; - loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(loc_id); - /* get the object */ if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Set the location access parameters */ + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = obj_name; + loc_params.loc_data.loc_by_name.lapl_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_DELETE_BY_IDX; + vol_cb_args.args.delete_by_idx.idx_type = idx_type; + vol_cb_args.args.delete_by_idx.order = order; + vol_cb_args.args.delete_by_idx.n = n; + /* Delete the attribute */ - if (H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_DELETE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - NULL) < 0) + if (H5VL_attr_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") done: @@ -2233,7 +2327,8 @@ static herr_t H5A__exists_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name, hbool_t *attr_exists, void **token_ptr) { - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_attr_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -2245,9 +2340,13 @@ H5A__exists_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const if (!attr_name || !*attr_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_EXISTS; + vol_cb_args.args.exists.name = attr_name; + vol_cb_args.args.exists.exists = attr_exists; + /* Check if the attribute exists */ - if (H5VL_attr_specific(vol_obj, loc_params, H5VL_ATTR_EXISTS, H5P_DATASET_XFER_DEFAULT, token_ptr, - attr_name, attr_exists) < 0) + if (H5VL_attr_specific(vol_obj, loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") done: @@ -2400,7 +2499,7 @@ H5A__exists_by_name_api_common(hid_t loc_id, const char *obj_name, const char *a /* obj_name is verified in H5VL_setup_name_args() */ /* Set up object access arguments */ - if (H5VL_setup_name_args(loc_id, obj_name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) + if (H5VL_setup_name_args(loc_id, obj_name, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set object access arguments") /* Check if the attribute exists */ diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h index 188f9ee..a4e6d60 100644 --- a/src/H5ACprivate.h +++ b/src/H5ACprivate.h @@ -275,24 +275,24 @@ typedef struct H5AC_proxy_entry_t { /* size_t min_size = */ ( 1 * 1024 * 1024), \ /* long int epoch_length = */ 50000, \ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, \ - /* double lower_hr_threshold = */ 0.9f, \ - /* double increment = */ 2.0f, \ + /* double lower_hr_threshold = */ 0.9, \ + /* double increment = */ 2.0, \ /* hbool_t apply_max_increment = */ TRUE, \ /* size_t max_increment = */ (4 * 1024 * 1024), \ /* enum H5C_cache_flash_incr_mode */ \ /* flash_incr_mode = */ H5C_flash_incr__add_space, \ - /* double flash_multiple = */ 1.4f, \ - /* double flash_threshold = */ 0.25f, \ + /* double flash_multiple = */ 1.4, \ + /* double flash_threshold = */ 0.25, \ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,\ - /* double upper_hr_threshold = */ 0.999f, \ - /* double decrement = */ 0.9f, \ + /* double upper_hr_threshold = */ 0.999, \ + /* double decrement = */ 0.9, \ /* hbool_t apply_max_decrement = */ TRUE, \ /* size_t max_decrement = */ (1 * 1024 * 1024), \ /* int epochs_before_eviction = */ 3, \ /* hbool_t apply_empty_reserve = */ TRUE, \ - /* double empty_reserve = */ 0.1f, \ + /* double empty_reserve = */ 0.1, \ /* size_t dirty_bytes_threshold = */ (256 * 1024), \ - /* int metadata_write_strategy = */ \ + /* int metadata_write_strategy = */ \ H5AC__DEFAULT_METADATA_WRITE_STRATEGY \ } #endif /* H5_HAVE_PARALLEL */ diff --git a/src/H5Adeprec.c b/src/H5Adeprec.c index 3d4e391..8ae4e41 100644 --- a/src/H5Adeprec.c +++ b/src/H5Adeprec.c @@ -309,10 +309,11 @@ done: int H5Aget_num_attrs(hid_t loc_id) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5O_info2_t oinfo; - int ret_value = -1; + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + H5O_info2_t oinfo; + int ret_value = -1; FUNC_ENTER_API((-1)) H5TRACE1("Is", "i", loc_id); @@ -324,9 +325,13 @@ H5Aget_num_attrs(hid_t loc_id) if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_INFO; + vol_cb_args.args.get_info.oinfo = &oinfo; + vol_cb_args.args.get_info.fields = H5O_INFO_NUM_ATTRS; + /* Get the number of attributes for the object */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &oinfo, H5O_INFO_NUM_ATTRS) < 0) + if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, (-1), "unable to get attribute count for object") H5_CHECKED_ASSIGN(ret_value, int, oinfo.num_attrs, hsize_t); @@ -375,8 +380,10 @@ done: herr_t H5Aiterate1(hid_t loc_id, unsigned *attr_num /*in,out*/, H5A_operator1_t op, void *op_data) { - H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_attr_optional_args_t attr_opt_args; /* Arguments for optional operation */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(H5_ITER_ERROR) H5TRACE4("e", "i*IuAo*x", loc_id, attr_num, op, op_data); @@ -389,9 +396,17 @@ H5Aiterate1(hid_t loc_id, unsigned *attr_num /*in,out*/, H5A_operator1_t op, voi if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ATTR, H5E_BADTYPE, H5_ITER_ERROR, "invalid location identifier") + /* Set up VOL callback arguments */ + attr_opt_args.iterate_old.loc_id = loc_id; + attr_opt_args.iterate_old.attr_num = attr_num; + attr_opt_args.iterate_old.op = op; + attr_opt_args.iterate_old.op_data = op_data; + vol_cb_args.op_type = H5VL_NATIVE_ATTR_ITERATE_OLD; + vol_cb_args.args = &attr_opt_args; + /* Call attribute iteration routine */ - if ((ret_value = H5VL_attr_optional(vol_obj, H5VL_NATIVE_ATTR_ITERATE_OLD, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, loc_id, attr_num, op, op_data)) < 0) + if ((ret_value = H5VL_attr_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL)) < + 0) HERROR(H5E_ATTR, H5E_BADITER, "error iterating over attributes"); done: diff --git a/src/H5Aint.c b/src/H5Aint.c index 8ec5463..300d686 100644 --- a/src/H5Aint.c +++ b/src/H5Aint.c @@ -844,7 +844,6 @@ done: const void *buf; IN: Buffer of data to write RETURNS Non-negative on success/Negative on failure - DESCRIPTION This function writes a complete attribute to disk. --------------------------------------------------------------------------*/ @@ -949,31 +948,33 @@ done: NAME H5A__get_name PURPOSE - Private function for H5Aget_name. Gets a copy of the name for an - attribute + Gets a copy of the name for an attribute RETURNS - This function returns the length of the attribute's name (which may be - longer than 'buf_size') on success or negative for failure. + Non-negative on success/Negative on failure DESCRIPTION This function retrieves the name of an attribute for an attribute ID. Up to 'buf_size' characters are stored in 'buf' followed by a '\0' string terminator. If the name of the attribute is longer than 'buf_size'-1, the string terminator is stored in the last position of the buffer to properly terminate the string. + This function returns the length of the attribute's name (which may be + longer than 'buf_size') in the 'attr_name_len' parameter. --------------------------------------------------------------------------*/ -ssize_t -H5A__get_name(H5A_t *attr, size_t buf_size, char *buf) +herr_t +H5A__get_name(H5A_t *attr, size_t buf_size, char *buf, size_t *attr_name_len) { - size_t copy_len, nbytes; - ssize_t ret_value = -1; /* Return value */ + size_t copy_len, nbytes; FUNC_ENTER_PACKAGE_NOERR - /* get the real attribute length */ + /* Sanity checks */ + HDassert(attr); + HDassert(attr_name_len); + + /* Get the real attribute length */ nbytes = HDstrlen(attr->shared->name); - HDassert((ssize_t)nbytes >= 0); /*overflow, pretty unlikely --rpm*/ - /* compute the string length which will fit into the user's buffer */ + /* Compute the string length which will fit into the user's buffer */ copy_len = MIN(buf_size - 1, nbytes); /* Copy all/some of the name */ @@ -984,10 +985,10 @@ H5A__get_name(H5A_t *attr, size_t buf_size, char *buf) buf[copy_len] = '\0'; } /* end if */ - /* Set return value */ - ret_value = (ssize_t)nbytes; + /* Set actual attribute name length */ + *attr_name_len = nbytes; - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(SUCCEED) } /* H5A__get_name() */ /*------------------------------------------------------------------------- @@ -1091,13 +1092,10 @@ done: NAME H5A__get_create_plist PURPOSE - private version of H5Aget_create_plist + Private version of H5Aget_create_plist RETURNS This function returns the ID of a copy of the attribute's creation property list, or negative on failure. - - ERRORS - DESCRIPTION This function returns a copy of the creation property list for an attribute. The resulting ID must be closed with H5Pclose() or @@ -1304,7 +1302,7 @@ H5A__close_cb(H5VL_object_t *attr_vol_obj, void **request) HDassert(attr_vol_obj); /* Close the attribute */ - if ((ret_value = H5VL_attr_close(attr_vol_obj, H5P_DATASET_XFER_DEFAULT, request)) < 0) + if (H5VL_attr_close(attr_vol_obj, H5P_DATASET_XFER_DEFAULT, request) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "problem closing attribute") /* Free the VOL object */ @@ -2768,7 +2766,7 @@ H5A__iterate(const H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type, H5 /* Call internal attribute iteration routine */ if ((ret_value = H5A__iterate_common(obj_loc_id, idx_type, order, idx, &attr_op, op_data)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_BADITER, FAIL, "error iterating over attributes") + HERROR(H5E_ATTR, H5E_BADITER, "error iterating over attributes"); done: /* Release resources */ diff --git a/src/H5Amodule.h b/src/H5Amodule.h index c89c93f..9f86ddd 100644 --- a/src/H5Amodule.h +++ b/src/H5Amodule.h @@ -33,33 +33,29 @@ * * Use the functions in this module to manage HDF5 attributes. * - * The Attribute Interface, H5A, provides a mechanism for attaching additional - * information to a dataset, group, or named datatype. - * - * Attributes are accessed by opening the object that they are attached to and - * are not independent objects. Typically an attribute is small in size and - * contains user metadata about the object that it is attached to. - * - * Attributes look similar to HDF5 datasets in that they have a datatype and - * dataspace. However, they do not support partial I/O operations and cannot be - * compressed or extended. + * Like HDF5 datasets, HDF5 attributes are array variables which have an element + * datatype and a shape (dataspace). However, they perform a different function: + * Attributes decorate other HDF5 objects, and are typically used to + * represent application metadata. Unlike datasets, the HDF5 library does not + * support partial I/O operations for attributes and they cannot be compressed + * or extended. * * <table> * <tr><th>Create</th><th>Read</th></tr> * <tr valign="top"> * <td> - * \snippet H5A_examples.c create + * \snippet{lineno} H5A_examples.c create * </td> * <td> - * \snippet H5A_examples.c read + * \snippet{lineno} H5A_examples.c read * </td> * <tr><th>Update</th><th>Delete</th></tr> * <tr valign="top"> * <td> - * \snippet H5A_examples.c update + * \snippet{lineno} H5A_examples.c update * </td> * <td> - * \snippet H5A_examples.c delete + * \snippet{lineno} H5A_examples.c delete * </td> * </tr> * </table> diff --git a/src/H5Apkg.h b/src/H5Apkg.h index a349f9f..b50cbc4 100644 --- a/src/H5Apkg.h +++ b/src/H5Apkg.h @@ -200,14 +200,14 @@ H5_DLL herr_t H5A__iterate(const H5G_loc_t *loc, const char *obj_name, H5_index_ #ifndef H5_NO_DEPRECATED_SYMBOLS H5_DLL herr_t H5A__iterate_old(hid_t loc_id, unsigned *attr_num, H5A_operator1_t op, void *op_data); #endif /* H5_NO_DEPRECATED_SYMBOLS */ -H5_DLL herr_t H5A__delete_by_name(const H5G_loc_t *loc, const char *obj_name, const char *attr_name); -H5_DLL herr_t H5A__delete_by_idx(const H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n); -H5_DLL herr_t H5A__exists_by_name(H5G_loc_t loc, const char *obj_name, const char *attr_name, - hbool_t *attr_exists); -H5_DLL herr_t H5A__write(H5A_t *attr, const H5T_t *mem_type, const void *buf); -H5_DLL herr_t H5A__read(const H5A_t *attr, const H5T_t *mem_type, void *buf); -H5_DLL ssize_t H5A__get_name(H5A_t *attr, size_t buf_size, char *buf); +H5_DLL herr_t H5A__delete_by_name(const H5G_loc_t *loc, const char *obj_name, const char *attr_name); +H5_DLL herr_t H5A__delete_by_idx(const H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n); +H5_DLL herr_t H5A__exists_by_name(H5G_loc_t loc, const char *obj_name, const char *attr_name, + hbool_t *attr_exists); +H5_DLL herr_t H5A__write(H5A_t *attr, const H5T_t *mem_type, const void *buf); +H5_DLL herr_t H5A__read(const H5A_t *attr, const H5T_t *mem_type, void *buf); +H5_DLL herr_t H5A__get_name(H5A_t *attr, size_t buf_size, char *buf, size_t *attr_name_len); /* Attribute "dense" storage routines */ H5_DLL herr_t H5A__dense_create(H5F_t *f, H5O_ainfo_t *ainfo); diff --git a/src/H5Apublic.h b/src/H5Apublic.h index b3da77f..b78ae05 100644 --- a/src/H5Apublic.h +++ b/src/H5Apublic.h @@ -78,11 +78,11 @@ extern "C" { * * \return \herr_t * - * \details H5Aclose() terminates access to the attribute specified by - * \p attr_id by releasing the identifier. + * \details H5Aclose() terminates access to the attribute through + * \p attr_id and releases the identifier. * - * \attention Further use of a released attribute identifier is illegal; a - * function using such an identifier will generate an error. + * \par Example + * \snippet H5A_examples.c create * * \since 1.0.0 * @@ -117,27 +117,19 @@ H5_DLL herr_t H5Aclose_async(const char *app_file, const char *app_func, unsigne * The attribute name, \p attr_name, must be unique for the object. * * The attribute is created with the specified datatype and dataspace, - * \p type_id and \p space_id, which are created with the H5T and - * H5S interfaces, respectively. + * \p type_id and \p space_id. * - * If \p type_id is either a fixed-length or variable-length string, - * it is important to set the string length when defining the - * datatype. String datatypes are derived from #H5T_C_S1 (or - * #H5T_FORTRAN_S1 for Fortran), which defaults to 1 character in - * size. See H5Tset_size() and Creating variable-length string - * datatypes. - * - * The access property list is currently unused, but will be used in - * the future. This property list should currently be #H5P_DEFAULT. + * \plist_unused{acpl} * * The attribute identifier returned by this function must be released * with H5Aclose() resource leaks will develop. * - * \note The \p aapl parameter is currently not used; specify #H5P_DEFAULT. - * * \note If \p loc_id is a file identifier, the attribute will be attached * that file’s root group. * + * \par Example + * \snippet H5A_examples.c create + * * \since 1.8.0 * * \see H5Aclose() @@ -175,28 +167,19 @@ H5_DLL hid_t H5Acreate_async(const char *app_file, const char *app_func, unsigne * attached to the object specified by \p loc_id and \p obj_name. * * \p loc_id is a location identifier; \p obj_name is the object - * name relative to \p loc_id. If \p loc_id fully specifies the - * object to which the attribute is to be attached, \p obj_name - * should be '.' (a dot). + * name relative to \p loc_id. * * The attribute name, \p attr_name, must be unique for the object. * * The attribute is created with the specified datatype and - * dataspace, \p type_id and \p space_id, which are created with - * the H5T and H5S interfaces respectively. + * dataspace, \p type_id and \p space_id. * - * The attribute creation and access property lists are currently - * unused, but will be used in the future for optional attribute - * creation and access properties. These property lists should - * currently be #H5P_DEFAULT. + * \plist_unused{aapl} * * The link access property list, \p lapl_id, may provide * information regarding the properties of links required to access * the object, \p obj_name. * - * The attribute identifier returned by this function must be - * released with H5close() or resource leaks will develop. - * * \since 1.8.0 * */ @@ -224,10 +207,14 @@ H5_DLL hid_t H5Acreate_by_name_async(const char *app_file, const char *app_func, * * \details H5Adelete() removes the attribute specified by its name, * \p attr_name, from a file, dataset, group, or named datatype. - * This function should not be used when attribute identifiers - * are open on \p loc_id as it may cause the internal indexes of - * the attributes to change and future writes to the open - * attributes to produce incorrect results. + * + * \attention This function should not be used when other attribute identifiers + * are open on \p loc_id. This may cause the internal indexes of + * the attributes to change and future writes to the open + * attributes to produce incorrect results. + * + * \par Example + * \snippet H5A_examples.c delete * * \since 1.0.0 * @@ -254,27 +241,16 @@ H5_DLL herr_t H5Adelete(hid_t loc_id, const char *attr_name); * * The object from which the attribute is to be removed is * specified by a location identifier and name, \p loc_id and - * \p obj_name, respectively. If \p loc_id fully specifies the - * object from which the attribute is to be removed, \p obj_name - * should be '.' (a dot). + * \p obj_name, respectively. * * The attribute to be removed is specified by a position in an - * index, \p n. The type of index is specified by \p idx_type and - * may be #H5_INDEX_NAME, for an alpha-numeric index by name, or - * #H5_INDEX_CRT_ORDER, for an index by creation order. The order - * in which the index is to be traversed is specified by \p order - * and may be #H5_ITER_INC (increment) for top-down iteration, - * #H5_ITER_DEC (decrement) for bottom-up iteration, or - * #H5_ITER_NATIVE, in which case HDF5 will iterate in the - * fastest-available order. For example, if \p idx_type, \p order, + * index, \p n. The type of index is specified by \p idx_type. + * The order in which the index is to be traversed is specified by + * \p order. For example, if \p idx_type, \p order, * and \p n are set to #H5_INDEX_NAME, #H5_ITER_INC, and 5, - * respectively, the fifth attribute by alpha-numeric order of + * respectively, the fifth attribute in lexicographic order of * attribute names will be removed. * - * For a discussion of \p idx_type and \p order, the valid values - * of those parameters, and the use of \p n, see the description - * of H5Aiterate2(). - * * The link access property list, \p lapl_id, may provide * information regarding the properties of links required to access * the object, \p obj_name. @@ -302,9 +278,6 @@ H5_DLL herr_t H5Adelete_by_idx(hid_t loc_id, const char *obj_name, H5_index_t id * from an object specified by location and name, \p loc_id and * \p obj_name, respectively. * - * If \p loc_id fully specifies the object from which the - * attribute is to be removed, \p obj_name should be '.' (a dot). - * * The link access property list, \p lapl_id, may provide * information regarding the properties of links required to * access the object, \p obj_name. @@ -360,9 +333,7 @@ H5_DLL herr_t H5Aexists_async(const char *app_file, const char *app_func, unsign * \p loc_id specifies a location in the file containing the object. * \p obj_name is the name of the object to which the attribute is * attached and can be a relative name, relative to \p loc_id, - * or an absolute name, based in the root group of the file. If - * \p loc_id fully specifies the object, \p obj_name should be '.' - * (a dot). + * or an absolute name, based in the root group of the file. * * The link access property list, \p lapl_id, may provide * information regarding the properties of links required to access @@ -394,9 +365,6 @@ H5_DLL herr_t H5Aexists_by_name_async(const char *app_file, const char *app_func * creation property list associated with the attribute specified * by \p attr_id. * - * The creation property list identifier should be released with - * H5Pclose(). - * * \since 1.8.0 * */ @@ -413,32 +381,9 @@ H5_DLL hid_t H5Aget_create_plist(hid_t attr_id); * \return \herr_t * * \details H5Aget_info() retrieves attribute information, locating the - * attribute with an attribute identifier, \p attr_id, which is - * the identifier returned by H5Aopen() or H5Aopen_by_idx(). The + * attribute with an attribute identifier, \p attr_id. The * attribute information is returned in the \p ainfo struct. * - * The \p ainfo struct is defined as follows: - * \snippet this H5A_info_t_snip - * - * \p corder_valid indicates whether the creation order data is - * valid for this attribute. Note that if creation order is not - * being tracked, no creation order data will be valid. Valid - * values are \c TRUE and \c FALSE. - * - * \p corder is a positive integer containing the creation - * order of the attribute. This value is 0-based, so, for - * example, the third attribute created will have a \p corder - * value of 2. - * - * \p cset indicates the character set used for the attribute’s - * name; valid values are defined in H5Tpublic.h and include - * the following: - * \csets - * This value is set with H5Pset_char_encoding(). - * - * \p data_size indicates the size, in the number of characters, - * of the attribute. - * * \since 1.8.0 * */ @@ -466,16 +411,9 @@ H5_DLL herr_t H5Aget_info(hid_t attr_id, H5A_info_t *ainfo /*out*/); * The attribute is located by its index position and the attribute * information is returned in the \p ainfo struct. * - * If \p loc_id fully specifies the object to which the attribute - * is attached, \p obj_name should be '.' (a dot). - * * The attribute is located by means of an index type, an index * traversal order, and a position in the index, \p idx_type, - * \p order and \p n, respectively. These parameters and their - * valid values are discussed in the description of H5Aiterate2(). - * - * The \p ainfo struct, which will contain the returned attribute - * information, is described in H5Aget_info(). + * \p order and \p n, respectively. * * The link access property list, \p lapl_id, may provide * information regarding the properties of links required to access @@ -493,8 +431,7 @@ H5_DLL herr_t H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t * \brief Retrieves attribute information, by attribute name * * \fgdt_loc_id - * - * \param[in] obj_name Name of object to which attribute is attached, + * \param[in] obj_name Name of the object to which an attribute is attached, * relative to location * \param[in] attr_name Attribute name * \param[out] ainfo Struct containing returned attribute information @@ -507,11 +444,6 @@ H5_DLL herr_t H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t * location and name, \p loc_id and \p obj_name, respectively. * The attribute information is returned in the \p ainfo struct. * - * If \p loc_id fully specifies the object to which the attribute - * is attached, \p obj_name should be '.' (a dot). - * - * The \p ainfo struct is described in H5Aget_info(). - * * The link access property list, \p lapl_id, may provide * information regarding the properties of links required to * access the object, \p obj_name. @@ -542,8 +474,8 @@ H5_DLL herr_t H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char * string terminator is stored in the last position of the buffer * to properly terminate the string. * - * If the user only wants to find out the size of this name, the - * values 0 and NULL can be passed in for the parameters + * If the user only wants to retrieve the name length, the + * values 0 and NULL should be passed for the parameters * \p bufsize and \p buf. * * \since 1.0.0 @@ -554,7 +486,7 @@ H5_DLL ssize_t H5Aget_name(hid_t attr_id, size_t buf_size, char *buf); /** * \ingroup H5A * - * \brief Gets an attribute name, by attribute index position + * \brief Gets an attribute name by attribute index position * * \fgdt_loc_id * \param[in] obj_name Name of object to which attribute is attached, @@ -575,13 +507,9 @@ H5_DLL ssize_t H5Aget_name(hid_t attr_id, size_t buf_size, char *buf); * located by its index position, the size of the name is specified * in \p size, and the attribute name is returned in \p name. * - * If \p loc_id fully specifies the object to which the attribute - * is attached, \p obj_name should be '.' (a dot). - * * The attribute is located by means of an index type, an index * traversal order, and a position in the index, \p idx_type, - * \p order and \p n, respectively. These parameters and their - * valid values are discussed in the description of H5Aiterate2(). + * \p order and \p n, respectively. * * If the attribute name’s size is unknown, the values 0 and NULL * can be passed in for the parameters \p size and \p name. The @@ -621,7 +549,7 @@ H5_DLL hid_t H5Aget_space(hid_t attr_id); /** * \ingroup H5A * - * \brief Returns the amount of storage required for an attribute + * \brief Returns the amount of storage used to store an attribute * * \attr_id * @@ -639,17 +567,16 @@ H5_DLL hsize_t H5Aget_storage_size(hid_t attr_id); /** * \ingroup H5A * - * \brief Gets an attribute datatype + * \brief Gets an attribute's datatype * * \attr_id * * \return \hid_t{datatype} * - * \details H5Aget_type() retrieves a copy of the datatype for an attribute. + * \details H5Aget_type() retrieves a copy of the attribute's datatype. * The datatype is reopened if it is a named type before returning * it to the application. The datatypes returned by this function - * are always read-only. If an error occurs when atomizing the - * return datatype, then the datatype is closed. + * are always read-only. * * The datatype identifier returned from this function must be * released with H5Tclose() or resource leaks will develop. @@ -662,7 +589,7 @@ H5_DLL hid_t H5Aget_type(hid_t attr_id); /** * \ingroup H5A * - * \brief Calls user-defined function for each attribute on an object + * \brief Calls a user-defined function for each attribute on an object * * \fgdt_loc_id * \param[in] idx_type Type of index @@ -689,17 +616,6 @@ H5_DLL hid_t H5Aget_type(hid_t attr_id); * are specified by three parameters: the index type, * \p idx_type; the order in which the index is to be traversed, * \p order; and the attribute’s position in the index, \p idx. - * - * The type of index specified by \p idx_type can be one of the - * following: - * - * \indexes - * - * The order in which the index is to be traversed, as specified - * by \p order, can be one of the following: - * - * \orders - * * The next attribute to be operated on is specified by \p idx, * a position in the index. * @@ -716,11 +632,6 @@ H5_DLL hid_t H5Aget_type(hid_t attr_id); * the value returned identifies the parameter to be operated on * in the next step of the iteration. * - * \p op is a user-defined function whose prototype is defined - * as follows: - * \snippet this H5A_operator2_t_snip - * \click4more - * * \note This function is also available through the H5Aiterate() macro. * * \since 1.8.0 @@ -756,24 +667,10 @@ H5_DLL herr_t H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t ord * additional information as defined below, is passed to a * user-defined function, \p op, which operates on that attribute. * - * If \p loc_id fully specifies the object to which these - * attributes are attached, \p obj_name should be '.' (a dot). - * * The order of the iteration and the attributes iterated over * are specified by three parameters: the index type, \p idx_type; * the order in which the index is to be traversed, \p order; * and the attribute’s position in the index, \p idx. - * - * The type of index specified by \p idx_type can be one of the - * following: - * - * \indexes - * - * The order in which the index is to be traversed, as specified - * by \p order, can be one of the following: - * - * \orders - * * The next attribute to be operated on is specified by \p idx, * a position in the index. * @@ -790,25 +687,6 @@ H5_DLL herr_t H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t ord * the value returned identifies the parameter to be operated on in * the next step of the iteration. * - * \p op is a user-defined function whose prototype is defined - * as follows: - * \snippet this H5A_operator2_t_snip - * \click4more - * - * Valid return values from an operator and the resulting - * H5Aiterate_by_name() and \p op behavior are as follows: - * - * \li Zero causes the iterator to continue, returning zero when - * all attributes have been processed. - * \li A positive value causes the iterator to immediately return - * that positive value, indicating short-circuit success. - * The iterator can be restarted at the next attribute, as - * indicated by the return value of \p idx. - * \li A negative value causes the iterator to immediately return - * that value, indicating failure. The iterator can be - * restarted at the next attribute, as indicated by the return - * value of \p idx. - * * The link access property list, \p lapl_id, may provide * information regarding the properties of links required to access * the object, \p obj_name. @@ -835,8 +713,7 @@ H5_DLL herr_t H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t * \details H5Aopen() opens an existing attribute, \p attr_name, that is * attached to object specified by an object identifier, \p obj_id. * - * The attribute access property list, \p aapl_id, is currently unused - * and should be #H5P_DEFAULT. + * \plist_unused{aapl_id} * * This function, H5Aopen_by_idx() or H5Aopen_by_name() must be called * before the attribute can be accessed for any further purpose, @@ -845,6 +722,9 @@ H5_DLL herr_t H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t * The attribute identifier returned by this function must be released * with H5Aclose() or resource leaks will develop. * + * \par Example + * \snippet H5A_examples.c read + * * \since 1.8.0 * * \see H5Aclose(), H5Acreate() @@ -876,17 +756,13 @@ H5_DLL hid_t H5Aopen_async(const char *app_file, const char *app_func, unsigned * * \details H5Aopen_by_idx() opens an existing attribute that is attached * to an object specified by location and name, \p loc_id and - * \p obj_name, respectively. If \p loc_id fully specifies the - * object to which the attribute is attached, \p obj_name, should - * be '.' (a dot). + * \p obj_name, respectively. * * The attribute is identified by an index type, an index traversal * order, and a position in the index, \p idx_type, \p order and - * \p n, respectively. These parameters and their valid values are - * discussed in the description of H5Aiterate2(). + * \p n, respectively. * - * The attribute access property list, \p aapl_id, is currently - * unused and should currently be #H5P_DEFAULT. + * \plist_unused{aapl_id} * * The link access property list, \p lapl_id, may provide * information regarding the properties of links required to access @@ -933,11 +809,9 @@ H5_DLL hid_t H5Aopen_by_idx_async(const char *app_file, const char *app_func, un * * \p loc_id specifies a location from which the target object can * be located and \p obj_name is an object name relative to - * \p loc_id. If \p loc_id fully specifies the object to which the - * attribute is attached, \p obj_name should be '.' (a dot). + * \p loc_id. * - * The attribute access property list, \p aapl_id, is currently - * unused and should currently be #H5P_DEFAULT. + * \plist_unused{aapl_id} * * The link access property list, \p lapl_id, may provide * information regarding the properties of links required to access @@ -982,6 +856,9 @@ H5_DLL hid_t H5Aopen_by_name_async(const char *app_file, const char *app_func, u * Datatype conversion takes place at the time of a read or write and * is automatic. * + * \par Example + * \snippet H5A_examples.c read + * * \version 1.8.8 Fortran updated to Fortran2003. * \version 1.4.2 The \p dims parameter was added to the Fortran API in this * release. @@ -1051,15 +928,12 @@ H5_DLL herr_t H5Arename_by_name_async(const char *app_file, const char *app_func * attribute's in-memory datatype is specified with \p type_id. * The entire attribute is written from \p buf to the file. * - * If \p type_id is either a fixed-length or variable-length string, - * it is important to set the string length when defining the datatype. - * String datatypes are derived from #H5T_C_S1 (or #H5T_FORTRAN_S1 for - * Fortran codes), which defaults to 1 character in size. - * See H5Tset_size() and Creating variable-length string datatypes. - * * Datatype conversion takes place at the time of a read or write and * is automatic. * + * \par Example + * \snippet H5A_examples.c update + * * \version 1.8.8 Fortran updated to Fortran2003. * \version 1.4.2 Fortran \p dims parameter added in this release * \since 1.0.0 @@ -1100,6 +974,7 @@ H5_DLL herr_t H5Awrite_async(const char *app_file, const char *app_func, unsigne H5_DLL herr_t H5Arename_by_name(hid_t loc_id, const char *obj_name, const char *old_attr_name, const char *new_attr_name, hid_t lapl_id); +/// \cond DEV /* API Wrappers for async routines */ /* (Must be defined _after_ the function prototype) */ /* (And must only defined when included in application code, not the library) */ @@ -1133,6 +1008,7 @@ H5_DLL herr_t H5Arename_by_name(hid_t loc_id, const char *obj_name, const char * #define H5Aexists_by_name_async_wrap H5_NO_EXPAND(H5Aexists_by_name_async) #define H5Aclose_async_wrap H5_NO_EXPAND(H5Aclose_async) #endif /* H5A_MODULE */ +/// \endcond /* Symbols defined for compatibility with previous versions of the HDF5 API. * @@ -1182,9 +1058,9 @@ typedef herr_t (*H5A_operator1_t)(hid_t location_id /*in*/, const char *attr_nam * * \return \hid_tv{attribute} * - * \note The \p acpl parameters is currently not used; specify #H5P_DEFAULT. + * \deprecation_note{H5Acreate2()} * - * \deprecated Deprecated in favor of H5Acreate2() + * \plist_unused{acpl} * * \details H5Acreate1() creates an attribute, \p name, which is attached * to the object specified by the identifier \p loc_id. @@ -1192,18 +1068,7 @@ typedef herr_t (*H5A_operator1_t)(hid_t location_id /*in*/, const char *attr_nam * The attribute name, \p name, must be unique for the object. * * The attribute is created with the specified datatype and dataspace, - * \p type_id and \p space_id, which are created with the H5T and - * H5S interfaces, respectively. - * - * If \p type_id is either a fixed-length or variable-length string, - * it is important to set the string length when defining the - * datatype. String datatypes are derived from #H5T_C_S1 (or - * #H5T_FORTRAN_S1 for Fortran), which defaults to 1 character in - * size. See H5Tset_size() and Creating variable-length string - * datatypes. - * - * The attribute identifier returned by this function must be released - * with H5Aclose() resource leaks will develop. + * \p type_id and \p space_id. * * \since 1.8.0 * @@ -1225,8 +1090,7 @@ H5_DLL hid_t H5Acreate1(hid_t loc_id, const char *name, hid_t type_id, hid_t spa * \return Returns the number of attributes if successful; otherwise returns * a negative value. * - * \deprecated This function is deprecated in favor of the functions - * H5Oget_info(), H5Oget_info_by_name(), and H5Oget_info_by_idx(). + * \deprecation_note{H5Oget_info(), H5Oget_info_by_name(), and H5Oget_info_by_idx()} * * \details H5Aget_num_attrs() returns the number of attributes attached to * the object specified by its identifier, \p loc_id. @@ -1249,8 +1113,7 @@ H5_DLL int H5Aget_num_attrs(hid_t loc_id); * * \return \herr_t * - * \deprecated This function is deprecated in favor of the function - * H5Aiterate2(). + * \deprecation_note{H5Aiterate2()} * * \details H5Aiterate1() iterates over the attributes of the object * specified by its identifier, \p loc_id. The object can be a @@ -1262,10 +1125,6 @@ H5_DLL int H5Aget_num_attrs(hid_t loc_id); * \p op, is returned in \p idx. If \p idx is the null pointer, * then all attributes are processed. * - * \p op is a user-defined function whose prototype is defined as follows: - * \snippet this H5A_operator1_t_snip - * \click4more - * * \version 1.8.0 The function \p H5Aiterate was renamed to H5Aiterate1() * and deprecated in this release. * \since 1.0.0 @@ -1283,8 +1142,7 @@ H5_DLL herr_t H5Aiterate1(hid_t loc_id, unsigned *idx, H5A_operator1_t op, void * * \return \hid_tv{attribute} * - * \deprecated This function is deprecated in favor of the function - * H5Aopen_by_idx(). + * \deprecation_note{H5Aopen_by_idx()} * * \details H5Aopen_idx() opens an attribute which is attached to the * object specified with \p loc_id . The location object may be @@ -1310,8 +1168,7 @@ H5_DLL hid_t H5Aopen_idx(hid_t loc_id, unsigned idx); * * \return \hid_tv{attribute} * - * \deprecated This function is deprecated in favor of the function - * H5Aopen_by_name(). + * \deprecation_note{H5Aopen_by_name()} * * \details H5Aopen_name() opens an attribute specified by its name, * \p name, which is attached to the object specified with diff --git a/src/H5CS.c b/src/H5CS.c index 6510c25..d7cb6f1 100644 --- a/src/H5CS.c +++ b/src/H5CS.c @@ -262,9 +262,9 @@ H5CS_copy_stack(void) if (NULL == (new_stack->rec = HDcalloc(old_stack->nused, sizeof(const char *)))) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "can't allocate function stack records") - /* Copy old stack to new one, duplicating the strings */ - for (u = 0; u < old_stack->nused; u++) - new_stack->rec[u] = HDstrdup(old_stack->rec[u]); + /* Copy pointers on old stack to new one */ + /* (Strings don't need to be duplicated, they are statically allocated) */ + HDmemcpy(new_stack->rec, old_stack->rec, sizeof(char *) * old_stack->nused); new_stack->nused = new_stack->nalloc = old_stack->nused; /* Set the return value */ @@ -298,11 +298,9 @@ H5CS_close_stack(H5CS_t *stack) HDassert(stack); /* Free stack */ - for (u = 0; u < stack->nused; u++) { - if (stack->rec[u]) - HDfree((void *)stack->rec[u]); - stack->rec[u] = NULL; - } /* end for */ + /* The function name string are statically allocated (by the compiler) + * and are not allocated, so there's no need to free them. + */ if (stack->rec) { HDfree(stack->rec); stack->rec = NULL; diff --git a/src/H5CX.c b/src/H5CX.c index c304548..01bf435 100644 --- a/src/H5CX.c +++ b/src/H5CX.c @@ -761,13 +761,14 @@ H5CX__get_context(void) static void H5CX__push_common(H5CX_node_t *cnode) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_STATIC_NOERR /* Sanity check */ HDassert(cnode); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + HDassert(head); /* Set non-zero context info */ cnode->ctx.dxpl_id = H5P_DATASET_XFER_DEFAULT; @@ -834,7 +835,7 @@ done: void H5CX_push_special(void) { - H5CX_node_t *cnode; /* Context node */ + H5CX_node_t *cnode = NULL; /* Context node */ FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -868,13 +869,13 @@ H5CX_push_special(void) herr_t H5CX_retrieve_state(H5CX_state_t **api_state) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(api_state); @@ -975,6 +976,16 @@ H5CX_retrieve_state(H5CX_state_t **api_state) #endif /* H5_HAVE_PARALLEL */ done: + /* Cleanup on error */ + if (ret_value < 0) { + if (*api_state) { + /* Release the (possibly partially allocated) API state struct */ + if (H5CX_free_state(*api_state) < 0) + HDONE_ERROR(H5E_CONTEXT, H5E_CANTRELEASE, FAIL, "unable to release API state") + *api_state = NULL; + } /* end if */ + } /* end if */ + FUNC_LEAVE_NOAPI(ret_value) } /* end H5CX_retrieve_state() */ @@ -998,12 +1009,12 @@ done: herr_t H5CX_restore_state(const H5CX_state_t *api_state) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(api_state); @@ -1066,22 +1077,22 @@ H5CX_free_state(H5CX_state_t *api_state) HDassert(api_state); /* Release the DCPL */ - if (api_state->dcpl_id != H5P_DATASET_CREATE_DEFAULT) + if (0 != api_state->dcpl_id && H5P_DATASET_CREATE_DEFAULT != api_state->dcpl_id) if (H5I_dec_ref(api_state->dcpl_id) < 0) HGOTO_ERROR(H5E_CONTEXT, H5E_CANTDEC, FAIL, "can't decrement refcount on DCPL") /* Release the DXPL */ - if (api_state->dxpl_id != H5P_DATASET_XFER_DEFAULT) + if (0 != api_state->dxpl_id && H5P_DATASET_XFER_DEFAULT != api_state->dxpl_id) if (H5I_dec_ref(api_state->dxpl_id) < 0) HGOTO_ERROR(H5E_CONTEXT, H5E_CANTDEC, FAIL, "can't decrement refcount on DXPL") /* Release the LAPL */ - if (api_state->lapl_id != H5P_LINK_ACCESS_DEFAULT) + if (0 != api_state->lapl_id && H5P_LINK_ACCESS_DEFAULT != api_state->lapl_id) if (H5I_dec_ref(api_state->lapl_id) < 0) HGOTO_ERROR(H5E_CONTEXT, H5E_CANTDEC, FAIL, "can't decrement refcount on LAPL") /* Release the LCPL */ - if (api_state->lcpl_id != H5P_LINK_CREATE_DEFAULT) + if (0 != api_state->lcpl_id && H5P_LINK_CREATE_DEFAULT != api_state->lcpl_id) if (H5I_dec_ref(api_state->lcpl_id) < 0) HGOTO_ERROR(H5E_CONTEXT, H5E_CANTDEC, FAIL, "can't decrement refcount on LCPL") @@ -1124,15 +1135,19 @@ done: hbool_t H5CX_is_def_dxpl(void) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + hbool_t is_def_dxpl = FALSE; /* Flag to indicate DXPL is default */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); - FUNC_LEAVE_NOAPI((*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT); + /* Set return value */ + is_def_dxpl = ((*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT); + + FUNC_LEAVE_NOAPI(is_def_dxpl) } /* end H5CX_is_def_dxpl() */ /*------------------------------------------------------------------------- @@ -1150,13 +1165,13 @@ H5CX_is_def_dxpl(void) void H5CX_set_dxpl(hid_t dxpl_id) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ - HDassert(*head); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + HDassert(head && *head); /* Set the API context's DXPL to a new value */ (*head)->ctx.dxpl_id = dxpl_id; @@ -1179,13 +1194,13 @@ H5CX_set_dxpl(hid_t dxpl_id) void H5CX_set_dcpl(hid_t dcpl_id) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ - HDassert(*head); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + HDassert(head && *head); /* Set the API context's DCPL to a new value */ (*head)->ctx.dcpl_id = dcpl_id; @@ -1209,13 +1224,13 @@ H5CX_set_dcpl(hid_t dcpl_id) herr_t H5CX_set_libver_bounds(H5F_t *f) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set the API context value */ @@ -1245,13 +1260,13 @@ done: void H5CX_set_lcpl(hid_t lcpl_id) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ - HDassert(*head); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + HDassert(head && *head); /* Set the API context's LCPL to a new value */ (*head)->ctx.lcpl_id = lcpl_id; @@ -1274,12 +1289,12 @@ H5CX_set_lcpl(hid_t lcpl_id) void H5CX_set_lapl(hid_t lapl_id) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set the API context's LAPL to a new value */ @@ -1314,15 +1329,15 @@ H5CX_set_apl(hid_t *acspl_id, const H5P_libclass_t *libclass, #endif /* H5_HAVE_PARALLEL */ is_collective) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity checks */ HDassert(acspl_id); HDassert(libclass); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set access plist to the default property list of the appropriate class if it's the generic default */ @@ -1437,13 +1452,13 @@ H5CX_set_loc(hid_t loc_id) { #ifdef H5_HAVE_PARALLEL - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set collective metadata read flag */ @@ -1491,13 +1506,13 @@ done: herr_t H5CX_set_vol_wrap_ctx(void *vol_wrap_ctx) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set the API context value */ @@ -1525,13 +1540,13 @@ done: herr_t H5CX_set_vol_connector_prop(const H5VL_connector_prop_t *vol_connector_prop) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set the API context value */ @@ -1559,15 +1574,19 @@ done: hid_t H5CX_get_dxpl(void) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + hid_t dxpl_id = H5I_INVALID_HID; /* DXPL ID for API operation */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); - FUNC_LEAVE_NOAPI((*head)->ctx.dxpl_id) + /* Set return value */ + dxpl_id = (*head)->ctx.dxpl_id; + + FUNC_LEAVE_NOAPI(dxpl_id) } /* end H5CX_get_dxpl() */ /*------------------------------------------------------------------------- @@ -1585,15 +1604,19 @@ H5CX_get_dxpl(void) hid_t H5CX_get_lapl(void) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + hid_t lapl_id = H5I_INVALID_HID; /* LAPL ID for API operation */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); - FUNC_LEAVE_NOAPI((*head)->ctx.lapl_id) + /* Set return value */ + lapl_id = (*head)->ctx.lapl_id; + + FUNC_LEAVE_NOAPI(lapl_id) } /* end H5CX_get_lapl() */ /*------------------------------------------------------------------------- @@ -1611,14 +1634,14 @@ H5CX_get_lapl(void) herr_t H5CX_get_vol_wrap_ctx(void **vol_wrap_ctx) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(vol_wrap_ctx); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Check for value that was set */ @@ -1647,14 +1670,14 @@ done: herr_t H5CX_get_vol_connector_prop(H5VL_connector_prop_t *vol_connector_prop) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(vol_connector_prop); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Check for value that was set */ @@ -1683,15 +1706,19 @@ done: haddr_t H5CX_get_tag(void) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + haddr_t tag = HADDR_UNDEF; /* Current object's tag (ohdr chunk #0 address) */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); - FUNC_LEAVE_NOAPI((*head)->ctx.tag) + /* Set return value */ + tag = (*head)->ctx.tag; + + FUNC_LEAVE_NOAPI(tag) } /* end H5CX_get_tag() */ /*------------------------------------------------------------------------- @@ -1709,15 +1736,19 @@ H5CX_get_tag(void) H5AC_ring_t H5CX_get_ring(void) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + H5AC_ring_t ring = H5AC_RING_INV; /* Current metadata cache ring for entries */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); - FUNC_LEAVE_NOAPI((*head)->ctx.ring) + /* Set return value */ + ring = (*head)->ctx.ring; + + FUNC_LEAVE_NOAPI(ring) } /* end H5CX_get_ring() */ #ifdef H5_HAVE_PARALLEL @@ -1737,15 +1768,19 @@ H5CX_get_ring(void) hbool_t H5CX_get_coll_metadata_read(void) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + hbool_t coll_md_read = FALSE; FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); - FUNC_LEAVE_NOAPI((*head)->ctx.coll_metadata_read) + /* Set return value */ + coll_md_read = (*head)->ctx.coll_metadata_read; + + FUNC_LEAVE_NOAPI(coll_md_read) } /* end H5CX_get_coll_metadata_read() */ /*------------------------------------------------------------------------- @@ -1765,15 +1800,15 @@ H5CX_get_coll_metadata_read(void) herr_t H5CX_get_mpi_coll_datatypes(MPI_Datatype *btype, MPI_Datatype *ftype) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(btype); HDassert(ftype); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set the API context values */ @@ -1799,15 +1834,19 @@ done: hbool_t H5CX_get_mpi_file_flushing(void) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + hbool_t flushing = FALSE; FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); - FUNC_LEAVE_NOAPI((*head)->ctx.mpi_file_flushing) + /* Set return value */ + flushing = (*head)->ctx.mpi_file_flushing; + + FUNC_LEAVE_NOAPI(flushing) } /* end H5CX_get_mpi_file_flushing() */ /*------------------------------------------------------------------------- @@ -1826,15 +1865,19 @@ H5CX_get_mpi_file_flushing(void) hbool_t H5CX_get_mpio_rank0_bcast(void) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + hbool_t do_rank0_bcast = FALSE; FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); - FUNC_LEAVE_NOAPI((*head)->ctx.rank0_bcast) + /* Set return value */ + do_rank0_bcast = (*head)->ctx.rank0_bcast; + + FUNC_LEAVE_NOAPI(do_rank0_bcast) } /* end H5CX_get_mpio_rank0_bcast() */ #endif /* H5_HAVE_PARALLEL */ @@ -1853,14 +1896,14 @@ H5CX_get_mpio_rank0_bcast(void) herr_t H5CX_get_btree_split_ratios(double split_ratio[3]) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(split_ratio); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -1889,14 +1932,14 @@ done: herr_t H5CX_get_max_temp_buf(size_t *max_temp_buf) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(max_temp_buf); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -1924,14 +1967,14 @@ done: herr_t H5CX_get_tconv_buf(void **tconv_buf) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(tconv_buf); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -1959,14 +2002,14 @@ done: herr_t H5CX_get_bkgr_buf(void **bkgr_buf) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(bkgr_buf); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -1994,14 +2037,14 @@ done: herr_t H5CX_get_bkgr_buf_type(H5T_bkg_t *bkgr_buf_type) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(bkgr_buf_type); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2029,14 +2072,14 @@ done: herr_t H5CX_get_vec_size(size_t *vec_size) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(vec_size); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2066,14 +2109,14 @@ done: herr_t H5CX_get_io_xfer_mode(H5FD_mpio_xfer_t *io_xfer_mode) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(io_xfer_mode); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2101,14 +2144,14 @@ done: herr_t H5CX_get_mpio_coll_opt(H5FD_mpio_collective_opt_t *mpio_coll_opt) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(mpio_coll_opt); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2136,14 +2179,14 @@ done: herr_t H5CX_get_mpio_local_no_coll_cause(uint32_t *mpio_local_no_coll_cause) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(mpio_local_no_coll_cause); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2172,14 +2215,14 @@ done: herr_t H5CX_get_mpio_global_no_coll_cause(uint32_t *mpio_global_no_coll_cause) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(mpio_global_no_coll_cause); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2208,14 +2251,14 @@ done: herr_t H5CX_get_mpio_chunk_opt_mode(H5FD_mpio_chunk_opt_t *mpio_chunk_opt_mode) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(mpio_chunk_opt_mode); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2244,14 +2287,14 @@ done: herr_t H5CX_get_mpio_chunk_opt_num(unsigned *mpio_chunk_opt_num) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(mpio_chunk_opt_num); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2280,14 +2323,14 @@ done: herr_t H5CX_get_mpio_chunk_opt_ratio(unsigned *mpio_chunk_opt_ratio) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(mpio_chunk_opt_ratio); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2317,14 +2360,14 @@ done: herr_t H5CX_get_err_detect(H5Z_EDC_t *err_detect) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(err_detect); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2352,14 +2395,14 @@ done: herr_t H5CX_get_filter_cb(H5Z_cb_t *filter_cb) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(filter_cb); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2387,14 +2430,14 @@ done: herr_t H5CX_get_data_transform(H5Z_data_xform_t **data_transform) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(data_transform); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2445,14 +2488,14 @@ done: herr_t H5CX_get_vlen_alloc_info(H5T_vlen_alloc_info_t *vl_alloc_info) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(vl_alloc_info); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2510,14 +2553,14 @@ done: herr_t H5CX_get_dt_conv_cb(H5T_conv_cb_t *dt_conv_cb) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(dt_conv_cb); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2545,14 +2588,14 @@ done: herr_t H5CX_get_encoding(H5T_cset_t *encoding) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(encoding); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.lcpl_id); @@ -2580,14 +2623,14 @@ done: herr_t H5CX_get_intermediate_group(unsigned *crt_intermed_group) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(crt_intermed_group); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.lcpl_id); @@ -2616,14 +2659,14 @@ done: herr_t H5CX_get_nlinks(size_t *nlinks) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(nlinks); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2651,15 +2694,15 @@ done: herr_t H5CX_get_libver_bounds(H5F_libver_t *low_bound, H5F_libver_t *high_bound) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(low_bound); HDassert(high_bound); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.fapl_id); @@ -2690,14 +2733,14 @@ done: herr_t H5CX_get_dset_min_ohdr_flag(hbool_t *dset_min_ohdr_flag) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(dset_min_ohdr_flag); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dcpl_id); @@ -2726,14 +2769,14 @@ done: herr_t H5CX_get_ext_file_prefix(const char **extfile_prefix) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(extfile_prefix); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dapl_id); @@ -2784,14 +2827,14 @@ done: herr_t H5CX_get_vds_prefix(const char **vds_prefix) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(vds_prefix); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dapl_id); @@ -2842,12 +2885,12 @@ done: void H5CX_set_tag(haddr_t tag) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); (*head)->ctx.tag = tag; @@ -2870,12 +2913,12 @@ H5CX_set_tag(haddr_t tag) void H5CX_set_ring(H5AC_ring_t ring) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); (*head)->ctx.ring = ring; @@ -2900,12 +2943,12 @@ H5CX_set_ring(H5AC_ring_t ring) void H5CX_set_coll_metadata_read(hbool_t cmdr) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); (*head)->ctx.coll_metadata_read = cmdr; @@ -2930,14 +2973,14 @@ H5CX_set_coll_metadata_read(hbool_t cmdr) herr_t H5CX_set_mpi_coll_datatypes(MPI_Datatype btype, MPI_Datatype ftype) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set the API context values */ @@ -2963,13 +3006,13 @@ done: herr_t H5CX_set_io_xfer_mode(H5FD_mpio_xfer_t io_xfer_mode) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set the API context value */ @@ -2997,13 +3040,13 @@ done: herr_t H5CX_set_mpio_coll_opt(H5FD_mpio_collective_opt_t mpio_coll_opt) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set the API context value */ @@ -3031,12 +3074,12 @@ done: void H5CX_set_mpi_file_flushing(hbool_t flushing) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); (*head)->ctx.mpi_file_flushing = flushing; @@ -3060,12 +3103,12 @@ H5CX_set_mpi_file_flushing(hbool_t flushing) void H5CX_set_mpio_rank0_bcast(hbool_t rank0_bcast) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); (*head)->ctx.rank0_bcast = rank0_bcast; @@ -3089,13 +3132,13 @@ H5CX_set_mpio_rank0_bcast(hbool_t rank0_bcast) herr_t H5CX_set_vlen_alloc_info(H5MM_allocate_t alloc_func, void *alloc_info, H5MM_free_t free_func, void *free_info) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set the API context value */ @@ -3126,13 +3169,13 @@ done: herr_t H5CX_set_nlinks(size_t nlinks) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set the API context value */ @@ -3162,12 +3205,12 @@ done: void H5CX_set_mpio_actual_chunk_opt(H5D_mpio_actual_chunk_opt_mode_t mpio_actual_chunk_opt) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT)); @@ -3193,12 +3236,12 @@ H5CX_set_mpio_actual_chunk_opt(H5D_mpio_actual_chunk_opt_mode_t mpio_actual_chun void H5CX_set_mpio_actual_io_mode(H5D_mpio_actual_io_mode_t mpio_actual_io_mode) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT)); @@ -3224,12 +3267,12 @@ H5CX_set_mpio_actual_io_mode(H5D_mpio_actual_io_mode_t mpio_actual_io_mode) void H5CX_set_mpio_local_no_coll_cause(uint32_t mpio_local_no_coll_cause) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert((*head)->ctx.dxpl_id != H5P_DEFAULT); @@ -3258,12 +3301,12 @@ H5CX_set_mpio_local_no_coll_cause(uint32_t mpio_local_no_coll_cause) void H5CX_set_mpio_global_no_coll_cause(uint32_t mpio_global_no_coll_cause) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert((*head)->ctx.dxpl_id != H5P_DEFAULT); @@ -3296,13 +3339,13 @@ H5CX_set_mpio_global_no_coll_cause(uint32_t mpio_global_no_coll_cause) herr_t H5CX_test_set_mpio_coll_chunk_link_hard(int mpio_coll_chunk_link_hard) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT)); @@ -3329,13 +3372,13 @@ done: herr_t H5CX_test_set_mpio_coll_chunk_multi_hard(int mpio_coll_chunk_multi_hard) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT)); @@ -3362,13 +3405,13 @@ done: herr_t H5CX_test_set_mpio_coll_chunk_link_num_true(int mpio_coll_chunk_link_num_true) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT)); @@ -3396,13 +3439,13 @@ done: herr_t H5CX_test_set_mpio_coll_chunk_link_num_false(int mpio_coll_chunk_link_num_false) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT)); @@ -3430,13 +3473,13 @@ done: herr_t H5CX_test_set_mpio_coll_chunk_multi_ratio_coll(int mpio_coll_chunk_multi_ratio_coll) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT)); @@ -3464,13 +3507,13 @@ done: herr_t H5CX_test_set_mpio_coll_chunk_multi_ratio_ind(int mpio_coll_chunk_multi_ratio_ind) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT)); @@ -3497,13 +3540,13 @@ done: herr_t H5CX_test_set_mpio_coll_rank0_bcast(hbool_t mpio_coll_rank0_bcast) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT)); @@ -3530,14 +3573,14 @@ done: herr_t H5CX_get_ohdr_flags(uint8_t *ohdr_flags) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(ohdr_flags); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dcpl_id); @@ -3565,9 +3608,8 @@ done: static H5CX_node_t * H5CX__pop_common(hbool_t update_dxpl_props) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - H5CX_node_t *ret_value = NULL; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + H5CX_node_t * ret_value = NULL; /* Return value */ #ifdef H5_HAVE_PARALLEL FUNC_ENTER_STATIC @@ -3576,6 +3618,7 @@ H5CX__pop_common(hbool_t update_dxpl_props) #endif /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Check for cached DXPL properties to return to application */ diff --git a/src/H5D.c b/src/H5D.c index ed97bff..7153c7d 100644 --- a/src/H5D.c +++ b/src/H5D.c @@ -557,8 +557,9 @@ H5D__get_space_api_common(hid_t dset_id, void **token_ptr, H5VL_object_t **_vol_ { H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = - (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_dataset_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_STATIC @@ -566,11 +567,17 @@ H5D__get_space_api_common(hid_t dset_id, void **token_ptr, H5VL_object_t **_vol_ if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid dataset identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_GET_SPACE; + vol_cb_args.args.get_space.space_id = H5I_INVALID_HID; + /* Get the dataspace */ - if (H5VL_dataset_get(*vol_obj_ptr, H5VL_DATASET_GET_SPACE, H5P_DATASET_XFER_DEFAULT, token_ptr, - &ret_value) < 0) + if (H5VL_dataset_get(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, H5I_INVALID_HID, "unable to get dataspace") + /* Set return value */ + ret_value = vol_cb_args.args.get_space.space_id; + done: FUNC_LEAVE_NOAPI(ret_value) } /* H5D__get_space_api_common() */ @@ -591,7 +598,7 @@ done: hid_t H5Dget_space(hid_t dset_id) { - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", dset_id); @@ -664,8 +671,9 @@ done: herr_t H5Dget_space_status(hid_t dset_id, H5D_space_status_t *allocation /*out*/) { - H5VL_object_t *vol_obj = NULL; /* Dataset structure */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object for loc_id */ + H5VL_dataset_get_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", dset_id, allocation); @@ -674,9 +682,12 @@ H5Dget_space_status(hid_t dset_id, H5D_space_status_t *allocation /*out*/) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_GET_SPACE_STATUS; + vol_cb_args.args.get_space_status.status = allocation; + /* Get dataspace status */ - if ((ret_value = H5VL_dataset_get(vol_obj, H5VL_DATASET_GET_SPACE_STATUS, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, allocation)) < 0) + if (H5VL_dataset_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get space status") done: @@ -699,8 +710,9 @@ done: hid_t H5Dget_type(hid_t dset_id) { - H5VL_object_t *vol_obj; /* Dataset structure */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj; /* Object for loc_id */ + H5VL_dataset_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", dset_id); @@ -709,11 +721,17 @@ H5Dget_type(hid_t dset_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid dataset identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_GET_TYPE; + vol_cb_args.args.get_type.type_id = H5I_INVALID_HID; + /* Get the datatype */ - if (H5VL_dataset_get(vol_obj, H5VL_DATASET_GET_TYPE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &ret_value) < 0) + if (H5VL_dataset_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, H5I_INVALID_HID, "unable to get datatype") + /* Set return value */ + ret_value = vol_cb_args.args.get_type.type_id; + done: FUNC_LEAVE_API(ret_value) } /* end H5Dget_type() */ @@ -737,8 +755,9 @@ done: hid_t H5Dget_create_plist(hid_t dset_id) { - H5VL_object_t *vol_obj; /* Dataset structure */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj; /* Object for loc_id */ + H5VL_dataset_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", dset_id); @@ -747,11 +766,17 @@ H5Dget_create_plist(hid_t dset_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid dataset identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_GET_DCPL; + vol_cb_args.args.get_dcpl.dcpl_id = H5I_INVALID_HID; + /* Get the dataset creation property list */ - if (H5VL_dataset_get(vol_obj, H5VL_DATASET_GET_DCPL, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &ret_value) < 0) + if (H5VL_dataset_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, H5I_INVALID_HID, "unable to get dataset creation properties") + /* Set return value */ + ret_value = vol_cb_args.args.get_dcpl.dcpl_id; + done: FUNC_LEAVE_API(ret_value) } /* end H5Dget_create_plist() */ @@ -792,8 +817,9 @@ done: hid_t H5Dget_access_plist(hid_t dset_id) { - H5VL_object_t *vol_obj; /* Dataset structure */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj; /* Object for loc_id */ + H5VL_dataset_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", dset_id); @@ -802,11 +828,17 @@ H5Dget_access_plist(hid_t dset_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid dataset identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_GET_DAPL; + vol_cb_args.args.get_dapl.dapl_id = H5I_INVALID_HID; + /* Get the dataset access property list */ - if (H5VL_dataset_get(vol_obj, H5VL_DATASET_GET_DAPL, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &ret_value) < 0) + if (H5VL_dataset_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, H5I_INVALID_HID, "unable to get dataset access properties") + /* Set return value */ + ret_value = vol_cb_args.args.get_dapl.dapl_id; + done: FUNC_LEAVE_API(ret_value) } /* end H5Dget_access_plist() */ @@ -829,8 +861,10 @@ done: hsize_t H5Dget_storage_size(hid_t dset_id) { - H5VL_object_t *vol_obj; /* Dataset for this operation */ - hsize_t ret_value = 0; /* Return value */ + H5VL_object_t * vol_obj; /* Object for loc_id */ + H5VL_dataset_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hsize_t storage_size = 0; /* Storage size of dataset */ + hsize_t ret_value = 0; /* Return value */ FUNC_ENTER_API(0) H5TRACE1("h", "i", dset_id); @@ -839,11 +873,17 @@ H5Dget_storage_size(hid_t dset_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "invalid dataset identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_GET_STORAGE_SIZE; + vol_cb_args.args.get_storage_size.storage_size = &storage_size; + /* Get the storage size */ - if (H5VL_dataset_get(vol_obj, H5VL_DATASET_GET_STORAGE_SIZE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &ret_value) < 0) + if (H5VL_dataset_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, 0, "unable to get storage size") + /* Set return value */ + ret_value = storage_size; + done: FUNC_LEAVE_API(ret_value) } /* end H5Dget_storage_size() */ @@ -862,8 +902,11 @@ done: haddr_t H5Dget_offset(hid_t dset_id) { - H5VL_object_t *vol_obj; /* Dataset for this operation */ - haddr_t ret_value = HADDR_UNDEF; /* Return value */ + H5VL_object_t * vol_obj; /* Dataset for this operation */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_dataset_optional_args_t dset_opt_args; /* Arguments for optional operation */ + haddr_t dset_offset = HADDR_UNDEF; /* Dataset's offset */ + haddr_t ret_value = HADDR_UNDEF; /* Return value */ FUNC_ENTER_API(HADDR_UNDEF) H5TRACE1("a", "i", dset_id); @@ -872,11 +915,18 @@ H5Dget_offset(hid_t dset_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, HADDR_UNDEF, "invalid dataset identifier") + /* Set up VOL callback arguments */ + dset_opt_args.get_offset.offset = &dset_offset; + vol_cb_args.op_type = H5VL_NATIVE_DATASET_GET_OFFSET; + vol_cb_args.args = &dset_opt_args; + /* Get the offset */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_GET_OFFSET, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &ret_value) < 0) + if (H5VL_dataset_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, HADDR_UNDEF, "unable to get offset") + /* Set return value */ + ret_value = dset_offset; + done: FUNC_LEAVE_API(ret_value) } /* end H5Dget_offset() */ @@ -941,7 +991,11 @@ done: * * The MEM_SPACE_ID can be the constant H5S_ALL in which case * the memory dataspace is the same as the file dataspace - * defined when the dataset was created. + * defined when the dataset was created. The MEM_SPACE_ID can + * also be the constant H5S_BLOCK, which indicates that the + * buffer provided is a single contiguous block of memory, with + * the same # of elements as specified in the FILE_SPACE_ID + * selection. * * The number of elements in the memory dataspace must match * the number of elements in the file dataspace. @@ -1032,13 +1086,15 @@ done: *--------------------------------------------------------------------------- */ herr_t -H5Dread_chunk(hid_t dset_id, hid_t dxpl_id, const hsize_t *offset, uint32_t *filters, void *buf) +H5Dread_chunk(hid_t dset_id, hid_t dxpl_id, const hsize_t *offset, uint32_t *filters, void *buf /*out*/) { - H5VL_object_t *vol_obj = NULL; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Dataset for this operation */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_dataset_optional_args_t dset_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE5("e", "ii*h*Iu*x", dset_id, dxpl_id, offset, filters, buf); + H5TRACE5("e", "ii*h*Iux", dset_id, dxpl_id, offset, filters, buf); /* Check arguments */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) @@ -1056,11 +1112,20 @@ H5Dread_chunk(hid_t dset_id, hid_t dxpl_id, const hsize_t *offset, uint32_t *fil else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dxpl_id is not a dataset transfer property list ID") + /* Set up VOL callback arguments */ + dset_opt_args.chunk_read.offset = offset; + dset_opt_args.chunk_read.filters = 0; + dset_opt_args.chunk_read.buf = buf; + vol_cb_args.op_type = H5VL_NATIVE_DATASET_CHUNK_READ; + vol_cb_args.args = &dset_opt_args; + /* Read the raw chunk */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_CHUNK_READ, dxpl_id, H5_REQUEST_NULL, offset, - filters, buf) < 0) + if (H5VL_dataset_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read unprocessed chunk data") + /* Set return value */ + *filters = dset_opt_args.chunk_read.filters; + done: FUNC_LEAVE_API(ret_value) } /* end H5Dread_chunk() */ @@ -1126,7 +1191,11 @@ done: * * The MEM_SPACE_ID can be the constant H5S_ALL in which case * the memory dataspace is the same as the file dataspace - * defined when the dataset was created. + * defined when the dataset was created. The MEM_SPACE_ID can + * also be the constant H5S_BLOCK, which indicates that the + * buffer provided is a single contiguous block of memory, with + * the same # of elements as specified in the FILE_SPACE_ID + * selection. * * The number of elements in the memory dataspace must match * the number of elements in the file dataspace. @@ -1222,9 +1291,11 @@ herr_t H5Dwrite_chunk(hid_t dset_id, hid_t dxpl_id, uint32_t filters, const hsize_t *offset, size_t data_size, const void *buf) { - H5VL_object_t *vol_obj = NULL; - uint32_t data_size_32; /* Chunk data size (limited to 32-bits currently) */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Dataset for this operation */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_dataset_optional_args_t dset_opt_args; /* Arguments for optional operation */ + uint32_t data_size_32; /* Chunk data size (limited to 32-bits currently) */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "iiIu*hz*x", dset_id, dxpl_id, filters, offset, data_size, buf); @@ -1250,9 +1321,16 @@ H5Dwrite_chunk(hid_t dset_id, hid_t dxpl_id, uint32_t filters, const hsize_t *of else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dxpl_id is not a dataset transfer property list ID") + /* Set up VOL callback arguments */ + dset_opt_args.chunk_write.offset = offset; + dset_opt_args.chunk_write.filters = filters; + dset_opt_args.chunk_write.size = data_size_32; + dset_opt_args.chunk_write.buf = buf; + vol_cb_args.op_type = H5VL_NATIVE_DATASET_CHUNK_WRITE; + vol_cb_args.args = &dset_opt_args; + /* Write chunk */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_CHUNK_WRITE, dxpl_id, H5_REQUEST_NULL, filters, - offset, data_size_32, buf) < 0) + if (H5VL_dataset_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write unprocessed chunk data") done: @@ -1348,7 +1426,7 @@ H5Dscatter(H5D_scatter_func_t op, void *op_data, hid_t type_id, hid_t dst_space_ done: /* Release selection iterator */ if (iter_init && H5S_SELECT_ITER_RELEASE(iter) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't release selection iterator") + HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't release selection iterator") if (iter) iter = H5FL_FREE(H5S_sel_iter_t, iter); @@ -1447,7 +1525,7 @@ H5Dgather(hid_t src_space_id, const void *src_buf, hid_t type_id, size_t dst_buf done: /* Release selection iterator */ if (iter_init && H5S_SELECT_ITER_RELEASE(iter) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't release selection iterator") + HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't release selection iterator") if (iter) iter = H5FL_FREE(H5S_sel_iter_t, iter); @@ -1642,9 +1720,18 @@ H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id, hsize_t *s &supported) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't check for 'get vlen buf size' operation") if (supported & H5VL_OPT_QUERY_SUPPORTED) { + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_dataset_optional_args_t dset_opt_args; /* Arguments for optional operation */ + + /* Set up VOL callback arguments */ + dset_opt_args.get_vlen_buf_size.type_id = type_id; + dset_opt_args.get_vlen_buf_size.space_id = space_id; + dset_opt_args.get_vlen_buf_size.size = size; + vol_cb_args.op_type = H5VL_NATIVE_DATASET_GET_VLEN_BUF_SIZE; + vol_cb_args.args = &dset_opt_args; + /* Make the 'get_vlen_buf_size' callback */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_GET_VLEN_BUF_SIZE, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, type_id, space_id, size) < 0) + if (H5VL_dataset_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get vlen buf size") } /* end if */ else { @@ -1673,7 +1760,8 @@ H5D__set_extent_api_common(hid_t dset_id, const hsize_t size[], void **token_ptr H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_dataset_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -1687,9 +1775,12 @@ H5D__set_extent_api_common(hid_t dset_id, const hsize_t size[], void **token_ptr if (H5CX_set_loc(dset_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set collective metadata read info") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_SET_EXTENT; + vol_cb_args.args.set_extent.size = size; + /* Set the extent */ - if ((ret_value = H5VL_dataset_specific(*vol_obj_ptr, H5VL_DATASET_SET_EXTENT, H5P_DATASET_XFER_DEFAULT, - token_ptr, size)) < 0) + if (H5VL_dataset_specific(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to set dataset extent") done: @@ -1775,8 +1866,9 @@ done: herr_t H5Dflush(hid_t dset_id) { - H5VL_object_t *vol_obj; /* Dataset for this operation */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object for loc_id */ + H5VL_dataset_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", dset_id); @@ -1789,12 +1881,15 @@ H5Dflush(hid_t dset_id) if (H5CX_set_loc(dset_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set collective metadata read info") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_FLUSH; + vol_cb_args.args.flush.dset_id = dset_id; + /* Flush dataset information cached in memory * XXX: Note that we need to pass the ID to the VOL since the H5F_flush_cb_t * callback needs it and that's in the public API. */ - if ((ret_value = H5VL_dataset_specific(vol_obj, H5VL_DATASET_FLUSH, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, dset_id)) < 0) + if (H5VL_dataset_specific(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to flush dataset") done: @@ -1802,41 +1897,6 @@ done: } /* H5Dflush */ /*------------------------------------------------------------------------- - * Function: H5Dwait - * - * Purpose: Wait for all operations on a dataset. - * Tang: added for async - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5Dwait(hid_t dset_id) -{ - H5VL_object_t *vol_obj; /* Dataset for this operation */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(FAIL) - H5TRACE1("e", "i", dset_id); - - /* Check args */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dset_id parameter is not a valid dataset identifier") - - /* Set up collective metadata if appropriate */ - if (H5CX_set_loc(dset_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set collective metadata read info") - - if ((ret_value = H5VL_dataset_specific(vol_obj, H5VL_DATASET_WAIT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, dset_id)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTOPERATE, FAIL, "unable to wait dataset") - -done: - FUNC_LEAVE_API(ret_value) -} /* H5Dwait*/ - -/*------------------------------------------------------------------------- * Function: H5Drefresh * * Purpose: Refreshes all buffers associated with a dataset. @@ -1848,8 +1908,9 @@ done: herr_t H5Drefresh(hid_t dset_id) { - H5VL_object_t *vol_obj; /* Dataset for this operation */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object for loc_id */ + H5VL_dataset_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", dset_id); @@ -1862,9 +1923,12 @@ H5Drefresh(hid_t dset_id) if (H5CX_set_loc(dset_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set collective metadata read info") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_REFRESH; + vol_cb_args.args.refresh.dset_id = dset_id; + /* Refresh the dataset object */ - if ((ret_value = H5VL_dataset_specific(vol_obj, H5VL_DATASET_REFRESH, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, dset_id)) < 0) + if (H5VL_dataset_specific(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTLOAD, FAIL, "unable to refresh dataset") done: @@ -1891,8 +1955,9 @@ done: herr_t H5Dformat_convert(hid_t dset_id) { - H5VL_object_t *vol_obj; /* Dataset for this operation */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Dataset for this operation */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", dset_id); @@ -1905,9 +1970,12 @@ H5Dformat_convert(hid_t dset_id) if (H5CX_set_loc(dset_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set collective metadata read info") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_DATASET_FORMAT_CONVERT; + vol_cb_args.args = NULL; + /* Convert the dataset */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_FORMAT_CONVERT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + if (H5VL_dataset_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_INTERNAL, FAIL, "can't convert dataset format") done: @@ -1929,8 +1997,10 @@ done: herr_t H5Dget_chunk_index_type(hid_t dset_id, H5D_chunk_index_t *idx_type /*out*/) { - H5VL_object_t *vol_obj; /* Dataset for this operation */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Dataset for this operation */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_dataset_optional_args_t dset_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", dset_id, idx_type); @@ -1941,9 +2011,13 @@ H5Dget_chunk_index_type(hid_t dset_id, H5D_chunk_index_t *idx_type /*out*/) if (NULL == idx_type) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "idx_type parameter cannot be NULL") + /* Set up VOL callback arguments */ + dset_opt_args.get_chunk_idx_type.idx_type = idx_type; + vol_cb_args.op_type = H5VL_NATIVE_DATASET_GET_CHUNK_INDEX_TYPE; + vol_cb_args.args = &dset_opt_args; + /* Get the chunk indexing type */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_GET_CHUNK_INDEX_TYPE, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, idx_type) < 0) + if (H5VL_dataset_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk index type") done: @@ -1968,8 +2042,10 @@ done: herr_t H5Dget_chunk_storage_size(hid_t dset_id, const hsize_t *offset, hsize_t *chunk_nbytes /*out*/) { - H5VL_object_t *vol_obj; /* Dataset for this operation */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Dataset for this operation */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_dataset_optional_args_t dset_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "i*hx", dset_id, offset, chunk_nbytes); @@ -1982,9 +2058,14 @@ H5Dget_chunk_storage_size(hid_t dset_id, const hsize_t *offset, hsize_t *chunk_n if (NULL == chunk_nbytes) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "chunk_nbytes parameter cannot be NULL") + /* Set up VOL callback arguments */ + dset_opt_args.get_chunk_storage_size.offset = offset; + dset_opt_args.get_chunk_storage_size.size = chunk_nbytes; + vol_cb_args.op_type = H5VL_NATIVE_DATASET_GET_CHUNK_STORAGE_SIZE; + vol_cb_args.args = &dset_opt_args; + /* Get the dataset creation property list */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_GET_CHUNK_STORAGE_SIZE, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, offset, chunk_nbytes) < 0) + if (H5VL_dataset_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get storage size of chunk") done: @@ -2015,8 +2096,10 @@ done: herr_t H5Dget_num_chunks(hid_t dset_id, hid_t fspace_id, hsize_t *nchunks /*out*/) { - H5VL_object_t *vol_obj = NULL; /* Dataset for this operation */ - herr_t ret_value = SUCCEED; + H5VL_object_t * vol_obj = NULL; /* Dataset for this operation */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_dataset_optional_args_t dset_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; FUNC_ENTER_API(FAIL) H5TRACE3("e", "iix", dset_id, fspace_id, nchunks); @@ -2027,10 +2110,15 @@ H5Dget_num_chunks(hid_t dset_id, hid_t fspace_id, hsize_t *nchunks /*out*/) if (NULL == nchunks) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument (null)") + /* Set up VOL callback arguments */ + dset_opt_args.get_num_chunks.space_id = fspace_id; + dset_opt_args.get_num_chunks.nchunks = nchunks; + vol_cb_args.op_type = H5VL_NATIVE_DATASET_GET_NUM_CHUNKS; + vol_cb_args.args = &dset_opt_args; + /* Get the number of written chunks */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_GET_NUM_CHUNKS, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, fspace_id, nchunks) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "Can't get number of chunks") + if (H5VL_dataset_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get number of chunks") done: FUNC_LEAVE_API(ret_value); @@ -2062,9 +2150,11 @@ herr_t H5Dget_chunk_info(hid_t dset_id, hid_t fspace_id, hsize_t chk_index, hsize_t *offset /*out*/, unsigned *filter_mask /*out*/, haddr_t *addr /*out*/, hsize_t *size /*out*/) { - H5VL_object_t *vol_obj = NULL; /* Dataset for this operation */ - hsize_t nchunks = 0; - herr_t ret_value = SUCCEED; + H5VL_object_t * vol_obj = NULL; /* Dataset for this operation */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_dataset_optional_args_t dset_opt_args; /* Arguments for optional operation */ + hsize_t nchunks = 0; /* Number of chunks */ + herr_t ret_value = SUCCEED; FUNC_ENTER_API(FAIL) H5TRACE7("e", "iihxxxx", dset_id, fspace_id, chk_index, offset, filter_mask, addr, size); @@ -2076,19 +2166,33 @@ H5Dget_chunk_info(hid_t dset_id, hid_t fspace_id, hsize_t chk_index, hsize_t *of if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") + /* Set up VOL callback arguments */ + dset_opt_args.get_num_chunks.space_id = fspace_id; + dset_opt_args.get_num_chunks.nchunks = &nchunks; + vol_cb_args.op_type = H5VL_NATIVE_DATASET_GET_NUM_CHUNKS; + vol_cb_args.args = &dset_opt_args; + /* Get the number of written chunks to check range */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_GET_NUM_CHUNKS, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, fspace_id, &nchunks) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "Can't get number of chunks") + if (H5VL_dataset_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get number of chunks") /* Check range for chunk index */ if (chk_index >= nchunks) HGOTO_ERROR(H5E_DATASET, H5E_BADRANGE, FAIL, "chunk index is out of range") + /* Set up VOL callback arguments */ + dset_opt_args.get_chunk_info_by_idx.space_id = fspace_id; + dset_opt_args.get_chunk_info_by_idx.chk_index = chk_index; + dset_opt_args.get_chunk_info_by_idx.offset = offset; + dset_opt_args.get_chunk_info_by_idx.filter_mask = filter_mask; + dset_opt_args.get_chunk_info_by_idx.addr = addr; + dset_opt_args.get_chunk_info_by_idx.size = size; + vol_cb_args.op_type = H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_IDX; + vol_cb_args.args = &dset_opt_args; + /* Call private function to get the chunk info given the chunk's index */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_IDX, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, fspace_id, chk_index, offset, filter_mask, addr, size) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "Can't get chunk info by index") + if (H5VL_dataset_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk info by index") done: FUNC_LEAVE_API(ret_value); @@ -2119,8 +2223,10 @@ herr_t H5Dget_chunk_info_by_coord(hid_t dset_id, const hsize_t *offset, unsigned *filter_mask /*out*/, haddr_t *addr /*out*/, hsize_t *size /*out*/) { - H5VL_object_t *vol_obj = NULL; /* Dataset for this operation */ - herr_t ret_value = SUCCEED; + H5VL_object_t * vol_obj = NULL; /* Dataset for this operation */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_dataset_optional_args_t dset_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; FUNC_ENTER_API(FAIL) H5TRACE5("e", "i*hxxx", dset_id, offset, filter_mask, addr, size); @@ -2134,10 +2240,17 @@ H5Dget_chunk_info_by_coord(hid_t dset_id, const hsize_t *offset, unsigned *filte if (NULL == offset) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument (null)") + /* Set up VOL callback arguments */ + dset_opt_args.get_chunk_info_by_coord.offset = offset; + dset_opt_args.get_chunk_info_by_coord.filter_mask = filter_mask; + dset_opt_args.get_chunk_info_by_coord.addr = addr; + dset_opt_args.get_chunk_info_by_coord.size = size; + vol_cb_args.op_type = H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_COORD; + vol_cb_args.args = &dset_opt_args; + /* Call private function to get the chunk info given the chunk's index */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_COORD, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, offset, filter_mask, addr, size) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "Can't get chunk info by its logical coordinates") + if (H5VL_dataset_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk info by its logical coordinates") done: FUNC_LEAVE_API(ret_value) @@ -2150,6 +2263,7 @@ done: * * Parameters: * hid_t dset_id; IN: Chunked dataset ID + * hid_t dxpl_id; IN: Dataset transfer property list ID * H5D_chunk_iter_op_t cb IN: User callback function, called for every chunk. * void *op_data IN/OUT: Optional user data passed on to user callback. * @@ -2187,22 +2301,37 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Dchunk_iter(hid_t dset_id, H5D_chunk_iter_op_t cb, void *op_data) +H5Dchunk_iter(hid_t dset_id, hid_t dxpl_id, H5D_chunk_iter_op_t op, void *op_data) { - H5VL_object_t *vol_obj = NULL; /* Dataset for this operation */ - herr_t ret_value = SUCCEED; + H5VL_object_t * vol_obj = NULL; /* Dataset for this operation */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_dataset_optional_args_t dset_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; FUNC_ENTER_API(FAIL) - H5TRACE3("e", "ix*x", dset_id, cb, op_data); + H5TRACE4("e", "iix*x", dset_id, dxpl_id, op, op_data); /* Check arguments */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") + if (NULL == op) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid callback to chunk iteration") - /* Call private function to get the chunk info given the chunk's index */ - if (H5VL_dataset_specific(vol_obj, H5VL_DATASET_CHUNK_ITER, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, cb, - op_data) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "Can't iterate over chunks") + /* Get the default dataset transfer property list if the user didn't provide one */ + if (H5P_DEFAULT == dxpl_id) + dxpl_id = H5P_DATASET_XFER_DEFAULT; + else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dxpl_id is not a dataset transfer property list ID") + + /* Set up VOL callback arguments */ + dset_opt_args.chunk_iter.op = op; + dset_opt_args.chunk_iter.op_data = op_data; + vol_cb_args.op_type = H5VL_NATIVE_DATASET_CHUNK_ITER; + vol_cb_args.args = &dset_opt_args; + + /* Iterate over the chunks */ + if ((ret_value = H5VL_dataset_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL)) < 0) + HERROR(H5E_BADITER, H5E_BADITER, "error iterating over dataset chunks"); done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index 5fc7abb..71a15b0 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -107,9 +107,9 @@ /*#define H5D_CHUNK_DEBUG */ /* Flags for the "edge_chunk_state" field below */ -#define H5D_RDCC_DISABLE_FILTERS 0x01u /* Disable filters on this chunk */ +#define H5D_RDCC_DISABLE_FILTERS 0x01U /* Disable filters on this chunk */ #define H5D_RDCC_NEWLY_DISABLED_FILTERS \ - 0x02u /* Filters have been disabled since \ + 0x02U /* Filters have been disabled since \ * the last flush */ /******************/ @@ -245,10 +245,10 @@ typedef struct H5D_chunk_coll_info_t { } H5D_chunk_coll_info_t; #endif /* H5_HAVE_PARALLEL */ -typedef struct H5D_chunk_iter_cb_data_t { - H5D_chunk_iter_op_t cb; /* User defined callback */ +typedef struct H5D_chunk_iter_ud_t { + H5D_chunk_iter_op_t op; /* User defined callback */ void * op_data; /* User data for user defined callback */ -} H5D_chunk_iter_cb_data_t; +} H5D_chunk_iter_ud_t; /********************/ /* Local Prototypes */ @@ -7515,14 +7515,15 @@ done: static int H5D__chunk_iter_cb(const H5D_chunk_rec_t *chunk_rec, void *udata) { - int ret_value = 0; + const H5D_chunk_iter_ud_t *data = (H5D_chunk_iter_ud_t *)udata; + int ret_value = H5_ITER_CONT; FUNC_ENTER_STATIC_NOERR - const H5D_chunk_iter_cb_data_t *data = (H5D_chunk_iter_cb_data_t *)udata; - - ret_value = (data->cb)(chunk_rec->scaled, chunk_rec->filter_mask, chunk_rec->chunk_addr, - chunk_rec->nbytes, data->op_data); + /* Check for callback failure and pass along return value */ + if ((ret_value = (data->op)(chunk_rec->scaled, chunk_rec->filter_mask, chunk_rec->chunk_addr, + chunk_rec->nbytes, data->op_data)) < 0) + HERROR(H5E_DATASET, H5E_CANTNEXT, "iteration operator failed"); FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__chunk_iter_cb */ @@ -7541,7 +7542,7 @@ H5D__chunk_iter_cb(const H5D_chunk_rec_t *chunk_rec, void *udata) *------------------------------------------------------------------------- */ herr_t -H5D__chunk_iter(const H5D_t *dset, H5D_chunk_iter_op_t cb, void *op_data) +H5D__chunk_iter(const H5D_t *dset, H5D_chunk_iter_op_t op, void *op_data) { const H5O_layout_t *layout = NULL; /* Dataset layout */ const H5D_rdcc_t * rdcc = NULL; /* Raw data chunk cache */ @@ -7576,15 +7577,65 @@ H5D__chunk_iter(const H5D_t *dset, H5D_chunk_iter_op_t cb, void *op_data) /* If the dataset is not written, return without errors */ if (H5F_addr_defined(idx_info.storage->idx_addr)) { - H5D_chunk_iter_cb_data_t data; - data.cb = cb; - data.op_data = op_data; + H5D_chunk_iter_ud_t ud; + + /* Set up info for iteration callback */ + ud.op = op; + ud.op_data = op_data; /* Iterate over the allocated chunks calling the iterator callback */ - if ((dset->shared->layout.storage.u.chunk.ops->iterate)(&idx_info, H5D__chunk_iter_cb, &data) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to iterate over chunks.") + if ((ret_value = + (dset->shared->layout.storage.u.chunk.ops->iterate)(&idx_info, H5D__chunk_iter_cb, &ud)) < 0) + HERROR(H5E_DATASET, H5E_CANTNEXT, "chunk iteration failed"); } /* end if H5F_addr_defined */ done: FUNC_LEAVE_NOAPI_TAG(ret_value) } /* end H5D__chunk_iter() */ + +/*------------------------------------------------------------------------- + * Function: H5D__chunk_get_offset_copy + * + * Purpose: Copies an offset buffer and performs bounds checks on the + * values. + * + * This helper function ensures that the offset buffer given + * by the user is suitable for use with the rest of the library. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5D__chunk_get_offset_copy(const H5D_t *dset, const hsize_t *offset, hsize_t *offset_copy) +{ + unsigned u; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(dset); + HDassert(offset); + HDassert(offset_copy); + + /* The library's chunking code requires the offset to terminate with a zero. + * So transfer the offset array to an internal offset array that we + * can properly terminate (handled via the memset call). + */ + HDmemset(offset_copy, 0, H5O_LAYOUT_NDIMS * sizeof(hsize_t)); + + for (u = 0; u < dset->shared->ndims; u++) { + /* Make sure the offset doesn't exceed the dataset's dimensions */ + if (offset[u] > dset->shared->curr_dims[u]) + HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "offset exceeds dimensions of dataset") + + /* Make sure the offset fall right on a chunk's boundary */ + if (offset[u] % dset->shared->layout.u.chunk.dim[u]) + HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "offset doesn't fall on chunks's boundary") + + offset_copy[u] = offset[u]; + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__chunk_get_offset_copy() */ diff --git a/src/H5Ddeprec.c b/src/H5Ddeprec.c index 1c66f26..61ecab26 100644 --- a/src/H5Ddeprec.c +++ b/src/H5Ddeprec.c @@ -233,13 +233,15 @@ done: herr_t H5Dextend(hid_t dset_id, const hsize_t size[]) { - H5VL_object_t *vol_obj = NULL; /* Dataset structure */ - hid_t sid = H5I_INVALID_HID; /* Dataspace ID */ - H5S_t * ds = NULL; /* Dataspace struct */ - int ndims; /* Dataset/space rank */ - hsize_t dset_dims[H5S_MAX_RANK]; /* Current dataset dimensions */ - int i; /* Local index variable */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object for loc_id */ + H5VL_dataset_get_args_t vol_get_cb_args; /* Arguments to VOL callback */ + H5VL_dataset_specific_args_t vol_spec_cb_args; /* Arguments to VOL callback */ + hid_t sid = H5I_INVALID_HID; /* Dataspace ID */ + H5S_t * ds = NULL; /* Dataspace struct */ + int ndims; /* Dataset/space rank */ + hsize_t dset_dims[H5S_MAX_RANK]; /* Current dataset dimensions */ + int i; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*h", dset_id, size); @@ -250,10 +252,14 @@ H5Dextend(hid_t dset_id, const hsize_t size[]) if (!size) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no size specified") + /* Set up VOL callback arguments */ + vol_get_cb_args.op_type = H5VL_DATASET_GET_SPACE; + vol_get_cb_args.args.get_space.space_id = H5I_INVALID_HID; + /* Get the dataspace pointer for the dataset */ - if (H5VL_dataset_get(vol_obj, H5VL_DATASET_GET_SPACE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &sid) < - 0) + if (H5VL_dataset_get(vol_obj, &vol_get_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get dataspace") + sid = vol_get_cb_args.args.get_space.space_id; if (H5I_INVALID_HID == sid) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "received an invalid dataspace from the dataset") if (NULL == (ds = (H5S_t *)H5I_object_verify(sid, H5I_DATASPACE))) @@ -281,9 +287,12 @@ H5Dextend(hid_t dset_id, const hsize_t size[]) if (H5CX_set_loc(dset_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set collective metadata read info") + /* Set up VOL callback arguments */ + vol_spec_cb_args.op_type = H5VL_DATASET_SET_EXTENT; + vol_spec_cb_args.args.set_extent.size = dset_dims; + /* Increase size */ - if ((ret_value = H5VL_dataset_specific(vol_obj, H5VL_DATASET_SET_EXTENT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, dset_dims)) < 0) + if (H5VL_dataset_specific(vol_obj, &vol_spec_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to extend dataset") done: diff --git a/src/H5Dint.c b/src/H5Dint.c index 5e709db..a287ae8 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -2853,13 +2853,14 @@ H5D__vlen_get_buf_size_gen(H5VL_object_t *vol_obj, hid_t type_id, hid_t space_id { H5D_vlen_bufsize_generic_t vlen_bufsize = { NULL, H5I_INVALID_HID, NULL, H5I_INVALID_HID, H5I_INVALID_HID, {NULL, NULL, 0, 0}}; - H5P_genplist_t * dxpl = NULL; /* DXPL for operation */ - H5S_t * mspace = NULL; /* Memory dataspace */ - char bogus; /* Bogus value to pass to H5Diterate() */ - H5S_t * space; /* Dataspace for iteration */ - H5T_t * type; /* Datatype */ - H5S_sel_iter_op_t dset_op; /* Operator for iteration */ - herr_t ret_value = SUCCEED; /* Return value */ + H5P_genplist_t * dxpl = NULL; /* DXPL for operation */ + H5S_t * mspace = NULL; /* Memory dataspace */ + char bogus; /* Bogus value to pass to H5Diterate() */ + H5S_t * space; /* Dataspace for iteration */ + H5T_t * type; /* Datatype */ + H5S_sel_iter_op_t dset_op; /* Operator for iteration */ + H5VL_dataset_get_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -2874,10 +2875,14 @@ H5D__vlen_get_buf_size_gen(H5VL_object_t *vol_obj, hid_t type_id, hid_t space_id /* Save the dataset */ vlen_bufsize.dset_vol_obj = vol_obj; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_GET_SPACE; + vol_cb_args.args.get_space.space_id = H5I_INVALID_HID; + /* Get a copy of the dataset's dataspace */ - if (H5VL_dataset_get(vol_obj, H5VL_DATASET_GET_SPACE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &vlen_bufsize.fspace_id) < 0) + if (H5VL_dataset_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataspace") + vlen_bufsize.fspace_id = vol_cb_args.args.get_space.space_id; if (NULL == (vlen_bufsize.fspace = (H5S_t *)H5I_object(vlen_bufsize.fspace_id))) HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "not a dataspace") @@ -3943,7 +3948,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5D__refresh(hid_t dset_id, H5D_t *dset) +H5D__refresh(H5D_t *dset, hid_t dset_id) { H5D_virtual_held_file_t *head = NULL; /* Pointer to list of files held open */ hbool_t virt_dsets_held = FALSE; /* Whether virtual datasets' files are held open */ @@ -3968,7 +3973,7 @@ H5D__refresh(hid_t dset_id, H5D_t *dset) } /* end if */ /* Refresh dataset object */ - if ((H5O_refresh_metadata(dset_id, dset->oloc)) < 0) + if ((H5O_refresh_metadata(&dset->oloc, dset_id)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to refresh dataset") done: diff --git a/src/H5Dio.c b/src/H5Dio.c index 03400cf..d1861c4 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -69,55 +69,6 @@ H5FL_BLK_DEFINE(type_conv); H5FL_DEFINE(H5D_chunk_map_t); /*------------------------------------------------------------------------- - * Function: H5D__get_offset_copy - * - * Purpose: Copies an offset buffer and performs bounds checks on the - * values. - * - * This helper function ensures that the offset buffer given - * by the user is suitable for use with the rest of the library. - * - * Return: SUCCEED/FAIL - * - *------------------------------------------------------------------------- - */ -herr_t -H5D__get_offset_copy(const H5D_t *dset, const hsize_t *offset, hsize_t *offset_copy) -{ - unsigned u; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - HDassert(dset); - HDassert(offset); - HDassert(offset_copy); - - /* The library's chunking code requires the offset to terminate with a zero. - * So transfer the offset array to an internal offset array that we - * can properly terminate (handled via the calloc call). - */ - - HDmemset(offset_copy, 0, H5O_LAYOUT_NDIMS * sizeof(hsize_t)); - - for (u = 0; u < dset->shared->ndims; u++) { - /* Make sure the offset doesn't exceed the dataset's dimensions */ - if (offset[u] > dset->shared->curr_dims[u]) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "offset exceeds dimensions of dataset") - - /* Make sure the offset fall right on a chunk's boundary */ - if (offset[u] % dset->shared->layout.u.chunk.dim[u]) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "offset doesn't fall on chunks's boundary") - - offset_copy[u] = offset[u]; - } - -done: - FUNC_LEAVE_NOAPI(ret_value) - -} /* end H5D__get_offset_copy() */ - -/*------------------------------------------------------------------------- * Function: H5D__read * * Purpose: Reads (part of) a DATASET into application memory BUF. See @@ -161,12 +112,8 @@ H5D__read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_t /* check args */ HDassert(dataset && dataset->oloc.file); - - if (!file_space) - file_space = dataset->shared->space; - if (!mem_space) - mem_space = file_space; - nelmts = H5S_GET_SELECT_NPOINTS(mem_space); + HDassert(file_space); + HDassert(mem_space); /* Set up datatype info for operation */ if (H5D__typeinfo_init(dataset, mem_type_id, FALSE, &type_info) < 0) @@ -189,11 +136,12 @@ H5D__read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_t #endif /*H5_HAVE_PARALLEL*/ /* Make certain that the number of elements in each selection is the same */ + nelmts = H5S_GET_SELECT_NPOINTS(mem_space); if (nelmts != H5S_GET_SELECT_NPOINTS(file_space)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "src and dest dataspaces have different number of elements selected") - /* Check for a NULL buffer, after the H5S_ALL dataspace selection has been handled */ + /* Check for a NULL buffer */ if (NULL == buf) { /* Check for any elements selected (which is invalid) */ if (nelmts > 0) @@ -225,7 +173,7 @@ H5D__read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_t * Note that in general, this requires us to touch up the memory buffer as * well. */ - if (TRUE == H5S_SELECT_SHAPE_SAME(mem_space, file_space) && + if (nelmts > 0 && TRUE == H5S_SELECT_SHAPE_SAME(mem_space, file_space) && H5S_GET_EXTENT_NDIMS(mem_space) != H5S_GET_EXTENT_NDIMS(file_space)) { const void *adj_buf = NULL; /* Pointer to the location in buf corresponding */ /* to the beginning of the projected mem space. */ @@ -377,6 +325,8 @@ H5D__write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_ /* check args */ HDassert(dataset && dataset->oloc.file); + HDassert(file_space); + HDassert(mem_space); /* All filters in the DCPL must have encoding enabled. */ if (!dataset->shared->checked_filters) { @@ -418,20 +368,13 @@ H5D__write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_ } /* end else */ #endif /*H5_HAVE_PARALLEL*/ - /* Initialize dataspace information */ - if (!file_space) - file_space = dataset->shared->space; - if (!mem_space) - mem_space = file_space; - - nelmts = H5S_GET_SELECT_NPOINTS(mem_space); - /* Make certain that the number of elements in each selection is the same */ + nelmts = H5S_GET_SELECT_NPOINTS(mem_space); if (nelmts != H5S_GET_SELECT_NPOINTS(file_space)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "src and dest dataspaces have different number of elements selected") - /* Check for a NULL buffer, after the H5S_ALL dataspace selection has been handled */ + /* Check for a NULL buffer */ if (NULL == buf) { /* Check for any elements selected (which is invalid) */ if (nelmts > 0) @@ -463,7 +406,7 @@ H5D__write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_ * Note that in general, this requires us to touch up the memory buffer * as well. */ - if (TRUE == H5S_SELECT_SHAPE_SAME(mem_space, file_space) && + if (nelmts > 0 && TRUE == H5S_SELECT_SHAPE_SAME(mem_space, file_space) && H5S_GET_EXTENT_NDIMS(mem_space) != H5S_GET_EXTENT_NDIMS(file_space)) { const void *adj_buf = NULL; /* Pointer to the location in buf corresponding */ /* to the beginning of the projected mem space. */ @@ -867,11 +810,19 @@ H5D__ioinfo_adjust(H5D_io_info_t *io_info, const H5D_t *dset, const H5S_t *file_ io_info->io_ops.single_write = H5D__mpio_select_write; } /* end if */ else { + int comm_size = 0; + + /* Retrieve size of MPI communicator used for file */ + if ((comm_size = H5F_shared_mpi_get_size(io_info->f_sh)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get MPI communicator size") + /* Check if there are any filters in the pipeline. If there are, - * we cannot break to independent I/O if this is a write operation; - * otherwise there will be metadata inconsistencies in the file. + * we cannot break to independent I/O if this is a write operation + * with multiple ranks involved; otherwise, there will be metadata + * inconsistencies in the file. */ - if (io_info->op_type == H5D_IO_OP_WRITE && io_info->dset->shared->dcpl_cache.pline.nused > 0) { + if (comm_size > 1 && io_info->op_type == H5D_IO_OP_WRITE && + io_info->dset->shared->dcpl_cache.pline.nused > 0) { H5D_mpio_no_collective_cause_t cause; uint32_t local_no_collective_cause; uint32_t global_no_collective_cause; diff --git a/src/H5Dmodule.h b/src/H5Dmodule.h index 595c714..596fd48 100644 --- a/src/H5Dmodule.h +++ b/src/H5Dmodule.h @@ -44,18 +44,18 @@ * <tr><th>Create</th><th>Read</th></tr> * <tr valign="top"> * <td> - * \snippet H5D_examples.c create + * \snippet{lineno} H5D_examples.c create * </td> * <td> - * \snippet H5D_examples.c read + * \snippet{lineno} H5D_examples.c read * </td> * <tr><th>Update</th><th>Delete</th></tr> * <tr valign="top"> * <td> - * \snippet H5D_examples.c update + * \snippet{lineno} H5D_examples.c update * </td> * <td> - * \snippet H5D_examples.c delete + * \snippet{lineno} H5D_examples.c delete * </td> * </tr> * </table> diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 972a67b..92ea120 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -576,7 +576,7 @@ H5_DLL herr_t H5D__flush_sieve_buf(H5D_t *dataset); H5_DLL herr_t H5D__flush_real(H5D_t *dataset); H5_DLL herr_t H5D__flush(H5D_t *dset, hid_t dset_id); H5_DLL herr_t H5D__mark(const H5D_t *dataset, unsigned flags); -H5_DLL herr_t H5D__refresh(hid_t dset_id, H5D_t *dataset); +H5_DLL herr_t H5D__refresh(H5D_t *dataset, hid_t dset_id); /* To convert a dataset's chunk indexing type to v1 B-tree */ H5_DLL herr_t H5D__format_convert(H5D_t *dataset); @@ -651,7 +651,7 @@ H5_DLL herr_t H5D__chunk_copy(H5F_t *f_src, H5O_storage_chunk_t *storage_src, H5 H5_DLL herr_t H5D__chunk_bh_info(const H5O_loc_t *loc, H5O_t *oh, H5O_layout_t *layout, hsize_t *btree_size); H5_DLL herr_t H5D__chunk_dump_index(H5D_t *dset, FILE *stream); H5_DLL herr_t H5D__chunk_delete(H5F_t *f, H5O_t *oh, H5O_storage_t *store); -H5_DLL herr_t H5D__get_offset_copy(const H5D_t *dset, const hsize_t *offset, hsize_t *offset_copy); +H5_DLL herr_t H5D__chunk_get_offset_copy(const H5D_t *dset, const hsize_t *offset, hsize_t *offset_copy); H5_DLL herr_t H5D__chunk_direct_write(const H5D_t *dset, uint32_t filters, hsize_t *offset, uint32_t data_size, const void *buf); H5_DLL herr_t H5D__chunk_direct_read(const H5D_t *dset, hsize_t *offset, uint32_t *filters, void *buf); diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h index 0b5fac6..c496414 100644 --- a/src/H5Dpublic.h +++ b/src/H5Dpublic.h @@ -32,7 +32,9 @@ #define H5D_CHUNK_CACHE_NBYTES_DEFAULT SIZE_MAX #define H5D_CHUNK_CACHE_W0_DEFAULT (-1.0) -/* Bit flags for the H5Pset_chunk_opts() and H5Pget_chunk_opts() */ +/** + * Bit flags for the H5Pset_chunk_opts() and H5Pget_chunk_opts() + */ #define H5D_CHUNK_DONT_FILTER_PARTIAL_CHUNKS (0x0002u) /*******************/ @@ -44,13 +46,12 @@ * Values for the H5D_LAYOUT property */ typedef enum H5D_layout_t { - H5D_LAYOUT_ERROR = -1, - - H5D_COMPACT = 0, /**< raw data is very small */ - H5D_CONTIGUOUS = 1, /**< the default */ - H5D_CHUNKED = 2, /**< slow and fancy */ - H5D_VIRTUAL = 3, /**< actual data is stored in other datasets */ - H5D_NLAYOUTS = 4 /**< this one must be last! */ + H5D_LAYOUT_ERROR = -1, /**< error */ + H5D_COMPACT = 0, /**< raw data is small (< 64KB) */ + H5D_CONTIGUOUS = 1, /**< contiguous layout */ + H5D_CHUNKED = 2, /**< chunked or tiled layout */ + H5D_VIRTUAL = 3, /**< actual data is stored in other datasets */ + H5D_NLAYOUTS = 4 /**< this one must be last! */ } H5D_layout_t; //! <!-- [H5D_layout_t_snip] --> @@ -75,11 +76,11 @@ typedef enum H5D_chunk_index_t { * Values for the space allocation time property */ typedef enum H5D_alloc_time_t { - H5D_ALLOC_TIME_ERROR = -1, - H5D_ALLOC_TIME_DEFAULT = 0, - H5D_ALLOC_TIME_EARLY = 1, - H5D_ALLOC_TIME_LATE = 2, - H5D_ALLOC_TIME_INCR = 3 + H5D_ALLOC_TIME_ERROR = -1, /**< Error */ + H5D_ALLOC_TIME_DEFAULT = 0, /**< \todo Define this! */ + H5D_ALLOC_TIME_EARLY = 1, /**< Allocate on creation */ + H5D_ALLOC_TIME_LATE = 2, /**< Allocate on first write */ + H5D_ALLOC_TIME_INCR = 3 /**< Allocate incrementally (by chunk) */ } H5D_alloc_time_t; //! <!-- [H5D_alloc_time_t_snip] --> @@ -88,10 +89,11 @@ typedef enum H5D_alloc_time_t { * Values for the status of space allocation */ typedef enum H5D_space_status_t { - H5D_SPACE_STATUS_ERROR = -1, - H5D_SPACE_STATUS_NOT_ALLOCATED = 0, - H5D_SPACE_STATUS_PART_ALLOCATED = 1, - H5D_SPACE_STATUS_ALLOCATED = 2 + H5D_SPACE_STATUS_ERROR = -1, /**< Error */ + H5D_SPACE_STATUS_NOT_ALLOCATED = 0, /**< Space has not been allocated for this dataset. */ + H5D_SPACE_STATUS_PART_ALLOCATED = 1, /**< Space has been allocated for this dataset. */ + H5D_SPACE_STATUS_ALLOCATED = 2 /**< Space has been partially allocated for this dataset. (Used only for + datasets with chunked storage.) */ } H5D_space_status_t; //! <!-- [H5D_space_status_t_snip] --> @@ -100,10 +102,10 @@ typedef enum H5D_space_status_t { * Values for time of writing fill value property */ typedef enum H5D_fill_time_t { - H5D_FILL_TIME_ERROR = -1, - H5D_FILL_TIME_ALLOC = 0, - H5D_FILL_TIME_NEVER = 1, - H5D_FILL_TIME_IFSET = 2 + H5D_FILL_TIME_ERROR = -1, /**< Error */ + H5D_FILL_TIME_ALLOC = 0, /**< Fill on allocation */ + H5D_FILL_TIME_NEVER = 1, /**< Never write fill values */ + H5D_FILL_TIME_IFSET = 2 /**< Fill if fill-value was set */ } H5D_fill_time_t; //! <!-- [H5D_fill_time_t_snip] --> @@ -112,10 +114,10 @@ typedef enum H5D_fill_time_t { * Values for fill value status */ typedef enum H5D_fill_value_t { - H5D_FILL_VALUE_ERROR = -1, - H5D_FILL_VALUE_UNDEFINED = 0, - H5D_FILL_VALUE_DEFAULT = 1, - H5D_FILL_VALUE_USER_DEFINED = 2 + H5D_FILL_VALUE_ERROR = -1, /**< Error */ + H5D_FILL_VALUE_UNDEFINED = 0, /**< No fill value defined */ + H5D_FILL_VALUE_DEFAULT = 1, /**< Default fill-value */ + H5D_FILL_VALUE_USER_DEFINED = 2 /**< User-defined fill-value */ } H5D_fill_value_t; //! <!-- [H5D_fill_value_t_snip] --> @@ -124,22 +126,40 @@ typedef enum H5D_fill_value_t { * Values for VDS bounds option */ typedef enum H5D_vds_view_t { - H5D_VDS_ERROR = -1, - H5D_VDS_FIRST_MISSING = 0, - H5D_VDS_LAST_AVAILABLE = 1 + H5D_VDS_ERROR = -1, /**< Error */ + H5D_VDS_FIRST_MISSING = 0, /**< \todo Define this! */ + H5D_VDS_LAST_AVAILABLE = 1 /**< \todo Define this! */ } H5D_vds_view_t; //! <!-- [H5D_vds_view_t_snip] --> //! <!-- [H5D_append_cb_t_snip] --> /** - * Callback for H5Pset_append_flush() in a dataset access property list + * \brief Callback for H5Pset_append_flush() + * + * \dset_id{dataset_id} + * \param[in] cur_dims The current extent of the dataset's dimensions + * \param[in,out] op_data User context + * + * \return \herr_t + * */ typedef herr_t (*H5D_append_cb_t)(hid_t dataset_id, hsize_t *cur_dims, void *op_data); //! <!-- [H5D_append_cb_t_snip] --> //! <!-- [H5D_operator_t_snip] --> /** - * Define the operator function pointer for H5Diterate() + * \brief Callback for H5Diterate() + * + * \param[in,out] elem Pointer to the memory buffer containing the current dataset + * element + * \param[in] type_id Datatype identifier of the elements stored in \p elem + * \param[in] ndim Number of dimensions for the \p point array + * \param[in] point Array containing the location of the element within + * the original dataspace + * \param[in,out] operator_data Pointer to any user-defined data associated with + * the operation + * \return \herr_t_iter + * */ typedef herr_t (*H5D_operator_t)(void *elem, hid_t type_id, unsigned ndim, const hsize_t *point, void *operator_data); @@ -147,7 +167,29 @@ typedef herr_t (*H5D_operator_t)(void *elem, hid_t type_id, unsigned ndim, const //! <!-- [H5D_scatter_func_t_snip] --> /** - * Define the operator function pointer for H5Dscatter() + * \brief Callback for H5Dscatter() + * + * \param[out] src_buf Pointer to the buffer holding the next set of elements to + * scatter. On entry, the value of where \p src_buf points to + * is undefined. The callback function should set \p src_buf + * to point to the next set of elements. + * \param[out] src_buf_bytes_used Pointer to the number of valid bytes in \p src_buf. + * On entry, the value where \p src_buf_bytes_used points + * to is undefined. The callback function should set + * \p src_buf_bytes_used to the of valid bytes in \p src_buf. + * This number must be a multiple of the datatype size. + * \param[in,out] op_data User-defined pointer to data required by the callback + * function. A pass-through of the \p op_data pointer provided + * with the H5Dscatter() function call. + * \return herr_t + * + * \details The callback function should always return at least one + * element in \p src_buf, and must not return more elements + * than are remaining to be scattered. This function will be + * repeatedly called until all elements to be scattered have + * been returned. The callback function should return zero (0) + * to indicate success, and a negative value to indicate failure. + * */ typedef herr_t (*H5D_scatter_func_t)(const void **src_buf /*out*/, size_t *src_buf_bytes_used /*out*/, void *op_data); @@ -155,18 +197,51 @@ typedef herr_t (*H5D_scatter_func_t)(const void **src_buf /*out*/, size_t *src_b //! <!-- [H5D_gather_func_t_snip] --> /** - * Define the operator function pointer for H5Dgather() + * \brief Callback for H5Dgather() + * + * \param[in] dst_buf Pointer to the destination buffer which has been filled + * with the next set of elements gathered. This will always + * be identical to the \p dst_buf passed to H5Dgather() + * \param[in] dst_buf_bytes_used Pointer to the number of valid bytes in + * \p dst_buf. This number must be a multiple of + * the datatype size. + * \param[in,out] op_data User-defined pointer to data required by the callback + * function; a pass-through of the \p op_data pointer + * provided with the H5Dgather() function call. + * \returns \herr_t + * + * \details The callback function should process, store, or otherwise make use + * of the data returned in dst_buf before it returns, because the + * buffer will be overwritten unless it is the last call to the + * callback. This function will be repeatedly called until all gathered + * elements have been passed to the callback in dst_buf. The callback + * function should return zero (0) to indicate success, and a negative + * value to indicate failure. + * */ typedef herr_t (*H5D_gather_func_t)(const void *dst_buf, size_t dst_buf_bytes_used, void *op_data); //! <!-- [H5D_gather_func_t_snip] --> //! <!-- [H5D_chunk_iter_op_t_snip] --> /** - * Define the operator function pointer for H5Dchunk_iter() + * \brief Callback for H5Dchunk_iter() + * + * \param[in] offset Array of starting logical coordinates of chunk. + * \param[in] filter_mask Filter mask of chunk. + * \param[in] addr Offset in file of chunk data. + * \param[in] nbytes Size in bytes of chunk data in file. + * \param[in,out] op_data Pointer to any user-defined data associated with + * the operation. + * \returns \li Zero (#H5_ITER_CONT) causes the iterator to continue, returning + * zero when all elements have been processed. + * \li A positive value (#H5_ITER_STOP) causes the iterator to + * immediately return that value, indicating short-circuit success. + * \li A negative (#H5_ITER_ERROR) causes the iterator to immediately + * return that value, indicating failure. */ -//! <!-- [H5D_chunk_iter_op_t_snip] --> typedef int (*H5D_chunk_iter_op_t)(const hsize_t *offset, uint32_t filter_mask, haddr_t addr, uint32_t nbytes, void *op_data); +//! <!-- [H5D_chunk_iter_op_t_snip] --> /********************/ /* Public Variables */ @@ -186,7 +261,7 @@ extern "C" { * \brief Creates a new dataset and links it into the file * * \fgdta_loc_id - * \param[in] name Name of the dataset to create + * \param[in] name Name of the dataset to create * \type_id * \space_id * \lcpl_id @@ -211,13 +286,6 @@ extern "C" { * \p name may be either an absolute path in the file or a relative * path from \p loc_id naming the dataset. * - * \p dtype_id specifies the datatype of each data element as stored - * in the file. If \p dtype_id is either a fixed-length or - * variable-length string, it is important to set the string length - * when defining the datatype. String datatypes are derived from - * #H5T_C_S1 (or #H5T_FORTRAN_S1 for Fortran codes), which defaults - * to 1 character in size. - * * If \p dtype_id is a committed datatype, and if the file location * associated with the committed datatype is different from the * file location where the dataset will be created, the datatype @@ -225,7 +293,7 @@ extern "C" { * * The link creation property list, \p lcpl_id, governs creation * of the link(s) by which the new dataset is accessed and the - * creation of any * intermediate groups that may be missing. + * creation of any intermediate groups that may be missing. * * The datatype and dataspace properties and the dataset creation * and access property lists are attached to the dataset, so the @@ -236,8 +304,8 @@ extern "C" { * not previously written, the HDF5 library will return default * or user-defined fill values. * - * To conserve and release resources, the dataset should be closed - * when access is no longer required. + * \par Example + * \snippet H5D_examples.c create * * \since 1.8.0 * @@ -285,34 +353,14 @@ H5_DLL hid_t H5Dcreate_async(const char *app_file, const char *app_func, unsigne * the file, which may differ from the datatype and dataspace * in application memory. * - * Dataset creation property list and dataset access creation - * property list are specified by \p dcpl_id and \p dapl_id. - * * H5Dcreate_anon() returns a new dataset identifier. Using * this identifier, the new dataset must be linked into the * HDF5 file structure with H5Olink() or it will be deleted - * from the file when the file is closed. - * - * See H5Dcreate2() for further details and considerations on - * the use of H5Dcreate2() and H5Dcreate_anon(). - * - * The differences between this function and H5Dcreate2() are - * as follows: - * \li H5Dcreate_anon() explicitly includes a dataset access property - * list. H5Dcreate() always uses default dataset access properties. - * - * \li H5Dcreate_anon() neither provides the new dataset’s name nor - * links it into the HDF5 file structure; those actions must be - * performed separately through a call to H5Olink(), which offers - * greater control over linking. - * - * A dataset created with this function should be closed with - * H5Dclose() when the dataset is no longer needed so that resource - * leaks will not develop. + * when the file is closed. * * \since 1.8.0 * - * \see H5Olink(), H5Dcreate(), Using Identifiers + * \see H5Olink(), H5Dcreate() * */ H5_DLL hid_t H5Dcreate_anon(hid_t loc_id, hid_t type_id, hid_t space_id, hid_t dcpl_id, hid_t dapl_id); @@ -338,12 +386,6 @@ H5_DLL hid_t H5Dcreate_anon(hid_t loc_id, hid_t type_id, hid_t space_id, hid_t d * specified then the dataset will be opened at the location * where the attribute, dataset, or named datatype is attached. * - * The dataset access property list, \p dapl_id, provides - * information regarding access to the dataset. - * - * To conserve and release resources, the dataset should be closed - * when access is no longer required. - * * \since 1.8.0 * * \see H5Dcreate2(), H5Dclose() @@ -377,6 +419,9 @@ H5_DLL hid_t H5Dopen_async(const char *app_file, const char *app_func, unsigned * be released with H5Sclose() when the identifier is no longer * needed so that resource leaks will not occur. * + * \par Example + * \snippet H5D_examples.c update + * * \see H5Sclose() * */ @@ -393,7 +438,19 @@ H5_DLL hid_t H5Dget_space_async(const char *app_file, const char *app_func, unsi /** * -------------------------------------------------------------------------- * \ingroup H5D - * \todo Document this function! + * + * \brief Determines whether space has been allocated for a dataset + * + * \dset_id + * \param[out] allocation Space allocation status + * + * \return \herr_t + * + * \details H5Dget_space_status() determines whether space has been allocated + * for the dataset \p dset_id. + * + * \since 1.6.0 + * */ H5_DLL herr_t H5Dget_space_status(hid_t dset_id, H5D_space_status_t *allocation); @@ -412,27 +469,7 @@ H5_DLL herr_t H5Dget_space_status(hid_t dset_id, H5D_space_status_t *allocation) * * If a dataset has a named datatype, then an identifier to the * opened datatype is returned. Otherwise, the returned datatype - * is read-only. If atomization of the datatype fails, then the - * datatype is closed. - * - * A datatype identifier returned from this function should be - * released with H5Tclose() when the identifier is no longer - * needed to prevent resource leaks. - * - * \note Datatype Identifiers - * - * Please note that the datatype identifier is actually an object - * identifier or a handle returned from opening the datatype. It - * is not persistent and its value can be different from one HDF5 - * session to the next. - * - * H5Tequal() can be used to compare datatypes. - * - * HDF5 High Level APIs that may also be of interest are: - * - * H5LTdtype_to_text() creates a text description of a - * datatype. H5LTtext_to_dtype() creates an HDF5 datatype - * given a text description. + * is read-only. * */ H5_DLL hid_t H5Dget_type(hid_t dset_id); @@ -452,9 +489,6 @@ H5_DLL hid_t H5Dget_type(hid_t dset_id); * a copy of the dataset creation property list associated with * the dataset specified by \p dset_id. * - * The creation property list identifier should be released - * with H5Pclose() to prevent resource leaks. - * */ H5_DLL hid_t H5Dget_create_plist(hid_t dset_id); @@ -488,10 +522,6 @@ H5_DLL hid_t H5Dget_create_plist(hid_t dset_id); * All link access properties in the returned list will be set * to the default values. * - * The access property list identifier should be released with - * H5Pclose() when the identifier is no longer needed so that - * resource leaks will not develop. - * * \since 1.8.3 * */ @@ -510,11 +540,8 @@ H5_DLL hid_t H5Dget_access_plist(hid_t dset_id); * \details H5Dget_storage_size() returns the amount of storage, * in bytes, that is allocated in the file for the raw data of * the dataset specified by \p dset_id. - * - * \note The amount of storage in this case is the storage - * allocated in the written file, which will typically differ - * from the space required to hold a dataset in working memory. - * + * H5Dget_storage_size() reports only the space required to store + * the dataset elements, excluding any metadata. * \li For contiguous datasets, the returned size equals the current * allocated size of the raw data. * \li For unfiltered chunked datasets, the returned size is the @@ -524,21 +551,19 @@ H5_DLL hid_t H5Dget_access_plist(hid_t dset_id); * compression filter is in use, H5Dget_storage_size() will return * the total space required to store the compressed chunks. * - * H5Dget_storage_size() reports only the space required to store - * the data, not including that of any metadata. + * \note Note that H5Dget_storage_size() is not generally an + * appropriate function to use when determining the amount + * of memory required to work with a dataset. In such + * circumstances, you must determine the number of data + * points in a dataset and the size of an individual dataset + * element. H5Sget_simple_extent_npoints() and H5Tget_size() + * can be used to calculate that amount. * - * \attention H5Dget_storage_size() does not differentiate between 0 (zero), + * \warning H5Dget_storage_size() does not differentiate between 0 (zero), * the value returned for the storage size of a dataset * with no stored values, and 0 (zero), the value returned to * indicate an error. * - * \note Note that H5Dget_storage_size() is not generally an - * appropriate function to use when determining the amount - * of memory required to work with a dataset. In such - * circumstances, you must determine the number of data - * points in a dataset and the size of an individual data - * element. H5Sget_simple_extent_npoints() and H5Tget_size() - * can be used to get that information. * */ H5_DLL hsize_t H5Dget_storage_size(hid_t dset_id); @@ -595,7 +620,7 @@ H5_DLL herr_t H5Dget_chunk_storage_size(hid_t dset_id, const hsize_t *offset, hs * effect. Also, the implementation does not handle the #H5S_ALL * macro correctly. As a workaround, application can get * the dataspace for the dataset using H5Dget_space() and pass that - * in for \p fspace_id. This will be fixed in coming releases. + * in for \p fspace_id. This will be fixed in a future release. * * \since 1.10.5 * @@ -638,9 +663,10 @@ H5_DLL herr_t H5Dget_chunk_info_by_coord(hid_t dset_id, const hsize_t *offset, u * -------------------------------------------------------------------------- * \ingroup H5D * - * \brief Iterate over all chunks + * \brief Iterate over all chunks of a chunked dataset * * \dset_id + * \param[in] dxpl_id Identifier of a transfer property list * \param[in] cb User callback function, called for every chunk. * \param[in] op_data User-defined pointer to data required by op * @@ -648,36 +674,19 @@ H5_DLL herr_t H5Dget_chunk_info_by_coord(hid_t dset_id, const hsize_t *offset, u * * \details H5Dget_chunk_iter iterates over all chunks in the dataset, calling the * user supplied callback with the details of the chunk and the supplied - * \p op_data. - * - * Callback information: - * H5D_chunk_iter_op_t is defined as: - * - * typedef int (*H5D_chunk_iter_op_t)( - * const hsize_t *offset, - * uint32_t filter_mask, - * haddr_t addr, - * uint32_t nbytes, - * void *op_data); - * - * H5D_chunk_iter_op_t parameters: - * hsize_t *offset; IN/OUT: Array of starting logical coordinates of chunk. - * uint32_t filter_mask; IN: Filter mask of chunk. - * haddr_t addr; IN: Offset in file of chunk data. - * uint32_t nbytes; IN: Size in number of bytes of chunk data in file. - * void *op_data; IN/OUT: Pointer to any user-defined data - * associated with the operation. - * - * The return values from an operator are: - * Zero (H5_ITER_CONT) causes the iterator to continue, returning zero when all - * elements have been processed. - * Positive (H5_ITER_STOP) causes the iterator to immediately return that positive - * value, indicating short-circuit success. - * Negative (H5_ITER_ERROR) causes the iterator to immediately return that value, - * indicating failure. + * context \p op_data. + * + * \par Example + * For each chunk, print the allocated chunk size (0 for un-allocated chunks). + * \snippet H5D_examples.c H5Dchunk_iter_cb + * Iterate over all chunked datasets and chunks in a file. + * \snippet H5D_examples.c H5Ovisit_cb + * + * \version 1.?.? + * \todo When was this function introduced? * */ -H5_DLL herr_t H5Dchunk_iter(hid_t dset_id, H5D_chunk_iter_op_t cb, void *op_data); +H5_DLL herr_t H5Dchunk_iter(hid_t dset_id, hid_t dxpl_id, H5D_chunk_iter_op_t cb, void *op_data); /** * -------------------------------------------------------------------------- @@ -695,16 +704,16 @@ H5_DLL herr_t H5Dchunk_iter(hid_t dset_id, H5D_chunk_iter_op_t cb, void *op_data * * \return \herr_t * - * \details H5Dget_chunk_info() retrieves the offset coordinates - * offset, filter mask filter_mask, size size and address addr for - * the dataset specified by the identifier dset_id and the chunk - * specified by the index index. The chunk belongs to a set of - * chunks in the selection specified by fspace_id. If the queried + * \details H5Dget_chunk_info() retrieves the offset coordinates, + * \p offset, filter mask, \p filter_mask, size, \p size, and address + * \p addr for the dataset specified by the identifier \p dset_id and the chunk + * specified by the index \p index. The chunk belongs to a set of + * chunks in the selection specified by \p fspace_id. If the queried * chunk does not exist in the file, the size will be set to 0 and - * address to \c HADDR_UNDEF. The value pointed to by filter_mask will - * not be modified. NULL can be passed in for any \p out parameters. + * address to #HADDR_UNDEF. The value pointed to by filter_mask will + * not be modified. \c NULL can be passed in for any \p out parameters. * - * \p chk_idx is the chunk index in the selection. Index value + * \p chk_idx is the chunk index in the selection. The index value * may have a value of 0 up to the number of chunks stored in * the file that have a nonempty intersection with the file * dataspace selection @@ -718,9 +727,9 @@ H5_DLL herr_t H5Dchunk_iter(hid_t dset_id, H5D_chunk_iter_op_t cb, void *op_data * \note Please be aware that this function currently does not * support non-trivial selections, thus \p fspace_id has no * effect. Also, the implementation does not handle the #H5S_ALL - * macro correctly. As a workaround, application can get + * macro correctly. As a workaround, an application can get * the dataspace for the dataset using H5Dget_space() and pass that - * in for \p fspace_id. This will be fixed in coming releases. + * in for \p fspace_id. This will be fixed in a future release. * * \since 1.10.5 * @@ -736,7 +745,7 @@ H5_DLL herr_t H5Dget_chunk_info(hid_t dset_id, hid_t fspace_id, hsize_t chk_idx, * * \dset_id * - * \return Returns the offset in bytes; otherwise, returns \c HADDR_UNDEF, + * \return Returns the offset in bytes; otherwise, returns #HADDR_UNDEF, * a negative value. * * \details H5Dget_offset() returns the address in the file of @@ -785,9 +794,8 @@ H5_DLL haddr_t H5Dget_offset(hid_t dset_id); * used for the memory dataspace and the selection defined with \p * file_space_id is used for the selection within that dataspace. * - * If raw data storage space has not been allocated for the dataset - * and a fill value has been defined, the returned buffer \p buf - * is filled with the fill value. + * The number of elements selected in the memory dataspace \Emph{must} + * be equal to the number of elements selected in the file dataspace. * * The behavior of the library for the various combinations of * valid dataspace identifiers and #H5S_ALL for the \p mem_space_id @@ -832,14 +840,12 @@ H5_DLL haddr_t H5Dget_offset(hid_t dset_id); * </tr> * </table> * - * \details Setting an #H5S_ALL selection indicates that the entire - * dataspace, as defined by the current dimensions of a dataspace, - * will be selected. The number of elements selected in the memory - * dataspace must match the number of elements selected in the - * file dataspace. + * \note If no storage space was allocated for the dataset + * and a fill value is defined, the returned buffer \p buf + * is filled with the fill value. * - * \p dxpl_id can be the constant #H5P_DEFAULT, in which case the - * default data transfer properties are used. + * \par Example + * \snippet H5D_examples.c read * */ H5_DLL herr_t H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, @@ -952,6 +958,8 @@ H5_DLL herr_t H5Dread_async(const char *app_file, const char *app_func, unsigned * time if the dataset's fill time is set to #H5D_FILL_TIME_IFSET * or #H5D_FILL_TIME_ALLOC. * + * \par_compr_note + * * \attention If a dataset's storage layout is 'compact', care must be * taken when writing data to the dataset in parallel. A compact * dataset's raw data is cached in memory and may be flushed @@ -959,6 +967,9 @@ H5_DLL herr_t H5Dread_async(const char *app_file, const char *app_func, unsigned * applications should always attempt to write identical data to * the dataset from all processes. * + * \par Example + * \snippet H5D_examples.c update + * * \see H5Pset_fill_time(), H5Pset_alloc_time() * */ @@ -999,11 +1010,6 @@ H5_DLL herr_t H5Dwrite_async(const char *app_file, const char *app_func, unsigne * pipeline, including filters, and will be written directly to * the file. Only one chunk can be written with this function. * - * H5Dwrite_chunk() replaces the now deprecated H5DOwrite_chunk() - * function, which was located in the high level optimization - * library. The parameters and behavior are identical to the - * original. - * * \p filters is a mask providing a record of which filters are * used with the the chunk. The default value of the mask is * zero (0), indicating that all enabled filters are applied. A @@ -1031,11 +1037,10 @@ H5_DLL herr_t H5Dwrite_async(const char *app_file, const char *app_func, unsigne * in a file. H5Dwrite_chunk() bypasses hyperslab selection, the * conversion of data from one datatype to another, and the filter * pipeline to write the chunk. Developers should have experience - * with these processes before using this function. Please see - * Using the Direct Chunk Write Function for more information. + * with these processes before using this function. * - * \note H5Dread_chunk() and H5Dwrite_chunk() are not supported under - * parallel and do not support variable length types. + * \note H5Dread_chunk() and H5Dwrite_chunk() are currently not supported + * with parallel HDF5 and do not support variable-length types. * * \since 1.10.2 * @@ -1073,10 +1078,10 @@ H5_DLL herr_t H5Dwrite_chunk(hid_t dset_id, hid_t dxpl_id, uint32_t filters, con * the dimension limits and must specify a point that falls on * a dataset chunk boundary. * - * The mask \p filters indicates which filters are used with the - * chunk when written. A zero value indicates that all enabled - * filters are applied on the chunk. A filter is skipped if the - * bit corresponding to the filter’s position in the pipeline + * The mask \p filters indicates which filters were used when the + * chunk was written. A zero value (all bits 0) indicates that all + * enabled filters are applied on the chunk. A filter is skipped if + * the bit corresponding to the filter’s position in the pipeline * (0 ≤ position < 32) is turned on. * * \p buf is the memory buffer containing the chunk read from @@ -1090,8 +1095,8 @@ H5_DLL herr_t H5Dwrite_chunk(hid_t dset_id, hid_t dxpl_id, uint32_t filters, con * with these processes before using this function. Please see * Using the Direct Chunk Write Function for more information. * - * \note H5Dread_chunk() and H5Dwrite_chunk() are not supported under - * parallel and do not support variable length types. + * \note H5Dread_chunk() and H5Dwrite_chunk() are currently not supported + * with parallel HDF5 and do not support variable-length datatypes. * * \since 1.10.2 * @@ -1121,52 +1126,9 @@ H5_DLL herr_t H5Dread_chunk(hid_t dset_id, hid_t dxpl_id, const hsize_t *offset, * in the memory buffer \p buf, executing the callback function * \p op once for each such data element. * - * The prototype of the callback function \p op is as follows - * (as defined in the source code file H5Lpublic.h): - * \snippet this H5D_operator_t_snip - * The parameters of this callback function are: - * - * <table> - * <tr><td>\c elem</td> - * <td><tt>[in,out]</tt></td> - * <td>Pointer to the memory buffer containing the current - * data element</td></tr> - * <tr><td>\c type_id</td> - * <td><tt>[in]</tt></td> - * <td>Datatype identifier of the elements stored in elem</td></tr> - * <tr><td>\c ndim</td> - * <td><tt>[in]</tt></td> - * <td>Number of dimensions for the point array</td></tr> - * <tr><td>\c point</td> - * <td><tt>[in]</tt></td> - * <td>Array containing the location of the element within - * the original dataspace</td></tr> - * <tr><td>\c operator_data</td> - * <td><tt>[in,out]</tt></td> - * <td>Pointer to any user-defined data associated with the - * operation</td></tr> - * </table> - * - * The possible return values from the callback function, and - * the effect ofeach,are as follows: - * - * \li Zero causes the iterator to continue, returning zero - * when all data elements have been processed. - * \li A positive value causes the iterator to immediately - * return that positive value, indicating short-circuit success. - * \li A negative value causes the iterator to immediately return - * that value, indicating failure. - * - * The \p operator_data parameter is a user-defined pointer to - * the data required to process dataset elements in the course - * of the iteration. If operator needs to pass data back to the - * application, such data can be returned in this same buffer. This - * pointer is passed back to each step of the iteration in the - * operator callback function’s operator_data parameter. - * - * Unlike other HDF5 iterators, this iteration operation cannot - * be restarted at the point of exit; a second H5Diterate() - * call will always restart at the beginning. + * \attention Unlike other HDF5 iterators, this iteration operation cannot + * be restarted at the point of exit; a second H5Diterate() + * call will always restart at the beginning. * * * \since 1.10.2 @@ -1216,30 +1178,25 @@ H5_DLL herr_t H5Dvlen_get_buf_size(hid_t dset_id, hid_t type_id, hid_t space_id, * * \return \herr_t * - * \details H5Dfill() fills the dataspace selection in memory, \p space_id, + * \details H5Dfill() fills the dataspace selection, \p space_id, in memory * with the fill value specified in \p fill. If \p fill is NULL, * a fill value of 0 (zero) is used. * * \p fill_type_id specifies the datatype of the fill value. - * \p buf specifies the buffer in which the dataspace elements - * will be written. - * \p buf_type_id specifies the datatype of those data elements. + * \p buf specifies the buffer in which the fill elements + * will be written. \p buf_type_id specifies the datatype of + * those data elements. * * \note Note that if the fill value datatype differs from the memory - * buffer datatype, the fill value will be converted to the memory - * buffer datatype before filling the selection. + * buffer datatype, the fill value will be converted to the memory + * buffer datatype before filling the selection. * * \note Applications sometimes write data only to portions of an - * allocated dataset. It is often useful in such cases to fill - * the unused space with a known fill value. See the following - * function for more information: - * - H5Pset_fill_value() - * - H5Pget_fill_value() - * - H5Pfill_value_defined() - * - H5Pset_fill_time() - * - H5Pget_fill_time() - * - H5Pcreate() - * - H5Pcreate_anon() + * allocated dataset. It is often useful in such cases to fill + * the unused space with a known fill value. + * + * \see H5Pset_fill_value(), H5Pget_fill_value(), H5Pfill_value_defined(), + * H5Pset_fill_time(), H5Pget_fill_time(), H5Pcreate(), H5Dcreate_anon() * */ H5_DLL herr_t H5Dfill(const void *fill, hid_t fill_type_id, void *buf, hid_t buf_type_id, hid_t space_id); @@ -1286,22 +1243,21 @@ H5_DLL herr_t H5Dfill(const void *fill, hid_t fill_type_id, void *buf, hid_t buf * - If the dataset’s fill time is set to #H5D_FILL_TIME_ALLOC * (see H5Pset_alloc_time()) * - * \note - * \li If the sizes specified in \p size array are smaller than - * the dataset’s current dimension sizes, H5Dset_extent() will reduce - * the dataset’s dimension sizes to the specified values. It is the - * user application’s responsibility to ensure that valuable data is - * not lost as H5Dset_extent() does not check. + * \note If the sizes specified in \p size array are smaller than the dataset’s + * current dimension sizes, H5Dset_extent() will reduce the dataset’s + * dimension sizes to the specified values. It is the user application’s + * responsibility to ensure that valuable data is not lost as + * H5Dset_extent() does not check. * - * \li Except for external datasets, H5Dset_extent() is for use with - * chunked datasets only, not contiguous datasets. + * \note Except for external datasets, H5Dset_extent() is for use with + * chunked datasets only, not contiguous datasets. * - * \li A call to H5Dset_extent() affects the dataspace of a dataset. - * If a dataspace handle was opened for a dataset prior to a call to - * H5Dset_extent() then that dataspace handle will no longer reflect - * the correct dataspace extent of the dataset. H5Dget_space() must - * be called (after closing the previous handle) to obtain the current - * dataspace extent. + * \note A call to H5Dset_extent() affects the dataspace of a dataset. If a + * dataspace handle was opened for a dataset prior to a call to + * H5Dset_extent() then that dataspace handle will no longer reflect the + * correct dataspace extent of the dataset. H5Dget_space() must be called + * (after closing the previous handle) to obtain the current dataspace + * extent. * * \since 1.8.0 * @@ -1336,11 +1292,11 @@ H5_DLL herr_t H5Dset_extent_async(const char *app_file, const char *app_func, un * open files. After that, the OS is responsible for ensuring * that the data is actually flushed to disk. * + * \since 1.10.0 + * */ H5_DLL herr_t H5Dflush(hid_t dset_id); -H5_DLL herr_t H5Dwait(hid_t dset_id); - /** * -------------------------------------------------------------------------- * \ingroup H5D @@ -1396,40 +1352,7 @@ H5_DLL herr_t H5Drefresh(hid_t dset_id); * * To retrieve the data to be scattered, H5Dscatter() repeatedly * calls \p op, which should return a valid source buffer, until - * enough data to fill the selection has been retrieved. The - * prototype of the callback function \p op is as follows (as - * defined in the source code file H5Dpublic.h): - * \snippet this H5D_scatter_func_t_snip - * The parameters of this callback function are described below: - * - * <table> - * <tr><td>\c src_buf</td> - * <td><tt>[out]</tt></td> - * <td>Pointer to the buffer holding the next set of elements to - * scatter. On entry, the value of where \c src_buf points to - * is undefined. The callback function should set \c src_buf - * to point to the next set of elements.</td></tr> - * <tr><td>\c src_buf_bytes_used</td> - * <td><tt>[out]</tt></td> - * <td>Pointer to the number of valid bytes in \c src_buf. On - * entry, the value where \c src_buf_bytes_used points to is - * undefined. The callback function should set - * \c src_buf_bytes_used to the of valid bytes in \c src_buf. - * This number must be a multiple of the datatype size. - * </td></tr> - * <tr><td>\c op_data</td> - * <td><tt>[in,out]</tt></td> - * <td>User-defined pointer to data required by the callback - * function. A pass-through of the \c op_data pointer provided - * with the H5Dscatter() function call.</td></tr> - * </table> - * - * The callback function should always return at least one - * element in \p src_buf, and must not return more elements - * than are remaining to be scattered. This function will be - * repeatedly called until all elements to be scattered have - * been returned. The callback function should return zero (0) - * to indicate success, and a negative value to indicate failure. + * enough data to fill the selection has been retrieved. * * \since 1.10.2 * @@ -1481,27 +1404,9 @@ H5_DLL herr_t H5Dscatter(H5D_scatter_func_t op, void *op_data, hid_t type_id, hi * If no callback function is provided, H5Dgather() simply gathers * the data into \p dst_buf and returns. If a callback function is * provided, H5Dgather() repeatedly gathers up to \p dst_buf_size - * bytes to process the serialized data. The prototype of the - * callback function \p op is as follows (as defined in the source - * code file H5Dpublic.h): - * \snippet this H5D_gather_func_t_snip - * The parameters of this callback function are described in the - * table below. - * <table> - * <tr><td>\c dst_buf</td> - * <td>Pointer to the destination buffer which has been filled - * with the next set of elements gathered. This will always be - * identical to the \p dst_buf passed to H5Dgather().</td></tr> - * <tr><td>\c dst_buf_bytes_used</td> - * <td>Pointer to the number of valid bytes in \p dst_buf. - * This number must be a multiple of the datatype - * size.</td></tr> - * <tr><td>\c op_data</td> - * <td>User-defined pointer to data required by the callback - * function; a pass-through of the \p op_data pointer - * provided with the H5Dgather() function call.</td></tr> - * </table> - * The callback function should process, store, or otherwise, + * bytes to process the serialized data. + * + * The callback function \p op should process, store, or otherwise, * make use of the data returned in \p dst_buf before it returns, * because the buffer will be overwritten unless it is the last * call to the callback. This function will be repeatedly called @@ -1525,11 +1430,11 @@ H5_DLL herr_t H5Dgather(hid_t src_space_id, const void *src_buf, hid_t type_id, * * \return \herr_t * - * \details H5Dclose() ends access to a dataset specified by \p dset_id - * and releases resources used by it. + * \details H5Dclose() terminates access to a dataset via the identifier + * \p dset_id and releases the underlying resources. * - * \attention Further use of a released dataset identifier is illegal; a - * function using such an identifier will generate an error. + * \par Example + * \snippet H5D_examples.c read * * \since 1.8.0 * @@ -1545,12 +1450,14 @@ H5_DLL herr_t H5Dclose(hid_t dset_id); */ H5_DLL herr_t H5Dclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id, hid_t es_id); - +/// \cond DEV /* Internal API routines */ H5_DLL herr_t H5Ddebug(hid_t dset_id); H5_DLL herr_t H5Dformat_convert(hid_t dset_id); H5_DLL herr_t H5Dget_chunk_index_type(hid_t did, H5D_chunk_index_t *idx_type); +/// \endcond +/// \cond DEV /* API Wrappers for async routines */ /* (Must be defined _after_ the function prototype) */ /* (And must only defined when included in application code, not the library) */ @@ -1574,6 +1481,7 @@ H5_DLL herr_t H5Dget_chunk_index_type(hid_t did, H5D_chunk_index_t *idx_type); #define H5Dset_extent_async_wrap H5_NO_EXPAND(H5Dset_extent_async) #define H5Dclose_async_wrap H5_NO_EXPAND(H5Dclose_async) #endif /* H5D_MODULE */ +/// \endcond /* Symbols defined for compatibility with previous versions of the HDF5 API. * @@ -1614,8 +1522,7 @@ H5_DLL herr_t H5Dget_chunk_index_type(hid_t did, H5D_chunk_index_t *idx_type); * * \return \hid_t{dataset} * - * \deprecated This function is deprecated in favor of the function H5Dcreate2() - * or the macro H5Dcreate(). + * \deprecation_note{H5Dcreate2() or the macro H5Dcreate()} * * \details H5Dcreate1() creates a data set with a name, \p name, in the * location specified by the identifier \p loc_id. \p loc_id may be a @@ -1681,8 +1588,7 @@ H5_DLL hid_t H5Dcreate1(hid_t loc_id, const char *name, hid_t type_id, hid_t spa * * \return \hid_t{dataset} * - * \deprecated This function is deprecated in favor of the function H5Dopen2() - * or the macro H5Dopen(). + * \deprecation_note{H5Dopen2() or the macro H5Dopen()} * * \details H5Dopen1() opens an existing dataset for access at the location * specified by \p loc_id. \p loc_id may be a file, group, dataset, @@ -1712,10 +1618,10 @@ H5_DLL hid_t H5Dopen1(hid_t loc_id, const char *name); * * \return \herr_t * - * \deprecated This function is deprecated in favor of the function H5Dset_extent(). + * \deprecation_note{H5Dset_extent()} * * \details H5Dextend() verifies that the dataset is at least of size \p size, - * extending it if necessary. The dimensionality of size is the same as + * extending it if necessary. The length of \p size is the same as * that of the dataspace of the dataset being changed. * * This function can be applied to the following datasets: @@ -1735,7 +1641,7 @@ H5_DLL hid_t H5Dopen1(hid_t loc_id, const char *name); * the sizes specified in size. The function H5Dset_extent() must be * used if the dataset dimension sizes are are to be reduced. * - * \version 1.8.0 Function Function deprecated in this release. Parameter size + * \version 1.8.0 Function deprecated in this release. Parameter size * syntax changed to \Code{const hsize_t size[]} in this release. * */ @@ -1753,8 +1659,7 @@ H5_DLL herr_t H5Dextend(hid_t dset_id, const hsize_t size[]); * * \return \herr_t * - * \deprecated This function has been deprecated in HDF5-1.12 in favor of the - * function H5Treclaim(). + * \deprecation_note{H5Treclaim()} * * \details H5Dvlen_reclaim() reclaims memory buffers created to store VL * datatypes. @@ -1772,7 +1677,7 @@ H5_DLL herr_t H5Dextend(hid_t dset_id, const hsize_t size[]); * frees them from the bottom up, releasing all the memory without * creating memory leaks. * - * \version 1.12.0 Routine was deprecated + * \version 1.12.0 Function was deprecated * */ H5_DLL herr_t H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t dxpl_id, void *buf); diff --git a/src/H5Dvirtual.c b/src/H5Dvirtual.c index d1c0266..d5375c1 100644 --- a/src/H5Dvirtual.c +++ b/src/H5Dvirtual.c @@ -3129,7 +3129,7 @@ H5D__virtual_refresh_source_dset(H5D_t **dset) HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "can't register (temporary) source dataset ID") /* Refresh source dataset */ - if (H5D__refresh(temp_id, *dset) < 0) + if (H5D__refresh(*dset, temp_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to refresh source dataset") /* Discard the identifier & replace the dataset */ diff --git a/src/H5E.c b/src/H5E.c index b8e17a4..a5a9a2e 100644 --- a/src/H5E.c +++ b/src/H5E.c @@ -639,7 +639,7 @@ H5E__get_class_name(const H5E_cls_t *cls, char *name, size_t size) /* Set the user's buffer, if provided */ if (name) { - HDstrncpy(name, cls->cls_name, MIN((size_t)(len + 1), size)); + HDstrncpy(name, cls->cls_name, size); if ((size_t)len >= size) name[size - 1] = '\0'; } /* end if */ @@ -996,11 +996,12 @@ H5E__get_current_stack(void) if (H5I_inc_ref(current_error->min_num, FALSE) < 0) HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, NULL, "unable to increment ref count on error message") new_error->min_num = current_error->min_num; - if (NULL == (new_error->func_name = H5MM_xstrdup(current_error->func_name))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - if (NULL == (new_error->file_name = H5MM_xstrdup(current_error->file_name))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - new_error->line = current_error->line; + /* The 'func' & 'file' strings are statically allocated (by the compiler) + * there's no need to duplicate them. + */ + new_error->func_name = current_error->func_name; + new_error->file_name = current_error->file_name; + new_error->line = current_error->line; if (NULL == (new_error->desc = H5MM_xstrdup(current_error->desc))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") } /* end for */ @@ -1116,11 +1117,12 @@ H5E__set_current_stack(H5E_t *estack) if (H5I_inc_ref(new_error->min_num, FALSE) < 0) HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to increment ref count on error class") current_error->min_num = new_error->min_num; - if (NULL == (current_error->func_name = H5MM_xstrdup(new_error->func_name))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - if (NULL == (current_error->file_name = H5MM_xstrdup(new_error->file_name))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - current_error->line = new_error->line; + /* The 'func' & 'file' strings are statically allocated (by the compiler) + * there's no need to duplicate them. + */ + current_error->func_name = new_error->func_name; + current_error->file_name = new_error->file_name; + current_error->line = new_error->line; if (NULL == (current_error->desc = H5MM_xstrdup(new_error->desc))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") } /* end for */ @@ -1813,11 +1815,12 @@ H5E__append_stack(H5E_t *dst_stack, const H5E_t *src_stack) if (H5I_inc_ref(src_error->min_num, FALSE) < 0) HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to increment ref count on error message") dst_error->min_num = src_error->min_num; - if (NULL == (dst_error->func_name = H5MM_xstrdup(src_error->func_name))) - HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "memory allocation failed") - if (NULL == (dst_error->file_name = H5MM_xstrdup(src_error->file_name))) - HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "memory allocation failed") - dst_error->line = src_error->line; + /* The 'func' & 'file' strings are statically allocated (by the compiler) + * there's no need to duplicate them. + */ + dst_error->func_name = src_error->func_name; + dst_error->file_name = src_error->file_name; + dst_error->line = src_error->line; if (NULL == (dst_error->desc = H5MM_xstrdup(src_error->desc))) HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "memory allocation failed") diff --git a/src/H5ES.c b/src/H5ES.c index 2ba8a72..ccc0dd8 100644 --- a/src/H5ES.c +++ b/src/H5ES.c @@ -34,11 +34,12 @@ /***********/ /* Headers */ /***********/ -#include "H5private.h" /* Generic Functions */ -#include "H5Eprivate.h" /* Error handling */ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ #include "H5ESpkg.h" /* Event Sets */ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ /****************/ /* Local Macros */ @@ -103,10 +104,61 @@ done: } /* end H5EScreate() */ /*------------------------------------------------------------------------- + * Function: H5ESinsert_request + * + * Purpose: Insert a request from a VOL connector into an event set. + * + * Note: This function is primarily targeted at VOL connector + * authors and is _not_ designed for general-purpose application use. + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, December 11, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ESinsert_request(hid_t es_id, hid_t connector_id, void *request) +{ + H5ES_t *es; /* Event set */ + H5VL_t *connector = NULL; /* VOL connector */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "ii*x", es_id, connector_id, request); + + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + if (NULL == request) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL request pointer") + + /* Create new VOL connector object, using the connector ID */ + if (NULL == (connector = H5VL_new_connector(connector_id))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTCREATE, FAIL, "can't create VOL connector object") + + /* Insert request into event set */ + if (H5ES__insert_request(es, connector, request) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTINSERT, FAIL, "can't insert request into event set") + +done: + /* Clean up on error */ + if (ret_value < 0) + /* Release newly created connector */ + if (connector && H5VL_conn_dec_rc(connector) < 0) + HDONE_ERROR(H5E_EVENTSET, H5E_CANTDEC, FAIL, "unable to decrement ref count on VOL connector") + + FUNC_LEAVE_API(ret_value) +} /* end H5ESinsert_request() */ + +/*------------------------------------------------------------------------- * Function: H5ESget_count * * Purpose: Retrieve the # of events in an event set * + * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op + * * Return: SUCCEED / FAIL * * Programmer: Quincey Koziol @@ -117,19 +169,23 @@ done: herr_t H5ESget_count(hid_t es_id, size_t *count /*out*/) { - H5ES_t *es; /* Event set */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", es_id, count); - /* Check arguments */ - if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + /* Passing H5ES_NONE is valid, but a no-op */ + if (H5ES_NONE != es_id) { + H5ES_t *es; /* Event set */ + + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") - /* Retrieve the count, if non-NULL */ - if (count) - *count = H5ES__list_count(&es->active); + /* Retrieve the count, if non-NULL */ + if (count) + *count = H5ES__list_count(&es->active); + } /* end if */ done: FUNC_LEAVE_API(ret_value) @@ -145,6 +201,8 @@ done: * mechanism for matching operations inserted into the event * set with [possible] errors that occur. * + * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op + * * Return: SUCCEED / FAIL * * Programmer: Quincey Koziol @@ -155,19 +213,23 @@ done: herr_t H5ESget_op_counter(hid_t es_id, uint64_t *op_counter /*out*/) { - H5ES_t *es; /* Event set */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", es_id, op_counter); - /* Check arguments */ - if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + /* Passing H5ES_NONE is valid, but a no-op */ + if (H5ES_NONE != es_id) { + H5ES_t *es; /* Event set */ - /* Retrieve the operation counter, if non-NULL */ - if (op_counter) - *op_counter = es->op_counter; + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + + /* Retrieve the operation counter, if non-NULL */ + if (op_counter) + *op_counter = es->op_counter; + } /* end if */ done: FUNC_LEAVE_API(ret_value) @@ -192,6 +254,8 @@ done: * value returned for the # of operations in progress may be * inaccurate. * + * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op + * * Return: SUCCEED / FAIL * * Programmer: Quincey Koziol @@ -202,33 +266,82 @@ done: herr_t H5ESwait(hid_t es_id, uint64_t timeout, size_t *num_in_progress /*out*/, hbool_t *op_failed /*out*/) { - H5ES_t *es; /* Event set */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "iULxx", es_id, timeout, num_in_progress, op_failed); - /* Check arguments */ - if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") - if (NULL == num_in_progress) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL num_in_progress pointer") - if (NULL == op_failed) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL op_failed pointer") - - /* Wait for operations */ - if (H5ES__wait(es, timeout, num_in_progress, op_failed) < 0) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTWAIT, FAIL, "can't wait on operations") + /* Passing H5ES_NONE is valid, but a no-op */ + if (H5ES_NONE != es_id) { + H5ES_t *es; /* Event set */ + + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + if (NULL == num_in_progress) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL num_in_progress pointer") + if (NULL == op_failed) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL op_failed pointer") + + /* Wait for operations */ + if (H5ES__wait(es, timeout, num_in_progress, op_failed) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTWAIT, FAIL, "can't wait on operations") + } /* end if */ done: FUNC_LEAVE_API(ret_value) } /* end H5ESwait() */ /*------------------------------------------------------------------------- + * Function: H5EScancel + * + * Purpose: Attempt to cancel operations in an event set + * + * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Thursday, December 10, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5EScancel(hid_t es_id, size_t *num_not_canceled /*out*/, hbool_t *op_failed /*out*/) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "ixx", es_id, num_not_canceled, op_failed); + + /* Passing H5ES_NONE is valid, but a no-op */ + if (H5ES_NONE != es_id) { + H5ES_t *es; /* Event set */ + + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + if (NULL == num_not_canceled) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL num_not_canceled pointer") + if (NULL == op_failed) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL op_failed pointer") + + /* Cancel operations */ + if (H5ES__cancel(es, num_not_canceled, op_failed) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTCANCEL, FAIL, "can't cancel operations") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5EScancel() */ + +/*------------------------------------------------------------------------- * Function: H5ESget_err_status * * Purpose: Check if event set has failed operations * + * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op + * * Return: SUCCEED / FAIL * * Programmer: Quincey Koziol @@ -239,19 +352,23 @@ done: herr_t H5ESget_err_status(hid_t es_id, hbool_t *err_status /*out*/) { - H5ES_t *es; /* Event set */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", es_id, err_status); - /* Check arguments */ - if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + /* Passing H5ES_NONE is valid, but a no-op */ + if (H5ES_NONE != es_id) { + H5ES_t *es; /* Event set */ - /* Retrieve the error flag, if non-NULL */ - if (err_status) - *err_status = es->err_occurred; + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + + /* Retrieve the error flag, if non-NULL */ + if (err_status) + *err_status = es->err_occurred; + } /* end if */ done: FUNC_LEAVE_API(ret_value) @@ -265,6 +382,8 @@ done: * Note: Does not wait for active operations to complete, so count may * not include all failures. * + * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op + * * Return: SUCCEED / FAIL * * Programmer: Quincey Koziol @@ -275,23 +394,27 @@ done: herr_t H5ESget_err_count(hid_t es_id, size_t *num_errs /*out*/) { - H5ES_t *es; /* Event set */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", es_id, num_errs); - /* Check arguments */ - if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + /* Passing H5ES_NONE is valid, but a no-op */ + if (H5ES_NONE != es_id) { + H5ES_t *es; /* Event set */ - /* Retrieve the error flag, if non-NULL */ - if (num_errs) { - if (es->err_occurred) - *num_errs = H5ES__list_count(&es->failed); - else - *num_errs = 0; - } /* end if */ + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + + /* Retrieve the error flag, if non-NULL */ + if (num_errs) { + if (es->err_occurred) + *num_errs = H5ES__list_count(&es->failed); + else + *num_errs = 0; + } /* end if */ + } /* end if */ done: FUNC_LEAVE_API(ret_value) @@ -305,6 +428,8 @@ done: * Note: The strings retrieved for each error info must be released * by calling H5free_memory(). * + * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op + * * Return: SUCCEED / FAIL * * Programmer: Quincey Koziol @@ -316,29 +441,164 @@ herr_t H5ESget_err_info(hid_t es_id, size_t num_err_info, H5ES_err_info_t err_info[] /*out*/, size_t *num_cleared /*out*/) { - H5ES_t *es; /* Event set */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "izxx", es_id, num_err_info, err_info, num_cleared); + /* Passing H5ES_NONE is valid, but a no-op */ + if (H5ES_NONE != es_id) { + H5ES_t *es; /* Event set */ + + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + if (0 == num_err_info) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "err_info array size is 0") + if (NULL == err_info) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL err_info array pointer") + if (NULL == num_cleared) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL errors cleared pointer") + + /* Retrieve the error information */ + if (H5ES__get_err_info(es, num_err_info, err_info, num_cleared) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTGET, FAIL, "can't retrieve error info for failed operation(s)") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5ESget_err_info() */ + +/*------------------------------------------------------------------------- + * Function: H5ESfree_err_info + * + * Purpose: Convenience routine to free 1+ H5ES_err_info_t structs. + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, March 5, 2021 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ESfree_err_info(size_t num_err_info, H5ES_err_info_t err_info[]) +{ + size_t u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "z*#", num_err_info, err_info); + /* Check arguments */ - if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") if (0 == num_err_info) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "err_info array size is 0") if (NULL == err_info) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL err_info array pointer") - if (NULL == num_cleared) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL errors cleared pointer") - /* Retrieve the error information */ - if (H5ES__get_err_info(es, num_err_info, err_info, num_cleared) < 0) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTGET, FAIL, "can't retrieve error info for failed operation(s)") + /* Iterate over array, releasing error information */ + for (u = 0; u < num_err_info; u++) { + H5MM_xfree(err_info[u].api_name); + H5MM_xfree(err_info[u].api_args); + H5MM_xfree(err_info[u].app_file_name); + H5MM_xfree(err_info[u].app_func_name); + if (H5I_dec_app_ref(err_info[u].err_stack_id) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTDEC, FAIL, "can't close error stack for err_info #%zu", u) + } /* end for */ done: FUNC_LEAVE_API(ret_value) -} /* end H5ESget_err_info() */ +} /* end H5ESfree_err_info() */ + +/*------------------------------------------------------------------------- + * Function: H5ESregister_insert_func + * + * Purpose: Registers a callback to invoke when a new operation is inserted + * into an event set. + * + * Note: Only one insert callback can be registered for each event set. + * Registering a new callback will replace the existing one. + * + * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, December 11, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ESregister_insert_func(hid_t es_id, H5ES_event_insert_func_t func, void *ctx) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "iEI*x", es_id, func, ctx); + + /* Passing H5ES_NONE is valid, but a no-op */ + if (H5ES_NONE != es_id) { + H5ES_t *es; /* Event set */ + + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + if (NULL == func) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL function callback pointer") + + /* Set the event set's insert callback */ + es->ins_func = func; + es->ins_ctx = ctx; + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5ESregister_insert_func() */ + +/*------------------------------------------------------------------------- + * Function: H5ESregister_complete_func + * + * Purpose: Registers a callback to invoke when an operation completes + * within an event set. + * + * Note: Only one complete callback can be registered for each event set. + * Registering a new callback will replace the existing one. + * + * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, December 11, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ESregister_complete_func(hid_t es_id, H5ES_event_complete_func_t func, void *ctx) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "iEC*x", es_id, func, ctx); + + /* Passing H5ES_NONE is valid, but a no-op */ + if (H5ES_NONE != es_id) { + H5ES_t *es; /* Event set */ + + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + if (NULL == func) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL function callback pointer") + + /* Set the event set's completion callback */ + es->comp_func = func; + es->comp_ctx = ctx; + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5ESregister_complete_func() */ /*------------------------------------------------------------------------- * Function: H5ESclose @@ -347,6 +607,8 @@ done: * * Note: Fails if active operations are present. * + * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op + * * Return: SUCCEED / FAIL * * Programmer: Quincey Koziol @@ -362,16 +624,19 @@ H5ESclose(hid_t es_id) FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", es_id); - /* Check arguments */ - if (H5I_EVENTSET != H5I_get_type(es_id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an event set") - - /* - * Decrement the counter on the object. It will be freed if the count - * reaches zero. - */ - if (H5I_dec_app_ref(es_id) < 0) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTDEC, FAIL, "unable to decrement ref count on event set") + /* Passing H5ES_NONE is valid, but a no-op */ + if (H5ES_NONE != es_id) { + /* Check arguments */ + if (H5I_EVENTSET != H5I_get_type(es_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an event set") + + /* + * Decrement the counter on the object. It will be freed if the count + * reaches zero. + */ + if (H5I_dec_app_ref(es_id) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTDEC, FAIL, "unable to decrement ref count on event set") + } /* end if */ done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5ESdevelop.h b/src/H5ESdevelop.h new file mode 100644 index 0000000..5a0f2b4 --- /dev/null +++ b/src/H5ESdevelop.h @@ -0,0 +1,50 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * This file contains public declarations for the H5ES (event set) developer + * support routines. + */ + +#ifndef _H5ESdevelop_H +#define _H5ESdevelop_H + +/* Include package's public header */ +#include "H5ESpublic.h" + +/*****************/ +/* Public Macros */ +/*****************/ + +/*******************/ +/* Public Typedefs */ +/*******************/ + +/********************/ +/* Public Variables */ +/********************/ + +/*********************/ +/* Public Prototypes */ +/*********************/ + +#ifdef __cplusplus +extern "C" { +#endif + +H5_DLL herr_t H5ESinsert_request(hid_t es_id, hid_t connector_id, void *request); + +#ifdef __cplusplus +} +#endif + +#endif /* _H5ESdevelop_H */ diff --git a/src/H5ESevent.c b/src/H5ESevent.c index b0c3578..aafc785 100644 --- a/src/H5ESevent.c +++ b/src/H5ESevent.c @@ -139,14 +139,14 @@ H5ES__event_free(H5ES_event_t *ev) /* Sanity check */ HDassert(ev); - if (ev->api_name) - H5MM_xfree_const(ev->api_name); - if (ev->api_args) - H5MM_xfree_const(ev->api_args); - if (ev->app_file) - H5MM_xfree_const(ev->app_file); - if (ev->app_func) - H5MM_xfree_const(ev->app_func); + /* The 'app_func_name', 'app_file_name', and 'api_name' strings are statically allocated (by the compiler) + * and are not allocated, so there's no need to free them. + */ + ev->op_info.api_name = NULL; + if (ev->op_info.api_args) + H5MM_xfree_const(ev->op_info.api_args); + ev->op_info.app_file_name = NULL; + ev->op_info.app_func_name = NULL; if (ev->request) { /* Free the request */ if (H5VL_request_free(ev->request) < 0) diff --git a/src/H5ESint.c b/src/H5ESint.c index da3f779..6f9efe9 100644 --- a/src/H5ESint.c +++ b/src/H5ESint.c @@ -53,11 +53,18 @@ /* Callback context for wait operations */ typedef struct H5ES_wait_ctx_t { H5ES_t * es; /* Event set being operated on */ - uint64_t timeout; /* Timeout for wait operation */ + uint64_t timeout; /* Timeout for wait operation (in ns) */ size_t * num_in_progress; /* Count of # of operations that have not completed */ hbool_t *op_failed; /* Flag to indicate an operation failed */ } H5ES_wait_ctx_t; +/* Callback context for cancel operations */ +typedef struct H5ES_cancel_ctx_t { + H5ES_t * es; /* Event set being operated on */ + size_t * num_not_canceled; /* Count of # of operations were not canceled */ + hbool_t *op_failed; /* Flag to indicate an operation failed */ +} H5ES_cancel_ctx_t; + /* Callback context for get error info (gei) operations */ typedef struct H5ES_gei_ctx_t { H5ES_t * es; /* Event set being operated on */ @@ -73,9 +80,14 @@ typedef struct H5ES_gei_ctx_t { /********************/ /* Local Prototypes */ /********************/ +static herr_t H5ES__close(H5ES_t *es); static herr_t H5ES__close_cb(void *es, void **request_token); +static herr_t H5ES__insert(H5ES_t *es, H5VL_t *connector, void *request_token, const char *app_file, + const char *app_func, unsigned app_line, const char *caller, const char *api_args); static herr_t H5ES__handle_fail(H5ES_t *es, H5ES_event_t *ev); +static herr_t H5ES__op_complete(H5ES_t *es, H5ES_event_t *ev, H5VL_request_status_t ev_status); static int H5ES__wait_cb(H5ES_event_t *ev, void *_ctx); +static int H5ES__cancel_cb(H5ES_event_t *ev, void *_ctx); static int H5ES__get_err_info_cb(H5ES_event_t *ev, void *_ctx); static int H5ES__close_failed_cb(H5ES_event_t *ev, void *_ctx); @@ -233,6 +245,81 @@ done: } /* end H5ES__create() */ /*------------------------------------------------------------------------- + * Function: H5ES__insert + * + * Purpose: Insert a request token into an event set + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, December 11, 2020 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5ES__insert(H5ES_t *es, H5VL_t *connector, void *request_token, const char *app_file, const char *app_func, + unsigned app_line, const char *caller, const char *api_args) +{ + H5ES_event_t *ev = NULL; /* Event for request */ + hbool_t ev_inserted = FALSE; /* Flag to indicate that event is in active list */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(es); + + /* Create new event */ + if (NULL == (ev = H5ES__event_new(connector, request_token))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTCREATE, FAIL, "can't create event object") + + /* Copy the app source information */ + /* The 'app_func' & 'app_file' strings are statically allocated (by the compiler) + * there's no need to duplicate them. + */ + ev->op_info.app_file_name = app_file; + ev->op_info.app_func_name = app_func; + ev->op_info.app_line_num = app_line; + + /* Set the event's operation counter */ + ev->op_info.op_ins_count = es->op_counter++; + + /* Set the event's timestamp & execution time */ + ev->op_info.op_ins_ts = H5_now_usec(); + ev->op_info.op_exec_ts = UINT64_MAX; + ev->op_info.op_exec_time = UINT64_MAX; + + /* Copy the API routine's name & arguments */ + /* The 'caller' string is also statically allocated (by the compiler) + * there's no need to duplicate it. + */ + ev->op_info.api_name = caller; + if (NULL == (ev->op_info.api_args = H5MM_xstrdup(api_args))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, FAIL, "can't copy API routine arguments") + + /* Append fully initialized event onto the event set's 'active' list */ + H5ES__list_append(&es->active, ev); + ev_inserted = TRUE; + + /* Invoke the event set's 'insert' callback, if present */ + if (es->ins_func) + if ((es->ins_func)(&ev->op_info, es->ins_ctx) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CALLBACK, FAIL, "'insert' callback for event set failed") + +done: + /* Release resources on error */ + if (ret_value < 0) + if (ev) { + if (ev_inserted) + H5ES__list_remove(&es->active, ev); + if (H5ES__event_free(ev) < 0) + HDONE_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, FAIL, "unable to release event") + } + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__insert() */ + +/*------------------------------------------------------------------------- * Function: H5ES_insert * * Purpose: Insert a request token into an event set @@ -247,15 +334,15 @@ done: herr_t H5ES_insert(hid_t es_id, H5VL_t *connector, void *token, const char *caller, const char *caller_args, ...) { - H5ES_t * es = NULL; /* Event set for the operation */ - H5ES_event_t *ev = NULL; /* Event for request */ - H5RS_str_t * rs = NULL; /* Ref-counted string to compose formatted argument string in */ - const char * app_file; /* Application source file name */ - const char * app_func; /* Application source function name */ - const char * s; /* Pointer to internal string from ref-counted string */ - va_list ap; /* Varargs for caller */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ - herr_t ret_value = SUCCEED; /* Return value */ + H5ES_t * es = NULL; /* Event set for the operation */ + const char *app_file; /* Application source file name */ + const char *app_func; /* Application source function name */ + unsigned app_line; /* Application source line number */ + H5RS_str_t *rs = NULL; /* Ref-counted string to compose formatted argument string in */ + const char *api_args; /* Pointer to api_args string from ref-counted string */ + va_list ap; /* Varargs for caller */ + hbool_t arg_started = FALSE; /* Whether the va_list has been started */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -273,10 +360,6 @@ H5ES_insert(hid_t es_id, H5VL_t *connector, void *token, const char *caller, con if (es->err_occurred) HGOTO_ERROR(H5E_EVENTSET, H5E_CANTINSERT, FAIL, "event set has failed operations") - /* Create new event */ - if (NULL == (ev = H5ES__event_new(connector, token))) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTCREATE, FAIL, "can't create event object") - /* Start working on the API routines arguments */ HDva_start(ap, caller_args); arg_started = TRUE; @@ -284,24 +367,10 @@ H5ES_insert(hid_t es_id, H5VL_t *connector, void *token, const char *caller, con /* Copy the app source information */ (void)HDva_arg(ap, char *); /* Toss the 'app_file' parameter name */ app_file = HDva_arg(ap, char *); - if (NULL == (ev->app_file = H5MM_strdup(app_file))) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, FAIL, "can't copy app source file name") (void)HDva_arg(ap, char *); /* Toss the 'app_func' parameter name */ app_func = HDva_arg(ap, char *); - if (NULL == (ev->app_func = H5MM_strdup(app_func))) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, FAIL, "can't copy app source function name") (void)HDva_arg(ap, char *); /* Toss the 'app_line' parameter name */ - ev->app_line = HDva_arg(ap, unsigned); - - /* Set the event's operation counter */ - ev->ev_count = es->op_counter++; - - /* Set the event's timestamp */ - ev->ev_time = H5_now_usec(); - - /* Copy the API routine's name */ - if (NULL == (ev->api_name = H5MM_strdup(caller))) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, FAIL, "can't copy API routine name") + app_line = HDva_arg(ap, unsigned); /* Create the string for the API routine's arguments */ if (NULL == (rs = H5RS_create(NULL))) @@ -312,13 +381,12 @@ H5ES_insert(hid_t es_id, H5VL_t *connector, void *token, const char *caller, con HDassert(0 == HDstrncmp(caller_args, "*s*sIu", 6)); if (H5_trace_args(rs, caller_args + 6, ap) < 0) HGOTO_ERROR(H5E_EVENTSET, H5E_CANTSET, FAIL, "can't create formatted API arguments") - if (NULL == (s = H5RS_get_str(rs))) + if (NULL == (api_args = H5RS_get_str(rs))) HGOTO_ERROR(H5E_EVENTSET, H5E_CANTGET, FAIL, "can't get pointer to formatted API arguments") - if (NULL == (ev->api_args = H5MM_strdup(s))) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, FAIL, "can't copy API routine arguments") - /* Append fully initialized event onto the event set's 'active' list */ - H5ES__list_append(&es->active, ev); + /* Insert the operation into the event set */ + if (H5ES__insert(es, connector, token, app_file, app_func, app_line, caller, api_args) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTINSERT, FAIL, "event set has failed operations") done: /* Clean up */ @@ -327,15 +395,42 @@ done: if (rs) H5RS_decr(rs); - /* Release resources on error */ - if (ret_value < 0) - if (ev && H5ES__event_free(ev) < 0) - HDONE_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, FAIL, "unable to release event") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5ES_insert() */ /*------------------------------------------------------------------------- + * Function: H5ES__insert_request + * + * Purpose: Directly insert a request token into an event set + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, December 11, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ES__insert_request(H5ES_t *es, H5VL_t *connector, void *token) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity check */ + HDassert(es); + HDassert(connector); + HDassert(token); + + /* Insert an 'anonymous' operation into the event set */ + if (H5ES__insert(es, connector, token, NULL, NULL, 0, NULL, NULL) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTINSERT, FAIL, "event set has failed operations") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__insert_request() */ + +/*------------------------------------------------------------------------- * Function: H5ES__handle_fail * * Purpose: Handle a failed event @@ -370,6 +465,101 @@ H5ES__handle_fail(H5ES_t *es, H5ES_event_t *ev) } /* end H5ES__handle_fail() */ /*------------------------------------------------------------------------- + * Function: H5ES__op_complete + * + * Purpose: Handle an operation completing + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, December 11, 2020 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5ES__op_complete(H5ES_t *es, H5ES_event_t *ev, H5VL_request_status_t ev_status) +{ + H5VL_request_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + hid_t err_stack_id = H5I_INVALID_HID; /* Error stack for failed operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(es); + HDassert(ev); + HDassert(H5VL_REQUEST_STATUS_SUCCEED == ev_status || H5VL_REQUEST_STATUS_FAIL == ev_status || + H5VL_REQUEST_STATUS_CANCELED == ev_status); + + /* Handle each form of event completion */ + if (H5VL_REQUEST_STATUS_SUCCEED == ev_status || H5VL_REQUEST_STATUS_CANCELED == ev_status) { + /* Invoke the event set's 'complete' callback, if present */ + if (es->comp_func) { + H5ES_status_t op_status; /* Status for complete callback */ + + /* Set appropriate info for callback */ + if (H5VL_REQUEST_STATUS_SUCCEED == ev_status) { + /* Translate status */ + op_status = H5ES_STATUS_SUCCEED; + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_REQUEST_GET_EXEC_TIME; + vol_cb_args.args.get_exec_time.exec_ts = &ev->op_info.op_exec_ts; + vol_cb_args.args.get_exec_time.exec_time = &ev->op_info.op_exec_time; + + /* Retrieve the execution time info */ + if (H5VL_request_specific(ev->request, &vol_cb_args) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTGET, FAIL, + "unable to retrieve execution time info for operation") + } + else + /* Translate status */ + op_status = H5ES_STATUS_CANCELED; + + if ((es->comp_func)(&ev->op_info, op_status, H5I_INVALID_HID, es->comp_ctx) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CALLBACK, FAIL, "'complete' callback for event set failed") + } /* end if */ + + /* Event success or cancellation */ + if (H5ES__event_completed(ev, &es->active) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, FAIL, "unable to release completed event") + } /* end if */ + else if (H5VL_REQUEST_STATUS_FAIL == ev_status) { + /* Invoke the event set's 'complete' callback, if present */ + if (es->comp_func) { + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_REQUEST_GET_ERR_STACK; + vol_cb_args.args.get_err_stack.err_stack_id = H5I_INVALID_HID; + + /* Retrieve the error stack for the operation */ + if (H5VL_request_specific(ev->request, &vol_cb_args) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTGET, FAIL, "unable to retrieve error stack for operation") + + /* Set values */ + err_stack_id = vol_cb_args.args.get_err_stack.err_stack_id; + + if ((es->comp_func)(&ev->op_info, H5ES_STATUS_FAIL, err_stack_id, es->comp_ctx) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CALLBACK, FAIL, "'complete' callback for event set failed") + } /* end if */ + + /* Handle failure */ + if (H5ES__handle_fail(es, ev) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTSET, FAIL, "unable to handle failed event") + } /* end else-if */ + else + HGOTO_ERROR(H5E_EVENTSET, H5E_BADVALUE, FAIL, "unknown event status?!?") + +done: + /* Clean up */ + if (H5I_INVALID_HID != err_stack_id) + if (H5I_dec_ref(err_stack_id) < 0) + HDONE_ERROR(H5E_EVENTSET, H5E_CANTDEC, FAIL, + "unable to decrement ref count on error stack for failed operation") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__op_complete() */ + +/*------------------------------------------------------------------------- * Function: H5ES__wait_cb * * Purpose: Common routine for testing / waiting on an operation @@ -405,9 +595,9 @@ H5ES__wait_cb(H5ES_event_t *ev, void *_ctx) /* Check for status values that indicate we should break out of the loop */ if (ev_status == H5VL_REQUEST_STATUS_FAIL) { - /* Handle failure */ - if (H5ES__handle_fail(ctx->es, ev) < 0) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTSET, H5_ITER_ERROR, "unable to handle failed event") + /* Handle event completion */ + if (H5ES__op_complete(ctx->es, ev, ev_status) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, H5_ITER_ERROR, "unable to release completed event") /* Record the error */ *ctx->op_failed = TRUE; @@ -415,13 +605,15 @@ H5ES__wait_cb(H5ES_event_t *ev, void *_ctx) /* Exit from the iteration */ ret_value = H5_ITER_STOP; } /* end if */ - else if (ev_status == H5VL_REQUEST_STATUS_SUCCEED) { - if (H5ES__event_completed(ev, &ctx->es->active) < 0) + else if (ev_status == H5VL_REQUEST_STATUS_SUCCEED || ev_status == H5VL_REQUEST_STATUS_CANCELED) { + /* Handle event completion */ + if (H5ES__op_complete(ctx->es, ev, ev_status) < 0) HGOTO_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, H5_ITER_ERROR, "unable to release completed event") } /* end else-if */ - else if (ev_status == H5VL_REQUEST_STATUS_CANCELED) - /* Should never get a status of 'cancel' back from test / wait operation */ - HGOTO_ERROR(H5E_EVENTSET, H5E_BADVALUE, H5_ITER_ERROR, "received 'cancel' status for operation") + else if (ev_status == H5VL_REQUEST_STATUS_CANT_CANCEL) + /* Should never get a status of 'can't cancel' back from test / wait operation */ + HGOTO_ERROR(H5E_EVENTSET, H5E_BADVALUE, H5_ITER_ERROR, + "received \"can't cancel\" status for operation") else { /* Sanity check */ HDassert(ev_status == H5VL_REQUEST_STATUS_IN_PROGRESS); @@ -489,6 +681,114 @@ done: } /* end H5ES__wait() */ /*------------------------------------------------------------------------- + * Function: H5ES__cancel_cb + * + * Purpose: Callback for canceling operations + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Thursday, December 10, 2020 + * + *------------------------------------------------------------------------- + */ +static int +H5ES__cancel_cb(H5ES_event_t *ev, void *_ctx) +{ + H5ES_cancel_ctx_t * ctx = (H5ES_cancel_ctx_t *)_ctx; /* Callback context */ + H5VL_request_status_t ev_status = H5VL_REQUEST_STATUS_SUCCEED; /* Status from event's operation */ + int ret_value = H5_ITER_CONT; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(ev); + HDassert(ctx); + + /* Attempt to cancel the request */ + if (H5VL_request_cancel(ev->request, &ev_status) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTCANCEL, H5_ITER_ERROR, "unable to cancel operation") + + /* Check for status values that indicate we should break out of the loop */ + if (ev_status == H5VL_REQUEST_STATUS_FAIL) { + /* Handle event completion */ + if (H5ES__op_complete(ctx->es, ev, ev_status) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTSET, H5_ITER_ERROR, "unable to handle failed event") + + /* Record the error */ + *ctx->op_failed = TRUE; + + /* Exit from the iteration */ + ret_value = H5_ITER_STOP; + } /* end if */ + else if (ev_status == H5VL_REQUEST_STATUS_SUCCEED) { + /* Increment "not canceled" counter */ + (*ctx->num_not_canceled)++; + + /* Handle event completion */ + if (H5ES__op_complete(ctx->es, ev, ev_status) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, H5_ITER_ERROR, "unable to release completed event") + } /* end else-if */ + else if (ev_status == H5VL_REQUEST_STATUS_CANT_CANCEL || ev_status == H5VL_REQUEST_STATUS_IN_PROGRESS) { + /* Increment "not canceled" counter */ + (*ctx->num_not_canceled)++; + } /* end else-if */ + else { + /* Sanity check */ + HDassert(ev_status == H5VL_REQUEST_STATUS_CANCELED); + + /* Handle event completion */ + if (H5ES__op_complete(ctx->es, ev, ev_status) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, H5_ITER_ERROR, "unable to release completed event") + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__cancel_cb() */ + +/*------------------------------------------------------------------------- + * Function: H5ES__cancel + * + * Purpose: Cancel operations in event set + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Thursday, December 10, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ES__cancel(H5ES_t *es, size_t *num_not_canceled, hbool_t *op_failed) +{ + H5ES_cancel_ctx_t ctx; /* Iterator callback context info */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity check */ + HDassert(es); + HDassert(num_not_canceled); + HDassert(op_failed); + + /* Set user's parameters to known values */ + *num_not_canceled = 0; + *op_failed = FALSE; + + /* Set up context for iterator callbacks */ + ctx.es = es; + ctx.num_not_canceled = num_not_canceled; + ctx.op_failed = op_failed; + + /* Iterate over the events in the set, attempting to cancel them */ + if (H5ES__list_iterate(&es->active, H5ES__cancel_cb, &ctx) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_BADITER, FAIL, "iteration failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__cancel() */ + +/*------------------------------------------------------------------------- * Function: H5ES__get_err_info_cb * * Purpose: Retrieve information about a failed operation @@ -503,8 +803,9 @@ done: static int H5ES__get_err_info_cb(H5ES_event_t *ev, void *_ctx) { - H5ES_gei_ctx_t *ctx = (H5ES_gei_ctx_t *)_ctx; /* Callback context */ - int ret_value = H5_ITER_CONT; /* Return value */ + H5VL_request_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5ES_gei_ctx_t * ctx = (H5ES_gei_ctx_t *)_ctx; /* Callback context */ + int ret_value = H5_ITER_CONT; /* Return value */ FUNC_ENTER_STATIC @@ -513,22 +814,35 @@ H5ES__get_err_info_cb(H5ES_event_t *ev, void *_ctx) HDassert(ctx); /* Copy operation info for event */ - if (NULL == (ctx->curr_err_info->api_name = H5MM_strdup(ev->api_name))) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy HDF5 API name") - if (NULL == (ctx->curr_err_info->api_args = H5MM_strdup(ev->api_args))) + /* The 'app_func_name', 'app_file_name', and 'api_name' strings are statically allocated (by the compiler) + * so there's no need to duplicate them internally, but they are duplicated + * here, when they are given back to the user. + */ + if (NULL == (ctx->curr_err_info->api_name = H5MM_strdup(ev->op_info.api_name))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy HDF5 API routine name") + if (NULL == (ctx->curr_err_info->api_args = H5MM_strdup(ev->op_info.api_args))) HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy HDF5 API routine arguments") - if (NULL == (ctx->curr_err_info->app_file_name = H5MM_strdup(ev->app_file))) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy app source file name") - if (NULL == (ctx->curr_err_info->app_func_name = H5MM_strdup(ev->app_func))) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy app function name") - ctx->curr_err_info->app_line_num = ev->app_line; - ctx->curr_err_info->op_ins_count = ev->ev_count; - ctx->curr_err_info->op_ins_ts = ev->ev_time; + if (NULL == (ctx->curr_err_info->app_file_name = H5MM_strdup(ev->op_info.app_file_name))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy HDF5 application file name") + if (NULL == (ctx->curr_err_info->app_func_name = H5MM_strdup(ev->op_info.app_func_name))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy HDF5 application function name") + ctx->curr_err_info->app_line_num = ev->op_info.app_line_num; + ctx->curr_err_info->op_ins_count = ev->op_info.op_ins_count; + ctx->curr_err_info->op_ins_ts = ev->op_info.op_ins_ts; + ctx->curr_err_info->op_exec_ts = ev->op_info.op_exec_ts; + ctx->curr_err_info->op_exec_time = ev->op_info.op_exec_time; + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_REQUEST_GET_ERR_STACK; + vol_cb_args.args.get_err_stack.err_stack_id = H5I_INVALID_HID; /* Get error stack for event */ - if (H5VL_request_specific(ev->request, H5VL_REQUEST_GET_ERR_STACK, &ctx->curr_err_info->err_stack_id) < 0) + if (H5VL_request_specific(ev->request, &vol_cb_args) < 0) HGOTO_ERROR(H5E_EVENTSET, H5E_CANTGET, H5_ITER_ERROR, "unable to retrieve error stack for operation") + /* Set value */ + ctx->curr_err_info->err_stack_id = vol_cb_args.args.get_err_stack.err_stack_id; + /* Remove event from event set's failed list */ H5ES__list_remove(&ctx->es->failed, ev); diff --git a/src/H5ESmodule.h b/src/H5ESmodule.h index cbc812e..5169b52 100644 --- a/src/H5ESmodule.h +++ b/src/H5ESmodule.h @@ -29,8 +29,10 @@ #define H5_MY_PKG_ERR H5E_EVENTSET #define H5_MY_PKG_INIT YES -/** - * \defgroup H5ES H5ES +/**\defgroup H5ES H5ES + * + * \todo Add the event set life cycle. + * * \brief Event Set Interface * * \details \Bold{This interface can be only used with the HDF5 VOL connectors that diff --git a/src/H5ESpkg.h b/src/H5ESpkg.h index 339ce1d..a7a8e20 100644 --- a/src/H5ESpkg.h +++ b/src/H5ESpkg.h @@ -43,14 +43,7 @@ typedef struct H5ES_event_t { H5VL_object_t * request; /* Request token for event */ struct H5ES_event_t *prev, *next; /* Previous and next event nodes */ - /* Useful info for debugging and error reporting */ - const char *api_name; /* Name of API routine for event */ - const char *api_args; /* Arguments to API routine */ - const char *app_file; /* Name of source file from application */ - const char *app_func; /* Name of source function from application */ - unsigned app_line; /* Line # of source file from application */ - uint64_t ev_count; /* This event is the n'th operation in the event set */ - uint64_t ev_time; /* Timestamp for this event (in ms from UNIX epoch) */ + H5ES_op_info_t op_info; /* Useful info about operation */ } H5ES_event_t; /* Typedef for lists of event set operations */ @@ -61,7 +54,11 @@ typedef struct H5ES_event_list_t { /* Typedef for event set objects */ struct H5ES_t { - uint64_t op_counter; /* Count of operations inserted into this set */ + uint64_t op_counter; /* Count of operations inserted into this set */ + H5ES_event_insert_func_t ins_func; /* Callback to invoke for operation inserts */ + void * ins_ctx; /* Context for callback to invoke for operation inserts */ + H5ES_event_complete_func_t comp_func; /* Callback to invoke for operation completions */ + void * comp_ctx; /* Context for callback to invoke for operation inserts */ /* Active events */ H5ES_event_list_t active; /* List of active events in set */ @@ -82,10 +79,11 @@ typedef int (*H5ES_list_iter_func_t)(H5ES_event_t *ev, void *ctx); /* Package Private Prototypes */ /******************************/ H5_DLL H5ES_t *H5ES__create(void); +H5_DLL herr_t H5ES__insert_request(H5ES_t *es, H5VL_t *connector, void *token); H5_DLL herr_t H5ES__wait(H5ES_t *es, uint64_t timeout, size_t *num_in_progress, hbool_t *op_failed); +H5_DLL herr_t H5ES__cancel(H5ES_t *es, size_t *num_not_canceled, hbool_t *op_failed); H5_DLL herr_t H5ES__get_err_info(H5ES_t *es, size_t num_err_info, H5ES_err_info_t err_info[], size_t *num_cleared); -H5_DLL herr_t H5ES__close(H5ES_t *es); /* Event list operations */ H5_DLL void H5ES__list_append(H5ES_event_list_t *el, H5ES_event_t *ev); diff --git a/src/H5ESprivate.h b/src/H5ESprivate.h index 4f843ba..3d9ce9f 100644 --- a/src/H5ESprivate.h +++ b/src/H5ESprivate.h @@ -24,8 +24,9 @@ #ifndef H5ESprivate_H #define H5ESprivate_H -/* Include package's public header */ -#include "H5ESpublic.h" /* Event Sets */ +/* Include package's public headers */ +#include "H5ESpublic.h" +#include "H5ESdevelop.h" /* Private headers needed by this file */ #include "H5VLprivate.h" /* Virtual Object Layer */ diff --git a/src/H5ESpublic.h b/src/H5ESpublic.h index 409282c..4cf71c5 100644 --- a/src/H5ESpublic.h +++ b/src/H5ESpublic.h @@ -42,24 +42,49 @@ /* Asynchronous operation status */ typedef enum H5ES_status_t { - H5ES_STATUS_IN_PROGRESS, /* Operation(s) have not yet completed */ - H5ES_STATUS_SUCCEED, /* Operation(s) have completed, successfully */ - H5ES_STATUS_FAIL /* An operation has completed, but failed */ + H5ES_STATUS_IN_PROGRESS, /* Operation(s) have not yet completed */ + H5ES_STATUS_SUCCEED, /* Operation(s) have completed, successfully */ + H5ES_STATUS_CANCELED, /* Operation(s) has been canceled */ + H5ES_STATUS_FAIL /* An operation has completed, but failed */ } H5ES_status_t; +/* Information about operations in an event set */ +typedef struct H5ES_op_info_t { + /* API call info */ + char *api_name; /* Name of HDF5 API routine called */ + char *api_args; /* "Argument string" for arguments to HDF5 API routine called */ + + /* Application info */ + char * app_file_name; /* Name of source file where the HDF5 API routine was called */ + char * app_func_name; /* Name of function where the HDF5 API routine was called */ + unsigned app_line_num; /* Line # of source file where the HDF5 API routine was called */ + + /* Operation info */ + uint64_t op_ins_count; /* Counter of operation's insertion into event set */ + uint64_t op_ins_ts; /* Timestamp for when the operation was inserted into the event set */ + uint64_t op_exec_ts; /* Timestamp for when the operation began execution */ + uint64_t op_exec_time; /* Execution time for operation (in ns) */ +} H5ES_op_info_t; + //! <!-- [H5ES_err_info_t_snip] --> /** * Information about failed operations in event set */ typedef struct H5ES_err_info_t { - /* Operation info */ - char * api_name; /**< Name of HDF5 API routine called */ - char * api_args; /**< "Argument string" for arguments to HDF5 API routine called */ + /* API call info */ + char *api_name; /**< Name of HDF5 API routine called */ + char *api_args; /**< "Argument string" for arguments to HDF5 API routine called */ + + /* Application info */ char * app_file_name; /**< Name of source file where the HDF5 API routine was called */ char * app_func_name; /**< Name of function where the HDF5 API routine was called */ unsigned app_line_num; /**< Line # of source file where the HDF5 API routine was called */ - uint64_t op_ins_count; /**< Counter of operation's insertion into event set */ - uint64_t op_ins_ts; /**< Timestamp for when the operation was inserted into the event set */ + + /* Operation info */ + uint64_t op_ins_count; /**< Counter of operation's insertion into event set */ + uint64_t op_ins_ts; /**< Timestamp for when the operation was inserted into the event set */ + uint64_t op_exec_ts; /**< Timestamp for when the operation began execution */ + uint64_t op_exec_time; /**< Execution time for operation (in ns) */ /* Error info */ hid_t err_stack_id; /**< ID for error stack from failed operation */ @@ -67,25 +92,11 @@ typedef struct H5ES_err_info_t { //! <!-- [H5ES_err_info_t_snip] --> /* -H5ES_op_info_t: - const char *: API name (H5Dwrite_async, ...) - const char *: Arg string - const char *: Appl. source file name - const char *: Appl. source function - unsigned: Appl. source file line - uint64_t: Insert Time Timestamp - uint64_t: "event count" - n'th event inserted into event set - uint64_t: Execution Time timestamp (*) - More Possible Info for H5ES_op_info_t: Parent Operation's request token (*) -> "parent event count"? -- Could be used to "prune" child operations from reported errors, with flag to H5ESget_err_info? -H5ES_err_info_t: - H5ES_op_info_t: (above) - hid_t: Error stack (*) - Possible debugging routines: (Should also be configured from Env Var) H5ESdebug_signal(hid_t es_id, signal_t sig, uint64_t <event count>); H5ESdebug_err_trace_log(hid_t es_id, const char *filename); @@ -102,15 +113,12 @@ Possible debugging routines: (Should also be configured from Env Var) How to Trace Async Operations? <Example of stacking Logging VOL Connector w/Async VOL Connector> -"Library / wrapper developer" version of API routines: (Auto-generated) - H5Dwrite_async_wrap(const char *app_file, const char *app_func, - unsigned app_line_num, dset_id, mem_type_id, mem_space_id, ..., es_id); - - vs. - - H5Dwrite_async(dset_id, mem_type_id, mem_space_id, ..., es_id); */ +typedef int (*H5ES_event_insert_func_t)(const H5ES_op_info_t *op_info, void *ctx); +typedef int (*H5ES_event_complete_func_t)(const H5ES_op_info_t *op_info, H5ES_status_t status, + hid_t err_stack, void *ctx); + /********************/ /* Public Variables */ /********************/ @@ -170,6 +178,7 @@ H5_DLL hid_t H5EScreate(void); * */ H5_DLL herr_t H5ESwait(hid_t es_id, uint64_t timeout, size_t *num_in_progress, hbool_t *err_occurred); +H5_DLL herr_t H5EScancel(hid_t es_id, size_t *num_not_canceled, hbool_t *err_occurred); /** * \ingroup H5ES @@ -260,6 +269,9 @@ H5_DLL herr_t H5ESget_err_count(hid_t es_id, size_t *num_errs); */ H5_DLL herr_t H5ESget_err_info(hid_t es_id, size_t num_err_info, H5ES_err_info_t err_info[], size_t *err_cleared); +H5_DLL herr_t H5ESfree_err_info(size_t num_err_info, H5ES_err_info_t err_info[]); +H5_DLL herr_t H5ESregister_insert_func(hid_t es_id, H5ES_event_insert_func_t func, void *ctx); +H5_DLL herr_t H5ESregister_complete_func(hid_t es_id, H5ES_event_complete_func_t func, void *ctx); /** * \ingroup H5ES diff --git a/src/H5Eint.c b/src/H5Eint.c index 3fd4099..6438cd9 100644 --- a/src/H5Eint.c +++ b/src/H5Eint.c @@ -129,7 +129,7 @@ H5E__get_msg(const H5E_msg_t *msg, H5E_type_t *type, char *msg_str, size_t size) /* Copy the message into the user's buffer, if given */ if (msg_str) { - HDstrncpy(msg_str, msg->msg, MIN((size_t)(len + 1), size)); + HDstrncpy(msg_str, msg->msg, size); if ((size_t)len >= size) msg_str[size - 1] = '\0'; } /* end if */ @@ -772,11 +772,12 @@ H5E__push_stack(H5E_t *estack, const char *file, const char *func, unsigned line if (H5I_inc_ref(min_id, FALSE) < 0) HGOTO_DONE(FAIL) estack->slot[estack->nused].min_num = min_id; - if (NULL == (estack->slot[estack->nused].func_name = H5MM_xstrdup(func))) - HGOTO_DONE(FAIL) - if (NULL == (estack->slot[estack->nused].file_name = H5MM_xstrdup(file))) - HGOTO_DONE(FAIL) - estack->slot[estack->nused].line = line; + /* The 'func' & 'file' strings are statically allocated (by the compiler) + * there's no need to duplicate them. + */ + estack->slot[estack->nused].func_name = func; + estack->slot[estack->nused].file_name = file; + estack->slot[estack->nused].line = line; if (NULL == (estack->slot[estack->nused].desc = H5MM_xstrdup(desc))) HGOTO_DONE(FAIL) estack->nused++; @@ -826,10 +827,11 @@ H5E__clear_entries(H5E_t *estack, size_t nentries) HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error class") /* Release strings */ - if (error->func_name) - error->func_name = (const char *)H5MM_xfree_const(error->func_name); - if (error->file_name) - error->file_name = (const char *)H5MM_xfree_const(error->file_name); + /* The 'func' & 'file' strings are statically allocated (by the compiler) + * and are not allocated, so there's no need to free them. + */ + error->func_name = NULL; + error->file_name = NULL; if (error->desc) error->desc = (const char *)H5MM_xfree_const(error->desc); } diff --git a/src/H5Emodule.h b/src/H5Emodule.h index 43d5d36..58a3517 100644 --- a/src/H5Emodule.h +++ b/src/H5Emodule.h @@ -29,33 +29,54 @@ #define H5_MY_PKG_ERR H5E_ERROR #define H5_MY_PKG_INIT YES -/** - * \defgroup H5E H5E - * \brief Error Handling Interface - * - * \details The Error interface provides error handling in the form of a stack. - * The \Code{FUNC_ENTER} macro clears the error stack whenever an - * interface function is entered. When an error is detected, an entry - * is pushed onto the stack. As the functions unwind, additional - * entries are pushed onto the stack. The API function will return some - * indication that an error occurred and the application can print the - * error stack. - * - * Certain API functions in the \c H5E package, such as H5Eprint1(), do - * not clear the error stack. Otherwise, any function which does not - * have an underscore immediately after the package name will clear the - * error stack. For instance, H5Fopen() clears the error stack while - * \Code{H5F_open} does not. - * - * An error stack has a fixed maximum size. If this size is exceeded - * then the stack will be truncated and only the inner-most functions - * will have entries on the stack. This is expected to be a rare - * condition. - * - * Each thread has its own error stack, but since multi-threading has - * not been added to the library yet, this package maintains a single - * error stack. The error stack is statically allocated to reduce the - * complexity of handling errors within the \c H5E package. +/**\defgroup H5E H5E + * + * Use the functions in this module to manage HDF5 error stacks and error + * messages. + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5E_examples.c create + * </td> + * <td> + * \snippet{lineno} H5E_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5E_examples.c update + * </td> + * <td> + * \snippet{lineno} H5E_examples.c delete + * </td> + * </tr> + * </table> + * + * \internal The \c FUNC_ENTER macro clears the error stack whenever an + * interface function is entered. When an error is detected, an entry + * is pushed onto the stack. As the functions unwind, additional + * entries are pushed onto the stack. The API function will return + * some indication that an error occurred and the application can + * print the error stack. + * + * \internal Certain API functions in the \ref H5E package, such as H5Eprint(), + * do not clear the error stack. Otherwise, any function which does + * not have an underscore immediately after the package name will + * clear the error stack. For instance, H5Fopen() clears the error + * stack while \Code{H5F_open} does not. + * + * \internal An error stack has a fixed maximum size. If this size is exceeded + * then the stack will be truncated and only the inner-most functions + * will have entries on the stack. This is expected to be a rare + * condition. + * + * \internal Each thread has its own error stack, but since multi-threading has + * not been added to the library yet, this package maintains a single + * error stack. The error stack is statically allocated to reduce the + * complexity of handling errors within the \ref H5E package. + * */ #endif /* H5Emodule_H */ diff --git a/src/H5Epublic.h b/src/H5Epublic.h index 0294023..9dfd1fc 100644 --- a/src/H5Epublic.h +++ b/src/H5Epublic.h @@ -716,12 +716,13 @@ typedef herr_t (*H5E_auto1_t)(void *client_data); * * \return \herr_t * + * \deprecated 1.8.0 Function H5Eclear() renamed to H5Eclear1() and deprecated + * in this release. + * * \details H5Eclear1() clears the error stack for the current thread.\n * The stack is also cleared whenever an API function is called, with * certain exceptions (for instance, H5Eprint1()). * - * \deprecated 1.8.0 Function H5Eclear() renamed to H5Eclear1() and deprecated - * in this release. */ H5_DLL herr_t H5Eclear1(void); /** @@ -737,6 +738,9 @@ H5_DLL herr_t H5Eclear1(void); * function * \return \herr_t * + * \deprecated 1.8.0 Function H5Eget_auto() renamed to H5Eget_auto1() and + * deprecated in this release. + * * \details H5Eget_auto1() returns the current settings for the automatic error * stack traversal function, \p func, and its data, * \p client_data. Either or both arguments may be \c NULL, in which case the @@ -763,8 +767,6 @@ H5_DLL herr_t H5Eclear1(void); * H5Eprint2(), mixing H5Eset_auto1() and H5Eget_auto2() or mixing * H5Eset_auto2() and H5Eget_auto1() does not fail. * - * \deprecated 1.8.0 Function H5Eget_auto() renamed to H5Eget_auto1() and - * deprecated in this release. */ H5_DLL herr_t H5Eget_auto1(H5E_auto1_t *func, void **client_data); /** @@ -781,6 +783,9 @@ H5_DLL herr_t H5Eget_auto1(H5E_auto1_t *func, void **client_data); * \param[in] str Error description string * \return \herr_t * + * \deprecated 1.8.0 Function H5Epush() renamed to H5Epush1() and + * deprecated in this release. + * * \details H5Epush1() pushes a new error record onto the error stack for the * current thread.\n * The error has major and minor numbers \p maj_num @@ -791,8 +796,6 @@ H5_DLL herr_t H5Eget_auto1(H5E_auto1_t *func, void **client_data); * allocated. * * \since 1.4.0 - * \deprecated 1.8.0 Function H5Epush() renamed to H5Epush1() and - * deprecated in this release. */ H5_DLL herr_t H5Epush1(const char *file, const char *func, unsigned line, H5E_major_t maj, H5E_minor_t min, const char *str); @@ -805,6 +808,9 @@ H5_DLL herr_t H5Epush1(const char *file, const char *func, unsigned line, H5E_ma * \param[in] stream File pointer, or \c NULL for \c stderr * \return \herr_t * + * \deprecated 1.8.0 Function H5Eprint() renamed to H5Eprint1() and + * deprecated in this release. + * * \details H5Eprint1() prints prints the error stack for the current thread * on the specified stream, \p stream. Even if the error stack is empty, a * one-line message of the following form will be printed: @@ -815,8 +821,6 @@ H5_DLL herr_t H5Epush1(const char *file, const char *func, unsigned line, H5E_ma * that prints error messages. Users are encouraged to write their own * more specific error handlers. * - * \deprecated 1.8.0 Function H5Eprint() renamed to H5Eprint1() and - * deprecated in this release. */ H5_DLL herr_t H5Eprint1(FILE *stream); /** @@ -829,6 +833,9 @@ H5_DLL herr_t H5Eprint1(FILE *stream); * \param[in] client_data Data passed to the error function * \return \herr_t * + * \deprecated 1.8.0 Function H5Eset_auto() renamed to H5Eset_auto1() and + * deprecated in this release. + * * \details H5Eset_auto1() turns on or off automatic printing of errors. When * turned on (non-null \p func pointer), any API function which returns * an error indication will first call \p func, passing it \p @@ -845,8 +852,6 @@ H5_DLL herr_t H5Eprint1(FILE *stream); * Automatic stack traversal is always in the #H5E_WALK_DOWNWARD * direction. * - * \deprecated 1.8.0 Function H5Eset_auto() renamed to H5Eset_auto1() and - * deprecated in this release. */ H5_DLL herr_t H5Eset_auto1(H5E_auto1_t func, void *client_data); /** @@ -860,6 +865,9 @@ H5_DLL herr_t H5Eset_auto1(H5E_auto1_t func, void *client_data); * \param[in] client_data Data to be passed to \p func * \return \herr_t * + * \deprecated 1.8.0 Function H5Ewalk() renamed to H5Ewalk1() and + * deprecated in this release. + * * \details H5Ewalk1() walks the error stack for the current thread and calls * the function specified in \p func for each error along the way. * @@ -877,8 +885,6 @@ H5_DLL herr_t H5Eset_auto1(H5E_auto1_t func, void *client_data); * is as follows: * \snippet this H5E_walk1_t_snip * - * \deprecated 1.8.0 Function H5Ewalk() renamed to H5Ewalk1() and - * deprecated in this release. */ H5_DLL herr_t H5Ewalk1(H5E_direction_t direction, H5E_walk1_t func, void *client_data); /** @@ -891,6 +897,8 @@ H5_DLL herr_t H5Ewalk1(H5E_direction_t direction, H5E_walk1_t func, void *client * \param[in] maj Major error number * \return \herr_t * + * \deprecated 1.8.0 Function deprecated in this release. + * * \details Given a major error number, H5Eget_major() returns a constant * character string that describes the error. * @@ -898,7 +906,6 @@ H5_DLL herr_t H5Ewalk1(H5E_direction_t direction, H5E_walk1_t func, void *client * array). An application calling this function must free the memory * associated with the return value to prevent a memory leak. * - * \deprecated 1.8.0 Function deprecated in this release. */ H5_DLL char *H5Eget_major(H5E_major_t maj); /** @@ -911,6 +918,8 @@ H5_DLL char *H5Eget_major(H5E_major_t maj); * \param[in] min Minor error number * \return \herr_t * + * \deprecated 1.8.0 Function deprecated and return type changed in this release. + * * \details Given a minor error number, H5Eget_minor() returns a constant * character string that describes the error. * @@ -920,7 +929,6 @@ H5_DLL char *H5Eget_major(H5E_major_t maj); * the memory associated with the return value to prevent a memory * leak. This is a change from the 1.6.x release series. * - * \deprecated 1.8.0 Function deprecated and return type changed in this release. */ H5_DLL char *H5Eget_minor(H5E_minor_t min); #endif /* H5_NO_DEPRECATED_SYMBOLS */ diff --git a/src/H5F.c b/src/H5F.c index 0baf399..46c8c0e 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -112,8 +112,9 @@ H5FL_EXTERN(H5VL_object_t); hid_t H5Fget_create_plist(hid_t file_id) { - H5VL_object_t *vol_obj; /* File info */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj; /* File for file_id */ + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", file_id); @@ -122,10 +123,17 @@ H5Fget_create_plist(hid_t file_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid file identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_FCPL; + vol_cb_args.args.get_fcpl.fcpl_id = H5I_INVALID_HID; + /* Retrieve the file creation property list */ - if (H5VL_file_get(vol_obj, H5VL_FILE_GET_FCPL, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &ret_value) < 0) + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, H5I_INVALID_HID, "unable to retrieve file creation properties") + /* Set return value */ + ret_value = vol_cb_args.args.get_fcpl.fcpl_id; + done: FUNC_LEAVE_API(ret_value) } /* end H5Fget_create_plist() */ @@ -151,8 +159,9 @@ done: hid_t H5Fget_access_plist(hid_t file_id) { - H5VL_object_t *vol_obj; /* File info */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj; /* File for file_id */ + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", file_id); @@ -161,10 +170,17 @@ H5Fget_access_plist(hid_t file_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid file identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_FAPL; + vol_cb_args.args.get_fapl.fapl_id = H5I_INVALID_HID; + /* Retrieve the file's access property list */ - if (H5VL_file_get(vol_obj, H5VL_FILE_GET_FAPL, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &ret_value) < 0) + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't get file access property list") + /* Set return value */ + ret_value = vol_cb_args.args.get_fapl.fapl_id; + done: FUNC_LEAVE_API(ret_value) } /* end H5Fget_access_plist() */ @@ -222,16 +238,25 @@ H5Fget_obj_count(hid_t file_id, unsigned types) * count the IDs in the file. */ if (file_id != (hid_t)H5F_OBJ_ALL) { - H5VL_object_t *vol_obj; + H5VL_object_t * vol_obj; /* File for file_id */ + size_t count = 0; /* Object count */ + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ /* Get the file object */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "not a file id") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_OBJ_COUNT; + vol_cb_args.args.get_obj_count.types = types; + vol_cb_args.args.get_obj_count.count = &count; + /* Get the count */ - if (H5VL_file_get(vol_obj, H5VL_FILE_GET_OBJ_COUNT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, types, - &ret_value) < 0) + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, (-1), "unable to get object count in file(s)") + + /* Set return value */ + ret_value = (ssize_t)count; } /* If we passed in the 'special' ID, get the count for everything open in the * library, iterating over all open files and getting the object count for each. @@ -333,16 +358,27 @@ H5Fget_obj_ids(hid_t file_id, unsigned types, size_t max_objs, hid_t *oid_list / * get the IDs from the file. */ if (file_id != (hid_t)H5F_OBJ_ALL) { - H5VL_object_t *vol_obj; + H5VL_object_t * vol_obj; /* File for file_id */ + size_t count = 0; /* Object count */ + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ /* get the file object */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid file identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_OBJ_IDS; + vol_cb_args.args.get_obj_ids.types = types; + vol_cb_args.args.get_obj_ids.max_objs = max_objs; + vol_cb_args.args.get_obj_ids.oid_list = oid_list; + vol_cb_args.args.get_obj_ids.count = &count; + /* Get the IDs */ - if (H5VL_file_get(vol_obj, H5VL_FILE_GET_OBJ_IDS, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, types, - max_objs, oid_list, &ret_value) < 0) + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, (-1), "unable to get object ids in file(s)") + + /* Set return value */ + ret_value = (ssize_t)count; } /* end if */ /* If we passed in the 'special' ID, get the count for everything open in the * library, iterating over all open files and getting the object count for each. @@ -396,8 +432,10 @@ done: herr_t H5Fget_vfd_handle(hid_t file_id, hid_t fapl_id, void **file_handle /*out*/) { - H5VL_object_t *vol_obj; /* File info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "iix", file_id, fapl_id, file_handle); @@ -410,9 +448,14 @@ H5Fget_vfd_handle(hid_t file_id, hid_t fapl_id, void **file_handle /*out*/) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* Set up VOL callback arguments */ + file_opt_args.get_vfd_handle.fapl_id = fapl_id; + file_opt_args.get_vfd_handle.file_handle = file_handle; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_VFD_HANDLE; + vol_cb_args.args = &file_opt_args; + /* Retrieve the VFD handle for the file */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_VFD_HANDLE, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, file_handle, fapl_id) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get VFD handle") done: @@ -432,7 +475,9 @@ done: htri_t H5Fis_accessible(const char *filename, hid_t fapl_id) { - htri_t ret_value; /* Return value */ + H5VL_file_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + hbool_t is_accessible = FALSE; /* Whether file is accessible */ + htri_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("t", "*si", filename, fapl_id); @@ -447,11 +492,19 @@ H5Fis_accessible(const char *filename, hid_t fapl_id) else if (TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file access property list") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_IS_ACCESSIBLE; + vol_cb_args.args.is_accessible.filename = filename; + vol_cb_args.args.is_accessible.fapl_id = fapl_id; + vol_cb_args.args.is_accessible.accessible = &is_accessible; + /* Check if file is accessible */ - if (H5VL_file_specific(NULL, H5VL_FILE_IS_ACCESSIBLE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, fapl_id, - filename, &ret_value) < 0) + if (H5VL_file_specific(NULL, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "unable to determine if file is accessible as HDF5") + /* Set return value */ + ret_value = (htri_t)is_accessible; + done: FUNC_LEAVE_API(ret_value) } /* end H5Fis_accessible() */ @@ -477,10 +530,17 @@ H5F__post_open_api_common(H5VL_object_t *vol_obj, void **token_ptr) supported = 0; if (H5VL_introspect_opt_query(vol_obj, H5VL_SUBCLS_FILE, H5VL_NATIVE_FILE_POST_OPEN, &supported) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't check for 'post open' operation") - if (supported & H5VL_OPT_QUERY_SUPPORTED) + if (supported & H5VL_OPT_QUERY_SUPPORTED) { + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_POST_OPEN; + vol_cb_args.args = NULL; + /* Make the 'post open' callback */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_POST_OPEN, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to make file 'post open' callback") + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -870,8 +930,9 @@ H5F__flush_api_common(hid_t object_id, H5F_scope_t scope, void **token_ptr, H5VL H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5I_type_t obj_type; /* Type of object to use */ - herr_t ret_value = SUCCEED; /* Return value */ + H5I_type_t obj_type; /* Type of object to use */ + H5VL_file_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -885,9 +946,13 @@ H5F__flush_api_common(hid_t object_id, H5F_scope_t scope, void **token_ptr, H5VL if (NULL == (*vol_obj_ptr = H5VL_vol_object(object_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_FLUSH; + vol_cb_args.args.flush.obj_type = obj_type; + vol_cb_args.args.flush.scope = scope; + /* Flush the object */ - if (H5VL_file_specific(*vol_obj_ptr, H5VL_FILE_FLUSH, H5P_DATASET_XFER_DEFAULT, token_ptr, (int)obj_type, - (int)scope) < 0) + if (H5VL_file_specific(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file") done: @@ -1072,10 +1137,11 @@ done: herr_t H5Fdelete(const char *filename, hid_t fapl_id) { - H5P_genplist_t * plist; /* Property list pointer */ - H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */ - htri_t is_hdf5 = FAIL; - herr_t ret_value = SUCCEED; + H5P_genplist_t * plist; /* Property list pointer */ + H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */ + H5VL_file_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + hbool_t is_accessible = FALSE; /* Whether file is accessible */ + herr_t ret_value = SUCCEED; FUNC_ENTER_API(FAIL) H5TRACE2("e", "*si", filename, fapl_id); @@ -1100,16 +1166,25 @@ H5Fdelete(const char *filename, hid_t fapl_id) if (H5CX_set_vol_connector_prop(&connector_prop) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set VOL connector info in API context") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_IS_ACCESSIBLE; + vol_cb_args.args.is_accessible.filename = filename; + vol_cb_args.args.is_accessible.fapl_id = fapl_id; + vol_cb_args.args.is_accessible.accessible = &is_accessible; + /* Make sure this is HDF5 storage for this VOL connector */ - if (H5VL_file_specific(NULL, H5VL_FILE_IS_ACCESSIBLE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, fapl_id, - filename, &is_hdf5) < 0) + if (H5VL_file_specific(NULL, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "unable to determine if file is accessible as HDF5") - if (!is_hdf5) + if (!is_accessible) HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "not an HDF5 file") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_DELETE; + vol_cb_args.args.del.filename = filename; + vol_cb_args.args.del.fapl_id = fapl_id; + /* Delete the file */ - if (H5VL_file_specific(NULL, H5VL_FILE_DELETE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, fapl_id, - filename, &ret_value) < 0) + if (H5VL_file_specific(NULL, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTDELETEFILE, FAIL, "unable to delete the file") done: @@ -1129,11 +1204,13 @@ done: herr_t H5Fmount(hid_t loc_id, const char *name, hid_t child_id, hid_t plist_id) { - H5VL_object_t *loc_vol_obj = NULL; /* Parent object */ - H5VL_object_t *child_vol_obj = NULL; /* Child object */ - H5I_type_t loc_type; /* ID type of location */ - H5I_type_t child_type; /* ID type of child */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * loc_vol_obj = NULL; /* Parent object */ + H5VL_object_t * child_vol_obj = NULL; /* Child object */ + H5VL_group_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + void * grp = NULL; /* Root group opened */ + H5I_type_t loc_type; /* ID type of location */ + int same_connector = 0; /* Whether parent and child files use the same connector */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "i*sii", loc_id, name, child_id, plist_id); @@ -1146,8 +1223,7 @@ H5Fmount(hid_t loc_id, const char *name, hid_t child_id, hid_t plist_id) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be NULL") if (!*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be the empty string") - child_type = H5I_get_type(child_id); - if (H5I_FILE != child_type) + if (H5I_FILE != H5I_get_type(child_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "child_id parameter not a file ID") if (H5P_DEFAULT == plist_id) plist_id = H5P_FILE_MOUNT_DEFAULT; @@ -1159,23 +1235,71 @@ H5Fmount(hid_t loc_id, const char *name, hid_t child_id, hid_t plist_id) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info") /* Get the location object */ - if (NULL == (loc_vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not get location object") + /* Need to open the root group of a file, if a file ID was given as the + * 'loc_id', because the 'mount' operation is a group specific operation. + */ + if (H5I_FILE == loc_type) { + H5VL_object_t * vol_obj; /* Object for loc_id (file) */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + + /* Get the location object */ + if (NULL == (vol_obj = (H5VL_object_t *)H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = loc_type; + + /* Open the root group object */ + if (NULL == (grp = H5VL_group_open(vol_obj, &loc_params, "/", H5P_GROUP_ACCESS_DEFAULT, + H5P_DATASET_XFER_DEFAULT, NULL))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "unable to open group") + + /* Create a VOL object for the root group */ + if (NULL == (loc_vol_obj = H5VL_create_object(grp, vol_obj->connector))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "can't create VOL object for root group") + } /* end if */ + else { + HDassert(H5I_GROUP == loc_type); + if (NULL == (loc_vol_obj = (H5VL_object_t *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not get location object") + } /* end else */ /* Get the child object */ if (NULL == (child_vol_obj = (H5VL_object_t *)H5I_object(child_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not get child object") /* Check if both objects are associated with the same VOL connector */ - if (loc_vol_obj->connector->cls->value != child_vol_obj->connector->cls->value) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Can't mount file onto object from different VOL connector") + if (H5VL_cmp_connector_cls(&same_connector, loc_vol_obj->connector->cls, child_vol_obj->connector->cls) < + 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOMPARE, FAIL, "can't compare connector classes") + if (same_connector) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "can't mount file onto object from different VOL connector") + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_GROUP_MOUNT; + vol_cb_args.args.mount.name = name; + vol_cb_args.args.mount.child_file = + child_vol_obj->data; /* Don't unwrap fully, so each connector can see its object */ + vol_cb_args.args.mount.fmpl_id = plist_id; /* Perform the mount operation */ - if (H5VL_file_specific(loc_vol_obj, H5VL_FILE_MOUNT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - (int)loc_type, name, child_vol_obj->data, plist_id) < 0) + /* (This is on a group, so that the VOL framework always sees groups for + * the 'mount' operation, instead of mixing files and groups) + */ + if (H5VL_group_specific(loc_vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to mount file") done: + /* Clean up if we temporarily opened the root group for a file */ + if (grp) { + HDassert(loc_vol_obj); + if (H5VL_group_close(loc_vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_FILE, H5E_CLOSEERROR, FAIL, "unable to release group") + if (H5VL_free_object(loc_vol_obj) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "unable to free VOL object") + } /* end if */ + FUNC_LEAVE_API(ret_value) } /* end H5Fmount() */ @@ -1198,9 +1322,11 @@ done: herr_t H5Funmount(hid_t loc_id, const char *name) { - H5VL_object_t *vol_obj = NULL; /* Parent object */ - H5I_type_t loc_type; /* ID type of location */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * loc_vol_obj = NULL; /* Parent object */ + H5VL_group_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + void * grp = NULL; /* Root group opened */ + H5I_type_t loc_type; /* ID type of location */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*s", loc_id, name); @@ -1219,15 +1345,57 @@ H5Funmount(hid_t loc_id, const char *name) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info") /* Get the location object */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not get location object") + /* Need to open the root group of a file, if a file ID was given as the + * 'loc_id', because the 'mount' operation is a group specific operation. + */ + if (H5I_FILE == loc_type) { + H5VL_object_t * vol_obj; /* Object for loc_id (file) */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + + /* Get the location object */ + if (NULL == (vol_obj = (H5VL_object_t *)H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = loc_type; + + /* Open the root group object */ + if (NULL == (grp = H5VL_group_open(vol_obj, &loc_params, "/", H5P_GROUP_ACCESS_DEFAULT, + H5P_DATASET_XFER_DEFAULT, NULL))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "unable to open group") + + /* Create a VOL object for the root group */ + if (NULL == (loc_vol_obj = H5VL_create_object(grp, vol_obj->connector))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "can't create VOL object for root group") + } /* end if */ + else { + HDassert(H5I_GROUP == loc_type); + if (NULL == (loc_vol_obj = (H5VL_object_t *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not get location object") + } /* end else */ + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_GROUP_UNMOUNT; + vol_cb_args.args.unmount.name = name; /* Perform the unmount operation */ - if (H5VL_file_specific(vol_obj, H5VL_FILE_UNMOUNT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - (int)loc_type, name) < 0) + /* (This is on a group, so that the VOL framework always sees groups for + * the 'unmount' operation, instead of mixing files and groups) + */ + if (H5VL_group_specific(loc_vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to unmount file") done: + /* Clean up if we temporarily opened the root group for a file */ + if (grp) { + HDassert(loc_vol_obj); + if (H5VL_group_close(loc_vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_FILE, H5E_CLOSEERROR, FAIL, "unable to release group") + if (H5VL_free_object(loc_vol_obj) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "unable to free VOL object") + } /* end if */ + FUNC_LEAVE_API(ret_value) } /* end H5Funmount() */ @@ -1245,9 +1413,10 @@ done: static hid_t H5F__reopen_api_common(hid_t file_id, void **token_ptr) { - void * file = NULL; /* File struct for new file */ - H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object for loc_id */ + H5VL_file_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + void * reopen_file = NULL; /* Pointer to the re-opened file object */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_STATIC @@ -1255,16 +1424,20 @@ H5F__reopen_api_common(hid_t file_id, void **token_ptr) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid file identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_REOPEN; + vol_cb_args.args.reopen.file = &reopen_file; + /* Reopen the file */ - if (H5VL_file_specific(vol_obj, H5VL_FILE_REOPEN, H5P_DATASET_XFER_DEFAULT, token_ptr, &file) < 0) + if (H5VL_file_specific(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "unable to reopen file via the VOL connector") /* Make sure that worked */ - if (NULL == file) + if (NULL == reopen_file) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "unable to reopen file") /* Get an ID for the file */ - if ((ret_value = H5VL_register(H5I_FILE, file, vol_obj->connector, TRUE)) < 0) + if ((ret_value = H5VL_register(H5I_FILE, reopen_file, vol_obj->connector, TRUE)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register file handle") done: @@ -1398,15 +1571,19 @@ H5Fget_intent(hid_t file_id, unsigned *intent_flags /*out*/) /* If no intent flags were passed in, exit quietly */ if (intent_flags) { - H5VL_object_t *vol_obj; /* File info */ + H5VL_object_t * vol_obj; /* File for file_id */ + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ /* Get the internal file structure */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_INTENT; + vol_cb_args.args.get_intent.flags = intent_flags; + /* Get the flags */ - if ((ret_value = H5VL_file_get(vol_obj, H5VL_FILE_GET_INTENT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, intent_flags)) < 0) + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file's intent flags") } /* end if */ @@ -1434,15 +1611,19 @@ H5Fget_fileno(hid_t file_id, unsigned long *fnumber /*out*/) /* If no fnumber pointer was passed in, exit quietly */ if (fnumber) { - H5VL_object_t *vol_obj; /* File info */ + H5VL_object_t * vol_obj; /* File for file_id */ + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ /* Get the internal file structure */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - /* Get the flags */ - if ((ret_value = H5VL_file_get(vol_obj, H5VL_FILE_GET_FILENO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, fnumber)) < 0) + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_FILENO; + vol_cb_args.args.get_fileno.fileno = fnumber; + + /* Get the 'file number' */ + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file's 'file number'") } /* end if */ @@ -1462,8 +1643,11 @@ done: hssize_t H5Fget_freespace(hid_t file_id) { - H5VL_object_t *vol_obj = NULL; - hssize_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + hsize_t file_freespace = 0; /* Size of freespace in the file */ + hssize_t ret_value; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE1("Hs", "i", file_id); @@ -1472,11 +1656,18 @@ H5Fget_freespace(hid_t file_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid file identifier") + /* Set up VOL callback arguments */ + file_opt_args.get_freespace.size = &file_freespace; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_FREE_SPACE; + vol_cb_args.args = &file_opt_args; + /* Get the amount of free space in the file */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_FREE_SPACE, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &ret_value) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, (-1), "unable to get file free space") + /* Set return value */ + ret_value = (hssize_t)file_freespace; + done: FUNC_LEAVE_API(ret_value) } /* end H5Fget_freespace() */ @@ -1495,8 +1686,10 @@ done: herr_t H5Fget_filesize(hid_t file_id, hsize_t *size /*out*/) { - H5VL_object_t *vol_obj; /* File info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", file_id, size); @@ -1507,9 +1700,13 @@ H5Fget_filesize(hid_t file_id, hsize_t *size /*out*/) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + /* Set up VOL callback arguments */ + file_opt_args.get_size.size = size; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_SIZE; + vol_cb_args.args = &file_opt_args; + /* Get the file size */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_SIZE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - size) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file size") done: @@ -1556,8 +1753,11 @@ done: ssize_t H5Fget_file_image(hid_t file_id, void *buf /*out*/, size_t buf_len) { - H5VL_object_t *vol_obj; /* File object for file ID */ - ssize_t ret_value; /* Return value */ + H5VL_object_t * vol_obj; /* File object for file ID */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + size_t image_len = 0; /* Size of image buffer */ + ssize_t ret_value; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE3("Zs", "ixz", file_id, buf, buf_len); @@ -1566,11 +1766,20 @@ H5Fget_file_image(hid_t file_id, void *buf /*out*/, size_t buf_len) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "not a file ID") + /* Set up VOL callback arguments */ + file_opt_args.get_file_image.buf_size = buf_len; + file_opt_args.get_file_image.buf = buf; + file_opt_args.get_file_image.image_len = &image_len; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_FILE_IMAGE; + vol_cb_args.args = &file_opt_args; + /* Get the file image */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_FILE_IMAGE, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, buf, &ret_value, buf_len) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, (-1), "unable to get file image") + /* Set return value */ + ret_value = (ssize_t)image_len; + done: FUNC_LEAVE_API(ret_value) } /* H5Fget_file_image() */ @@ -1592,8 +1801,10 @@ done: herr_t H5Fget_mdc_config(hid_t file_id, H5AC_cache_config_t *config /*out*/) { - H5VL_object_t *vol_obj = NULL; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", file_id, config); @@ -1606,9 +1817,13 @@ H5Fget_mdc_config(hid_t file_id, H5AC_cache_config_t *config /*out*/) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* Set up VOL callback arguments */ + file_opt_args.get_mdc_config.config = config; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_MDC_CONF; + vol_cb_args.args = &file_opt_args; + /* Get the metadata cache configuration */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_MDC_CONF, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - config) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get metadata cache configuration") done: @@ -1627,10 +1842,12 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Fset_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr) +H5Fset_mdc_config(hid_t file_id, const H5AC_cache_config_t *config_ptr) { - H5VL_object_t *vol_obj = NULL; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*Cc", file_id, config_ptr); @@ -1639,9 +1856,13 @@ H5Fset_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* Set up VOL callback arguments */ + file_opt_args.set_mdc_config.config = config_ptr; + vol_cb_args.op_type = H5VL_NATIVE_FILE_SET_MDC_CONFIG; + vol_cb_args.args = &file_opt_args; + /* Set the metadata cache configuration */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_SET_MDC_CONFIG, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, config_ptr) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to set metadata cache configuration") done: @@ -1663,8 +1884,10 @@ done: herr_t H5Fget_mdc_hit_rate(hid_t file_id, double *hit_rate /*out*/) { - H5VL_object_t *vol_obj; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", file_id, hit_rate); @@ -1675,9 +1898,13 @@ H5Fget_mdc_hit_rate(hid_t file_id, double *hit_rate /*out*/) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + /* Set up VOL callback arguments */ + file_opt_args.get_mdc_hit_rate.hit_rate = hit_rate; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_MDC_HR; + vol_cb_args.args = &file_opt_args; + /* Get the current hit rate */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_MDC_HR, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - hit_rate) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get MDC hit rate") done: @@ -1701,8 +1928,11 @@ herr_t H5Fget_mdc_size(hid_t file_id, size_t *max_size /*out*/, size_t *min_clean_size /*out*/, size_t *cur_size /*out*/, int *cur_num_entries /*out*/) { - H5VL_object_t *vol_obj; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + uint32_t index_len = 0; /* Size of cache index */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "ixxxx", file_id, max_size, min_clean_size, cur_size, cur_num_entries); @@ -1711,11 +1941,22 @@ H5Fget_mdc_size(hid_t file_id, size_t *max_size /*out*/, size_t *min_clean_size if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + /* Set up VOL callback arguments */ + file_opt_args.get_mdc_size.max_size = max_size; + file_opt_args.get_mdc_size.min_clean_size = min_clean_size; + file_opt_args.get_mdc_size.cur_size = cur_size; + file_opt_args.get_mdc_size.cur_num_entries = &index_len; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_MDC_SIZE; + vol_cb_args.args = &file_opt_args; + /* Get the size data */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_MDC_SIZE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - max_size, min_clean_size, cur_size, cur_num_entries) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get MDC size") + /* Set mis-matched return value */ + if (cur_num_entries) + *cur_num_entries = (int)index_len; + done: FUNC_LEAVE_API(ret_value) } /* H5Fget_mdc_size() */ @@ -1739,8 +1980,9 @@ done: herr_t H5Freset_mdc_hit_rate_stats(hid_t file_id) { - H5VL_object_t *vol_obj = NULL; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); @@ -1749,9 +1991,12 @@ H5Freset_mdc_hit_rate_stats(hid_t file_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_RESET_MDC_HIT_RATE; + vol_cb_args.args = NULL; + /* Reset the hit rate statistic */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_RESET_MDC_HIT_RATE, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't reset cache hit rate") done: @@ -1780,9 +2025,11 @@ done: ssize_t H5Fget_name(hid_t obj_id, char *name /*out*/, size_t size) { - H5VL_object_t *vol_obj = NULL; - H5I_type_t type; - ssize_t ret_value = -1; /* Return value */ + H5VL_object_t * vol_obj; /* File for file_id */ + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5I_type_t type; + size_t file_name_len = 0; /* Length of file name */ + ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE3("Zs", "ixz", obj_id, name, size); @@ -1797,11 +2044,20 @@ H5Fget_name(hid_t obj_id, char *name /*out*/, size_t size) if (NULL == (vol_obj = H5VL_vol_object(obj_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid file identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_NAME; + vol_cb_args.args.get_name.type = type; + vol_cb_args.args.get_name.buf_size = size; + vol_cb_args.args.get_name.buf = name; + vol_cb_args.args.get_name.file_name_len = &file_name_len; + /* Get the filename via the VOL */ - if (H5VL_file_get(vol_obj, H5VL_FILE_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, (int)type, size, - name, &ret_value) < 0) + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, (-1), "unable to get file name") + /* Set the return value */ + ret_value = (ssize_t)file_name_len; + done: FUNC_LEAVE_API(ret_value) } /* end H5Fget_name() */ @@ -1822,9 +2078,11 @@ done: herr_t H5Fget_info2(hid_t obj_id, H5F_info2_t *finfo /*out*/) { - H5VL_object_t *vol_obj = NULL; - H5I_type_t type; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + H5I_type_t type; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", obj_id, finfo); @@ -1843,9 +2101,14 @@ H5Fget_info2(hid_t obj_id, H5F_info2_t *finfo /*out*/) if (NULL == (vol_obj = H5VL_vol_object(obj_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Set up VOL callback arguments */ + file_opt_args.get_info.type = type; + file_opt_args.get_info.finfo = finfo; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_INFO; + vol_cb_args.args = &file_opt_args; + /* Get the file information */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - (int)type, finfo) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to retrieve file info") done: @@ -1865,8 +2128,10 @@ done: herr_t H5Fget_metadata_read_retry_info(hid_t file_id, H5F_retry_info_t *info /*out*/) { - H5VL_object_t *vol_obj = NULL; /* File object for file ID */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* File object for file ID */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", file_id, info); @@ -1879,10 +2144,14 @@ H5Fget_metadata_read_retry_info(hid_t file_id, H5F_retry_info_t *info /*out*/) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + /* Set up VOL callback arguments */ + file_opt_args.get_metadata_read_retry_info.info = info; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_METADATA_READ_RETRY_INFO; + vol_cb_args.args = &file_opt_args; + /* Get the retry info */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_METADATA_READ_RETRY_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, info) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't get metadata read retry info") + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get metadata read retry info") done: FUNC_LEAVE_API(ret_value) @@ -1903,8 +2172,11 @@ done: ssize_t H5Fget_free_sections(hid_t file_id, H5F_mem_t type, size_t nsects, H5F_sect_info_t *sect_info /*out*/) { - H5VL_object_t *vol_obj = NULL; - ssize_t ret_value = -1; /* Return value */ + H5VL_object_t * vol_obj = NULL; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + size_t sect_count = 0; /* Number of sections */ + ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE4("Zs", "iFmzx", file_id, type, nsects, sect_info); @@ -1915,11 +2187,21 @@ H5Fget_free_sections(hid_t file_id, H5F_mem_t type, size_t nsects, H5F_sect_info if (sect_info && nsects == 0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "nsects must be > 0") + /* Set up VOL callback arguments */ + file_opt_args.get_free_sections.type = type; + file_opt_args.get_free_sections.sect_info = sect_info; + file_opt_args.get_free_sections.nsects = nsects; + file_opt_args.get_free_sections.sect_count = §_count; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_FREE_SECTIONS; + vol_cb_args.args = &file_opt_args; + /* Get the free-space section information in the file */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_FREE_SECTIONS, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, sect_info, &ret_value, (int)type, nsects) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, (-1), "unable to get file free sections") + /* Set return value */ + ret_value = (ssize_t)sect_count; + done: FUNC_LEAVE_API(ret_value) } /* end H5Fget_free_sections() */ @@ -1938,8 +2220,9 @@ done: herr_t H5Fclear_elink_file_cache(hid_t file_id) { - H5VL_object_t *vol_obj; /* File */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); @@ -1948,9 +2231,12 @@ H5Fclear_elink_file_cache(hid_t file_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_CLEAR_ELINK_CACHE; + vol_cb_args.args = NULL; + /* Release the EFC */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_CLEAR_ELINK_CACHE, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release external file cache") done: @@ -1994,8 +2280,9 @@ done: herr_t H5Fstart_swmr_write(hid_t file_id) { - H5VL_object_t *vol_obj = NULL; /* File info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); @@ -2008,9 +2295,12 @@ H5Fstart_swmr_write(hid_t file_id) if (H5CX_set_loc(file_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_START_SWMR_WRITE; + vol_cb_args.args = NULL; + /* Start SWMR writing */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_START_SWMR_WRITE, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "unable to start SWMR writing") done: @@ -2030,8 +2320,9 @@ done: herr_t H5Fstart_mdc_logging(hid_t file_id) { - H5VL_object_t *vol_obj; /* File info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); @@ -2040,9 +2331,12 @@ H5Fstart_mdc_logging(hid_t file_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_START_MDC_LOGGING; + vol_cb_args.args = NULL; + /* Call mdc logging function */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_START_MDC_LOGGING, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_LOGGING, FAIL, "unable to start mdc logging") done: @@ -2063,8 +2357,9 @@ done: herr_t H5Fstop_mdc_logging(hid_t file_id) { - H5VL_object_t *vol_obj; /* File info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); @@ -2073,9 +2368,12 @@ H5Fstop_mdc_logging(hid_t file_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_STOP_MDC_LOGGING; + vol_cb_args.args = NULL; + /* Call mdc logging function */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_STOP_MDC_LOGGING, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_LOGGING, FAIL, "unable to stop mdc logging") done: @@ -2096,8 +2394,10 @@ done: herr_t H5Fget_mdc_logging_status(hid_t file_id, hbool_t *is_enabled /*out*/, hbool_t *is_currently_logging /*out*/) { - H5VL_object_t *vol_obj; /* File info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "ixx", file_id, is_enabled, is_currently_logging); @@ -2106,9 +2406,14 @@ H5Fget_mdc_logging_status(hid_t file_id, hbool_t *is_enabled /*out*/, hbool_t *i if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID") + /* Set up VOL callback arguments */ + file_opt_args.get_mdc_logging_status.is_enabled = is_enabled; + file_opt_args.get_mdc_logging_status.is_currently_logging = is_currently_logging; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_MDC_LOGGING_STATUS; + vol_cb_args.args = &file_opt_args; + /* Call mdc logging function */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_MDC_LOGGING_STATUS, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, is_enabled, is_currently_logging) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_LOGGING, FAIL, "unable to get logging status") done: @@ -2130,8 +2435,10 @@ done: herr_t H5Fset_libver_bounds(hid_t file_id, H5F_libver_t low, H5F_libver_t high) { - H5VL_object_t *vol_obj; /* File as VOL object */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File as VOL object */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "iFvFv", file_id, low, high); @@ -2144,9 +2451,14 @@ H5Fset_libver_bounds(hid_t file_id, H5F_libver_t low, H5F_libver_t high) if (H5CX_set_loc(file_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info") + /* Set up VOL callback arguments */ + file_opt_args.set_libver_bounds.low = low; + file_opt_args.set_libver_bounds.high = high; + vol_cb_args.op_type = H5VL_NATIVE_FILE_SET_LIBVER_BOUNDS; + vol_cb_args.args = &file_opt_args; + /* Set the library's version bounds */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_SET_LIBVER_BOUNDS, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, low, high) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set library version bounds") done: @@ -2167,8 +2479,9 @@ done: herr_t H5Fformat_convert(hid_t file_id) { - H5VL_object_t *vol_obj = NULL; /* File */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* File */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); @@ -2181,9 +2494,12 @@ H5Fformat_convert(hid_t file_id) if (H5CX_set_loc(file_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_FORMAT_CONVERT; + vol_cb_args.args = NULL; + /* Convert the format */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_FORMAT_CONVERT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCONVERT, FAIL, "can't convert file format") done: @@ -2202,8 +2518,9 @@ done: herr_t H5Freset_page_buffering_stats(hid_t file_id) { - H5VL_object_t *vol_obj; /* File to reset stats on */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File to reset stats on */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); @@ -2212,9 +2529,12 @@ H5Freset_page_buffering_stats(hid_t file_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_RESET_PAGE_BUFFERING_STATS; + vol_cb_args.args = NULL; + /* Reset the statistics */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_RESET_PAGE_BUFFERING_STATS, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't reset stats for page buffering") done: @@ -2235,8 +2555,10 @@ H5Fget_page_buffering_stats(hid_t file_id, unsigned accesses[2] /*out*/, unsigne unsigned misses[2] /*out*/, unsigned evictions[2] /*out*/, unsigned bypasses[2] /*out*/) { - H5VL_object_t *vol_obj; /* File object */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File object */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "ixxxxx", file_id, accesses, hits, misses, evictions, bypasses); @@ -2247,9 +2569,17 @@ H5Fget_page_buffering_stats(hid_t file_id, unsigned accesses[2] /*out*/, unsigne if (NULL == accesses || NULL == hits || NULL == misses || NULL == evictions || NULL == bypasses) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL input parameters for stats") + /* Set up VOL callback arguments */ + file_opt_args.get_page_buffering_stats.accesses = accesses; + file_opt_args.get_page_buffering_stats.hits = hits; + file_opt_args.get_page_buffering_stats.misses = misses; + file_opt_args.get_page_buffering_stats.evictions = evictions; + file_opt_args.get_page_buffering_stats.bypasses = bypasses; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_PAGE_BUFFERING_STATS; + vol_cb_args.args = &file_opt_args; + /* Get the statistics */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_PAGE_BUFFERING_STATS, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, accesses, hits, misses, evictions, bypasses) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve stats for page buffering") done: @@ -2272,8 +2602,10 @@ done: herr_t H5Fget_mdc_image_info(hid_t file_id, haddr_t *image_addr /*out*/, hsize_t *image_len /*out*/) { - H5VL_object_t *vol_obj; /* File info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "ixx", file_id, image_addr, image_len); @@ -2282,9 +2614,14 @@ H5Fget_mdc_image_info(hid_t file_id, haddr_t *image_addr /*out*/, hsize_t *image if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID") + /* Set up VOL callback arguments */ + file_opt_args.get_mdc_image_info.addr = image_addr; + file_opt_args.get_mdc_image_info.len = image_len; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_MDC_IMAGE_INFO; + vol_cb_args.args = &file_opt_args; + /* Go get the address and size of the cache image */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_MDC_IMAGE_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, image_addr, image_len) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve cache image info") done: @@ -2317,9 +2654,16 @@ H5Fget_eoa(hid_t file_id, haddr_t *eoa /*out*/) /* Only do work if valid pointer to fill in */ if (eoa) { + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + + /* Set up VOL callback arguments */ + file_opt_args.get_eoa.eoa = eoa; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_EOA; + vol_cb_args.args = &file_opt_args; + /* Retrieve the EOA for the file */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_EOA, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - eoa) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get EOA") } /* end if */ @@ -2339,8 +2683,10 @@ done: herr_t H5Fincrement_filesize(hid_t file_id, hsize_t increment) { - H5VL_object_t *vol_obj; /* File info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ih", file_id, increment); @@ -2349,9 +2695,13 @@ H5Fincrement_filesize(hid_t file_id, hsize_t increment) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID") + /* Set up VOL callback arguments */ + file_opt_args.increment_filesize.increment = increment; + vol_cb_args.op_type = H5VL_NATIVE_FILE_INCR_FILESIZE; + vol_cb_args.args = &file_opt_args; + /* Increment the file size */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_INCR_FILESIZE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - increment) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to increment file size") done: @@ -2371,21 +2721,27 @@ done: herr_t H5Fget_dset_no_attrs_hint(hid_t file_id, hbool_t *minimize /*out*/) { - H5VL_object_t *vol_obj = NULL; - herr_t ret_value = SUCCEED; + H5VL_object_t * vol_obj; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", file_id, minimize); + /* Check args */ if (NULL == minimize) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "out pointer 'minimize' cannot be NULL") - - vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE); - if (NULL == vol_obj) + if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_MIN_DSET_OHDR_FLAG, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, minimize) < 0) + /* Set up VOL callback arguments */ + file_opt_args.get_min_dset_ohdr_flag.minimize = minimize; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_MIN_DSET_OHDR_FLAG; + vol_cb_args.args = &file_opt_args; + + /* Get the dataset object header minimum size flag */ + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to set file's dataset header minimization flag") done: @@ -2405,18 +2761,25 @@ done: herr_t H5Fset_dset_no_attrs_hint(hid_t file_id, hbool_t minimize) { - H5VL_object_t *vol_obj = NULL; - herr_t ret_value = SUCCEED; + H5VL_object_t * vol_obj; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ib", file_id, minimize); - vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE); - if (NULL == vol_obj) + /* Check args */ + if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_SET_MIN_DSET_OHDR_FLAG, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, minimize) < 0) + /* Set up VOL callback arguments */ + file_opt_args.set_min_dset_ohdr_flag.minimize = minimize; + vol_cb_args.op_type = H5VL_NATIVE_FILE_SET_MIN_DSET_OHDR_FLAG; + vol_cb_args.args = &file_opt_args; + + /* Set the 'minimize dataset object headers flag' */ + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to set file's dataset header minimization flag") done: @@ -2424,43 +2787,6 @@ done: } /* H5Fset_dset_no_attrs_hint */ /*------------------------------------------------------------------------- - * Function: H5Fwait - * - * Purpose: Wait for all operations on a dataset. - * Tang: added for async - * - * Return: SUCCEED/FAIL - * - *------------------------------------------------------------------------- - */ -herr_t -H5Fwait(hid_t file_id) -{ - H5VL_object_t *vol_obj; /* File for this operation */ - H5I_type_t obj_type; /* Type of object */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(FAIL) - H5TRACE1("e", "i", file_id); - - /* Get the type of object we're flushing + sanity check */ - obj_type = H5I_get_type(file_id); - if (H5I_FILE != obj_type && H5I_GROUP != obj_type && H5I_DATATYPE != obj_type && - H5I_DATASET != obj_type && H5I_ATTR != obj_type) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "file_id parameter is not a valid file identifier") - - if ((ret_value = H5VL_file_specific(vol_obj, H5VL_FILE_WAIT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - file_id)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPERATE, FAIL, "unable to wait file") - -done: - FUNC_LEAVE_API(ret_value) -} /* H5Fwait() */ - -/*------------------------------------------------------------------------- * Function: H5Fvfd_swmr_end_tick() * * Purpose: To trigger end of tick processing @@ -2471,8 +2797,9 @@ done: herr_t H5Fvfd_swmr_end_tick(hid_t file_id) { - H5VL_object_t *vol_obj = NULL; /* File info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* File */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ /* Note: use the version of FUNC_ENTER_API without EOT processing */ FUNC_ENTER_API_NO_EOT(FAIL) @@ -2487,8 +2814,11 @@ H5Fvfd_swmr_end_tick(hid_t file_id) if (H5CX_set_loc(file_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info") - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_VFD_SWMR_END_TICK, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_VFD_SWMR_END_TICK; + vol_cb_args.args = NULL; + + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "unable to trigger end of tick processing for VFD SWMR") done: @@ -2507,9 +2837,9 @@ done: herr_t H5Fvfd_swmr_disable_end_of_tick(hid_t file_id) { - - H5VL_object_t *vol_obj = NULL; /* File info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* File */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); @@ -2523,8 +2853,11 @@ H5Fvfd_swmr_disable_end_of_tick(hid_t file_id) if (H5CX_set_loc(file_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info") - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_VFD_SWMR_DISABLE_EOT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_VFD_SWMR_DISABLE_EOT; + vol_cb_args.args = NULL; + + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "unable to disable EOT for VFD SWMR") done: @@ -2542,9 +2875,9 @@ done: herr_t H5Fvfd_swmr_enable_end_of_tick(hid_t file_id) { - - H5VL_object_t *vol_obj = NULL; /* File info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* File */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); @@ -2558,8 +2891,11 @@ H5Fvfd_swmr_enable_end_of_tick(hid_t file_id) if (H5CX_set_loc(file_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info") - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_VFD_SWMR_ENABLE_EOT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_VFD_SWMR_ENABLE_EOT; + vol_cb_args.args = NULL; + + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "unable to enable EOT for VFD SWMR") done: diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c index b265e1d..8cf9f9e 100644 --- a/src/H5FDfamily.c +++ b/src/H5FDfamily.c @@ -582,7 +582,7 @@ done: * memb_name & temp in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("format-nonliteral") +H5_GCC_CLANG_DIAG_OFF("format-nonliteral") static H5FD_t * H5FD__family_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) { @@ -735,7 +735,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__family_open() */ -H5_GCC_DIAG_ON("format-nonliteral") +H5_GCC_CLANG_DIAG_ON("format-nonliteral") /*------------------------------------------------------------------------- * Function: H5FD__family_close @@ -905,7 +905,7 @@ H5FD__family_get_eoa(const H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type) * memb_name in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("format-nonliteral") +H5_GCC_CLANG_DIAG_OFF("format-nonliteral") static herr_t H5FD__family_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t abs_eoa) { @@ -974,7 +974,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } -H5_GCC_DIAG_ON("format-nonliteral") +H5_GCC_CLANG_DIAG_ON("format-nonliteral") /*------------------------------------------------------------------------- * Function: H5FD__family_get_eof diff --git a/src/H5FDhdfs.c b/src/H5FDhdfs.c index 102a3ab..2c4bff6 100644 --- a/src/H5FDhdfs.c +++ b/src/H5FDhdfs.c @@ -1,15 +1,13 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Read-Only HDFS Virtual File Driver (VFD) * - * Copyright (c) 2018, The HDF Group. * - * * + * Copyright by The HDF Group. * * All rights reserved. * * * - * NOTICE: * - * All information contained herein is, and remains, the property of The HDF * - * Group. The intellectual and technical concepts contained herein are * - * proprietary to The HDF Group. Dissemination of this information or * - * reproduction of this material is strictly forbidden unless prior written * - * permission is obtained from The HDF Group. * + * 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. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* @@ -20,8 +18,10 @@ * File System (HDFS). */ +#ifdef H5_HAVE_LIBHDFS /* This source code file is part of the H5FD driver module */ #include "H5FDdrvr_module.h" +#endif #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ diff --git a/src/H5FDhdfs.h b/src/H5FDhdfs.h index 8d65ac7..7c871a4 100644 --- a/src/H5FDhdfs.h +++ b/src/H5FDhdfs.h @@ -1,15 +1,14 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Read-Only HDFS Virtual File Driver (VFD) * - * Copyright (c) 2018, The HDF Group. * + * Copyright by The HDF Group. * * * * All rights reserved. * * * - * NOTICE: * - * All information contained herein is, and remains, the property of The HDF * - * Group. The intellectual and technical concepts contained herein are * - * proprietary to The HDF Group. Dissemination of this information or * - * reproduction of this material is strictly forbidden unless prior written * - * permission is obtained from The HDF Group. * + * 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. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* diff --git a/src/H5FDlog.c b/src/H5FDlog.c index 707c97b..f996b9e 100644 --- a/src/H5FDlog.c +++ b/src/H5FDlog.c @@ -1218,7 +1218,6 @@ H5FD__log_read(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, had #ifndef H5_HAVE_PREADWRITE /* Seek to the correct location (if we don't have pread) */ if (addr != file->pos || OP_READ != file->op) { - H5_timer_t seek_timer; /* Timer for seek operation */ H5_timevals_t seek_times; /* Elapsed time for seek operation */ @@ -1441,7 +1440,6 @@ H5FD__log_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, ha #ifndef H5_HAVE_PREADWRITE /* Seek to the correct location (if we don't have pwrite) */ if (addr != file->pos || OP_WRITE != file->op) { - H5_timer_t seek_timer; /* Timer for seek operation */ H5_timevals_t seek_times; /* Elapsed time for seek operation */ diff --git a/src/H5FDmirror.c b/src/H5FDmirror.c index cf14c90..8cbeff6 100644 --- a/src/H5FDmirror.c +++ b/src/H5FDmirror.c @@ -15,12 +15,12 @@ * a remote host. */ -#include "H5FDdrvr_module.h" /* This source code file is part of the H5FD driver module */ - #include "H5private.h" /* Generic Functions */ #ifdef H5_HAVE_MIRROR_VFD +#include "H5FDdrvr_module.h" /* This source code file is part of the H5FD driver module */ + #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* File access */ #include "H5FDprivate.h" /* File drivers */ diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c index 86f7664..cae4174 100644 --- a/src/H5FDmulti.c +++ b/src/H5FDmulti.c @@ -44,7 +44,7 @@ #define my_strdup strdup #endif -/* Macros for enabling/disabling particular GCC warnings +/* Macros for enabling/disabling particular GCC / clang warnings * * These are (renamed) duplicates of macros in H5private.h. If you make changes * here, be sure to update those as well. @@ -646,7 +646,7 @@ H5FD_multi_sb_encode(H5FD_t *_file, char *name /*out*/, unsigned char *buf /*out H5Eclear2(H5E_DEFAULT); /* Name and version number */ - strncpy(name, "NCSAmulti", (size_t)8); + strncpy(name, "NCSAmult", (size_t)9); name[8] = '\0'; assert(7 == H5FD_MEM_NTYPES); @@ -682,7 +682,7 @@ H5FD_multi_sb_encode(H5FD_t *_file, char *name /*out*/, unsigned char *buf /*out p = buf + 8 + nseen * 2 * 8; UNIQUE_MEMBERS (file->fa.memb_map, mt) { size_t n = strlen(file->fa.memb_name[mt]) + 1; - strncpy((char *)p, file->fa.memb_name[mt], n); + strcpy((char *)p, file->fa.memb_name[mt]); p += n; for (i = n; i % 8; i++) *p++ = '\0'; @@ -2019,6 +2019,7 @@ open_members(H5FD_multi_t *file) return 0; } +H5_MULTI_GCC_DIAG_ON("format-nonliteral") /*------------------------------------------------------------------------- * Function: H5FD_multi_delete @@ -2029,6 +2030,7 @@ open_members(H5FD_multi_t *file) * *------------------------------------------------------------------------- */ +H5_MULTI_GCC_DIAG_OFF("format-nonliteral") static herr_t H5FD_multi_delete(const char *filename, hid_t fapl_id) { diff --git a/src/H5FDros3.c b/src/H5FDros3.c index 6e116ee..c0361f9 100644 --- a/src/H5FDros3.c +++ b/src/H5FDros3.c @@ -22,8 +22,10 @@ * Relies on "s3comms" utility layer to implement the AWS REST API. */ +#ifdef H5_HAVE_ROS3_VFD /* This source code file is part of the H5FD driver module */ #include "H5FDdrvr_module.h" +#endif #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ diff --git a/src/H5FDsplitter.c b/src/H5FDsplitter.c index c27cd1b..73c898a 100644 --- a/src/H5FDsplitter.c +++ b/src/H5FDsplitter.c @@ -340,10 +340,12 @@ H5Pset_fapl_splitter(hid_t fapl_id, H5FD_splitter_vfd_config_t *vfd_config) HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "unable to allocate file access property list struct") info->ignore_wo_errs = vfd_config->ignore_wo_errs; - HDstrncpy(info->wo_path, vfd_config->wo_path, H5FD_SPLITTER_PATH_MAX); - HDstrncpy(info->log_file_path, vfd_config->log_file_path, H5FD_SPLITTER_PATH_MAX); - info->rw_fapl_id = H5P_FILE_ACCESS_DEFAULT; /* pre-set value */ - info->wo_fapl_id = H5P_FILE_ACCESS_DEFAULT; /* pre-set value */ + HDstrncpy(info->wo_path, vfd_config->wo_path, H5FD_SPLITTER_PATH_MAX + 1); + info->wo_path[H5FD_SPLITTER_PATH_MAX] = '\0'; + HDstrncpy(info->log_file_path, vfd_config->log_file_path, H5FD_SPLITTER_PATH_MAX + 1); + info->log_file_path[H5FD_SPLITTER_PATH_MAX] = '\0'; + info->rw_fapl_id = H5P_FILE_ACCESS_DEFAULT; /* pre-set value */ + info->wo_fapl_id = H5P_FILE_ACCESS_DEFAULT; /* pre-set value */ /* Set non-default channel FAPL IDs in splitter configuration info */ if (H5P_DEFAULT != vfd_config->rw_fapl_id) { @@ -412,8 +414,8 @@ H5Pget_fapl_splitter(hid_t fapl_id, H5FD_splitter_vfd_config_t *config /*out*/) if (NULL == (fapl_ptr = (const H5FD_splitter_fapl_t *)H5P_peek_driver_info(plist_ptr))) HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "unable to get specific-driver info") - HDstrncpy(config->wo_path, fapl_ptr->wo_path, H5FD_SPLITTER_PATH_MAX); - HDstrncpy(config->log_file_path, fapl_ptr->log_file_path, H5FD_SPLITTER_PATH_MAX); + HDstrncpy(config->wo_path, fapl_ptr->wo_path, H5FD_SPLITTER_PATH_MAX + 1); + HDstrncpy(config->log_file_path, fapl_ptr->log_file_path, H5FD_SPLITTER_PATH_MAX + 1); config->ignore_wo_errs = fapl_ptr->ignore_wo_errs; /* Copy R/W and W/O FAPLs */ @@ -587,8 +589,8 @@ H5FD__splitter_fapl_copy(const void *_old_fa) HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "unable to allocate log file FAPL") H5MM_memcpy(new_fa_ptr, old_fa_ptr, sizeof(H5FD_splitter_fapl_t)); - HDstrncpy(new_fa_ptr->wo_path, old_fa_ptr->wo_path, H5FD_SPLITTER_PATH_MAX); - HDstrncpy(new_fa_ptr->log_file_path, old_fa_ptr->log_file_path, H5FD_SPLITTER_PATH_MAX); + HDstrncpy(new_fa_ptr->wo_path, old_fa_ptr->wo_path, H5FD_SPLITTER_PATH_MAX + 1); + HDstrncpy(new_fa_ptr->log_file_path, old_fa_ptr->log_file_path, H5FD_SPLITTER_PATH_MAX + 1); /* Copy R/W and W/O FAPLs */ if (H5FD__copy_plist(old_fa_ptr->rw_fapl_id, &(new_fa_ptr->rw_fapl_id)) < 0) @@ -688,8 +690,8 @@ H5FD__splitter_open(const char *name, unsigned flags, hid_t splitter_fapl_id, ha HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "unable to get VFL driver info") /* Copy simpler info */ - HDstrncpy(file_ptr->fa.wo_path, fapl_ptr->wo_path, H5FD_SPLITTER_PATH_MAX); - HDstrncpy(file_ptr->fa.log_file_path, fapl_ptr->log_file_path, H5FD_SPLITTER_PATH_MAX); + HDstrncpy(file_ptr->fa.wo_path, fapl_ptr->wo_path, H5FD_SPLITTER_PATH_MAX + 1); + HDstrncpy(file_ptr->fa.log_file_path, fapl_ptr->log_file_path, H5FD_SPLITTER_PATH_MAX + 1); file_ptr->fa.ignore_wo_errs = fapl_ptr->ignore_wo_errs; /* Copy R/W and W/O channel FAPLs. */ diff --git a/src/H5FL.c b/src/H5FL.c index fbeb9d2..cb58868 100644 --- a/src/H5FL.c +++ b/src/H5FL.c @@ -337,8 +337,11 @@ H5FL_reg_free(H5FL_reg_head_t *head, void *obj) /* Free tracking information about the allocation location */ H5CS_close_stack(trk->stack); - trk->file = H5MM_xfree(trk->file); - trk->func = H5MM_xfree(trk->func); + /* The 'func' & 'file' strings are statically allocated (by the compiler) + * and are not allocated, so there's no need to free them. + */ + trk->file = NULL; + trk->func = NULL; /* Remove from "outstanding allocations" list */ if (trk == H5FL_out_head_g) { @@ -443,8 +446,11 @@ H5FL_reg_malloc(H5FL_reg_head_t *head H5FL_TRACK_PARAMS) /* Copy allocation location information */ ((H5FL_track_t *)ret_value)->stack = H5CS_copy_stack(); HDassert(((H5FL_track_t *)ret_value)->stack); - ((H5FL_track_t *)ret_value)->file = H5MM_strdup(call_file); - ((H5FL_track_t *)ret_value)->func = H5MM_strdup(call_func); + /* The 'call_func' & 'call_file' strings are statically allocated (by the compiler) + * there's no need to duplicate them. + */ + ((H5FL_track_t *)ret_value)->file = call_file; + ((H5FL_track_t *)ret_value)->func = call_func; ((H5FL_track_t *)ret_value)->line = call_line; /* Add to "outstanding allocations" list */ @@ -908,8 +914,11 @@ H5FL_blk_malloc(H5FL_blk_head_t *head, size_t size H5FL_TRACK_PARAMS) /* Copy allocation location information */ ((H5FL_track_t *)ret_value)->stack = H5CS_copy_stack(); HDassert(((H5FL_track_t *)ret_value)->stack); - ((H5FL_track_t *)ret_value)->file = H5MM_strdup(call_file); - ((H5FL_track_t *)ret_value)->func = H5MM_strdup(call_func); + /* The 'call_func' & 'call_file' strings are statically allocated (by the compiler) + * there's no need to duplicate them. + */ + ((H5FL_track_t *)ret_value)->file = call_file; + ((H5FL_track_t *)ret_value)->func = call_func; ((H5FL_track_t *)ret_value)->line = call_line; /* Add to "outstanding allocations" list */ @@ -1004,8 +1013,11 @@ H5FL_blk_free(H5FL_blk_head_t *head, void *block) /* Free tracking information about the allocation location */ H5CS_close_stack(trk->stack); - trk->file = H5MM_xfree(trk->file); - trk->func = H5MM_xfree(trk->func); + /* The 'func' & 'file' strings are statically allocated (by the compiler) + * and are not allocated, so there's no need to free them. + */ + trk->file = NULL; + trk->func = NULL; /* Remove from "outstanding allocations" list */ if (trk == H5FL_out_head_g) { @@ -1120,14 +1132,20 @@ H5FL_blk_realloc(H5FL_blk_head_t *head, void *block, size_t new_size H5FL_TRACK_ /* Release previous tracking information */ H5CS_close_stack(trk->stack); - trk->file = H5MM_xfree(trk->file); - trk->func = H5MM_xfree(trk->func); + /* The 'func' & 'file' strings are statically allocated (by the compiler) + * and are not allocated, so there's no need to free them. + */ + trk->file = NULL; + trk->func = NULL; /* Store new tracking information */ trk->stack = H5CS_copy_stack(); HDassert(trk->stack); - trk->file = H5MM_strdup(call_file); - trk->func = H5MM_strdup(call_func); + /* The 'call_func' & 'call_file' strings are statically allocated (by the compiler) + * there's no need to duplicate them. + */ + trk->file = call_file; + trk->func = call_func; trk->line = call_line; } #endif /* H5FL_TRACK */ @@ -2017,8 +2035,11 @@ H5FL_fac_free(H5FL_fac_head_t *head, void *obj) /* Free tracking information about the allocation location */ H5CS_close_stack(trk->stack); - trk->file = H5MM_xfree(trk->file); - trk->func = H5MM_xfree(trk->func); + /* The 'func' & 'file' strings are statically allocated (by the compiler) + * and are not allocated, so there's no need to free them. + */ + trk->file = NULL; + trk->func = NULL; /* Remove from "outstanding allocations" list */ if (trk == H5FL_out_head_g) { @@ -2120,8 +2141,11 @@ H5FL_fac_malloc(H5FL_fac_head_t *head H5FL_TRACK_PARAMS) /* Copy allocation location information */ ((H5FL_track_t *)ret_value)->stack = H5CS_copy_stack(); HDassert(((H5FL_track_t *)ret_value)->stack); - ((H5FL_track_t *)ret_value)->file = H5MM_strdup(call_file); - ((H5FL_track_t *)ret_value)->func = H5MM_strdup(call_func); + /* The 'call_func' & 'call_file' strings are statically allocated (by the compiler) + * there's no need to duplicate them. + */ + ((H5FL_track_t *)ret_value)->file = call_file; + ((H5FL_track_t *)ret_value)->func = call_func; ((H5FL_track_t *)ret_value)->line = call_line; /* Add to "outstanding allocations" list */ diff --git a/src/H5Faccum.c b/src/H5Faccum.c index aed5812..4821272 100644 --- a/src/H5Faccum.c +++ b/src/H5Faccum.c @@ -36,7 +36,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* File access */ -#include "H5FDprivate.h" /* File drivers */ +#include "H5FDprivate.h" /* File drivers */ #include "H5MMprivate.h" /* Memory management */ #include "H5VMprivate.h" /* Vectors and arrays */ diff --git a/src/H5Fdeprec.c b/src/H5Fdeprec.c index b482961..ff6b4a0 100644 --- a/src/H5Fdeprec.c +++ b/src/H5Fdeprec.c @@ -89,10 +89,12 @@ herr_t H5Fget_info1(hid_t obj_id, H5F_info1_t *finfo /*out*/) { - H5VL_object_t *vol_obj = NULL; - H5I_type_t type; - H5F_info2_t finfo2; /* Current file info struct */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + H5I_type_t type; + H5F_info2_t finfo2; /* Current file info struct */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", obj_id, finfo); @@ -111,9 +113,14 @@ H5Fget_info1(hid_t obj_id, H5F_info1_t *finfo /*out*/) if (NULL == (vol_obj = H5VL_vol_object(obj_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Set up VOL callback arguments */ + file_opt_args.get_info.type = type; + file_opt_args.get_info.finfo = &finfo2; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_INFO; + vol_cb_args.args = &file_opt_args; + /* Get the file information */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - type, &finfo2) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to retrieve file info") /* Copy the compatible fields into the older struct */ @@ -141,7 +148,9 @@ done: htri_t H5Fis_hdf5(const char *name) { - htri_t ret_value; /* Return value */ + H5VL_file_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + hbool_t is_accessible = FALSE; /* Whether file is accessible */ + htri_t ret_value; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE1("t", "*s", name); @@ -150,11 +159,19 @@ H5Fis_hdf5(const char *name) if (!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, (-1), "no file name specified") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_IS_ACCESSIBLE; + vol_cb_args.args.is_accessible.filename = name; + vol_cb_args.args.is_accessible.fapl_id = H5P_FILE_ACCESS_DEFAULT; + vol_cb_args.args.is_accessible.accessible = &is_accessible; + /* Check if file is accessible */ - if (H5VL_file_specific(NULL, H5VL_FILE_IS_ACCESSIBLE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - H5P_FILE_ACCESS_DEFAULT, name, &ret_value) < 0) + if (H5VL_file_specific(NULL, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, (-1), "unable to determine if file is accessible as HDF5") + /* Set return value */ + ret_value = (htri_t)is_accessible; + done: FUNC_LEAVE_API(ret_value) } /* end H5Fis_hdf5() */ @@ -196,10 +213,11 @@ done: herr_t H5Fset_latest_format(hid_t file_id, hbool_t latest_format) { - H5VL_object_t *vol_obj; /* File as VOL object */ - H5F_libver_t low = H5F_LIBVER_LATEST; /* Low bound */ - H5F_libver_t high = H5F_LIBVER_LATEST; /* High bound */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File as VOL object */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + H5F_libver_t low = H5F_LIBVER_LATEST; /* Low bound */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ib", file_id, latest_format); @@ -218,9 +236,14 @@ H5Fset_latest_format(hid_t file_id, hbool_t latest_format) if (!latest_format) low = H5F_LIBVER_EARLIEST; + /* Set up VOL callback arguments */ + file_opt_args.set_libver_bounds.low = low; + file_opt_args.set_libver_bounds.high = H5F_LIBVER_LATEST; + vol_cb_args.op_type = H5VL_NATIVE_FILE_SET_LIBVER_BOUNDS; + vol_cb_args.args = &file_opt_args; + /* Set the library's version bounds */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_SET_LIBVER_BOUNDS, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, (int)low, (int)high) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set library version bounds") done: diff --git a/src/H5Fefc.c b/src/H5Fefc.c index 3f9a22f..2d4eff2 100644 --- a/src/H5Fefc.c +++ b/src/H5Fefc.c @@ -36,10 +36,10 @@ #include "H5Pprivate.h" /* Property lists */ /* Special values for the "tag" field below */ -#define H5F_EFC_TAG_DEFAULT -1 -#define H5F_EFC_TAG_LOCK -2 -#define H5F_EFC_TAG_CLOSE -3 -#define H5F_EFC_TAG_DONTCLOSE -4 +#define H5F_EFC_TAG_DEFAULT (-1) +#define H5F_EFC_TAG_LOCK (-2) +#define H5F_EFC_TAG_CLOSE (-3) +#define H5F_EFC_TAG_DONTCLOSE (-4) /* Structure for each entry in a file's external file cache */ typedef struct H5F_efc_ent_t { diff --git a/src/H5Fint.c b/src/H5Fint.c index 247a047..e650878 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -82,6 +82,7 @@ static herr_t H5F__build_name(const char *prefix, const char *file_name, char ** static char * H5F__getenv_prefix_name(char **env_prefix /*in,out*/); static H5F_t *H5F__new(H5F_shared_t *shared, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf); static herr_t H5F__check_if_using_file_locks(H5P_genplist_t *fapl, hbool_t *use_file_locking); +static herr_t H5F__dest(H5F_t *f, hbool_t flush); static herr_t H5F__build_actual_name(const H5F_t *f, const H5P_genplist_t *fapl, const char *name, char ** /*out*/ actual_name); static herr_t H5F__flush_phase1(H5F_t *f); @@ -1403,12 +1404,12 @@ done: * Return: SUCCEED/FAIL *------------------------------------------------------------------------- */ -herr_t +static herr_t H5F__dest(H5F_t *f, hbool_t flush) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_PACKAGE + FUNC_ENTER_STATIC /* Sanity check */ HDassert(f); @@ -2487,11 +2488,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F_delete(const char *filename, hid_t fapl_id) +H5F__delete(const char *filename, hid_t fapl_id) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE HDassert(filename); @@ -2501,7 +2502,7 @@ H5F_delete(const char *filename, hid_t fapl_id) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_delete() */ +} /* end H5F__delete() */ /*------------------------------------------------------------------------- * Function: H5F_try_close @@ -3241,27 +3242,28 @@ done: /*------------------------------------------------------------------------- * Function: H5F__get_file_image * - * Purpose: Private version of H5Fget_file_image + * Purpose: Private version of H5Fget_file_image, returns bytes copied/ + * number of bytes needed in *image_len. + * + * Return: SUCCEED/FAIL * - * Return: Success: Bytes copied / number of bytes needed. - * Failure: -1 *------------------------------------------------------------------------- */ -ssize_t -H5F__get_file_image(H5F_t *file, void *buf_ptr, size_t buf_len) +herr_t +H5F__get_file_image(H5F_t *file, void *buf_ptr, size_t buf_len, size_t *image_len) { - H5FD_t *fd_ptr; /* file driver */ - haddr_t eoa; /* End of file address */ - ssize_t ret_value = -1; /* Return value */ + H5FD_t *fd_ptr; /* file driver */ + haddr_t eoa; /* End of file address */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE /* Check args */ if (!file || !file->shared || !file->shared->lf) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, (-1), "file_id yields invalid file pointer") + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "file_id yields invalid file pointer") fd_ptr = file->shared->lf; if (!fd_ptr->cls) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, (-1), "fd_ptr yields invalid class pointer") + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "fd_ptr yields invalid class pointer") /* the address space used by the split and multi file drivers is not * a good fit for this call. Since the plan is to depreciate these @@ -3282,7 +3284,7 @@ H5F__get_file_image(H5F_t *file, void *buf_ptr, size_t buf_len) * JRM -- 11/11/22 */ if (HDstrcmp(fd_ptr->cls->name, "multi") == 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "Not supported for multi file driver.") + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Not supported for multi file driver.") /* While the family file driver is conceptually fully compatible * with the get file image operation, it sets a file driver message @@ -3290,7 +3292,7 @@ H5F__get_file_image(H5F_t *file, void *buf_ptr, size_t buf_len) * driver other than the family file driver. Needless to say, this * rather defeats the purpose of the get file image operation. * - * While this problem is quire solvable, the required time and + * While this problem is quite solvable, the required time and * resources are lacking at present. Hence, for now, we don't * allow the get file image operation to be perfomed on files * opened with the family file driver. @@ -3304,30 +3306,24 @@ H5F__get_file_image(H5F_t *file, void *buf_ptr, size_t buf_len) * JRM -- 12/21/11 */ if (HDstrcmp(fd_ptr->cls->name, "family") == 0) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, (-1), "Not supported for family file driver.") + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "Not supported for family file driver.") /* Go get the actual file size */ if (HADDR_UNDEF == (eoa = H5FD_get_eoa(file->shared->lf, H5FD_MEM_DEFAULT))) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, (-1), "unable to get file size") - - /* set ret_value = to eoa -- will overwrite this if appropriate */ - ret_value = (ssize_t)eoa; + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file size") - /* test to see if a buffer was provided -- if not, we are done */ + /* Test to see if a buffer was provided */ if (buf_ptr != NULL) { - size_t space_needed; /* size of file image */ unsigned tmp, tmp_size; /* Check for buffer too small */ if ((haddr_t)buf_len < eoa) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, (-1), "supplied buffer too small") + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "supplied buffer too small") - space_needed = (size_t)eoa; - - /* read in the file image */ + /* Read in the file image */ /* (Note compensation for base address addition in internal routine) */ - if (H5FD_read(fd_ptr, H5FD_MEM_DEFAULT, 0, space_needed, buf_ptr) < 0) - HGOTO_ERROR(H5E_FILE, H5E_READERROR, (-1), "file image read request failed") + if (H5FD_read(fd_ptr, H5FD_MEM_DEFAULT, 0, (size_t)eoa, buf_ptr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "file image read request failed") /* Offset to "status_flags" in the superblock */ tmp = H5F_SUPER_STATUS_FLAGS_OFF(file->shared->sblock->super_vers); @@ -3339,6 +3335,9 @@ H5F__get_file_image(H5F_t *file, void *buf_ptr, size_t buf_len) HDmemset((uint8_t *)buf_ptr + tmp, 0, tmp_size); } /* end if */ + /* Set *image_len = to EOA */ + *image_len = (size_t)eoa; + done: FUNC_LEAVE_NOAPI(ret_value) } /* H5F__get_file_image() */ @@ -4043,11 +4042,12 @@ done: hid_t H5F_get_file_id(H5VL_object_t *vol_obj, H5I_type_t obj_type, hbool_t app_ref) { - void * vol_obj_file = NULL; /* File object pointer */ - H5VL_loc_params_t loc_params; /* Location parameters */ - hid_t file_id = H5I_INVALID_HID; /* File ID for object */ - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + void * vol_obj_file = NULL; /* File object pointer */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + hid_t file_id = H5I_INVALID_HID; /* File ID for object */ + hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_NOAPI(H5I_INVALID_HID) @@ -4055,9 +4055,12 @@ H5F_get_file_id(H5VL_object_t *vol_obj, H5I_type_t obj_type, hbool_t app_ref) loc_params.type = H5VL_OBJECT_BY_SELF; loc_params.obj_type = obj_type; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_FILE; + vol_cb_args.args.get_file.file = &vol_obj_file; + /* Retrieve VOL file from object */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_FILE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &vol_obj_file) < 0) + if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't retrieve file from object") /* Check if the file's ID already exists */ diff --git a/src/H5Fmodule.h b/src/H5Fmodule.h index 7f0299a..81c1ede 100644 --- a/src/H5Fmodule.h +++ b/src/H5Fmodule.h @@ -29,8 +29,7 @@ #define H5_MY_PKG_ERR H5E_FILE #define H5_MY_PKG_INIT YES -/** - * \defgroup H5F H5F +/**\defgroup H5F H5F * * Use the functions in this module to manage HDF5 files. * @@ -41,15 +40,23 @@ * creation or access \c mode control the interaction with the underlying * storage such as file systems. * - * \Emph{Proper error handling is part of the life cycle.} * <table> - * <tr><th>Create</th><th>Open</th></tr> + * <tr><th>Create</th><th>Read</th></tr> * <tr valign="top"> * <td> - * \snippet H5F_examples.c life_cycle + * \snippet{lineno} H5F_examples.c create * </td> * <td> - * \snippet H5F_examples.c life_cycle_w_open + * \snippet{lineno} H5F_examples.c read + * </td> + * </tr> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5F_examples.c update + * </td> + * <td> + * \snippet{lineno} H5F_examples.c delete * </td> * </tr> * </table> diff --git a/src/H5Fmount.c b/src/H5Fmount.c index f107c98..4b90ea3 100644 --- a/src/H5Fmount.c +++ b/src/H5Fmount.c @@ -83,7 +83,7 @@ done: } /* end H5F__close_mounts() */ /*------------------------------------------------------------------------- - * Function: H5F__mount + * Function: H5F_mount * * Purpose: Mount file CHILD onto the group specified by LOC and NAME, * using mount properties in PLIST. CHILD must not already be @@ -97,7 +97,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F__mount(H5G_loc_t *loc, const char *name, H5F_t *child, hid_t H5_ATTR_UNUSED plist_id) +H5F_mount(const H5G_loc_t *loc, const char *name, H5F_t *child, hid_t H5_ATTR_UNUSED plist_id) { H5G_t * mount_point = NULL; /*mount point group */ H5F_t * ancestor = NULL; /*ancestor files */ @@ -110,7 +110,7 @@ H5F__mount(H5G_loc_t *loc, const char *name, H5F_t *child, hid_t H5_ATTR_UNUSED H5G_loc_t root_loc; /* Group location of root of file to mount */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_PACKAGE + FUNC_ENTER_NOAPI(FAIL) HDassert(loc); HDassert(name && *name); @@ -157,10 +157,9 @@ H5F__mount(H5G_loc_t *loc, const char *name, H5F_t *child, hid_t H5_ATTR_UNUSED HDassert(mp_loc.oloc); mp_loc.path = H5G_nameof(mount_point); HDassert(mp_loc.path); - for (ancestor = parent; ancestor; ancestor = ancestor->parent) { + for (ancestor = parent; ancestor; ancestor = ancestor->parent) if (ancestor->shared == child->shared) HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "mount would introduce a cycle") - } /* Make certain that the parent & child files have the same "file close degree" */ if (parent->shared->fc_degree != child->shared->fc_degree) @@ -240,10 +239,10 @@ done: } FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F__mount() */ +} /* end H5F_mount() */ /*------------------------------------------------------------------------- - * Function: H5F__unmount + * Function: H5F_unmount * * Purpose: Unmount the child which is mounted at the group specified by * LOC and NAME or fail if nothing is mounted there. Neither @@ -261,7 +260,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F__unmount(H5G_loc_t *loc, const char *name) +H5F_unmount(const H5G_loc_t *loc, const char *name) { H5G_t * child_group = NULL; /* Child's group in parent mtab */ H5F_t * child = NULL; /*mounted file */ @@ -275,7 +274,7 @@ H5F__unmount(H5G_loc_t *loc, const char *name) int child_idx; /* Index of child in parent's mtab */ herr_t ret_value = SUCCEED; /*return value */ - FUNC_ENTER_PACKAGE + FUNC_ENTER_NOAPI(FAIL) HDassert(loc); HDassert(name && *name); @@ -291,7 +290,7 @@ H5F__unmount(H5G_loc_t *loc, const char *name) * then we must have found the mount point. */ if (H5G_loc_find(loc, name, &mp_loc /*out*/) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found") + HGOTO_ERROR(H5E_FILE, H5E_NOTFOUND, FAIL, "group not found") mp_loc_setup = TRUE; child = mp_loc.oloc->file; mnt_oloc = H5G_oloc(child->shared->root_grp); @@ -364,7 +363,7 @@ H5F__unmount(H5G_loc_t *loc, const char *name) /* Search the open IDs replace names to reflect unmount operation */ if (H5G_name_replace(NULL, H5G_NAME_UNMOUNT, mp_loc.oloc->file, mp_loc.path->full_path_r, root_loc.oloc->file, root_loc.path->full_path_r) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to replace name") + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to replace name") /* Eliminate the mount point from the table */ HDmemmove(parent->shared->mtab.child + (unsigned)child_idx, @@ -376,7 +375,7 @@ H5F__unmount(H5G_loc_t *loc, const char *name) /* Unmount the child file from the parent file */ if (H5G_unmount(child_group) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to reset group mounted flag") + HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to reset group mounted flag") if (H5G_close(child_group) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to close unmounted group") @@ -391,7 +390,7 @@ done: H5G_loc_free(&mp_loc); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F__unmount() */ +} /* end H5F_unmount() */ /*------------------------------------------------------------------------- * Function: H5F_is_mount diff --git a/src/H5Fmpi.c b/src/H5Fmpi.c index 4b5283e..53d2d78 100644 --- a/src/H5Fmpi.c +++ b/src/H5Fmpi.c @@ -193,7 +193,7 @@ done: } /* end H5F_mpi_get_size() */ /*------------------------------------------------------------------------- - * Function: H5F_set_mpi_atomicity + * Function: H5F__set_mpi_atomicity * * Purpose: Private call to set the atomicity mode * @@ -202,11 +202,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F_set_mpi_atomicity(H5F_t *file, hbool_t flag) +H5F__set_mpi_atomicity(H5F_t *file, hbool_t flag) { herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(FAIL); + FUNC_ENTER_PACKAGE /* Check args */ HDassert(file); @@ -222,7 +222,7 @@ H5F_set_mpi_atomicity(H5F_t *file, hbool_t flag) done: FUNC_LEAVE_NOAPI(ret_value); -} /* end H5F_set_mpi_atomicity() */ +} /* end H5F__set_mpi_atomicity() */ /*------------------------------------------------------------------------- * Function: H5Fset_mpi_atomicity @@ -240,9 +240,10 @@ done: herr_t H5Fset_mpi_atomicity(hid_t file_id, hbool_t flag) { - H5VL_object_t *vol_obj = NULL; - int va_flag = (int)flag; /* C is grumpy about passing hbool_t via va_arg */ - herr_t ret_value = SUCCEED; + H5VL_object_t * vol_obj; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL); H5TRACE2("e", "ib", file_id, flag); @@ -251,9 +252,13 @@ H5Fset_mpi_atomicity(hid_t file_id, hbool_t flag) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier"); + /* Set up VOL callback arguments */ + file_opt_args.set_mpi_atomicity.flag = flag; + vol_cb_args.op_type = H5VL_NATIVE_FILE_SET_MPI_ATOMICITY; + vol_cb_args.args = &file_opt_args; + /* Set atomicity value */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_SET_MPI_ATOMICITY, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, va_flag) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to set MPI atomicity"); done: @@ -261,7 +266,7 @@ done: } /* end H5Fset_mpi_atomicity() */ /*------------------------------------------------------------------------- - * Function: H5F_get_mpi_atomicity + * Function: H5F__get_mpi_atomicity * * Purpose: Private call to get the atomicity mode * @@ -270,11 +275,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F_get_mpi_atomicity(H5F_t *file, hbool_t *flag) +H5F__get_mpi_atomicity(const H5F_t *file, hbool_t *flag) { herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(FAIL); + FUNC_ENTER_PACKAGE /* Check args */ HDassert(file); @@ -291,7 +296,7 @@ H5F_get_mpi_atomicity(H5F_t *file, hbool_t *flag) done: FUNC_LEAVE_NOAPI(ret_value); -} /* end H5F_get_mpi_atomicity() */ +} /* end H5F__get_mpi_atomicity() */ /*------------------------------------------------------------------------- * Function: H5Fget_mpi_atomicity @@ -309,8 +314,10 @@ done: herr_t H5Fget_mpi_atomicity(hid_t file_id, hbool_t *flag /*out*/) { - H5VL_object_t *vol_obj = NULL; - herr_t ret_value = SUCCEED; + H5VL_object_t * vol_obj; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL); H5TRACE2("e", "ix", file_id, flag); @@ -319,9 +326,13 @@ H5Fget_mpi_atomicity(hid_t file_id, hbool_t *flag /*out*/) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier"); + /* Set up VOL callback arguments */ + file_opt_args.get_mpi_atomicity.flag = flag; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_MPI_ATOMICITY; + vol_cb_args.args = &file_opt_args; + /* Get atomicity value */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_MPI_ATOMICITY, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, flag) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get MPI atomicity"); done: diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 71c27f2..c94c5af 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -519,25 +519,23 @@ H5_DLLVAR htri_t use_locks_env_g; /* General routines */ H5_DLL herr_t H5F__post_open(H5F_t *f); -H5_DLL H5F_t * H5F__reopen(H5F_t *f); -H5_DLL herr_t H5F__dest(H5F_t *f, hbool_t flush); -H5_DLL herr_t H5F__flush(H5F_t *f); -H5_DLL htri_t H5F__is_hdf5(const char *name, hid_t fapl_id); -H5_DLL ssize_t H5F__get_file_image(H5F_t *f, void *buf_ptr, size_t buf_len); -H5_DLL herr_t H5F__get_info(H5F_t *f, H5F_info2_t *finfo); -H5_DLL herr_t H5F__format_convert(H5F_t *f); -H5_DLL herr_t H5F__start_swmr_write(H5F_t *f); -H5_DLL herr_t H5F__close(H5F_t *f); -H5_DLL herr_t H5F__set_libver_bounds(H5F_t *f, H5F_libver_t low, H5F_libver_t high); -H5_DLL herr_t H5F__get_cont_info(const H5F_t *f, H5VL_file_cont_info_t *info); -H5_DLL herr_t H5F__parse_file_lock_env_var(htri_t *use_locks); -H5_DLL herr_t H5F__vfd_swmr_end_tick(H5F_t *f); -H5_DLL herr_t H5F__vfd_swmr_disable_end_of_tick(H5F_t *f); -H5_DLL herr_t H5F__vfd_swmr_enable_end_of_tick(H5F_t *f); +H5_DLL H5F_t *H5F__reopen(H5F_t *f); +H5_DLL herr_t H5F__flush(H5F_t *f); +H5_DLL htri_t H5F__is_hdf5(const char *name, hid_t fapl_id); +H5_DLL herr_t H5F__get_file_image(H5F_t *f, void *buf_ptr, size_t buf_len, size_t *image_len); +H5_DLL herr_t H5F__get_info(H5F_t *f, H5F_info2_t *finfo); +H5_DLL herr_t H5F__format_convert(H5F_t *f); +H5_DLL herr_t H5F__start_swmr_write(H5F_t *f); +H5_DLL herr_t H5F__close(H5F_t *f); +H5_DLL herr_t H5F__set_libver_bounds(H5F_t *f, H5F_libver_t low, H5F_libver_t high); +H5_DLL herr_t H5F__get_cont_info(const H5F_t *f, H5VL_file_cont_info_t *info); +H5_DLL herr_t H5F__parse_file_lock_env_var(htri_t *use_locks); +H5_DLL herr_t H5F__delete(const char *filename, hid_t fapl_id); +H5_DLL herr_t H5F__vfd_swmr_end_tick(H5F_t *f); +H5_DLL herr_t H5F__vfd_swmr_disable_end_of_tick(H5F_t *f); +H5_DLL herr_t H5F__vfd_swmr_enable_end_of_tick(H5F_t *f); /* File mount related routines */ -H5_DLL herr_t H5F__mount(H5G_loc_t *loc, const char *name, H5F_t *child, hid_t plist_id); -H5_DLL herr_t H5F__unmount(H5G_loc_t *loc, const char *name); H5_DLL herr_t H5F__close_mounts(H5F_t *f); H5_DLL herr_t H5F__mount_count_ids(H5F_t *f, unsigned *nopen_files, unsigned *nopen_objs); @@ -567,6 +565,12 @@ H5_DLL herr_t H5F__sfile_add(H5F_shared_t *shared); H5_DLL H5F_shared_t *H5F__sfile_search(H5FD_t *lf); H5_DLL herr_t H5F__sfile_remove(H5F_shared_t *shared); +/* Parallel I/O (i.e. MPI) related routines */ +#ifdef H5_HAVE_PARALLEL +H5_DLL herr_t H5F__get_mpi_atomicity(const H5F_t *file, hbool_t *flag); +H5_DLL herr_t H5F__set_mpi_atomicity(H5F_t *file, hbool_t flag); +#endif /* H5_HAVE_PARALLEL */ + /* External file cache routines */ H5_DLL H5F_efc_t *H5F__efc_create(unsigned max_nfiles); H5_DLL H5F_t * H5F__efc_open(H5F_t *parent, const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id); diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 901ab7c..cef77dc 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -301,23 +301,36 @@ uint64_decode(uint8_t **pp) (p) += 8; \ } +/* clang-format off */ /* Address-related macros */ -#define H5F_addr_overflow(X, Z) \ - (HADDR_UNDEF == (X) || HADDR_UNDEF == (X) + (haddr_t)(Z) || (X) + (haddr_t)(Z) < (X)) -#define H5F_addr_defined(X) ((X) != HADDR_UNDEF) +#define H5F_addr_overflow(X,Z) (HADDR_UNDEF==(X) || \ + HADDR_UNDEF==(X)+(haddr_t)(Z) || \ + (X)+(haddr_t)(Z)<(X)) +#define H5F_addr_defined(X) ((X)!=HADDR_UNDEF) /* The H5F_addr_eq() macro guarantees that Y is not HADDR_UNDEF by making * certain that X is not HADDR_UNDEF and then checking that X equals Y */ -#define H5F_addr_eq(X, Y) ((X) != HADDR_UNDEF && (X) == (Y)) -#define H5F_addr_ne(X, Y) (!H5F_addr_eq((X), (Y))) -#define H5F_addr_lt(X, Y) ((X) != HADDR_UNDEF && (Y) != HADDR_UNDEF && (X) < (Y)) -#define H5F_addr_le(X, Y) ((X) != HADDR_UNDEF && (Y) != HADDR_UNDEF && (X) <= (Y)) -#define H5F_addr_gt(X, Y) ((X) != HADDR_UNDEF && (Y) != HADDR_UNDEF && (X) > (Y)) -#define H5F_addr_ge(X, Y) ((X) != HADDR_UNDEF && (Y) != HADDR_UNDEF && (X) >= (Y)) -#define H5F_addr_cmp(X, Y) (H5F_addr_eq((X), (Y)) ? 0 : (H5F_addr_lt((X), (Y)) ? -1 : 1)) -#define H5F_addr_pow2(N) ((haddr_t)1 << (N)) -#define H5F_addr_overlap(O1, L1, O2, L2) \ - (((O1) < (O2) && ((O1) + (L1)) > (O2)) || ((O1) >= (O2) && (O1) < ((O2) + (L2)))) +#define H5F_addr_eq(X,Y) ((X)!=HADDR_UNDEF && \ + (X)==(Y)) +#define H5F_addr_ne(X,Y) (!H5F_addr_eq((X),(Y))) +#define H5F_addr_lt(X,Y) ((X)!=HADDR_UNDEF && \ + (Y)!=HADDR_UNDEF && \ + (X)<(Y)) +#define H5F_addr_le(X,Y) ((X)!=HADDR_UNDEF && \ + (Y)!=HADDR_UNDEF && \ + (X)<=(Y)) +#define H5F_addr_gt(X,Y) ((X)!=HADDR_UNDEF && \ + (Y)!=HADDR_UNDEF && \ + (X)>(Y)) +#define H5F_addr_ge(X,Y) ((X)!=HADDR_UNDEF && \ + (Y)!=HADDR_UNDEF && \ + (X)>=(Y)) +#define H5F_addr_cmp(X,Y) (H5F_addr_eq((X), (Y)) ? 0 : \ + (H5F_addr_lt((X), (Y)) ? -1 : 1)) +#define H5F_addr_pow2(N) ((haddr_t)1<<(N)) +#define H5F_addr_overlap(O1,L1,O2,L2) (((O1) < (O2) && ((O1) + (L1)) > (O2)) || \ + ((O1) >= (O2) && (O1) < ((O2) + (L2)))) +/* clang-format on */ /* If the module using this macro is allowed access to the private variables, access them directly */ #ifdef H5F_MODULE @@ -540,18 +553,18 @@ uint64_decode(uint8_t **pp) #define H5F_DEFAULT_CSET H5T_CSET_ASCII /* ========= File Creation properties ============ */ -#define H5F_CRT_USER_BLOCK_NAME "block_size" /* Size of the file user block in bytes */ -#define H5F_CRT_SYM_LEAF_NAME "symbol_leaf" /* 1/2 rank for symbol table leaf nodes */ -#define H5F_CRT_SYM_LEAF_DEF 4 -#define H5F_CRT_BTREE_RANK_NAME "btree_rank" /* 1/2 rank for btree internal nodes */ -#define H5F_CRT_ADDR_BYTE_NUM_NAME "addr_byte_num" /* Byte number in an address */ -#define H5F_CRT_OBJ_BYTE_NUM_NAME "obj_byte_num" /* Byte number for object size */ -#define H5F_CRT_SUPER_VERS_NAME "super_version" /* Version number of the superblock */ -#define H5F_CRT_SHMSG_NINDEXES_NAME "num_shmsg_indexes" /* Number of shared object header message indexes */ +#define H5F_CRT_USER_BLOCK_NAME "block_size" /* Size of the file user block in bytes */ +#define H5F_CRT_SYM_LEAF_NAME "symbol_leaf" /* 1/2 rank for symbol table leaf nodes */ +#define H5F_CRT_SYM_LEAF_DEF 4 +#define H5F_CRT_BTREE_RANK_NAME "btree_rank" /* 1/2 rank for btree internal nodes */ +#define H5F_CRT_ADDR_BYTE_NUM_NAME "addr_byte_num" /* Byte number in an address */ +#define H5F_CRT_OBJ_BYTE_NUM_NAME "obj_byte_num" /* Byte number for object size */ +#define H5F_CRT_SUPER_VERS_NAME "super_version" /* Version number of the superblock */ +/* Number of shared object header message indexes */ +#define H5F_CRT_SHMSG_NINDEXES_NAME "num_shmsg_indexes" #define H5F_CRT_SHMSG_INDEX_TYPES_NAME "shmsg_message_types" /* Types of message in each index */ -#define H5F_CRT_SHMSG_INDEX_MINSIZE_NAME \ - "shmsg_message_minsize" /* Minimum size of messages in each index \ - */ +/* Minimum size of messages in each index */ +#define H5F_CRT_SHMSG_INDEX_MINSIZE_NAME "shmsg_message_minsize" #define H5F_CRT_SHMSG_LIST_MAX_NAME "shmsg_list_max" /* Shared message list maximum size */ #define H5F_CRT_SHMSG_BTREE_MIN_NAME "shmsg_btree_min" /* Shared message B-tree minimum size */ #define H5F_CRT_FILE_SPACE_STRATEGY_NAME "file_space_strategy" /* File space handling strategy */ @@ -598,10 +611,10 @@ uint64_decode(uint8_t **pp) #define H5F_ACS_CLEAR_STATUS_FLAGS_NAME \ "clear_status_flags" /* Whether to clear superblock status_flags (private property only used by h5clear) \ */ -#define H5F_ACS_NULL_FSM_ADDR_NAME "null_fsm_addr" /* Nullify addresses of free-space managers */ - /* Private property used only by h5clear */ -#define H5F_ACS_SKIP_EOF_CHECK_NAME "skip_eof_check" /* Skip EOF check */ - /* Private property used only by h5clear */ +#define H5F_ACS_NULL_FSM_ADDR_NAME "null_fsm_addr" /* Nullify addresses of free-space managers */ +/* Private property used only by h5clear */ +#define H5F_ACS_SKIP_EOF_CHECK_NAME "skip_eof_check" /* Skip EOF check */ +/* Private property used only by h5clear */ #define H5F_ACS_USE_MDC_LOGGING_NAME "use_mdc_logging" /* Whether to use metadata cache logging */ #define H5F_ACS_MDC_LOG_LOCATION_NAME "mdc_log_location" /* Name of metadata cache log location */ #define H5F_ACS_START_MDC_LOG_ON_ACCESS_NAME \ @@ -669,13 +682,13 @@ uint64_decode(uint8_t **pp) #define HDF5_BTREE_SNODE_IK_DEF 16 #define HDF5_BTREE_CHUNK_IK_DEF \ 32 /* Note! this value is assumed \ - to be 32 for version 0 \ - of the superblock and \ - if it is changed, the code \ - must compensate. -QAK \ - */ + to be 32 for version 0 \ + of the superblock and \ + if it is changed, the code \ + must compensate. -QAK \ + */ #define HDF5_BTREE_IK_MAX_ENTRIES 65536 /* 2^16 - 2 bytes for storing entries (children) */ - /* See format specification on version 1 B-trees */ +/* See format specification on version 1 B-trees */ /* Default file space handling strategy */ #define H5F_FILE_SPACE_STRATEGY_DEF H5F_FSPACE_STRATEGY_FSM_AGGR @@ -778,6 +791,7 @@ uint64_decode(uint8_t **pp) /* Forward declarations (for prototypes & type definitions) */ struct H5B_class_t; struct H5UC_t; +struct H5G_loc_t; struct H5O_loc_t; struct H5HG_heap_t; struct H5VL_class_t; @@ -853,7 +867,6 @@ H5_DLL herr_t H5F_init(void); H5_DLL H5F_t *H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id); H5_DLL herr_t H5F_try_close(H5F_t *f, hbool_t *was_closed /*out*/); H5_DLL hid_t H5F_get_file_id(H5VL_object_t *vol_obj, H5I_type_t obj_type, hbool_t app_ref); -H5_DLL herr_t H5F_delete(const char *filename, hid_t fapl_id); /* Functions that retrieve values from the file struct */ H5_DLL H5F_libver_t H5F_get_low_bound(const H5F_t *f); @@ -931,7 +944,12 @@ H5_DLL haddr_t H5F_shared_get_eoa(const H5F_shared_t *f_sh, H5FD_mem_t type); H5_DLL haddr_t H5F_get_eoa(const H5F_t *f, H5FD_mem_t type); H5_DLL herr_t H5F_get_vfd_handle(const H5F_t *file, hid_t fapl, void **file_handle); -/* Functions that check file mounting information */ +/* VFD SWMR functions */ +H5_DLL hbool_t H5F_use_vfd_swmr(const H5F_t *f); + +/* File mounting routines */ +H5_DLL herr_t H5F_mount(const struct H5G_loc_t *loc, const char *name, H5F_t *child, hid_t plist_id); +H5_DLL herr_t H5F_unmount(const struct H5G_loc_t *loc, const char *name); H5_DLL hbool_t H5F_is_mount(const H5F_t *file); H5_DLL hbool_t H5F_has_mount(const H5F_t *file); H5_DLL herr_t H5F_traverse_mount(struct H5O_loc_t *oloc /*in,out*/); @@ -984,8 +1002,6 @@ H5_DLL MPI_Comm H5F_mpi_get_comm(const H5F_t *f); H5_DLL int H5F_shared_mpi_get_size(const H5F_shared_t *f_sh); H5_DLL int H5F_mpi_get_size(const H5F_t *f); H5_DLL herr_t H5F_mpi_retrieve_comm(hid_t loc_id, hid_t acspl_id, MPI_Comm *mpi_comm); -H5_DLL herr_t H5F_get_mpi_atomicity(H5F_t *file, hbool_t *flag); -H5_DLL herr_t H5F_set_mpi_atomicity(H5F_t *file, hbool_t flag); #endif /* H5_HAVE_PARALLEL */ /* External file cache routines */ @@ -1005,6 +1021,4 @@ H5_DLL herr_t H5F_cwfs_remove_heap(H5F_shared_t *shared, struct H5HG_heap_t *hea /* Debugging functions */ H5_DLL herr_t H5F_debug(H5F_t *f, FILE *stream, int indent, int fwidth); -H5_DLL hbool_t H5F_use_vfd_swmr(const H5F_t *f); - #endif /* H5Fprivate_H */ diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h index 48bfaaa..d241816 100644 --- a/src/H5Fpublic.h +++ b/src/H5Fpublic.h @@ -1114,7 +1114,7 @@ H5_DLL herr_t H5Fget_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr); * \since 1.8.0 * */ -H5_DLL herr_t H5Fset_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr); +H5_DLL herr_t H5Fset_mdc_config(hid_t file_id, const H5AC_cache_config_t *config_ptr); /** * \ingroup MDC * @@ -1888,6 +1888,7 @@ H5_DLL herr_t H5Fset_mpi_atomicity(hid_t file_id, hbool_t flag); H5_DLL herr_t H5Fget_mpi_atomicity(hid_t file_id, hbool_t *flag); #endif /* H5_HAVE_PARALLEL */ +/// \cond DEV /* API Wrappers for async routines */ /* (Must be defined _after_ the function prototype) */ /* (And must only defined when included in application code, not the library) */ @@ -1907,6 +1908,7 @@ H5_DLL herr_t H5Fget_mpi_atomicity(hid_t file_id, hbool_t *flag); #define H5Fflush_async_wrap H5_NO_EXPAND(H5Fflush_async) #define H5Fclose_async_wrap H5_NO_EXPAND(H5Fclose_async) #endif /* H5F_MODULE */ +/// \endcond /* Symbols defined for compatibility with previous versions of the HDF5 API. * diff --git a/src/H5G.c b/src/H5G.c index 45ba023..deaf792 100644 --- a/src/H5G.c +++ b/src/H5G.c @@ -502,8 +502,9 @@ done: hid_t H5Gget_create_plist(hid_t group_id) { - H5VL_object_t *vol_obj = NULL; - hid_t ret_value = H5I_INVALID_HID; + H5VL_object_t * vol_obj; /* Object for loc_id */ + H5VL_group_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hid_t ret_value = H5I_INVALID_HID; FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", group_id); @@ -512,11 +513,17 @@ H5Gget_create_plist(hid_t group_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(group_id, H5I_GROUP))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a group ID") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_GROUP_GET_GCPL; + vol_cb_args.args.get_gcpl.gcpl_id = H5I_INVALID_HID; + /* Get the group creation property list for the group */ - if (H5VL_group_get(vol_obj, H5VL_GROUP_GET_GCPL, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &ret_value) < - 0) + if (H5VL_group_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5I_INVALID_HID, "can't get group's creation property list") + /* Set the return value */ + ret_value = vol_cb_args.args.get_gcpl.gcpl_id; + done: FUNC_LEAVE_API(ret_value) } /* end H5Gget_create_plist() */ @@ -538,9 +545,9 @@ H5G__get_info_api_common(hid_t loc_id, H5G_info_t *group_info /*out*/, void **to H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters for object access */ - H5I_type_t id_type; /* Type of ID */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_group_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5I_type_t id_type; /* Type of ID */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -551,13 +558,14 @@ H5G__get_info_api_common(hid_t loc_id, H5G_info_t *group_info /*out*/, void **to if (!group_info) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_info parameter cannot be NULL") - /* Set up object access arguments */ - if (H5VL_setup_self_args(loc_id, vol_obj_ptr, &loc_params) < 0) + /* Set up VOL callback & object access arguments */ + vol_cb_args.op_type = H5VL_GROUP_GET_INFO; + if (H5VL_setup_self_args(loc_id, vol_obj_ptr, &vol_cb_args.args.get_info.loc_params) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set object access arguments") + vol_cb_args.args.get_info.ginfo = group_info; /* Retrieve group information */ - if (H5VL_group_get(*vol_obj_ptr, H5VL_GROUP_GET_INFO, H5P_DATASET_XFER_DEFAULT, token_ptr, &loc_params, - group_info) < 0) + if (H5VL_group_get(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get group info") done: @@ -647,8 +655,8 @@ H5G__get_info_by_name_api_common(hid_t loc_id, const char *name, H5G_info_t *gro H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters for object access */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_group_get_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -656,13 +664,15 @@ H5G__get_info_by_name_api_common(hid_t loc_id, const char *name, H5G_info_t *gro if (!group_info) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_info parameter cannot be NULL") - /* Set up object access arguments */ - if (H5VL_setup_name_args(loc_id, name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) + /* Set up VOL callback & object access arguments */ + vol_cb_args.op_type = H5VL_GROUP_GET_INFO; + if (H5VL_setup_name_args(loc_id, name, FALSE, lapl_id, vol_obj_ptr, + &vol_cb_args.args.get_info.loc_params) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set object access arguments") + vol_cb_args.args.get_info.ginfo = group_info; /* Retrieve group information */ - if (H5VL_group_get(*vol_obj_ptr, H5VL_GROUP_GET_INFO, H5P_DATASET_XFER_DEFAULT, token_ptr, &loc_params, - group_info) < 0) + if (H5VL_group_get(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get group info") done: @@ -754,8 +764,8 @@ H5G__get_info_by_idx_api_common(hid_t loc_id, const char *group_name, H5_index_t H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters for object access */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_group_get_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -763,14 +773,15 @@ H5G__get_info_by_idx_api_common(hid_t loc_id, const char *group_name, H5_index_t if (!group_info) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_info parameter cannot be NULL") - /* Set up object access arguments */ - if (H5VL_setup_idx_args(loc_id, group_name, idx_type, order, n, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, - &loc_params) < 0) + /* Set up VOL callback & object access arguments */ + vol_cb_args.op_type = H5VL_GROUP_GET_INFO; + if (H5VL_setup_idx_args(loc_id, group_name, idx_type, order, n, FALSE, lapl_id, vol_obj_ptr, + &vol_cb_args.args.get_info.loc_params) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set object access arguments") + vol_cb_args.args.get_info.ginfo = group_info; /* Retrieve group information */ - if (H5VL_group_get(*vol_obj_ptr, H5VL_GROUP_GET_INFO, H5P_DATASET_XFER_DEFAULT, token_ptr, &loc_params, - group_info) < 0) + if (H5VL_group_get(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get group info") done: @@ -957,8 +968,9 @@ done: herr_t H5Gflush(hid_t group_id) { - H5VL_object_t *vol_obj; /* Group for this operation */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_group_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", group_id); @@ -971,9 +983,12 @@ H5Gflush(hid_t group_id) if (H5CX_set_loc(group_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set collective metadata read info") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_GROUP_FLUSH; + vol_cb_args.args.flush.grp_id = group_id; + /* Flush group's metadata to file */ - if (H5VL_group_specific(vol_obj, H5VL_GROUP_FLUSH, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, group_id) < - 0) + if (H5VL_group_specific(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTFLUSH, FAIL, "unable to flush group") done: @@ -995,8 +1010,9 @@ done: herr_t H5Grefresh(hid_t group_id) { - H5VL_object_t *vol_obj; /* Group for this operation */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_group_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", group_id); @@ -1009,9 +1025,12 @@ H5Grefresh(hid_t group_id) if (H5CX_set_loc(group_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set collective metadata read info") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_GROUP_REFRESH; + vol_cb_args.args.refresh.grp_id = group_id; + /* Refresh group's metadata */ - if (H5VL_group_specific(vol_obj, H5VL_GROUP_REFRESH, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - group_id) < 0) + if (H5VL_group_specific(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, "unable to refresh group") done: diff --git a/src/H5Gcompact.c b/src/H5Gcompact.c index a621f6e..0c0b5db 100644 --- a/src/H5Gcompact.c +++ b/src/H5Gcompact.c @@ -200,20 +200,20 @@ done: * * Purpose: Returns the name of objects in the group by giving index. * - * Return: Success: Non-negative, length of name - * Failure: Negative + * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Sep 6, 2005 * *------------------------------------------------------------------------- */ -ssize_t +herr_t H5G__compact_get_name_by_idx(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, H5_index_t idx_type, - H5_iter_order_t order, hsize_t idx, char *name, size_t size) + H5_iter_order_t order, hsize_t idx, char *name, size_t name_size, + size_t *name_len) { H5G_link_table_t ltable = {0, NULL}; /* Link table */ - ssize_t ret_value = -1; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -229,13 +229,13 @@ H5G__compact_get_name_by_idx(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, H5 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "index out of bound") /* Get the length of the name */ - ret_value = (ssize_t)HDstrlen(ltable.lnks[idx].name); + *name_len = HDstrlen(ltable.lnks[idx].name); /* Copy the name into the user's buffer, if given */ if (name) { - HDstrncpy(name, ltable.lnks[idx].name, MIN((size_t)(ret_value + 1), size)); - if ((size_t)ret_value >= size) - name[size - 1] = '\0'; + HDstrncpy(name, ltable.lnks[idx].name, MIN((*name_len + 1), name_size)); + if (*name_len >= name_size) + name[name_size - 1] = '\0'; } /* end if */ done: diff --git a/src/H5Gdense.c b/src/H5Gdense.c index ec5cb71..753936b 100644 --- a/src/H5Gdense.c +++ b/src/H5Gdense.c @@ -169,7 +169,7 @@ typedef struct { size_t name_size; /* Size of name buffer to fill */ /* upward */ - ssize_t name_len; /* Full length of name */ + size_t name_len; /* Full length of name */ } H5G_bt2_ud_gnbi_t; /* @@ -185,7 +185,7 @@ typedef struct { size_t name_size; /* Size of name buffer to fill */ /* upward */ - ssize_t name_len; /* Full length of name */ + size_t name_len; /* Full length of name */ } H5G_fh_ud_gnbi_t; /* @@ -1046,12 +1046,12 @@ H5G__dense_get_name_by_idx_fh_cb(const void *obj, size_t obj_len, void *_udata) HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode link") /* Get the length of the name */ - udata->name_len = (ssize_t)HDstrlen(lnk->name); + udata->name_len = HDstrlen(lnk->name); /* Copy the name into the user's buffer, if given */ if (udata->name) { - HDstrncpy(udata->name, lnk->name, MIN((size_t)(udata->name_len + 1), udata->name_size)); - if ((size_t)udata->name_len >= udata->name_size) + HDstrncpy(udata->name, lnk->name, MIN((udata->name_len + 1), udata->name_size)); + if (udata->name_len >= udata->name_size) udata->name[udata->name_size - 1] = '\0'; } /* end if */ @@ -1106,23 +1106,22 @@ done: * * Purpose: Returns the name of objects in the group by giving index. * - * Return: Success: Non-negative, length of name - * Failure: Negative + * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Sep 19 2006 * *------------------------------------------------------------------------- */ -ssize_t +herr_t H5G__dense_get_name_by_idx(H5F_t *f, H5O_linfo_t *linfo, H5_index_t idx_type, H5_iter_order_t order, - hsize_t n, char *name, size_t size) + hsize_t n, char *name, size_t name_size, size_t *name_len) { - H5HF_t * fheap = NULL; /* Fractal heap handle */ - H5G_link_table_t ltable = {0, NULL}; /* Table of links */ - H5B2_t * bt2 = NULL; /* v2 B-tree handle for index */ - haddr_t bt2_addr; /* Address of v2 B-tree to use for lookup */ - ssize_t ret_value = -1; /* Return value */ + H5HF_t * fheap = NULL; /* Fractal heap handle */ + H5G_link_table_t ltable = {0, NULL}; /* Table of links */ + H5B2_t * bt2 = NULL; /* v2 B-tree handle for index */ + haddr_t bt2_addr; /* Address of v2 B-tree to use for lookup */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -1176,14 +1175,14 @@ H5G__dense_get_name_by_idx(H5F_t *f, H5O_linfo_t *linfo, H5_index_t idx_type, H5 udata.f = f; udata.fheap = fheap; udata.name = name; - udata.name_size = size; + udata.name_size = name_size; /* Retrieve the name according to the v2 B-tree's index order */ if (H5B2_index(bt2, order, n, H5G__dense_get_name_by_idx_bt2_cb, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTLIST, FAIL, "can't locate object in v2 B-tree") /* Set return value */ - ret_value = udata.name_len; + *name_len = udata.name_len; } /* end if */ else { /* Otherwise, we need to build a table of the links and sort it */ /* Build the table of links for this group */ @@ -1195,13 +1194,13 @@ H5G__dense_get_name_by_idx(H5F_t *f, H5O_linfo_t *linfo, H5_index_t idx_type, H5 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "index out of bound") /* Get the length of the name */ - ret_value = (ssize_t)HDstrlen(ltable.lnks[n].name); + *name_len = HDstrlen(ltable.lnks[n].name); /* Copy the name into the user's buffer, if given */ if (name) { - HDstrncpy(name, ltable.lnks[n].name, MIN((size_t)(ret_value + 1), size)); - if ((size_t)ret_value >= size) - name[size - 1] = '\0'; + HDstrncpy(name, ltable.lnks[n].name, MIN((*name_len + 1), name_size)); + if (*name_len >= name_size) + name[name_size - 1] = '\0'; } /* end if */ } /* end else */ diff --git a/src/H5Gdeprec.c b/src/H5Gdeprec.c index 45065e8..7c0404f 100644 --- a/src/H5Gdeprec.c +++ b/src/H5Gdeprec.c @@ -308,7 +308,8 @@ done: herr_t H5Glink(hid_t cur_loc_id, H5G_link_t type, const char *cur_name, const char *new_name) { - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_link_create_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "iLl*s*s", cur_loc_id, type, cur_name, new_name); @@ -326,20 +327,15 @@ H5Glink(hid_t cur_loc_id, H5G_link_t type, const char *cur_name, const char *new /* Create link */ if (type == H5L_TYPE_HARD) { H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params1; - H5VL_loc_params_t loc_params2; + H5VL_loc_params_t new_loc_params; H5VL_object_t tmp_vol_obj; /* Temporary object */ - loc_params1.type = H5VL_OBJECT_BY_NAME; - loc_params1.obj_type = H5I_get_type(cur_loc_id); - loc_params1.loc_data.loc_by_name.name = cur_name; - loc_params1.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; + /* Set up new location struct */ + new_loc_params.type = H5VL_OBJECT_BY_NAME; + new_loc_params.loc_data.loc_by_name.name = new_name; + new_loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; - loc_params2.type = H5VL_OBJECT_BY_NAME; - loc_params2.loc_data.loc_by_name.name = new_name; - loc_params2.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; - - /* get the location object */ + /* Get the location object */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(cur_loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") @@ -347,16 +343,24 @@ H5Glink(hid_t cur_loc_id, H5G_link_t type, const char *cur_name, const char *new tmp_vol_obj.data = NULL; tmp_vol_obj.connector = vol_obj->connector; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_CREATE_HARD; + vol_cb_args.args.hard.curr_obj = vol_obj->data; + vol_cb_args.args.hard.curr_loc_params.type = H5VL_OBJECT_BY_NAME; + vol_cb_args.args.hard.curr_loc_params.obj_type = H5I_get_type(cur_loc_id); + vol_cb_args.args.hard.curr_loc_params.loc_data.loc_by_name.name = cur_name; + vol_cb_args.args.hard.curr_loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; + /* Create the link through the VOL */ - if (H5VL_link_create(H5VL_LINK_CREATE_HARD, &tmp_vol_obj, &loc_params2, H5P_LINK_CREATE_DEFAULT, - H5P_LINK_ACCESS_DEFAULT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - vol_obj->data, &loc_params1) < 0) + if (H5VL_link_create(&vol_cb_args, &tmp_vol_obj, &new_loc_params, H5P_LINK_CREATE_DEFAULT, + H5P_LINK_ACCESS_DEFAULT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") } /* end if */ else if (type == H5L_TYPE_SOFT) { H5VL_object_t * vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; + /* Set up location struct */ loc_params.type = H5VL_OBJECT_BY_NAME; loc_params.loc_data.loc_by_name.name = new_name; loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; @@ -366,10 +370,13 @@ H5Glink(hid_t cur_loc_id, H5G_link_t type, const char *cur_name, const char *new if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(cur_loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_CREATE_SOFT; + vol_cb_args.args.soft.target = cur_name; + /* Create the link through the VOL */ - if (H5VL_link_create(H5VL_LINK_CREATE_SOFT, vol_obj, &loc_params, H5P_LINK_CREATE_DEFAULT, - H5P_LINK_ACCESS_DEFAULT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - cur_name) < 0) + if (H5VL_link_create(&vol_cb_args, vol_obj, &loc_params, H5P_LINK_CREATE_DEFAULT, + H5P_LINK_ACCESS_DEFAULT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") } /* end else-if */ else @@ -390,7 +397,8 @@ done: herr_t H5Glink2(hid_t cur_loc_id, const char *cur_name, H5G_link_t type, hid_t new_loc_id, const char *new_name) { - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_link_create_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "i*sLli*s", cur_loc_id, cur_name, type, new_loc_id, new_name); @@ -409,29 +417,31 @@ H5Glink2(hid_t cur_loc_id, const char *cur_name, H5G_link_t type, hid_t new_loc_ if (type == H5L_TYPE_HARD) { H5VL_object_t * vol_obj1; /* Object of loc_id */ H5VL_object_t * vol_obj2; /* Object of loc_id */ - H5VL_loc_params_t loc_params1; - H5VL_loc_params_t loc_params2; + H5VL_loc_params_t new_loc_params; - loc_params1.type = H5VL_OBJECT_BY_NAME; - loc_params1.obj_type = H5I_get_type(cur_loc_id); - loc_params1.loc_data.loc_by_name.name = cur_name; - loc_params1.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; + /* Set up new location struct */ + new_loc_params.type = H5VL_OBJECT_BY_NAME; + new_loc_params.obj_type = H5I_get_type(new_loc_id); + new_loc_params.loc_data.loc_by_name.name = new_name; + new_loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; - loc_params2.type = H5VL_OBJECT_BY_NAME; - loc_params2.obj_type = H5I_get_type(new_loc_id); - loc_params2.loc_data.loc_by_name.name = new_name; - loc_params2.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; - - /* get the location object */ + /* Get the location objects */ if (NULL == (vol_obj1 = (H5VL_object_t *)H5I_object(cur_loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") if (NULL == (vol_obj2 = (H5VL_object_t *)H5I_object(new_loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_CREATE_HARD; + vol_cb_args.args.hard.curr_obj = vol_obj1->data; + vol_cb_args.args.hard.curr_loc_params.type = H5VL_OBJECT_BY_NAME; + vol_cb_args.args.hard.curr_loc_params.obj_type = H5I_get_type(cur_loc_id); + vol_cb_args.args.hard.curr_loc_params.loc_data.loc_by_name.name = cur_name; + vol_cb_args.args.hard.curr_loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; + /* Create the link through the VOL */ - if (H5VL_link_create(H5VL_LINK_CREATE_HARD, vol_obj2, &loc_params2, H5P_LINK_CREATE_DEFAULT, - H5P_LINK_ACCESS_DEFAULT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - vol_obj1->data, &loc_params1) < 0) + if (H5VL_link_create(&vol_cb_args, vol_obj2, &new_loc_params, H5P_LINK_CREATE_DEFAULT, + H5P_LINK_ACCESS_DEFAULT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") } /* end if */ else if (type == H5L_TYPE_SOFT) { @@ -443,6 +453,7 @@ H5Glink2(hid_t cur_loc_id, const char *cur_name, H5G_link_t type, hid_t new_loc_ if (new_loc_id == H5L_SAME_LOC) new_loc_id = cur_loc_id; + /* Set up location struct */ loc_params.type = H5VL_OBJECT_BY_NAME; loc_params.loc_data.loc_by_name.name = new_name; loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; @@ -452,10 +463,13 @@ H5Glink2(hid_t cur_loc_id, const char *cur_name, H5G_link_t type, hid_t new_loc_ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(new_loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_CREATE_SOFT; + vol_cb_args.args.soft.target = cur_name; + /* Create the link through the VOL */ - if (H5VL_link_create(H5VL_LINK_CREATE_SOFT, vol_obj, &loc_params, H5P_LINK_CREATE_DEFAULT, - H5P_LINK_ACCESS_DEFAULT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - cur_name) < 0) + if (H5VL_link_create(&vol_cb_args, vol_obj, &loc_params, H5P_LINK_CREATE_DEFAULT, + H5P_LINK_ACCESS_DEFAULT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") } /* end else-if */ else @@ -572,9 +586,10 @@ done: herr_t H5Gunlink(hid_t loc_id, const char *name) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*s", loc_id, name); @@ -596,9 +611,11 @@ H5Gunlink(hid_t loc_id, const char *name) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_DELETE; + /* Delete the link */ - if (H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_DELETE, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + if (H5VL_link_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "couldn't delete link") done: @@ -616,9 +633,10 @@ done: herr_t H5Gget_linkval(hid_t loc_id, const char *name, size_t size, char *buf /*out*/) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_link_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "i*szx", loc_id, name, size, buf); @@ -631,6 +649,7 @@ H5Gget_linkval(hid_t loc_id, const char *name, size_t size, char *buf /*out*/) if (H5CX_set_loc(loc_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set collective metadata read info") + /* Set up location struct */ loc_params.type = H5VL_OBJECT_BY_NAME; loc_params.obj_type = H5I_get_type(loc_id); loc_params.loc_data.loc_by_name.name = name; @@ -640,9 +659,13 @@ H5Gget_linkval(hid_t loc_id, const char *name, size_t size, char *buf /*out*/) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_GET_VAL; + vol_cb_args.args.get_val.buf = buf; + vol_cb_args.args.get_val.buf_size = size; + /* Get the link value */ - if (H5VL_link_get(vol_obj, &loc_params, H5VL_LINK_GET_VAL, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, buf, - size) < 0) + if (H5VL_link_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get link value") done: @@ -669,9 +692,11 @@ done: herr_t H5Gset_comment(hid_t loc_id, const char *name, const char *comment) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "i*s*s", loc_id, name, comment); @@ -693,9 +718,14 @@ H5Gset_comment(hid_t loc_id, const char *name, const char *comment) if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + obj_opt_args.set_comment.comment = comment; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_SET_COMMENT; + vol_cb_args.args = &obj_opt_args; + /* Set the comment */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_SET_COMMENT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, comment) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "unable to set comment value") done: @@ -728,10 +758,12 @@ done: int H5Gget_comment(hid_t loc_id, const char *name, size_t bufsize, char *buf /*out*/) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - ssize_t op_ret; /* Return value from operation */ - int ret_value; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5VL_loc_params_t loc_params; + size_t comment_len = 0; /* Length of comment */ + int ret_value; /* Return value */ FUNC_ENTER_API(-1) H5TRACE4("Is", "i*szx", loc_id, name, bufsize, buf); @@ -755,13 +787,20 @@ H5Gget_comment(hid_t loc_id, const char *name, size_t bufsize, char *buf /*out*/ if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, -1, "invalid location identifier") + /* Set up VOL callback arguments */ + obj_opt_args.get_comment.buf = buf; + obj_opt_args.get_comment.buf_size = bufsize; + obj_opt_args.get_comment.comment_len = &comment_len; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_GET_COMMENT; + vol_cb_args.args = &obj_opt_args; + /* Get the comment */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_COMMENT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, buf, bufsize, &op_ret) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, -1, "unable to get comment value") /* Set return value */ - ret_value = (int)op_ret; + ret_value = (int)comment_len; done: FUNC_LEAVE_API(ret_value) @@ -794,12 +833,11 @@ done: herr_t H5Giterate(hid_t loc_id, const char *name, int *idx_p, H5G_iterate_t op, void *op_data) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5G_link_iterate_t lnk_op; /* Link operator */ - hsize_t last_obj; /* Index of last object looked at */ - hsize_t idx; /* Internal location to hold index */ - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_group_optional_args_t grp_opt_args; /* Arguments for optional operation */ + hsize_t last_obj = 0; /* Pointer to index value */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "i*s*IsGi*x", loc_id, name, idx_p, op, op_data); @@ -812,30 +850,28 @@ H5Giterate(hid_t loc_id, const char *name, int *idx_p, H5G_iterate_t op, void *o if (!op) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified") - /* Set number of objects looked at to zero */ - last_obj = 0; - idx = (hsize_t)(idx_p == NULL ? 0 : *idx_p); - - /* Build link operator info */ - lnk_op.op_type = H5G_LINK_OP_OLD; - lnk_op.op_func.op_old = op; - - /* Fill out location struct */ - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.loc_data.loc_by_name.name = name; - loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; - loc_params.obj_type = H5I_get_type(loc_id); - /* Get the object pointer */ if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ID, H5E_BADTYPE, (-1), "invalid identifier") + /* Set up VOL callback arguments */ + grp_opt_args.iterate_old.loc_params.type = H5VL_OBJECT_BY_NAME; + grp_opt_args.iterate_old.loc_params.loc_data.loc_by_name.name = name; + grp_opt_args.iterate_old.loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; + grp_opt_args.iterate_old.loc_params.obj_type = H5I_get_type(loc_id); + grp_opt_args.iterate_old.idx = (hsize_t)(idx_p == NULL ? 0 : *idx_p); + grp_opt_args.iterate_old.last_obj = &last_obj; + grp_opt_args.iterate_old.op = op; + grp_opt_args.iterate_old.op_data = op_data; + vol_cb_args.op_type = H5VL_NATIVE_GROUP_ITERATE_OLD; + vol_cb_args.args = &grp_opt_args; + /* Call private iteration function, through VOL callback */ - if ((ret_value = H5VL_group_optional(vol_obj, H5VL_NATIVE_GROUP_ITERATE_OLD, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, idx, &last_obj, &lnk_op, op_data)) < 0) + if ((ret_value = H5VL_group_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL)) < + 0) HERROR(H5E_SYM, H5E_BADITER, "error iterating over group's links"); - /* Set the index we stopped at */ + /* Set value to return */ if (idx_p) *idx_p = (int)last_obj; @@ -862,11 +898,11 @@ done: herr_t H5Gget_num_objs(hid_t loc_id, hsize_t *num_objs /*out*/) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5I_type_t id_type; /* Type of ID */ - H5VL_loc_params_t loc_params; - H5G_info_t grp_info; /* Group information */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_group_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5I_type_t id_type; /* Type of ID */ + H5G_info_t grp_info; /* Group information */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", loc_id, num_objs); @@ -878,17 +914,14 @@ H5Gget_num_objs(hid_t loc_id, hsize_t *num_objs /*out*/) if (!num_objs) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad pointer to # of objects") - /* Fill in location struct fields */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = id_type; - - /* Get group location */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback & object access arguments */ + vol_cb_args.op_type = H5VL_GROUP_GET_INFO; + if (H5VL_setup_self_args(loc_id, &vol_obj, &vol_cb_args.args.get_info.loc_params) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set object access arguments") + vol_cb_args.args.get_info.ginfo = &grp_info; /* Retrieve the group's information */ - if (H5VL_group_get(vol_obj, H5VL_GROUP_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, - &grp_info) < 0) + if (H5VL_group_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get group info") /* Set the number of objects [i.e. links] in the group */ @@ -918,9 +951,10 @@ done: herr_t H5Gget_objinfo(hid_t loc_id, const char *name, hbool_t follow_link, H5G_stat_t *statbuf /*out*/) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_group_optional_args_t grp_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL); H5TRACE4("e", "i*sbx", loc_id, name, follow_link, statbuf); @@ -933,20 +967,22 @@ H5Gget_objinfo(hid_t loc_id, const char *name, hbool_t follow_link, H5G_stat_t * if (H5CX_set_loc(loc_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set collective metadata read info"); - /* Retrieve object info */ - /* Fill out location struct */ - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.loc_data.loc_by_name.name = name; - loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; - loc_params.obj_type = H5I_get_type(loc_id); - /* Get the location object */ if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier"); + /* Set up VOL callback arguments */ + grp_opt_args.get_objinfo.loc_params.type = H5VL_OBJECT_BY_NAME; + grp_opt_args.get_objinfo.loc_params.loc_data.loc_by_name.name = name; + grp_opt_args.get_objinfo.loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; + grp_opt_args.get_objinfo.loc_params.obj_type = H5I_get_type(loc_id); + grp_opt_args.get_objinfo.follow_link = follow_link; + grp_opt_args.get_objinfo.statbuf = statbuf; + vol_cb_args.op_type = H5VL_NATIVE_GROUP_GET_OBJINFO; + vol_cb_args.args = &grp_opt_args; + /* Retrieve the object's information */ - if (H5VL_group_optional(vol_obj, H5VL_NATIVE_GROUP_GET_OBJINFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &loc_params, (unsigned)follow_link, statbuf) < 0) + if (H5VL_group_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get info for object: '%s'", name); done: @@ -1138,9 +1174,11 @@ done: ssize_t H5Gget_objname_by_idx(hid_t loc_id, hsize_t idx, char *name /*out*/, size_t size) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - ssize_t ret_value; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_link_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + size_t name_len = 0; /* Length of object name */ + ssize_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("Zs", "ihxz", loc_id, idx, name, size); @@ -1149,7 +1187,7 @@ H5Gget_objname_by_idx(hid_t loc_id, hsize_t idx, char *name /*out*/, size_t size if (H5CX_set_loc(loc_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTSET, (-1), "can't set collective metadata read info") - /* Fill in location struct fields */ + /* Set up location struct */ loc_params.type = H5VL_OBJECT_BY_IDX; loc_params.loc_data.loc_by_idx.name = "."; loc_params.loc_data.loc_by_idx.idx_type = H5_INDEX_NAME; @@ -1162,11 +1200,19 @@ H5Gget_objname_by_idx(hid_t loc_id, hsize_t idx, char *name /*out*/, size_t size if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_GET_NAME; + vol_cb_args.args.get_name.name_size = size; + vol_cb_args.args.get_name.name = name; + vol_cb_args.args.get_name.name_len = &name_len; + /* Call internal function */ - if (H5VL_link_get(vol_obj, &loc_params, H5VL_LINK_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - name, size, &ret_value) < 0) + if (H5VL_link_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, (-1), "can't get object name") + /* Set the return value */ + ret_value = (ssize_t)name_len; + done: FUNC_LEAVE_API(ret_value) } /* end H5Gget_objname_by_idx() */ @@ -1189,10 +1235,11 @@ done: H5G_obj_t H5Gget_objtype_by_idx(hid_t loc_id, hsize_t idx) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5O_info2_t oinfo; /* Object info (contains object type) */ - H5G_obj_t ret_value; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + H5O_info2_t oinfo; /* Object info (contains object type) */ + H5G_obj_t ret_value; /* Return value */ FUNC_ENTER_API(H5G_UNKNOWN) H5TRACE2("Go", "ih", loc_id, idx); @@ -1210,9 +1257,13 @@ H5Gget_objtype_by_idx(hid_t loc_id, hsize_t idx) if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_INFO; + vol_cb_args.args.get_info.oinfo = &oinfo; + vol_cb_args.args.get_info.fields = H5O_INFO_BASIC; + /* Retrieve the object's basic information (which includes its type) */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &oinfo, H5O_INFO_BASIC) < 0) + if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, H5G_UNKNOWN, "can't get object info") /* Map to group object type */ diff --git a/src/H5Gloc.c b/src/H5Gloc.c index 7d08b54..2844c66 100644 --- a/src/H5Gloc.c +++ b/src/H5Gloc.c @@ -53,12 +53,6 @@ typedef struct { H5G_loc_t *loc; /* Group location to set */ } H5G_loc_fnd_t; -/* User data for checking if an object exists */ -typedef struct { - /* upward */ - htri_t exists; /* Whether the object exists */ -} H5G_loc_exists_t; - /* User data for looking up an object in a group by index */ typedef struct { /* downward */ @@ -103,7 +97,7 @@ typedef struct { size_t bufsize; /* Size of object comment buffer */ /* upward */ - ssize_t comment_size; /* Actual size of object comment */ + size_t comment_size; /* Actual size of object comment */ } H5G_loc_gc_t; /********************/ @@ -616,24 +610,26 @@ H5G__loc_exists_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc /*in*/, const char H5_ATTR_ const H5O_link_t H5_ATTR_UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata /*in,out*/, H5G_own_loc_t *own_loc /*out*/) { - H5G_loc_exists_t *udata = (H5G_loc_exists_t *)_udata; /* User data passed in */ + hbool_t *exists = (hbool_t *)_udata; /* User data passed in */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC_NOERR + FUNC_ENTER_STATIC /* Check if the name in this group resolved to a valid object */ if (obj_loc == NULL) if (lnk) - udata->exists = FALSE; + *exists = FALSE; else - udata->exists = FAIL; + HGOTO_ERROR(H5E_SYM, H5E_INTERNAL, FAIL, "no object or link info?") else - udata->exists = TRUE; + *exists = TRUE; /* Indicate that this callback didn't take ownership of the group * * location for the object */ *own_loc = H5G_OWN_NONE; - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G__loc_exists_cb() */ /*------------------------------------------------------------------------- @@ -649,28 +645,22 @@ H5G__loc_exists_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc /*in*/, const char H5_ATTR_ * *------------------------------------------------------------------------- */ -htri_t -H5G_loc_exists(const H5G_loc_t *loc, const char *name) +herr_t +H5G_loc_exists(const H5G_loc_t *loc, const char *name, hbool_t *exists) { - H5G_loc_exists_t udata; /* User data for traversal callback */ - htri_t ret_value = FAIL; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Check args. */ HDassert(loc); HDassert(name && *name); - - /* Set up user data for locating object */ - udata.exists = FALSE; + HDassert(exists); /* Traverse group hierarchy to locate object */ - if (H5G_traverse(loc, name, H5G_TARGET_EXISTS, H5G__loc_exists_cb, &udata) < 0) + if (H5G_traverse(loc, name, H5G_TARGET_EXISTS, H5G__loc_exists_cb, exists) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't check if object exists") - /* Set return value */ - ret_value = udata.exists; - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc_exists() */ @@ -1024,7 +1014,7 @@ H5G__loc_get_comment_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc /*in*/, const char H5_ else { if (udata->comment && udata->bufsize) HDstrncpy(udata->comment, comment.s, udata->bufsize); - udata->comment_size = (ssize_t)HDstrlen(comment.s); + udata->comment_size = HDstrlen(comment.s); H5O_msg_reset(H5O_NAME_ID, &comment); } @@ -1043,22 +1033,19 @@ done: * Purpose: Retrieve the information for an object from a group location * and path to that object * - * Return: Success: Number of bytes in the comment excluding the - * null terminator. Zero if the object has no - * comment. - * - * Failure: Negative + * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Thursday, August 30, 2007 * *------------------------------------------------------------------------- */ -ssize_t -H5G_loc_get_comment(const H5G_loc_t *loc, const char *name, char *comment /*out*/, size_t bufsize) +herr_t +H5G_loc_get_comment(const H5G_loc_t *loc, const char *name, char *comment /*out*/, size_t bufsize, + size_t *comment_len) { - H5G_loc_gc_t udata; /* User data for traversal callback */ - ssize_t ret_value = -1; /* Return value */ + H5G_loc_gc_t udata; /* User data for traversal callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -1069,14 +1056,15 @@ H5G_loc_get_comment(const H5G_loc_t *loc, const char *name, char *comment /*out* /* Set up user data for locating object */ udata.comment = comment; udata.bufsize = bufsize; - udata.comment_size = (-1); + udata.comment_size = 0; /* Traverse group hierarchy to locate object */ if (H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G__loc_get_comment_cb, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object") - /* Set the return value */ - ret_value = udata.comment_size; + /* Set value to return */ + if (comment_len) + *comment_len = udata.comment_size; done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Gmodule.h b/src/H5Gmodule.h index fe26bd2..a0e121d 100644 --- a/src/H5Gmodule.h +++ b/src/H5Gmodule.h @@ -29,8 +29,29 @@ #define H5_MY_PKG_ERR H5E_SYM #define H5_MY_PKG_INIT YES -/** - * \defgroup H5G H5G +/** \defgroup H5G H5G + * + * Use the functions in this module to manage HDF5 groups. + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5G_examples.c create + * </td> + * <td> + * \snippet{lineno} H5G_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5G_examples.c update + * </td> + * <td> + * \snippet{lineno} H5G_examples.c delete + * </td> + * </tr> + * </table> * * \details \Bold{Groups in HDF5:} A group associates names with objects and * provides a mechanism for mapping a name to an object. Since all diff --git a/src/H5Gname.c b/src/H5Gname.c index 2465f01..c139a4e 100644 --- a/src/H5Gname.c +++ b/src/H5Gname.c @@ -468,11 +468,10 @@ H5G_name_copy(H5G_name_t *dst, const H5G_name_t *src, H5_copy_depth_t depth) * *------------------------------------------------------------------------- */ -ssize_t -H5G_get_name(const H5G_loc_t *loc, char *name /*out*/, size_t size, hbool_t *cached) +herr_t +H5G_get_name(const H5G_loc_t *loc, char *name /*out*/, size_t size, size_t *name_len, hbool_t *cached) { - ssize_t len = 0; /* Length of object's name */ - ssize_t ret_value = -1; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -481,14 +480,20 @@ H5G_get_name(const H5G_loc_t *loc, char *name /*out*/, size_t size, hbool_t *cac /* If the user path is available and it's not "hidden", use it */ if (loc->path->user_path_r != NULL && loc->path->obj_hidden == 0) { + size_t len; /* Length of object's name */ + len = H5RS_len(loc->path->user_path_r); if (name) { - HDstrncpy(name, H5RS_get_str(loc->path->user_path_r), MIN((size_t)(len + 1), size)); - if ((size_t)len >= size) + HDstrncpy(name, H5RS_get_str(loc->path->user_path_r), MIN((len + 1), size)); + if (len >= size) name[size - 1] = '\0'; } /* end if */ + /* Set name length, if requested */ + if (name_len) + *name_len = len; + /* Indicate that the name is cached, if requested */ /* (Currently only used for testing - QAK, 2010/07/26) */ if (cached) @@ -496,7 +501,7 @@ H5G_get_name(const H5G_loc_t *loc, char *name /*out*/, size_t size, hbool_t *cac } /* end if */ else if (!loc->path->obj_hidden) { /* Search for name of object */ - if ((len = H5G_get_name_by_addr(loc->oloc->file, loc->oloc, name, size)) < 0) + if (H5G_get_name_by_addr(loc->oloc->file, loc->oloc, name, size, name_len) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't determine name") /* Indicate that the name is _not_ cached, if requested */ @@ -505,9 +510,6 @@ H5G_get_name(const H5G_loc_t *loc, char *name /*out*/, size_t size, hbool_t *cac *cached = FALSE; } /* end else */ - /* Set return value */ - ret_value = len; - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_get_name() */ @@ -1152,28 +1154,29 @@ done: * *------------------------------------------------------------------------- */ -ssize_t -H5G_get_name_by_addr(H5F_t *f, const H5O_loc_t *loc, char *name, size_t size) +herr_t +H5G_get_name_by_addr(H5F_t *f, const H5O_loc_t *loc, char *name, size_t size, size_t *name_len) { - H5G_gnba_iter_t udata; /* User data for iteration */ - H5G_loc_t root_loc; /* Root group's location */ - hbool_t found_obj = FALSE; /* If we found the object */ - herr_t status; /* Status from iteration */ - ssize_t ret_value = -1; /* Return value */ + H5G_gnba_iter_t udata; /* User data for iteration */ + size_t len; /* Length of path name */ + H5G_loc_t root_loc; /* Root group's location */ + hbool_t found_obj = FALSE; /* If we found the object */ + herr_t status; /* Status from iteration */ + herr_t ret_value = SUCCEED; /* Return value */ /* Portably clear udata struct (before FUNC_ENTER) */ HDmemset(&udata, 0, sizeof(udata)); - FUNC_ENTER_NOAPI((-1)) + FUNC_ENTER_NOAPI(FAIL) /* Construct a group location for root group of the file */ if (H5G_root_loc(f, &root_loc) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTGET, (-1), "can't get root group's location") + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get root group's location") /* Check for root group being the object looked for */ if (root_loc.oloc->addr == loc->addr && root_loc.oloc->file == loc->file) { if (NULL == (udata.path = H5MM_strdup(""))) - HGOTO_ERROR(H5E_SYM, H5E_CANTALLOC, (-1), "can't duplicate path string") + HGOTO_ERROR(H5E_SYM, H5E_CANTALLOC, FAIL, "can't duplicate path string") found_obj = TRUE; } /* end if */ else { @@ -1184,7 +1187,7 @@ H5G_get_name_by_addr(H5F_t *f, const H5O_loc_t *loc, char *name, size_t size) /* Visit all the links in the file */ if ((status = H5G_visit(&root_loc, "/", H5_INDEX_NAME, H5_ITER_NATIVE, H5G__get_name_by_addr_cb, &udata)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_BADITER, (-1), "group traversal failed while looking for object name") + HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "group traversal failed while looking for object name") else if (status > 0) found_obj = TRUE; } /* end else */ @@ -1192,7 +1195,7 @@ H5G_get_name_by_addr(H5F_t *f, const H5O_loc_t *loc, char *name, size_t size) /* Check for finding the object */ if (found_obj) { /* Set the length of the full path */ - ret_value = (ssize_t)(HDstrlen(udata.path) + 1); /* Length of path + 1 (for "/") */ + len = HDstrlen(udata.path) + 1; /* Length of path + 1 (for "/") */ /* If there's a buffer provided, copy into it, up to the limit of its size */ if (name) { @@ -1202,12 +1205,16 @@ H5G_get_name_by_addr(H5F_t *f, const H5O_loc_t *loc, char *name, size_t size) /* Append the rest of the path */ /* (less one character, for the initial path separator) */ HDstrncat(name, udata.path, (size - 2)); - if ((size_t)ret_value >= size) + if (len >= size) name[size - 1] = '\0'; } /* end if */ } /* end if */ else - ret_value = 0; + len = 0; + + /* Set path name length, if given */ + if (name_len) + *name_len = len; done: /* Release resources */ diff --git a/src/H5Gobj.c b/src/H5Gobj.c index 1ca6b14..66917c2 100644 --- a/src/H5Gobj.c +++ b/src/H5Gobj.c @@ -767,13 +767,13 @@ done: * *------------------------------------------------------------------------- */ -ssize_t +herr_t H5G_obj_get_name_by_idx(const H5O_loc_t *oloc, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, - char *name, size_t size) + char *name, size_t name_size, size_t *name_len) { - H5O_linfo_t linfo; /* Link info message */ - htri_t linfo_exists; /* Whether the link info message exists */ - ssize_t ret_value = -1; /* Return value */ + H5O_linfo_t linfo; /* Link info message */ + htri_t linfo_exists; /* Whether the link info message exists */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_TAG(oloc->addr, FAIL) @@ -785,22 +785,21 @@ H5G_obj_get_name_by_idx(const H5O_loc_t *oloc, H5_index_t idx_type, H5_iter_orde HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't check for link info message") if (linfo_exists) { /* Check for creation order tracking, if creation order index lookup requested */ - if (idx_type == H5_INDEX_CRT_ORDER) { + if (idx_type == H5_INDEX_CRT_ORDER) /* Check if creation order is tracked */ if (!linfo.track_corder) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "creation order not tracked for links in group") - } /* end if */ /* Check for dense link storage */ if (H5F_addr_defined(linfo.fheap_addr)) { /* Get the object's name from the dense link storage */ - if ((ret_value = H5G__dense_get_name_by_idx(oloc->file, &linfo, idx_type, order, n, name, size)) < - 0) + if (H5G__dense_get_name_by_idx(oloc->file, &linfo, idx_type, order, n, name, name_size, + name_len) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate name") } /* end if */ else { /* Get the object's name from the link messages */ - if ((ret_value = H5G__compact_get_name_by_idx(oloc, &linfo, idx_type, order, n, name, size)) < 0) + if (H5G__compact_get_name_by_idx(oloc, &linfo, idx_type, order, n, name, name_size, name_len) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate name") } /* end else */ } /* end if */ @@ -810,7 +809,7 @@ H5G_obj_get_name_by_idx(const H5O_loc_t *oloc, H5_index_t idx_type, H5_iter_orde HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "no creation order index to query") /* Get the object's name from the symbol table */ - if ((ret_value = H5G__stab_get_name_by_idx(oloc, order, n, name, size)) < 0) + if (H5G__stab_get_name_by_idx(oloc, order, n, name, name_size, name_len) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate name") } /* end else */ diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index a5efd48..d108b03 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -358,14 +358,14 @@ H5_DLL herr_t H5G__stab_iterate(const H5O_loc_t *oloc, H5_iter_order_t order, hs H5G_lib_iterate_t op, void *op_data); H5_DLL herr_t H5G__stab_count(const struct H5O_loc_t *oloc, hsize_t *num_objs); H5_DLL herr_t H5G__stab_bh_size(H5F_t *f, const H5O_stab_t *stab, H5_ih_info_t *bh_info); -H5_DLL ssize_t H5G__stab_get_name_by_idx(const H5O_loc_t *oloc, H5_iter_order_t order, hsize_t n, char *name, - size_t size); -H5_DLL herr_t H5G__stab_remove(const H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, const char *name); -H5_DLL herr_t H5G__stab_remove_by_idx(const H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, - H5_iter_order_t order, hsize_t n); -H5_DLL herr_t H5G__stab_lookup(const H5O_loc_t *grp_oloc, const char *name, hbool_t *found, H5O_link_t *lnk); -H5_DLL herr_t H5G__stab_lookup_by_idx(const H5O_loc_t *grp_oloc, H5_iter_order_t order, hsize_t n, - H5O_link_t *lnk); +H5_DLL herr_t H5G__stab_get_name_by_idx(const H5O_loc_t *oloc, H5_iter_order_t order, hsize_t n, char *name, + size_t name_size, size_t *name_len); +H5_DLL herr_t H5G__stab_remove(const H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, const char *name); +H5_DLL herr_t H5G__stab_remove_by_idx(const H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, + H5_iter_order_t order, hsize_t n); +H5_DLL herr_t H5G__stab_lookup(const H5O_loc_t *grp_oloc, const char *name, hbool_t *found, H5O_link_t *lnk); +H5_DLL herr_t H5G__stab_lookup_by_idx(const H5O_loc_t *grp_oloc, H5_iter_order_t order, hsize_t n, + H5O_link_t *lnk); #ifndef H5_STRICT_FORMAT_CHECKS H5_DLL herr_t H5G__stab_valid(H5O_loc_t *grp_oloc, H5O_stab_t *alt_stab); #endif /* H5_STRICT_FORMAT_CHECKS */ @@ -405,41 +405,42 @@ H5_DLL herr_t H5G__link_release_table(H5G_link_table_t *ltable); H5_DLL herr_t H5G__link_name_replace(H5F_t *file, H5RS_str_t *grp_full_path_r, const H5O_link_t *lnk); /* Functions that understand "compact" link storage */ -H5_DLL herr_t H5G__compact_insert(const H5O_loc_t *grp_oloc, H5O_link_t *obj_lnk); -H5_DLL ssize_t H5G__compact_get_name_by_idx(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, - H5_index_t idx_type, H5_iter_order_t order, hsize_t idx, - char *name, size_t size); -H5_DLL herr_t H5G__compact_remove(const H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, const char *name); -H5_DLL herr_t H5G__compact_remove_by_idx(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, - H5RS_str_t *grp_full_path_r, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n); -H5_DLL herr_t H5G__compact_iterate(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, H5_index_t idx_type, - H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, - H5G_lib_iterate_t op, void *op_data); -H5_DLL herr_t H5G__compact_lookup(const H5O_loc_t *grp_oloc, const char *name, hbool_t *found, - H5O_link_t *lnk); +H5_DLL herr_t H5G__compact_insert(const H5O_loc_t *grp_oloc, H5O_link_t *obj_lnk); +H5_DLL herr_t H5G__compact_get_name_by_idx(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, + H5_index_t idx_type, H5_iter_order_t order, hsize_t idx, + char *name, size_t name_size, size_t *name_len); +H5_DLL herr_t H5G__compact_remove(const H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, const char *name); +H5_DLL herr_t H5G__compact_remove_by_idx(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, + H5RS_str_t *grp_full_path_r, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n); +H5_DLL herr_t H5G__compact_iterate(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, H5_index_t idx_type, + H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, + H5G_lib_iterate_t op, void *op_data); +H5_DLL herr_t H5G__compact_lookup(const H5O_loc_t *grp_oloc, const char *name, hbool_t *found, + H5O_link_t *lnk); H5_DLL herr_t H5G__compact_lookup_by_idx(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_link_t *lnk); /* Functions that understand "dense" link storage */ -H5_DLL herr_t H5G__dense_build_table(H5F_t *f, const H5O_linfo_t *linfo, H5_index_t idx_type, - H5_iter_order_t order, H5G_link_table_t *ltable); -H5_DLL herr_t H5G__dense_create(H5F_t *f, H5O_linfo_t *linfo, const H5O_pline_t *pline); -H5_DLL herr_t H5G__dense_insert(H5F_t *f, const H5O_linfo_t *linfo, const H5O_link_t *lnk); -H5_DLL herr_t H5G__dense_lookup(H5F_t *f, const H5O_linfo_t *linfo, const char *name, hbool_t *found, - H5O_link_t *lnk); -H5_DLL herr_t H5G__dense_lookup_by_idx(H5F_t *f, const H5O_linfo_t *linfo, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, H5O_link_t *lnk); -H5_DLL herr_t H5G__dense_iterate(H5F_t *f, const H5O_linfo_t *linfo, H5_index_t idx_type, - H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, H5G_lib_iterate_t op, - void *op_data); -H5_DLL ssize_t H5G__dense_get_name_by_idx(H5F_t *f, H5O_linfo_t *linfo, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, char *name, size_t size); -H5_DLL herr_t H5G__dense_remove(H5F_t *f, const H5O_linfo_t *linfo, H5RS_str_t *grp_full_path_r, - const char *name); -H5_DLL herr_t H5G__dense_remove_by_idx(H5F_t *f, const H5O_linfo_t *linfo, H5RS_str_t *grp_full_path_r, - H5_index_t idx_type, H5_iter_order_t order, hsize_t n); -H5_DLL herr_t H5G__dense_delete(H5F_t *f, H5O_linfo_t *linfo, hbool_t adj_link); +H5_DLL herr_t H5G__dense_build_table(H5F_t *f, const H5O_linfo_t *linfo, H5_index_t idx_type, + H5_iter_order_t order, H5G_link_table_t *ltable); +H5_DLL herr_t H5G__dense_create(H5F_t *f, H5O_linfo_t *linfo, const H5O_pline_t *pline); +H5_DLL herr_t H5G__dense_insert(H5F_t *f, const H5O_linfo_t *linfo, const H5O_link_t *lnk); +H5_DLL herr_t H5G__dense_lookup(H5F_t *f, const H5O_linfo_t *linfo, const char *name, hbool_t *found, + H5O_link_t *lnk); +H5_DLL herr_t H5G__dense_lookup_by_idx(H5F_t *f, const H5O_linfo_t *linfo, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, H5O_link_t *lnk); +H5_DLL herr_t H5G__dense_iterate(H5F_t *f, const H5O_linfo_t *linfo, H5_index_t idx_type, + H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, H5G_lib_iterate_t op, + void *op_data); +H5_DLL herr_t H5G__dense_get_name_by_idx(H5F_t *f, H5O_linfo_t *linfo, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, char *name, size_t name_size, + size_t *name_len); +H5_DLL herr_t H5G__dense_remove(H5F_t *f, const H5O_linfo_t *linfo, H5RS_str_t *grp_full_path_r, + const char *name); +H5_DLL herr_t H5G__dense_remove_by_idx(H5F_t *f, const H5O_linfo_t *linfo, H5RS_str_t *grp_full_path_r, + H5_index_t idx_type, H5_iter_order_t order, hsize_t n); +H5_DLL herr_t H5G__dense_delete(H5F_t *f, H5O_linfo_t *linfo, hbool_t adj_link); /* Functions that understand group objects */ H5_DLL herr_t H5G__obj_create(H5F_t *f, H5G_obj_create_t *gcrt_info, H5O_loc_t *oloc /*out*/); diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index 409d790..4cf4623 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -144,7 +144,7 @@ struct H5O_link_t; * The "location" of an object in a group hierarchy. This points to an object * location and a group hierarchy path for the object. */ -typedef struct { +typedef struct H5G_loc_t { struct H5O_loc_t *oloc; /* Object header location */ H5G_name_t * path; /* Group hierarchy path */ } H5G_loc_t; @@ -227,16 +227,17 @@ H5_DLL herr_t H5G_link_to_info(const struct H5O_loc_t *link_loc, const struct H5 /* * Functions that understand group objects */ -H5_DLL herr_t H5G_obj_insert(const struct H5O_loc_t *grp_oloc, const char *name, struct H5O_link_t *obj_lnk, - hbool_t adj_link, H5O_type_t obj_type, const void *crt_info); -H5_DLL ssize_t H5G_obj_get_name_by_idx(const struct H5O_loc_t *oloc, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, char *name, size_t size); -H5_DLL herr_t H5G_obj_remove(const struct H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, const char *name); -H5_DLL herr_t H5G_obj_remove_by_idx(const struct H5O_loc_t *grp_oloc, H5RS_str_t *grp_full_path_r, - H5_index_t idx_type, H5_iter_order_t order, hsize_t n); -H5_DLL herr_t H5G_obj_lookup_by_idx(const struct H5O_loc_t *grp_oloc, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, struct H5O_link_t *lnk); -H5_DLL hid_t H5G_get_create_plist(const H5G_t *grp); +H5_DLL herr_t H5G_obj_insert(const struct H5O_loc_t *grp_oloc, const char *name, struct H5O_link_t *obj_lnk, + hbool_t adj_link, H5O_type_t obj_type, const void *crt_info); +H5_DLL herr_t H5G_obj_get_name_by_idx(const struct H5O_loc_t *oloc, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, char *name, size_t name_size, + size_t *name_len); +H5_DLL herr_t H5G_obj_remove(const struct H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, const char *name); +H5_DLL herr_t H5G_obj_remove_by_idx(const struct H5O_loc_t *grp_oloc, H5RS_str_t *grp_full_path_r, + H5_index_t idx_type, H5_iter_order_t order, hsize_t n); +H5_DLL herr_t H5G_obj_lookup_by_idx(const struct H5O_loc_t *grp_oloc, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, struct H5O_link_t *lnk); +H5_DLL hid_t H5G_get_create_plist(const H5G_t *grp); /* * These functions operate on symbol table nodes. @@ -253,35 +254,37 @@ H5_DLL herr_t H5G_ent_decode(const H5F_t *f, const uint8_t **pp, H5G_entry_t *en /* * These functions operate on group hierarchy names. */ -H5_DLL herr_t H5G_name_set(const H5G_name_t *loc, H5G_name_t *obj, const char *name); -H5_DLL herr_t H5G_name_replace(const struct H5O_link_t *lnk, H5G_names_op_t op, H5F_t *src_file, - H5RS_str_t *src_full_path_r, H5F_t *dst_file, H5RS_str_t *dst_full_path_r); -H5_DLL herr_t H5G_name_reset(H5G_name_t *name); -H5_DLL herr_t H5G_name_copy(H5G_name_t *dst, const H5G_name_t *src, H5_copy_depth_t depth); -H5_DLL herr_t H5G_name_free(H5G_name_t *name); -H5_DLL ssize_t H5G_get_name(const H5G_loc_t *loc, char *name /*out*/, size_t size, hbool_t *cached); -H5_DLL ssize_t H5G_get_name_by_addr(H5F_t *f, const struct H5O_loc_t *loc, char *name, size_t size); +H5_DLL herr_t H5G_name_set(const H5G_name_t *loc, H5G_name_t *obj, const char *name); +H5_DLL herr_t H5G_name_replace(const struct H5O_link_t *lnk, H5G_names_op_t op, H5F_t *src_file, + H5RS_str_t *src_full_path_r, H5F_t *dst_file, H5RS_str_t *dst_full_path_r); +H5_DLL herr_t H5G_name_reset(H5G_name_t *name); +H5_DLL herr_t H5G_name_copy(H5G_name_t *dst, const H5G_name_t *src, H5_copy_depth_t depth); +H5_DLL herr_t H5G_name_free(H5G_name_t *name); +H5_DLL herr_t H5G_get_name(const H5G_loc_t *loc, char *name /*out*/, size_t size, size_t *name_len, + hbool_t *cached); +H5_DLL herr_t H5G_get_name_by_addr(H5F_t *f, const struct H5O_loc_t *loc, char *name, size_t size, + size_t *name_len); H5_DLL H5RS_str_t *H5G_build_fullpath_refstr_str(H5RS_str_t *path_r, const char *name); /* * These functions operate on group "locations" */ -H5_DLL herr_t H5G_loc_real(void *obj, H5I_type_t type, H5G_loc_t *loc); -H5_DLL herr_t H5G_loc(hid_t loc_id, H5G_loc_t *loc); -H5_DLL herr_t H5G_loc_copy(H5G_loc_t *dst, const H5G_loc_t *src, H5_copy_depth_t depth); -H5_DLL herr_t H5G_loc_find(const H5G_loc_t *loc, const char *name, H5G_loc_t *obj_loc /*out*/); -H5_DLL herr_t H5G_loc_find_by_idx(const H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, H5G_loc_t *obj_loc /*out*/); -H5_DLL htri_t H5G_loc_exists(const H5G_loc_t *loc, const char *name); -H5_DLL herr_t H5G_loc_info(const H5G_loc_t *loc, const char *name, H5O_info2_t *oinfo /*out*/, - unsigned fields); -H5_DLL herr_t H5G_loc_native_info(const H5G_loc_t *loc, const char *name, H5O_native_info_t *oinfo /*out*/, - unsigned fields); -H5_DLL herr_t H5G_loc_set_comment(const H5G_loc_t *loc, const char *name, const char *comment); -H5_DLL ssize_t H5G_loc_get_comment(const H5G_loc_t *loc, const char *name, char *comment /*out*/, - size_t bufsize); -H5_DLL herr_t H5G_loc_reset(H5G_loc_t *loc); -H5_DLL herr_t H5G_loc_free(H5G_loc_t *loc); +H5_DLL herr_t H5G_loc_real(void *obj, H5I_type_t type, H5G_loc_t *loc); +H5_DLL herr_t H5G_loc(hid_t loc_id, H5G_loc_t *loc); +H5_DLL herr_t H5G_loc_copy(H5G_loc_t *dst, const H5G_loc_t *src, H5_copy_depth_t depth); +H5_DLL herr_t H5G_loc_find(const H5G_loc_t *loc, const char *name, H5G_loc_t *obj_loc /*out*/); +H5_DLL herr_t H5G_loc_find_by_idx(const H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, H5G_loc_t *obj_loc /*out*/); +H5_DLL herr_t H5G_loc_exists(const H5G_loc_t *loc, const char *name, hbool_t *exists); +H5_DLL herr_t H5G_loc_info(const H5G_loc_t *loc, const char *name, H5O_info2_t *oinfo /*out*/, + unsigned fields); +H5_DLL herr_t H5G_loc_native_info(const H5G_loc_t *loc, const char *name, H5O_native_info_t *oinfo /*out*/, + unsigned fields); +H5_DLL herr_t H5G_loc_set_comment(const H5G_loc_t *loc, const char *name, const char *comment); +H5_DLL herr_t H5G_loc_get_comment(const H5G_loc_t *loc, const char *name, char *comment /*out*/, + size_t bufsize, size_t *comment_len); +H5_DLL herr_t H5G_loc_reset(H5G_loc_t *loc); +H5_DLL herr_t H5G_loc_free(H5G_loc_t *loc); /* * These functions operate on the root group diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h index b009d41..d9c29f6 100644 --- a/src/H5Gpublic.h +++ b/src/H5Gpublic.h @@ -467,6 +467,7 @@ H5_DLL herr_t H5Gclose(hid_t group_id); H5_DLL herr_t H5Gclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t group_id, hid_t es_id); +/// \cond DEV /* API Wrappers for async routines */ /* (Must be defined _after_ the function prototype) */ /* (And must only defined when included in application code, not the library) */ @@ -488,6 +489,7 @@ H5_DLL herr_t H5Gclose_async(const char *app_file, const char *app_func, unsigne #define H5Gget_info_by_idx_async_wrap H5_NO_EXPAND(H5Gget_info_by_idx_async) #define H5Gclose_async_wrap H5_NO_EXPAND(H5Gclose_async) #endif /* H5G_MODULE */ +/// \endcond /* Symbols defined for compatibility with previous versions of the HDF5 API. * diff --git a/src/H5Gstab.c b/src/H5Gstab.c index bf4b417..ca74aa5 100644 --- a/src/H5Gstab.c +++ b/src/H5Gstab.c @@ -705,22 +705,22 @@ done: * * Purpose: Returns the name of objects in the group by giving index. * - * Return: Success: Non-negative, length of name - * Failure: Negative + * Return: Non-negative on success/Negative on failure * * Programmer: Raymond Lu * Nov 20, 2002 * *------------------------------------------------------------------------- */ -ssize_t -H5G__stab_get_name_by_idx(const H5O_loc_t *oloc, H5_iter_order_t order, hsize_t n, char *name, size_t size) +herr_t +H5G__stab_get_name_by_idx(const H5O_loc_t *oloc, H5_iter_order_t order, hsize_t n, char *name, + size_t name_size, size_t *name_len) { - H5HL_t * heap = NULL; /* Pointer to local heap */ - H5O_stab_t stab; /* Info about local heap & B-tree */ - H5G_bt_it_gnbi_t udata; /* Iteration information */ - hbool_t udata_valid = FALSE; /* Whether iteration information is valid */ - ssize_t ret_value = -1; /* Return value */ + H5HL_t * heap = NULL; /* Pointer to local heap */ + H5O_stab_t stab; /* Info about local heap & B-tree */ + H5G_bt_it_gnbi_t udata; /* Iteration information */ + hbool_t udata_valid = FALSE; /* Whether iteration information is valid */ + herr_t ret_value = SUCCEED; /* Return value */ /* Portably clear udata struct (before FUNC_ENTER) */ HDmemset(&udata, 0, sizeof(udata)); @@ -767,13 +767,13 @@ H5G__stab_get_name_by_idx(const H5O_loc_t *oloc, H5_iter_order_t order, hsize_t HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "index out of bound") /* Get the length of the name */ - ret_value = (ssize_t)HDstrlen(udata.name); + *name_len = HDstrlen(udata.name); /* Copy the name into the user's buffer, if given */ if (name) { - HDstrncpy(name, udata.name, MIN((size_t)(ret_value + 1), size)); - if ((size_t)ret_value >= size) - name[size - 1] = '\0'; + HDstrncpy(name, udata.name, MIN((*name_len + 1), name_size)); + if (*name_len >= name_size) + name[name_size - 1] = '\0'; } /* end if */ done: diff --git a/src/H5Gtest.c b/src/H5Gtest.c index 9f0dca2..7ae41ed 100644 --- a/src/H5Gtest.c +++ b/src/H5Gtest.c @@ -616,14 +616,14 @@ H5G__user_path_test(hid_t obj_id, char *user_path, size_t *user_path_len, unsign /* Retrieve a copy of the user path and put it into the buffer */ if (obj_path->user_path_r) { - ssize_t len = H5RS_len(obj_path->user_path_r); + size_t len = H5RS_len(obj_path->user_path_r); /* Set the user path, if given */ if (user_path) - HDstrncpy(user_path, H5RS_get_str(obj_path->user_path_r), (size_t)(len + 1)); + HDstrncpy(user_path, H5RS_get_str(obj_path->user_path_r), (len + 1)); /* Set the length of the path */ - *user_path_len = (size_t)len; + *user_path_len = len; /* Set the user path hidden flag */ *obj_hidden = obj_path->obj_hidden; diff --git a/src/H5I.c b/src/H5I.c index 1973354..954a86b 100644 --- a/src/H5I.c +++ b/src/H5I.c @@ -925,9 +925,11 @@ done: ssize_t H5Iget_name(hid_t id, char *name /*out*/, size_t size) { - H5VL_object_t * vol_obj = NULL; /* Object stored in ID */ - H5VL_loc_params_t loc_params; - ssize_t ret_value = -1; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object stored in ID */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + size_t obj_name_len = 0; /* Length of object's name */ + ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE3("Zs", "ixz", id, name, size); @@ -940,11 +942,19 @@ H5Iget_name(hid_t id, char *name /*out*/, size_t size) loc_params.type = H5VL_OBJECT_BY_SELF; loc_params.obj_type = H5I_get_type(id); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_NAME; + vol_cb_args.args.get_name.buf_size = size; + vol_cb_args.args.get_name.buf = name; + vol_cb_args.args.get_name.name_len = &obj_name_len; + /* Retrieve object's name */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &ret_value, name, size) < 0) + if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ID, H5E_CANTGET, (-1), "can't retrieve object name") + /* Set return value */ + ret_value = (ssize_t)obj_name_len; + done: FUNC_LEAVE_API(ret_value) } /* end H5Iget_name() */ diff --git a/src/H5Idbg.c b/src/H5Idbg.c index 7b5eb5a..8bf8ecb 100644 --- a/src/H5Idbg.c +++ b/src/H5Idbg.c @@ -110,9 +110,9 @@ H5I__id_dump_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) case H5I_DATATYPE: { const H5T_t *dt = (const H5T_t *)info->object; - H5_GCC_DIAG_OFF("cast-qual") + H5_GCC_CLANG_DIAG_OFF("cast-qual") object = (void *)H5T_get_actual_type((H5T_t *)dt); /* Casting away const OK - QAK */ - H5_GCC_DIAG_ON("cast-qual") + H5_GCC_CLANG_DIAG_ON("cast-qual") path = H5T_nameof((const H5T_t *)object); break; diff --git a/src/H5Iint.c b/src/H5Iint.c index 164fafc..86a2810 100644 --- a/src/H5Iint.c +++ b/src/H5Iint.c @@ -391,7 +391,7 @@ H5I__mark_node(void *_info, void H5_ATTR_UNUSED *key, void *_udata) */ if (udata->force || (info->count - (!udata->app_ref * info->app_count)) <= 1) { /* Check if this is an un-realized future object */ - H5_GCC_DIAG_OFF("cast-qual") + H5_GCC_CLANG_DIAG_OFF("cast-qual") if (info->is_future) { /* Discard the future object */ if ((info->discard_cb)((void *)info->object) < 0) { @@ -437,7 +437,7 @@ H5I__mark_node(void *_info, void H5_ATTR_UNUSED *key, void *_udata) mark = TRUE; } } - H5_GCC_DIAG_ON("cast-qual") + H5_GCC_CLANG_DIAG_ON("cast-qual") /* Remove ID if requested */ if (mark) { @@ -705,9 +705,9 @@ H5I_subst(hid_t id, const void *new_object) HGOTO_ERROR(H5E_ID, H5E_NOTFOUND, NULL, "can't get ID ref count") /* Get the old object pointer to return */ - H5_GCC_DIAG_OFF("cast-qual") + H5_GCC_CLANG_DIAG_OFF("cast-qual") ret_value = (void *)info->object; /* (Casting away const OK -QAK) */ - H5_GCC_DIAG_ON("cast-qual") + H5_GCC_CLANG_DIAG_ON("cast-qual") /* Set the new object pointer for the ID */ info->object = new_object; @@ -739,9 +739,9 @@ H5I_object(hid_t id) /* General lookup of the ID */ if (NULL != (info = H5I__find_id(id))) { /* Get the object pointer to return */ - H5_GCC_DIAG_OFF("cast-qual") + H5_GCC_CLANG_DIAG_OFF("cast-qual") ret_value = (void *)info->object; /* (Casting away const OK -QAK) */ - H5_GCC_DIAG_ON("cast-qual") + H5_GCC_CLANG_DIAG_ON("cast-qual") } FUNC_LEAVE_NOAPI(ret_value) @@ -775,9 +775,9 @@ H5I_object_verify(hid_t id, H5I_type_t type) /* Verify that the type of the ID is correct & lookup the ID */ if (type == H5I_TYPE(id) && NULL != (info = H5I__find_id(id))) { /* Get the object pointer to return */ - H5_GCC_DIAG_OFF("cast-qual") + H5_GCC_CLANG_DIAG_OFF("cast-qual") ret_value = (void *)info->object; /* (Casting away const OK -QAK) */ - H5_GCC_DIAG_ON("cast-qual") + H5_GCC_CLANG_DIAG_ON("cast-qual") } FUNC_LEAVE_NOAPI(ret_value) @@ -938,9 +938,9 @@ H5I__remove_common(H5I_type_info_t *type_info, hid_t id) if (type_info->last_id_info == info) type_info->last_id_info = NULL; - H5_GCC_DIAG_OFF("cast-qual") + H5_GCC_CLANG_DIAG_OFF("cast-qual") ret_value = (void *)info->object; /* (Casting away const OK -QAK) */ - H5_GCC_DIAG_ON("cast-qual") + H5_GCC_CLANG_DIAG_ON("cast-qual") if (!H5I_marking_g) info = H5FL_FREE(H5I_id_info_t, info); @@ -1040,7 +1040,7 @@ H5I__dec_ref(hid_t id, void **request) /* Get the ID's type */ type_info = H5I_type_info_array_g[H5I_TYPE(id)]; - H5_GCC_DIAG_OFF("cast-qual") + H5_GCC_CLANG_DIAG_OFF("cast-qual") /* (Casting away const OK -QAK) */ if (!type_info->cls->free_func || (type_info->cls->free_func)((void *)info->object, request) >= 0) { /* Remove the node from the type */ @@ -1050,7 +1050,7 @@ H5I__dec_ref(hid_t id, void **request) } /* end if */ else ret_value = -1; - H5_GCC_DIAG_ON("cast-qual") + H5_GCC_CLANG_DIAG_ON("cast-qual") } /* end if */ else { --(info->count); @@ -1529,9 +1529,9 @@ H5I__iterate_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) /* The stored object pointer might be an H5VL_object_t, in which * case we'll need to get the wrapped object struct (H5F_t *, etc.). */ - H5_GCC_DIAG_OFF("cast-qual") + H5_GCC_CLANG_DIAG_OFF("cast-qual") object = H5I__unwrap((void *)info->object, type); /* Casting away const OK */ - H5_GCC_DIAG_ON("cast-qual") + H5_GCC_CLANG_DIAG_ON("cast-qual") /* Invoke callback function */ cb_ret_val = (*udata->user_func)((void *)object, info->id, udata->user_udata); @@ -1654,7 +1654,7 @@ H5I__find_id(hid_t id) } /* Check if this is a future ID */ - H5_GCC_DIAG_OFF("cast-qual") + H5_GCC_CLANG_DIAG_OFF("cast-qual") if (id_info && id_info->is_future) { hid_t actual_id = H5I_INVALID_HID; /* ID for actual object */ void *future_object; /* Pointer to the future object */ @@ -1686,7 +1686,7 @@ H5I__find_id(hid_t id) id_info->realize_cb = NULL; id_info->discard_cb = NULL; } - H5_GCC_DIAG_ON("cast-qual") + H5_GCC_CLANG_DIAG_ON("cast-qual") /* Set return value */ ret_value = id_info; @@ -1721,9 +1721,9 @@ H5I__find_id_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) HDassert(udata); /* Get a pointer to the VOL connector's data */ - H5_GCC_DIAG_OFF("cast-qual") + H5_GCC_CLANG_DIAG_OFF("cast-qual") object = H5I__unwrap((void *)info->object, type); /* Casting away const OK */ - H5_GCC_DIAG_ON("cast-qual") + H5_GCC_CLANG_DIAG_ON("cast-qual") /* Check for a match */ if (object == udata->object) { diff --git a/src/H5Imodule.h b/src/H5Imodule.h index 8db31c8..08f8bb0 100644 --- a/src/H5Imodule.h +++ b/src/H5Imodule.h @@ -30,8 +30,85 @@ #define H5_MY_PKG_INIT NO /**\defgroup H5I H5I - * \brief Identifier Interface - * \todo Describe concisely what the functions in this module are about. + * + * Use the functions in this module to manage identifiers defined by the HDF5 + * library. See \ref H5IUD for user-defined identifiers and identifier + * types. + * + * HDF5 identifiers are usually created as a side-effect of creating HDF5 + * entities such as groups, datasets, attributes, or property lists. + * + * Identifiers defined by the HDF5 library can be used to retrieve information + * such as path names and reference counts, and their validity can be checked. + * + * Identifiers can be updated by manipulating their reference counts. + * + * Unused identifiers should be reclaimed by closing the associated item, e.g., + * HDF5 object, or decrementing the reference count to 0. + * + * \note Identifiers (of type \ref hid_t) are run-time auxiliaries and + * not persisted in the file. + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5I_examples.c create + * </td> + * <td> + * \snippet{lineno} H5I_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5I_examples.c update + * </td> + * <td> + * \snippet{lineno} H5I_examples.c delete + * </td> + * </tr> + * </table> + * + * \defgroup H5IUD User-defined ID Types + * \ingroup H5I + * + * The \ref H5I module contains functions to define new identifier types. + * For convenience, handles of type \ref hid_t can then be associated with the + * new identifier types and user objects. + * + * New identifier types can be created by registering a new identifier type + * with the HDF5 library. Once a new identifier type has bee registered, + * it can be used to generate identifiers for user objects. + * + * User-defined identifier types can be searched and iterated. + * + * Like library-defined identifiers, user-defined identifiers \Emph{and} + * identifier types are reference counted, and the reference counts can be + * manipulated accordingly. + * + * User-defined identifiers no longer in use should be deleted or reclaimed, + * and identifier types should be destroyed if they are no longer required. + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5I_examples.c create_ud + * </td> + * <td> + * \snippet{lineno} H5I_examples.c read_ud + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5I_examples.c update_ud + * </td> + * <td> + * \snippet{lineno} H5I_examples.c delete_ud + * </td> + * </tr> + * </table> + * */ #endif /* H5Imodule_H */ diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h index a5f830b..8d4dbf8 100644 --- a/src/H5Ipublic.h +++ b/src/H5Ipublic.h @@ -106,7 +106,7 @@ extern "C" { /* Public API functions */ /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Registers an object under a type and returns an ID for it * @@ -128,7 +128,7 @@ extern "C" { */ H5_DLL hid_t H5Iregister(H5I_type_t type, const void *object); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Returns the object referenced by an ID * @@ -151,7 +151,7 @@ H5_DLL hid_t H5Iregister(H5I_type_t type, const void *object); */ H5_DLL void *H5Iobject_verify(hid_t id, H5I_type_t type); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Removes an ID from its type * @@ -190,12 +190,7 @@ H5_DLL void *H5Iremove_verify(hid_t id, H5I_type_t type); * \return Returns the object type if successful; otherwise #H5I_BADID. * * \details H5Iget_type() retrieves the type of the object identified by - * \p id. - * - * Valid types returned by the function are: - * \id_types - * - * If no valid type can be determined or the identifier submitted is + * \p id. If no valid type can be determined or the identifier submitted is * invalid, the function returns #H5I_BADID. * * This function is of particular use in determining the type of @@ -391,7 +386,7 @@ H5_DLL int H5Idec_ref(hid_t id); */ H5_DLL int H5Iget_ref(hid_t id); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Creates and returns a new ID type * @@ -423,7 +418,7 @@ H5_DLL int H5Iget_ref(hid_t id); */ H5_DLL H5I_type_t H5Iregister_type(size_t hash_size, unsigned reserved, H5I_free_t free_func); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Deletes all identifiers of the given type * @@ -447,7 +442,7 @@ H5_DLL H5I_type_t H5Iregister_type(size_t hash_size, unsigned reserved, H5I_free */ H5_DLL herr_t H5Iclear_type(H5I_type_t type, hbool_t force); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Removes an identifier type and all identifiers within that type * @@ -470,7 +465,7 @@ H5_DLL herr_t H5Iclear_type(H5I_type_t type, hbool_t force); */ H5_DLL herr_t H5Idestroy_type(H5I_type_t type); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Increments the reference count on an ID type * @@ -489,7 +484,7 @@ H5_DLL herr_t H5Idestroy_type(H5I_type_t type); */ H5_DLL int H5Iinc_type_ref(H5I_type_t type); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Decrements the reference count on an identifier type * @@ -509,7 +504,7 @@ H5_DLL int H5Iinc_type_ref(H5I_type_t type); */ H5_DLL int H5Idec_type_ref(H5I_type_t type); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Retrieves the reference count on an ID type * @@ -528,7 +523,7 @@ H5_DLL int H5Idec_type_ref(H5I_type_t type); */ H5_DLL int H5Iget_type_ref(H5I_type_t type); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Finds the memory referred to by an ID within the given ID type such * that some criterion is satisfied @@ -569,7 +564,7 @@ H5_DLL int H5Iget_type_ref(H5I_type_t type); */ H5_DLL void *H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Calls a callback for each member of the identifier type specified * @@ -598,7 +593,7 @@ H5_DLL void *H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key); */ H5_DLL herr_t H5Iiterate(H5I_type_t type, H5I_iterate_func_t op, void *op_data); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Returns the number of identifiers in a given identifier type * @@ -618,7 +613,7 @@ H5_DLL herr_t H5Iiterate(H5I_type_t type, H5I_iterate_func_t op, void *op_data); */ H5_DLL herr_t H5Inmembers(H5I_type_t type, hsize_t *num_members); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Determines whether an identifier type is registered * diff --git a/src/H5Itest.c b/src/H5Itest.c index 71ef3f8..80738a9 100644 --- a/src/H5Itest.c +++ b/src/H5Itest.c @@ -71,6 +71,7 @@ H5I__get_name_test(hid_t id, char *name /*out*/, size_t size, hbool_t *cached) H5G_loc_t loc; /* Object location */ hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ + size_t name_len = 0; /* Length of name */ ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_PACKAGE @@ -86,7 +87,7 @@ H5I__get_name_test(hid_t id, char *name /*out*/, size_t size, hbool_t *cached) /* Set wrapper info in API context */ if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_ID, H5E_CANTSET, FAIL, "can't set VOL wrapper info") + HGOTO_ERROR(H5E_ID, H5E_CANTSET, (-1), "can't set VOL wrapper info") vol_wrapper_set = TRUE; /* Get object location */ @@ -94,13 +95,16 @@ H5I__get_name_test(hid_t id, char *name /*out*/, size_t size, hbool_t *cached) HGOTO_ERROR(H5E_ID, H5E_CANTGET, (-1), "can't retrieve object location") /* Call internal group routine to retrieve object's name */ - if ((ret_value = H5G_get_name(&loc, name, size, cached)) < 0) + if (H5G_get_name(&loc, name, size, &name_len, cached) < 0) HGOTO_ERROR(H5E_ID, H5E_CANTGET, (-1), "can't retrieve object name") + /* Set return value */ + ret_value = (ssize_t)name_len; + done: /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_ID, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") + HDONE_ERROR(H5E_ID, H5E_CANTRESET, (-1), "can't reset VOL wrapper info") if (api_ctx_pushed && H5CX_pop(FALSE) < 0) HDONE_ERROR(H5E_SYM, H5E_CANTRESET, (-1), "can't reset API context") diff --git a/src/H5L.c b/src/H5L.c index a30c4da..065cc5c 100644 --- a/src/H5L.c +++ b/src/H5L.c @@ -148,14 +148,28 @@ H5Lmove(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *ds HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") /* Make sure that the VOL connectors are the same */ - if (vol_obj1 && vol_obj2) - if (vol_obj1->connector->cls->value != vol_obj2->connector->cls->value) + if (vol_obj1 && vol_obj2) { + int same_connector = 0; + + /* Check if both objects are associated with the same VOL connector */ + if (H5VL_cmp_connector_cls(&same_connector, vol_obj1->connector->cls, vol_obj2->connector->cls) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOMPARE, FAIL, "can't compare connector classes") + if (same_connector) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Objects are accessed through different VOL connectors and can't be linked") + } /* end if */ /* Construct a temporary source VOL object */ - tmp_vol_obj.data = (vol_obj1 ? vol_obj1->data : NULL); - tmp_vol_obj.connector = (vol_obj1 ? vol_obj1->connector : vol_obj2->connector); + if (vol_obj1) { + tmp_vol_obj.connector = vol_obj1->connector; + tmp_vol_obj.data = vol_obj1->data; + } /* end if */ + else { + HDassert(vol_obj2); + + tmp_vol_obj.connector = vol_obj2->connector; + tmp_vol_obj.data = NULL; + } /* end else */ /* Move the link */ if (H5VL_link_move(&tmp_vol_obj, &loc_params1, vol_obj2, &loc_params2, lcpl_id, lapl_id, @@ -238,14 +252,28 @@ H5Lcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *ds HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") /* Make sure that the VOL connectors are the same */ - if (vol_obj1 && vol_obj2) - if (vol_obj1->connector->cls->value != vol_obj2->connector->cls->value) + if (vol_obj1 && vol_obj2) { + int same_connector = 0; + + /* Check if both objects are associated with the same VOL connector */ + if (H5VL_cmp_connector_cls(&same_connector, vol_obj1->connector->cls, vol_obj2->connector->cls) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOMPARE, FAIL, "can't compare connector classes") + if (same_connector) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Objects are accessed through different VOL connectors and can't be linked") + } /* end if */ /* Construct a temporary source VOL object */ - tmp_vol_obj.data = (vol_obj1 ? vol_obj1->data : NULL); - tmp_vol_obj.connector = (vol_obj1 ? vol_obj1->connector : vol_obj2->connector); + if (vol_obj1) { + tmp_vol_obj.connector = vol_obj1->connector; + tmp_vol_obj.data = vol_obj1->data; + } /* end if */ + else { + HDassert(vol_obj2); + + tmp_vol_obj.connector = vol_obj2->connector; + tmp_vol_obj.data = NULL; + } /* end else */ /* Copy the link */ if (H5VL_link_copy(&tmp_vol_obj, &loc_params1, vol_obj2, &loc_params2, lcpl_id, lapl_id, @@ -272,8 +300,9 @@ H5L__create_soft_api_common(const char *link_target, hid_t link_loc_id, const ch H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters for object access */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_link_create_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -286,6 +315,7 @@ H5L__create_soft_api_common(const char *link_target, hid_t link_loc_id, const ch HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "link_target parameter cannot be an empty string") if (lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list") + /* link_name is verified in H5VL_setup_name_args() */ /* Get the link creation property list */ if (H5P_DEFAULT == lcpl_id) @@ -298,15 +328,17 @@ H5L__create_soft_api_common(const char *link_target, hid_t link_loc_id, const ch if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, link_loc_id, TRUE) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") - /* link_name is verified in H5VL_setup_name_args() */ /* Set up object access arguments */ - if (H5VL_setup_name_args(link_loc_id, link_name, H5P_CLS_LACC, TRUE, lapl_id, vol_obj_ptr, &loc_params) < - 0) + if (H5VL_setup_name_args(link_loc_id, link_name, TRUE, lapl_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set object access arguments") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_CREATE_SOFT; + vol_cb_args.args.soft.target = link_target; + /* Create the link */ - if (H5VL_link_create(H5VL_LINK_CREATE_SOFT, *vol_obj_ptr, &loc_params, lcpl_id, lapl_id, - H5P_DATASET_XFER_DEFAULT, token_ptr, link_target) < 0) + if (H5VL_link_create(&vol_cb_args, *vol_obj_ptr, &loc_params, lcpl_id, lapl_id, H5P_DATASET_XFER_DEFAULT, + token_ptr) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to create soft link") done: @@ -401,31 +433,31 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5L__create_hard_api_common(hid_t cur_loc_id, const char *cur_name, hid_t new_loc_id, const char *new_name, +H5L__create_hard_api_common(hid_t cur_loc_id, const char *cur_name, hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) { - H5VL_object_t * vol_obj1 = NULL; /* Object of cur_loc_id */ - H5VL_object_t * vol_obj2 = NULL; /* Object of new_loc_id */ + H5VL_object_t * curr_vol_obj = NULL; /* Object of cur_loc_id */ + H5VL_object_t * link_vol_obj = NULL; /* Object of link_loc_id */ H5VL_object_t tmp_vol_obj; /* Temporary object */ H5VL_object_t * tmp_vol_obj_ptr = &tmp_vol_obj; /* Ptr to temporary object */ H5VL_object_t **tmp_vol_obj_ptr_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj_ptr); /* Ptr to ptr to temporary object */ - H5VL_loc_params_t loc_params1; /* Location parameters for cur_loc_id object access */ - H5VL_loc_params_t loc_params2; /* Location parameters for new_loc_id object access */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_link_create_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t link_loc_params; /* Location parameters for link_loc_id object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC /* Check arguments */ - if (cur_loc_id == H5L_SAME_LOC && new_loc_id == H5L_SAME_LOC) + if (cur_loc_id == H5L_SAME_LOC && link_loc_id == H5L_SAME_LOC) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should not be both H5L_SAME_LOC") if (!cur_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cur_name parameter cannot be NULL") if (!*cur_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cur_name parameter cannot be an empty string") - if (!new_name) + if (!link_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "new_name parameter cannot be NULL") - if (!*new_name) + if (!*link_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "new_name parameter cannot be an empty string") if (lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list") @@ -441,40 +473,59 @@ H5L__create_hard_api_common(hid_t cur_loc_id, const char *cur_name, hid_t new_lo if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, cur_loc_id, TRUE) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") - /* Set up current & new location structs */ - loc_params1.type = H5VL_OBJECT_BY_NAME; - loc_params1.obj_type = H5I_get_type(cur_loc_id); - loc_params1.loc_data.loc_by_name.name = cur_name; - loc_params1.loc_data.loc_by_name.lapl_id = lapl_id; - - loc_params2.type = H5VL_OBJECT_BY_NAME; - loc_params2.obj_type = H5I_get_type(new_loc_id); - loc_params2.loc_data.loc_by_name.name = new_name; - loc_params2.loc_data.loc_by_name.lapl_id = lapl_id; + /* Set up new location struct */ + link_loc_params.type = H5VL_OBJECT_BY_NAME; + link_loc_params.obj_type = H5I_get_type(link_loc_id); + link_loc_params.loc_data.loc_by_name.name = link_name; + link_loc_params.loc_data.loc_by_name.lapl_id = lapl_id; if (H5L_SAME_LOC != cur_loc_id) /* Get the current location object */ - if (NULL == (vol_obj1 = (H5VL_object_t *)H5VL_vol_object(cur_loc_id))) + if (NULL == (curr_vol_obj = (H5VL_object_t *)H5VL_vol_object(cur_loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") - if (H5L_SAME_LOC != new_loc_id) + if (H5L_SAME_LOC != link_loc_id) /* Get the new location object */ - if (NULL == (vol_obj2 = (H5VL_object_t *)H5VL_vol_object(new_loc_id))) + if (NULL == (link_vol_obj = (H5VL_object_t *)H5VL_vol_object(link_loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") /* Make sure that the VOL connectors are the same */ - if (vol_obj1 && vol_obj2) - if (vol_obj1->connector->cls->value != vol_obj2->connector->cls->value) + if (curr_vol_obj && link_vol_obj) { + int same_connector = 0; + + /* Check if both objects are associated with the same VOL connector */ + if (H5VL_cmp_connector_cls(&same_connector, curr_vol_obj->connector->cls, + link_vol_obj->connector->cls) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOMPARE, FAIL, "can't compare connector classes") + if (same_connector) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Objects are accessed through different VOL connectors and can't be linked") + } /* end if */ /* Construct a temporary VOL object */ - (*tmp_vol_obj_ptr_ptr)->data = (vol_obj2 ? (vol_obj2->data) : NULL); - (*tmp_vol_obj_ptr_ptr)->connector = (vol_obj1 != NULL ? vol_obj1->connector : vol_obj2->connector); + if (curr_vol_obj) + (*tmp_vol_obj_ptr_ptr)->connector = curr_vol_obj->connector; + else { + HDassert(link_vol_obj); + + (*tmp_vol_obj_ptr_ptr)->connector = link_vol_obj->connector; + } /* end else */ + if (link_vol_obj) + (*tmp_vol_obj_ptr_ptr)->data = link_vol_obj->data; + else + (*tmp_vol_obj_ptr_ptr)->data = NULL; + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_CREATE_HARD; + vol_cb_args.args.hard.curr_obj = (curr_vol_obj ? curr_vol_obj->data : NULL); + vol_cb_args.args.hard.curr_loc_params.type = H5VL_OBJECT_BY_NAME; + vol_cb_args.args.hard.curr_loc_params.obj_type = + (H5L_SAME_LOC != cur_loc_id ? H5I_get_type(cur_loc_id) : H5I_BADID); + vol_cb_args.args.hard.curr_loc_params.loc_data.loc_by_name.name = cur_name; + vol_cb_args.args.hard.curr_loc_params.loc_data.loc_by_name.lapl_id = lapl_id; /* Create the link */ - if (H5VL_link_create(H5VL_LINK_CREATE_HARD, *tmp_vol_obj_ptr_ptr, &loc_params2, lcpl_id, lapl_id, - H5P_DATASET_XFER_DEFAULT, token_ptr, (vol_obj1 ? vol_obj1->data : NULL), - &loc_params1) < 0) + if (H5VL_link_create(&vol_cb_args, *tmp_vol_obj_ptr_ptr, &link_loc_params, lcpl_id, lapl_id, + H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to create hard link") done: @@ -534,12 +585,11 @@ H5Lcreate_hard_async(const char *app_file, const char *app_func, unsigned app_li const char *cur_name, hid_t new_loc_id, const char *new_name, hid_t lcpl_id, hid_t lapl_id, hid_t es_id) { - H5VL_object_t vol_obj; /* Object for loc_id */ - H5VL_object_t * vol_obj_ptr = &vol_obj; /* Pointer to object for loc_id */ - H5VL_object_t **vol_obj_ptr_ptr = &vol_obj_ptr; /* Pointer to object pointer */ - void * token = NULL; /* Request token for async operation */ - void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t vol_obj; /* Object for loc_id */ + H5VL_object_t *vol_obj_ptr = &vol_obj; /* Pointer to object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE10("e", "*s*sIui*si*siii", app_file, app_func, app_line, cur_loc_id, cur_name, new_loc_id, @@ -551,7 +601,7 @@ H5Lcreate_hard_async(const char *app_file, const char *app_func, unsigned app_li /* Creates a hard link asynchronously */ if (H5L__create_hard_api_common(cur_loc_id, cur_name, new_loc_id, new_name, lcpl_id, lapl_id, token_ptr, - vol_obj_ptr_ptr) < 0) + &vol_obj_ptr) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to asynchronously create hard link") /* If a token was created, add the token to the event set */ @@ -590,16 +640,16 @@ herr_t H5Lcreate_external(const char *file_name, const char *obj_name, hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - char * norm_obj_name = NULL; /* Pointer to normalized current name */ - void * ext_link_buf = NULL; /* Buffer to contain external link */ - size_t buf_size; /* Size of buffer to hold external link */ - size_t file_name_len; /* Length of file name string */ - size_t norm_obj_name_len; /* Length of normalized object name string */ - uint8_t * p; /* Pointer into external link buffer */ - H5L_type_t link_type = H5L_TYPE_EXTERNAL; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_link_create_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + char * norm_obj_name = NULL; /* Pointer to normalized current name */ + void * ext_link_buf = NULL; /* Buffer to contain external link */ + size_t buf_size; /* Size of buffer to hold external link */ + size_t file_name_len; /* Length of file name string */ + size_t norm_obj_name_len; /* Length of normalized object name string */ + uint8_t * p; /* Pointer into external link buffer */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "*s*si*sii", file_name, obj_name, link_loc_id, link_name, lcpl_id, lapl_id); @@ -650,10 +700,15 @@ H5Lcreate_external(const char *file_name, const char *obj_name, hid_t link_loc_i if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(link_loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_CREATE_UD; + vol_cb_args.args.ud.type = H5L_TYPE_EXTERNAL; + vol_cb_args.args.ud.buf = ext_link_buf; + vol_cb_args.args.ud.buf_size = buf_size; + /* Create an external link */ - if (H5VL_link_create(H5VL_LINK_CREATE_UD, vol_obj, &loc_params, lcpl_id, lapl_id, - H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, (int)link_type, ext_link_buf, - buf_size) < 0) + if (H5VL_link_create(&vol_cb_args, vol_obj, &loc_params, lcpl_id, lapl_id, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create external link") done: @@ -691,9 +746,10 @@ herr_t H5Lcreate_ud(hid_t link_loc_id, const char *link_name, H5L_type_t link_type, const void *udata, size_t udata_size, hid_t lcpl_id, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_link_create_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE7("e", "i*sLl*xzii", link_loc_id, link_name, link_type, udata, udata_size, lcpl_id, lapl_id); @@ -726,9 +782,15 @@ H5Lcreate_ud(hid_t link_loc_id, const char *link_name, H5L_type_t link_type, con if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(link_loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") - /* Create external link */ - if (H5VL_link_create(H5VL_LINK_CREATE_UD, vol_obj, &loc_params, lcpl_id, lapl_id, - H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, (int)link_type, udata, udata_size) < 0) + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_CREATE_UD; + vol_cb_args.args.ud.type = link_type; + vol_cb_args.args.ud.buf = udata; + vol_cb_args.args.ud.buf_size = udata_size; + + /* Create user-defined link */ + if (H5VL_link_create(&vol_cb_args, vol_obj, &loc_params, lcpl_id, lapl_id, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") done: @@ -751,8 +813,9 @@ H5L__delete_api_common(hid_t loc_id, const char *name, hid_t lapl_id, void **tok H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters for object access */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -760,12 +823,14 @@ H5L__delete_api_common(hid_t loc_id, const char *name, hid_t lapl_id, void **tok /* name is verified in H5VL_setup_name_args() */ /* Set up object access arguments */ - if (H5VL_setup_name_args(loc_id, name, H5P_CLS_LACC, TRUE, lapl_id, vol_obj_ptr, &loc_params) < 0) + if (H5VL_setup_name_args(loc_id, name, TRUE, lapl_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set object access arguments") - /* Unlink */ - if (H5VL_link_specific(*vol_obj_ptr, &loc_params, H5VL_LINK_DELETE, H5P_DATASET_XFER_DEFAULT, token_ptr) < - 0) + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_DELETE; + + /* Delete link */ + if (H5VL_link_specific(*vol_obj_ptr, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link") done: @@ -864,8 +929,9 @@ H5L__delete_by_idx_api_common(hid_t loc_id, const char *group_name, H5_index_t i H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters for object access */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -878,13 +944,15 @@ H5L__delete_by_idx_api_common(hid_t loc_id, const char *group_name, H5_index_t i HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") /* Set up object access arguments */ - if (H5VL_setup_idx_args(loc_id, group_name, idx_type, order, n, H5P_CLS_LACC, TRUE, lapl_id, vol_obj_ptr, - &loc_params) < 0) + if (H5VL_setup_idx_args(loc_id, group_name, idx_type, order, n, TRUE, lapl_id, vol_obj_ptr, &loc_params) < + 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set object access arguments") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_DELETE; + /* Delete the link */ - if (H5VL_link_specific(*vol_obj_ptr, &loc_params, H5VL_LINK_DELETE, H5P_DATASET_XFER_DEFAULT, token_ptr) < - 0) + if (H5VL_link_specific(*vol_obj_ptr, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link") done: @@ -993,9 +1061,10 @@ done: herr_t H5Lget_val(hid_t loc_id, const char *name, void *buf /*out*/, size_t size, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* object of loc_id */ + H5VL_link_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "i*sxzi", loc_id, name, buf, size, lapl_id); @@ -1008,18 +1077,23 @@ H5Lget_val(hid_t loc_id, const char *name, void *buf /*out*/, size_t size, hid_t if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set up location struct */ loc_params.type = H5VL_OBJECT_BY_NAME; loc_params.obj_type = H5I_get_type(loc_id); loc_params.loc_data.loc_by_name.name = name; loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - /* Get the location object */ + /* Get the VOL object */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_GET_VAL; + vol_cb_args.args.get_val.buf = buf; + vol_cb_args.args.get_val.buf_size = size; + /* Get the link value */ - if (H5VL_link_get(vol_obj, &loc_params, H5VL_LINK_GET_VAL, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, buf, - size) < 0) + if (H5VL_link_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link value for '%s'", name) done: @@ -1048,9 +1122,10 @@ herr_t H5Lget_val_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, void *buf /*out*/, size_t size, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* object of loc_id */ + H5VL_link_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("e", "i*sIiIohxzi", loc_id, group_name, idx_type, order, n, buf, size, lapl_id); @@ -1067,6 +1142,7 @@ H5Lget_val_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_ if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set up location struct */ loc_params.type = H5VL_OBJECT_BY_IDX; loc_params.loc_data.loc_by_idx.name = group_name; loc_params.loc_data.loc_by_idx.idx_type = idx_type; @@ -1075,13 +1151,17 @@ H5Lget_val_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_ loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; loc_params.obj_type = H5I_get_type(loc_id); - /* get the location object */ + /* Get the VOL object */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_GET_VAL; + vol_cb_args.args.get_val.buf = buf; + vol_cb_args.args.get_val.buf_size = size; + /* Get the link value */ - if (H5VL_link_get(vol_obj, &loc_params, H5VL_LINK_GET_VAL, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, buf, - size) < 0) + if (H5VL_link_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link value") done: @@ -1104,8 +1184,9 @@ H5L__exists_api_common(hid_t loc_id, const char *name, hbool_t *exists, hid_t la H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters for object access */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -1115,12 +1196,15 @@ H5L__exists_api_common(hid_t loc_id, const char *name, hbool_t *exists, hid_t la HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer for link existence") /* Set up object access arguments */ - if (H5VL_setup_name_args(loc_id, name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) + if (H5VL_setup_name_args(loc_id, name, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set object access arguments") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_EXISTS; + vol_cb_args.args.exists.exists = exists; + /* Check for the existence of the link */ - if (H5VL_link_specific(*vol_obj_ptr, &loc_params, H5VL_LINK_EXISTS, H5P_DATASET_XFER_DEFAULT, token_ptr, - exists) < 0) + if (H5VL_link_specific(*vol_obj_ptr, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link info") done: @@ -1216,9 +1300,10 @@ done: herr_t H5Lget_info2(hid_t loc_id, const char *name, H5L_info2_t *linfo /*out*/, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* object of loc_id */ + H5VL_link_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "i*sxi", loc_id, name, linfo, lapl_id); @@ -1231,18 +1316,22 @@ H5Lget_info2(hid_t loc_id, const char *name, H5L_info2_t *linfo /*out*/, hid_t l if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set up location struct */ loc_params.type = H5VL_OBJECT_BY_NAME; loc_params.obj_type = H5I_get_type(loc_id); loc_params.loc_data.loc_by_name.name = name; loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - /* get the location object */ + /* Get the location object */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_GET_INFO; + vol_cb_args.args.get_info.linfo = linfo; + /* Get the link information */ - if (H5VL_link_get(vol_obj, &loc_params, H5VL_LINK_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - linfo) < 0) + if (H5VL_link_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link info") done: @@ -1267,9 +1356,10 @@ herr_t H5Lget_info_by_idx2(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5L_info2_t *linfo /*out*/, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* object of loc_id */ + H5VL_link_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE7("e", "i*sIiIohxi", loc_id, group_name, idx_type, order, n, linfo, lapl_id); @@ -1286,6 +1376,7 @@ H5Lget_info_by_idx2(hid_t loc_id, const char *group_name, H5_index_t idx_type, H if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set up location struct */ loc_params.type = H5VL_OBJECT_BY_IDX; loc_params.loc_data.loc_by_idx.name = group_name; loc_params.loc_data.loc_by_idx.idx_type = idx_type; @@ -1294,13 +1385,16 @@ H5Lget_info_by_idx2(hid_t loc_id, const char *group_name, H5_index_t idx_type, H loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; loc_params.obj_type = H5I_get_type(loc_id); - /* get the location object */ + /* Get the location object */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_GET_INFO; + vol_cb_args.args.get_info.linfo = linfo; + /* Get the link information */ - if (H5VL_link_get(vol_obj, &loc_params, H5VL_LINK_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - linfo) < 0) + if (H5VL_link_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link info") done: @@ -1463,9 +1557,11 @@ ssize_t H5Lget_name_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, char *name /*out*/, size_t size, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - ssize_t ret_value = -1; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* object of loc_id */ + H5VL_link_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + size_t link_name_len = 0; /* Length of the link name string */ + ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE8("Zs", "i*sIiIohxzi", loc_id, group_name, idx_type, order, n, name, size, lapl_id); @@ -1482,7 +1578,7 @@ H5Lget_name_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5 if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, (-1), "can't set access property list info") - /* Fill in location struct fields */ + /* Set up location struct */ loc_params.type = H5VL_OBJECT_BY_IDX; loc_params.loc_data.loc_by_idx.name = group_name; loc_params.loc_data.loc_by_idx.idx_type = idx_type; @@ -1491,15 +1587,23 @@ H5Lget_name_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5 loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; loc_params.obj_type = H5I_get_type(loc_id); - /* Get the location object */ + /* Get the VOL object */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_GET_NAME; + vol_cb_args.args.get_name.name_size = size; + vol_cb_args.args.get_name.name = name; + vol_cb_args.args.get_name.name_len = &link_name_len; + /* Get the link information */ - if (H5VL_link_get(vol_obj, &loc_params, H5VL_LINK_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - name, size, &ret_value) < 0) + if (H5VL_link_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, (-1), "unable to get link name") + /* Set the return value */ + ret_value = (ssize_t)link_name_len; + done: FUNC_LEAVE_API(ret_value) } /* end H5Lget_name_by_idx() */ @@ -1519,10 +1623,11 @@ H5L__iterate_api_common(hid_t group_id, H5_index_t idx_type, H5_iter_order_t ord { H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = - (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters for object access */ - H5I_type_t id_type; /* Type of ID */ - herr_t ret_value = H5_ITER_CONT; /* Return value */ + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5I_type_t id_type; /* Type of ID */ + herr_t ret_value = H5_ITER_CONT; /* Return value */ FUNC_ENTER_STATIC @@ -1541,10 +1646,18 @@ H5L__iterate_api_common(hid_t group_id, H5_index_t idx_type, H5_iter_order_t ord if (H5VL_setup_self_args(group_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set object access arguments") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_ITER; + vol_cb_args.args.iterate.recursive = FALSE; + vol_cb_args.args.iterate.idx_type = idx_type; + vol_cb_args.args.iterate.order = order; + vol_cb_args.args.iterate.idx_p = idx_p; + vol_cb_args.args.iterate.op = op; + vol_cb_args.args.iterate.op_data = op_data; + /* Iterate over the links */ - if ((ret_value = H5VL_link_specific(*vol_obj_ptr, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, - token_ptr, (unsigned)FALSE, (int)idx_type, (int)order, idx_p, op, - op_data)) < 0) + if ((ret_value = H5VL_link_specific(*vol_obj_ptr, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + token_ptr)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link iteration failed") done: @@ -1663,9 +1776,10 @@ herr_t H5Literate_by_name2(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx_p, H5L_iterate2_t op, void *op_data, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("e", "i*sIiIo*hLI*xi", loc_id, group_name, idx_type, order, idx_p, op, op_data, lapl_id); @@ -1696,9 +1810,18 @@ H5Literate_by_name2(hid_t loc_id, const char *group_name, H5_index_t idx_type, H loc_params.loc_data.loc_by_name.name = group_name; loc_params.loc_data.loc_by_name.lapl_id = lapl_id; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_ITER; + vol_cb_args.args.iterate.recursive = FALSE; + vol_cb_args.args.iterate.idx_type = idx_type; + vol_cb_args.args.iterate.order = order; + vol_cb_args.args.iterate.idx_p = idx_p; + vol_cb_args.args.iterate.op = op; + vol_cb_args.args.iterate.op_data = op_data; + /* Iterate over the links */ - if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, FALSE, idx_type, order, idx_p, op, op_data)) < 0) + if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link iteration failed") done: @@ -1736,10 +1859,11 @@ done: herr_t H5Lvisit2(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, H5L_iterate2_t op, void *op_data) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5I_type_t id_type; /* Type of ID */ - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5I_type_t id_type; /* Type of ID */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "iIiIoLI*x", group_id, idx_type, order, op, op_data); @@ -1763,9 +1887,18 @@ H5Lvisit2(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, H5L_iterat if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(group_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_ITER; + vol_cb_args.args.iterate.recursive = TRUE; + vol_cb_args.args.iterate.idx_type = idx_type; + vol_cb_args.args.iterate.order = order; + vol_cb_args.args.iterate.idx_p = NULL; + vol_cb_args.args.iterate.op = op; + vol_cb_args.args.iterate.op_data = op_data; + /* Iterate over the links */ - if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, TRUE, idx_type, order, NULL, op, op_data)) < 0) + if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed") done: @@ -1804,9 +1937,10 @@ herr_t H5Lvisit_by_name2(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, H5L_iterate2_t op, void *op_data, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE7("e", "i*sIiIoLI*xi", loc_id, group_name, idx_type, order, op, op_data, lapl_id); @@ -1837,9 +1971,18 @@ H5Lvisit_by_name2(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_ loc_params.loc_data.loc_by_name.name = group_name; loc_params.loc_data.loc_by_name.lapl_id = lapl_id; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_ITER; + vol_cb_args.args.iterate.recursive = TRUE; + vol_cb_args.args.iterate.idx_type = idx_type; + vol_cb_args.args.iterate.order = order; + vol_cb_args.args.iterate.idx_p = NULL; + vol_cb_args.args.iterate.op = op; + vol_cb_args.args.iterate.op_data = op_data; + /* Visit the links */ - if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, TRUE, idx_type, order, NULL, op, op_data)) < 0) + if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed") done: diff --git a/src/H5Ldeprec.c b/src/H5Ldeprec.c index df4c384..01e77f9 100644 --- a/src/H5Ldeprec.c +++ b/src/H5Ldeprec.c @@ -141,12 +141,13 @@ herr_t H5Literate1(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx_p, H5L_iterate1_t op, void *op_data) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5I_type_t id_type; /* Type of ID */ - H5L_shim_data_t shim_data; - hbool_t is_native_vol_obj; - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + H5I_type_t id_type; /* Type of ID */ + H5L_shim_data_t shim_data; + hbool_t is_native_vol_obj; + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "iIiIo*hLi*x", group_id, idx_type, order, idx_p, op, op_data); @@ -181,10 +182,18 @@ H5Literate1(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t shim_data.real_op = op; shim_data.real_op_data = op_data; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_ITER; + vol_cb_args.args.iterate.recursive = FALSE; + vol_cb_args.args.iterate.idx_type = idx_type; + vol_cb_args.args.iterate.order = order; + vol_cb_args.args.iterate.idx_p = idx_p; + vol_cb_args.args.iterate.op = H5L__iterate2_shim; + vol_cb_args.args.iterate.op_data = &shim_data; + /* Iterate over the links */ - if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, (unsigned)FALSE, (int)idx_type, (int)order, idx_p, - H5L__iterate2_shim, (void *)&shim_data)) < 0) + if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link iteration failed") done: @@ -219,11 +228,12 @@ herr_t H5Literate_by_name1(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx_p, H5L_iterate1_t op, void *op_data, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5L_shim_data_t shim_data; - hbool_t is_native_vol_obj; - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + H5L_shim_data_t shim_data; + hbool_t is_native_vol_obj; + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("e", "i*sIiIo*hLi*xi", loc_id, group_name, idx_type, order, idx_p, op, op_data, lapl_id); @@ -265,10 +275,18 @@ H5Literate_by_name1(hid_t loc_id, const char *group_name, H5_index_t idx_type, H shim_data.real_op = op; shim_data.real_op_data = op_data; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_ITER; + vol_cb_args.args.iterate.recursive = FALSE; + vol_cb_args.args.iterate.idx_type = idx_type; + vol_cb_args.args.iterate.order = order; + vol_cb_args.args.iterate.idx_p = idx_p; + vol_cb_args.args.iterate.op = H5L__iterate2_shim; + vol_cb_args.args.iterate.op_data = &shim_data; + /* Iterate over the links */ - if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, FALSE, idx_type, order, idx_p, H5L__iterate2_shim, - (void *)&shim_data)) < 0) + if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link iteration failed") done: @@ -293,11 +311,12 @@ done: herr_t H5Lget_info1(hid_t loc_id, const char *name, H5L_info1_t *linfo /*out*/, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - H5L_info2_t linfo2; /* New-style link info */ - hbool_t is_native_vol_obj; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* object of loc_id */ + H5VL_link_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + H5L_info2_t linfo2; /* New-style link info */ + hbool_t is_native_vol_obj; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "i*sxi", loc_id, name, linfo, lapl_id); @@ -310,12 +329,13 @@ H5Lget_info1(hid_t loc_id, const char *name, H5L_info1_t *linfo /*out*/, hid_t l if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set up location struct */ loc_params.type = H5VL_OBJECT_BY_NAME; loc_params.obj_type = H5I_get_type(loc_id); loc_params.loc_data.loc_by_name.name = name; loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - /* get the location object */ + /* Get the location object */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") @@ -326,9 +346,12 @@ H5Lget_info1(hid_t loc_id, const char *name, H5L_info1_t *linfo /*out*/, hid_t l HGOTO_ERROR(H5E_LINK, H5E_BADVALUE, FAIL, "H5Lget_info1 is only meant to be used with the native VOL connector") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_GET_INFO; + vol_cb_args.args.get_info.linfo = &linfo2; + /* Get the link information */ - if (H5VL_link_get(vol_obj, &loc_params, H5VL_LINK_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &linfo2) < 0) + if (H5VL_link_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link info") /* Copy the new-style members into the old-style struct */ @@ -376,11 +399,12 @@ herr_t H5Lget_info_by_idx1(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5L_info1_t *linfo /*out*/, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - H5L_info2_t linfo2; /* New-style link info */ - hbool_t is_native_vol_obj; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* object of loc_id */ + H5VL_link_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + H5L_info2_t linfo2; /* New-style link info */ + hbool_t is_native_vol_obj; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE7("e", "i*sIiIohxi", loc_id, group_name, idx_type, order, n, linfo, lapl_id); @@ -397,6 +421,7 @@ H5Lget_info_by_idx1(hid_t loc_id, const char *group_name, H5_index_t idx_type, H if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set up location struct */ loc_params.type = H5VL_OBJECT_BY_IDX; loc_params.loc_data.loc_by_idx.name = group_name; loc_params.loc_data.loc_by_idx.idx_type = idx_type; @@ -405,7 +430,7 @@ H5Lget_info_by_idx1(hid_t loc_id, const char *group_name, H5_index_t idx_type, H loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; loc_params.obj_type = H5I_get_type(loc_id); - /* get the location object */ + /* Get the location object */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") @@ -416,9 +441,12 @@ H5Lget_info_by_idx1(hid_t loc_id, const char *group_name, H5_index_t idx_type, H HGOTO_ERROR(H5E_LINK, H5E_BADVALUE, FAIL, "H5Lget_info_by_idx1 is only meant to be used with the native VOL connector") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_GET_INFO; + vol_cb_args.args.get_info.linfo = &linfo2; + /* Get the link information */ - if (H5VL_link_get(vol_obj, &loc_params, H5VL_LINK_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &linfo2) < 0) + if (H5VL_link_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link info") /* Copy the new-style members into the old-style struct */ @@ -479,12 +507,13 @@ done: herr_t H5Lvisit1(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, H5L_iterate1_t op, void *op_data) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5I_type_t id_type; /* Type of ID */ - H5L_shim_data_t shim_data; - hbool_t is_native_vol_obj; - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + H5I_type_t id_type; /* Type of ID */ + H5L_shim_data_t shim_data; + hbool_t is_native_vol_obj; + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "iIiIoLi*x", group_id, idx_type, order, op, op_data); @@ -519,10 +548,18 @@ H5Lvisit1(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, H5L_iterat shim_data.real_op = op; shim_data.real_op_data = op_data; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_ITER; + vol_cb_args.args.iterate.recursive = TRUE; + vol_cb_args.args.iterate.idx_type = idx_type; + vol_cb_args.args.iterate.order = order; + vol_cb_args.args.iterate.idx_p = NULL; + vol_cb_args.args.iterate.op = H5L__iterate2_shim; + vol_cb_args.args.iterate.op_data = &shim_data; + /* Iterate over the links */ - if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, TRUE, idx_type, order, NULL, H5L__iterate2_shim, - (void *)&shim_data)) < 0) + if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed") done: @@ -563,11 +600,12 @@ herr_t H5Lvisit_by_name1(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, H5L_iterate1_t op, void *op_data, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5L_shim_data_t shim_data; - hbool_t is_native_vol_obj; - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + H5L_shim_data_t shim_data; + hbool_t is_native_vol_obj; + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE7("e", "i*sIiIoLi*xi", loc_id, group_name, idx_type, order, op, op_data, lapl_id); @@ -609,10 +647,18 @@ H5Lvisit_by_name1(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_ shim_data.real_op = op; shim_data.real_op_data = op_data; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_ITER; + vol_cb_args.args.iterate.recursive = TRUE; + vol_cb_args.args.iterate.idx_type = idx_type; + vol_cb_args.args.iterate.order = order; + vol_cb_args.args.iterate.idx_p = NULL; + vol_cb_args.args.iterate.op = H5L__iterate2_shim; + vol_cb_args.args.iterate.op_data = &shim_data; + /* Visit the links */ - if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, TRUE, idx_type, order, NULL, H5L__iterate2_shim, - (void *)&shim_data)) < 0) + if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed") done: diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c index eccd2c6..2f7c7eb 100644 --- a/src/H5Lexternal.c +++ b/src/H5Lexternal.c @@ -173,30 +173,30 @@ H5L__extern_traverse(const char H5_ATTR_UNUSED *link_name, hid_t cur_group, cons /* Make callback if it exists */ if (cb_info.func) { - const char *parent_file_name; /* Parent file name */ - ssize_t group_name_len; /* Length of parent group name */ + const char *parent_file_name; /* Parent file name */ + size_t group_name_len = 0; /* Length of parent group name */ /* Get parent file name */ parent_file_name = H5F_OPEN_NAME(loc.oloc->file); /* Query length of parent group name */ - if ((group_name_len = H5G_get_name(&loc, NULL, (size_t)0, NULL)) < 0) + if (H5G_get_name(&loc, NULL, (size_t)0, &group_name_len, NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, H5I_INVALID_HID, "unable to retrieve length of group name") /* Account for null terminator */ group_name_len++; /* Check if we need to allocate larger buffer */ - if ((size_t)group_name_len > sizeof(local_group_name)) { - if (NULL == (parent_group_name = (char *)H5MM_malloc((size_t)group_name_len))) + if (group_name_len > sizeof(local_group_name)) { + if (NULL == (parent_group_name = (char *)H5MM_malloc(group_name_len))) HGOTO_ERROR(H5E_LINK, H5E_CANTALLOC, H5I_INVALID_HID, - "can't allocate buffer to hold group name, group_name_len = %zd", group_name_len) + "can't allocate buffer to hold group name, group_name_len = %zu", group_name_len) } /* end if */ else parent_group_name = local_group_name; /* Get parent group name */ - if (H5G_get_name(&loc, parent_group_name, (size_t)group_name_len, NULL) < 0) + if (H5G_get_name(&loc, parent_group_name, group_name_len, NULL, NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, H5I_INVALID_HID, "unable to retrieve group name") /* Make callback */ diff --git a/src/H5Lint.c b/src/H5Lint.c index a8e9ba2..346c37d 100644 --- a/src/H5Lint.c +++ b/src/H5Lint.c @@ -47,6 +47,50 @@ typedef struct { H5L_info2_t *linfo; /* Buffer to return to user */ } H5L_trav_gi_t; +/* User data for path traversal routine for getting link value by index */ +typedef struct { + /* In */ + H5_index_t idx_type; /* Index to use */ + H5_iter_order_t order; /* Order to iterate in index */ + hsize_t n; /* Offset of link within index */ + size_t size; /* Size of user buffer */ + + /* Out */ + void *buf; /* User buffer */ +} H5L_trav_gvbi_t; + +/* User data for path traversal routine for getting link info by index */ +typedef struct { + /* In */ + H5_index_t idx_type; /* Index to use */ + H5_iter_order_t order; /* Order to iterate in index */ + hsize_t n; /* Offset of link within index */ + + /* Out */ + H5L_info2_t *linfo; /* Buffer to return to user */ +} H5L_trav_gibi_t; + +/* User data for path traversal routine for removing link by index */ +typedef struct { + /* In */ + H5_index_t idx_type; /* Index to use */ + H5_iter_order_t order; /* Order to iterate in index */ + hsize_t n; /* Offset of link within index */ +} H5L_trav_rmbi_t; + +/* User data for path traversal routine for getting name by index */ +typedef struct { + /* In */ + H5_index_t idx_type; /* Index to use */ + H5_iter_order_t order; /* Order to iterate in index */ + hsize_t n; /* Offset of link within index */ + size_t size; /* Size of name buffer */ + + /* Out */ + char * name; /* Buffer to return name to user */ + size_t name_len; /* Length of full name */ +} H5L_trav_gnbi_t; + /* User data for path traversal callback to creating a link */ typedef struct { H5F_t * file; /* Pointer to the file */ @@ -2012,8 +2056,8 @@ H5L__get_name_by_idx_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc /*in*/, const char H5_ HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "group doesn't exist") /* Query link */ - if ((udata->name_len = H5G_obj_get_name_by_idx(obj_loc->oloc, udata->idx_type, udata->order, udata->n, - udata->name, udata->size)) < 0) + if (H5G_obj_get_name_by_idx(obj_loc->oloc, udata->idx_type, udata->order, udata->n, udata->name, + udata->size, &udata->name_len) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "link not found") done: @@ -2034,18 +2078,19 @@ done: * *------------------------------------------------------------------------- */ -ssize_t +herr_t H5L__get_name_by_idx(const H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, - hsize_t n, char *name /*out*/, size_t size) + hsize_t n, char *name /*out*/, size_t size, size_t *link_name_len) { - H5L_trav_gnbi_t udata; /* User data for callback */ - ssize_t ret_value = FAIL; /* Return value */ + H5L_trav_gnbi_t udata; /* User data for callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE /* Check arguments */ HDassert(loc); HDassert(group_name && *group_name); + HDassert(link_name_len); /* Set up user data for callback */ udata.idx_type = idx_type; @@ -2053,7 +2098,7 @@ H5L__get_name_by_idx(const H5G_loc_t *loc, const char *group_name, H5_index_t id udata.n = n; udata.name = name; udata.size = size; - udata.name_len = -1; + udata.name_len = 0; /* Traverse the group hierarchy to locate the link to get name of */ if (H5G_traverse(loc, group_name, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, H5L__get_name_by_idx_cb, &udata) < @@ -2061,7 +2106,7 @@ H5L__get_name_by_idx(const H5G_loc_t *loc, const char *group_name, H5_index_t id HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get name") /* Set the return value */ - ret_value = udata.name_len; + *link_name_len = udata.name_len; done: FUNC_LEAVE_NOAPI(ret_value) @@ -2104,9 +2149,9 @@ H5L__link_copy_file(H5F_t *dst_file, const H5O_link_t *_src_lnk, const H5O_loc_t /* Expand soft or external link, if requested */ if ((H5L_TYPE_SOFT == src_lnk->type && cpy_info->expand_soft_link) || (H5L_TYPE_EXTERNAL == src_lnk->type && cpy_info->expand_ext_link)) { - H5G_loc_t lnk_grp_loc; /* Group location holding link */ - H5G_name_t lnk_grp_path; /* Path for link */ - htri_t tar_exists; /* Whether the target object exists */ + H5G_loc_t lnk_grp_loc; /* Group location holding link */ + H5G_name_t lnk_grp_path; /* Path for link */ + hbool_t tar_exists = FALSE; /* Whether the target object exists */ /* Set up group location for link */ H5G_name_reset(&lnk_grp_path); @@ -2114,7 +2159,7 @@ H5L__link_copy_file(H5F_t *dst_file, const H5O_link_t *_src_lnk, const H5O_loc_t lnk_grp_loc.oloc = (H5O_loc_t *)src_oloc; /* Casting away const OK -QAK */ /* Check if the target object exists */ - if ((tar_exists = H5G_loc_exists(&lnk_grp_loc, src_lnk->name)) < 0) + if (H5G_loc_exists(&lnk_grp_loc, src_lnk->name, &tar_exists) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to check if target object exists") if (tar_exists) { diff --git a/src/H5Lmodule.h b/src/H5Lmodule.h index 16f1f34..cffd25c 100644 --- a/src/H5Lmodule.h +++ b/src/H5Lmodule.h @@ -30,8 +30,29 @@ #define H5_MY_PKG_INIT YES /**\defgroup H5L H5L - * \brief Link Interface - * \todo Describe concisely what the functions in this module are about. + * + * Use the functions in this module to manage HDF5 links and link types. + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5L_examples.c create + * </td> + * <td> + * \snippet{lineno} H5L_examples.c iter_cb + * \snippet{lineno} H5L_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5L_examples.c update + * </td> + * <td> + * \snippet{lineno} H5L_examples.c delete + * </td> + * </tr> + * </table> * * \defgroup TRAV Link Traversal * \ingroup H5L diff --git a/src/H5Lpkg.h b/src/H5Lpkg.h index 7057e30..36a4d12 100644 --- a/src/H5Lpkg.h +++ b/src/H5Lpkg.h @@ -53,26 +53,27 @@ /* Package Private Prototypes */ /******************************/ -H5_DLL herr_t H5L__create_hard(H5G_loc_t *cur_loc, const char *cur_name, const H5G_loc_t *link_loc, - const char *link_name, hid_t lcpl_id); -H5_DLL herr_t H5L__create_soft(const char *target_path, const H5G_loc_t *cur_loc, const char *cur_name, - hid_t lcpl_id); -H5_DLL herr_t H5L__create_ud(const H5G_loc_t *link_loc, const char *link_name, const void *ud_data, - size_t ud_data_size, H5L_type_t type, hid_t lcpl_id); -H5_DLL herr_t H5L__exists(const H5G_loc_t *loc, const char *name, hbool_t *exists); -H5_DLL herr_t H5L__get_info_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, H5L_info2_t *linfo /*out*/); -H5_DLL ssize_t H5L__get_name_by_idx(const H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, char *name /*out*/, size_t size); -H5_DLL herr_t H5L__get_val(const H5G_loc_t *loc, const char *name, void *buf /*out*/, size_t size); -H5_DLL herr_t H5L__get_val_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, void *buf /*out*/, size_t size); -H5_DLL herr_t H5L__move(const H5G_loc_t *src_loc, const char *src_name, const H5G_loc_t *dst_loc, - const char *dst_name, hbool_t copy_flag, hid_t lcpl_id); -H5_DLL herr_t H5L__delete(const H5G_loc_t *loc, const char *name); -H5_DLL herr_t H5L__delete_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n); -H5_DLL herr_t H5L__link_copy_file(H5F_t *dst_file, const H5O_link_t *_src_lnk, const H5O_loc_t *src_oloc, - H5O_link_t *dst_lnk, H5O_copy_t *cpy_info); +H5_DLL herr_t H5L__create_hard(H5G_loc_t *cur_loc, const char *cur_name, const H5G_loc_t *link_loc, + const char *link_name, hid_t lcpl_id); +H5_DLL herr_t H5L__create_soft(const char *target_path, const H5G_loc_t *cur_loc, const char *cur_name, + hid_t lcpl_id); +H5_DLL herr_t H5L__create_ud(const H5G_loc_t *link_loc, const char *link_name, const void *ud_data, + size_t ud_data_size, H5L_type_t type, hid_t lcpl_id); +H5_DLL herr_t H5L__exists(const H5G_loc_t *loc, const char *name, hbool_t *exists); +H5_DLL herr_t H5L__get_info_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, H5L_info2_t *linfo /*out*/); +H5_DLL herr_t H5L__get_name_by_idx(const H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, char *name /*out*/, size_t size, + size_t *name_len); +H5_DLL herr_t H5L__get_val(const H5G_loc_t *loc, const char *name, void *buf /*out*/, size_t size); +H5_DLL herr_t H5L__get_val_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, void *buf /*out*/, size_t size); +H5_DLL herr_t H5L__move(const H5G_loc_t *src_loc, const char *src_name, const H5G_loc_t *dst_loc, + const char *dst_name, hbool_t copy_flag, hid_t lcpl_id); +H5_DLL herr_t H5L__delete(const H5G_loc_t *loc, const char *name); +H5_DLL herr_t H5L__delete_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n); +H5_DLL herr_t H5L__link_copy_file(H5F_t *dst_file, const H5O_link_t *_src_lnk, const H5O_loc_t *src_oloc, + H5O_link_t *dst_lnk, H5O_copy_t *cpy_info); #endif /* H5Lpkg_H */ diff --git a/src/H5Lprivate.h b/src/H5Lprivate.h index 53b8726..98e3051 100644 --- a/src/H5Lprivate.h +++ b/src/H5Lprivate.h @@ -52,50 +52,6 @@ /* Library Private Typedefs */ /****************************/ -/* User data for path traversal routine for getting link value by index */ -typedef struct { - /* In */ - H5_index_t idx_type; /* Index to use */ - H5_iter_order_t order; /* Order to iterate in index */ - hsize_t n; /* Offset of link within index */ - size_t size; /* Size of user buffer */ - - /* Out */ - void *buf; /* User buffer */ -} H5L_trav_gvbi_t; - -/* User data for path traversal routine for getting link info by index */ -typedef struct { - /* In */ - H5_index_t idx_type; /* Index to use */ - H5_iter_order_t order; /* Order to iterate in index */ - hsize_t n; /* Offset of link within index */ - - /* Out */ - H5L_info2_t *linfo; /* Buffer to return to user */ -} H5L_trav_gibi_t; - -/* User data for path traversal routine for getting name by index */ -typedef struct { - /* In */ - H5_index_t idx_type; /* Index to use */ - H5_iter_order_t order; /* Order to iterate in index */ - hsize_t n; /* Offset of link within index */ - size_t size; /* Size of name buffer */ - - /* Out */ - char * name; /* Buffer to return name to user */ - ssize_t name_len; /* Length of full name */ -} H5L_trav_gnbi_t; - -/* User data for path traversal routine for removing link by index */ -typedef struct { - /* In */ - H5_index_t idx_type; /* Index to use */ - H5_iter_order_t order; /* Order to iterate in index */ - hsize_t n; /* Offset of link within index */ -} H5L_trav_rmbi_t; - /* Structure for external link traversal callback property */ typedef struct H5L_elink_cb_t { H5L_elink_traverse_t func; diff --git a/src/H5Lpublic.h b/src/H5Lpublic.h index f665526..72b0182 100644 --- a/src/H5Lpublic.h +++ b/src/H5Lpublic.h @@ -1380,6 +1380,7 @@ H5_DLL herr_t H5Lunpack_elink_val(const void *ext_linkval /*in*/, size_t link_si H5_DLL herr_t H5Lcreate_external(const char *file_name, const char *obj_name, hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id); +/// \cond DEV /* API Wrappers for async routines */ /* (Must be defined _after_ the function prototype) */ /* (And must only defined when included in application code, not the library) */ @@ -1401,6 +1402,7 @@ H5_DLL herr_t H5Lcreate_external(const char *file_name, const char *obj_name, hi #define H5Lexists_async_wrap H5_NO_EXPAND(H5Lexists_async) #define H5Literate_async_wrap H5_NO_EXPAND(H5Literate_async) #endif /* H5L_MODULE */ +/// \endcond /* Symbols defined for compatibility with previous versions of the HDF5 API. * diff --git a/src/H5M.c b/src/H5M.c index f3cc2ea..b890a5c 100644 --- a/src/H5M.c +++ b/src/H5M.c @@ -211,15 +211,20 @@ H5M_term_package(void) static herr_t H5M__close_cb(H5VL_object_t *map_vol_obj, void **request) { - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC /* Sanity check */ HDassert(map_vol_obj); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_MAP_CLOSE; + vol_cb_args.args = NULL; + /* Close the map */ - if (H5VL_optional(map_vol_obj, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, request) < 0) + if (H5VL_optional(map_vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, request) < 0) HGOTO_ERROR(H5E_MAP, H5E_CLOSEERROR, FAIL, "unable to close map"); /* Free the VOL object */ @@ -251,8 +256,9 @@ H5M__create_api_common(hid_t loc_id, const char *name, hid_t key_type_id, hid_t H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_STATIC @@ -274,14 +280,24 @@ H5M__create_api_common(hid_t loc_id, const char *name, hid_t key_type_id, hid_t else if (TRUE != H5P_isa_class(mcpl_id, H5P_MAP_CREATE)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "mcpl_id is not a map create property list ID") - /* Set up object access arguments */ - if (H5VL_setup_acc_args(loc_id, H5P_CLS_MACC, TRUE, &mapl_id, vol_obj_ptr, &loc_params) < 0) + /* Set up VOL callback arguments */ + if (H5VL_setup_acc_args(loc_id, H5P_CLS_MACC, TRUE, &mapl_id, vol_obj_ptr, &map_args.create.loc_params) < + 0) HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") + map_args.create.name = name; + map_args.create.lcpl_id = lcpl_id; + map_args.create.key_type_id = key_type_id; + map_args.create.val_type_id = val_type_id; + map_args.create.mcpl_id = mcpl_id; + map_args.create.mapl_id = mapl_id; + map_args.create.map = NULL; + vol_cb_args.op_type = H5VL_MAP_CREATE; + vol_cb_args.args = &map_args; /* Create the map */ - if (H5VL_optional(*vol_obj_ptr, H5VL_MAP_CREATE, H5P_DATASET_XFER_DEFAULT, token_ptr, &loc_params, name, - lcpl_id, key_type_id, val_type_id, mcpl_id, mapl_id, &map) < 0) + if (H5VL_optional(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, H5I_INVALID_HID, "unable to create map") + map = map_args.create.map; /* Get an ID for the map */ if ((ret_value = H5VL_register(H5I_MAP, map, (*vol_obj_ptr)->connector, TRUE)) < 0) @@ -289,9 +305,14 @@ H5M__create_api_common(hid_t loc_id, const char *name, hid_t key_type_id, hid_t done: /* Cleanup on failure */ - if (H5I_INVALID_HID == ret_value) - if (map && H5VL_optional(*vol_obj_ptr, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + if (H5I_INVALID_HID == ret_value) { + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_MAP_CLOSE; + vol_cb_args.args = NULL; + + if (map && H5VL_optional(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map") + } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5M__create_api_common() */ @@ -407,10 +428,11 @@ done: hid_t H5Mcreate_anon(hid_t loc_id, hid_t key_type_id, hid_t val_type_id, hid_t mcpl_id, hid_t mapl_id) { - void * map = NULL; /* map object from VOL connector */ - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + void * map = NULL; /* map object from VOL connector */ + H5VL_object_t * vol_obj = NULL; /* object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE5("i", "iiiii", loc_id, key_type_id, val_type_id, mcpl_id, mapl_id); @@ -430,13 +452,24 @@ H5Mcreate_anon(hid_t loc_id, hid_t key_type_id, hid_t val_type_id, hid_t mcpl_id HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(loc_id); + + /* Set up VOL callback arguments */ + map_args.create.loc_params.type = H5VL_OBJECT_BY_SELF; + map_args.create.loc_params.obj_type = H5I_get_type(loc_id); + map_args.create.name = NULL; + map_args.create.lcpl_id = H5P_LINK_CREATE_DEFAULT; + map_args.create.key_type_id = key_type_id; + map_args.create.val_type_id = val_type_id; + map_args.create.mcpl_id = mcpl_id; + map_args.create.mapl_id = mapl_id; + map_args.create.map = NULL; + vol_cb_args.op_type = H5VL_MAP_CREATE; + vol_cb_args.args = &map_args; /* Create the map */ - if (H5VL_optional(vol_obj, H5VL_MAP_CREATE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, NULL, - H5P_LINK_CREATE_DEFAULT, key_type_id, val_type_id, mcpl_id, mapl_id, &map) < 0) + if (H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, H5I_INVALID_HID, "unable to create map") + map = map_args.create.map; /* Get an ID for the map */ if ((ret_value = H5VL_register(H5I_MAP, map, vol_obj->connector, TRUE)) < 0) @@ -444,9 +477,14 @@ H5Mcreate_anon(hid_t loc_id, hid_t key_type_id, hid_t val_type_id, hid_t mcpl_id done: /* Cleanup on failure */ - if (H5I_INVALID_HID == ret_value) - if (map && H5VL_optional(vol_obj, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + if (H5I_INVALID_HID == ret_value) { + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_MAP_CLOSE; + vol_cb_args.args = NULL; + + if (map && H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map") + } /* end if */ FUNC_LEAVE_API(ret_value) } /* end H5Mcreate_anon() */ @@ -470,8 +508,9 @@ H5M__open_api_common(hid_t loc_id, const char *name, hid_t mapl_id, void **token H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_STATIC @@ -481,14 +520,20 @@ H5M__open_api_common(hid_t loc_id, const char *name, hid_t mapl_id, void **token if (!*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string") - /* Set up object access arguments */ - if (H5VL_setup_acc_args(loc_id, H5P_CLS_MACC, FALSE, &mapl_id, vol_obj_ptr, &loc_params) < 0) + /* Set up VOL callback arguments */ + if (H5VL_setup_acc_args(loc_id, H5P_CLS_MACC, FALSE, &mapl_id, vol_obj_ptr, &map_args.open.loc_params) < + 0) HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") + map_args.open.name = name; + map_args.open.mapl_id = mapl_id; + map_args.open.map = NULL; + vol_cb_args.op_type = H5VL_MAP_OPEN; + vol_cb_args.args = &map_args; /* Open the map */ - if (H5VL_optional(*vol_obj_ptr, H5VL_MAP_OPEN, H5P_DATASET_XFER_DEFAULT, token_ptr, &loc_params, name, - mapl_id, &map) < 0) + if (H5VL_optional(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open map") + map = map_args.create.map; /* Register an ID for the map */ if ((ret_value = H5VL_register(H5I_MAP, map, (*vol_obj_ptr)->connector, TRUE)) < 0) @@ -496,9 +541,14 @@ H5M__open_api_common(hid_t loc_id, const char *name, hid_t mapl_id, void **token done: /* Cleanup on failure */ - if (H5I_INVALID_HID == ret_value) - if (map && H5VL_optional(*vol_obj_ptr, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + if (H5I_INVALID_HID == ret_value) { + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_MAP_CLOSE; + vol_cb_args.args = NULL; + + if (map && H5VL_optional(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map") + } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5M__open_api_common() */ @@ -521,9 +571,7 @@ done: hid_t H5Mopen(hid_t loc_id, const char *name, hid_t mapl_id) { - void * map = NULL; /* map object from VOL connector */ - H5VL_object_t *vol_obj = NULL; /* object of loc_id */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE3("i", "i*si", loc_id, name, mapl_id); @@ -533,11 +581,6 @@ H5Mopen(hid_t loc_id, const char *name, hid_t mapl_id) HGOTO_ERROR(H5E_MAP, H5E_CANTCREATE, H5I_INVALID_HID, "unable to open map synchronously") done: - /* Cleanup on failure */ - if (H5I_INVALID_HID == ret_value) - if (map && H5VL_optional(vol_obj, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map") - FUNC_LEAVE_API(ret_value) } /* end H5Mopen() */ @@ -697,8 +740,10 @@ done: hid_t H5Mget_key_type(hid_t map_id) { - H5VL_object_t *vol_obj; /* Map structure */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj; /* Map structure */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", map_id); @@ -707,10 +752,18 @@ H5Mget_key_type(hid_t map_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier") - /* get the datatype */ - if (H5VL_optional(vol_obj, H5VL_MAP_GET, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, H5VL_MAP_GET_KEY_TYPE, - &ret_value) < 0) - HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get datatype") + /* Set up VOL callback arguments */ + map_args.get.get_type = H5VL_MAP_GET_KEY_TYPE; + map_args.get.args.get_key_type.type_id = H5I_INVALID_HID; + vol_cb_args.op_type = H5VL_MAP_GET; + vol_cb_args.args = &map_args; + + /* Get the key datatype */ + if (H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get key datatype") + + /* Set return value */ + ret_value = map_args.get.args.get_key_type.type_id; done: FUNC_LEAVE_API(ret_value) @@ -732,8 +785,10 @@ done: hid_t H5Mget_val_type(hid_t map_id) { - H5VL_object_t *vol_obj; /* Map structure */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj; /* Map structure */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", map_id); @@ -742,10 +797,18 @@ H5Mget_val_type(hid_t map_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier") - /* get the datatype */ - if (H5VL_optional(vol_obj, H5VL_MAP_GET, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, H5VL_MAP_GET_VAL_TYPE, - &ret_value) < 0) - HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get datatype") + /* Set up VOL callback arguments */ + map_args.get.get_type = H5VL_MAP_GET_VAL_TYPE; + map_args.get.args.get_val_type.type_id = H5I_INVALID_HID; + vol_cb_args.op_type = H5VL_MAP_GET; + vol_cb_args.args = &map_args; + + /* Get the value datatype */ + if (H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get value datatype") + + /* Set return value */ + ret_value = map_args.get.args.get_val_type.type_id; done: FUNC_LEAVE_API(ret_value) @@ -767,8 +830,10 @@ done: hid_t H5Mget_create_plist(hid_t map_id) { - H5VL_object_t *vol_obj; /* Map structure */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj; /* Map structure */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", map_id); @@ -777,11 +842,19 @@ H5Mget_create_plist(hid_t map_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier") + /* Set up VOL callback arguments */ + map_args.get.get_type = H5VL_MAP_GET_MCPL; + map_args.get.args.get_mcpl.mcpl_id = H5I_INVALID_HID; + vol_cb_args.op_type = H5VL_MAP_GET; + vol_cb_args.args = &map_args; + /* Get the map creation property list */ - if (H5VL_optional(vol_obj, H5VL_MAP_GET, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, H5VL_MAP_GET_MCPL, - &ret_value) < 0) + if (H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get map creation properties") + /* Set return value */ + ret_value = map_args.get.args.get_mcpl.mcpl_id; + done: FUNC_LEAVE_API(ret_value) } /* end H5Mget_create_plist() */ @@ -805,8 +878,10 @@ done: hid_t H5Mget_access_plist(hid_t map_id) { - H5VL_object_t *vol_obj; /* Map structure */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj; /* Map structure */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", map_id); @@ -815,11 +890,19 @@ H5Mget_access_plist(hid_t map_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier") + /* Set up VOL callback arguments */ + map_args.get.get_type = H5VL_MAP_GET_MAPL; + map_args.get.args.get_mapl.mapl_id = H5I_INVALID_HID; + vol_cb_args.op_type = H5VL_MAP_GET; + vol_cb_args.args = &map_args; + /* Get the map access property list */ - if (H5VL_optional(vol_obj, H5VL_MAP_GET, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, H5VL_MAP_GET_MAPL, - &ret_value) < 0) + if (H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get map access properties") + /* Set return value */ + ret_value = map_args.get.args.get_mapl.mapl_id; + done: FUNC_LEAVE_API(ret_value) } /* end H5Mget_access_plist() */ @@ -839,8 +922,10 @@ done: herr_t H5Mget_count(hid_t map_id, hsize_t *count /*out*/, hid_t dxpl_id) { - H5VL_object_t *vol_obj; /* Map structure */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Map structure */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE3("e", "ixi", map_id, count, dxpl_id); @@ -858,9 +943,19 @@ H5Mget_count(hid_t map_id, hsize_t *count /*out*/, hid_t dxpl_id) /* Set DXPL for operation */ H5CX_set_dxpl(dxpl_id); + /* Set up VOL callback arguments */ + map_args.get.get_type = H5VL_MAP_GET_COUNT; + map_args.get.args.get_count.count = 0; + vol_cb_args.op_type = H5VL_MAP_GET; + vol_cb_args.args = &map_args; + /* Get the number of key-value pairs stored in the map */ - if (H5VL_optional(vol_obj, H5VL_MAP_GET, dxpl_id, H5_REQUEST_NULL, H5VL_MAP_GET_COUNT, count) < 0) - HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get map access properties") + if (H5VL_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get KV pair count for map") + + /* Set value to return */ + if (count) + *count = map_args.get.args.get_count.count; done: FUNC_LEAVE_API(ret_value) @@ -882,7 +977,9 @@ H5M__put_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -905,9 +1002,16 @@ H5M__put_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t /* Set DXPL for operation */ H5CX_set_dxpl(dxpl_id); + /* Set up VOL callback arguments */ + map_args.put.key_mem_type_id = key_mem_type_id; + map_args.put.key = key; + map_args.put.value_mem_type_id = val_mem_type_id; + map_args.put.value = value; + vol_cb_args.op_type = H5VL_MAP_PUT; + vol_cb_args.args = &map_args; + /* Set the key/value pair */ - if (H5VL_optional(*vol_obj_ptr, H5VL_MAP_PUT, dxpl_id, token_ptr, key_mem_type_id, key, val_mem_type_id, - value) < 0) + if (H5VL_optional(*vol_obj_ptr, &vol_cb_args, dxpl_id, token_ptr) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTSET, FAIL, "unable to put key/value pair") done: @@ -1008,7 +1112,9 @@ H5M__get_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -1031,9 +1137,16 @@ H5M__get_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t /* Set DXPL for operation */ H5CX_set_dxpl(dxpl_id); + /* Set up VOL callback arguments */ + map_args.get_val.key_mem_type_id = key_mem_type_id; + map_args.get_val.key = key; + map_args.get_val.value_mem_type_id = val_mem_type_id; + map_args.get_val.value = value; + vol_cb_args.op_type = H5VL_MAP_GET_VAL; + vol_cb_args.args = &map_args; + /* Get the value for the key */ - if (H5VL_optional(*vol_obj_ptr, H5VL_MAP_GET_VAL, dxpl_id, token_ptr, key_mem_type_id, key, - val_mem_type_id, value) < 0) + if (H5VL_optional(*vol_obj_ptr, &vol_cb_args, dxpl_id, token_ptr) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "unable to get value from map") done: @@ -1137,8 +1250,10 @@ done: herr_t H5Mexists(hid_t map_id, hid_t key_mem_type_id, const void *key, hbool_t *exists, hid_t dxpl_id) { - H5VL_object_t *vol_obj = NULL; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "ii*x*bi", map_id, key_mem_type_id, key, exists, dxpl_id); @@ -1160,11 +1275,21 @@ H5Mexists(hid_t map_id, hid_t key_mem_type_id, const void *key, hbool_t *exists, /* Set DXPL for operation */ H5CX_set_dxpl(dxpl_id); + /* Set up VOL callback arguments */ + map_args.exists.key_mem_type_id = key_mem_type_id; + map_args.exists.key = key; + map_args.exists.exists = FALSE; + vol_cb_args.op_type = H5VL_MAP_EXISTS; + vol_cb_args.args = &map_args; + /* Check if key exists */ - if ((ret_value = H5VL_optional(vol_obj, H5VL_MAP_EXISTS, dxpl_id, H5_REQUEST_NULL, key_mem_type_id, key, - exists)) < 0) + if (H5VL_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTGET, ret_value, "unable to check if key exists") + /* Set value to return */ + if (exists) + *exists = map_args.exists.exists; + done: FUNC_LEAVE_API(ret_value) } /* end H5Mexists() */ @@ -1203,9 +1328,10 @@ done: herr_t H5Miterate(hid_t map_id, hsize_t *idx, hid_t key_mem_type_id, H5M_iterate_t op, void *op_data, hid_t dxpl_id) { - H5VL_object_t * vol_obj = NULL; - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "i*hiMI*xi", map_id, idx, key_mem_type_id, op, op_data, dxpl_id); @@ -1229,14 +1355,23 @@ H5Miterate(hid_t map_id, hsize_t *idx, hid_t key_mem_type_id, H5M_iterate_t op, /* Set DXPL for operation */ H5CX_set_dxpl(dxpl_id); - /* Set location struct fields */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(map_id); + /* Set up VOL callback arguments */ + map_args.specific.specific_type = H5VL_MAP_ITER; + map_args.specific.args.iterate.loc_params.type = H5VL_OBJECT_BY_SELF; + map_args.specific.args.iterate.loc_params.obj_type = H5I_get_type(map_id); + map_args.specific.args.iterate.idx = (idx ? *idx : 0); + map_args.specific.args.iterate.op = op; + map_args.specific.args.iterate.op_data = op_data; + vol_cb_args.op_type = H5VL_MAP_SPECIFIC; + vol_cb_args.args = &map_args; /* Iterate over keys */ - if ((ret_value = H5VL_optional(vol_obj, H5VL_MAP_SPECIFIC, dxpl_id, H5_REQUEST_NULL, &loc_params, - H5VL_MAP_ITER, idx, key_mem_type_id, op, op_data)) < 0) - HGOTO_ERROR(H5E_MAP, H5E_BADITER, ret_value, "unable to iterate over keys") + if ((ret_value = H5VL_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL)) < 0) + HERROR(H5E_MAP, H5E_BADITER, "unable to iterate over keys"); + + /* Set value to return */ + if (idx) + *idx = map_args.specific.args.iterate.idx; done: FUNC_LEAVE_API(ret_value) @@ -1277,9 +1412,10 @@ herr_t H5Miterate_by_name(hid_t loc_id, const char *map_name, hsize_t *idx, hid_t key_mem_type_id, H5M_iterate_t op, void *op_data, hid_t dxpl_id, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("e", "i*s*hiMI*xii", loc_id, map_name, idx, key_mem_type_id, op, op_data, dxpl_id, lapl_id); @@ -1307,16 +1443,25 @@ H5Miterate_by_name(hid_t loc_id, const char *map_name, hsize_t *idx, hid_t key_m /* Set DXPL for operation */ H5CX_set_dxpl(dxpl_id); - /* Set location struct fields */ - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.obj_type = H5I_get_type(loc_id); - loc_params.loc_data.loc_by_name.name = map_name; - loc_params.loc_data.loc_by_name.lapl_id = lapl_id; + /* Set up VOL callback arguments */ + map_args.specific.specific_type = H5VL_MAP_ITER; + map_args.specific.args.iterate.loc_params.type = H5VL_OBJECT_BY_NAME; + map_args.specific.args.iterate.loc_params.obj_type = H5I_get_type(loc_id); + map_args.specific.args.iterate.loc_params.loc_data.loc_by_name.name = map_name; + map_args.specific.args.iterate.loc_params.loc_data.loc_by_name.lapl_id = lapl_id; + map_args.specific.args.iterate.idx = (idx ? *idx : 0); + map_args.specific.args.iterate.op = op; + map_args.specific.args.iterate.op_data = op_data; + vol_cb_args.op_type = H5VL_MAP_SPECIFIC; + vol_cb_args.args = &map_args; /* Iterate over keys */ - if ((ret_value = H5VL_optional(vol_obj, H5VL_MAP_SPECIFIC, dxpl_id, H5_REQUEST_NULL, &loc_params, - H5VL_MAP_ITER, idx, key_mem_type_id, op, op_data)) < 0) - HGOTO_ERROR(H5E_MAP, H5E_BADITER, ret_value, "unable to ierate over keys") + if ((ret_value = H5VL_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL)) < 0) + HERROR(H5E_MAP, H5E_BADITER, "unable to ierate over keys"); + + /* Set value to return */ + if (idx) + *idx = map_args.specific.args.iterate.idx; done: FUNC_LEAVE_API(ret_value) @@ -1340,9 +1485,10 @@ done: herr_t H5Mdelete(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t dxpl_id) { - H5VL_object_t * vol_obj = NULL; - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "ii*xi", map_id, key_mem_type_id, key, dxpl_id); @@ -1364,13 +1510,17 @@ H5Mdelete(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t dxpl_id) /* Set DXPL for operation */ H5CX_set_dxpl(dxpl_id); - /* Set location struct fields */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(map_id); + /* Set up VOL callback arguments */ + map_args.specific.specific_type = H5VL_MAP_DELETE; + map_args.specific.args.del.loc_params.type = H5VL_OBJECT_BY_SELF; + map_args.specific.args.del.loc_params.obj_type = H5I_get_type(map_id); + map_args.specific.args.del.key_mem_type_id = key_mem_type_id; + map_args.specific.args.del.key = key; + vol_cb_args.op_type = H5VL_MAP_SPECIFIC; + vol_cb_args.args = &map_args; /* Delete the key/value pair */ - if (H5VL_optional(vol_obj, H5VL_MAP_SPECIFIC, dxpl_id, H5_REQUEST_NULL, &loc_params, H5VL_MAP_DELETE, - key_mem_type_id, key) < 0) + if (H5VL_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTSET, FAIL, "unable to delete key/value pair") done: diff --git a/src/H5MF.c b/src/H5MF.c index fd38495..ca780c3 100644 --- a/src/H5MF.c +++ b/src/H5MF.c @@ -2463,15 +2463,15 @@ done: * Purpose: To retrieve free-space section information for * paged or non-paged aggregation * - * Return: Success: Number of free sections - * Failure: -1 + * Return: SUCCEED/FAIL * * Programmer: Vailin Choi; Dec 2012 * *------------------------------------------------------------------------- */ -ssize_t -H5MF_get_free_sections(H5F_t *f, H5FD_mem_t type, size_t nsects, H5F_sect_info_t *sect_info) +herr_t +H5MF_get_free_sections(H5F_t *f, H5FD_mem_t type, size_t nsects, H5F_sect_info_t *sect_info, + size_t *sect_count) { H5AC_ring_t orig_ring = H5AC_RING_INV; /* Original ring value */ H5AC_ring_t curr_ring = H5AC_RING_INV; /* Current ring value */ @@ -2480,9 +2480,9 @@ H5MF_get_free_sections(H5F_t *f, H5FD_mem_t type, size_t nsects, H5F_sect_info_t H5MF_sect_iter_ud_t sect_udata; /* User data for callback */ H5F_mem_page_t start_type, end_type; /* Memory types to iterate over */ H5F_mem_page_t ty; /* Memory type for iteration */ - ssize_t ret_value = -1; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, (-1)) + FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL) /* check args */ HDassert(f); @@ -2544,7 +2544,7 @@ H5MF_get_free_sections(H5F_t *f, H5FD_mem_t type, size_t nsects, H5F_sect_info_t if (!f->shared->fs_man[ty] && H5F_addr_defined(f->shared->fs_addr[ty])) { if (H5MF__open_fstype(f, ty) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, (-1), "can't open the free space manager") + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't open the free space manager") HDassert(f->shared->fs_man[ty]); fs_started = TRUE; } /* end if */ @@ -2552,7 +2552,7 @@ H5MF_get_free_sections(H5F_t *f, H5FD_mem_t type, size_t nsects, H5F_sect_info_t /* Check if there's free space sections of this type */ if (f->shared->fs_man[ty]) if (H5MF__get_free_sects(f, f->shared->fs_man[ty], §_udata, &nums) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, (-1), + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't get section info for the free space manager") /* Increment total # of sections */ @@ -2561,13 +2561,13 @@ H5MF_get_free_sections(H5F_t *f, H5FD_mem_t type, size_t nsects, H5F_sect_info_t /* Close the free space manager of this type, if we started it here */ if (fs_started) if (H5MF__close_fstype(f, ty) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTCLOSEOBJ, (-1), "can't close file free space") + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTCLOSEOBJ, FAIL, "can't close file free space") if ((H5F_PAGED_AGGR(f)) && (type != H5FD_MEM_DEFAULT)) ty = (H5F_mem_page_t)(ty + H5FD_MEM_NTYPES - 2); } /* end for */ - /* Set return value */ - ret_value = (ssize_t)total_sects; + /* Set value to return */ + *sect_count = total_sects; done: /* Reset the ring in the API context */ diff --git a/src/H5MFprivate.h b/src/H5MFprivate.h index 81bf36d..e55b00f 100644 --- a/src/H5MFprivate.h +++ b/src/H5MFprivate.h @@ -56,7 +56,8 @@ H5_DLL haddr_t H5MF_aggr_vfd_alloc(H5F_t *f, H5FD_mem_t type, hsize_t size); H5_DLL herr_t H5MF_xfree(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size); H5_DLL herr_t H5MF_try_extend(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size, hsize_t extra_requested); H5_DLL htri_t H5MF_try_shrink(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size); -H5_DLL ssize_t H5MF_get_free_sections(H5F_t *f, H5FD_mem_t type, size_t nsects, H5F_sect_info_t *sect_info); +H5_DLL herr_t H5MF_get_free_sections(H5F_t *f, H5FD_mem_t type, size_t nsects, H5F_sect_info_t *sect_info, + size_t *sect_count); /* File 'temporary' space allocation routines */ H5_DLL haddr_t H5MF_alloc_tmp(H5F_t *f, hsize_t size); diff --git a/src/H5Mmodule.h b/src/H5Mmodule.h index 3dae3e2..848f63f 100644 --- a/src/H5Mmodule.h +++ b/src/H5Mmodule.h @@ -26,9 +26,9 @@ #define H5_MY_PKG_ERR H5E_MAP #define H5_MY_PKG_INIT YES -/** - * \defgroup H5M H5M - * \brief Map Interface +/**\defgroup H5M H5M + * + * \todo Describe the map life cycle. * * \details \Bold{The interface can only be used with the HDF5 VOL connectors that * implement map objects.} The native HDF5 library does not support this diff --git a/src/H5Mprivate.h b/src/H5Mprivate.h index 1a2524e..e62434a 100644 --- a/src/H5Mprivate.h +++ b/src/H5Mprivate.h @@ -21,10 +21,9 @@ #include "H5Mpublic.h" /* Private headers needed by this file */ -#include "H5FDprivate.h" /* File drivers */ -#include "H5Oprivate.h" /* Object headers */ -#include "H5Sprivate.h" /* Dataspaces */ -#include "H5Zprivate.h" /* Data filters */ +#include "H5Oprivate.h" /* Object headers */ +#include "H5Sprivate.h" /* Dataspaces */ +#include "H5Zprivate.h" /* Data filters */ /**************************/ /* Library Private Macros */ diff --git a/src/H5Mpublic.h b/src/H5Mpublic.h index 3f6bf01..3f94edb 100644 --- a/src/H5Mpublic.h +++ b/src/H5Mpublic.h @@ -25,6 +25,7 @@ /* Public headers needed by this file */ #include "H5public.h" #include "H5Ipublic.h" +#include "H5VLconnector.h" /*****************/ /* Public Macros */ @@ -68,6 +69,115 @@ typedef enum H5VL_map_specific_t { typedef herr_t (*H5M_iterate_t)(hid_t map_id, const void *key, void *op_data); //! <!-- [H5M_iterate_t_snip] --> +/* Parameters for map operations */ +typedef union H5VL_map_args_t { + /* H5VL_MAP_CREATE */ + struct { + H5VL_loc_params_t loc_params; /* Location parameters for object */ + const char * name; /* Name of new map object */ + hid_t lcpl_id; /* Link creation property list for map */ + hid_t key_type_id; /* Datatype for map keys */ + hid_t val_type_id; /* Datatype for map values */ + hid_t mcpl_id; /* Map creation property list */ + hid_t mapl_id; /* Map access property list */ + void * map; /* Pointer to newly created map object (OUT) */ + } create; + + /* H5VL_MAP_OPEN */ + struct { + H5VL_loc_params_t loc_params; /* Location parameters for object */ + const char * name; /* Name of new map object */ + hid_t mapl_id; /* Map access property list */ + void * map; /* Pointer to newly created map object (OUT) */ + } open; + + /* H5VL_MAP_GET_VAL */ + struct { + hid_t key_mem_type_id; /* Memory datatype for key */ + const void *key; /* Pointer to key */ + hid_t value_mem_type_id; /* Memory datatype for value */ + void * value; /* Buffer for value (OUT) */ + } get_val; + + /* H5VL_MAP_EXISTS */ + struct { + hid_t key_mem_type_id; /* Memory datatype for key */ + const void *key; /* Pointer to key */ + hbool_t exists; /* Flag indicating whether key exists in map (OUT) */ + } exists; + + /* H5VL_MAP_PUT */ + struct { + hid_t key_mem_type_id; /* Memory datatype for key */ + const void *key; /* Pointer to key */ + hid_t value_mem_type_id; /* Memory datatype for value */ + const void *value; /* Pointer to value */ + } put; + + /* H5VL_MAP_GET */ + struct { + H5VL_map_get_t get_type; /* 'get' operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_MAP_GET_MAPL */ + struct { + hid_t mapl_id; /* Map access property list ID (OUT) */ + } get_mapl; + + /* H5VL_MAP_GET_MCPL */ + struct { + hid_t mcpl_id; /* Map creation property list ID (OUT) */ + } get_mcpl; + + /* H5VL_MAP_GET_KEY_TYPE */ + struct { + hid_t type_id; /* Datatype ID for map's keys (OUT) */ + } get_key_type; + + /* H5VL_MAP_GET_VAL_TYPE */ + struct { + hid_t type_id; /* Datatype ID for map's values (OUT) */ + } get_val_type; + + /* H5VL_MAP_GET_COUNT */ + struct { + hsize_t count; /* # of KV pairs in map (OUT) */ + } get_count; + } args; + } get; + + /* H5VL_MAP_SPECIFIC */ + struct { + H5VL_map_specific_t specific_type; /* 'specific' operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_MAP_ITER */ + struct { + H5VL_loc_params_t loc_params; /* Location parameters for object */ + hsize_t idx; /* Start/end iteration index (IN/OUT) */ + hid_t key_mem_type_id; /* Memory datatype for key */ + H5M_iterate_t op; /* Iteration callback routine */ + void * op_data; /* Pointer to callback context */ + } iterate; + + /* H5VL_MAP_DELETE */ + struct { + H5VL_loc_params_t loc_params; /* Location parameters for object */ + hid_t key_mem_type_id; /* Memory datatype for key */ + const void * key; /* Pointer to key */ + } del; + } args; + } specific; + + /* H5VL_MAP_OPTIONAL */ + /* Unused */ + + /* H5VL_MAP_CLOSE */ + /* No args */ +} H5VL_map_args_t; + /********************/ /* Public Variables */ /********************/ @@ -478,6 +588,7 @@ H5_DLL herr_t H5Miterate_by_name(hid_t loc_id, const char *map_name, hsize_t *id */ H5_DLL herr_t H5Mdelete(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t dxpl_id); +/// \cond DEV /* API Wrappers for async routines */ /* (Must be defined _after_ the function prototype) */ /* (And must only defined when included in application code, not the library) */ @@ -496,6 +607,7 @@ H5_DLL herr_t H5Mdelete(hid_t map_id, hid_t key_mem_type_id, const void *key, hi #define H5Mput_async_wrap H5_NO_EXPAND(H5Mput_async) #define H5Mget_async_wrap H5_NO_EXPAND(H5Mget_async) #endif /* H5M_MODULE */ +/// \endcond /* Symbols defined for compatibility with previous versions of the HDF5 API. * diff --git a/src/H5O.c b/src/H5O.c index 732473f..db3ff31 100644 --- a/src/H5O.c +++ b/src/H5O.c @@ -70,7 +70,7 @@ static herr_t H5O__copy_api_common(hid_t src_loc_id, const char *src_name, hid_t H5VL_object_t **_vol_obj_ptr); static herr_t H5O__flush_api_common(hid_t obj_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr); static herr_t H5O__refresh_api_common(hid_t oid, void **token_ptr, H5VL_object_t **_vol_obj_ptr); -static htri_t H5O__close_check_common(hid_t object_id); +static htri_t H5O__close_check_type(hid_t object_id); /*********************/ /* Package Variables */ @@ -112,7 +112,7 @@ H5O__open_api_common(hid_t loc_id, const char *name, hid_t lapl_id, void **token /* name is checked in this H5VL_setup_name_args() */ /* Set up object access arguments */ - if (H5VL_setup_name_args(loc_id, name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) + if (H5VL_setup_name_args(loc_id, name, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") /* Open the object */ @@ -239,7 +239,7 @@ H5O__open_by_idx_api_common(hid_t loc_id, const char *group_name, H5_index_t idx /* Check args */ /* group_name, idx_type, order are checked in H5VL_setup_idx-args() */ /* Set up object access arguments */ - if (H5VL_setup_idx_args(loc_id, group_name, idx_type, order, n, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, + if (H5VL_setup_idx_args(loc_id, group_name, idx_type, order, n, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") @@ -617,8 +617,9 @@ H5O__flush_api_common(hid_t obj_id, void **token_ptr, H5VL_object_t **_vol_obj_p H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters for object access */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -626,9 +627,13 @@ H5O__flush_api_common(hid_t obj_id, void **token_ptr, H5VL_object_t **_vol_obj_p if (H5VL_setup_loc_args(obj_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set object access arguments") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_FLUSH; + vol_cb_args.args.flush.obj_id = obj_id; + /* Flush the object */ - if (H5VL_object_specific(*vol_obj_ptr, &loc_params, H5VL_OBJECT_FLUSH, H5P_DATASET_XFER_DEFAULT, - token_ptr, obj_id) < 0) + if (H5VL_object_specific(*vol_obj_ptr, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object") done: @@ -718,8 +723,9 @@ H5O__refresh_api_common(hid_t oid, void **token_ptr, H5VL_object_t **_vol_obj_pt H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters for object access */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -727,9 +733,13 @@ H5O__refresh_api_common(hid_t oid, void **token_ptr, H5VL_object_t **_vol_obj_pt if (H5VL_setup_loc_args(oid, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set object access arguments") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_REFRESH; + vol_cb_args.args.refresh.obj_id = oid; + /* Refresh the object */ - if (H5VL_object_specific(*vol_obj_ptr, &loc_params, H5VL_OBJECT_REFRESH, H5P_DATASET_XFER_DEFAULT, - token_ptr, oid) < 0) + if (H5VL_object_specific(*vol_obj_ptr, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object") done: @@ -828,12 +838,12 @@ done: herr_t H5Olink(hid_t obj_id, hid_t new_loc_id, const char *new_name, hid_t lcpl_id, hid_t lapl_id) { - H5VL_object_t * vol_obj1 = NULL; /* object of obj_id */ - H5VL_object_t * vol_obj2 = NULL; /* object of new_loc_id */ - H5VL_object_t tmp_vol_obj; /* Temporary object */ - H5VL_loc_params_t loc_params1; - H5VL_loc_params_t loc_params2; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj1 = NULL; /* object of obj_id */ + H5VL_object_t * vol_obj2 = NULL; /* object of new_loc_id */ + H5VL_object_t tmp_vol_obj; /* Temporary object */ + H5VL_link_create_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t new_loc_params; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "ii*sii", obj_id, new_loc_id, new_name, lcpl_id, lapl_id); @@ -863,36 +873,45 @@ H5Olink(hid_t obj_id, hid_t new_loc_id, const char *new_name, hid_t lcpl_id, hid if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, obj_id, TRUE) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set access property list info") - loc_params1.type = H5VL_OBJECT_BY_SELF; - loc_params1.obj_type = H5I_get_type(obj_id); - - loc_params2.type = H5VL_OBJECT_BY_NAME; - loc_params2.obj_type = H5I_get_type(new_loc_id); - loc_params2.loc_data.loc_by_name.name = new_name; - loc_params2.loc_data.loc_by_name.lapl_id = lapl_id; + /* Set up new location struct */ + new_loc_params.type = H5VL_OBJECT_BY_NAME; + new_loc_params.obj_type = H5I_get_type(new_loc_id); + new_loc_params.loc_data.loc_by_name.name = new_name; + new_loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - if (H5L_SAME_LOC != obj_id) - /* get the location object */ - if (NULL == (vol_obj1 = H5VL_vol_object(obj_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Get the first location object */ + if (NULL == (vol_obj1 = H5VL_vol_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") if (H5L_SAME_LOC != new_loc_id) /* get the location object */ if (NULL == (vol_obj2 = H5VL_vol_object(new_loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") /* Make sure that the VOL connectors are the same */ - if (vol_obj1 && vol_obj2) - if (vol_obj1->connector->cls->value != vol_obj2->connector->cls->value) + if (vol_obj1 && vol_obj2) { + int same_connector = 0; + + /* Check if both objects are associated with the same VOL connector */ + if (H5VL_cmp_connector_cls(&same_connector, vol_obj1->connector->cls, vol_obj2->connector->cls) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOMPARE, FAIL, "can't compare connector classes") + if (same_connector) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Objects are accessed through different VOL connectors and can't be linked") + } /* end if */ /* Construct a temporary VOL object */ tmp_vol_obj.data = vol_obj2->data; - tmp_vol_obj.connector = (vol_obj1 != NULL ? vol_obj1->connector : vol_obj2->connector); + tmp_vol_obj.connector = vol_obj1->connector; + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_CREATE_HARD; + vol_cb_args.args.hard.curr_obj = vol_obj1->data; + vol_cb_args.args.hard.curr_loc_params.type = H5VL_OBJECT_BY_SELF; + vol_cb_args.args.hard.curr_loc_params.obj_type = H5I_get_type(obj_id); /* Create a link to the object */ - if (H5VL_link_create(H5VL_LINK_CREATE_HARD, &tmp_vol_obj, &loc_params2, lcpl_id, lapl_id, - H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, vol_obj1->data, &loc_params1) < 0) + if (H5VL_link_create(&vol_cb_args, &tmp_vol_obj, &new_loc_params, lcpl_id, lapl_id, + H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL, "unable to create link") done: @@ -922,9 +941,10 @@ done: herr_t H5Oincr_refcount(hid_t object_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_object_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", object_id); @@ -940,9 +960,13 @@ H5Oincr_refcount(hid_t object_id) if (H5CX_set_loc(object_id) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_CHANGE_REF_COUNT; + vol_cb_args.args.change_rc.delta = 1; + /* Change the object's reference count */ - if (H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_CHANGE_REF_COUNT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, 1) < 0) + if (H5VL_object_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "modifying object link count failed") done: @@ -972,9 +996,10 @@ done: herr_t H5Odecr_refcount(hid_t object_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_object_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", object_id); @@ -990,9 +1015,13 @@ H5Odecr_refcount(hid_t object_id) if (H5CX_set_loc(object_id) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_CHANGE_REF_COUNT; + vol_cb_args.args.change_rc.delta = -1; + /* Change the object's reference count */ - if (H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_CHANGE_REF_COUNT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, -1) < 0) + if (H5VL_object_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "modifying object link count failed") done: @@ -1015,9 +1044,11 @@ done: htri_t H5Oexists_by_name(hid_t loc_id, const char *name, hid_t lapl_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - htri_t ret_value = FAIL; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_object_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + hbool_t obj_exists = FALSE; /* Whether object exists */ + htri_t ret_value = FAIL; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("t", "i*si", loc_id, name, lapl_id); @@ -1042,11 +1073,18 @@ H5Oexists_by_name(hid_t loc_id, const char *name, hid_t lapl_id) loc_params.loc_data.loc_by_name.lapl_id = lapl_id; loc_params.obj_type = H5I_get_type(loc_id); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_EXISTS; + vol_cb_args.args.exists.exists = &obj_exists; + /* Check if the object exists */ - if (H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_EXISTS, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &ret_value) < 0) + if (H5VL_object_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to determine if '%s' exists", name) + /* Set return value */ + ret_value = (htri_t)obj_exists; + done: FUNC_LEAVE_API(ret_value) } /* end H5Oexists_by_name() */ @@ -1066,9 +1104,10 @@ done: herr_t H5Oget_info3(hid_t loc_id, H5O_info2_t *oinfo /*out*/, unsigned fields) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "ixIu", loc_id, oinfo, fields); @@ -1087,9 +1126,13 @@ H5Oget_info3(hid_t loc_id, H5O_info2_t *oinfo /*out*/, unsigned fields) if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_INFO; + vol_cb_args.args.get_info.oinfo = oinfo; + vol_cb_args.args.get_info.fields = fields; + /* Retrieve the object's information */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - oinfo, fields) < 0) + if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get data model info for object") done: @@ -1113,8 +1156,9 @@ H5O__get_info_by_name_api_common(hid_t loc_id, const char *name, H5O_info2_t *oi H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters for object access */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -1126,12 +1170,16 @@ H5O__get_info_by_name_api_common(hid_t loc_id, const char *name, H5O_info2_t *oi /* "name" is checked in H5VL_setup_name_args() */ /* Set up object access arguments */ - if (H5VL_setup_name_args(loc_id, name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) + if (H5VL_setup_name_args(loc_id, name, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set object access arguments") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_INFO; + vol_cb_args.args.get_info.oinfo = oinfo; + vol_cb_args.args.get_info.fields = fields; + /* Retrieve the object's information */ - if (H5VL_object_get(*vol_obj_ptr, &loc_params, H5VL_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, token_ptr, - oinfo, fields) < 0) + if (H5VL_object_get(*vol_obj_ptr, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get data model info for object") done: @@ -1228,9 +1276,10 @@ herr_t H5Oget_info_by_idx3(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_info2_t *oinfo /*out*/, unsigned fields, hid_t lapl_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("e", "i*sIiIohxIui", loc_id, group_name, idx_type, order, n, oinfo, fields, lapl_id); @@ -1251,6 +1300,7 @@ H5Oget_info_by_idx3(hid_t loc_id, const char *group_name, H5_index_t idx_type, H if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set location struct fields */ loc_params.type = H5VL_OBJECT_BY_IDX; loc_params.loc_data.loc_by_idx.name = group_name; loc_params.loc_data.loc_by_idx.idx_type = idx_type; @@ -1263,9 +1313,13 @@ H5Oget_info_by_idx3(hid_t loc_id, const char *group_name, H5_index_t idx_type, H if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_INFO; + vol_cb_args.args.get_info.oinfo = oinfo; + vol_cb_args.args.get_info.fields = fields; + /* Retrieve the object's information */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - oinfo, fields) < 0) + if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get data model info for object") done: @@ -1287,9 +1341,11 @@ done: herr_t H5Oget_native_info(hid_t loc_id, H5O_native_info_t *oinfo /*out*/, unsigned fields) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "ixIu", loc_id, oinfo, fields); @@ -1308,9 +1364,15 @@ H5Oget_native_info(hid_t loc_id, H5O_native_info_t *oinfo /*out*/, unsigned fiel if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + obj_opt_args.get_native_info.fields = fields; + obj_opt_args.get_native_info.ninfo = oinfo; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_GET_NATIVE_INFO; + vol_cb_args.args = &obj_opt_args; + /* Retrieve the object's information */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_NATIVE_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, oinfo, fields) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get native file format info for object") done: @@ -1333,9 +1395,11 @@ herr_t H5Oget_native_info_by_name(hid_t loc_id, const char *name, H5O_native_info_t *oinfo /*out*/, unsigned fields, hid_t lapl_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "i*sxIui", loc_id, name, oinfo, fields, lapl_id); @@ -1364,9 +1428,15 @@ H5Oget_native_info_by_name(hid_t loc_id, const char *name, H5O_native_info_t *oi if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + obj_opt_args.get_native_info.fields = fields; + obj_opt_args.get_native_info.ninfo = oinfo; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_GET_NATIVE_INFO; + vol_cb_args.args = &obj_opt_args; + /* Retrieve the object's information */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_NATIVE_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, oinfo, fields) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get native file format info for object: '%s'", name) done: @@ -1391,9 +1461,11 @@ herr_t H5Oget_native_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_native_info_t *oinfo /*out*/, unsigned fields, hid_t lapl_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("e", "i*sIiIohxIui", loc_id, group_name, idx_type, order, n, oinfo, fields, lapl_id); @@ -1414,6 +1486,7 @@ H5Oget_native_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_t if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set location struct fields */ loc_params.type = H5VL_OBJECT_BY_IDX; loc_params.loc_data.loc_by_idx.name = group_name; loc_params.loc_data.loc_by_idx.idx_type = idx_type; @@ -1426,9 +1499,15 @@ H5Oget_native_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_t if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + obj_opt_args.get_native_info.fields = fields; + obj_opt_args.get_native_info.ninfo = oinfo; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_GET_NATIVE_INFO; + vol_cb_args.args = &obj_opt_args; + /* Retrieve the object's information */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_NATIVE_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, oinfo, fields) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get native file format info for object") done: @@ -1455,9 +1534,11 @@ done: herr_t H5Oset_comment(hid_t obj_id, const char *comment) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*s", obj_id, comment); @@ -1474,9 +1555,14 @@ H5Oset_comment(hid_t obj_id, const char *comment) loc_params.type = H5VL_OBJECT_BY_SELF; loc_params.obj_type = H5I_get_type(obj_id); + /* Set up VOL callback arguments */ + obj_opt_args.set_comment.comment = comment; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_SET_COMMENT; + vol_cb_args.args = &obj_opt_args; + /* (Re)set the object's comment */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_SET_COMMENT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, comment) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set comment for object") done: @@ -1503,9 +1589,11 @@ done: herr_t H5Oset_comment_by_name(hid_t loc_id, const char *name, const char *comment, hid_t lapl_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "i*s*si", loc_id, name, comment, lapl_id); @@ -1528,9 +1616,14 @@ H5Oset_comment_by_name(hid_t loc_id, const char *name, const char *comment, hid_ if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + obj_opt_args.set_comment.comment = comment; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_SET_COMMENT; + vol_cb_args.args = &obj_opt_args; + /* (Re)set the object's comment */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_SET_COMMENT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, comment) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set comment for object: '%s'", name) done: @@ -1556,9 +1649,12 @@ done: ssize_t H5Oget_comment(hid_t obj_id, char *comment /*out*/, size_t bufsize) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - ssize_t ret_value = -1; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5VL_loc_params_t loc_params; + size_t comment_len = 0; /* Length of comment string */ + ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE3("Zs", "ixz", obj_id, comment, bufsize); @@ -1571,11 +1667,21 @@ H5Oget_comment(hid_t obj_id, char *comment /*out*/, size_t bufsize) loc_params.type = H5VL_OBJECT_BY_SELF; loc_params.obj_type = H5I_get_type(obj_id); + /* Set up VOL callback arguments */ + obj_opt_args.get_comment.buf = comment; + obj_opt_args.get_comment.buf_size = bufsize; + obj_opt_args.get_comment.comment_len = &comment_len; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_GET_COMMENT; + vol_cb_args.args = &obj_opt_args; + /* Retrieve the object's comment */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_COMMENT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, comment, bufsize, &ret_value) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, (-1), "can't get comment for object") + /* Set return value */ + ret_value = (ssize_t)comment_len; + done: FUNC_LEAVE_API(ret_value) } /* end H5Oget_comment() */ @@ -1599,9 +1705,12 @@ done: ssize_t H5Oget_comment_by_name(hid_t loc_id, const char *name, char *comment /*out*/, size_t bufsize, hid_t lapl_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - ssize_t ret_value = -1; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5VL_loc_params_t loc_params; + size_t comment_len = 0; /* Length of comment string */ + ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE5("Zs", "i*sxzi", loc_id, name, comment, bufsize, lapl_id); @@ -1624,11 +1733,21 @@ H5Oget_comment_by_name(hid_t loc_id, const char *name, char *comment /*out*/, si if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid location identifier") + /* Set up VOL callback arguments */ + obj_opt_args.get_comment.buf = comment; + obj_opt_args.get_comment.buf_size = bufsize; + obj_opt_args.get_comment.comment_len = &comment_len; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_GET_COMMENT; + vol_cb_args.args = &obj_opt_args; + /* Retrieve the object's comment */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_COMMENT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, comment, bufsize, &ret_value) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, (-1), "can't get comment for object: '%s'", name) + /* Set return value */ + ret_value = (ssize_t)comment_len; + done: FUNC_LEAVE_API(ret_value) } /* end H5Oget_comment_by_name() */ @@ -1672,9 +1791,10 @@ herr_t H5Ovisit3(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate2_t op, void *op_data, unsigned fields) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_object_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "iIiIoOI*xIu", obj_id, idx_type, order, op, op_data, fields); @@ -1697,10 +1817,17 @@ H5Ovisit3(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate2 loc_params.type = H5VL_OBJECT_BY_SELF; loc_params.obj_type = H5I_get_type(obj_id); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_VISIT; + vol_cb_args.args.visit.idx_type = idx_type; + vol_cb_args.args.visit.order = order; + vol_cb_args.args.visit.op = op; + vol_cb_args.args.visit.op_data = op_data; + vol_cb_args.args.visit.fields = fields; + /* Visit the objects */ - if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_VISIT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, (int)idx_type, (int)order, op, op_data, fields)) < - 0) + if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object iteration failed") done: @@ -1746,9 +1873,10 @@ herr_t H5Ovisit_by_name3(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate2_t op, void *op_data, unsigned fields, hid_t lapl_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_object_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("e", "i*sIiIoOI*xIui", loc_id, obj_name, idx_type, order, op, op_data, fields, lapl_id); @@ -1781,10 +1909,17 @@ H5Ovisit_by_name3(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_it loc_params.loc_data.loc_by_name.lapl_id = lapl_id; loc_params.obj_type = H5I_get_type(loc_id); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_VISIT; + vol_cb_args.args.visit.idx_type = idx_type; + vol_cb_args.args.visit.order = order; + vol_cb_args.args.visit.op = op; + vol_cb_args.args.visit.op_data = op_data; + vol_cb_args.args.visit.fields = fields; + /* Visit the objects */ - if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_VISIT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, (int)idx_type, (int)order, op, op_data, fields)) < - 0) + if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object iteration failed") done: @@ -1792,23 +1927,23 @@ done: } /* end H5Ovisit_by_name3() */ /*------------------------------------------------------------------------- - * Function: H5O__close_check_common + * Function: H5O__close_check_type * * Purpose: This is the common function to validate an object - * when closing it. + * before closing it. * * Return: TRUE/FALSE/FAIL * *------------------------------------------------------------------------- */ static htri_t -H5O__close_check_common(hid_t object_id) +H5O__close_check_type(hid_t object_id) { htri_t ret_value = TRUE; /* Return value */ FUNC_ENTER_STATIC - /* Get the type of the object and close it in the correct way */ + /* Check for closeable object */ switch (H5I_get_type(object_id)) { case H5I_GROUP: case H5I_DATATYPE: @@ -1834,14 +1969,13 @@ H5O__close_check_common(hid_t object_id) case H5I_EVENTSET: case H5I_NTYPES: default: - HGOTO_ERROR(H5E_ARGS, H5E_CANTRELEASE, FALSE, - "not a valid file object ID (dataset, group, or datatype)") + HGOTO_DONE(FALSE); break; } /* end switch */ done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5O__close_check_common() */ +} /* H5O__close_check_type() */ /*------------------------------------------------------------------------- * Function: H5Oclose @@ -1869,7 +2003,7 @@ H5Oclose(hid_t object_id) H5TRACE1("e", "i", object_id); /* Validate the object type before closing */ - if (H5O__close_check_common(object_id) <= 0) + if (H5O__close_check_type(object_id) <= 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "not a valid object") if (H5I_dec_app_ref(object_id) < 0) @@ -1901,7 +2035,7 @@ H5Oclose_async(const char *app_file, const char *app_func, unsigned app_line, hi H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, object_id, es_id); /* Validate the object type before closing */ - if (H5O__close_check_common(object_id) <= 0) + if (H5O__close_check_type(object_id) <= 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "not a valid object") /* Prepare for possible asynchronous operation */ @@ -1941,7 +2075,7 @@ done: } /* end H5Oclose_async() */ /*------------------------------------------------------------------------- - * Function: H5O_disable_mdc_flushes + * Function: H5O__disable_mdc_flushes * * Purpose: Private version of the metadata cache cork function. * @@ -1950,18 +2084,18 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_disable_mdc_flushes(H5O_loc_t *oloc) +H5O__disable_mdc_flushes(H5O_loc_t *oloc) { herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(FAIL); + FUNC_ENTER_PACKAGE if (H5AC_cork(oloc->file, oloc->addr, H5AC__SET_CORK, NULL) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCORK, FAIL, "unable to cork object"); done: FUNC_LEAVE_NOAPI(ret_value); -} /* H5O_disable_mdc_flushes() */ +} /* H5O__disable_mdc_flushes() */ /*------------------------------------------------------------------------- * Function: H5Odisable_mdc_flushes @@ -1980,9 +2114,10 @@ done: herr_t H5Odisable_mdc_flushes(hid_t object_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL); H5TRACE1("e", "i", object_id); @@ -1999,9 +2134,13 @@ H5Odisable_mdc_flushes(hid_t object_id) loc_params.type = H5VL_OBJECT_BY_SELF; loc_params.obj_type = H5I_get_type(object_id); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_DISABLE_MDC_FLUSHES; + vol_cb_args.args = NULL; + /* Cork the object */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_DISABLE_MDC_FLUSHES, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCORK, FAIL, "unable to cork object"); done: @@ -2009,7 +2148,7 @@ done: } /* H5Odisable_mdc_flushes() */ /*------------------------------------------------------------------------- - * Function: H5O_enable_mdc_flushes + * Function: H5O__enable_mdc_flushes * * Purpose: Private version of the metadata cache uncork function. * @@ -2018,18 +2157,18 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_enable_mdc_flushes(H5O_loc_t *oloc) +H5O__enable_mdc_flushes(H5O_loc_t *oloc) { herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(FAIL); + FUNC_ENTER_PACKAGE if (H5AC_cork(oloc->file, oloc->addr, H5AC__UNCORK, NULL) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTUNCORK, FAIL, "unable to uncork object"); done: FUNC_LEAVE_NOAPI(ret_value); -} /* H5O_enable_mdc_flushes() */ +} /* H5O__enable_mdc_flushes() */ /*------------------------------------------------------------------------- * Function: H5Oenable_mdc_flushes @@ -2048,9 +2187,10 @@ done: herr_t H5Oenable_mdc_flushes(hid_t object_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL); H5TRACE1("e", "i", object_id); @@ -2067,9 +2207,13 @@ H5Oenable_mdc_flushes(hid_t object_id) loc_params.type = H5VL_OBJECT_BY_SELF; loc_params.obj_type = H5I_get_type(object_id); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_ENABLE_MDC_FLUSHES; + vol_cb_args.args = NULL; + /* Uncork the object */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_ENABLE_MDC_FLUSHES, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTUNCORK, FAIL, "unable to uncork object"); done: @@ -2077,7 +2221,7 @@ done: } /* H5Oenable_mdc_flushes() */ /*------------------------------------------------------------------------- - * Function: H5O_are_mdc_flushes_disabled + * Function: H5O__are_mdc_flushes_disabled * * Purpose: Private version of cork status getter. * @@ -2086,11 +2230,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_are_mdc_flushes_disabled(H5O_loc_t *oloc, hbool_t *are_disabled) +H5O__are_mdc_flushes_disabled(const H5O_loc_t *oloc, hbool_t *are_disabled) { herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(FAIL); + FUNC_ENTER_PACKAGE HDassert(are_disabled); @@ -2099,7 +2243,7 @@ H5O_are_mdc_flushes_disabled(H5O_loc_t *oloc, hbool_t *are_disabled) done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5O_are_mdc_flushes_disabled() */ +} /* H5O__are_mdc_flushes_disabled() */ /*------------------------------------------------------------------------- * Function: H5Oare_mdc_flushes_disabled @@ -2121,9 +2265,11 @@ done: herr_t H5Oare_mdc_flushes_disabled(hid_t object_id, hbool_t *are_disabled) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5VL_loc_params_t loc_params; /* Location parameters */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL); H5TRACE2("e", "i*b", object_id, are_disabled); @@ -2144,9 +2290,14 @@ H5Oare_mdc_flushes_disabled(hid_t object_id, hbool_t *are_disabled) loc_params.type = H5VL_OBJECT_BY_SELF; loc_params.obj_type = H5I_get_type(object_id); + /* Set up VOL callback arguments */ + obj_opt_args.are_mdc_flushes_disabled.flag = are_disabled; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_ARE_MDC_FLUSHES_DISABLED; + vol_cb_args.args = &obj_opt_args; + /* Get the cork status */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_ARE_MDC_FLUSHES_DISABLED, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, are_disabled) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to retrieve object's cork status"); done: diff --git a/src/H5Ocache.c b/src/H5Ocache.c index a968f84..8eed092 100644 --- a/src/H5Ocache.c +++ b/src/H5Ocache.c @@ -78,8 +78,8 @@ static herr_t H5O__cache_chk_free_icr(void *thing); static herr_t H5O__prefix_deserialize(const uint8_t *image, H5O_cache_ud_t *udata); /* Chunk routines */ -static herr_t H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t len, const uint8_t *image, - H5O_common_cache_ud_t *udata, hbool_t *dirty); +static herr_t H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t chunk_size, const uint8_t *image, + size_t len, H5O_common_cache_ud_t *udata, hbool_t *dirty); static herr_t H5O__chunk_serialize(const H5F_t *f, H5O_t *oh, unsigned chunkno); /* Misc. routines */ @@ -289,7 +289,7 @@ H5O__cache_verify_chksum(const void *_image, size_t len, void *_udata) *------------------------------------------------------------------------- */ static void * -H5O__cache_deserialize(const void *image, size_t H5_ATTR_NDEBUG_UNUSED len, void *_udata, hbool_t *dirty) +H5O__cache_deserialize(const void *image, size_t len, void *_udata, hbool_t *dirty) { H5O_t * oh = NULL; /* Object header read in */ H5O_cache_ud_t *udata = (H5O_cache_ud_t *)_udata; /* User data for callback */ @@ -335,7 +335,7 @@ H5O__cache_deserialize(const void *image, size_t H5_ATTR_NDEBUG_UNUSED len, void oh->proxy = NULL; /* Parse the first chunk */ - if (H5O__chunk_deserialize(oh, udata->common.addr, udata->chunk0_size, (const uint8_t *)image, + if (H5O__chunk_deserialize(oh, udata->common.addr, udata->chunk0_size, (const uint8_t *)image, len, &(udata->common), dirty) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't deserialize first object header chunk") @@ -738,7 +738,7 @@ H5O__cache_chk_verify_chksum(const void *_image, size_t len, void *_udata) *------------------------------------------------------------------------- */ static void * -H5O__cache_chk_deserialize(const void *image, size_t H5_ATTR_NDEBUG_UNUSED len, void *_udata, hbool_t *dirty) +H5O__cache_chk_deserialize(const void *image, size_t len, void *_udata, hbool_t *dirty) { H5O_chunk_proxy_t * chk_proxy = NULL; /* Chunk proxy object */ H5O_chk_cache_ud_t *udata = (H5O_chk_cache_ud_t *)_udata; /* User data for callback */ @@ -765,7 +765,7 @@ H5O__cache_chk_deserialize(const void *image, size_t H5_ATTR_NDEBUG_UNUSED len, HDassert(udata->common.cont_msg_info); /* Parse the chunk */ - if (H5O__chunk_deserialize(udata->oh, udata->common.addr, udata->size, (const uint8_t *)image, + if (H5O__chunk_deserialize(udata->oh, udata->common.addr, udata->size, (const uint8_t *)image, len, &(udata->common), dirty) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't deserialize object header chunk") @@ -1277,7 +1277,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t len, const uint8_t *image, +H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t chunk_size, const uint8_t *image, size_t len, H5O_common_cache_ud_t *udata, hbool_t *dirty) { const uint8_t *chunk_image; /* Pointer into buffer to decode */ @@ -1297,6 +1297,7 @@ H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t len, const uint8_t *image HDassert(oh); HDassert(H5F_addr_defined(addr)); HDassert(image); + HDassert(len); HDassert(udata->f); HDassert(udata->cont_msg_info); @@ -1317,14 +1318,16 @@ H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t len, const uint8_t *image oh->chunk[chunkno].addr = addr; if (chunkno == 0) /* First chunk's 'image' includes room for the object header prefix */ - oh->chunk[0].size = len + (size_t)H5O_SIZEOF_HDR(oh); + oh->chunk[0].size = chunk_size + (size_t)H5O_SIZEOF_HDR(oh); else - oh->chunk[chunkno].size = len; + oh->chunk[chunkno].size = chunk_size; if (NULL == (oh->chunk[chunkno].image = H5FL_BLK_MALLOC(chunk_image, oh->chunk[chunkno].size))) HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, FAIL, "memory allocation failed") oh->chunk[chunkno].chunk_proxy = NULL; /* Copy disk image into chunk's image */ + if (len < oh->chunk[chunkno].size) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "attempted to copy too many disk image bytes into buffer") H5MM_memcpy(oh->chunk[chunkno].image, image, oh->chunk[chunkno].size); /* Point into chunk image to decode */ diff --git a/src/H5Odeprec.c b/src/H5Odeprec.c index 5e13f9f..7def20a 100644 --- a/src/H5Odeprec.c +++ b/src/H5Odeprec.c @@ -122,8 +122,6 @@ H5O__iterate1_adapter(hid_t obj_id, const char *name, const H5O_info2_t *oinfo2, H5O_info1_t oinfo; /* Deprecated object info struct */ unsigned dm_fields; /* Fields for data model query */ unsigned nat_fields; /* Fields for native query */ - H5VL_object_t * vol_obj; /* Object of obj_id */ - H5VL_loc_params_t loc_params; /* Location parameters for VOL callback */ herr_t ret_value = H5_ITER_CONT; /* Return value */ FUNC_ENTER_STATIC @@ -160,24 +158,34 @@ H5O__iterate1_adapter(hid_t obj_id, const char *name, const H5O_info2_t *oinfo2, oinfo.num_attrs = oinfo2->num_attrs; } - /* Fill out location struct */ - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.loc_data.loc_by_name.name = name; - loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; - loc_params.obj_type = H5I_get_type(obj_id); - - /* Get the location object */ - if (NULL == (vol_obj = H5VL_vol_object(obj_id))) - HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, H5_ITER_ERROR, "invalid location identifier") - /* Check for retrieving native information */ nat_fields = shim_data->fields & (H5O_INFO_HDR | H5O_INFO_META_SIZE); if (nat_fields) { - H5O_native_info_t nat_info; /* Native object info */ + H5VL_object_t * vol_obj; /* Object of obj_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5VL_loc_params_t loc_params; /* Location parameters for VOL callback */ + H5O_native_info_t nat_info; /* Native object info */ + + /* Fill out location struct */ + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = name; + loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; + loc_params.obj_type = H5I_get_type(obj_id); + + /* Get the location object */ + if (NULL == (vol_obj = H5VL_vol_object(obj_id))) + HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, H5_ITER_ERROR, "invalid location identifier") + + /* Set up VOL callback arguments */ + obj_opt_args.get_native_info.fields = nat_fields; + obj_opt_args.get_native_info.ninfo = &nat_info; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_GET_NATIVE_INFO; + vol_cb_args.args = &obj_opt_args; /* Retrieve the object's native information */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_NATIVE_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, &nat_info, nat_fields) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get native info for object") /* Set the native fields */ @@ -228,11 +236,16 @@ H5O__get_info_old(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, H5O_inf /* Check for retrieving data model information */ dm_fields = fields & (H5O_INFO_BASIC | H5O_INFO_TIME | H5O_INFO_NUM_ATTRS); if (dm_fields) { - H5O_info2_t dm_info; /* Data model object info */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5O_info2_t dm_info; /* Data model object info */ + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_INFO; + vol_cb_args.args.get_info.oinfo = &dm_info; + vol_cb_args.args.get_info.fields = dm_fields; /* Retrieve the object's data model information */ - if (H5VL_object_get(vol_obj, loc_params, H5VL_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &dm_info, dm_fields) < 0) + if (H5VL_object_get(vol_obj, loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get data model info for object") /* Set the data model fields */ @@ -265,11 +278,19 @@ H5O__get_info_old(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, H5O_inf /* Check for retrieving native information */ nat_fields = fields & (H5O_INFO_HDR | H5O_INFO_META_SIZE); if (nat_fields) { - H5O_native_info_t nat_info; /* Native object info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5O_native_info_t nat_info; /* Native object info */ + + /* Set up VOL callback arguments */ + obj_opt_args.get_native_info.fields = nat_fields; + obj_opt_args.get_native_info.ninfo = &nat_info; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_GET_NATIVE_INFO; + vol_cb_args.args = &obj_opt_args; /* Retrieve the object's native information */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_NATIVE_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, loc_params, &nat_info, nat_fields) < 0) + if (H5VL_object_optional(vol_obj, loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get native info for object") /* Set the native fields */ @@ -751,10 +772,11 @@ done: herr_t H5Ovisit1(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate1_t op, void *op_data) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5O_visit1_adapter_t shim_data; /* Adapter for passing app callback & user data */ - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_object_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5O_visit1_adapter_t shim_data; /* Adapter for passing app callback & user data */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "iIiIoOi*x", obj_id, idx_type, order, op, op_data); @@ -780,10 +802,17 @@ H5Ovisit1(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate1 shim_data.fields = H5O_INFO_ALL; shim_data.real_op_data = op_data; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_VISIT; + vol_cb_args.args.visit.idx_type = idx_type; + vol_cb_args.args.visit.order = order; + vol_cb_args.args.visit.op = H5O__iterate1_adapter; + vol_cb_args.args.visit.op_data = &shim_data; + vol_cb_args.args.visit.fields = H5O_INFO_ALL; + /* Visit the objects */ - if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_VISIT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, (int)idx_type, (int)order, H5O__iterate1_adapter, - (void *)&shim_data, H5O_INFO_ALL)) < 0) + if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object visitation failed") done: @@ -826,10 +855,11 @@ herr_t H5Ovisit_by_name1(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate1_t op, void *op_data, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5O_visit1_adapter_t shim_data; /* Adapter for passing app callback & user data */ - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_object_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5O_visit1_adapter_t shim_data; /* Adapter for passing app callback & user data */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE7("e", "i*sIiIoOi*xi", loc_id, obj_name, idx_type, order, op, op_data, lapl_id); @@ -865,10 +895,17 @@ H5Ovisit_by_name1(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_it shim_data.fields = H5O_INFO_ALL; shim_data.real_op_data = op_data; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_VISIT; + vol_cb_args.args.visit.idx_type = idx_type; + vol_cb_args.args.visit.order = order; + vol_cb_args.args.visit.op = H5O__iterate1_adapter; + vol_cb_args.args.visit.op_data = &shim_data; + vol_cb_args.args.visit.fields = H5O_INFO_ALL; + /* Visit the objects */ - if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_VISIT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, (int)idx_type, (int)order, H5O__iterate1_adapter, - (void *)&shim_data, H5O_INFO_ALL)) < 0) + if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object visitation failed") done: @@ -914,11 +951,12 @@ herr_t H5Ovisit2(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate1_t op, void *op_data, unsigned fields) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5O_visit1_adapter_t shim_data; /* Adapter for passing app callback & user data */ - hbool_t is_native_vol_obj; - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_object_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5O_visit1_adapter_t shim_data; /* Adapter for passing app callback & user data */ + hbool_t is_native_vol_obj; + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "iIiIoOi*xIu", obj_id, idx_type, order, op, op_data, fields); @@ -954,10 +992,17 @@ H5Ovisit2(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate1 shim_data.fields = fields; shim_data.real_op_data = op_data; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_VISIT; + vol_cb_args.args.visit.idx_type = idx_type; + vol_cb_args.args.visit.order = order; + vol_cb_args.args.visit.op = H5O__iterate1_adapter; + vol_cb_args.args.visit.op_data = &shim_data; + vol_cb_args.args.visit.fields = fields; + /* Visit the objects */ - if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_VISIT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, (int)idx_type, (int)order, H5O__iterate1_adapter, - (void *)&shim_data, fields)) < 0) + if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object iteration failed") done: @@ -1003,11 +1048,12 @@ herr_t H5Ovisit_by_name2(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate1_t op, void *op_data, unsigned fields, hid_t lapl_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5O_visit1_adapter_t shim_data; /* Adapter for passing app callback & user data */ - hbool_t is_native_vol_obj; - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_object_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5O_visit1_adapter_t shim_data; /* Adapter for passing app callback & user data */ + hbool_t is_native_vol_obj; + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("e", "i*sIiIoOi*xIui", loc_id, obj_name, idx_type, order, op, op_data, fields, lapl_id); @@ -1053,10 +1099,17 @@ H5Ovisit_by_name2(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_it shim_data.fields = fields; shim_data.real_op_data = op_data; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_VISIT; + vol_cb_args.args.visit.idx_type = idx_type; + vol_cb_args.args.visit.order = order; + vol_cb_args.args.visit.op = H5O__iterate1_adapter; + vol_cb_args.args.visit.op_data = &shim_data; + vol_cb_args.args.visit.fields = fields; + /* Visit the objects */ - if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_VISIT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, (int)idx_type, (int)order, H5O__iterate1_adapter, - (void *)&shim_data, fields)) < 0) + if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object iteration failed") done: diff --git a/src/H5Oflush.c b/src/H5Oflush.c index 2e3c1fd..f2eacd6 100644 --- a/src/H5Oflush.c +++ b/src/H5Oflush.c @@ -49,7 +49,7 @@ /* Local Prototypes */ /********************/ static herr_t H5O__oh_tag(const H5O_loc_t *oloc, haddr_t *tag); -static herr_t H5O__refresh_metadata_close(hid_t oid, H5O_loc_t oloc, H5G_loc_t *obj_loc); +static herr_t H5O__refresh_metadata_close(H5O_loc_t *oloc, H5G_loc_t *obj_loc, hid_t oid); /*************/ /* Functions */ @@ -194,7 +194,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc) +H5O_refresh_metadata(H5O_loc_t *oloc, hid_t oid) { hbool_t objs_incr = FALSE; /* Whether the object count in the file was incremented */ herr_t ret_value = SUCCEED; /* Return value */ @@ -202,7 +202,7 @@ H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc) FUNC_ENTER_NOAPI(FAIL) /* If the file is opened with write access, no need to perform refresh actions. */ - if (!(H5F_INTENT(oloc.file) & H5F_ACC_RDWR)) { + if (!(H5F_INTENT(oloc->file) & H5F_ACC_RDWR)) { H5G_loc_t obj_loc; H5O_loc_t obj_oloc; H5G_name_t obj_path; @@ -219,7 +219,7 @@ H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc) /* "Fake" another open object in the file, so that it doesn't get closed * if this object is the only thing holding the file open. */ - H5F_incr_nopen_objs(oloc.file); + H5F_incr_nopen_objs(oloc->file); objs_incr = TRUE; /* Get the VOL object from the ID and cache a pointer to the connector. @@ -252,7 +252,7 @@ H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc) connector->nrefs++; /* Close object & evict its metadata */ - if ((H5O__refresh_metadata_close(oid, oloc, &obj_loc)) < 0) + if (H5O__refresh_metadata_close(oloc, &obj_loc, oid) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object") /* Re-open the object, re-fetching its metadata */ @@ -280,7 +280,7 @@ H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc) done: if (objs_incr) - H5F_decr_nopen_objs(oloc.file); + H5F_decr_nopen_objs(oloc->file); FUNC_LEAVE_NOAPI(ret_value); } /* end H5O_refresh_metadata() */ @@ -305,8 +305,9 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5O__refresh_metadata_close(hid_t oid, H5O_loc_t oloc, H5G_loc_t *obj_loc) +H5O__refresh_metadata_close(H5O_loc_t *oloc, H5G_loc_t *obj_loc, hid_t oid) { + H5F_t * file; /* Local copy of the object's file pointer */ haddr_t tag = 0; /* Tag for object */ hbool_t corked = FALSE; /* Whether object's metadata is corked */ herr_t ret_value = SUCCEED; /* Return value */ @@ -327,28 +328,32 @@ H5O__refresh_metadata_close(hid_t oid, H5O_loc_t oloc, H5G_loc_t *obj_loc) HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to prepare refresh for dataset") /* Retrieve tag for object */ - if (H5O__oh_tag(&oloc, &tag) < 0) + if (H5O__oh_tag(oloc, &tag) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to get object header address") /* Get cork status of the object with tag */ - if (H5AC_cork(oloc.file, tag, H5AC__GET_CORKED, &corked) < 0) + if (H5AC_cork(oloc->file, tag, H5AC__GET_CORKED, &corked) < 0) HGOTO_ERROR(H5E_OHDR, H5E_SYSTEM, FAIL, "unable to retrieve an object's cork status") + /* Hold a copy of the object's file pointer, since closing the object will + * invalidate the file pointer in the oloc. + */ + file = oloc->file; /* Close the object */ if (H5I_dec_ref(oid) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to close object") /* Flush metadata based on tag value of the object */ - if (H5F_flush_tagged_metadata(oloc.file, tag) < 0) + if (H5F_flush_tagged_metadata(file, tag) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush tagged metadata") /* Evict the object's tagged metadata */ - if (H5F_evict_tagged_metadata(oloc.file, tag) < 0) + if (H5F_evict_tagged_metadata(file, tag) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to evict metadata") /* Re-cork object with tag */ if (corked) - if (H5AC_cork(oloc.file, tag, H5AC__SET_CORK, &corked) < 0) + if (H5AC_cork(file, tag, H5AC__SET_CORK, &corked) < 0) HGOTO_ERROR(H5E_OHDR, H5E_SYSTEM, FAIL, "unable to cork the object") done: diff --git a/src/H5Ofsinfo.c b/src/H5Ofsinfo.c index 44c4985..b60f589 100644 --- a/src/H5Ofsinfo.c +++ b/src/H5Ofsinfo.c @@ -91,11 +91,12 @@ H5FL_DEFINE_STATIC(H5O_fsinfo_t); */ static void * H5O__fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, - unsigned H5_ATTR_UNUSED *ioflags, size_t H5_ATTR_UNUSED p_size, const uint8_t *p) + unsigned H5_ATTR_UNUSED *ioflags, size_t p_size, const uint8_t *p) { - H5O_fsinfo_t * fsinfo = NULL; /* File space info message */ - H5F_mem_page_t ptype; /* Memory type for iteration */ - unsigned vers; /* message version */ + H5O_fsinfo_t * fsinfo = NULL; /* File space info message */ + H5F_mem_page_t ptype; /* Memory type for iteration */ + unsigned vers; /* message version */ + const uint8_t *p_end = p + p_size; void * ret_value = NULL; /* Return value */ FUNC_ENTER_STATIC @@ -136,8 +137,12 @@ H5O__fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU fsinfo->threshold = threshold; if (HADDR_UNDEF == (fsinfo->eoa_pre_fsm_fsalloc = H5F_get_eoa(f, H5FD_MEM_DEFAULT))) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to get file size") - for (type = H5FD_MEM_SUPER; type < H5FD_MEM_NTYPES; type++) + for (type = H5FD_MEM_SUPER; type < H5FD_MEM_NTYPES; type++) { + if (p + H5_SIZEOF_HADDR_T > p_end) + HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, NULL, + "ran off end of input buffer while decoding") H5F_addr_decode(f, &p, &(fsinfo->fs_addr[type - 1])); + } break; case H5F_FILE_SPACE_ALL: diff --git a/src/H5Omodule.h b/src/H5Omodule.h index 134aa92..8afba29 100644 --- a/src/H5Omodule.h +++ b/src/H5Omodule.h @@ -30,9 +30,46 @@ #define H5_MY_PKG_INIT YES /**\defgroup H5O H5O - * \brief Object Interface * - * \todo Describe concisely what the functions in this module are about. + * Use the functions in this module to manage HDF5 objects. + * + * HDF5 objects (groups, datasets, datatype objects) are usually created + * using functions in the object-specific modules (\ref H5G, \ref H5D, + * \ref H5T). However, new objects can also be created by copying existing + * objects. + * + * Many functions in this module are variations on object introspection, + * that is, the retrieval of detailed information about HDF5 objects in a file. + * Objects in an HDF5 file can be "visited" in an iterative fashion. + * + * HDF5 objects are usually updated using functions in the object-specific + * modules. However, there are certain generic object properties, such as + * reference counts, that can be manipulated using functions in this module. + * + * HDF5 objects are deleted as a side effect of rendering them unreachable + * from the root group. The net effect is the diminution of the object's + * reference count to zero, which can (but should not usually) be effected + * by a function in this module. + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5O_examples.c create + * </td> + * <td> + * \snippet{lineno} H5O_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5O_examples.c update + * </td> + * <td> + * \snippet{lineno} H5O_examples.c delete + * </td> + * </tr> + * </table> * */ #endif /* H5Omodule_H */ diff --git a/src/H5Opkg.h b/src/H5Opkg.h index 6e203bb..331fcf6 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -581,6 +581,11 @@ H5_DLL herr_t H5O__chunk_resize(H5O_t *oh, H5O_chunk_proxy_t *chk_pr H5_DLL herr_t H5O__chunk_delete(H5F_t *f, H5O_t *oh, unsigned idx); H5_DLL herr_t H5O__chunk_dest(H5O_chunk_proxy_t *chunk_proxy); +/* Cache corking functions */ +H5_DLL herr_t H5O__disable_mdc_flushes(H5O_loc_t *oloc); +H5_DLL herr_t H5O__enable_mdc_flushes(H5O_loc_t *oloc); +H5_DLL herr_t H5O__are_mdc_flushes_disabled(const H5O_loc_t *oloc, hbool_t *are_disabled); + /* Collect storage info for btree and heap */ H5_DLL herr_t H5O__attr_bh_info(H5F_t *f, H5O_t *oh, H5_ih_info_t *bh_info); diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index d3b469c..72306df 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -990,13 +990,9 @@ H5_DLL herr_t H5O_msg_get_flags(const H5O_loc_t *loc, unsigned type_id, uint8_t /* Object metadata flush/refresh routines */ H5_DLL herr_t H5O_flush(H5O_loc_t *oloc, hid_t obj_id); H5_DLL herr_t H5O_flush_common(H5O_loc_t *oloc, hid_t obj_id); -H5_DLL herr_t H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc); -H5_DLL herr_t H5O_refresh_metadata_reopen(hid_t, H5G_loc_t *, const H5O_refresh_state_t *, H5VL_t *, hbool_t); - -/* Cache corking functions */ -H5_DLL herr_t H5O_disable_mdc_flushes(H5O_loc_t *oloc); -H5_DLL herr_t H5O_enable_mdc_flushes(H5O_loc_t *oloc); -H5_DLL herr_t H5O_are_mdc_flushes_disabled(H5O_loc_t *oloc, hbool_t *are_disabled); +H5_DLL herr_t H5O_refresh_metadata(H5O_loc_t *oloc, hid_t oid); +H5_DLL herr_t H5O_refresh_metadata_reopen(hid_t oid, H5G_loc_t *obj_loc, const H5O_refresh_state_t *state, + H5VL_t *vol_driver, hbool_t start_swmr); /* Object copying routines */ H5_DLL herr_t H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, diff --git a/src/H5Opublic.h b/src/H5Opublic.h index 7bc7784..d9d0500 100644 --- a/src/H5Opublic.h +++ b/src/H5Opublic.h @@ -35,14 +35,14 @@ /*****************/ /* Flags for object copy (H5Ocopy) */ -#define H5O_COPY_SHALLOW_HIERARCHY_FLAG (0x0001u) /* Copy only immediate members */ -#define H5O_COPY_EXPAND_SOFT_LINK_FLAG (0x0002u) /* Expand soft links into new objects */ -#define H5O_COPY_EXPAND_EXT_LINK_FLAG (0x0004u) /* Expand external links into new objects */ -#define H5O_COPY_EXPAND_REFERENCE_FLAG (0x0008u) /* Copy objects that are pointed by references */ -#define H5O_COPY_WITHOUT_ATTR_FLAG (0x0010u) /* Copy object without copying attributes */ -#define H5O_COPY_PRESERVE_NULL_FLAG (0x0020u) /* Copy NULL messages (empty space) */ -#define H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG (0x0040u) /* Merge committed datatypes in dest file */ -#define H5O_COPY_ALL (0x007Fu) /* All object copying flags (for internal checking) */ +#define H5O_COPY_SHALLOW_HIERARCHY_FLAG (0x0001u) /**< Copy only immediate members */ +#define H5O_COPY_EXPAND_SOFT_LINK_FLAG (0x0002u) /**< Expand soft links into new objects */ +#define H5O_COPY_EXPAND_EXT_LINK_FLAG (0x0004u) /**< Expand external links into new objects */ +#define H5O_COPY_EXPAND_REFERENCE_FLAG (0x0008u) /**< Copy objects that are pointed by references */ +#define H5O_COPY_WITHOUT_ATTR_FLAG (0x0010u) /**< Copy object without copying attributes */ +#define H5O_COPY_PRESERVE_NULL_FLAG (0x0020u) /**< Copy NULL messages (empty space) */ +#define H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG (0x0040u) /**< Merge committed datatypes in dest file */ +#define H5O_COPY_ALL (0x007Fu) /**< All object copying flags (for internal checking) */ /* Flags for shared message indexes. * Pass these flags in using the mesg_type_flags parameter in @@ -51,25 +51,27 @@ * but we need to assign each kind of message to a different bit so that * one index can hold multiple types.) */ -#define H5O_SHMESG_NONE_FLAG 0x0000 /* No shared messages */ -#define H5O_SHMESG_SDSPACE_FLAG ((unsigned)1 << 0x0001) /* Simple Dataspace Message. */ -#define H5O_SHMESG_DTYPE_FLAG ((unsigned)1 << 0x0003) /* Datatype Message. */ -#define H5O_SHMESG_FILL_FLAG ((unsigned)1 << 0x0005) /* Fill Value Message. */ -#define H5O_SHMESG_PLINE_FLAG ((unsigned)1 << 0x000b) /* Filter pipeline message. */ -#define H5O_SHMESG_ATTR_FLAG ((unsigned)1 << 0x000c) /* Attribute Message. */ +#define H5O_SHMESG_NONE_FLAG 0x0000 /**< No shared messages */ +#define H5O_SHMESG_SDSPACE_FLAG ((unsigned)1 << 0x0001) /**< Simple Dataspace Message. */ +#define H5O_SHMESG_DTYPE_FLAG ((unsigned)1 << 0x0003) /**< Datatype Message. */ +#define H5O_SHMESG_FILL_FLAG ((unsigned)1 << 0x0005) /**< Fill Value Message. */ +#define H5O_SHMESG_PLINE_FLAG ((unsigned)1 << 0x000b) /**< Filter pipeline message. */ +#define H5O_SHMESG_ATTR_FLAG ((unsigned)1 << 0x000c) /**< Attribute Message. */ #define H5O_SHMESG_ALL_FLAG \ (H5O_SHMESG_SDSPACE_FLAG | H5O_SHMESG_DTYPE_FLAG | H5O_SHMESG_FILL_FLAG | H5O_SHMESG_PLINE_FLAG | \ H5O_SHMESG_ATTR_FLAG) +/* clang-format off */ /* Object header status flag definitions */ -#define H5O_HDR_CHUNK0_SIZE 0x03 /* 2-bit field indicating # of bytes to store the size of chunk 0's data */ -#define H5O_HDR_ATTR_CRT_ORDER_TRACKED 0x04 /* Attribute creation order is tracked */ -#define H5O_HDR_ATTR_CRT_ORDER_INDEXED 0x08 /* Attribute creation order has index */ -#define H5O_HDR_ATTR_STORE_PHASE_CHANGE 0x10 /* Non-default attribute storage phase change values stored */ -#define H5O_HDR_STORE_TIMES 0x20 /* Store access, modification, change & birth times for object */ +#define H5O_HDR_CHUNK0_SIZE 0x03 /**< 2-bit field indicating # of bytes to store the size of chunk 0's data */ +#define H5O_HDR_ATTR_CRT_ORDER_TRACKED 0x04 /**< Attribute creation order is tracked */ +#define H5O_HDR_ATTR_CRT_ORDER_INDEXED 0x08 /**< Attribute creation order has index */ +#define H5O_HDR_ATTR_STORE_PHASE_CHANGE 0x10 /**< Non-default attribute storage phase change values stored */ +#define H5O_HDR_STORE_TIMES 0x20 /**< Store access, modification, change & birth times for object */ #define H5O_HDR_ALL_FLAGS \ (H5O_HDR_CHUNK0_SIZE | H5O_HDR_ATTR_CRT_ORDER_TRACKED | H5O_HDR_ATTR_CRT_ORDER_INDEXED | \ H5O_HDR_ATTR_STORE_PHASE_CHANGE | H5O_HDR_STORE_TIMES) +/* clang-format on */ /* Maximum shared message values. Number of indexes is 8 to allow room to add * new types of messages. @@ -81,9 +83,9 @@ * Theses flags determine which fields will be filled in in the H5O_info_t * struct. */ -#define H5O_INFO_BASIC 0x0001u /* Fill in the fileno, addr, type, and rc fields */ -#define H5O_INFO_TIME 0x0002u /* Fill in the atime, mtime, ctime, and btime fields */ -#define H5O_INFO_NUM_ATTRS 0x0004u /* Fill in the num_attrs field */ +#define H5O_INFO_BASIC 0x0001u /**< Fill in the fileno, addr, type, and rc fields */ +#define H5O_INFO_TIME 0x0002u /**< Fill in the atime, mtime, ctime, and btime fields */ +#define H5O_INFO_NUM_ATTRS 0x0004u /**< Fill in the num_attrs field */ #define H5O_INFO_ALL (H5O_INFO_BASIC | H5O_INFO_TIME | H5O_INFO_NUM_ATTRS) //! <!-- [H5O_native_info_fields_snip] --> @@ -91,8 +93,8 @@ * Flags for H5Oget_native_info(). Theses flags determine which fields will be * filled in in the \ref H5O_native_info_t struct. */ -#define H5O_NATIVE_INFO_HDR 0x0008u /* Fill in the hdr field */ -#define H5O_NATIVE_INFO_META_SIZE 0x0010u /* Fill in the meta_size field */ +#define H5O_NATIVE_INFO_HDR 0x0008u /**< Fill in the hdr field */ +#define H5O_NATIVE_INFO_META_SIZE 0x0010u /**< Fill in the meta_size field */ #define H5O_NATIVE_INFO_ALL (H5O_NATIVE_INFO_HDR | H5O_NATIVE_INFO_META_SIZE) //! <!-- [H5O_native_info_fields_snip] --> @@ -146,15 +148,15 @@ typedef struct H5O_hdr_info_t { * (For H5Oget_info(), H5Oget_info_by_name(), H5Oget_info_by_idx() version 3) */ typedef struct H5O_info2_t { - unsigned long fileno; /* File number that object is located in */ - H5O_token_t token; /* Token representing the object */ - H5O_type_t type; /* Basic object type (group, dataset, etc.) */ - unsigned rc; /* Reference count of object */ - time_t atime; /* Access time */ - time_t mtime; /* Modification time */ - time_t ctime; /* Change time */ - time_t btime; /* Birth time */ - hsize_t num_attrs; /* # of attributes attached to object */ + unsigned long fileno; /**< File number that object is located in */ + H5O_token_t token; /**< Token representing the object */ + H5O_type_t type; /**< Basic object type (group, dataset, etc.) */ + unsigned rc; /**< Reference count of object */ + time_t atime; /**< Access time */ + time_t mtime; /**< Modification time */ + time_t ctime; /**< Change time */ + time_t btime; /**< Birth time */ + hsize_t num_attrs; /**< Number of attributes attached to object */ } H5O_info2_t; //! <!-- [H5O_info2_t_snip] --> @@ -165,11 +167,10 @@ typedef struct H5O_info2_t { */ typedef struct H5O_native_info_t { H5O_hdr_info_t hdr; /**< Object header information */ - /* Extra metadata storage for obj & attributes */ struct { H5_ih_info_t obj; /**< v1/v2 B-tree & local/fractal heap for groups, B-tree for chunked datasets */ H5_ih_info_t attr; /**< v2 B-tree & heap for attributes */ - } meta_size; + } meta_size; /**< Extra metadata storage for obj & attributes */ } H5O_native_info_t; //! <!-- [H5O_native_info_t_snip] --> @@ -181,6 +182,17 @@ typedef uint32_t H5O_msg_crt_idx_t; //! <!-- [H5O_iterate2_t_snip] --> /** * Prototype for H5Ovisit(), H5Ovisit_by_name() operator (version 3) + * + * \param[in] obj Object that serves as the root of the iteration; + * the same value as the H5Ovisit3() \c obj_id parameter + * \param[in] name Name of object, relative to \p obj, being examined at current + * step of the iteration + * \param[out] info Information about that object + * \param[in,out] op_data User-defined pointer to data required by the application + * in processing the object; a pass-through of the \c op_data + * pointer provided with the H5Ovisit3() function call + * \return \herr_t_iter + * */ typedef herr_t (*H5O_iterate2_t)(hid_t obj, const char *name, const H5O_info2_t *info, void *op_data); //! <!-- [H5O_iterate2_t_snip] --> @@ -460,28 +472,7 @@ H5_DLL htri_t H5Oexists_by_name(hid_t loc_id, const char *name, hid_t lapl_id); * \return \herr_t * * \details H5Oget_info3() specifies an object by its identifier, \p loc_id , and - * retrieves the metadata describing that object in \p oinfo , an H5O_info2_t \c struct. - * - * The H5O_info2_t \c struct is defined in H5Opublic.h as follows : - * \snippet this H5O_info2_t_snip - * - * Note the following about H5O_info2_t : - * - Of the four time fields (\c atime, \c mtime, \c ctime, and \c btime) - * only \c ctime has been implemented. - * - The \c atime value is the last time the object was read or written. - * - The \c mtime value is the last time the raw data in the object was changed. - * - The \c ctime value is the last time the metadata for the object was changed. - * - The \c btime value is the time the object was created. - * - * The H5O_token_t is defined in H5public.h as follows: - * \snippet H5public.h H5O_token_t_snip - * - * The H5O_type_t \c enum indicates the object type and - * is defined in H5Opublic.h as follows: - * \snippet this H5O_type_t_snip - * - * Note that the object retrieved as indicated by \p loc_id - * refers only to the types specified by H5O_type_t. + * retrieves the metadata describing that object in \p oinfo. * * The \p fields parameter contains flags to determine which fields will be filled in * the H5O_info2_t \c struct returned in \p oinfo. @@ -530,29 +521,6 @@ H5_DLL herr_t H5Oget_info3(hid_t loc_id, H5O_info2_t *oinfo, unsigned fields); * \p loc_id and \p name, respectively, and retrieves the metadata * describing that object in \p oinfo, an H5O_info2_t struct. * - * \p oinfo, in which the object information is returned, is a \c struct of - * type H5O_info2_t, which is defined in H5Opublic.h in the HDF5 source code: - * - * \snippet this H5O_info2_t_snip - * - * Note the following about H5O_info2_t : - * - Of the four time fields (\c atime, \c mtime, \c ctime, and \c btime) - * only \c ctime has been implemented. - * - The \c atime value is the last time the object was read or written. - * - The \c mtime value is the last time the raw data in the object was changed. - * - The \c ctime value is the last time the metadata for the object was changed. - * - The \c btime value is the time the object was created. - * - * The H5O_token_t is defined in H5public.h as follows: - * \snippet H5public.h H5O_token_t_snip - * - * The H5O_type_t \c enum indicates the object type and - * is defined in H5Opublic.h as follows: - * \snippet this H5O_type_t_snip - * - * Note that the object retrieved as indicated by \p loc_id - * refers only to the types specified by H5O_type_t. - * * The \p fields parameter contains flags to determine which fields will be filled in * the H5O_info2_t \c struct returned in \p oinfo. * These flags are defined in the H5Opublic.h file: @@ -608,34 +576,6 @@ H5_DLL herr_t H5Oget_info_by_name_async(const char *app_file, const char *app_fu * If \p loc_id fully specifies the group in which the object resides, * \p group_name can be a dot (\c .). * - * \p idx_type is of type #H5_index_t, defined in H5public.h as: - * \snippet H5public.h H5_index_t_snip - * - * \p order is of type #H5_iter_order_t defined in H5public.h as: - * \snippet H5public.h H5_iter_order_t_snip - * - * \p oinfo, in which the object information is returned, is a \c struct of - * type H5O_info2_t, which is defined in H5Opublic.h in the HDF5 source code: - * \snippet this H5O_info2_t_snip - * - * Note the following about H5O_info2_t : - * - Of the four time fields (\c atime, \c mtime, \c ctime, and \c btime) - * only \c ctime has been implemented. - * - The \c atime value is the last time the object was read or written. - * - The \c mtime value is the last time the raw data in the object was changed. - * - The \c ctime value is the last time the metadata for the object was changed. - * - The \c btime value is the time the object was created. - * - * H5O_token_t is defined in H5public.h as follows: - * \snippet H5public.h H5O_token_t_snip - * - * The #H5O_type_t \c enum indicates the object type and - * is defined in H5Opublic.h as follows: - * \snippet this H5O_type_t_snip - * - * Note that the object retrieved as indicated by \p loc_id - * refers only to the types specified by #H5O_type_t. - * * The \p fields parameter contains flags to determine which fields will be filled in * the H5O_info2_t \c struct returned in \p oinfo. * These flags are defined in the H5Opublic.h file: @@ -668,11 +608,7 @@ H5_DLL herr_t H5Oget_info_by_idx3(hid_t loc_id, const char *group_name, H5_index * \return \herr_t * * \details H5Oget_native_info() retrieves the native file format information for an object - * specified by \p loc_id. The information is retrieved into the - * buffer specified by \p oinfo, which is defined as a \c struct of - * type H5O_native_info_t in H5Opublic.h: - * - * \snippet this H5O_native_info_t_snip + * specified by \p loc_id. * * The \p fields parameter indicates which fields to fill in * H5O_native_info_t. Possible values defined in H5Opublic.h are: @@ -703,12 +639,9 @@ H5_DLL herr_t H5Oget_native_info(hid_t loc_id, H5O_native_info_t *oinfo, unsigne * * \return \herr_t * - * \details H5Oget_native_info_by_name() retrieves the native file format information for an object - * specified by \p loc_id and the name \p name. The information is - * retrieved into the buffer specified by \p oinfo, which is defined - * as a \c struct of type H5O_native_info_t in H5Opublic.h: - * - * \snippet this H5O_native_info_t_snip + * \details H5Oget_native_info_by_name() retrieves the native file format + * information for an object specified by \p loc_id and the name \p + * name. * * The \p fields parameter which fields to fill in H5O_native_info_t. * Possible values defined in H5Opublic.h are: @@ -747,16 +680,7 @@ H5_DLL herr_t H5Oget_native_info_by_name(hid_t loc_id, const char *name, H5O_nat * specified by \p loc_id, group name, \p group_name, the index by which * objects in the group are tracked, \p idx_type, the order by which * the index is to be traversed, \p order , and an object's position - * \p n within that index. The information is retrieved into the - * buffer specified by \p oinfo, which is defined as a \c struct of - * type H5O_native_info_t in H5Opublic.h: - * \snippet this H5O_native_info_t_snip - * - * \p idx_type is of type #H5_index_t, defined in H5public.h as: - * \snippet H5public.h H5_index_t_snip - * - * \p order is of type #H5_iter_order_t defined in H5public.h as: - * \snippet H5public.h H5_iter_order_t_snip + * \p n within that index. * * The \p fields parameter indicates which fields to fill in H5O_native_info_t. * Possible values defined in H5Opublic.h are: @@ -1236,11 +1160,8 @@ H5_DLL ssize_t H5Oget_comment_by_name(hid_t loc_id, const char *name, char *comm * a group have not been indexed by the index type, they will * first be sorted by that index then the iteration will begin; * if the links have been so indexed, the sorting step will be - * unnecessary, so the iteration may begin more quickly. Valid - * values include the following: - * - * \indexes - * + * unnecessary, so the iteration may begin more quickly. + * Note that the index type passed in \p idx_type is a * <em>best effort</em> setting. If the application passes in * a value indicating iteration in creation order and a group is @@ -1250,62 +1171,7 @@ H5_DLL ssize_t H5Oget_comment_by_name(hid_t loc_id, const char *name, char *comm * used by the HDF5 library and is always available.) * * \p order specifies the order in which objects are to be inspected - * along the index specified in \p idx_type. Valid values include - * the following: - * - * \orders - * - * The prototype of the callback function op is as follows (as - * defined in the source code file H5Opublic.h): - * - * \snippet this H5O_iterate2_t_snip - * - * The parameters of this callback function have the following values - * or meanings: - * <table> - * <tr> - * <td>\c obj</td> - * <td>Object that serves as root of the iteration; - * same value as the H5Ovisit() \p obj_id parameter</td> - * </tr> - * <tr> - * <td>\c name</td> - * <td>Name of object, relative to \c obj, being examined at - * current step of the iteration</td> - * </tr> - * <tr> - * <td>\c info</td> - * <td>H5O_info2_t \c struct containing information - * regarding that object</td> - * </tr> - * <tr> - * <td>\c op_data</td> - * <td>User-defined pointer to data required by the application in - * processing the object; a pass-through of the \c op_data pointer - * provided with the H5Ovisit() function call</td> - * </tr> - * </table> - * - * The H5O_info2_t \c struct is defined in H5Opublic.h as follows: - * \snippet this H5O_info2_t_snip - * - * H5O_token_t is defined in H5public.h as follows: - * \snippet H5public.h H5O_token_t_snip - * - * The #H5O_type_t enum indicates the object type and is - * defined in H5Opublic.h as follows: - * \snippet this H5O_type_t_snip - * - * Note that the object retrieved as indicated by \p obj_id - * refers only to the types specified by #H5O_type_t. - * - * The return values from an operator are: - * - Zero causes the visit iterator to continue, returning zero when all - * group members have been processed. - * - A positive value causes the visit iterator to immediately return that - * positive value, indicating short-circuit success. - * - A negative value causes the visit iterator to immediately return that - * value, indicating failure. + * along the index specified in \p idx_type. * * The H5Ovisit3() \p op_data parameter is a user-defined pointer to the data * required to process objects in the course of the iteration. This pointer @@ -1329,24 +1195,6 @@ H5_DLL ssize_t H5Oget_comment_by_name(hid_t loc_id, const char *name, char *comm * group change during the iteration, the resulting behavior * is undefined. * - * \note \Bold{Programming Note for C++ Developers Using C Functions:} - * \note If a C routine that takes a function pointer as an argument is - * called from within C++ code, the C routine should be returned - * from normally. - * - * \note Examples of this kind of routine include callbacks such as - * H5Pset_elink_cb() and H5Pset_type_conv_cb() and - * functions such as H5Tconvert() and H5Ewalk2(). - * - * \note Exiting the routine in its normal fashion allows the HDF5 - * C library to clean up its work properly. In other words, if - * the C++ application jumps out of the routine back to the C++ - * “catch” statement, the library is not given the opportunity - * to close any temporary data structures that were set up when - * the routine was called. The C++ application should save some - * state as the routine is started so that any problem that occurs - * might be diagnosed. - * * \par Example * An example snippet from test/links.c: * \snippet links.c H5Ovisit3_snip @@ -1411,10 +1259,7 @@ H5_DLL herr_t H5Ovisit3(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order * a group have not been indexed by the index type, they will * first be sorted by that index then the iteration will begin; * if the links have been so indexed, the sorting step will be - * unnecessary, so the iteration may begin more quickly. Valid - * values include the following: - * - * \indexes + * unnecessary, so the iteration may begin more quickly. * * Note that the index type passed in \p idx_type is a * <em>best effort</em> setting. If the application passes in a @@ -1425,49 +1270,7 @@ H5_DLL herr_t H5Ovisit3(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order * used by the HDF5 library and is always available.) * * \p order specifies the order in which objects are to be inspected - * along the index specified in \p idx_type. Valid values include - * the following: - * - * \orders - * - * The prototype of the callback function op is as follows (as - * defined in the source code file H5Opublic.h): - * - * \snippet this H5O_iterate2_t_snip - * - * The parameters of this callback function have the following - * values or meanings: - * <table> - * <tr> - * <td>\c obj</td> - * <td>Object that serves as root of the iteration</td> - * </tr> - * <tr> - * <td>\c name</td> - * <td>Name of object, relative to \c obj, being examined at - * current step of the iteration</td> - * </tr> - * <tr> - * <td>\c info</td> - * <td>H5O_info2_t \c struct containing information - * regarding that object</td> - * </tr> - * <tr> - * <td>\c op_data</td> - * <td>User-defined pointer to data required by the application in - * processing the object</td> - * </tr> - * </table> - * - * The H5O_info2_t \c struct is defined in H5Opublic.h as follows: - * \snippet this H5O_info2_t_snip - * - * H5O_token_t is defined in H5public.h as follows: - * \snippet H5public.h H5O_token_t_snip - * - * The #H5O_type_t enum indicates the object type and is - * defined in H5Opublic.h as follows: - * \snippet this H5O_type_t_snip + * along the index specified in \p idx_type. * * The H5Ovisit_by_name3() \p op_data parameter is a user-defined * pointer to the data required to process objects in the course @@ -1495,24 +1298,6 @@ H5_DLL herr_t H5Ovisit3(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order * in the file has been presented to the application for whatever * processing the application requires. * - * \note \Bold{Programming Note for C++ Developers Using C Functions:} - * \note If a C routine that takes a function pointer as an argument is - * called from within C++ code, the C routine should be returned - * from normally. - * - * \note Examples of this kind of routine include callbacks such as - * H5Pset_elink_cb() and H5Pset_type_conv_cb() and - * functions such as H5Tconvert() and H5Ewalk2(). - * - * \note Exiting the routine in its normal fashion allows the HDF5 - * C library to clean up its work properly. In other words, if - * the C++ application jumps out of the routine back to the C++ - * “catch” statement, the library is not given the opportunity - * to close any temporary data structures that were set up when - * the routine was called. The C++ application should save some - * state as the routine is started so that any problem that occurs - * might be diagnosed. - * * \par Example * An example snippet from test/links.c: * \snippet links.c H5Ovisit_by_name3_snip @@ -1579,26 +1364,11 @@ H5_DLL herr_t H5Oclose_async(const char *app_file, const char *app_func, unsigne * files. After that, the OS is responsible for ensuring that * the data is actually flushed to disk. * - * \par See Also: - * - H5Dflush() - * - H5Drefresh() - * - H5Oflush() - * - H5Grefresh() - * - H5Oflush() - * - H5Orefresh() - * - H5Tflush() - * - H5Trefresh() - * \par - * - \c H5DOappend() - * - H5Fstart_swmr_write() - * - H5Pget_append_flush() - * - H5Pget_object_flush_cb() - * - H5Pset_append_flush() - * - H5Pset_object_flush_cb() - * \par - * - H5Oare_mdc_flushes_disabled() - * - H5Odisable_mdc_flushes() - * - H5Oenable_mdc_flushes() + * \see H5Dflush(), H5Drefresh(), H5Oflush(), H5Grefresh(), H5Oflush(), + * H5Orefresh(), H5Tflush(), H5Trefresh() + * \see H5DOappend(), H5Fstart_swmr_write(), H5Pget_append_flush(), + * H5Pget_object_flush_cb(), H5Pset_append_flush(), H5Pset_object_flush_cb() + * \see H5Oare_mdc_flushes_disabled(), H5Odisable_mdc_flushes(), H5Oenable_mdc_flushes() * * \since 1.10.0 * @@ -1670,21 +1440,17 @@ H5_DLL herr_t H5Orefresh_async(const char *app_file, const char *app_func, unsig * HDF5 object level (datasets, groups, committed datatypes) * and the entire metadata cache level. * - * \note HDF5 objects include datasets, groups, and committed datatypes. - * Only #hid_t identifiers that represent these objects can be passed to the function. - * \note Passing in a #hid_t identifier that represents any other HDF5 entity is - * considered an error. - * \note It is an error to pass an HDF5 file identifier - * (obtained from H5Fopen() or H5Fcreate()) - * to this function. - * \note Misuse of this function can cause the cache to exhaust - * available memory. - * \note Objects can be returned to the default automatic flush behavior - * with H5Oenable_mdc_flushes(). - * \note Flush prevention only pertains to new or dirty metadata entries. - * Clean entries can be evicted from the cache. - * \note Calling this function on an object that has already had flushes - * disabled will return an error. + * \note HDF5 objects include datasets, groups, and committed datatypes. Only + * #hid_t identifiers that represent these objects can be passed to the + * function. Passing in a #hid_t identifier that represents any other + * HDF5 entity is considered an error. It is an error to pass an HDF5 + * file identifier (obtained from H5Fopen() or H5Fcreate()) to this + * function. Misuse of this function can cause the cache to exhaust + * available memory. Objects can be returned to the default automatic + * flush behavior with H5Oenable_mdc_flushes(). Flush prevention only + * pertains to new or dirty metadata entries. Clean entries can be + * evicted from the cache. Calling this function on an object that has + * already had flushes disabled will return an error. * * \since 1.10.0 * @@ -1714,28 +1480,18 @@ H5_DLL herr_t H5Odisable_mdc_flushes(hid_t object_id); * metadata cache level. * * - * \note HDF5 objects include datasets, groups, and committed datatypes. - * Only #hid_t identifiers that represent these objects can be - * passed to the function. - * - * \note Passing in a #hid_t identifier that represents any other HDF5 entity - * is considered an error. - * - * \note It is an error to pass an HDF5 file identifier - * (obtained from H5Fopen() or H5Fcreate()) - * to this function. - * - * \note Using this function on an object that has not had flushes disabled - * is considered an error. The state of an object can be determined - * with H5Oare_mdc_flushes_disabled(). - * - * \note An object will be returned to the default flush algorithm when it is closed. - * - * \note All objects will be returned to the default flush algorithm when - * the file is closed. - * - * \note An object’s entries will not necessarily be flushed as a result of - * calling this function. + * \note HDF5 objects include datasets, groups, and committed datatypes. Only + * #hid_t identifiers that represent these objects can be passed to the + * function. Passing in a #hid_t identifier that represents any other + * HDF5 entity is considered an error. It is an error to pass an HDF5 + * file identifier (obtained from H5Fopen() or H5Fcreate()) to this + * function. Using this function on an object that has not had flushes + * disabled is considered an error. The state of an object can be + * determined with H5Oare_mdc_flushes_disabled(). An object will be + * returned to the default flush algorithm when it is closed. All objects + * will be returned to the default flush algorithm when the file is + * closed. An object’s entries will not necessarily be flushed as a + * result of calling this function. * * \since 1.10.0 * @@ -1871,6 +1627,7 @@ H5_DLL herr_t H5Otoken_to_str(hid_t loc_id, const H5O_token_t *token, char **tok */ H5_DLL herr_t H5Otoken_from_str(hid_t loc_id, const char *token_str, H5O_token_t *token); +/// \cond DEV /* API Wrappers for async routines */ /* (Must be defined _after_ the function prototype) */ /* (And must only defined when included in application code, not the library) */ @@ -1894,6 +1651,7 @@ H5_DLL herr_t H5Otoken_from_str(hid_t loc_id, const char *token_str, H5O_token_t #define H5Orefresh_async_wrap H5_NO_EXPAND(H5Orefresh_async) #define H5Ocopy_async_wrap H5_NO_EXPAND(H5Ocopy_async) #endif +/// \endcond /* The canonical 'undefined' token value */ #define H5O_TOKEN_UNDEF (H5OPEN H5O_TOKEN_UNDEF_g) @@ -1908,8 +1666,8 @@ H5_DLLVAR const H5O_token_t H5O_TOKEN_UNDEF_g; /* Macros */ /* Deprecated flags for earlier versions of H5Oget_info* */ -#define H5O_INFO_HDR 0x0008u /* Fill in the hdr field */ -#define H5O_INFO_META_SIZE 0x0010u /* Fill in the meta_size field */ +#define H5O_INFO_HDR 0x0008u /**< Fill in the hdr field */ +#define H5O_INFO_META_SIZE 0x0010u /**< Fill in the meta_size field */ #undef H5O_INFO_ALL #define H5O_INFO_ALL (H5O_INFO_BASIC | H5O_INFO_TIME | H5O_INFO_NUM_ATTRS | H5O_INFO_HDR | H5O_INFO_META_SIZE) @@ -1942,7 +1700,7 @@ typedef struct H5O_info1_t { time_t mtime; /**< Modification time */ time_t ctime; /**< Change time */ time_t btime; /**< Birth time */ - hsize_t num_attrs; /**< # of attributes attached to object */ + hsize_t num_attrs; /**< Number of attributes attached to object */ H5O_hdr_info_t hdr; /**< Object header information */ /* Extra metadata storage for obj & attributes */ struct { @@ -1955,6 +1713,16 @@ typedef struct H5O_info1_t { //! <!-- [H5O_iterate1_t_snip] --> /** * Prototype for H5Ovisit(), H5Ovisit_by_name() operator (versions 1 & 2) + * + * \param[in] obj Object that serves as the root of the iteration; + * the same value as the H5Ovisit1() \c obj_id parameter + * \param[in] name Name of object, relative to \p obj, being examined at current + * step of the iteration + * \param[out] info Information about that object + * \param[in,out] op_data User-defined pointer to data required by the application + * in processing the object + * \return \herr_t_iter + * */ typedef herr_t (*H5O_iterate1_t)(hid_t obj, const char *name, const H5O_info1_t *info, void *op_data); //! <!-- [H5O_iterate1_t_snip] --> @@ -2027,36 +1795,7 @@ H5_DLL hid_t H5Oopen_by_addr(hid_t loc_id, haddr_t addr); * the function H5Oget_info3() or the macro #H5Oget_info. * * \details H5Oget_info1() specifies an object by its identifier, \p loc_id , and - * retrieves the metadata describing that object in \p oinfo , - * defined as a \c struct of type H5O_info1_t : - * - * \snippet this H5O_info1_t_snip - * - * Note the following about H5O_info1_t : - * - Of the four time fields (\c atime, \c mtime, \c ctime, and \c btime) - * only \c ctime has been implemented. - * - The \c atime value is the last time the object was read or written. - * - The \c mtime value is the last time the raw data in the object was changed. - * - The \c ctime value is the last time the metadata for the object was changed. - * - The \c btime value is the time the object was created. - * - The fields nested in the \c meta_size field are for internal library use only. - * - * The #H5O_type_t \c enum indicates the object type and - * is defined in H5Opublic.h as follows: - * \snippet this H5O_type_t_snip - * - * Note that the object retrieved as indicated by \p loc_id - * refers only to the types specified by #H5O_type_t. - * - * An H5O_hdr_info_t \c struct holds object header metadata and is - * defined in H5Opublic.h as follows: - * \snippet this H5O_hdr_info_t_snip - * - * Valid values for the \c version field are \c H5O_VERSION_1 and \c H5O_VERSION_2. - * Version 2 of the object header is smaller and more efficient than version 1. - * - * Please be aware that the information held by H5O_hdr_info_t may only be useful to - * developers with extensive HDF5 experience. + * retrieves the metadata describing that object in \p oinfo. * * \note If you are iterating through a lot of different objects to * retrieve information via the H5Oget_info() family of routines, @@ -2156,16 +1895,6 @@ H5_DLL herr_t H5Oget_info_by_name1(hid_t loc_id, const char *name, H5O_info1_t * * If \p loc_id fully specifies the group in which the object resides, * \p group_name can be a dot (\c .). * - * \p idx_type is of type #H5_index_t, defined in H5public.h as: - * \snippet H5public.h H5_index_t_snip - * - * \p order is of type #H5_iter_order_t defined in H5public.h as: - * \snippet H5public.h H5_iter_order_t_snip - * - * \p oinfo, in which the object information is returned, is a \c struct of - * type H5O_info1_t . - * \snippet this H5O_info1_t_snip - * * The link access property list, \c lapl_id, is not currently used; * it should be passed in as #H5P_DEFAULT. * @@ -2361,10 +2090,7 @@ H5_DLL herr_t H5Oget_info_by_idx2(hid_t loc_id, const char *group_name, H5_index * a group have not been indexed by the index type, they will * first be sorted by that index then the iteration will begin; * if the links have been so indexed, the sorting step will be - * unnecessary, so the iteration may begin more quickly. Valid - * values include the following: - * - * \indexes + * unnecessary, so the iteration may begin more quickly. * * Note that the index type passed in \p idx_type is a * <em>best effort</em> setting. If the application passes in @@ -2375,56 +2101,7 @@ H5_DLL herr_t H5Oget_info_by_idx2(hid_t loc_id, const char *group_name, H5_index * used by the HDF5 library and is always available.) * * \p order specifies the order in which objects are to be inspected - * along the index specified in \p idx_type. Valid values include - * the following: - * - * \orders - * - * The prototype of the callback function op is as follows (as - * defined in the source code file H5Opublic.h): - * - * \snippet this H5O_iterate1_t_snip - * - * The parameters of this callback function have the following values - * or meanings: - * <table> - * <tr> - * <td>\c obj</td> - * <td>Object that serves as root of the iteration; - * same value as the H5Ovisit1() \p obj_id parameter</td> - * </tr> - * <tr> - * <td>\c name</td> - * <td>Name of object, relative to \c obj, being examined at - * current step of the iteration</td> - * </tr> - * <tr> - * <td>\c info</td> - * <td>H5O_info1_t \c struct containing information - * regarding that object</td> - * </tr> - * <tr> - * <td>\c op_data</td> - * <td>User-defined pointer to data required by the application in - * processing the object</td> - * </tr> - * </table> - * - * The H5O_info1_t \c struct is defined in H5Opublic.h: - * \snippet this H5O_info1_t_snip - * - * The return values from an operator are: - * - Zero causes the visit iterator to continue, returning zero when all - * group members have been processed. - * - A positive value causes the visit iterator to immediately return that - * positive value, indicating short-circuit success. - * - A negative value causes the visit iterator to immediately return that - * value, indicating failure. - * - * The H5Ovisit1() \p op_data parameter is a user-defined pointer to the data - * required to process objects in the course of the iteration. This pointer - * is passed back to each step of the iteration in the callback - * function’s \p op_data parameter. + * along the index specified in \p idx_type. * * H5Lvisit1() and H5Ovisit1() are companion functions: one for * examining and operating on links; the other for examining @@ -2438,24 +2115,6 @@ H5_DLL herr_t H5Oget_info_by_idx2(hid_t loc_id, const char *group_name, H5_index * group change during the iteration, the resulting behavior * is undefined. * - * \note \Bold{Programming Note for C++ Developers Using C Functions:} - * \note If a C routine that takes a function pointer as an argument is - * called from within C++ code, the C routine should be returned - * from normally. - * - * \note Examples of this kind of routine include callbacks such as - * H5Pset_elink_cb() and H5Pset_type_conv_cb() and - * functions such as H5Tconvert() and H5Ewalk2(). - * - * \note Exiting the routine in its normal fashion allows the HDF5 - * C library to clean up its work properly. In other words, if - * the C++ application jumps out of the routine back to the C++ - * “catch” statement, the library is not given the opportunity - * to close any temporary data structures that were set up when - * the routine was called. The C++ application should save some - * state as the routine is started so that any problem that occurs - * might be diagnosed. - * * \version 1.10.5 The macro #H5Ovisit was removed and the function * H5Ovisit1() was copied to H5Ovisit(). * \version 1.10.3 Function H5Ovisit() was copied to H5Ovisit1(), @@ -2523,10 +2182,7 @@ H5_DLL herr_t H5Ovisit1(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order * a group have not been indexed by the index type, they will * first be sorted by that index then the iteration will begin; * if the links have been so indexed, the sorting step will be - * unnecessary, so the iteration may begin more quickly. Valid - * values include the following: - * - * \indexes + * unnecessary, so the iteration may begin more quickly. * * Note that the index type passed in \p idx_type is a * <em>best effort</em> setting. If the application passes in a @@ -2537,10 +2193,7 @@ H5_DLL herr_t H5Ovisit1(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order * used by the HDF5 library and is always available.) * * \p order specifies the order in which objects are to be inspected - * along the index specified in \p idx_type. Valid values include - * the following: - * - * \orders + * along the index specified in \p idx_type. * * The \p op callback function and the effect of the callback * function’s return value on the application are described @@ -2570,24 +2223,6 @@ H5_DLL herr_t H5Ovisit1(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order * in the file has been presented to the application for whatever * processing the application requires. * - * \note \Bold{Programming Note for C++ Developers Using C Functions:} - * \note If a C routine that takes a function pointer as an argument is - * called from within C++ code, the C routine should be returned - * from normally. - * - * \note Examples of this kind of routine include callbacks such as - * H5Pset_elink_cb() and H5Pset_type_conv_cb() and - * functions such as H5Tconvert() and H5Ewalk2(). - * - * \note Exiting the routine in its normal fashion allows the HDF5 - * C library to clean up its work properly. In other words, if - * the C++ application jumps out of the routine back to the C++ - * “catch” statement, the library is not given the opportunity - * to close any temporary data structures that were set up when - * the routine was called. The C++ application should save some - * state as the routine is started so that any problem that occurs - * might be diagnosed. - * * \version 1.10.5 The macro #H5Ovisit_by_name was removed and the function * H5Ovisit_by_name1() was copied to #H5Ovisit_by_name. * \version 1.10.3 The H5Ovisit_by_name() function was renamed to H5Ovisit_by_name1(), @@ -2650,10 +2285,7 @@ H5_DLL herr_t H5Ovisit_by_name1(hid_t loc_id, const char *obj_name, H5_index_t i * a group have not been indexed by the index type, they will * first be sorted by that index then the iteration will begin; * if the links have been so indexed, the sorting step will be - * unnecessary, so the iteration may begin more quickly. Valid - * values include the following: - * - * \indexes + * unnecessary, so the iteration may begin more quickly. * * Note that the index type passed in \p idx_type is a * <em>best effort</em> setting. If the application passes in @@ -2664,57 +2296,7 @@ H5_DLL herr_t H5Ovisit_by_name1(hid_t loc_id, const char *obj_name, H5_index_t i * used by the HDF5 library and is always available.) * * \p order specifies the order in which objects are to be inspected - * along the index specified in \p idx_type. Valid values include - * the following: - * - * \orders - * - * The prototype of the callback function op is as follows (as - * defined in the source code file H5Opublic.h): - * - * \snippet this H5O_iterate1_t_snip - * - * The parameters of this callback function have the following values - * or meanings: - * <table> - * <tr> - * <td>\c obj</td> - * <td>Object that serves as root of the iteration; - * same value as the H5Ovisit1() \p obj_id parameter</td> - * </tr> - * <tr> - * <td>\c name</td> - * <td>Name of object, relative to \c obj, being examined at - * current step of the iteration</td> - * </tr> - * <tr> - * <td>\c info</td> - * <td>H5O_info1_t \c struct containing information - * regarding that object</td> - * </tr> - * <tr> - * <td>\c op_data</td> - * <td>User-defined pointer to data required by the application in - * processing the object; a pass-through of the \c op_data pointer - * provided with the H5Ovisit() function call</td> - * </tr> - * </table> - * - * The H5O_info1_t \c struct is defined in H5Opublic.h and - * described in the H5Oget_info1() function entry. - * - * The return values from an operator are: - * - Zero causes the visit iterator to continue, returning zero when all - * group members have been processed. - * - A positive value causes the visit iterator to immediately return that - * positive value, indicating short-circuit success. - * - A negative value causes the visit iterator to immediately return that - * value, indicating failure. - * - * The H5Ovisit2() \p op_data parameter is a user-defined pointer to the data - * required to process objects in the course of the iteration. This pointer - * is passed back to each step of the iteration in the callback - * function’s \p op_data parameter. + * along the index specified in \p idx_type. * * The \p fields parameter contains flags to determine which fields will * be retrieved by the \p op callback function. These flags are defined @@ -2733,23 +2315,6 @@ H5_DLL herr_t H5Ovisit_by_name1(hid_t loc_id, const char *obj_name, H5_index_t i * group change during the iteration, the resulting behavior * is undefined. * - * \note \Bold{Programming Note for C++ Developers Using C Functions:} - * \note If a C routine that takes a function pointer as an argument is - * called from within C++ code, the C routine should be returned - * from normally. - * - * \note Examples of this kind of routine include callbacks such as - * H5Pset_elink_cb() and H5Pset_type_conv_cb() and - * functions such as H5Tconvert() and H5Ewalk2(). - * - * \note Exiting the routine in its normal fashion allows the HDF5 - * C library to clean up its work properly. In other words, if - * the C++ application jumps out of the routine back to the C++ - * “catch” statement, the library is not given the opportunity - * to close any temporary data structures that were set up when - * the routine was called. The C++ application should save some - * state as the routine is started so that any problem that occurs - * might be diagnosed. * * \since 1.10.3 * @@ -2814,10 +2379,7 @@ H5_DLL herr_t H5Ovisit2(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order * a group have not been indexed by the index type, they will * first be sorted by that index then the iteration will begin; * if the links have been so indexed, the sorting step will be - * unnecessary, so the iteration may begin more quickly. Valid - * values include the following: - * - * \indexes + * unnecessary, so the iteration may begin more quickly. * * Note that the index type passed in \p idx_type is a * <em>best effort</em> setting. If the application passes in a @@ -2828,10 +2390,7 @@ H5_DLL herr_t H5Ovisit2(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order * used by the HDF5 library and is always available.) * * \p order specifies the order in which objects are to be inspected - * along the index specified in \p idx_type. Valid values include - * the following: - * - * \orders + * along the index specified in \p idx_type. * * The \p op callback function and the effect of the callback * function’s return value on the application are described @@ -2866,24 +2425,6 @@ H5_DLL herr_t H5Ovisit2(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order * in the file has been presented to the application for whatever * processing the application requires. * - * \note \Bold{Programming Note for C++ Developers Using C Functions:} - * \note If a C routine that takes a function pointer as an argument is - * called from within C++ code, the C routine should be returned - * from normally. - * - * \note Examples of this kind of routine include callbacks such as - * H5Pset_elink_cb() and H5Pset_type_conv_cb() and - * functions such as H5Tconvert() and H5Ewalk2(). - * - * \note Exiting the routine in its normal fashion allows the HDF5 - * C library to clean up its work properly. In other words, if - * the C++ application jumps out of the routine back to the C++ - * “catch” statement, the library is not given the opportunity - * to close any temporary data structures that were set up when - * the routine was called. The C++ application should save some - * state as the routine is started so that any problem that occurs - * might be diagnosed. - * * \since 1.10.3 * */ diff --git a/src/H5PL.c b/src/H5PL.c index 06443f3..30b6c52 100644 --- a/src/H5PL.c +++ b/src/H5PL.c @@ -359,7 +359,7 @@ H5PLget(unsigned int idx, char *path_buf, size_t buf_size) /* If the path buffer is not NULL, copy the path to the buffer */ if (path_buf) { - HDstrncpy(path_buf, path, MIN((size_t)(path_len + 1), buf_size)); + HDstrncpy(path_buf, path, buf_size); if ((size_t)path_len >= buf_size) path_buf[buf_size - 1] = '\0'; } /* end if */ diff --git a/src/H5PLint.c b/src/H5PLint.c index cf6135d..d20401e 100644 --- a/src/H5PLint.c +++ b/src/H5PLint.c @@ -236,11 +236,13 @@ H5PL_load(H5PL_type_t type, const H5PL_key_t *key) if ((H5PL_plugin_control_mask_g & H5PL_FILTER_PLUGIN) == 0) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTLOAD, NULL, "filter plugins disabled") break; + case H5PL_TYPE_VOL: if ((H5PL_plugin_control_mask_g & H5PL_VOL_PLUGIN) == 0) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTLOAD, NULL, "Virtual Object Layer (VOL) driver plugins disabled") break; + case H5PL_TYPE_ERROR: case H5PL_TYPE_NONE: default: @@ -290,7 +292,7 @@ done: * get_plugin_info function pointer, but early (4.4.7, at least) gcc * only allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("pedantic") +H5_GCC_CLANG_DIAG_OFF("pedantic") herr_t H5PL__open(const char *path, H5PL_type_t type, const H5PL_key_t *key, hbool_t *success, H5PL_type_t *plugin_type, const void **plugin_info) @@ -412,7 +414,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5PL__open() */ -H5_GCC_DIAG_ON("pedantic") +H5_GCC_CLANG_DIAG_ON("pedantic") /*------------------------------------------------------------------------- * Function: H5PL__close diff --git a/src/H5PLmodule.h b/src/H5PLmodule.h index ab9f1d5..a093096 100644 --- a/src/H5PLmodule.h +++ b/src/H5PLmodule.h @@ -28,8 +28,34 @@ #define H5_MY_PKG_INIT YES /**\defgroup H5PL H5PL - * \brief Plugins - * \todo Describe what programmatically controlling dynamically loaded plugins (H5PL) is all about + * + * Use the functions in this module to manage the loading behavior of HDF5 + * plugins. + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet H5PL_examples.c create + * </td> + * <td> + * \snippet H5PL_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet H5PL_examples.c update + * </td> + * <td> + * \snippet H5PL_examples.c delete + * </td> + * </tr> + * </table> + * + * \attention The loading behavior of HDF5 plugins can be controlled via the + * functions described below and certain environment variables, such + * as \c HDF5_PLUGIN_PRELOAD and \c HDF5_PLUGIN_PATH. + * */ #endif /* H5PLmodule_H */ diff --git a/src/H5PLplugin_cache.c b/src/H5PLplugin_cache.c index 2ec0845..b7cdac0 100644 --- a/src/H5PLplugin_cache.c +++ b/src/H5PLplugin_cache.c @@ -242,7 +242,7 @@ done: /* See the other use of H5PL_GET_LIB_FUNC() for an explanation * for why we disable -Wpedantic here. */ -H5_GCC_DIAG_OFF("pedantic") +H5_GCC_CLANG_DIAG_OFF("pedantic") herr_t H5PL__find_plugin_in_cache(const H5PL_search_params_t *search_params, hbool_t *found, const void **plugin_info) @@ -263,35 +263,61 @@ H5PL__find_plugin_in_cache(const H5PL_search_params_t *search_params, hbool_t *f /* Loop over all the plugins, looking for one that matches */ for (u = 0; u < H5PL_num_plugins_g; u++) { - - /* If the plugin type (filter, VOL connector, etc.) and ID match, query the plugin for its info */ - if ((search_params->type == (H5PL_cache_g[u]).type) && - (search_params->key->id == (H5PL_cache_g[u]).key.id)) { - - H5PL_get_plugin_info_t get_plugin_info_function; - const void * info; - - /* Get the "get plugin info" function from the plugin. */ - if (NULL == (get_plugin_info_function = (H5PL_get_plugin_info_t)H5PL_GET_LIB_FUNC( - (H5PL_cache_g[u]).handle, "H5PLget_plugin_info"))) - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get function for H5PLget_plugin_info") - - /* Call the "get plugin info" function */ - if (NULL == (info = (*get_plugin_info_function)())) - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get plugin info") - - /* Set output parameters */ - *found = TRUE; - *plugin_info = info; - - /* No need to continue processing */ - break; - - } /* end if */ - - } /* end for */ + /* If the plugin type (filter, VOL connector, etc.) match, proceed */ + if (search_params->type == H5PL_cache_g[u].type) { + hbool_t matched = FALSE; /* Whether cached plugin info matches */ + + switch (search_params->type) { + case H5PL_TYPE_FILTER: + if (search_params->key->id == H5PL_cache_g[u].key.id) + matched = TRUE; + break; + + case H5PL_TYPE_VOL: + if (search_params->key->vol.kind == H5VL_GET_CONNECTOR_BY_VALUE) { + if (search_params->key->vol.u.value == H5PL_cache_g[u].key.vol.u.value) + matched = TRUE; + } /* end if */ + else if (search_params->key->vol.kind == H5VL_GET_CONNECTOR_BY_NAME) { + if (0 == HDstrcmp(search_params->key->vol.u.name, H5PL_cache_g[u].key.vol.u.name)) + matched = TRUE; + } /* end else-if */ + else + HGOTO_ERROR(H5E_PLUGIN, H5E_BADVALUE, FAIL, "bad VOL plugin search key type") + break; + + case H5PL_TYPE_ERROR: + case H5PL_TYPE_NONE: + default: + HGOTO_ERROR(H5E_PLUGIN, H5E_BADVALUE, FAIL, "bad plugin type") + } /* end switch */ + + /* If the plugin type (filter, VOL connector, etc.) and key match, query the plugin for its info + */ + if (matched) { + H5PL_get_plugin_info_t get_plugin_info_function; + const void * info; + + /* Get the "get plugin info" function from the plugin. */ + if (NULL == (get_plugin_info_function = (H5PL_get_plugin_info_t)H5PL_GET_LIB_FUNC( + (H5PL_cache_g[u]).handle, "H5PLget_plugin_info"))) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get function for H5PLget_plugin_info") + + /* Call the "get plugin info" function */ + if (NULL == (info = (*get_plugin_info_function)())) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get plugin info") + + /* Set output parameters */ + *found = TRUE; + *plugin_info = info; + + /* No need to continue processing */ + break; + } /* end if */ + } /* end if */ + } /* end for */ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5PL__find_plugin_in_cache() */ -H5_GCC_DIAG_ON("pedantic") +H5_GCC_CLANG_DIAG_ON("pedantic") diff --git a/src/H5Pdapl.c b/src/H5Pdapl.c index 2ebdbe3..d374b25 100644 --- a/src/H5Pdapl.c +++ b/src/H5Pdapl.c @@ -1453,7 +1453,7 @@ H5Pget_efile_prefix(hid_t plist_id, char *prefix /*out*/, size_t size) /* Copy to user's buffer, if given */ len = HDstrlen(my_prefix); if (prefix) { - HDstrncpy(prefix, my_prefix, MIN(len + 1, size)); + HDstrncpy(prefix, my_prefix, size); if (len >= size) prefix[size - 1] = '\0'; } /* end if */ @@ -1543,7 +1543,7 @@ H5Pget_virtual_prefix(hid_t plist_id, char *prefix /*out*/, size_t size) /* Copy to user's buffer, if given */ len = HDstrlen(my_prefix); if (prefix) { - HDstrncpy(prefix, my_prefix, MIN(len + 1, size)); + HDstrncpy(prefix, my_prefix, size); if (len >= size) prefix[size - 1] = '\0'; } /* end if */ diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c index 046b046..46dc94c 100644 --- a/src/H5Pdxpl.c +++ b/src/H5Pdxpl.c @@ -68,7 +68,7 @@ #define H5D_XFER_BTREE_SPLIT_RATIO_SIZE sizeof(double[3]) #define H5D_XFER_BTREE_SPLIT_RATIO_DEF \ { \ - 0.1f, 0.5f, 0.9f \ + 0.1, 0.5, 0.9 \ } #define H5D_XFER_BTREE_SPLIT_RATIO_ENC H5P__dxfr_btree_split_ratio_enc #define H5D_XFER_BTREE_SPLIT_RATIO_DEC H5P__dxfr_btree_split_ratio_dec @@ -1052,7 +1052,7 @@ H5Pget_data_transform(hid_t plist_id, char *expression /*out*/, size_t size) /* Copy into application buffer */ len = HDstrlen(pexp); if (expression) { - HDstrncpy(expression, pexp, MIN(len + 1, size)); + HDstrncpy(expression, pexp, size); if (len >= size) expression[size - 1] = '\0'; } /* end if */ @@ -2281,7 +2281,7 @@ herr_t H5Pset_dataset_io_hyperslab_selection(hid_t plist_id, unsigned rank, H5S_seloper_t op, const hsize_t start[], const hsize_t stride[], const hsize_t count[], const hsize_t block[]) { - H5P_genplist_t *plist; /* Property list pointer */ + H5P_genplist_t *plist = NULL; /* Property list pointer */ H5S_t * space; /* Dataspace to hold selection */ hbool_t space_created = FALSE; /* Whether a new dataspace has been created */ hbool_t reset_prop_on_error = FALSE; /* Whether to reset the property on failure */ @@ -2371,7 +2371,7 @@ H5Pset_dataset_io_hyperslab_selection(hid_t plist_id, unsigned rank, H5S_seloper done: /* Cleanup on failure */ if (ret_value < 0) { - if (reset_prop_on_error && H5P_poke(plist, H5D_XFER_DSET_IO_SEL_NAME, &space) < 0) + if (reset_prop_on_error && plist && H5P_poke(plist, H5D_XFER_DSET_IO_SEL_NAME, &space) < 0) HDONE_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "error setting dataset I/O selection") if (space_created && H5S_close(space) < 0) HDONE_ERROR(H5E_PLIST, H5E_CLOSEERROR, FAIL, "unable to release dataspace") diff --git a/src/H5Pencdec.c b/src/H5Pencdec.c index 5b0ecb6..e2a97f8 100644 --- a/src/H5Pencdec.c +++ b/src/H5Pencdec.c @@ -333,7 +333,7 @@ H5P__encode_cb(H5P_genprop_t *prop, void *_udata) /* Encode (or not, if the 'encode' flag is off) the property's name */ prop_name_len = HDstrlen(prop->name) + 1; if (udata->encode) { - HDstrncpy((char *)*(udata->pp), prop->name, prop_name_len); + HDstrcpy((char *)*(udata->pp), prop->name); *(uint8_t **)(udata->pp) += prop_name_len; } /* end if */ *(udata->enc_size_ptr) += prop_name_len; diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index 5332ea6..d20503f 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -5930,6 +5930,64 @@ done: } /* end H5Pget_vol_info() */ /*------------------------------------------------------------------------- + * Function: H5Pget_vol_cap_flags + * + * Purpose: Queries the current VOL connector information for a FAPL to + * retrieve the capability flags for the VOL connector stack, as will + * be used by a file open or create operation that uses this FAPL. + * + * Current capability flags are: + * H5VL_CAP_FLAG_THREADSAFE - Connector is threadsafe + * H5VL_CAP_FLAG_ASYNC - Connector performs operations asynchronously + * H5VL_CAP_FLAG_NATIVE_FILES - Connector produces native file format + * + * Note: This routine supports the use of the HDF5_VOL_CONNECTOR environment + * environment variable to override the VOL connector set programmatically + * for the FAPL (with H5Pset_vol). + * + * Note: The H5VL_CAP_FLAG_ASYNC flag can be checked to see if asynchronous + * operations are supported by the VOL connector stack. + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_vol_cap_flags(hid_t plist_id, unsigned *cap_flags) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "i*Iu", plist_id, cap_flags); + + /* Get the 'cap_flags' from the connector */ + if (cap_flags) { + if (TRUE == H5P_isa_class(plist_id, H5P_FILE_ACCESS)) { + H5P_genplist_t * plist; /* Property list pointer */ + H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */ + + /* Get property list for ID */ + if (NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + + /* Get the connector property */ + if (H5P_peek(plist, H5F_ACS_VOL_CONN_NAME, &connector_prop) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get VOL connector property") + + /* Query the capability flags */ + if (H5VL_get_cap_flags(&connector_prop, cap_flags) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get VOL connector capability flags") + } /* end if */ + else + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_vol_cap_flags() */ + +/*------------------------------------------------------------------------- * Function: H5P__facc_vol_create * connectorose: Create callback for the VOL connector ID & info property. diff --git a/src/H5Pint.c b/src/H5Pint.c index b27a440..90fd1c2 100644 --- a/src/H5Pint.c +++ b/src/H5Pint.c @@ -4879,7 +4879,8 @@ H5P__copy_prop_plist(hid_t dst_id, hid_t src_id, const char *name) /* If not, get the information required to do an H5Pinsert2 with the property into the destination list */ else { /* Get the pointer to the source property */ - prop = H5P__find_prop_plist(src_plist, name); + if (NULL == (prop = H5P__find_prop_plist(src_plist, name))) + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist") /* Create property object from parameters */ if (NULL == diff --git a/src/H5Plapl.c b/src/H5Plapl.c index 879e6ed..d00efaf 100644 --- a/src/H5Plapl.c +++ b/src/H5Plapl.c @@ -1044,7 +1044,7 @@ H5Pget_elink_prefix(hid_t plist_id, char *prefix /*out*/, size_t size) /* Copy to user's buffer, if given */ len = HDstrlen(my_prefix); if (prefix) { - HDstrncpy(prefix, my_prefix, MIN(len + 1, size)); + HDstrncpy(prefix, my_prefix, size); if (len >= size) prefix[size - 1] = '\0'; } /* end if */ diff --git a/src/H5Pmodule.h b/src/H5Pmodule.h index 18f30c6..6e92e66 100644 --- a/src/H5Pmodule.h +++ b/src/H5Pmodule.h @@ -30,49 +30,165 @@ #define H5_MY_PKG_INIT YES /**\defgroup H5P H5P - * \brief Property List Interface * - * \details The HDF5 Property List Interface provides a mechanism to take - * advantage of more powerful or unusual features in HDF5. + * Use the functions in this module to manage HDF5 property lists and property + * list classes. HDF5 property lists are the main vehicle to configure the + * behavior of HDF5 API functions. * - * HDF5 objects have properties or characteristics associated with - * them, and there are default properties that handle the most - * common needs. These default properties can be modified using the - * HDF5 Property List Interface. For example, the data storage - * layout property of a dataset is contiguous by default. For better - * performance, the layout can be modified to be chunked or chunked - * and compressed. + * Typically, property lists are created by instantiating one of the built-in + * or user-defined property list classes. After adding suitable properties, + * property lists are used when opening or creating HDF5 items, or when reading + * or writing data. Property lists can be modified by adding or changing + * properties. Property lists are deleted by closing the associated handles. * - * \todo Describe concisely what the functions in this module are about. + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5P_examples.c create + * </td> + * <td> + * \snippet{lineno} H5P_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5P_examples.c update + * </td> + * <td> + * \snippet{lineno} H5P_examples.c delete + * </td> + * </tr> + * </table> * - * \defgroup GPLO General Property List Operations + * \defgroup ALCAPL Attribute and Link Creation Properties * \ingroup H5P - * \defgroup GPLOA General Property List Operations (Advanced) + * Currently, there are only two creation properties that you can use to control + * the creation of HDF5 attributes and links. The first creation property, the + * choice of a character encoding, applies to both attributes and links. + * The second creation property applies to links only, and advises the library + * to automatically create missing intermediate groups when creating new objects. + * + * \defgroup DAPL Dataset Access Properties * \ingroup H5P - * \defgroup FCPL File Creation Properties + * Use dataset access properties to modify the default behavior of the HDF5 + * library when accessing datasets. The properties include adjusting the size + * of the chunk cache, providing prefixes for external content and virtual + * dataset file paths, and controlling flush behavior, etc. These properties + * are \Emph{not} persisted with datasets, and can be adjusted at runtime before + * a dataset is created or opened. + * + * \defgroup DCPL Dataset Creation Properties + * \ingroup H5P + * Use dataset creation properties to control aspects of dataset creation such + * as fill time, storage layout, compression methods, etc. + * Unlike dataset access and transfer properties, creation properties \Emph{are} + * stored with the dataset, and cannot be changed once a dataset has been + * created. + * + * \defgroup DXPL Dataset Transfer Properties * \ingroup H5P + * Use dataset transfer properties to customize certain aspects of reading + * and writing datasets such as transformations, MPI-IO I/O mode, error + * detection, etc. These properties are \Emph{not} persisted with datasets, + * and can be adjusted at runtime before a dataset is read or written. + * * \defgroup FAPL File Access Properties * \ingroup H5P - * \defgroup GCPL Group Creation Properties + * Use file access properties to modify the default behavior of the HDF5 + * library when accessing files. The properties include selecting a virtual + * file driver (VFD), configuring the metadata cache (MDC), control + * file locking, etc. These properties are \Emph{not} persisted with files, and + * can be adjusted at runtime before a file is created or opened. + * + * \defgroup FCPL File Creation Properties * \ingroup H5P - * \defgroup ALCAPL Attribute and Link Creation Properties + * Use file creation properties to control aspects of file creation such + * as setting a file space management strategy or creating a user block. + * Unlike file access properties, creation properties \Emph{are} + * stored with the file, and cannot be changed once a file has been + * created. + * + * \defgroup GAPL General Access Properties * \ingroup H5P - * \defgroup LAPL Link Access Properties + * \todo Should this be as standalone page? + * + * \defgroup GCPL Group Creation Properties * \ingroup H5P - * \defgroup DCPL Dataset Creation Properties + * Use group creation properties to control aspects of group creation such + * as storage layout, compression, and link creation order tracking. + * Unlike file access properties, creation properties \Emph{are} + * stored with the group, and cannot be changed once a group has been + * created. + * + * \defgroup GPLO General Property List Operations * \ingroup H5P - * \defgroup DAPL Dataset Access Properties + * + * Use the functions in this module to manage HDF5 property lists. + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5P_examples.c create + * </td> + * <td> + * \snippet{lineno} H5P_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5P_examples.c update + * </td> + * <td> + * \snippet{lineno} H5P_examples.c delete + * </td> + * </tr> + * </table> + * + * \defgroup GPLOA General Property List Operations (Advanced) * \ingroup H5P - * \defgroup DXPL Dataset Transfer Properties + * + * You can create and customize user-defined property list classes using the + * functions described below. Arbitrary user-defined properties can also + * be inserted into existing property lists as so-called temporary properties. + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * + * <tr valign="top"> + * <td> + * \snippet{lineno} H5P_examples.c create_class + * </td> + * <td> + * \snippet{lineno} H5P_examples.c read_class + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5P_examples.c update_class + * </td> + * <td> + * \snippet{lineno} H5P_examples.c delete_class + * </td> + * </tr> + * </table> + * + * \defgroup LAPL Link Access Properties * \ingroup H5P + * + * + * \defgroup MAPL Map Access Properties + * \ingroup H5P + * \defgroup OCPL Object Creation Properties * \ingroup H5P + * + * * \defgroup OCPPL Object Copy Properties * \ingroup H5P - * \defgroup GACPL General Access Properties - * \ingroup H5P - * \defgroup MAPL Map Access Properties - * \ingroup H5P + * + * */ #endif /* H5Pmodule_H */ diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index 72a2358..cba7e03 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -22,16 +22,17 @@ /* Public headers needed by this file */ #include "H5public.h" -#include "H5ACpublic.h" -#include "H5Dpublic.h" -#include "H5Fpublic.h" -#include "H5FDpublic.h" -#include "H5Ipublic.h" -#include "H5Lpublic.h" -#include "H5Opublic.h" -#include "H5MMpublic.h" -#include "H5Tpublic.h" -#include "H5Zpublic.h" +#include "H5ACpublic.h" /* Metadata cache */ +#include "H5Dpublic.h" /* Datasets */ +#include "H5Fpublic.h" /* Files */ +#include "H5FDpublic.h" /* File drivers */ +#include "H5Ipublic.h" /* ID management */ +#include "H5Lpublic.h" /* Links */ +#include "H5MMpublic.h" /* Memory management */ +#include "H5Opublic.h" /* Object headers */ +#include "H5Spublic.h" /* Dataspaces */ +#include "H5Tpublic.h" /* Datatypes */ +#include "H5Zpublic.h" /* Data filters */ /*****************/ /* Public Macros */ @@ -100,7 +101,9 @@ #define H5P_CRT_ORDER_TRACKED 0x0001 #define H5P_CRT_ORDER_INDEXED 0x0002 -/* Default value for all property list classes */ +/** + * Default value of type \ref hid_t for all property list classes + */ #define H5P_DEFAULT 0 /* (hid_t) */ #ifdef __cplusplus @@ -113,14 +116,23 @@ extern "C" { /* Define property list class callback function pointer types */ //! <!-- [H5P_cls_create_func_t_snip] --> +/** + * \todo Document me! + */ typedef herr_t (*H5P_cls_create_func_t)(hid_t prop_id, void *create_data); //! <!-- [H5P_cls_create_func_t_snip] --> //! <!-- [H5P_cls_copy_func_t_snip] --> +/** + * \todo Document me! + */ typedef herr_t (*H5P_cls_copy_func_t)(hid_t new_prop_id, hid_t old_prop_id, void *copy_data); //! <!-- [H5P_cls_copy_func_t_snip] --> //! <!-- [H5P_cls_close_func_t_snip] --> +/** + * \todo Document me! + */ typedef herr_t (*H5P_cls_close_func_t)(hid_t prop_id, void *close_data); //! <!-- [H5P_cls_close_func_t_snip] --> @@ -159,12 +171,25 @@ typedef herr_t (*H5P_prp_cb2_t)(hid_t prop_id, const char *name, size_t size, vo typedef H5P_prp_cb1_t H5P_prp_create_func_t; typedef H5P_prp_cb2_t H5P_prp_set_func_t; typedef H5P_prp_cb2_t H5P_prp_get_func_t; +//! <!-- [H5P_prp_encode_func_t_snip] --> +/** + * \todo Document me! + */ typedef herr_t (*H5P_prp_encode_func_t)(const void *value, void **buf, size_t *size); +//! <!-- [H5P_prp_encode_func_t_snip] --> +//! <!-- [H5P_prp_decode_func_t_snip] --> +/** + * \todo Document me! + */ typedef herr_t (*H5P_prp_decode_func_t)(const void **buf, void *value); +//! <!-- [H5P_prp_decode_func_t_snip] --> typedef H5P_prp_cb2_t H5P_prp_delete_func_t; typedef H5P_prp_cb1_t H5P_prp_copy_func_t; //! <!-- [H5P_prp_compare_func_t_snip] --> +/** + * \todo Document me! + */ typedef int (*H5P_prp_compare_func_t)(const void *value1, const void *value2, size_t size); //! <!-- [H5P_prp_compare_func_t_snip] --> @@ -172,6 +197,9 @@ typedef H5P_prp_cb1_t H5P_prp_close_func_t; /* Define property list iteration function type */ //! <!-- [H5P_iterate_t_snip] --> +/** + * \todo Document me! + */ typedef herr_t (*H5P_iterate_t)(hid_t id, const char *name, void *iter_data); //! <!-- [H5P_iterate_t_snip] --> @@ -2212,7 +2240,7 @@ H5_DLL herr_t H5Pset_attr_creation_order(hid_t plist_id, unsigned crt_order_flag */ H5_DLL herr_t H5Pset_attr_phase_change(hid_t plist_id, unsigned max_compact, unsigned min_dense); /** - * \ingroup OCPL + * \ingroup DCPL * * \brief Sets deflate (GNU gzip) compression method and compression level * @@ -2221,6 +2249,8 @@ H5_DLL herr_t H5Pset_attr_phase_change(hid_t plist_id, unsigned max_compact, uns * * \return \herr_t * + * \par_compr_note + * * \details H5Pset_deflate() sets the deflate compression method and the * compression level, \p level, for a dataset or group creation * property list, \p plist_id. @@ -5212,9 +5242,37 @@ H5_DLL herr_t H5Pset_small_data_block_size(hid_t fapl_id, hsize_t size); */ H5_DLL herr_t H5Pset_vol(hid_t plist_id, hid_t new_vol_id, const void *new_vol_info); +/** + * \ingroup FAPL + * + * \brief Query the capability flags for the VOL connector that will be used + * with this file access property list (FAPL). + * + * \fapl_id{plist_id} + * \param[out] cap_flags Flags that indicate the VOL connector capabilities + * + * \return \herr_t + * + * \details H5Pget_vol_cap_flags() queries the current VOL connector information + * for a FAPL to retrieve the capability flags for the VOL + * connector stack, as will be used by a file open or create + * operation that uses this FAPL. + * + * \note This routine supports the use of the HDF5_VOL_CONNECTOR environment + * variable to override the VOL connector set programmatically for the + * FAPL (with H5Pset_vol). + * + * \note The H5VL_CAP_FLAG_ASYNC flag can be checked to see if asynchronous + * operations are supported by the VOL connector stack. + * + * \since 1.13.0 + * + */ +H5_DLL herr_t H5Pget_vol_cap_flags(hid_t plist_id, unsigned *cap_flags); + #ifdef H5_HAVE_PARALLEL /** - * \ingroup GACPL + * \ingroup GAPL * * \brief Sets metadata I/O mode for read operations to collective or independent (default) * @@ -5283,7 +5341,7 @@ H5_DLL herr_t H5Pset_vol(hid_t plist_id, hid_t new_vol_id, const void *new_vol_i */ H5_DLL herr_t H5Pset_all_coll_metadata_ops(hid_t plist_id, hbool_t is_collective); /** - * \ingroup GACPL + * \ingroup GAPL * * \brief Retrieves metadata read mode setting * @@ -6247,6 +6305,8 @@ H5_DLL herr_t H5Pset_fill_value(hid_t plist_id, hid_t type_id, const void *value * * \return \herr_t * + * \par_compr_note + * * \details H5Pset_shuffle() sets the shuffle filter, #H5Z_FILTER_SHUFFLE, * in the dataset creation property list \p plist_id. The shuffle * filter de-interlaces a block of data by reordering the bytes. @@ -6318,6 +6378,8 @@ H5_DLL herr_t H5Pset_layout(hid_t plist_id, H5D_layout_t layout); * * \return \herr_t * + * \par_compr_note + * * \details H5Pset_nbit() sets the N-Bit filter, #H5Z_FILTER_NBIT, in the * dataset creation property list \p plist_id. * @@ -6411,6 +6473,8 @@ H5_DLL herr_t H5Pset_nbit(hid_t plist_id); * * \return \herr_t * + * \par_compr_note + * * \details H5Pset_scaleoffset() sets the scale-offset filter, * #H5Z_FILTER_SCALEOFFSET, for a dataset. * @@ -6520,6 +6584,8 @@ H5_DLL herr_t H5Pset_scaleoffset(hid_t plist_id, H5Z_SO_scale_type_t scale_type, * * \return \herr_t * + * \par_compr_note + * * \details H5Pset_szip() sets an SZIP compression filter, #H5Z_FILTER_SZIP, * for a dataset. SZIP is a compression method designed for use with * scientific data. @@ -7430,10 +7496,6 @@ H5_DLL size_t H5Pget_buffer(hid_t plist_id, void **tconv /*out*/, void **bkg /*o * If an error occurs, the buffer pointed to by \p expression is * unchanged, and the function returns a negative value. * - * \par Example - * An example snippet from examples/h5_dtransform.c: - * \snippet h5_dtransform.c H5Pget_data_transform_snip - * * \since 1.8.0 * */ @@ -8009,6 +8071,44 @@ H5_DLL herr_t H5Pget_mpio_actual_io_mode(hid_t plist_id, H5D_mpio_actual_io_mode H5_DLL herr_t H5Pget_mpio_no_collective_cause(hid_t plist_id, uint32_t *local_no_collective_cause, uint32_t *global_no_collective_cause); #endif /* H5_HAVE_PARALLEL */ +/** + * + * \ingroup DXPL + * + * \brief Sets a hyperslab file selection for a dataset I/O operation + * + * \param[in] plist_id Property list identifier + * \param[in] rank Number of dimensions of selection + * \param[in] op Operation to perform on current selection + * \param[in] start Offset of start of hyperslab + * \param[in] stride Hyperslab stride + * \param[in] count Number of blocks included in hyperslab + * \param[in] block Size of block in hyperslab + * + * \return \herr_t + * + * \details H5Pset_dataset_io_hyperslab_selection() is designed to be used + * in conjunction with using #H5S_PLIST for the file dataspace + * ID when making a call to H5Dread() or H5Dwrite(). When used + * with #H5S_PLIST, the selection created by one or more calls to + * this routine is used for determining which dataset elements to + * access. + * + * \p rank is the dimensionality of the selection and determines + * the size of the \p start, \p stride, \p count, and \p block arrays. + * \p rank must be between 1 and #H5S_MAX_RANK, inclusive. + * + * The \p op, \p start, \p stride, \p count, and \p block parameters + * behave identically to their behavior for H5Sselect_hyperslab(), + * please see the documentation for that routine for details about + * their use. + * + * \since 1.13.0 + * + */ +H5_DLL herr_t H5Pset_dataset_io_hyperslab_selection(hid_t plist_id, unsigned rank, H5S_seloper_t op, + const hsize_t start[], const hsize_t stride[], + const hsize_t count[], const hsize_t block[]); /* Link creation property list (LCPL) routines */ /** @@ -9398,9 +9498,6 @@ H5_DLL herr_t H5Pset_mcdt_search_cb(hid_t plist_id, H5O_mcdt_search_cb_t func, v * The #H5P_prp_cb2_t is as follows: * \snippet this H5P_prp_cb2_t_snip * - * - * \cpp_c_api_note - * */ /* Function prototypes */ @@ -9514,8 +9611,7 @@ H5_DLL herr_t H5Pregister1(hid_t cls_id, const char *name, size_t size, void *de * * The #H5P_prp_cb2_t is as follows: * \snippet this H5P_prp_cb2_t_snip - - * \cpp_c_api_note + * */ H5_DLL herr_t H5Pinsert1(hid_t plist_id, const char *name, size_t size, void *value, H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get, diff --git a/src/H5R.c b/src/H5R.c index 1413c1c..102af7f 100644 --- a/src/H5R.c +++ b/src/H5R.c @@ -79,14 +79,16 @@ static hid_t H5R__open_attr_api_common(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t herr_t H5Rcreate_object(hid_t loc_id, const char *name, hid_t oapl_id, H5R_ref_t *ref_ptr) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5I_type_t obj_type; /* Object type of loc_id */ - hid_t file_id = H5I_INVALID_HID; /* File ID */ - H5VL_object_t * vol_obj_file = NULL; /* Object of file_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - H5O_token_t obj_token = {0}; /* Object token */ - H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5I_type_t obj_type; /* Object type of loc_id */ + hid_t file_id = H5I_INVALID_HID; /* File ID */ + H5VL_object_t * vol_obj_file = NULL; /* Object of file_id */ + H5VL_object_specific_args_t obj_spec_vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5O_token_t obj_token = {0}; /* Object token */ + H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + H5VL_file_get_args_t file_get_vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "i*si*Rr", loc_id, name, oapl_id, ref_ptr); @@ -121,9 +123,12 @@ H5Rcreate_object(hid_t loc_id, const char *name, hid_t oapl_id, H5R_ref_t *ref_p if (NULL == (vol_obj_file = H5VL_vol_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + file_get_vol_cb_args.op_type = H5VL_FILE_GET_CONT_INFO; + file_get_vol_cb_args.args.get_cont_info.info = &cont_info; + /* Get container info */ - if (H5VL_file_get(vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &cont_info) < 0) + if (H5VL_file_get(vol_obj_file, &file_get_vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get container info") /* Set location parameters */ @@ -132,15 +137,18 @@ H5Rcreate_object(hid_t loc_id, const char *name, hid_t oapl_id, H5R_ref_t *ref_p loc_params.loc_data.loc_by_name.lapl_id = oapl_id; loc_params.obj_type = obj_type; + /* Set up VOL callback arguments */ + obj_spec_vol_cb_args.op_type = H5VL_OBJECT_LOOKUP; + obj_spec_vol_cb_args.args.lookup.token_ptr = &obj_token; + /* Get the object token */ - if (H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_LOOKUP, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &obj_token) < 0) + if (H5VL_object_specific(vol_obj, &loc_params, &obj_spec_vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to retrieve object token") /* Create the reference (do not pass filename, since file_id is attached) */ HDmemset(ref_ptr, 0, H5R_REF_BUF_SIZE); - if (H5R__create_object((const H5O_token_t *)&obj_token, cont_info.token_size, (H5R_ref_priv_t *)ref_ptr) < - 0) + if (H5R__create_object(&obj_token, cont_info.token_size, (H5R_ref_priv_t *)ref_ptr) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create object reference") /* Attach loc_id to reference and hold reference to it */ @@ -167,15 +175,17 @@ done: herr_t H5Rcreate_region(hid_t loc_id, const char *name, hid_t space_id, hid_t oapl_id, H5R_ref_t *ref_ptr) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5I_type_t obj_type; /* Object type of loc_id */ - hid_t file_id = H5I_INVALID_HID; /* File ID */ - H5VL_object_t * vol_obj_file = NULL; /* Object of file_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - H5O_token_t obj_token = {0}; /* Object token */ - H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; - struct H5S_t * space = NULL; /* Pointer to dataspace containing region */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5I_type_t obj_type; /* Object type of loc_id */ + hid_t file_id = H5I_INVALID_HID; /* File ID */ + H5VL_object_t * vol_obj_file = NULL; /* Object of file_id */ + H5VL_object_specific_args_t obj_spec_vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5O_token_t obj_token = {0}; /* Object token */ + H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + H5VL_file_get_args_t file_get_vol_cb_args; /* Arguments to VOL callback */ + struct H5S_t * space = NULL; /* Pointer to dataspace containing region */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "i*sii*Rr", loc_id, name, space_id, oapl_id, ref_ptr); @@ -185,7 +195,7 @@ H5Rcreate_region(hid_t loc_id, const char *name, hid_t space_id, hid_t oapl_id, HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") if (!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name given") - if ((space_id == H5I_INVALID_HID) || (space_id == H5S_ALL)) + if ((space_id == H5I_INVALID_HID) || (space_id == H5S_ALL) || (space_id == H5S_BLOCK)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "reference region dataspace id must be valid") if (NULL == (space = (struct H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") @@ -214,9 +224,12 @@ H5Rcreate_region(hid_t loc_id, const char *name, hid_t space_id, hid_t oapl_id, if (NULL == (vol_obj_file = H5VL_vol_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + file_get_vol_cb_args.op_type = H5VL_FILE_GET_CONT_INFO; + file_get_vol_cb_args.args.get_cont_info.info = &cont_info; + /* Get container info */ - if (H5VL_file_get(vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &cont_info) < 0) + if (H5VL_file_get(vol_obj_file, &file_get_vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get container info") /* Set location parameters */ @@ -225,9 +238,13 @@ H5Rcreate_region(hid_t loc_id, const char *name, hid_t space_id, hid_t oapl_id, loc_params.loc_data.loc_by_name.lapl_id = oapl_id; loc_params.obj_type = obj_type; + /* Set up VOL callback arguments */ + obj_spec_vol_cb_args.op_type = H5VL_OBJECT_LOOKUP; + obj_spec_vol_cb_args.args.lookup.token_ptr = &obj_token; + /* Get the object token */ - if (H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_LOOKUP, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &obj_token) < 0) + if (H5VL_object_specific(vol_obj, &loc_params, &obj_spec_vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to retrieve object token") /* Create the reference (do not pass filename, since file_id is attached) */ @@ -259,14 +276,16 @@ done: herr_t H5Rcreate_attr(hid_t loc_id, const char *name, const char *attr_name, hid_t oapl_id, H5R_ref_t *ref_ptr) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5I_type_t obj_type; /* Object type of loc_id */ - hid_t file_id = H5I_INVALID_HID; /* File ID */ - H5VL_object_t * vol_obj_file = NULL; /* Object of file_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - H5O_token_t obj_token = {0}; /* Object token */ - H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5I_type_t obj_type; /* Object type of loc_id */ + hid_t file_id = H5I_INVALID_HID; /* File ID */ + H5VL_object_t * vol_obj_file = NULL; /* Object of file_id */ + H5VL_object_specific_args_t obj_spec_vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5O_token_t obj_token = {0}; /* Object token */ + H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + H5VL_file_get_args_t file_get_vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "i*s*si*Rr", loc_id, name, attr_name, oapl_id, ref_ptr); @@ -303,9 +322,12 @@ H5Rcreate_attr(hid_t loc_id, const char *name, const char *attr_name, hid_t oapl if (NULL == (vol_obj_file = H5VL_vol_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + file_get_vol_cb_args.op_type = H5VL_FILE_GET_CONT_INFO; + file_get_vol_cb_args.args.get_cont_info.info = &cont_info; + /* Get container info */ - if (H5VL_file_get(vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &cont_info) < 0) + if (H5VL_file_get(vol_obj_file, &file_get_vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get container info") /* Set location parameters */ @@ -314,9 +336,13 @@ H5Rcreate_attr(hid_t loc_id, const char *name, const char *attr_name, hid_t oapl loc_params.loc_data.loc_by_name.lapl_id = oapl_id; loc_params.obj_type = obj_type; + /* Set up VOL callback arguments */ + obj_spec_vol_cb_args.op_type = H5VL_OBJECT_LOOKUP; + obj_spec_vol_cb_args.args.lookup.token_ptr = &obj_token; + /* Get the object token */ - if (H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_LOOKUP, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &obj_token) < 0) + if (H5VL_object_specific(vol_obj, &loc_params, &obj_spec_vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to retrieve object token") /* Create the reference (do not pass filename, since file_id is attached) */ @@ -611,15 +637,16 @@ H5R__open_region_api_common(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id, vo hid_t loc_id; /* Reference location ID */ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = - (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - H5O_token_t obj_token = {0}; /* Object token */ - H5I_type_t opened_type; /* Opened object type */ - void * opened_obj = NULL; /* Opened object */ - hid_t opened_obj_id = H5I_INVALID_HID; /* Opened object ID */ - H5S_t * space = NULL; /* Dataspace pointer (copy) */ - hid_t space_id = H5I_INVALID_HID; /* Dataspace ID */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5VL_dataset_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5O_token_t obj_token = {0}; /* Object token */ + H5I_type_t opened_type; /* Opened object type */ + void * opened_obj = NULL; /* Opened object */ + hid_t opened_obj_id = H5I_INVALID_HID; /* Opened object ID */ + H5S_t * space = NULL; /* Dataspace pointer (copy) */ + hid_t space_id = H5I_INVALID_HID; /* Dataspace ID */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_STATIC @@ -662,10 +689,14 @@ H5R__open_region_api_common(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id, vo if (NULL == (opened_obj = H5VL_vol_object(opened_obj_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_GET_SPACE; + vol_cb_args.args.get_space.space_id = H5I_INVALID_HID; + /* Get dataspace from object */ - if (H5VL_dataset_get(opened_obj, H5VL_DATASET_GET_SPACE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &space_id) < 0) + if (H5VL_dataset_get(opened_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get dataspace from dataset") + space_id = vol_cb_args.args.get_space.space_id; if (NULL == (space = (struct H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a dataspace") @@ -940,11 +971,12 @@ done: herr_t H5Rget_obj_type3(H5R_ref_t *ref_ptr, hid_t rapl_id, H5O_type_t *obj_type /*out*/) { - hid_t loc_id; /* Reference location ID */ - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - H5O_token_t obj_token = {0}; /* Object token */ - herr_t ret_value = SUCCEED; /* Return value */ + hid_t loc_id; /* Reference location ID */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5O_token_t obj_token = {0}; /* Object token */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "*Rrix", ref_ptr, rapl_id, obj_type); @@ -959,11 +991,10 @@ H5Rget_obj_type3(H5R_ref_t *ref_ptr, hid_t rapl_id, H5O_type_t *obj_type /*out*/ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") /* Retrieve loc_id from reference */ - if (H5I_INVALID_HID == (loc_id = H5R__get_loc_id((const H5R_ref_priv_t *)ref_ptr))) { + if (H5I_INVALID_HID == (loc_id = H5R__get_loc_id((const H5R_ref_priv_t *)ref_ptr))) /* Attempt to re-open file and pass rapl_id as a fapl_id */ if ((loc_id = H5R__reopen_file((H5R_ref_priv_t *)ref_ptr, rapl_id)) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENFILE, FAIL, "cannot re-open referenced file") - } /* Get object token */ if (H5R__get_obj_token((const H5R_ref_priv_t *)ref_ptr, &obj_token, NULL) < 0) @@ -978,9 +1009,12 @@ H5Rget_obj_type3(H5R_ref_t *ref_ptr, hid_t rapl_id, H5O_type_t *obj_type /*out*/ loc_params.loc_data.loc_by_token.token = &obj_token; loc_params.obj_type = H5I_get_type(loc_id); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_TYPE; + vol_cb_args.args.get_type.obj_type = obj_type; + /* Retrieve object's type */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_TYPE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - obj_type) < 0) + if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't retrieve object type") done: @@ -1021,15 +1055,27 @@ H5Rget_file_name(const H5R_ref_t *ref_ptr, char *buf /*out*/, size_t size) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "unable to retrieve file name") } else { - H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ + size_t file_name_len = 0; /* Length of file name */ /* Retrieve VOL file object */ if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid location identifier") - if (H5VL_file_get(vol_obj, H5VL_FILE_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, H5I_FILE, - size, buf, &ret_value) < 0) + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_NAME; + vol_cb_args.args.get_name.type = H5I_FILE; + vol_cb_args.args.get_name.buf_size = size; + vol_cb_args.args.get_name.buf = buf; + vol_cb_args.args.get_name.file_name_len = &file_name_len; + + /* Get file name */ + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "unable to get file name") + + /* Set return value */ + ret_value = (ssize_t)file_name_len; } done: @@ -1049,11 +1095,13 @@ done: ssize_t H5Rget_obj_name(H5R_ref_t *ref_ptr, hid_t rapl_id, char *buf /*out*/, size_t size) { - hid_t loc_id; /* Reference location ID */ - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - H5O_token_t obj_token = {0}; /* Object token */ - ssize_t ret_value = 0; /* Return value */ + hid_t loc_id; /* Reference location ID */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5O_token_t obj_token = {0}; /* Object token */ + size_t obj_name_len = 0; /* Length of object's name */ + ssize_t ret_value = 0; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE4("Zs", "*Rrixz", ref_ptr, rapl_id, buf, size); @@ -1068,11 +1116,10 @@ H5Rget_obj_name(H5R_ref_t *ref_ptr, hid_t rapl_id, char *buf /*out*/, size_t siz HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "not a property list") /* Retrieve loc_id from reference */ - if (H5I_INVALID_HID == (loc_id = H5R__get_loc_id((const H5R_ref_priv_t *)ref_ptr))) { + if (H5I_INVALID_HID == (loc_id = H5R__get_loc_id((const H5R_ref_priv_t *)ref_ptr))) /* Attempt to re-open file and pass rapl_id as a fapl_id */ if ((loc_id = H5R__reopen_file((H5R_ref_priv_t *)ref_ptr, rapl_id)) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENFILE, (-1), "cannot re-open referenced file") - } /* Get object token */ if (H5R__get_obj_token((const H5R_ref_priv_t *)ref_ptr, &obj_token, NULL) < 0) @@ -1087,11 +1134,19 @@ H5Rget_obj_name(H5R_ref_t *ref_ptr, hid_t rapl_id, char *buf /*out*/, size_t siz loc_params.loc_data.loc_by_token.token = &obj_token; loc_params.obj_type = H5I_get_type(loc_id); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_NAME; + vol_cb_args.args.get_name.buf_size = size; + vol_cb_args.args.get_name.buf = buf; + vol_cb_args.args.get_name.name_len = &obj_name_len; + /* Retrieve object's name */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &ret_value, buf, size) < 0) + if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "can't retrieve object name") + /* Set return value */ + ret_value = (ssize_t)obj_name_len; + done: FUNC_LEAVE_API(ret_value) } /* end H5Rget_obj_name() */ diff --git a/src/H5RS.c b/src/H5RS.c index 96d55e7..d9915f2 100644 --- a/src/H5RS.c +++ b/src/H5RS.c @@ -349,7 +349,7 @@ done: * format_templ in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("format-nonliteral") +H5_GCC_CLANG_DIAG_OFF("format-nonliteral") H5_ATTR_FORMAT(printf, 2, 3) herr_t H5RS_asprintf_cat(H5RS_str_t *rs, const char *fmt, ...) @@ -392,7 +392,7 @@ H5RS_asprintf_cat(H5RS_str_t *rs, const char *fmt, ...) done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5RS_asprintf_cat() */ -H5_GCC_DIAG_ON("format-nonliteral") +H5_GCC_CLANG_DIAG_ON("format-nonliteral") /*------------------------------------------------------------------------- * Function: H5RS_acat @@ -698,7 +698,7 @@ H5RS_cmp(const H5RS_str_t *rs1, const H5RS_str_t *rs2) const H5RS_str_t *rs; IN: Ref-counted string to compute length of RETURNS - Returns non-negative value on success, negative value on failure + Returns non-negative value on success, can't fail DESCRIPTION Compute the length of a ref-counted string. [same as strlen()] GLOBAL VARIABLES @@ -706,7 +706,7 @@ H5RS_cmp(const H5RS_str_t *rs1, const H5RS_str_t *rs2) EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -ssize_t +size_t H5RS_len(const H5RS_str_t *rs) { FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -715,7 +715,7 @@ H5RS_len(const H5RS_str_t *rs) HDassert(rs); HDassert(rs->s); - FUNC_LEAVE_NOAPI((ssize_t)HDstrlen(rs->s)) + FUNC_LEAVE_NOAPI(HDstrlen(rs->s)) } /* end H5RS_len() */ /*-------------------------------------------------------------------------- diff --git a/src/H5RSprivate.h b/src/H5RSprivate.h index 7d2b728..ebca1a3 100644 --- a/src/H5RSprivate.h +++ b/src/H5RSprivate.h @@ -53,7 +53,7 @@ H5_DLL herr_t H5RS_acat(H5RS_str_t *rs, const char *s); H5_DLL herr_t H5RS_ancat(H5RS_str_t *rs, const char *s, size_t len); H5_DLL herr_t H5RS_aputc(H5RS_str_t *rs, int c); H5_DLL int H5RS_cmp(const H5RS_str_t *rs1, const H5RS_str_t *rs2); -H5_DLL ssize_t H5RS_len(const H5RS_str_t *rs); +H5_DLL size_t H5RS_len(const H5RS_str_t *rs); H5_DLL char * H5RS_get_str(const H5RS_str_t *rs); H5_DLL unsigned H5RS_get_count(const H5RS_str_t *rs); diff --git a/src/H5Rdeprec.c b/src/H5Rdeprec.c index d5f5a7d..3f1d70f 100644 --- a/src/H5Rdeprec.c +++ b/src/H5Rdeprec.c @@ -94,7 +94,8 @@ H5R__decode_token_compat(H5VL_object_t *vol_obj, H5I_type_t type, H5R_type_t ref hid_t file_id = H5I_INVALID_HID; /* File ID for region reference */ H5VL_object_t * vol_obj_file = NULL; H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; - herr_t ret_value = SUCCEED; + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; FUNC_ENTER_STATIC @@ -119,9 +120,12 @@ H5R__decode_token_compat(H5VL_object_t *vol_obj, H5I_type_t type, H5R_type_t ref if (NULL == (vol_obj_file = H5VL_vol_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_CONT_INFO; + vol_cb_args.args.get_cont_info.info = &cont_info; + /* Get container info */ - if (H5VL_file_get((const H5VL_object_t *)vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &cont_info) < 0) + if (H5VL_file_get(vol_obj_file, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get container info") if (ref_type == H5R_OBJECT1) { @@ -240,13 +244,14 @@ done: H5G_obj_t H5Rget_obj_type1(hid_t id, H5R_type_t ref_type, const void *ref) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - H5O_token_t obj_token = {0}; /* Object token */ - H5O_type_t obj_type; /* Object type */ - const unsigned char *buf = (const unsigned char *)ref; /* Reference buffer */ - H5G_obj_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5O_token_t obj_token = {0}; /* Object token */ + const unsigned char * buf = (const unsigned char *)ref; /* Reference buffer */ + H5O_type_t obj_type = H5O_TYPE_UNKNOWN; /* Type of the referenced object */ + H5G_obj_t ret_value; /* Return value */ FUNC_ENTER_API(H5G_UNKNOWN) H5TRACE3("Go", "iRt*x", id, ref_type, ref); @@ -274,9 +279,12 @@ H5Rget_obj_type1(hid_t id, H5R_type_t ref_type, const void *ref) loc_params.loc_data.loc_by_token.token = &obj_token; loc_params.obj_type = vol_obj_type; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_TYPE; + vol_cb_args.args.get_type.obj_type = &obj_type; + /* Retrieve object's type */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_TYPE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &obj_type) < 0) + if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5G_UNKNOWN, "can't retrieve object type") /* Set return value */ @@ -365,15 +373,17 @@ done: herr_t H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t space_id) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - H5O_token_t obj_token = {0}; /* Object token */ - H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; - hid_t file_id = H5I_INVALID_HID; /* File ID for region reference */ - void * vol_obj_file = NULL; - unsigned char * buf = (unsigned char *)ref; /* Return reference pointer */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ + H5VL_object_specific_args_t obj_spec_vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5O_token_t obj_token = {0}; /* Object token */ + H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + H5VL_file_get_args_t file_get_vol_cb_args; /* Arguments to VOL callback */ + hid_t file_id = H5I_INVALID_HID; /* File ID for region reference */ + void * vol_obj_file = NULL; + unsigned char * buf = (unsigned char *)ref; /* Return reference pointer */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "*xi*sRti", ref, loc_id, name, ref_type, space_id); @@ -417,9 +427,13 @@ H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; loc_params.obj_type = vol_obj_type; + /* Set up VOL callback arguments */ + obj_spec_vol_cb_args.op_type = H5VL_OBJECT_LOOKUP; + obj_spec_vol_cb_args.args.lookup.token_ptr = &obj_token; + /* Get the object token */ - if (H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_LOOKUP, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &obj_token) < 0) + if (H5VL_object_specific(vol_obj, &loc_params, &obj_spec_vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to retrieve object token") /* Get the file for the object */ @@ -430,9 +444,12 @@ H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t if (NULL == (vol_obj_file = H5VL_vol_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + file_get_vol_cb_args.op_type = H5VL_FILE_GET_CONT_INFO; + file_get_vol_cb_args.args.get_cont_info.info = &cont_info; + /* Get container info */ - if (H5VL_file_get((const H5VL_object_t *)vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &cont_info) < 0) + if (H5VL_file_get(vol_obj_file, &file_get_vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get container info") /* Create reference */ @@ -483,12 +500,13 @@ done: herr_t H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *ref, H5O_type_t *obj_type /*out*/) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - H5O_token_t obj_token = {0}; /* Object token */ - const unsigned char *buf = (const unsigned char *)ref; /* Reference pointer */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5O_token_t obj_token = {0}; /* Object token */ + const unsigned char * buf = (const unsigned char *)ref; /* Reference pointer */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "iRt*xx", id, ref_type, ref, obj_type); @@ -516,9 +534,12 @@ H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *ref, H5O_type_t *obj loc_params.loc_data.loc_by_token.token = &obj_token; loc_params.obj_type = vol_obj_type; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_TYPE; + vol_cb_args.args.get_type.obj_type = obj_type; + /* Retrieve object's type */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_TYPE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - obj_type) < 0) + if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't retrieve object type") done: @@ -612,12 +633,13 @@ H5Rget_region(hid_t id, H5R_type_t ref_type, const void *ref) H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ void * vol_obj_file = NULL; /* VOL file */ H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; - H5F_t * f = NULL; /* Native file */ - size_t buf_size = H5R_DSET_REG_REF_BUF_SIZE; /* Reference buffer size */ - H5S_t * space = NULL; /* Dataspace object */ - hid_t file_id = H5I_INVALID_HID; /* File ID for region reference */ - const unsigned char * buf = (const unsigned char *)ref; /* Reference pointer */ - hid_t ret_value; /* Return value */ + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5F_t * f = NULL; /* Native file */ + size_t buf_size = H5R_DSET_REG_REF_BUF_SIZE; /* Reference buffer size */ + H5S_t * space = NULL; /* Dataspace object */ + hid_t file_id = H5I_INVALID_HID; /* File ID for region reference */ + const unsigned char * buf = (const unsigned char *)ref; /* Reference pointer */ + hid_t ret_value; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE3("i", "iRt*x", id, ref_type, ref); @@ -658,9 +680,12 @@ H5Rget_region(hid_t id, H5R_type_t ref_type, const void *ref) if (NULL == (vol_obj_file = H5VL_vol_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_CONT_INFO; + vol_cb_args.args.get_cont_info.info = &cont_info; + /* Get container info */ - if (H5VL_file_get((const H5VL_object_t *)vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &cont_info) < 0) + if (H5VL_file_get(vol_obj_file, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get container info") /* Retrieve file from VOL object */ @@ -695,12 +720,14 @@ done: ssize_t H5Rget_name(hid_t id, H5R_type_t ref_type, const void *ref, char *name /*out*/, size_t size) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - H5O_token_t obj_token = {0}; /* Object token */ - const unsigned char *buf = (const unsigned char *)ref; /* Reference pointer */ - ssize_t ret_value = -1; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5O_token_t obj_token = {0}; /* Object token */ + const unsigned char * buf = (const unsigned char *)ref; /* Reference pointer */ + size_t obj_name_len = 0; /* Length of object's name */ + ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE5("Zs", "iRt*xxz", id, ref_type, ref, name, size); @@ -728,11 +755,19 @@ H5Rget_name(hid_t id, H5R_type_t ref_type, const void *ref, char *name /*out*/, loc_params.loc_data.loc_by_token.token = &obj_token; loc_params.obj_type = vol_obj_type; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_NAME; + vol_cb_args.args.get_name.buf_size = size; + vol_cb_args.args.get_name.buf = name; + vol_cb_args.args.get_name.name_len = &obj_name_len; + /* Retrieve object's name */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &ret_value, name, size) < 0) + if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "can't retrieve object name") + /* Set return value */ + ret_value = (ssize_t)obj_name_len; + done: FUNC_LEAVE_API(ret_value) } /* end H5Rget_name() */ diff --git a/src/H5Rint.c b/src/H5Rint.c index b714f09..e1a5dcd 100644 --- a/src/H5Rint.c +++ b/src/H5Rint.c @@ -588,11 +588,18 @@ H5R__reopen_file(H5R_ref_priv_t *ref, hid_t fapl_id) supported = 0; if (H5VL_introspect_opt_query(vol_obj, H5VL_SUBCLS_FILE, H5VL_NATIVE_FILE_POST_OPEN, &supported) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "can't check for 'post open' operation") - if (supported & H5VL_OPT_QUERY_SUPPORTED) - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_POST_OPEN, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + if (supported & H5VL_OPT_QUERY_SUPPORTED) { + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_POST_OPEN; + vol_cb_args.args = NULL; + + /* Make the 'post open' callback */ + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, H5I_INVALID_HID, "unable to make file 'post open' callback") + } /* end if */ /* Attach loc_id to reference */ if (H5R__set_loc_id((H5R_ref_priv_t *)ref, ret_value, FALSE, TRUE) < 0) diff --git a/src/H5Rmodule.h b/src/H5Rmodule.h index 2a34d56..fe28bb2 100644 --- a/src/H5Rmodule.h +++ b/src/H5Rmodule.h @@ -27,9 +27,32 @@ /** * \defgroup H5R H5R - * \brief Reference Interface - * \details The HDF5 Reference Interface, H5R, provides a mechanism for managing - * HDF5 referenced objects. + * + * Use the functions in this module to manage HDF5 references. Referents can + * be HDF5 objects, attributes, and selections on datasets a.k.a. dataset + * regions. + * + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5R_examples.c create + * </td> + * <td> + * \snippet{lineno} H5R_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5R_examples.c update + * </td> + * <td> + * \snippet{lineno} H5R_examples.c delete + * </td> + * </tr> + * </table> + * */ #endif /* H5Rmodule_H */ diff --git a/src/H5Rpublic.h b/src/H5Rpublic.h index b33960e..ef798ea 100644 --- a/src/H5Rpublic.h +++ b/src/H5Rpublic.h @@ -30,9 +30,11 @@ #define H5R_OBJ_REF_BUF_SIZE sizeof(haddr_t) #define H5R_DSET_REG_REF_BUF_SIZE (sizeof(haddr_t) + 4) -/* Default reference buffer size. - * Note! Be careful with the sizes of the references because they should really - * depend on the run-time values in the file. +/** + * Default reference buffer size. + * + * \internal Note! Be careful with the sizes of the references because they + * should really depend on the run-time values in the file. */ #define H5R_REF_BUF_SIZE (64) @@ -560,6 +562,7 @@ H5_DLL ssize_t H5Rget_obj_name(H5R_ref_t *ref_ptr, hid_t rapl_id, char *name, si */ H5_DLL ssize_t H5Rget_attr_name(const H5R_ref_t *ref_ptr, char *name, size_t size); +/// \cond DEV /* API Wrappers for async routines */ /* (Must be defined _after_ the function prototype) */ /* (And must only defined when included in application code, not the library) */ @@ -574,6 +577,7 @@ H5_DLL ssize_t H5Rget_attr_name(const H5R_ref_t *ref_ptr, char *name, size_t siz #define H5Ropen_region_async_wrap H5_NO_EXPAND(H5Ropen_region_async) #define H5Ropen_attr_async_wrap H5_NO_EXPAND(H5Ropen_attr_async) #endif /* H5R_MODULE */ +/// \endcond /* Symbols defined for compatibility with previous versions of the HDF5 API. * diff --git a/src/H5SL.c b/src/H5SL.c index 166019b..ba9721c 100644 --- a/src/H5SL.c +++ b/src/H5SL.c @@ -209,7 +209,7 @@ /* Check if we need to increase allocation of forward pointers */ \ if (LVL + 1 >= 1u << X->log_nalloc) { \ H5SL_node_t **_tmp; \ - HDassert(LVL + 1 == 1u << X->log_nalloc); \ + HDassert(LVL + 1 == 1U << X->log_nalloc); \ /* Double the amount of allocated space */ \ X->log_nalloc++; \ \ @@ -251,7 +251,7 @@ /* Check if we can reduce the allocation of forward pointers */ \ if (LVL <= 1u << (X->log_nalloc - 1)) { \ H5SL_node_t **_tmp; \ - HDassert(LVL == 1u << (X->log_nalloc - 1)); \ + HDassert(LVL == 1U << (X->log_nalloc - 1)); \ X->log_nalloc--; \ \ /* Allocate space for new forward pointers */ \ diff --git a/src/H5SM.c b/src/H5SM.c index e8ce4b2..03fb08c 100644 --- a/src/H5SM.c +++ b/src/H5SM.c @@ -1079,7 +1079,7 @@ H5SM_try_share(H5F_t *f, H5O_t *open_oh, unsigned defer_flags, unsigned type_id, ssize_t index_num; htri_t tri_ret; #ifndef NDEBUG - unsigned deferred_type = -1u; + unsigned deferred_type = -1U; #endif htri_t ret_value = TRUE; diff --git a/src/H5Smodule.h b/src/H5Smodule.h index bb33eb8..010f4a6 100644 --- a/src/H5Smodule.h +++ b/src/H5Smodule.h @@ -30,29 +30,36 @@ #define H5_MY_PKG_INIT YES /**\defgroup H5S H5S - * \brief Dataspace Interface * - * \details The Dataspace Interface provides functions for creating and - * working with dataspaces. + * Use the functions in this module to manage HDF5 dataspaces \Emph{and} selections. * - * A dataspace has two roles: + * HDF5 dataspaces describe the \Emph{shape} of datasets in memory or in HDF5 + * files. Dataspaces can be empty (#H5S_NULL), a singleton (#H5S_SCALAR), or + * a multi-dimensional, regular grid (#H5S_SIMPLE). Dataspaces can be re-shaped. * - * \li It contains the spatial information (logical layout) of a - * dataset stored in a file. - * \li It describes an application’s data buffers and data elements - * participating in I/O. In other words, it can be used to - * select a portion or subset of a dataset. + * Subsets of dataspaces can be "book-marked" or used to restrict I/O operations + * using \Emph{selections}. Furthermore, certain set operations are supported + * for selections. * - * The spatial information of a dataset in a file includes the - * rank and dimensions of the dataset, which are a permanent part - * of the dataset definition. It can have dimensions that are fixed - * (unchanging) or unlimited, which means they can grow in size - * (or are extendible). - * - * A dataspace can consist of: - * \li no elements (NULL) - * \li a single element (scalar), or - * \li a simple array. + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5S_examples.c create + * </td> + * <td> + * \snippet{lineno} H5S_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5S_examples.c update + * </td> + * <td> + * \snippet{lineno} H5S_examples.c delete + * </td> + * </tr> + * </table> * */ diff --git a/src/H5Spublic.h b/src/H5Spublic.h index 7962035..30ca813 100644 --- a/src/H5Spublic.h +++ b/src/H5Spublic.h @@ -26,98 +26,101 @@ #define H5S_BLOCK 1 /* (hid_t) */ #define H5S_PLIST 2 /* (hid_t) */ -/* Define value for 'unlimited' dimensions */ -#define H5S_UNLIMITED HSIZE_UNDEF +#define H5S_UNLIMITED HSIZE_UNDEF /**< Value for 'unlimited' dimensions */ -/* Define user-level maximum number of dimensions */ +/** + * The maximum dataspace rank or number of dimensions + */ #define H5S_MAX_RANK 32 /* Flags for selection iterators */ #define H5S_SEL_ITER_GET_SEQ_LIST_SORTED \ - 0x0001 /* Retrieve elements from iterator \ - * in increasing offset order, for \ - * each call to retrieve sequences. \ - * Currently, this only applies to \ - * point selections, as hyperslab \ - * selections are always returned \ - * in increasing offset order. \ - * \ - * Note that the order is only \ - * increasing for each call to \ - * get_seq_list, the next set of \ - * sequences could start with an \ - * earlier offset than the previous \ - * one. \ + 0x0001 /**< Retrieve elements from iterator in increasing offset order, for \ + * each call to retrieve sequences. Currently, this only applies to \ + * point selections, as hyperslab selections are always returned in \ + * increasing offset order. Note that the order is only increasing \ + * for each call to H5Sget_seq_list(), the next set of sequences \ + * could start with an earlier offset than the previous one. \ */ #define H5S_SEL_ITER_SHARE_WITH_DATASPACE \ - 0x0002 /* Don't copy the dataspace \ - * selection when creating the \ - * selection iterator. \ - * \ - * This can improve performance \ - * of creating the iterator, but \ - * the dataspace _MUST_NOT_ be \ - * modified or closed until the \ - * selection iterator is closed \ - * or the iterator's behavior \ - * will be undefined. \ + 0x0002 /**< Don't copy the dataspace selection when creating the selection \ + * iterator. This can improve performance of creating the iterator, \ + * but the dataspace \Bold{MUST NOT} be modified or closed until the \ + * selection iterator is closed or the iterator's behavior will be \ + * undefined. \ */ -/* Different types of dataspaces */ +/** + * Types of dataspaces + */ typedef enum H5S_class_t { - H5S_NO_CLASS = -1, /*error */ - H5S_SCALAR = 0, /*scalar variable */ - H5S_SIMPLE = 1, /*simple dataspace */ - H5S_NULL = 2 /*null dataspace */ + H5S_NO_CLASS = -1, /**< Error */ + H5S_SCALAR = 0, /**< Singleton (scalar) */ + H5S_SIMPLE = 1, /**< Regular grid */ + H5S_NULL = 2 /**< Empty set */ } H5S_class_t; -/* Different ways of combining selections */ +/** + * Different ways of combining selections + */ typedef enum H5S_seloper_t { - H5S_SELECT_NOOP = -1, /* error */ - H5S_SELECT_SET = 0, /* Select "set" operation */ - H5S_SELECT_OR, /* Binary "or" operation for hyperslabs + H5S_SELECT_NOOP = -1, /**< Error */ + H5S_SELECT_SET = 0, /**< Select "set" operation */ + H5S_SELECT_OR, /**< Binary "or" operation for hyperslabs * (add new selection to existing selection) + * \code * Original region: AAAAAAAAAA * New region: BBBBBBBBBB * A or B: CCCCCCCCCCCCCCCC + * \endcode */ - H5S_SELECT_AND, /* Binary "and" operation for hyperslabs + H5S_SELECT_AND, /**< Binary "and" operation for hyperslabs * (only leave overlapped regions in selection) + * \code * Original region: AAAAAAAAAA * New region: BBBBBBBBBB * A and B: CCCC + * \endcode */ - H5S_SELECT_XOR, /* Binary "xor" operation for hyperslabs + H5S_SELECT_XOR, /**< Binary "xor" operation for hyperslabs * (only leave non-overlapped regions in selection) + * \code * Original region: AAAAAAAAAA * New region: BBBBBBBBBB * A xor B: CCCCCC CCCCCC + * \endcode */ - H5S_SELECT_NOTB, /* Binary "not" operation for hyperslabs + H5S_SELECT_NOTB, /**< Binary "not" operation for hyperslabs * (only leave non-overlapped regions in original selection) + * \code * Original region: AAAAAAAAAA * New region: BBBBBBBBBB * A not B: CCCCCC + * \endcode */ - H5S_SELECT_NOTA, /* Binary "not" operation for hyperslabs + H5S_SELECT_NOTA, /**< Binary "not" operation for hyperslabs * (only leave non-overlapped regions in new selection) + * \code * Original region: AAAAAAAAAA * New region: BBBBBBBBBB * B not A: CCCCCC + * \endcode */ - H5S_SELECT_APPEND, /* Append elements to end of point selection */ - H5S_SELECT_PREPEND, /* Prepend elements to beginning of point selection */ - H5S_SELECT_INVALID /* Invalid upper bound on selection operations */ + H5S_SELECT_APPEND, /**< Append elements to end of point selection */ + H5S_SELECT_PREPEND, /**< Prepend elements to beginning of point selection */ + H5S_SELECT_INVALID /**< Invalid upper bound on selection operations */ } H5S_seloper_t; -/* Enumerated type for the type of selection */ +/** + * Selection type + */ typedef enum { - H5S_SEL_ERROR = -1, /* Error */ - H5S_SEL_NONE = 0, /* Nothing selected */ - H5S_SEL_POINTS = 1, /* Points / elements selected */ - H5S_SEL_HYPERSLABS = 2, /* Hyperslab selected */ - H5S_SEL_ALL = 3, /* Entire extent selected */ - H5S_SEL_N /*THIS MUST BE LAST */ + H5S_SEL_ERROR = -1, /**< Error */ + H5S_SEL_NONE = 0, /**< Empty selection */ + H5S_SEL_POINTS = 1, /**< Set of points */ + H5S_SEL_HYPERSLABS = 2, /**< Hyperslab */ + H5S_SEL_ALL = 3, /**< Everything */ + H5S_SEL_N /**< Sentinel \internal THIS MUST BE LAST */ } H5S_sel_type; #ifdef __cplusplus @@ -1318,9 +1321,6 @@ H5_DLL herr_t H5Sset_extent_none(hid_t space_id); * \details H5Sset_extent_simple() sets or resets the size of an existing * dataspace. * - * \p rank is the dimensionality, or number of dimensions, of the - * dataspace. - * * \p dims is an array of size \p rank which contains the new size * of each dimension in the dataspace. \p max is an array of size * \p rank which contains the maximum size of each dimension in @@ -1329,10 +1329,6 @@ H5_DLL herr_t H5Sset_extent_none(hid_t space_id); * Any previous extent is removed from the dataspace, the dataspace * type is set to #H5S_SIMPLE, and the extent is set as specified. * - * Note that a dataset must be chunked if \p dims does not equal - * \p max. - * - * * \version 1.4.0 Fortran subroutine was introduced. * \since 1.0.0 * diff --git a/src/H5T.c b/src/H5T.c index b6bfb9a..19a3d39 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -290,7 +290,7 @@ #define H5T_INIT_TYPE_SET_SIZE(SIZE) \ { \ dt->shared->size = SIZE; \ - dt->shared->u.atomic.prec = 8 * SIZE; \ + dt->shared->u.atomic.prec = 8 * (SIZE); \ } #define H5T_INIT_TYPE_NOSET_SIZE(SIZE) \ @@ -327,7 +327,7 @@ H5_GLUE3(H5T_INIT_TYPE_, GUTS, _CORE) \ \ /* Register result */ \ - if ((GLOBAL = H5I_register(H5I_DATATYPE, dt, FALSE)) < 0) \ + if (((GLOBAL) = H5I_register(H5I_DATATYPE, dt, FALSE)) < 0) \ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register datatype atom") \ } @@ -560,8 +560,8 @@ size_t H5T_NATIVE_UINT_FAST64_ALIGN_g = 0; /* Useful floating-point values for conversion routines */ /* (+/- Inf for all floating-point types) */ -float H5T_NATIVE_FLOAT_POS_INF_g = 0.0f; -float H5T_NATIVE_FLOAT_NEG_INF_g = 0.0f; +float H5T_NATIVE_FLOAT_POS_INF_g = 0.0F; +float H5T_NATIVE_FLOAT_NEG_INF_g = 0.0F; double H5T_NATIVE_DOUBLE_POS_INF_g = 0.0; double H5T_NATIVE_DOUBLE_NEG_INF_g = 0.0; @@ -1892,19 +1892,24 @@ H5Tcopy(hid_t obj_id) break; case H5I_DATASET: { - H5VL_object_t *vol_obj = NULL; /* Dataset structure */ + H5VL_object_t * vol_obj; /* Object for obj_id */ + H5VL_dataset_get_args_t vol_cb_args; /* Arguments to VOL callback */ /* The argument is a dataset handle */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(obj_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "type_id is not a dataset ID") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_GET_TYPE; + vol_cb_args.args.get_type.type_id = H5I_INVALID_HID; + /* Get the datatype from the dataset * NOTE: This will have to be closed after we're done with it. */ - if (H5VL_dataset_get(vol_obj, H5VL_DATASET_GET_TYPE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &dset_tid) < 0) + if (H5VL_dataset_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, H5I_INVALID_HID, "unable to get datatype from the dataset") + dset_tid = vol_cb_args.args.get_type.type_id; /* Unwrap the type ID */ if (NULL == (dt = (H5T_t *)H5I_object(dset_tid))) diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c index 91801c6..d079e71 100644 --- a/src/H5Tcommit.c +++ b/src/H5Tcommit.c @@ -790,12 +790,19 @@ H5Tget_create_plist(hid_t dtype_id) } /* end if */ /* If the datatype is committed, retrieve further information */ else { - H5VL_object_t *vol_obj = type->vol_obj; + H5VL_object_t * vol_obj = type->vol_obj; + H5VL_datatype_get_args_t vol_cb_args; /* Arguments to VOL callback */ + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATATYPE_GET_TCPL; + vol_cb_args.args.get_tcpl.tcpl_id = H5I_INVALID_HID; /* Get the property list through the VOL */ - if (H5VL_datatype_get(vol_obj, H5VL_DATATYPE_GET_TCPL, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &ret_value) < 0) + if (H5VL_datatype_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, H5I_INVALID_HID, "can't get object creation info") + + /* Set return value */ + ret_value = vol_cb_args.args.get_tcpl.tcpl_id; } /* end else */ done: @@ -829,15 +836,21 @@ H5Tflush(hid_t type_id) if (!H5T_is_named(dt)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a committed datatype") - /* Set up collective metadata if appropriate */ - if (H5CX_set_loc(type_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set access property list info") - /* Flush metadata for named datatype */ - if (dt->vol_obj) - if (H5VL_datatype_specific(dt->vol_obj, H5VL_DATATYPE_FLUSH, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, type_id) < 0) + if (dt->vol_obj) { + H5VL_datatype_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + + /* Set up collective metadata if appropriate */ + if (H5CX_set_loc(type_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set access property list info") + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATATYPE_FLUSH; + vol_cb_args.args.flush.type_id = type_id; + + if (H5VL_datatype_specific(dt->vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFLUSH, FAIL, "unable to flush datatype") + } done: FUNC_LEAVE_API(ret_value) @@ -870,15 +883,21 @@ H5Trefresh(hid_t type_id) if (!H5T_is_named(dt)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a committed datatype") - /* Set up collective metadata if appropriate */ - if (H5CX_set_loc(type_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set access property list info") - /* Refresh the datatype's metadata */ - if (dt->vol_obj) - if (H5VL_datatype_specific(dt->vol_obj, H5VL_DATATYPE_REFRESH, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, type_id) < 0) + if (dt->vol_obj) { + H5VL_datatype_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + + /* Set up collective metadata if appropriate */ + if (H5CX_set_loc(type_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set access property list info") + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATATYPE_REFRESH; + vol_cb_args.args.refresh.type_id = type_id; + + if (H5VL_datatype_specific(dt->vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTLOAD, FAIL, "unable to refresh datatype") + } done: FUNC_LEAVE_API(ret_value) @@ -1222,32 +1241,41 @@ H5T_update_shared(H5T_t *dt) H5T_t * H5T_construct_datatype(H5VL_object_t *vol_obj) { - ssize_t nalloc; - void * buf = NULL; - H5T_t * dt = NULL; /* datatype object from VOL connector */ - H5T_t * ret_value = NULL; + H5T_t * dt = NULL; /* Datatype object from VOL connector */ + H5VL_datatype_get_args_t vol_cb_args; /* Arguments to VOL callback */ + size_t nalloc = 0; /* Size required to store serialized form of datatype */ + void * buf = NULL; /* Buffer to store serialized datatype */ + H5T_t * ret_value = NULL; FUNC_ENTER_NOAPI(NULL) - /* get required buf size for encoding the datatype */ - if (H5VL_datatype_get(vol_obj, H5VL_DATATYPE_GET_BINARY, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &nalloc, NULL, 0) < 0) + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATATYPE_GET_BINARY_SIZE; + vol_cb_args.args.get_binary_size.size = &nalloc; + + /* Get required buf size for encoding the datatype */ + if (H5VL_datatype_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to get datatype serialized size") - /* allocate buffer to store binary description of the datatype */ - if (NULL == (buf = (void *)H5MM_calloc((size_t)nalloc))) + /* Allocate buffer to store binary description of the datatype */ + if (NULL == (buf = (void *)H5MM_calloc(nalloc))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate space for datatype") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATATYPE_GET_BINARY; + vol_cb_args.args.get_binary.buf = buf; + vol_cb_args.args.get_binary.buf_size = nalloc; + /* get binary description of the datatype */ - if (H5VL_datatype_get(vol_obj, H5VL_DATATYPE_GET_BINARY, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &nalloc, buf, (size_t)nalloc) < 0) + if (H5VL_datatype_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to get serialized datatype") - if (NULL == (dt = H5T_decode((size_t)nalloc, (const unsigned char *)buf))) + /* Construct datatype, from serialized form in buffer */ + if (NULL == (dt = H5T_decode(nalloc, buf))) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "can't decode datatype") - dt->vol_obj = vol_obj; + /* Set return value */ ret_value = dt; done: @@ -1407,3 +1435,34 @@ H5T_already_vol_managed(const H5T_t *dt) FUNC_LEAVE_NOAPI(dt->vol_obj != NULL) } /* end H5T_already_vol_managed() */ + +/*------------------------------------------------------------------------- + * Function: H5T_invoke_vol_optional + * + * Purpose: Invokes an optional VOL connector-specific operation on a named datatype + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_invoke_vol_optional(H5T_t *dt, H5VL_optional_args_t *args, hid_t dxpl_id, void **req, + H5VL_object_t **vol_obj_ptr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check that datatype is committed */ + if (!H5T_is_named(dt)) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a committed datatype") + + /* Only invoke callback if VOL object is set for the datatype */ + if (dt->vol_obj) + if (H5VL_datatype_optional_op(dt->vol_obj, args, dxpl_id, req, vol_obj_ptr) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPERATE, FAIL, "unable to execute datatype optional callback") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T_invoke_vol_optional() */ diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 0c98633..18cbcf1 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -7725,9 +7725,9 @@ herr_t H5T__conv_float_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(FLOAT, SCHAR, float, signed char, SCHAR_MIN, SCHAR_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7747,9 +7747,9 @@ herr_t H5T__conv_float_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(FLOAT, UCHAR, float, unsigned char, 0, UCHAR_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7769,9 +7769,9 @@ herr_t H5T__conv_double_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(DOUBLE, SCHAR, double, signed char, SCHAR_MIN, SCHAR_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7791,9 +7791,9 @@ herr_t H5T__conv_double_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(DOUBLE, UCHAR, double, unsigned char, 0, UCHAR_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7813,9 +7813,9 @@ herr_t H5T__conv_ldouble_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(LDOUBLE, SCHAR, long double, signed char, SCHAR_MIN, SCHAR_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7835,9 +7835,9 @@ herr_t H5T__conv_ldouble_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(LDOUBLE, UCHAR, long double, unsigned char, 0, UCHAR_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7857,9 +7857,9 @@ herr_t H5T__conv_float_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(FLOAT, SHORT, float, short, SHRT_MIN, SHRT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7879,9 +7879,9 @@ herr_t H5T__conv_float_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(FLOAT, USHORT, float, unsigned short, 0, USHRT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7901,9 +7901,9 @@ herr_t H5T__conv_double_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(DOUBLE, SHORT, double, short, SHRT_MIN, SHRT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7923,9 +7923,9 @@ herr_t H5T__conv_double_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(DOUBLE, USHORT, double, unsigned short, 0, USHRT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7945,9 +7945,9 @@ herr_t H5T__conv_ldouble_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(LDOUBLE, SHORT, long double, short, SHRT_MIN, SHRT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7967,9 +7967,9 @@ herr_t H5T__conv_ldouble_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(LDOUBLE, USHORT, long double, unsigned short, 0, USHRT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7989,9 +7989,9 @@ herr_t H5T__conv_float_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(FLOAT, INT, float, int, INT_MIN, INT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8011,9 +8011,9 @@ herr_t H5T__conv_float_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(FLOAT, UINT, float, unsigned int, 0, UINT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8033,9 +8033,9 @@ herr_t H5T__conv_double_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(DOUBLE, INT, double, int, INT_MIN, INT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8055,9 +8055,9 @@ herr_t H5T__conv_double_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(DOUBLE, UINT, double, unsigned int, 0, UINT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8077,9 +8077,9 @@ herr_t H5T__conv_ldouble_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(LDOUBLE, INT, long double, int, INT_MIN, INT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8099,9 +8099,9 @@ herr_t H5T__conv_ldouble_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(LDOUBLE, UINT, long double, unsigned int, 0, UINT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8121,9 +8121,9 @@ herr_t H5T__conv_float_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(FLOAT, LONG, float, long, LONG_MIN, LONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8143,9 +8143,9 @@ herr_t H5T__conv_float_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(FLOAT, ULONG, float, unsigned long, 0, ULONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8165,9 +8165,9 @@ herr_t H5T__conv_double_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(DOUBLE, LONG, double, long, LONG_MIN, LONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8187,9 +8187,9 @@ herr_t H5T__conv_double_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(DOUBLE, ULONG, double, unsigned long, 0, ULONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8209,9 +8209,9 @@ herr_t H5T__conv_ldouble_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(LDOUBLE, LONG, long double, long, LONG_MIN, LONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8231,9 +8231,9 @@ herr_t H5T__conv_ldouble_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(LDOUBLE, ULONG, long double, unsigned long, 0, ULONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8253,9 +8253,9 @@ herr_t H5T__conv_float_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(FLOAT, LLONG, float, long long, LLONG_MIN, LLONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8275,9 +8275,9 @@ herr_t H5T__conv_float_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(FLOAT, ULLONG, float, unsigned long long, 0, ULLONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8297,9 +8297,9 @@ herr_t H5T__conv_double_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(DOUBLE, LLONG, double, long long, LLONG_MIN, LLONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8319,9 +8319,9 @@ herr_t H5T__conv_double_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(DOUBLE, ULLONG, double, unsigned long long, 0, ULLONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8342,9 +8342,9 @@ herr_t H5T__conv_ldouble_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(LDOUBLE, LLONG, long double, long long, LLONG_MIN, LLONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } #endif /*H5T_CONV_INTERNAL_LDOUBLE_LLONG*/ @@ -8366,9 +8366,9 @@ herr_t H5T__conv_ldouble_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(LDOUBLE, ULLONG, long double, unsigned long long, 0, ULLONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } #endif /*H5T_CONV_INTERNAL_LDOUBLE_ULLONG*/ diff --git a/src/H5Tmodule.h b/src/H5Tmodule.h index c489edc..73424fb 100644 --- a/src/H5Tmodule.h +++ b/src/H5Tmodule.h @@ -29,10 +29,38 @@ #define H5_MY_PKG_ERR H5E_DATATYPE #define H5_MY_PKG_INIT YES -/** - * \defgroup H5T H5T - * \brief Datatype Interface - * \todo Describe concisely what the functions in this module are about. +/**\defgroup H5T H5T + * + * Use the functions in this module to manage HDF5 datatypes. + * + * HDF5 datatypes describe the element type of HDF5 datasets and attributes. + * There's a large set of predefined datatypes, but users may find it useful + * to define new datatypes through a process called \Emph{derivation}. + * + * The element type is automatically persisted as part of the HDF5 metadata of + * attributes and datasets. Additionally, datatype definitions can be persisted + * to HDF5 files and linked to groups as HDF5 datatype objects or so-called + * \Emph{committed datatypes}. + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5T_examples.c create + * </td> + * <td> + * \snippet{lineno} H5T_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5T_examples.c update + * </td> + * <td> + * \snippet{lineno} H5T_examples.c delete + * </td> + * </tr> + * </table> * * \defgroup ARRAY Array Datatypes * \ingroup H5T diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index 2a45e17..6624096 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -59,10 +59,7 @@ typedef struct H5T_path_t H5T_path_t; struct H5S_t; /* How to copy a datatype */ -typedef enum H5T_copy_t { - H5T_COPY_TRANSIENT, - H5T_COPY_ALL, -} H5T_copy_t; +typedef enum H5T_copy_t { H5T_COPY_TRANSIENT, H5T_COPY_ALL } H5T_copy_t; /* Location of datatype information */ typedef enum { @@ -155,6 +152,8 @@ H5_DLL herr_t H5T_save_refresh_state(hid_t tid, struct H5O_shared_t *cached_H5O H5_DLL herr_t H5T_restore_refresh_state(hid_t tid, struct H5O_shared_t *cached_H5O_shared); H5_DLL hbool_t H5T_already_vol_managed(const H5T_t *dt); H5_DLL htri_t H5T_is_vl_storage(const H5T_t *dt); +H5_DLL herr_t H5T_invoke_vol_optional(H5T_t *dt, H5VL_optional_args_t *args, hid_t dxpl_id, void **req, + H5VL_object_t **vol_obj_ptr); /* Reference specific functions */ H5_DLL H5R_type_t H5T_get_ref_type(const H5T_t *dt); diff --git a/src/H5Tref.c b/src/H5Tref.c index 1114c25..cac8cf6 100644 --- a/src/H5Tref.c +++ b/src/H5Tref.c @@ -289,12 +289,16 @@ H5T__ref_set_loc(H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc) } /* end else-if */ else { H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ size_t ref_encode_size; H5R_ref_priv_t fixed_ref; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_CONT_INFO; + vol_cb_args.args.get_cont_info.info = &cont_info; + /* Get container info */ - if (H5VL_file_get(file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &cont_info) < 0) + if (H5VL_file_get(file, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to get container info") /* Retrieve min encode size (when references have no vlen part) */ @@ -434,8 +438,10 @@ H5T__ref_mem_getsize(H5VL_object_t H5_ATTR_UNUSED *src_file, const void *src_buf /* Force re-calculating encoding size if any flags are set */ if (flags || !src_ref->encode_size) { - char file_name_buf_static[256]; /* File name */ - ssize_t file_name_len; /* Size of file name buffer */ + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ + char * file_name = NULL; /* Actual file name */ + char file_name_buf_static[256]; /* File name */ + size_t file_name_len = 0; /* Length of file name */ /* Pass the correct encoding version for the selection depending on the * file libver bounds, this is later retrieved in H5S hyper encode */ @@ -458,21 +464,38 @@ H5T__ref_mem_getsize(H5VL_object_t H5_ATTR_UNUSED *src_file, const void *src_buf H5CX_set_libver_bounds(NULL); } /* end if */ + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_NAME; + vol_cb_args.args.get_name.type = H5I_FILE; + vol_cb_args.args.get_name.buf_size = sizeof(file_name_buf_static); + vol_cb_args.args.get_name.buf = file_name_buf_static; + vol_cb_args.args.get_name.file_name_len = &file_name_len; + /* Get file name */ - if (H5VL_file_get(vol_obj, H5VL_FILE_GET_NAME, H5P_DATASET_XFER_DEFAULT, NULL, H5I_FILE, - sizeof(file_name_buf_static), file_name_buf_static, &file_name_len) < 0) + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, 0, "can't get file name") - if (file_name_len >= (ssize_t)sizeof(file_name_buf_static)) { - if (NULL == (file_name_buf_dyn = (char *)H5MM_malloc((size_t)file_name_len + 1))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, 0, "can't allocate space for file name") - if (H5VL_file_get(vol_obj, H5VL_FILE_GET_NAME, H5P_DATASET_XFER_DEFAULT, NULL, H5I_FILE, - (size_t)file_name_len + 1, file_name_buf_dyn, &file_name_len) < 0) + + /* Check if we need to allocate a buffer for the file name */ + if (file_name_len >= sizeof(file_name_buf_static)) { + /* Allocate file name buffer */ + if (NULL == (file_name_buf_dyn = H5MM_malloc(file_name_len + 1))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, 0, "can't allocate space for file name") + + /* Update VOL callback arguments */ + vol_cb_args.args.get_name.buf_size = file_name_len + 1; + vol_cb_args.args.get_name.buf = file_name_buf_dyn; + + /* Get file name again */ + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, 0, "can't get file name") + + file_name = file_name_buf_dyn; } /* end if */ + else + file_name = file_name_buf_static; /* Determine encoding size */ - if (H5R__encode(file_name_buf_dyn ? file_name_buf_dyn : file_name_buf_static, src_ref, NULL, - &ret_value, flags) < 0) + if (H5R__encode(file_name, src_ref, NULL, &ret_value, flags) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, 0, "unable to determine encoding size") } /* end if */ else { @@ -506,10 +529,10 @@ H5T__ref_mem_read(H5VL_object_t H5_ATTR_UNUSED *src_file, const void *src_buf, s H5VL_object_t * vol_obj; /* VOL object for src ref's location */ const H5R_ref_priv_t *src_ref = (const H5R_ref_priv_t *)src_buf; hbool_t files_equal = TRUE; /* Whether src & dst references are in same file */ + char * file_name = NULL; /* Actual file name */ char file_name_buf_static[256] = {'\0'}; /* File name */ char * file_name_buf_dyn = NULL; /* Pointer to dynamically allocated buffer for file name, if static buffer is too small */ - ssize_t file_name_len; /* Size of file name buffer */ unsigned flags = 0; /* References flags */ herr_t ret_value = SUCCEED; /* Return value */ @@ -560,21 +583,42 @@ H5T__ref_mem_read(H5VL_object_t H5_ATTR_UNUSED *src_file, const void *src_buf, s /* Get file name (if external reference) */ if (flags) { - if (H5VL_file_get(vol_obj, H5VL_FILE_GET_NAME, H5P_DATASET_XFER_DEFAULT, NULL, H5I_FILE, - sizeof(file_name_buf_static), file_name_buf_static, &file_name_len) < 0) + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ + size_t file_name_len = 0; /* Length of file name */ + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_NAME; + vol_cb_args.args.get_name.type = H5I_FILE; + vol_cb_args.args.get_name.buf_size = sizeof(file_name_buf_static); + vol_cb_args.args.get_name.buf = file_name_buf_static; + vol_cb_args.args.get_name.file_name_len = &file_name_len; + + /* Get file name */ + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, 0, "can't get file name") - if (file_name_len >= (ssize_t)sizeof(file_name_buf_static)) { - if (NULL == (file_name_buf_dyn = (char *)H5MM_malloc((size_t)file_name_len + 1))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, 0, "can't allocate space for file name") - if (H5VL_file_get(vol_obj, H5VL_FILE_GET_NAME, H5P_DATASET_XFER_DEFAULT, NULL, H5I_FILE, - (size_t)file_name_len + 1, file_name_buf_dyn, &file_name_len) < 0) + + /* Check if we need to allocate a buffer for the file name */ + if (file_name_len >= sizeof(file_name_buf_static)) { + /* Allocate file name buffer */ + if (NULL == (file_name_buf_dyn = H5MM_malloc(file_name_len + 1))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, 0, "can't allocate space for file name") + + /* Update VOL callback arguments */ + vol_cb_args.args.get_name.buf_size = file_name_len + 1; + vol_cb_args.args.get_name.buf = file_name_buf_dyn; + + /* Get file name again */ + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, 0, "can't get file name") + + file_name = file_name_buf_dyn; } /* end if */ - } /* end if */ + else + file_name = file_name_buf_static; + } /* end if */ /* Encode reference */ - if (H5R__encode(file_name_buf_dyn ? file_name_buf_dyn : file_name_buf_static, src_ref, - (unsigned char *)dst_buf, &dst_size, flags) < 0) + if (H5R__encode(file_name, src_ref, (unsigned char *)dst_buf, &dst_size, flags) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "Cannot encode reference") done: @@ -731,11 +775,17 @@ H5T__ref_disk_isnull(const H5VL_object_t *src_file, const void *src_buf, hbool_t *isnull = FALSE; } else { + H5VL_blob_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + /* Skip the size / header */ p = (const uint8_t *)src_buf + H5R_ENCODE_HEADER_SIZE + H5_SIZEOF_UINT32_T; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_BLOB_ISNULL; + vol_cb_args.args.is_null.isnull = isnull; + /* Check if blob ID is "nil" */ - if (H5VL_blob_specific(src_file, (void *)p, H5VL_BLOB_ISNULL, isnull) < 0) + if (H5VL_blob_specific(src_file, (void *)p, &vol_cb_args) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to check if a blob ID is 'nil'") } @@ -755,9 +805,10 @@ done: static herr_t H5T__ref_disk_setnull(H5VL_object_t *dst_file, void *dst_buf, void *bg_buf) { - uint8_t *q = (uint8_t *)dst_buf; - uint8_t *p_bg = (uint8_t *)bg_buf; - herr_t ret_value = SUCCEED; + H5VL_blob_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + uint8_t * q = (uint8_t *)dst_buf; + uint8_t * p_bg = (uint8_t *)bg_buf; + herr_t ret_value = SUCCEED; FUNC_ENTER_STATIC H5T_REF_LOG_DEBUG(""); @@ -770,8 +821,11 @@ H5T__ref_disk_setnull(H5VL_object_t *dst_file, void *dst_buf, void *bg_buf) /* Skip the size / header */ p_bg += (H5_SIZEOF_UINT32_T + H5R_ENCODE_HEADER_SIZE); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_BLOB_DELETE; + /* Remove blob for old data */ - if (H5VL_blob_specific(dst_file, (void *)p_bg, H5VL_BLOB_DELETE) < 0) + if (H5VL_blob_specific(dst_file, (void *)p_bg, &vol_cb_args) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to delete blob") } /* end if */ @@ -782,8 +836,11 @@ H5T__ref_disk_setnull(H5VL_object_t *dst_file, void *dst_buf, void *bg_buf) /* Set the size */ UINT32ENCODE(q, 0); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_BLOB_SETNULL; + /* Set blob ID to "nil" */ - if (H5VL_blob_specific(dst_file, q, H5VL_BLOB_SETNULL) < 0) + if (H5VL_blob_specific(dst_file, q, &vol_cb_args) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "unable to set a blob ID to 'nil'") done: @@ -913,15 +970,19 @@ H5T__ref_disk_write(H5VL_object_t H5_ATTR_UNUSED *src_file, const void *src_buf, /* TODO Should get rid of bg stuff */ if (p_bg) { - size_t p_buf_size_left = dst_size; + H5VL_blob_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + size_t p_buf_size_left = dst_size; /* Skip the size / header */ p_bg += (H5_SIZEOF_UINT32_T + H5R_ENCODE_HEADER_SIZE); HDassert(p_buf_size_left > (H5_SIZEOF_UINT32_T + H5R_ENCODE_HEADER_SIZE)); p_buf_size_left -= (H5_SIZEOF_UINT32_T + H5R_ENCODE_HEADER_SIZE); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_BLOB_DELETE; + /* Remove blob for old data */ - if (H5VL_blob_specific(dst_file, (void *)p_bg, H5VL_BLOB_DELETE) < 0) + if (H5VL_blob_specific(dst_file, (void *)p_bg, &vol_cb_args) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to delete blob") } /* end if */ diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c index 39d14f3..080d725 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -247,8 +247,7 @@ done: htri_t H5T__vlen_set_loc(H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc) { - H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; - htri_t ret_value = FALSE; /* Indicate success, but no location change */ + htri_t ret_value = FALSE; /* Indicate success, but no location change */ FUNC_ENTER_PACKAGE @@ -293,15 +292,22 @@ H5T__vlen_set_loc(H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc) dt->shared->u.vlen.file = NULL; break; - case H5T_LOC_DISK: /* Disk based VL datatype */ + /* Disk based VL datatype */ + case H5T_LOC_DISK: { + H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ + HDassert(file); /* Mark this type as being stored on disk */ dt->shared->u.vlen.loc = H5T_LOC_DISK; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_CONT_INFO; + vol_cb_args.args.get_cont_info.info = &cont_info; + /* Get container info */ - if (H5VL_file_get(file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &cont_info) < 0) + if (H5VL_file_get(file, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to get container info") /* The datatype size is equal to 4 bytes for the sequence length @@ -319,6 +325,7 @@ H5T__vlen_set_loc(H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc) if (H5T_own_vol_obj(dt, file) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "can't give ownership of VOL object") break; + } case H5T_LOC_BADLOC: /* Allow undefined location. In H5Odtype.c, H5O_dtype_decode sets undefined @@ -841,8 +848,9 @@ H5T__vlen_disk_getlen(H5VL_object_t H5_ATTR_UNUSED *file, const void *_vl, size_ static herr_t H5T__vlen_disk_isnull(const H5VL_object_t *file, void *_vl, hbool_t *isnull) { - uint8_t *vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_blob_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + uint8_t * vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -854,8 +862,12 @@ H5T__vlen_disk_isnull(const H5VL_object_t *file, void *_vl, hbool_t *isnull) /* Skip the sequence's length */ vl += 4; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_BLOB_ISNULL; + vol_cb_args.args.is_null.isnull = isnull; + /* Check if blob ID is "nil" */ - if (H5VL_blob_specific(file, vl, H5VL_BLOB_ISNULL, isnull) < 0) + if (H5VL_blob_specific(file, vl, &vol_cb_args) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to check if a blob ID is 'nil'") done: @@ -877,8 +889,9 @@ done: static herr_t H5T__vlen_disk_setnull(H5VL_object_t *file, void *_vl, void *bg) { - uint8_t *vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_blob_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + uint8_t * vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -895,8 +908,11 @@ H5T__vlen_disk_setnull(H5VL_object_t *file, void *_vl, void *bg) /* Set the length of the sequence */ UINT32ENCODE(vl, 0); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_BLOB_SETNULL; + /* Set blob ID to "nil" */ - if (H5VL_blob_specific(file, vl, H5VL_BLOB_SETNULL) < 0) + if (H5VL_blob_specific(file, vl, &vol_cb_args) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "unable to set a blob ID to 'nil'") done: @@ -1013,10 +1029,16 @@ H5T__vlen_disk_delete(H5VL_object_t *file, const void *_vl) UINT32DECODE(vl, seq_len); /* Delete object, if length > 0 */ - if (seq_len > 0) - if (H5VL_blob_specific(file, (void *)vl, H5VL_BLOB_DELETE) < 0) /* Casting away 'const' OK -QAK */ + if (seq_len > 0) { + H5VL_blob_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_BLOB_DELETE; + + if (H5VL_blob_specific(file, (void *)vl, &vol_cb_args) < 0) /* Casting away 'const' OK -QAK */ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to delete blob") - } /* end if */ + } /* end if */ + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5VL.c b/src/H5VL.c index a77a6f3..2cece6d 100644 --- a/src/H5VL.c +++ b/src/H5VL.c @@ -764,6 +764,39 @@ done: } /* H5VLretrieve_lib_state() */ /*--------------------------------------------------------------------------- + * Function: H5VLstart_lib_state + * + * Purpose: Opens a new internal state for the HDF5 library. + * + * Note: This routine is _only_ for HDF5 VOL connector authors! It is + * _not_ part of the public API for HDF5 application developers. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Friday, February 5, 2021 + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VLstart_lib_state(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + /* Must use this, to avoid modifying the API context stack in FUNC_ENTER */ + FUNC_ENTER_API_NOINIT + H5TRACE0("e", ""); + + /* Start a new library state */ + if (H5VL_start_lib_state() < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't start new library state") + +done: + FUNC_LEAVE_API_NOINIT(ret_value) +} /* H5VLstart_lib_state() */ + +/*--------------------------------------------------------------------------- * Function: H5VLrestore_lib_state * * Purpose: Restores the internal state of the HDF5 library. @@ -801,16 +834,16 @@ done: } /* H5VLrestore_lib_state() */ /*--------------------------------------------------------------------------- - * Function: H5VLreset_lib_state + * Function: H5VLfinish_lib_state * - * Purpose: Resets the internal state of the HDF5 library, undoing the - * affects of H5VLrestore_lib_state. + * Purpose: Closes the internal state of the HDF5 library, undoing the + * affects of H5VLstart_lib_state. * * Note: This routine is _only_ for HDF5 VOL connector authors! It is * _not_ part of the public API for HDF5 application developers. * * Note: This routine must be called as a "pair" with - * H5VLrestore_lib_state. It can be called before / after / + * H5VLstart_lib_state. It can be called before / after / * independently of H5VLfree_lib_state. * * Return: Success: Non-negative @@ -822,7 +855,7 @@ done: *--------------------------------------------------------------------------- */ herr_t -H5VLreset_lib_state(void) +H5VLfinish_lib_state(void) { herr_t ret_value = SUCCEED; /* Return value */ @@ -831,12 +864,12 @@ H5VLreset_lib_state(void) H5TRACE0("e", ""); /* Reset the library state */ - if (H5VL_reset_lib_state() < 0) + if (H5VL_finish_lib_state() < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset library state") done: FUNC_LEAVE_API_NOINIT(ret_value) -} /* H5VLreset_lib_state() */ +} /* H5VLfinish_lib_state() */ /*--------------------------------------------------------------------------- * Function: H5VLfree_lib_state @@ -911,3 +944,136 @@ H5VLquery_optional(hid_t obj_id, H5VL_subclass_t subcls, int opt_type, uint64_t done: FUNC_LEAVE_API(ret_value) } /* H5VLquery_optional() */ + +/*--------------------------------------------------------------------------- + * Function: H5VLregister_opt_operation + * + * Purpose: Allow a VOL connector to register a new optional operation + * for a VOL object subclass. The operation name must be runtime + * unique for each operation, preferably avoiding naming clashes + * by using a Uniform Type Identifier (UTI, + *https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/understanding_utis/understand_utis_conc/understand_utis_conc.html) + * for each operation name. The value returned in the 'op_val' + * pointer will be unique for that VOL connector to use for its + * operation on that subclass. + * + * For example, registering a 'prefetch' operation for the + * caching VOL connector written at the ALCF at Argonne National + * Laboratory could have a UTI of: "gov.anl.alcf.cache.prefetch", + * and the "evict" operation for the same connector could have a + * UTI of: "gov.anl.alcf.cache.evict". Registering a "suspend + * background threads" operation for the asynchronous VOL connector + * written at NERSC at Lawrence Berkeley National Laboratory could + * have a UTI of: "gov.lbnl.nersc.async.suspend_bkg_threads". + * + * Note: The first 1024 values of each subclass's optional operations + * are reserved for the native VOL connector's use. + * + * Return: Success: Non-negative + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VLregister_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val /*out*/) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "VS*sx", subcls, op_name, op_val); + + /* Check args */ + if (NULL == op_val) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_val pointer") + if (NULL == op_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name pointer") + if ('\0' == *op_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name string") + if (!((H5VL_SUBCLS_ATTR == subcls) || (H5VL_SUBCLS_DATASET == subcls) || + (H5VL_SUBCLS_DATATYPE == subcls) || (H5VL_SUBCLS_FILE == subcls) || (H5VL_SUBCLS_GROUP == subcls) || + (H5VL_SUBCLS_OBJECT == subcls) || (H5VL_SUBCLS_LINK == subcls) || (H5VL_SUBCLS_REQUEST == subcls))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid VOL subclass type") + + /* Register the operation */ + if (H5VL__register_opt_operation(subcls, op_name, op_val) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, FAIL, "can't register dynamic optional operation: '%s'", + op_name) + +done: + FUNC_LEAVE_API(ret_value) +} /* H5VLregister_opt_operation() */ + +/*--------------------------------------------------------------------------- + * Function: H5VLfind_opt_operation + * + * Purpose: Look up a optional operation for a VOL object subclass, by name. + * + * Return: Success: Non-negative + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VLfind_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val /*out*/) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "VS*sx", subcls, op_name, op_val); + + /* Check args */ + if (NULL == op_val) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_val pointer") + if (NULL == op_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name pointer") + if ('\0' == *op_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name string") + if (!((H5VL_SUBCLS_ATTR == subcls) || (H5VL_SUBCLS_DATASET == subcls) || + (H5VL_SUBCLS_DATATYPE == subcls) || (H5VL_SUBCLS_FILE == subcls) || (H5VL_SUBCLS_GROUP == subcls) || + (H5VL_SUBCLS_OBJECT == subcls) || (H5VL_SUBCLS_LINK == subcls) || (H5VL_SUBCLS_REQUEST == subcls))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid VOL subclass type") + + /* Find the operation */ + if (H5VL__find_opt_operation(subcls, op_name, op_val) < 0) + HGOTO_ERROR(H5E_VOL, H5E_NOTFOUND, FAIL, "can't find dynamic optional operation: '%s'", op_name) + +done: + FUNC_LEAVE_API(ret_value) +} /* H5VLfind_opt_operation() */ + +/*--------------------------------------------------------------------------- + * Function: H5VLunregister_opt_operation + * + * Purpose: Unregister a optional operation for a VOL object subclass, by name. + * + * Return: Success: Non-negative + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VLunregister_opt_operation(H5VL_subclass_t subcls, const char *op_name) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "VS*s", subcls, op_name); + + /* Check args */ + if (NULL == op_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name pointer") + if ('\0' == *op_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name string") + if (!((H5VL_SUBCLS_ATTR == subcls) || (H5VL_SUBCLS_DATASET == subcls) || + (H5VL_SUBCLS_DATATYPE == subcls) || (H5VL_SUBCLS_FILE == subcls) || (H5VL_SUBCLS_GROUP == subcls) || + (H5VL_SUBCLS_OBJECT == subcls) || (H5VL_SUBCLS_LINK == subcls) || (H5VL_SUBCLS_REQUEST == subcls))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid VOL subclass type") + + /* Unregister the operation */ + if (H5VL__unregister_opt_operation(subcls, op_name) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTREMOVE, FAIL, "can't unregister dynamic optional operation: '%s'", + op_name) + +done: + FUNC_LEAVE_API(ret_value) +} /* H5VLunregister_opt_operation() */ diff --git a/src/H5VLcallback.c b/src/H5VLcallback.c index 80134a7..fcab19f 100644 --- a/src/H5VLcallback.c +++ b/src/H5VLcallback.c @@ -29,11 +29,13 @@ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ +#include "H5ESprivate.h" /* Event Sets */ #include "H5Fprivate.h" /* File access */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ #include "H5PLprivate.h" /* Plugins */ +#include "H5Tprivate.h" /* Datatypes */ #include "H5VLpkg.h" /* Virtual Object Layer */ /****************/ @@ -54,6 +56,10 @@ typedef struct H5VL_file_open_find_connector_t { hid_t fapl_id; } H5VL_file_open_find_connector_t; +/* Typedef for common callback form of registered optional operations */ +typedef herr_t (*H5VL_reg_opt_oper_t)(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, + hid_t dxpl_id, void **req); + /********************/ /* Package Typedefs */ /********************/ @@ -70,13 +76,12 @@ static herr_t H5VL__attr_read(void *obj, const H5VL_class_t *cls, hid_t mem_type void **req); static herr_t H5VL__attr_write(void *obj, const H5VL_class_t *cls, hid_t mem_type_id, const void *buf, hid_t dxpl_id, void **req); -static herr_t H5VL__attr_get(void *obj, const H5VL_class_t *cls, H5VL_attr_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments); +static herr_t H5VL__attr_get(void *obj, const H5VL_class_t *cls, H5VL_attr_get_args_t *args, hid_t dxpl_id, + void **req); static herr_t H5VL__attr_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, - H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -static herr_t H5VL__attr_optional(void *obj, const H5VL_class_t *cls, H5VL_attr_optional_t opt_type, - hid_t dxpl_id, void **req, va_list arguments); + H5VL_attr_specific_args_t *args, hid_t dxpl_id, void **req); +static herr_t H5VL__attr_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, + hid_t dxpl_id, void **req); static herr_t H5VL__attr_close(void *obj, const H5VL_class_t *cls, hid_t dxpl_id, void **req); static void * H5VL__dataset_create(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, const char *name, hid_t lcpl_id, hid_t type_id, hid_t space_id, @@ -87,26 +92,24 @@ static herr_t H5VL__dataset_read(void *dset, const H5VL_class_t *cls, hid_t mem_ hid_t file_space_id, hid_t dxpl_id, void *buf, void **req); static herr_t H5VL__dataset_write(void *obj, const H5VL_class_t *cls, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, const void *buf, void **req); -static herr_t H5VL__dataset_get(void *obj, const H5VL_class_t *cls, H5VL_dataset_get_t get_type, - hid_t dxpl_id, void **req, va_list arguments); -static herr_t H5VL__dataset_specific(void *obj, const H5VL_class_t *cls, - H5VL_dataset_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -static herr_t H5VL__dataset_optional(void *obj, const H5VL_class_t *cls, H5VL_dataset_optional_t opt_type, - hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__dataset_get(void *obj, const H5VL_class_t *cls, H5VL_dataset_get_args_t *args, + hid_t dxpl_id, void **req); +static herr_t H5VL__dataset_specific(void *obj, const H5VL_class_t *cls, H5VL_dataset_specific_args_t *args, + hid_t dxpl_id, void **req); +static herr_t H5VL__dataset_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, + hid_t dxpl_id, void **req); static herr_t H5VL__dataset_close(void *obj, const H5VL_class_t *cls, hid_t dxpl_id, void **req); static void * H5VL__datatype_commit(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t dxpl_id, void **req); static void * H5VL__datatype_open(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, const char *name, hid_t tapl_id, hid_t dxpl_id, void **req); -static herr_t H5VL__datatype_get(void *obj, const H5VL_class_t *cls, H5VL_datatype_get_t get_type, - hid_t dxpl_id, void **req, va_list arguments); -static herr_t H5VL__datatype_specific(void *obj, const H5VL_class_t *cls, - H5VL_datatype_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -static herr_t H5VL__datatype_optional(void *obj, const H5VL_class_t *cls, H5VL_datatype_optional_t opt_type, - hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__datatype_get(void *obj, const H5VL_class_t *cls, H5VL_datatype_get_args_t *args, + hid_t dxpl_id, void **req); +static herr_t H5VL__datatype_specific(void *obj, const H5VL_class_t *cls, H5VL_datatype_specific_args_t *args, + hid_t dxpl_id, void **req); +static herr_t H5VL__datatype_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, + hid_t dxpl_id, void **req); static herr_t H5VL__datatype_close(void *obj, const H5VL_class_t *cls, hid_t dxpl_id, void **req); static void * H5VL__file_create(const H5VL_class_t *cls, const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id, void **req); @@ -114,28 +117,28 @@ static void * H5VL__file_open(const H5VL_class_t *cls, const char *name, unsigne hid_t dxpl_id, void **req); static herr_t H5VL__file_open_find_connector_cb(H5PL_type_t plugin_type, const void *plugin_info, void *op_data); -static herr_t H5VL__file_get(void *obj, const H5VL_class_t *cls, H5VL_file_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments); -static herr_t H5VL__file_specific(void *obj, const H5VL_class_t *cls, H5VL_file_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments); -static herr_t H5VL__file_optional(void *obj, const H5VL_class_t *cls, H5VL_file_optional_t opt_type, - hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__file_get(void *obj, const H5VL_class_t *cls, H5VL_file_get_args_t *args, hid_t dxpl_id, + void **req); +static herr_t H5VL__file_specific(void *obj, const H5VL_class_t *cls, H5VL_file_specific_args_t *args, + hid_t dxpl_id, void **req); +static herr_t H5VL__file_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, + hid_t dxpl_id, void **req); static herr_t H5VL__file_close(void *obj, const H5VL_class_t *cls, hid_t dxpl_id, void **req); static void * H5VL__group_create(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id, hid_t dxpl_id, void **req); static void * H5VL__group_open(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, const char *name, hid_t gapl_id, hid_t dxpl_id, void **req); -static herr_t H5VL__group_get(void *obj, const H5VL_class_t *cls, H5VL_group_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments); -static herr_t H5VL__group_specific(void *obj, const H5VL_class_t *cls, H5VL_group_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments); -static herr_t H5VL__group_optional(void *obj, const H5VL_class_t *cls, H5VL_group_optional_t opt_type, - hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__group_get(void *obj, const H5VL_class_t *cls, H5VL_group_get_args_t *args, hid_t dxpl_id, + void **req); +static herr_t H5VL__group_specific(void *obj, const H5VL_class_t *cls, H5VL_group_specific_args_t *args, + hid_t dxpl_id, void **req); +static herr_t H5VL__group_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, + hid_t dxpl_id, void **req); static herr_t H5VL__group_close(void *obj, const H5VL_class_t *cls, hid_t dxpl_id, void **req); -static herr_t H5VL__link_create(H5VL_link_create_type_t create_type, void *obj, - const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, hid_t lcpl_id, - hid_t lapl_id, hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__link_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t *loc_params, + const H5VL_class_t *cls, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, + void **req); static herr_t H5VL__link_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj, const H5VL_loc_params_t *loc_params2, const H5VL_class_t *cls, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); @@ -143,12 +146,11 @@ static herr_t H5VL__link_move(void *src_obj, const H5VL_loc_params_t *loc_params const H5VL_loc_params_t *loc_params2, const H5VL_class_t *cls, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); static herr_t H5VL__link_get(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, - H5VL_link_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); + H5VL_link_get_args_t *args, hid_t dxpl_id, void **req); static herr_t H5VL__link_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, - H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -static herr_t H5VL__link_optional(void *obj, const H5VL_class_t *cls, H5VL_link_optional_t opt_type, - hid_t dxpl_id, void **req, va_list arguments); + H5VL_link_specific_args_t *args, hid_t dxpl_id, void **req); +static herr_t H5VL__link_optional(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req); static void * H5VL__object_open(void *obj, const H5VL_loc_params_t *params, const H5VL_class_t *cls, H5I_type_t *opened_type, hid_t dxpl_id, void **req); static herr_t H5VL__object_copy(void *src_obj, const H5VL_loc_params_t *src_loc_params, const char *src_name, @@ -156,12 +158,11 @@ static herr_t H5VL__object_copy(void *src_obj, const H5VL_loc_params_t *src_loc_ const H5VL_class_t *cls, hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req); static herr_t H5VL__object_get(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, - H5VL_object_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); + H5VL_object_get_args_t *args, hid_t dxpl_id, void **req); static herr_t H5VL__object_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, - H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -static herr_t H5VL__object_optional(void *obj, const H5VL_class_t *cls, H5VL_object_optional_t opt_type, - hid_t dxpl_id, void **req, va_list arguments); + H5VL_object_specific_args_t *args, hid_t dxpl_id, void **req); +static herr_t H5VL__object_optional(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req); static herr_t H5VL__introspect_get_conn_cls(void *obj, const H5VL_class_t *cls, H5VL_get_conn_lvl_t lvl, const H5VL_class_t **conn_cls); static herr_t H5VL__introspect_opt_query(void *obj, const H5VL_class_t *cls, H5VL_subclass_t subcls, @@ -170,27 +171,25 @@ static herr_t H5VL__request_wait(void *req, const H5VL_class_t *cls, uint64_t ti H5VL_request_status_t *status); static herr_t H5VL__request_notify(void *req, const H5VL_class_t *cls, H5VL_request_notify_t cb, void *ctx); static herr_t H5VL__request_cancel(void *req, const H5VL_class_t *cls, H5VL_request_status_t *status); -static herr_t H5VL__request_specific(void *req, const H5VL_class_t *cls, - H5VL_request_specific_t specific_type, va_list arguments); -static herr_t H5VL__request_optional(void *req, const H5VL_class_t *cls, H5VL_request_optional_t opt_type, - va_list arguments); +static herr_t H5VL__request_specific(void *req, const H5VL_class_t *cls, H5VL_request_specific_args_t *args); +static herr_t H5VL__request_optional(void *req, const H5VL_class_t *cls, H5VL_optional_args_t *args); static herr_t H5VL__request_free(void *req, const H5VL_class_t *cls); static herr_t H5VL__blob_put(void *obj, const H5VL_class_t *cls, const void *buf, size_t size, void *blob_id, void *ctx); static herr_t H5VL__blob_get(void *obj, const H5VL_class_t *cls, const void *blob_id, void *buf, size_t size, void *ctx); static herr_t H5VL__blob_specific(void *obj, const H5VL_class_t *cls, void *blob_id, - H5VL_blob_specific_t specific_type, va_list arguments); + H5VL_blob_specific_args_t *args); static herr_t H5VL__blob_optional(void *obj, const H5VL_class_t *cls, void *blob_id, - H5VL_blob_optional_t opt_type, va_list arguments); + H5VL_optional_args_t *args); static herr_t H5VL__token_cmp(void *obj, const H5VL_class_t *cls, const H5O_token_t *token1, const H5O_token_t *token2, int *cmp_value); static herr_t H5VL__token_to_str(void *obj, H5I_type_t obj_type, const H5VL_class_t *cls, const H5O_token_t *token, char **token_str); static herr_t H5VL__token_from_str(void *obj, H5I_type_t obj_type, const H5VL_class_t *cls, const char *token_str, H5O_token_t *token); -static herr_t H5VL__optional(void *obj, const H5VL_class_t *cls, int op_type, hid_t dxpl_id, void **req, - va_list arguments); +static herr_t H5VL__optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); /*********************/ /* Package Variables */ @@ -329,6 +328,50 @@ done: } /* H5VLget_value */ /*------------------------------------------------------------------------- + * Function: H5VL__common_optional_op + * + * Purpose: Performs an optional connector-specific operation on an object + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__common_optional_op(hid_t id, H5I_type_t id_type, H5VL_reg_opt_oper_t reg_opt_op, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req, H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for id */ + H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for id */ + hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check ID type & get VOL object */ + if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(id, id_type))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid identifier") + + /* Set wrapper info in API context */ + if (H5VL_set_vol_wrapper(*vol_obj_ptr) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") + vol_wrapper_set = TRUE; + + /* Call the corresponding internal VOL routine */ + /* (Must return value from callback, for iterators) */ + if ((ret_value = + (*reg_opt_op)((*vol_obj_ptr)->data, (*vol_obj_ptr)->connector->cls, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute optional callback"); + +done: + /* Reset object wrapping info in API context */ + if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__common_optional_op() */ + +/*------------------------------------------------------------------------- * Function: H5VL_copy_connector_info * * Purpose: Copy the VOL info for a connector @@ -1341,8 +1384,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__attr_get(void *obj, const H5VL_class_t *cls, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL__attr_get(void *obj, const H5VL_class_t *cls, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -1353,7 +1395,7 @@ H5VL__attr_get(void *obj, const H5VL_class_t *cls, H5VL_attr_get_t get_type, hid HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'attr get' method") /* Call the corresponding VOL callback */ - if ((cls->attr_cls.get)(obj, get_type, dxpl_id, req, arguments) < 0) + if ((cls->attr_cls.get)(obj, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "attribute get failed") done: @@ -1371,10 +1413,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_attr_get(const H5VL_object_t *vol_obj, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, ...) +H5VL_attr_get(const H5VL_object_t *vol_obj, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1386,16 +1426,10 @@ H5VL_attr_get(const H5VL_object_t *vol_obj, H5VL_attr_get_t get_type, hid_t dxpl vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__attr_get(vol_obj->data, vol_obj->connector->cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__attr_get(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "attribute get failed") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -1414,23 +1448,24 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLattr_get(void *obj, hid_t connector_id, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req /*out*/, - va_list arguments) +H5VLattr_get(void *obj, hid_t connector_id, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVaixx", obj, connector_id, get_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object") if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") + if (NULL == args) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument struct") /* Call the corresponding internal VOL routine */ - if (H5VL__attr_get(obj, cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__attr_get(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to get attribute information") done: @@ -1449,7 +1484,7 @@ done: */ static herr_t H5VL__attr_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, - H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments) + H5VL_attr_specific_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -1460,8 +1495,9 @@ H5VL__attr_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_c HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'attr specific' method") /* Call the corresponding VOL callback */ - if ((ret_value = (cls->attr_cls.specific)(obj, loc_params, specific_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute attribute specific callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = (cls->attr_cls.specific)(obj, loc_params, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute attribute 'specific' callback"); done: FUNC_LEAVE_NOAPI(ret_value) @@ -1479,10 +1515,8 @@ done: */ herr_t H5VL_attr_specific(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, - H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req, ...) + H5VL_attr_specific_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1494,17 +1528,12 @@ H5VL_attr_specific(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_pa vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if ((ret_value = H5VL__attr_specific(vol_obj->data, loc_params, vol_obj->connector->cls, specific_type, - dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute attribute specific callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = + H5VL__attr_specific(vol_obj->data, loc_params, vol_obj->connector->cls, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute attribute 'specific' callback"); done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -1524,13 +1553,13 @@ done: */ herr_t H5VLattr_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, - H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req /*out*/, va_list arguments) + H5VL_attr_specific_args_t *args, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE7("e", "*x*#iVbixx", obj, loc_params, connector_id, specific_type, dxpl_id, req, arguments); + H5TRACE6("e", "*x*#i*!ix", obj, loc_params, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -1539,8 +1568,9 @@ H5VLattr_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connecto HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if ((ret_value = H5VL__attr_specific(obj, loc_params, cls, specific_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute attribute specific callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = H5VL__attr_specific(obj, loc_params, cls, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute attribute 'specific' callback"); done: FUNC_LEAVE_API_NOINIT(ret_value) @@ -1557,8 +1587,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__attr_optional(void *obj, const H5VL_class_t *cls, H5VL_attr_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL__attr_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -1569,8 +1598,9 @@ H5VL__attr_optional(void *obj, const H5VL_class_t *cls, H5VL_attr_optional_t opt HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'attr optional' method") /* Call the corresponding VOL callback */ - if ((ret_value = (cls->attr_cls.optional)(obj, opt_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute attribute optional callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = (cls->attr_cls.optional)(obj, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute attribute optional callback"); done: FUNC_LEAVE_NOAPI(ret_value) @@ -1587,11 +1617,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_attr_optional(const H5VL_object_t *vol_obj, H5VL_attr_optional_t opt_type, hid_t dxpl_id, void **req, - ...) +H5VL_attr_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1603,17 +1630,11 @@ H5VL_attr_optional(const H5VL_object_t *vol_obj, H5VL_attr_optional_t opt_type, vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if ((ret_value = H5VL__attr_optional(vol_obj->data, vol_obj->connector->cls, opt_type, dxpl_id, req, - arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute attribute optional callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = H5VL__attr_optional(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute attribute optional callback"); done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -1632,14 +1653,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLattr_optional(void *obj, hid_t connector_id, H5VL_attr_optional_t opt_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLattr_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVsixx", obj, connector_id, opt_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -1648,14 +1669,58 @@ H5VLattr_optional(void *obj, hid_t connector_id, H5VL_attr_optional_t opt_type, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if ((ret_value = H5VL__attr_optional(obj, cls, opt_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute attribute optional callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = H5VL__attr_optional(obj, cls, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute attribute optional callback"); done: FUNC_LEAVE_API_NOINIT(ret_value) } /* end H5VLattr_optional() */ /*------------------------------------------------------------------------- + * Function: H5VLattr_optional_op + * + * Purpose: Performs an optional connector-specific operation on an attribute + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLattr_optional_op(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id, + H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Attribute VOL object */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "*s*sIui*!ii", app_file, app_func, app_line, attr_id, args, dxpl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Call the common VOL connector optional routine */ + if ((ret_value = H5VL__common_optional_op(attr_id, H5I_ATTR, H5VL__attr_optional, args, dxpl_id, + token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute attribute optional callback") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(__func__, "*s*sIui*!ii", app_file, app_func, app_line, attr_id, args, dxpl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLattr_optional_op() */ + +/*------------------------------------------------------------------------- * Function: H5VL__attr_close * * Purpose: Closes an attribute through the VOL @@ -2169,8 +2234,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__dataset_get(void *obj, const H5VL_class_t *cls, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL__dataset_get(void *obj, const H5VL_class_t *cls, H5VL_dataset_get_args_t *args, hid_t dxpl_id, + void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -2181,7 +2246,7 @@ H5VL__dataset_get(void *obj, const H5VL_class_t *cls, H5VL_dataset_get_t get_typ HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'dataset get' method") /* Call the corresponding VOL callback */ - if ((cls->dataset_cls.get)(obj, get_type, dxpl_id, req, arguments) < 0) + if ((cls->dataset_cls.get)(obj, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "dataset get failed") done: @@ -2199,10 +2264,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_dataset_get(const H5VL_object_t *vol_obj, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req, ...) +H5VL_dataset_get(const H5VL_object_t *vol_obj, H5VL_dataset_get_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -2214,16 +2277,10 @@ H5VL_dataset_get(const H5VL_object_t *vol_obj, H5VL_dataset_get_t get_type, hid_ vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__dataset_get(vol_obj->data, vol_obj->connector->cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__dataset_get(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "dataset get failed") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -2242,14 +2299,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLdataset_get(void *obj, hid_t connector_id, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req /*out*/, - va_list arguments) +H5VLdataset_get(void *obj, hid_t connector_id, H5VL_dataset_get_args_t *args, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVcixx", obj, connector_id, get_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -2258,7 +2315,7 @@ H5VLdataset_get(void *obj, hid_t connector_id, H5VL_dataset_get_t get_type, hid_ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__dataset_get(obj, cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__dataset_get(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to execute dataset get callback") done: @@ -2276,8 +2333,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__dataset_specific(void *obj, const H5VL_class_t *cls, H5VL_dataset_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments) +H5VL__dataset_specific(void *obj, const H5VL_class_t *cls, H5VL_dataset_specific_args_t *args, hid_t dxpl_id, + void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -2288,7 +2345,7 @@ H5VL__dataset_specific(void *obj, const H5VL_class_t *cls, H5VL_dataset_specific HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'dataset specific' method") /* Call the corresponding VOL callback */ - if ((cls->dataset_cls.specific)(obj, specific_type, dxpl_id, req, arguments) < 0) + if ((cls->dataset_cls.specific)(obj, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute dataset specific callback") done: @@ -2306,11 +2363,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_dataset_specific(const H5VL_object_t *vol_obj, H5VL_dataset_specific_t specific_type, hid_t dxpl_id, - void **req, ...) +H5VL_dataset_specific(const H5VL_object_t *vol_obj, H5VL_dataset_specific_args_t *args, hid_t dxpl_id, + void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -2322,17 +2377,10 @@ H5VL_dataset_specific(const H5VL_object_t *vol_obj, H5VL_dataset_specific_t spec vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__dataset_specific(vol_obj->data, vol_obj->connector->cls, specific_type, dxpl_id, req, - arguments) < 0) + if (H5VL__dataset_specific(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute dataset specific callback") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -2351,14 +2399,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLdataset_specific(void *obj, hid_t connector_id, H5VL_dataset_specific_t specific_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLdataset_specific(void *obj, hid_t connector_id, H5VL_dataset_specific_args_t *args, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVdixx", obj, connector_id, specific_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -2367,7 +2415,7 @@ H5VLdataset_specific(void *obj, hid_t connector_id, H5VL_dataset_specific_t spec HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__dataset_specific(obj, cls, specific_type, dxpl_id, req, arguments) < 0) + if (H5VL__dataset_specific(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute dataset specific callback") done: @@ -2385,8 +2433,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__dataset_optional(void *obj, const H5VL_class_t *cls, H5VL_dataset_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL__dataset_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -2397,7 +2445,7 @@ H5VL__dataset_optional(void *obj, const H5VL_class_t *cls, H5VL_dataset_optional HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'dataset optional' method") /* Call the corresponding VOL callback */ - if ((cls->dataset_cls.optional)(obj, opt_type, dxpl_id, req, arguments) < 0) + if ((cls->dataset_cls.optional)(obj, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute dataset optional callback") done: @@ -2415,11 +2463,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_dataset_optional(const H5VL_object_t *vol_obj, H5VL_dataset_optional_t opt_type, hid_t dxpl_id, - void **req, ...) +H5VL_dataset_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -2431,16 +2476,10 @@ H5VL_dataset_optional(const H5VL_object_t *vol_obj, H5VL_dataset_optional_t opt_ vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__dataset_optional(vol_obj->data, vol_obj->connector->cls, opt_type, dxpl_id, req, arguments) < 0) + if (H5VL__dataset_optional(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute dataset optional callback") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -2459,14 +2498,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLdataset_optional(void *obj, hid_t connector_id, H5VL_dataset_optional_t opt_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLdataset_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVtixx", obj, connector_id, opt_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -2475,7 +2514,7 @@ H5VLdataset_optional(void *obj, hid_t connector_id, H5VL_dataset_optional_t opt_ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__dataset_optional(obj, cls, opt_type, dxpl_id, req, arguments) < 0) + if (H5VL__dataset_optional(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute dataset optional callback") done: @@ -2483,6 +2522,49 @@ done: } /* end H5VLdataset_optional() */ /*------------------------------------------------------------------------- + * Function: H5VLdataset_optional_op + * + * Purpose: Performs an optional connector-specific operation on a dataset + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLdataset_optional_op(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id, + H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Dataset VOL object */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "*s*sIui*!ii", app_file, app_func, app_line, dset_id, args, dxpl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Call the corresponding internal VOL routine */ + if (H5VL__common_optional_op(dset_id, H5I_DATASET, H5VL__dataset_optional, args, dxpl_id, token_ptr, + &vol_obj) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute dataset optional callback") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(__func__, "*s*sIui*!ii", app_file, app_func, app_line, dset_id, args, dxpl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLdataset_optional_op() */ + +/*------------------------------------------------------------------------- * Function: H5VL__dataset_close * * Purpose: Closes a dataset through the VOL @@ -2807,8 +2889,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__datatype_get(void *obj, const H5VL_class_t *cls, H5VL_datatype_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL__datatype_get(void *obj, const H5VL_class_t *cls, H5VL_datatype_get_args_t *args, hid_t dxpl_id, + void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -2819,8 +2901,8 @@ H5VL__datatype_get(void *obj, const H5VL_class_t *cls, H5VL_datatype_get_t get_t HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'datatype get' method") /* Call the corresponding VOL callback */ - if ((cls->datatype_cls.get)(obj, get_type, dxpl_id, req, arguments) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "datatype get failed") + if ((cls->datatype_cls.get)(obj, args, dxpl_id, req) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "datatype 'get' failed") done: FUNC_LEAVE_NOAPI(ret_value) @@ -2837,10 +2919,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_datatype_get(const H5VL_object_t *vol_obj, H5VL_datatype_get_t get_type, hid_t dxpl_id, void **req, ...) +H5VL_datatype_get(const H5VL_object_t *vol_obj, H5VL_datatype_get_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -2852,16 +2932,10 @@ H5VL_datatype_get(const H5VL_object_t *vol_obj, H5VL_datatype_get_t get_type, hi vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__datatype_get(vol_obj->data, vol_obj->connector->cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__datatype_get(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "datatype get failed") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -2880,14 +2954,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLdatatype_get(void *obj, hid_t connector_id, H5VL_datatype_get_t get_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLdatatype_get(void *obj, hid_t connector_id, H5VL_datatype_get_args_t *args, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVeixx", obj, connector_id, get_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -2895,12 +2969,8 @@ H5VLdatatype_get(void *obj, hid_t connector_id, H5VL_datatype_get_t get_type, hi if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") - /* Check if the corresponding VOL callback exists */ - if (NULL == cls->datatype_cls.get) - HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no `datatype get' method") - /* Call the corresponding internal VOL routine */ - if (H5VL__datatype_get(obj, cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__datatype_get(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to execute datatype get callback") done: @@ -2918,8 +2988,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__datatype_specific(void *obj, const H5VL_class_t *cls, H5VL_datatype_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments) +H5VL__datatype_specific(void *obj, const H5VL_class_t *cls, H5VL_datatype_specific_args_t *args, + hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -2930,7 +3000,7 @@ H5VL__datatype_specific(void *obj, const H5VL_class_t *cls, H5VL_datatype_specif HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'datatype specific' method") /* Call the corresponding VOL callback */ - if ((cls->datatype_cls.specific)(obj, specific_type, dxpl_id, req, arguments) < 0) + if ((cls->datatype_cls.specific)(obj, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute datatype specific callback") done: @@ -2948,11 +3018,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_datatype_specific(const H5VL_object_t *vol_obj, H5VL_datatype_specific_t specific_type, hid_t dxpl_id, - void **req, ...) +H5VL_datatype_specific(const H5VL_object_t *vol_obj, H5VL_datatype_specific_args_t *args, hid_t dxpl_id, + void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -2964,17 +3032,10 @@ H5VL_datatype_specific(const H5VL_object_t *vol_obj, H5VL_datatype_specific_t sp vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__datatype_specific(vol_obj->data, vol_obj->connector->cls, specific_type, dxpl_id, req, - arguments) < 0) + if (H5VL__datatype_specific(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute datatype specific callback") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -2993,14 +3054,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLdatatype_specific(void *obj, hid_t connector_id, H5VL_datatype_specific_t specific_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLdatatype_specific(void *obj, hid_t connector_id, H5VL_datatype_specific_args_t *args, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVfixx", obj, connector_id, specific_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -3009,7 +3070,7 @@ H5VLdatatype_specific(void *obj, hid_t connector_id, H5VL_datatype_specific_t sp HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__datatype_specific(obj, cls, specific_type, dxpl_id, req, arguments) < 0) + if (H5VL__datatype_specific(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute datatype specific callback") done: @@ -3027,8 +3088,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__datatype_optional(void *obj, const H5VL_class_t *cls, H5VL_datatype_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL__datatype_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -3039,7 +3100,7 @@ H5VL__datatype_optional(void *obj, const H5VL_class_t *cls, H5VL_datatype_option HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'datatype optional' method") /* Call the corresponding VOL callback */ - if ((cls->datatype_cls.optional)(obj, opt_type, dxpl_id, req, arguments) < 0) + if ((cls->datatype_cls.optional)(obj, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute datatype optional callback") done: @@ -3057,11 +3118,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_datatype_optional(const H5VL_object_t *vol_obj, H5VL_datatype_optional_t opt_type, hid_t dxpl_id, - void **req, ...) +H5VL_datatype_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -3073,17 +3131,10 @@ H5VL_datatype_optional(const H5VL_object_t *vol_obj, H5VL_datatype_optional_t op vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__datatype_optional(vol_obj->data, vol_obj->connector->cls, opt_type, dxpl_id, req, arguments) < - 0) + if (H5VL__datatype_optional(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute datatype optional callback") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -3092,6 +3143,50 @@ done: } /* end H5VL_datatype_optional() */ /*------------------------------------------------------------------------- + * Function: H5VL_datatype_optional_op + * + * Purpose: Optional operation specific to connectors. + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_datatype_optional_op(H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req, + H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for id */ + H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for id */ + hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(vol_obj); + + /* Set up vol_obj_ptr */ + *vol_obj_ptr = vol_obj; + + /* Set wrapper info in API context */ + if (H5VL_set_vol_wrapper(*vol_obj_ptr) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") + vol_wrapper_set = TRUE; + + /* Call the corresponding internal VOL routine */ + if (H5VL__datatype_optional((*vol_obj_ptr)->data, (*vol_obj_ptr)->connector->cls, args, dxpl_id, req) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute datatype optional callback") + +done: + /* Reset object wrapping info in API context */ + if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_datatype_optional_op() */ + +/*------------------------------------------------------------------------- * Function: H5VLdatatype_optional * * Purpose: Performs an optional connector-specific operation on a datatype @@ -3102,14 +3197,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLdatatype_optional(void *obj, hid_t connector_id, H5VL_datatype_optional_t opt_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLdatatype_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVuixx", obj, connector_id, opt_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -3118,7 +3213,7 @@ H5VLdatatype_optional(void *obj, hid_t connector_id, H5VL_datatype_optional_t op HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__datatype_optional(obj, cls, opt_type, dxpl_id, req, arguments) < 0) + if (H5VL__datatype_optional(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute datatype optional callback") done: @@ -3126,6 +3221,53 @@ done: } /* end H5VLdatatype_optional() */ /*------------------------------------------------------------------------- + * Function: H5VLdatatype_optional_op + * + * Purpose: Performs an optional connector-specific operation on a datatype + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLdatatype_optional_op(const char *app_file, const char *app_func, unsigned app_line, hid_t type_id, + H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id) +{ + H5T_t * dt; /* Datatype for this operation */ + H5VL_object_t *vol_obj = NULL; /* Datatype VOL object */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "*s*sIui*!ii", app_file, app_func, app_line, type_id, args, dxpl_id, es_id); + + /* Check args */ + if (NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Only invoke callback if VOL object is set for the datatype */ + if (H5T_invoke_vol_optional(dt, args, dxpl_id, token_ptr, &vol_obj) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to invoke datatype optional callback") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(__func__, "*s*sIui*!ii", app_file, app_func, app_line, type_id, args, dxpl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLdatatype_optional_op() */ + +/*------------------------------------------------------------------------- * Function: H5VL__datatype_close * * Purpose: Closes a datatype through the VOL @@ -3380,14 +3522,16 @@ static herr_t H5VL__file_open_find_connector_cb(H5PL_type_t plugin_type, const void *plugin_info, void *op_data) { H5VL_file_open_find_connector_t *udata = (H5VL_file_open_find_connector_t *)op_data; - const H5VL_class_t * cls = (const H5VL_class_t *)plugin_info; + H5VL_file_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + const H5VL_class_t * cls = (const H5VL_class_t *)plugin_info; H5P_genplist_t * fapl_plist; H5P_genplist_t * fapl_plist_copy; + hbool_t is_accessible = FALSE; /* Whether file is accessible */ + ssize_t num_errors = 0; herr_t status; - htri_t is_accessible = FALSE; - hid_t connector_id = H5I_INVALID_HID; - hid_t fapl_id = H5I_INVALID_HID; - herr_t ret_value = H5_ITER_CONT; + hid_t connector_id = H5I_INVALID_HID; + hid_t fapl_id = H5I_INVALID_HID; + herr_t ret_value = H5_ITER_CONT; FUNC_ENTER_STATIC @@ -3416,19 +3560,40 @@ H5VL__file_open_find_connector_cb(H5PL_type_t plugin_type, const void *plugin_in if (H5P_set_vol(fapl_plist_copy, connector_id, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, H5_ITER_ERROR, "can't set VOL connector on fapl") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_IS_ACCESSIBLE; + vol_cb_args.args.is_accessible.filename = udata->filename; + vol_cb_args.args.is_accessible.fapl_id = fapl_id; + vol_cb_args.args.is_accessible.accessible = &is_accessible; + + /* Store current error stack size */ + if ((num_errors = H5Eget_num(H5E_DEFAULT)) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, H5_ITER_ERROR, "can't get current error stack size") + /* Check if file is accessible with given VOL connector */ H5E_BEGIN_TRY { - status = H5VL_file_specific(NULL, H5VL_FILE_IS_ACCESSIBLE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - fapl_id, udata->filename, &is_accessible); + status = H5VL_file_specific(NULL, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL); } H5E_END_TRY; - /* If the file was accessible with the current VOL connector, return - * the FAPL with that VOL connector set on it. Errors are ignored here - * as some VOL connectors may not support H5Fis_accessible. - */ - if (status == SUCCEED && is_accessible > 0) { + if (status < 0) { + ssize_t new_num_errors = 0; + + /* Pop any errors generated by the above call */ + if ((new_num_errors = H5Eget_num(H5E_DEFAULT)) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, H5_ITER_ERROR, "can't get current error stack size") + if (new_num_errors > num_errors) { + new_num_errors -= num_errors; + if (H5Epop(H5E_DEFAULT, (size_t)new_num_errors) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTRELEASE, H5_ITER_ERROR, "can't sanitize error stack") + } + } + else if (status == SUCCEED && is_accessible) { + /* If the file was accessible with the current VOL connector, return + * the FAPL with that VOL connector set on it. + */ + /* Modify 'connector_prop' to point to the VOL connector that * was actually used to open the file, rather than the original * VOL connector that was requested. @@ -3438,7 +3603,7 @@ H5VL__file_open_find_connector_cb(H5PL_type_t plugin_type, const void *plugin_in udata->fapl_id = fapl_id; ret_value = H5_ITER_STOP; - } /* end if */ + } done: if (ret_value != H5_ITER_STOP) { @@ -3479,21 +3644,18 @@ H5VL_file_open(H5VL_connector_prop_t *connector_prop, const char *name, unsigned /* Call the corresponding internal VOL routine */ if (NULL == (ret_value = H5VL__file_open(cls, name, flags, fapl_id, dxpl_id, req))) { - H5VL_file_open_find_connector_t find_connector_ud; - hbool_t find_connector; - hbool_t connector_available = FALSE; + hbool_t is_default_conn = TRUE; /* Opening the file failed - Determine whether we should search * the plugin path to see if any other VOL connectors are available - * to attempt to open the file with. This only occurs if no particular - * VOL connector was specified (either via a FAPL or the - * HDF5_VOL_CONNECTOR environment variable). + * to attempt to open the file with. This only occurs if the default + * VOL connector was used for the initial file open attempt. */ - find_connector = !getenv("HDF5_VOL_CONNECTOR") && ((H5P_FILE_ACCESS_DEFAULT == fapl_id) || - connector_prop->connector_id == H5_DEFAULT_VOL); + H5VL__is_default_conn(fapl_id, connector_prop->connector_id, &is_default_conn); - if (find_connector) { - herr_t iter_ret; + if (is_default_conn) { + H5VL_file_open_find_connector_t find_connector_ud; + herr_t iter_ret; find_connector_ud.connector_prop = connector_prop; find_connector_ud.filename = name; @@ -3505,24 +3667,24 @@ H5VL_file_open(H5VL_connector_prop_t *connector_prop, const char *name, unsigned if (iter_ret < 0) HGOTO_ERROR(H5E_VOL, H5E_BADITER, NULL, "failed to iterate over available VOL connector plugins") - else if (iter_ret) - connector_available = TRUE; + else if (iter_ret) { + /* If one of the available VOL connector plugins is + * able to open the file, clear the error stack from any + * previous file open failures and then open the file. + * Otherwise, if no VOL connectors are available, throw + * error from original file open failure. + */ + H5E_clear_stack(NULL); + + if (NULL == (ret_value = H5VL__file_open(find_connector_ud.cls, name, flags, + find_connector_ud.fapl_id, dxpl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, + "can't open file '%s' with VOL connector '%s'", name, + find_connector_ud.cls->name) + } + else + HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "open failed") } /* end if */ - - /* If one of the available VOL connector plugins is - * able to open the file, clear the error stack from any - * previous file open failures and then open the file. - * Otherwise, if no VOL connectors are available, throw - * error from original file open failure. - */ - if (connector_available) { - H5E_clear_stack(NULL); - - if (NULL == (ret_value = H5VL__file_open(find_connector_ud.cls, name, flags, - find_connector_ud.fapl_id, dxpl_id, req))) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "can't open file '%s' with VOL connector '%s'", - name, find_connector_ud.cls->name) - } else HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "open failed") } /* end if */ @@ -3581,8 +3743,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__file_get(void *obj, const H5VL_class_t *cls, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL__file_get(void *obj, const H5VL_class_t *cls, H5VL_file_get_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -3593,7 +3754,7 @@ H5VL__file_get(void *obj, const H5VL_class_t *cls, H5VL_file_get_t get_type, hid HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'file get' method") /* Call the corresponding VOL callback */ - if ((cls->file_cls.get)(obj, get_type, dxpl_id, req, arguments) < 0) + if ((cls->file_cls.get)(obj, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "file get failed") done: @@ -3611,10 +3772,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_file_get(const H5VL_object_t *vol_obj, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, ...) +H5VL_file_get(const H5VL_object_t *vol_obj, H5VL_file_get_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -3626,16 +3785,10 @@ H5VL_file_get(const H5VL_object_t *vol_obj, H5VL_file_get_t get_type, hid_t dxpl vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__file_get(vol_obj->data, vol_obj->connector->cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__file_get(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "file get failed") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -3654,14 +3807,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLfile_get(void *obj, hid_t connector_id, H5VL_file_get_t get_type, hid_t dxpl_id, void **req /*out*/, - va_list arguments) +H5VLfile_get(void *obj, hid_t connector_id, H5VL_file_get_args_t *args, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVgixx", obj, connector_id, get_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -3670,7 +3822,7 @@ H5VLfile_get(void *obj, hid_t connector_id, H5VL_file_get_t get_type, hid_t dxpl HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__file_get(obj, cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__file_get(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to execute file get callback") done: @@ -3688,8 +3840,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__file_specific(void *obj, const H5VL_class_t *cls, H5VL_file_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL__file_specific(void *obj, const H5VL_class_t *cls, H5VL_file_specific_args_t *args, hid_t dxpl_id, + void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -3700,7 +3852,7 @@ H5VL__file_specific(void *obj, const H5VL_class_t *cls, H5VL_file_specific_t spe HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'file specific' method") /* Call the corresponding VOL callback */ - if ((cls->file_cls.specific)(obj, specific_type, dxpl_id, req, arguments) < 0) + if ((cls->file_cls.specific)(obj, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "file specific failed") done: @@ -3718,33 +3870,28 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_file_specific(const H5VL_object_t *vol_obj, H5VL_file_specific_t specific_type, hid_t dxpl_id, - void **req, ...) +H5VL_file_specific(const H5VL_object_t *vol_obj, H5VL_file_specific_args_t *args, hid_t dxpl_id, void **req) { const H5VL_class_t *cls; /* VOL connector's class struct */ - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) - /* Start access to the varargs, so they are available in all situations below */ - HDva_start(arguments, req); - arg_started = TRUE; - /* Special treatment of file access check & delete operations */ /* (Retrieve the VOL connector from the FAPL, since the file isn't open) */ - if (specific_type == H5VL_FILE_IS_ACCESSIBLE || specific_type == H5VL_FILE_DELETE) { + if (args->op_type == H5VL_FILE_IS_ACCESSIBLE || args->op_type == H5VL_FILE_DELETE) { H5P_genplist_t * plist; /* Property list pointer */ H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */ - va_list tmp_args; /* argument list passed from the API call */ hid_t fapl_id; /* File access property list for accessing the file */ /* Get the file access property list to access the file */ - HDva_copy(tmp_args, arguments); - fapl_id = HDva_arg(tmp_args, hid_t); - HDva_end(tmp_args); + if (args->op_type == H5VL_FILE_IS_ACCESSIBLE) + fapl_id = args->args.is_accessible.fapl_id; + else { + HDassert(args->op_type == H5VL_FILE_DELETE); + fapl_id = args->args.del.fapl_id; + } /* Get the VOL info from the FAPL */ if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) @@ -3770,14 +3917,10 @@ H5VL_file_specific(const H5VL_object_t *vol_obj, H5VL_file_specific_t specific_t } /* end else */ /* Call the corresponding internal VOL routine */ - if (H5VL__file_specific(vol_obj ? vol_obj->data : NULL, cls, specific_type, dxpl_id, req, arguments) < 0) + if (H5VL__file_specific(vol_obj ? vol_obj->data : NULL, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "file specific failed") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -3798,21 +3941,21 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLfile_specific(void *obj, hid_t connector_id, H5VL_file_specific_t specific_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLfile_specific(void *obj, hid_t connector_id, H5VL_file_specific_args_t *args, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVhixx", obj, connector_id, specific_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__file_specific(obj, cls, specific_type, dxpl_id, req, arguments) < 0) + if (H5VL__file_specific(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute file specific callback") done: @@ -3830,8 +3973,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__file_optional(void *obj, const H5VL_class_t *cls, H5VL_file_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL__file_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -3842,7 +3984,7 @@ H5VL__file_optional(void *obj, const H5VL_class_t *cls, H5VL_file_optional_t opt HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'file optional' method") /* Call the corresponding VOL callback */ - if ((cls->file_cls.optional)(obj, opt_type, dxpl_id, req, arguments) < 0) + if ((cls->file_cls.optional)(obj, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "file optional failed") done: @@ -3860,11 +4002,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_file_optional(const H5VL_object_t *vol_obj, H5VL_file_optional_t opt_type, hid_t dxpl_id, void **req, - ...) +H5VL_file_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -3876,16 +4015,10 @@ H5VL_file_optional(const H5VL_object_t *vol_obj, H5VL_file_optional_t opt_type, vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__file_optional(vol_obj->data, vol_obj->connector->cls, opt_type, dxpl_id, req, arguments) < 0) + if (H5VL__file_optional(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "file optional failed") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -3904,14 +4037,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLfile_optional(void *obj, hid_t connector_id, H5VL_file_optional_t opt_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLfile_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVvixx", obj, connector_id, opt_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -3920,7 +4053,7 @@ H5VLfile_optional(void *obj, hid_t connector_id, H5VL_file_optional_t opt_type, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__file_optional(obj, cls, opt_type, dxpl_id, req, arguments) < 0) + if (H5VL__file_optional(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute file optional callback") done: @@ -3928,6 +4061,49 @@ done: } /* end H5VLfile_optional() */ /*------------------------------------------------------------------------- + * Function: H5VLfile_optional_op + * + * Purpose: Performs an optional connector-specific operation on a file + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLfile_optional_op(const char *app_file, const char *app_func, unsigned app_line, hid_t file_id, + H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* File VOL object */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "*s*sIui*!ii", app_file, app_func, app_line, file_id, args, dxpl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Call the corresponding internal VOL routine */ + if (H5VL__common_optional_op(file_id, H5I_FILE, H5VL__file_optional, args, dxpl_id, token_ptr, &vol_obj) < + 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute file optional callback") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(__func__, "*s*sIui*!ii", app_file, app_func, app_line, file_id, args, dxpl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLfile_optional_op() */ + +/*------------------------------------------------------------------------- * Function: H5VL__file_close * * Purpose: Closes a file through the VOL @@ -4244,8 +4420,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__group_get(void *obj, const H5VL_class_t *cls, H5VL_group_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL__group_get(void *obj, const H5VL_class_t *cls, H5VL_group_get_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -4256,7 +4431,7 @@ H5VL__group_get(void *obj, const H5VL_class_t *cls, H5VL_group_get_t get_type, h HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'group get' method") /* Call the corresponding VOL callback */ - if ((cls->group_cls.get)(obj, get_type, dxpl_id, req, arguments) < 0) + if ((cls->group_cls.get)(obj, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "group get failed") done: @@ -4274,10 +4449,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_group_get(const H5VL_object_t *vol_obj, H5VL_group_get_t get_type, hid_t dxpl_id, void **req, ...) +H5VL_group_get(const H5VL_object_t *vol_obj, H5VL_group_get_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -4289,16 +4462,10 @@ H5VL_group_get(const H5VL_object_t *vol_obj, H5VL_group_get_t get_type, hid_t dx vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__group_get(vol_obj->data, vol_obj->connector->cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__group_get(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "group get failed") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -4317,14 +4484,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLgroup_get(void *obj, hid_t connector_id, H5VL_group_get_t get_type, hid_t dxpl_id, void **req /*out*/, - va_list arguments) +H5VLgroup_get(void *obj, hid_t connector_id, H5VL_group_get_args_t *args, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiViixx", obj, connector_id, get_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -4333,7 +4499,7 @@ H5VLgroup_get(void *obj, hid_t connector_id, H5VL_group_get_t get_type, hid_t dx HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__group_get(obj, cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__group_get(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to execute group get callback") done: @@ -4351,8 +4517,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__group_specific(void *obj, const H5VL_class_t *cls, H5VL_group_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL__group_specific(void *obj, const H5VL_class_t *cls, H5VL_group_specific_args_t *args, hid_t dxpl_id, + void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -4363,7 +4529,7 @@ H5VL__group_specific(void *obj, const H5VL_class_t *cls, H5VL_group_specific_t s HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'group specific' method") /* Call the corresponding VOL callback */ - if ((cls->group_cls.specific)(obj, specific_type, dxpl_id, req, arguments) < 0) + if ((cls->group_cls.specific)(obj, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute group specific callback") done: @@ -4381,11 +4547,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_group_specific(const H5VL_object_t *vol_obj, H5VL_group_specific_t specific_type, hid_t dxpl_id, - void **req, ...) +H5VL_group_specific(const H5VL_object_t *vol_obj, H5VL_group_specific_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -4397,17 +4560,10 @@ H5VL_group_specific(const H5VL_object_t *vol_obj, H5VL_group_specific_t specific vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__group_specific(vol_obj->data, vol_obj->connector->cls, specific_type, dxpl_id, req, arguments) < - 0) + if (H5VL__group_specific(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute group specific callback") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -4426,14 +4582,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLgroup_specific(void *obj, hid_t connector_id, H5VL_group_specific_t specific_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLgroup_specific(void *obj, hid_t connector_id, H5VL_group_specific_args_t *args, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVjixx", obj, connector_id, specific_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -4442,7 +4598,7 @@ H5VLgroup_specific(void *obj, hid_t connector_id, H5VL_group_specific_t specific HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__group_specific(obj, cls, specific_type, dxpl_id, req, arguments) < 0) + if (H5VL__group_specific(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute group specific callback") done: @@ -4460,8 +4616,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__group_optional(void *obj, const H5VL_class_t *cls, H5VL_group_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL__group_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -4472,8 +4628,9 @@ H5VL__group_optional(void *obj, const H5VL_class_t *cls, H5VL_group_optional_t o HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'group optional' method") /* Call the corresponding VOL callback */ - if ((ret_value = (cls->group_cls.optional)(obj, opt_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute group optional callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = (cls->group_cls.optional)(obj, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute group optional callback"); done: FUNC_LEAVE_NOAPI(ret_value) @@ -4490,11 +4647,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_group_optional(const H5VL_object_t *vol_obj, H5VL_group_optional_t opt_type, hid_t dxpl_id, void **req, - ...) +H5VL_group_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -4506,17 +4660,11 @@ H5VL_group_optional(const H5VL_object_t *vol_obj, H5VL_group_optional_t opt_type vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if ((ret_value = H5VL__group_optional(vol_obj->data, vol_obj->connector->cls, opt_type, dxpl_id, req, - arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute group optional callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = H5VL__group_optional(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute group optional callback"); done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -4535,14 +4683,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLgroup_optional(void *obj, hid_t connector_id, H5VL_group_optional_t opt_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLgroup_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVwixx", obj, connector_id, opt_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -4551,14 +4699,58 @@ H5VLgroup_optional(void *obj, hid_t connector_id, H5VL_group_optional_t opt_type HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if ((ret_value = H5VL__group_optional(obj, cls, opt_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute group optional callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = H5VL__group_optional(obj, cls, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute group optional callback"); done: FUNC_LEAVE_API_NOINIT(ret_value) } /* end H5VLgroup_optional() */ /*------------------------------------------------------------------------- + * Function: H5VLgroup_optional_op + * + * Purpose: Performs an optional connector-specific operation on a group + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLgroup_optional_op(const char *app_file, const char *app_func, unsigned app_line, hid_t group_id, + H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Group VOL object */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "*s*sIui*!ii", app_file, app_func, app_line, group_id, args, dxpl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Call the corresponding internal VOL routine */ + if ((ret_value = H5VL__common_optional_op(group_id, H5I_GROUP, H5VL__group_optional, args, dxpl_id, + token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute group optional callback") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(__func__, "*s*sIui*!ii", app_file, app_func, app_line, group_id, args, dxpl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLgroup_optional_op() */ + +/*------------------------------------------------------------------------- * Function: H5VL__group_close * * Purpose: Closes a group through the VOL @@ -4672,9 +4864,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__link_create(H5VL_link_create_type_t create_type, void *obj, const H5VL_loc_params_t *loc_params, - const H5VL_class_t *cls, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req, - va_list arguments) +H5VL__link_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t *loc_params, + const H5VL_class_t *cls, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -4685,7 +4876,7 @@ H5VL__link_create(H5VL_link_create_type_t create_type, void *obj, const H5VL_loc HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'link create' method") /* Call the corresponding VOL callback */ - if ((cls->link_cls.create)(create_type, obj, loc_params, lcpl_id, lapl_id, dxpl_id, req, arguments) < 0) + if ((cls->link_cls.create)(args, obj, loc_params, lcpl_id, lapl_id, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, FAIL, "link create failed") done: @@ -4703,31 +4894,19 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_link_create(H5VL_link_create_type_t create_type, const H5VL_object_t *vol_obj, - const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req, - ...) +H5VL_link_create(H5VL_link_create_args_t *args, const H5VL_object_t *vol_obj, + const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req) { - H5VL_object_t tmp_vol_obj; /* Temporary object */ - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ + H5VL_object_t tmp_vol_obj; /* Temporary VOL object */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) - /* Start the varargs, so they can be copied */ - HDva_start(arguments, req); - arg_started = TRUE; - /* Special case for hard links */ - if (H5VL_LINK_CREATE_HARD == create_type && NULL == vol_obj->data) { - va_list tmp_arguments; /* Copy of argument list passed in */ - - /* Get the VOL data pointer from the varargs */ - HDva_copy(tmp_arguments, arguments); - tmp_vol_obj.data = HDva_arg(tmp_arguments, void *); - HDva_end(tmp_arguments); - } /* end if */ + if (H5VL_LINK_CREATE_HARD == args->op_type && NULL == vol_obj->data) + /* Get the VOL data pointer from the arguments */ + tmp_vol_obj.data = args->args.hard.curr_obj; else /* Use the VOL object passed in */ tmp_vol_obj.data = vol_obj->data; @@ -4739,15 +4918,11 @@ H5VL_link_create(H5VL_link_create_type_t create_type, const H5VL_object_t *vol_o vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - if (H5VL__link_create(create_type, vol_obj->data, loc_params, vol_obj->connector->cls, lcpl_id, lapl_id, - dxpl_id, req, arguments) < 0) + if (H5VL__link_create(args, vol_obj->data, loc_params, vol_obj->connector->cls, lcpl_id, lapl_id, dxpl_id, + req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, FAIL, "link create failed") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -4768,23 +4943,21 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLlink_create(H5VL_link_create_type_t create_type, void *obj, const H5VL_loc_params_t *loc_params, - hid_t connector_id, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req /*out*/, - va_list arguments) +H5VLlink_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t *loc_params, + hid_t connector_id, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE9("e", "Vk*x*#iiiixx", create_type, obj, loc_params, connector_id, lcpl_id, lapl_id, dxpl_id, req, - arguments); + H5TRACE8("e", "*!*x*#iiiix", args, obj, loc_params, connector_id, lcpl_id, lapl_id, dxpl_id, req); /* Get class pointer */ if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__link_create(create_type, obj, loc_params, cls, lcpl_id, lapl_id, dxpl_id, req, arguments) < 0) + if (H5VL__link_create(args, obj, loc_params, cls, lcpl_id, lapl_id, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, FAIL, "unable to create link") done: @@ -5017,7 +5190,7 @@ done: */ static herr_t H5VL__link_get(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, - H5VL_link_get_t get_type, hid_t dxpl_id, void **req, va_list arguments) + H5VL_link_get_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -5028,7 +5201,7 @@ H5VL__link_get(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_ HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'link get' method") /* Call the corresponding VOL callback */ - if ((cls->link_cls.get)(obj, loc_params, get_type, dxpl_id, req, arguments) < 0) + if ((cls->link_cls.get)(obj, loc_params, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "link get failed") done: @@ -5046,11 +5219,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_link_get(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_t get_type, - hid_t dxpl_id, void **req, ...) +H5VL_link_get(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_args_t *args, + hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -5062,17 +5233,10 @@ H5VL_link_get(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__link_get(vol_obj->data, loc_params, vol_obj->connector->cls, get_type, dxpl_id, req, - arguments) < 0) + if (H5VL__link_get(vol_obj->data, loc_params, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "link get failed") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -5091,14 +5255,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLlink_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, H5VL_link_get_t get_type, - hid_t dxpl_id, void **req /*out*/, va_list arguments) +H5VLlink_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, H5VL_link_get_args_t *args, + hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE7("e", "*x*#iVlixx", obj, loc_params, connector_id, get_type, dxpl_id, req, arguments); + H5TRACE6("e", "*x*#i*!ix", obj, loc_params, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -5107,7 +5271,7 @@ H5VLlink_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__link_get(obj, loc_params, cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__link_get(obj, loc_params, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to execute link get callback") done: @@ -5126,7 +5290,7 @@ done: */ static herr_t H5VL__link_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, - H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments) + H5VL_link_specific_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -5137,8 +5301,9 @@ H5VL__link_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_c HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'link specific' method") /* Call the corresponding VOL callback */ - if ((ret_value = (cls->link_cls.specific)(obj, loc_params, specific_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute link specific callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = (cls->link_cls.specific)(obj, loc_params, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute link specific callback"); done: FUNC_LEAVE_NOAPI(ret_value) @@ -5156,10 +5321,8 @@ done: */ herr_t H5VL_link_specific(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, - H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req, ...) + H5VL_link_specific_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -5171,17 +5334,12 @@ H5VL_link_specific(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_pa vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if ((ret_value = H5VL__link_specific(vol_obj->data, loc_params, vol_obj->connector->cls, specific_type, - dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute link specific callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = + H5VL__link_specific(vol_obj->data, loc_params, vol_obj->connector->cls, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute link specific callback"); done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -5201,13 +5359,13 @@ done: */ herr_t H5VLlink_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, - H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req /*out*/, va_list arguments) + H5VL_link_specific_args_t *args, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE7("e", "*x*#iVmixx", obj, loc_params, connector_id, specific_type, dxpl_id, req, arguments); + H5TRACE6("e", "*x*#i*!ix", obj, loc_params, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -5216,8 +5374,9 @@ H5VLlink_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connecto HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if ((ret_value = H5VL__link_specific(obj, loc_params, cls, specific_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute link specific callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = H5VL__link_specific(obj, loc_params, cls, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute link specific callback"); done: FUNC_LEAVE_API_NOINIT(ret_value) @@ -5234,8 +5393,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__link_optional(void *obj, const H5VL_class_t *cls, H5VL_link_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL__link_optional(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -5246,7 +5405,7 @@ H5VL__link_optional(void *obj, const H5VL_class_t *cls, H5VL_link_optional_t opt HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'link optional' method") /* Call the corresponding VOL callback */ - if ((cls->link_cls.optional)(obj, opt_type, dxpl_id, req, arguments) < 0) + if ((cls->link_cls.optional)(obj, loc_params, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute link optional callback") done: @@ -5264,11 +5423,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_link_optional(const H5VL_object_t *vol_obj, H5VL_link_optional_t opt_type, hid_t dxpl_id, void **req, - ...) +H5VL_link_optional(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -5280,16 +5437,10 @@ H5VL_link_optional(const H5VL_object_t *vol_obj, H5VL_link_optional_t opt_type, vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__link_optional(vol_obj->data, vol_obj->connector->cls, opt_type, dxpl_id, req, arguments) < 0) + if (H5VL__link_optional(vol_obj->data, loc_params, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute link optional callback") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -5308,14 +5459,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLlink_optional(void *obj, hid_t connector_id, H5VL_link_optional_t opt_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLlink_optional(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVxixx", obj, connector_id, opt_type, dxpl_id, req, arguments); + H5TRACE6("e", "*x*#i*!ix", obj, loc_params, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -5324,7 +5475,7 @@ H5VLlink_optional(void *obj, hid_t connector_id, H5VL_link_optional_t opt_type, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__link_optional(obj, cls, opt_type, dxpl_id, req, arguments) < 0) + if (H5VL__link_optional(obj, loc_params, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute link optional callback") done: @@ -5332,37 +5483,98 @@ done: } /* end H5VLlink_optional() */ /*------------------------------------------------------------------------- - * Function: H5VL__object_open + * Function: H5VLlink_optional_op * - * Purpose: Opens a object through the VOL + * Purpose: Performs an optional connector-specific operation on a link * - * Return: Success: Pointer to the object - * Failure: NULL + * Return: Success: Non-negative + * Failure: Negative * *------------------------------------------------------------------------- */ -static void * -H5VL__object_open(void *obj, const H5VL_loc_params_t *params, const H5VL_class_t *cls, - H5I_type_t *opened_type, hid_t dxpl_id, void **req) +herr_t +H5VLlink_optional_op(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *name, hid_t lapl_id, H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id) { - void *ret_value = NULL; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC + FUNC_ENTER_API(FAIL) + H5TRACE9("e", "*s*sIui*si*!ii", app_file, app_func, app_line, loc_id, name, lapl_id, args, dxpl_id, + es_id); - /* Check if the corresponding VOL callback exists */ - if (NULL == cls->object_cls.open) - HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "VOL connector has no 'object open' method") + /* Check arguments */ + /* name is verified in H5VL_setup_name_args() */ - /* Call the corresponding VOL callback */ - if (NULL == (ret_value = (cls->object_cls.open)(obj, params, opened_type, dxpl_id, req))) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "object open failed") + /* Set up object access arguments */ + if (H5VL_setup_name_args(loc_id, name, FALSE, lapl_id, &vol_obj, &loc_params) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set link access arguments") -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5VL__object_open() */ + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ -/*------------------------------------------------------------------------- - * Function: H5VL_object_open + /* Set wrapper info in API context */ + if (H5VL_set_vol_wrapper(vol_obj) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") + vol_wrapper_set = TRUE; + + /* Call the corresponding internal VOL routine */ + if (H5VL__link_optional(vol_obj->data, &loc_params, vol_obj->connector->cls, args, dxpl_id, token_ptr) < + 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute link optional callback") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, H5ARG_TRACE9(__func__, "*s*sIui*si*!ii", app_file, app_func, app_line, loc_id, name, lapl_id, args, dxpl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + /* Reset object wrapping info in API context */ + if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") + + FUNC_LEAVE_API(ret_value) +} /* end H5VLlink_optional_op() */ + +/*------------------------------------------------------------------------- + * Function: H5VL__object_open + * + * Purpose: Opens a object through the VOL + * + * Return: Success: Pointer to the object + * Failure: NULL + * + *------------------------------------------------------------------------- + */ +static void * +H5VL__object_open(void *obj, const H5VL_loc_params_t *params, const H5VL_class_t *cls, + H5I_type_t *opened_type, hid_t dxpl_id, void **req) +{ + void *ret_value = NULL; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check if the corresponding VOL callback exists */ + if (NULL == cls->object_cls.open) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "VOL connector has no 'object open' method") + + /* Call the corresponding VOL callback */ + if (NULL == (ret_value = (cls->object_cls.open)(obj, params, opened_type, dxpl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "object open failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__object_open() */ + +/*------------------------------------------------------------------------- + * Function: H5VL_object_open * * Purpose: Opens a object through the VOL * @@ -5556,7 +5768,7 @@ done: */ static herr_t H5VL__object_get(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, - H5VL_object_get_t get_type, hid_t dxpl_id, void **req, va_list arguments) + H5VL_object_get_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -5567,7 +5779,7 @@ H5VL__object_get(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_clas HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'object get' method") /* Call the corresponding VOL callback */ - if ((cls->object_cls.get)(obj, loc_params, get_type, dxpl_id, req, arguments) < 0) + if ((cls->object_cls.get)(obj, loc_params, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "get failed") done: @@ -5585,11 +5797,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_object_get(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_t get_type, - hid_t dxpl_id, void **req, ...) +H5VL_object_get(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, + H5VL_object_get_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -5601,17 +5811,10 @@ H5VL_object_get(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_param vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__object_get(vol_obj->data, loc_params, vol_obj->connector->cls, get_type, dxpl_id, req, - arguments) < 0) + if (H5VL__object_get(vol_obj->data, loc_params, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "get failed") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -5630,14 +5833,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLobject_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, H5VL_object_get_t get_type, - hid_t dxpl_id, void **req /*out*/, va_list arguments) +H5VLobject_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, + H5VL_object_get_args_t *args, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE7("e", "*x*#iVnixx", obj, loc_params, connector_id, get_type, dxpl_id, req, arguments); + H5TRACE6("e", "*x*#i*!ix", obj, loc_params, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -5646,7 +5849,7 @@ H5VLobject_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_i HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__object_get(obj, loc_params, cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__object_get(obj, loc_params, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to execute object get callback") done: @@ -5665,7 +5868,7 @@ done: */ static herr_t H5VL__object_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, - H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments) + H5VL_object_specific_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -5676,8 +5879,9 @@ H5VL__object_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'object specific' method") /* Call the corresponding VOL callback */ - if ((ret_value = (cls->object_cls.specific)(obj, loc_params, specific_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "object specific failed") + /* (Must return value from callback, for iterators) */ + if ((ret_value = (cls->object_cls.specific)(obj, loc_params, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "object specific failed"); done: FUNC_LEAVE_NOAPI(ret_value) @@ -5695,10 +5899,8 @@ done: */ herr_t H5VL_object_specific(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, - H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req, ...) + H5VL_object_specific_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -5710,17 +5912,12 @@ H5VL_object_specific(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_ vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if ((ret_value = H5VL__object_specific(vol_obj->data, loc_params, vol_obj->connector->cls, specific_type, - dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "object specific failed") + /* (Must return value from callback, for iterators) */ + if ((ret_value = H5VL__object_specific(vol_obj->data, loc_params, vol_obj->connector->cls, args, dxpl_id, + req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "object specific failed"); done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -5740,14 +5937,13 @@ done: */ herr_t H5VLobject_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, - H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req /*out*/, - va_list arguments) + H5VL_object_specific_args_t *args, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE7("e", "*x*#iVoixx", obj, loc_params, connector_id, specific_type, dxpl_id, req, arguments); + H5TRACE6("e", "*x*#i*!ix", obj, loc_params, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -5755,13 +5951,10 @@ H5VLobject_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connec if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") - /* Check if the corresponding VOL callback exists */ - if (NULL == cls->object_cls.specific) - HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no `object specific' method") - /* Bypass the H5VLint layer, calling the VOL callback directly */ - if ((ret_value = (cls->object_cls.specific)(obj, loc_params, specific_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute object specific callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = (cls->object_cls.specific)(obj, loc_params, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute object specific callback"); done: FUNC_LEAVE_API_NOINIT(ret_value) @@ -5778,8 +5971,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__object_optional(void *obj, const H5VL_class_t *cls, H5VL_object_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL__object_optional(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -5790,7 +5983,7 @@ H5VL__object_optional(void *obj, const H5VL_class_t *cls, H5VL_object_optional_t HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'object optional' method") /* Call the corresponding VOL callback */ - if ((cls->object_cls.optional)(obj, opt_type, dxpl_id, req, arguments) < 0) + if ((cls->object_cls.optional)(obj, loc_params, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute object optional callback") done: @@ -5808,11 +6001,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_object_optional(const H5VL_object_t *vol_obj, H5VL_object_optional_t opt_type, hid_t dxpl_id, void **req, - ...) +H5VL_object_optional(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -5824,16 +6015,10 @@ H5VL_object_optional(const H5VL_object_t *vol_obj, H5VL_object_optional_t opt_ty vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__object_optional(vol_obj->data, vol_obj->connector->cls, opt_type, dxpl_id, req, arguments) < 0) + if (H5VL__object_optional(vol_obj->data, loc_params, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute object optional callback") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -5852,14 +6037,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLobject_optional(void *obj, hid_t connector_id, H5VL_object_optional_t opt_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLobject_optional(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVyixx", obj, connector_id, opt_type, dxpl_id, req, arguments); + H5TRACE6("e", "*x*#i*!ix", obj, loc_params, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -5868,7 +6053,7 @@ H5VLobject_optional(void *obj, hid_t connector_id, H5VL_object_optional_t opt_ty HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__object_optional(obj, cls, opt_type, dxpl_id, req, arguments) < 0) + if (H5VL__object_optional(obj, loc_params, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute object optional callback") done: @@ -5876,6 +6061,68 @@ done: } /* end H5VLobject_optional() */ /*------------------------------------------------------------------------- + * Function: H5VLobject_optional_op + * + * Purpose: Performs an optional connector-specific operation on an object + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLobject_optional_op(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *name, hid_t lapl_id, H5VL_optional_args_t *args, hid_t dxpl_id, + hid_t es_id) +{ + H5VL_object_t * vol_obj = NULL; /* Object for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE9("e", "*s*sIui*si*!ii", app_file, app_func, app_line, loc_id, name, lapl_id, args, dxpl_id, + es_id); + + /* Check arguments */ + /* name is verified in H5VL_setup_name_args() */ + + /* Set up object access arguments */ + if (H5VL_setup_name_args(loc_id, name, FALSE, lapl_id, &vol_obj, &loc_params) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set link access arguments") + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Set wrapper info in API context */ + if (H5VL_set_vol_wrapper(vol_obj) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") + vol_wrapper_set = TRUE; + + /* Call the corresponding internal VOL routine */ + if (H5VL__object_optional(vol_obj->data, &loc_params, vol_obj->connector->cls, args, dxpl_id, token_ptr) < + 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute object optional callback") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, H5ARG_TRACE9(__func__, "*s*sIui*si*!ii", app_file, app_func, app_line, loc_id, name, lapl_id, args, dxpl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + /* Reset object wrapping info in API context */ + if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") + + FUNC_LEAVE_API(ret_value) +} /* end H5VLobject_optional_op() */ + +/*------------------------------------------------------------------------- * Function: H5VL__introspect_get_conn_cls * * Purpose: Calls the connector-specific callback to query the connector @@ -5989,6 +6236,76 @@ done: } /* end H5VLintrospect_get_conn_cls() */ /*------------------------------------------------------------------------- + * Function: H5VL_introspect_get_cap_flags + * + * Purpose: Calls the connector-specific callback to query the connector's + * capability flags. + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_introspect_get_cap_flags(const void *info, const H5VL_class_t *cls, unsigned *cap_flags) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(cls); + HDassert(cap_flags); + + /* Check if the corresponding VOL callback exists */ + if (NULL == cls->introspect_cls.get_cap_flags) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'get_cap_flags' method") + + /* Call the corresponding VOL callback */ + if ((cls->introspect_cls.get_cap_flags)(info, cap_flags) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't query connector capability flags") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_introspect_get_cap_flags() */ + +/*------------------------------------------------------------------------- + * Function: H5VLintrospect_get_cap_flags + * + * Purpose: Calls the connector-specific callback to query the connector's + * capability flags. + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLintrospect_get_cap_flags(const void *info, hid_t connector_id, unsigned *cap_flags /*out*/) +{ + H5VL_class_t *cls; /* VOL connector's class struct */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API_NOINIT + H5TRACE3("e", "*xix", info, connector_id, cap_flags); + + /* Check args */ + if (NULL == cap_flags) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL conn_cls pointer") + + /* Get class pointer */ + if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") + + /* Call the corresponding internal VOL routine */ + if (H5VL_introspect_get_cap_flags(info, cls, cap_flags) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't query connector's capability flags") + +done: + FUNC_LEAVE_API_NOINIT(ret_value) +} /* end H5VLintrospect_get_cap_flags() */ + +/*------------------------------------------------------------------------- * Function: H5VL__introspect_opt_query * * Purpose: Calls the connector-specific callback to query if an optional @@ -6135,28 +6452,18 @@ done: herr_t H5VL_request_wait(const H5VL_object_t *vol_obj, uint64_t timeout, H5VL_request_status_t *status) { - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity checks */ HDassert(vol_obj); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding internal VOL routine */ if (H5VL__request_wait(vol_obj->data, vol_obj->connector->cls, timeout, status) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "request wait failed") done: - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_request_wait() */ @@ -6239,28 +6546,18 @@ done: herr_t H5VL_request_notify(const H5VL_object_t *vol_obj, H5VL_request_notify_t cb, void *ctx) { - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(vol_obj); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding internal VOL routine */ if (H5VL__request_notify(vol_obj->data, vol_obj->connector->cls, cb, ctx) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "request notify failed") done: - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_request_notify() */ @@ -6342,28 +6639,18 @@ done: herr_t H5VL_request_cancel(const H5VL_object_t *vol_obj, H5VL_request_status_t *status) { - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(vol_obj); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding internal VOL routine */ if (H5VL__request_cancel(vol_obj->data, vol_obj->connector->cls, status) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "request cancel failed") done: - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_request_cancel() */ @@ -6378,13 +6665,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLrequest_cancel(void *req, hid_t connector_id, H5VL_request_status_t *status) +H5VLrequest_cancel(void *req, hid_t connector_id, H5VL_request_status_t *status /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE3("e", "*xi*#", req, connector_id, status); + H5TRACE3("e", "*xix", req, connector_id, status); /* Get class pointer */ if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) @@ -6409,8 +6696,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__request_specific(void *req, const H5VL_class_t *cls, H5VL_request_specific_t specific_type, - va_list arguments) +H5VL__request_specific(void *req, const H5VL_class_t *cls, H5VL_request_specific_args_t *args) { herr_t ret_value = SUCCEED; /* Return value */ @@ -6425,7 +6711,7 @@ H5VL__request_specific(void *req, const H5VL_class_t *cls, H5VL_request_specific HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'async specific' method") /* Call the corresponding VOL callback */ - if ((ret_value = (cls->request_cls.specific)(req, specific_type, arguments)) < 0) + if ((cls->request_cls.specific)(req, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute asynchronous request specific callback") @@ -6444,40 +6730,21 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_request_specific(const H5VL_object_t *vol_obj, H5VL_request_specific_t specific_type, ...) +H5VL_request_specific(const H5VL_object_t *vol_obj, H5VL_request_specific_args_t *args) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(vol_obj); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding internal VOL routine */ - HDva_start(arguments, specific_type); - arg_started = TRUE; - if ((ret_value = - H5VL__request_specific(vol_obj->data, vol_obj->connector->cls, specific_type, arguments)) < 0) + if (H5VL__request_specific(vol_obj->data, vol_obj->connector->cls, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute asynchronous request specific callback") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_request_specific() */ @@ -6492,20 +6759,20 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLrequest_specific(void *req, hid_t connector_id, H5VL_request_specific_t specific_type, va_list arguments) +H5VLrequest_specific(void *req, hid_t connector_id, H5VL_request_specific_args_t *args) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE4("e", "*xiVrx", req, connector_id, specific_type, arguments); + H5TRACE3("e", "*xi*!", req, connector_id, args); /* Get class pointer */ if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if ((ret_value = H5VL__request_specific(req, cls, specific_type, arguments)) < 0) + if (H5VL__request_specific(req, cls, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute asynchronous request specific callback") @@ -6524,8 +6791,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__request_optional(void *req, const H5VL_class_t *cls, H5VL_request_optional_t opt_type, - va_list arguments) +H5VL__request_optional(void *req, const H5VL_class_t *cls, H5VL_optional_args_t *args) { herr_t ret_value = SUCCEED; /* Return value */ @@ -6540,7 +6806,7 @@ H5VL__request_optional(void *req, const H5VL_class_t *cls, H5VL_request_optional HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'async optional' method") /* Call the corresponding VOL callback */ - if ((ret_value = (cls->request_cls.optional)(req, opt_type, arguments)) < 0) + if ((cls->request_cls.optional)(req, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute asynchronous request optional callback") @@ -6559,39 +6825,21 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_request_optional(const H5VL_object_t *vol_obj, H5VL_request_optional_t opt_type, ...) +H5VL_request_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(vol_obj); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding internal VOL routine */ - HDva_start(arguments, opt_type); - arg_started = TRUE; - if ((ret_value = H5VL__request_optional(vol_obj->data, vol_obj->connector->cls, opt_type, arguments)) < 0) + if (H5VL__request_optional(vol_obj->data, vol_obj->connector->cls, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute asynchronous request optional callback") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_request_optional() */ @@ -6606,20 +6854,20 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLrequest_optional(void *req, hid_t connector_id, H5VL_request_optional_t opt_type, va_list arguments) +H5VLrequest_optional(void *req, hid_t connector_id, H5VL_optional_args_t *args) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE4("e", "*xiVzx", req, connector_id, opt_type, arguments); + H5TRACE3("e", "*xi*!", req, connector_id, args); /* Get class pointer */ if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if ((ret_value = H5VL__request_optional(req, cls, opt_type, arguments)) < 0) + if (H5VL__request_optional(req, cls, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute asynchronous request optional callback") @@ -6628,6 +6876,43 @@ done: } /* end H5VLrequest_optional() */ /*------------------------------------------------------------------------- + * Function: H5VLrequest_optional_op + * + * Purpose: Performs an optional connector-specific operation on a request + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLrequest_optional_op(void *req, hid_t connector_id, H5VL_optional_args_t *args) +{ + H5VL_class_t *cls; /* VOL connector's class struct */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "*xi*!", req, connector_id, args); + + /* Check arguments */ + if (NULL == req) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid request") + if (NULL == args) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid arguments") + + /* Get class pointer */ + if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") + + /* Call the corresponding internal VOL routine */ + if (H5VL__request_optional(req, cls, args) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute request optional callback") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLrequest_optional_op() */ + +/*------------------------------------------------------------------------- * Function: H5VL__request_free * * Purpose: Frees an asynchronous request through the VOL @@ -6673,28 +6958,18 @@ done: herr_t H5VL_request_free(const H5VL_object_t *vol_obj) { - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(vol_obj); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding VOL callback */ if (H5VL__request_free(vol_obj->data, vol_obj->connector->cls) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "request free failed") done: - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_request_free() */ @@ -6778,8 +7053,7 @@ done: herr_t H5VL_blob_put(const H5VL_object_t *vol_obj, const void *buf, size_t size, void *blob_id, void *ctx) { - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -6788,19 +7062,11 @@ H5VL_blob_put(const H5VL_object_t *vol_obj, const void *buf, size_t size, void * HDassert(size == 0 || buf); HDassert(blob_id); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding VOL callback */ if (H5VL__blob_put(vol_obj->data, vol_obj->connector->cls, buf, size, blob_id, ctx) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "blob put failed") done: - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_blob_put() */ @@ -6882,8 +7148,7 @@ done: herr_t H5VL_blob_get(const H5VL_object_t *vol_obj, const void *blob_id, void *buf, size_t size, void *ctx) { - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -6892,19 +7157,11 @@ H5VL_blob_get(const H5VL_object_t *vol_obj, const void *blob_id, void *buf, size HDassert(blob_id); HDassert(buf); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding VOL callback */ if (H5VL__blob_get(vol_obj->data, vol_obj->connector->cls, blob_id, buf, size, ctx) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "blob get failed") done: - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_blob_get() */ @@ -6953,8 +7210,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__blob_specific(void *obj, const H5VL_class_t *cls, void *blob_id, H5VL_blob_specific_t specific_type, - va_list arguments) +H5VL__blob_specific(void *obj, const H5VL_class_t *cls, void *blob_id, H5VL_blob_specific_args_t *args) { herr_t ret_value = SUCCEED; /* Return value */ @@ -6970,7 +7226,7 @@ H5VL__blob_specific(void *obj, const H5VL_class_t *cls, void *blob_id, H5VL_blob HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob specific' method") /* Call the corresponding VOL callback */ - if ((cls->blob_cls.specific)(obj, blob_id, specific_type, arguments) < 0) + if ((cls->blob_cls.specific)(obj, blob_id, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute blob specific callback") done: @@ -6988,12 +7244,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_blob_specific(const H5VL_object_t *vol_obj, void *blob_id, H5VL_blob_specific_t specific_type, ...) +H5VL_blob_specific(const H5VL_object_t *vol_obj, void *blob_id, H5VL_blob_specific_args_t *args) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -7001,27 +7254,11 @@ H5VL_blob_specific(const H5VL_object_t *vol_obj, void *blob_id, H5VL_blob_specif HDassert(vol_obj); HDassert(blob_id); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding internal VOL routine */ - HDva_start(arguments, specific_type); - arg_started = TRUE; - if ((ret_value = H5VL__blob_specific(vol_obj->data, vol_obj->connector->cls, blob_id, specific_type, - arguments)) < 0) + if (H5VL__blob_specific(vol_obj->data, vol_obj->connector->cls, blob_id, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute blob specific callback") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_blob_specific() */ @@ -7035,14 +7272,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLblob_specific(void *obj, hid_t connector_id, void *blob_id, H5VL_blob_specific_t specific_type, - va_list arguments) +H5VLblob_specific(void *obj, hid_t connector_id, void *blob_id, H5VL_blob_specific_args_t *args) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE5("e", "*xi*xVBx", obj, connector_id, blob_id, specific_type, arguments); + H5TRACE4("e", "*xi*x*!", obj, connector_id, blob_id, args); /* Get class pointer */ if (NULL == obj) @@ -7051,7 +7287,7 @@ H5VLblob_specific(void *obj, hid_t connector_id, void *blob_id, H5VL_blob_specif HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding VOL callback */ - if (H5VL__blob_specific(obj, cls, blob_id, specific_type, arguments) < 0) + if (H5VL__blob_specific(obj, cls, blob_id, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "blob specific operation failed") done: @@ -7071,8 +7307,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__blob_optional(void *obj, const H5VL_class_t *cls, void *blob_id, H5VL_blob_optional_t opt_type, - va_list arguments) +H5VL__blob_optional(void *obj, const H5VL_class_t *cls, void *blob_id, H5VL_optional_args_t *args) { herr_t ret_value = SUCCEED; /* Return value */ @@ -7088,7 +7323,7 @@ H5VL__blob_optional(void *obj, const H5VL_class_t *cls, void *blob_id, H5VL_blob HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob optional' method") /* Call the corresponding VOL callback */ - if ((cls->blob_cls.optional)(obj, blob_id, opt_type, arguments) < 0) + if ((cls->blob_cls.optional)(obj, blob_id, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute blob optional callback") done: @@ -7106,12 +7341,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_blob_optional(const H5VL_object_t *vol_obj, void *blob_id, H5VL_blob_optional_t opt_type, ...) +H5VL_blob_optional(const H5VL_object_t *vol_obj, void *blob_id, H5VL_optional_args_t *args) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -7119,27 +7351,11 @@ H5VL_blob_optional(const H5VL_object_t *vol_obj, void *blob_id, H5VL_blob_option HDassert(vol_obj); HDassert(blob_id); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding internal VOL routine */ - HDva_start(arguments, opt_type); - arg_started = TRUE; - if ((ret_value = - H5VL__blob_optional(vol_obj->data, vol_obj->connector->cls, blob_id, opt_type, arguments)) < 0) + if (H5VL__blob_optional(vol_obj->data, vol_obj->connector->cls, blob_id, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute blob optional callback") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_blob_optional() */ @@ -7153,14 +7369,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLblob_optional(void *obj, hid_t connector_id, void *blob_id, H5VL_blob_optional_t opt_type, - va_list arguments) +H5VLblob_optional(void *obj, hid_t connector_id, void *blob_id, H5VL_optional_args_t *args) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE5("e", "*xi*xVAx", obj, connector_id, blob_id, opt_type, arguments); + H5TRACE4("e", "*xi*x*!", obj, connector_id, blob_id, args); /* Get class pointer */ if (NULL == obj) @@ -7169,7 +7384,7 @@ H5VLblob_optional(void *obj, hid_t connector_id, void *blob_id, H5VL_blob_option HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding VOL callback */ - if (H5VL__blob_optional(obj, cls, blob_id, opt_type, arguments) < 0) + if (H5VL__blob_optional(obj, cls, blob_id, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "blob optional operation failed") done: @@ -7243,8 +7458,7 @@ herr_t H5VL_token_cmp(const H5VL_object_t *vol_obj, const H5O_token_t *token1, const H5O_token_t *token2, int *cmp_value) { - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -7252,20 +7466,11 @@ H5VL_token_cmp(const H5VL_object_t *vol_obj, const H5O_token_t *token1, const H5 HDassert(vol_obj); HDassert(cmp_value); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding internal VOL routine */ - if ((ret_value = H5VL__token_cmp(vol_obj->data, vol_obj->connector->cls, token1, token2, cmp_value)) < 0) + if (H5VL__token_cmp(vol_obj->data, vol_obj->connector->cls, token1, token2, cmp_value) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTCOMPARE, FAIL, "token compare failed") done: - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_token_cmp() */ @@ -7362,8 +7567,7 @@ herr_t H5VL_token_to_str(const H5VL_object_t *vol_obj, H5I_type_t obj_type, const H5O_token_t *token, char **token_str) { - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -7372,21 +7576,11 @@ H5VL_token_to_str(const H5VL_object_t *vol_obj, H5I_type_t obj_type, const H5O_t HDassert(token); HDassert(token_str); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding internal VOL routine */ - if ((ret_value = H5VL__token_to_str(vol_obj->data, obj_type, vol_obj->connector->cls, token, token_str)) < - 0) + if (H5VL__token_to_str(vol_obj->data, obj_type, vol_obj->connector->cls, token, token_str) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSERIALIZE, FAIL, "token serialization failed") done: - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_token_to_str() */ @@ -7480,8 +7674,7 @@ herr_t H5VL_token_from_str(const H5VL_object_t *vol_obj, H5I_type_t obj_type, const char *token_str, H5O_token_t *token) { - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -7490,21 +7683,11 @@ H5VL_token_from_str(const H5VL_object_t *vol_obj, H5I_type_t obj_type, const cha HDassert(token); HDassert(token_str); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding internal VOL routine */ - if ((ret_value = - H5VL__token_from_str(vol_obj->data, obj_type, vol_obj->connector->cls, token_str, token)) < 0) + if (H5VL__token_from_str(vol_obj->data, obj_type, vol_obj->connector->cls, token_str, token) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTUNSERIALIZE, FAIL, "token deserialization failed") done: - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_token_from_str() */ @@ -7557,7 +7740,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__optional(void *obj, const H5VL_class_t *cls, int op_type, hid_t dxpl_id, void **req, va_list arguments) +H5VL__optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -7568,8 +7751,8 @@ H5VL__optional(void *obj, const H5VL_class_t *cls, int op_type, hid_t dxpl_id, v HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'optional' method") /* Call the corresponding VOL callback */ - if ((ret_value = (cls->optional)(obj, op_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, ret_value, "unable to execute optional callback") + if ((ret_value = (cls->optional)(obj, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute optional callback"); done: FUNC_LEAVE_NOAPI(ret_value) @@ -7586,10 +7769,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_optional(const H5VL_object_t *vol_obj, int op_type, hid_t dxpl_id, void **req, ...) +H5VL_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -7601,20 +7782,13 @@ H5VL_optional(const H5VL_object_t *vol_obj, int op_type, hid_t dxpl_id, void **r vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if ((ret_value = - H5VL__optional(vol_obj->data, vol_obj->connector->cls, op_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute optional callback") + if ((ret_value = H5VL__optional(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute optional callback"); done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, ret_value, "can't reset VOL wrapper info") + HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_optional() */ @@ -7630,13 +7804,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLoptional(void *obj, hid_t connector_id, int op_type, hid_t dxpl_id, void **req /*out*/, va_list arguments) +H5VLoptional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiIsixx", obj, connector_id, op_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -7645,8 +7819,8 @@ H5VLoptional(void *obj, hid_t connector_id, int op_type, hid_t dxpl_id, void **r HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if ((ret_value = H5VL__optional(obj, cls, op_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, ret_value, "unable to execute optional callback") + if ((ret_value = H5VL__optional(obj, cls, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute optional callback"); done: FUNC_LEAVE_API_NOINIT(ret_value) diff --git a/src/H5VLconnector.h b/src/H5VLconnector.h index 63613bc..af3530c 100644 --- a/src/H5VLconnector.h +++ b/src/H5VLconnector.h @@ -20,6 +20,7 @@ /* Public headers needed by this file */ #include "H5public.h" /* Generic Functions */ #include "H5Apublic.h" /* Attributes */ +#include "H5Dpublic.h" /* Datasets */ #include "H5ESpublic.h" /* Event Stack */ #include "H5Fpublic.h" /* Files */ #include "H5Ipublic.h" /* IDs */ @@ -33,8 +34,10 @@ /*****************/ /* Capability flags for connector */ -#define H5VL_CAP_FLAG_NONE 0 /* No special connector capabilities */ -#define H5VL_CAP_FLAG_THREADSAFE 0x01 /* Connector is threadsafe */ +#define H5VL_CAP_FLAG_NONE 0 /* No special connector capabilities */ +#define H5VL_CAP_FLAG_THREADSAFE 0x01 /* Connector is threadsafe */ +#define H5VL_CAP_FLAG_ASYNC 0x02 /* Connector performs operations asynchronously*/ +#define H5VL_CAP_FLAG_NATIVE_FILES 0x04 /* Connector produces native file format */ /* Container info version */ #define H5VL_CONTAINER_INFO_VERSION 0x01 /* Container info struct version */ @@ -42,11 +45,64 @@ /* The maximum size allowed for blobs */ #define H5VL_MAX_BLOB_ID_SIZE (16) /* Allow for 128-bits blob IDs */ +/* # of optional operations reserved for the native VOL connector */ +#define H5VL_RESERVED_NATIVE_OPTIONAL 1024 + /*******************/ /* Public Typedefs */ /*******************/ -/* types for attribute GET callback */ +/* Types for different ways that objects are located in an HDF5 container */ +typedef enum H5VL_loc_type_t { + H5VL_OBJECT_BY_SELF, + H5VL_OBJECT_BY_NAME, + H5VL_OBJECT_BY_IDX, + H5VL_OBJECT_BY_TOKEN +} H5VL_loc_type_t; + +typedef struct H5VL_loc_by_name { + const char *name; + hid_t lapl_id; +} H5VL_loc_by_name_t; + +typedef struct H5VL_loc_by_idx { + const char * name; + H5_index_t idx_type; + H5_iter_order_t order; + hsize_t n; + hid_t lapl_id; +} H5VL_loc_by_idx_t; + +typedef struct H5VL_loc_by_token { + H5O_token_t *token; +} H5VL_loc_by_token_t; + +/* Structure to hold parameters for object locations. + * Either: BY_SELF, BY_NAME, BY_IDX, BY_TOKEN + * + * Note: Leave loc_by_token as the first union member so we + * can perform the simplest initialization of the struct + * without raising warnings. + * + * Note: BY_SELF requires no union members. + */ +typedef struct H5VL_loc_params_t { + H5I_type_t obj_type; + H5VL_loc_type_t type; + union { + H5VL_loc_by_token_t loc_by_token; + H5VL_loc_by_name_t loc_by_name; + H5VL_loc_by_idx_t loc_by_idx; + } loc_data; +} H5VL_loc_params_t; + +/* Struct for all 'optional' callbacks */ +typedef struct H5VL_optional_args_t { + int op_type; /* Operation to perform */ + void *args; /* Pointer to operation's argument struct */ +} H5VL_optional_args_t; + +/* Values for attribute 'get' operations */ typedef enum H5VL_attr_get_t { H5VL_ATTR_GET_ACPL, /* creation property list */ H5VL_ATTR_GET_INFO, /* info */ @@ -56,18 +112,115 @@ typedef enum H5VL_attr_get_t { H5VL_ATTR_GET_TYPE /* datatype */ } H5VL_attr_get_t; -/* types for attribute SPECFIC callback */ +/* Parameters for attribute 'get_name' operation */ +typedef struct H5VL_attr_get_name_args_t { + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + size_t buf_size; /* Size of attribute name buffer */ + char * buf; /* Buffer for attribute name (OUT) */ + size_t * attr_name_len; /* Actual length of attribute name (OUT) */ +} H5VL_attr_get_name_args_t; + +/* Parameters for attribute 'get_info' operation */ +typedef struct H5VL_attr_get_info_args_t { + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + const char * attr_name; /* Attribute name (for get_info_by_name) */ + H5A_info_t * ainfo; /* Attribute info (OUT) */ +} H5VL_attr_get_info_args_t; + +/* Parameters for attribute 'get' operations */ +typedef struct H5VL_attr_get_args_t { + H5VL_attr_get_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_ATTR_GET_ACPL */ + struct { + hid_t acpl_id; /* Attribute creation property list ID (OUT) */ + } get_acpl; + + /* H5VL_ATTR_GET_INFO */ + H5VL_attr_get_info_args_t get_info; /* Attribute info */ + + /* H5VL_ATTR_GET_NAME */ + H5VL_attr_get_name_args_t get_name; /* Attribute name */ + + /* H5VL_ATTR_GET_SPACE */ + struct { + hid_t space_id; /* Dataspace ID (OUT) */ + } get_space; + + /* H5VL_ATTR_GET_STORAGE_SIZE */ + struct { + hsize_t *data_size; /* Size of attribute in file (OUT) */ + } get_storage_size; + + /* H5VL_ATTR_GET_TYPE */ + struct { + hid_t type_id; /* Datatype ID (OUT) */ + } get_type; + } args; +} H5VL_attr_get_args_t; + +/* Values for attribute 'specific' operation */ typedef enum H5VL_attr_specific_t { - H5VL_ATTR_DELETE, /* H5Adelete(_by_name/idx) */ - H5VL_ATTR_EXISTS, /* H5Aexists(_by_name) */ - H5VL_ATTR_ITER, /* H5Aiterate(_by_name) */ - H5VL_ATTR_RENAME /* H5Arename(_by_name) */ + H5VL_ATTR_DELETE, /* H5Adelete(_by_name) */ + H5VL_ATTR_DELETE_BY_IDX, /* H5Adelete_by_idx */ + H5VL_ATTR_EXISTS, /* H5Aexists(_by_name) */ + H5VL_ATTR_ITER, /* H5Aiterate(_by_name) */ + H5VL_ATTR_RENAME /* H5Arename(_by_name) */ } H5VL_attr_specific_t; +/* Parameters for attribute 'iterate' operation */ +typedef struct H5VL_attr_iterate_args_t { + H5_index_t idx_type; /* Type of index to iterate over */ + H5_iter_order_t order; /* Order of index iteration */ + hsize_t * idx; /* Start/stop iteration index (IN/OUT) */ + H5A_operator2_t op; /* Iteration callback function */ + void * op_data; /* Iteration callback context */ +} H5VL_attr_iterate_args_t; + +/* Parameters for attribute 'delete_by_idx' operation */ +typedef struct H5VL_attr_delete_by_idx_args_t { + H5_index_t idx_type; /* Type of index to iterate over */ + H5_iter_order_t order; /* Order of index iteration */ + hsize_t n; /* Iteration index */ +} H5VL_attr_delete_by_idx_args_t; + +/* Parameters for attribute 'specific' operations */ +typedef struct H5VL_attr_specific_args_t { + H5VL_attr_specific_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_ATTR_DELETE */ + struct { + const char *name; /* Name of attribute to delete */ + } del; + + /* H5VL_ATTR_DELETE_BY_IDX */ + H5VL_attr_delete_by_idx_args_t delete_by_idx; + + /* H5VL_ATTR_EXISTS */ + struct { + const char *name; /* Name of attribute to check */ + hbool_t * exists; /* Whether attribute exists (OUT) */ + } exists; + + /* H5VL_ATTR_ITER */ + H5VL_attr_iterate_args_t iterate; + + /* H5VL_ATTR_RENAME */ + struct { + const char *old_name; /* Name of attribute to rename */ + const char *new_name; /* New attribute name */ + } rename; + } args; +} H5VL_attr_specific_args_t; + /* Typedef for VOL connector attribute optional VOL operations */ typedef int H5VL_attr_optional_t; -/* types for dataset GET callback */ +/* Values for dataset 'get' operation */ typedef enum H5VL_dataset_get_t { H5VL_DATASET_GET_DAPL, /* access property list */ H5VL_DATASET_GET_DCPL, /* creation property list */ @@ -77,32 +230,146 @@ typedef enum H5VL_dataset_get_t { H5VL_DATASET_GET_TYPE /* datatype */ } H5VL_dataset_get_t; -/* types for dataset SPECFIC callback */ +/* Parameters for dataset 'get' operations */ +typedef struct H5VL_dataset_get_args_t { + H5VL_dataset_get_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_DATASET_GET_DAPL */ + struct { + hid_t dapl_id; /* Dataset access property list ID (OUT) */ + } get_dapl; + + /* H5VL_DATASET_GET_DCPL */ + struct { + hid_t dcpl_id; /* Dataset creation property list ID (OUT) */ + } get_dcpl; + + /* H5VL_DATASET_GET_SPACE */ + struct { + hid_t space_id; /* Dataspace ID (OUT) */ + } get_space; + + /* H5VL_DATASET_GET_SPACE_STATUS */ + struct { + H5D_space_status_t *status; /* Storage space allocation status (OUT) */ + } get_space_status; + + /* H5VL_DATASET_GET_STORAGE_SIZE */ + struct { + hsize_t *storage_size; /* Size of dataset's storage (OUT) */ + } get_storage_size; + + /* H5VL_DATASET_GET_TYPE */ + struct { + hid_t type_id; /* Datatype ID (OUT) */ + } get_type; + } args; +} H5VL_dataset_get_args_t; + +/* Values for dataset 'specific' operation */ typedef enum H5VL_dataset_specific_t { H5VL_DATASET_SET_EXTENT, /* H5Dset_extent */ H5VL_DATASET_FLUSH, /* H5Dflush */ - H5VL_DATASET_REFRESH, /* H5Drefresh */ - H5VL_DATASET_WAIT, /* H5Dwait */ - H5VL_DATASET_CHUNK_ITER /* H5Dchunk_iter */ + H5VL_DATASET_REFRESH /* H5Drefresh */ } H5VL_dataset_specific_t; +/* Parameters for dataset 'specific' operations */ +typedef struct H5VL_dataset_specific_args_t { + H5VL_dataset_specific_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_DATASET_SET_EXTENT */ + struct { + const hsize_t *size; /* New dataspace extent */ + } set_extent; + + /* H5VL_DATASET_FLUSH */ + struct { + hid_t dset_id; /* Dataset ID (IN) */ + } flush; + + /* H5VL_DATASET_REFRESH */ + struct { + hid_t dset_id; /* Dataset ID (IN) */ + } refresh; + } args; +} H5VL_dataset_specific_args_t; + /* Typedef for VOL connector dataset optional VOL operations */ typedef int H5VL_dataset_optional_t; -/* types for datatype GET callback */ +/* Values for datatype 'get' operation */ typedef enum H5VL_datatype_get_t { - H5VL_DATATYPE_GET_BINARY, /* get serialized form of transient type */ - H5VL_DATATYPE_GET_TCPL /* datatype creation property list */ + H5VL_DATATYPE_GET_BINARY_SIZE, /* Get size of serialized form of transient type */ + H5VL_DATATYPE_GET_BINARY, /* Get serialized form of transient type */ + H5VL_DATATYPE_GET_TCPL /* Datatype creation property list */ } H5VL_datatype_get_t; -/* types for datatype SPECFIC callback */ -typedef enum H5VL_datatype_specific_t { H5VL_DATATYPE_FLUSH, H5VL_DATATYPE_REFRESH } H5VL_datatype_specific_t; +/* Parameters for datatype 'get' operations */ +typedef struct H5VL_datatype_get_args_t { + H5VL_datatype_get_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_DATATYPE_GET_BINARY_SIZE */ + struct { + size_t *size; /* Size of serialized form of datatype (OUT) */ + } get_binary_size; + + /* H5VL_DATATYPE_GET_BINARY */ + struct { + void * buf; /* Buffer to store serialized form of datatype (OUT) */ + size_t buf_size; /* Size of serialized datatype buffer */ + } get_binary; + + /* H5VL_DATATYPE_GET_TCPL */ + struct { + hid_t tcpl_id; /* Named datatype creation property list ID (OUT) */ + } get_tcpl; + } args; +} H5VL_datatype_get_args_t; + +/* Values for datatype 'specific' operation */ +typedef enum H5VL_datatype_specific_t { + H5VL_DATATYPE_FLUSH, /* H5Tflush */ + H5VL_DATATYPE_REFRESH /* H5Trefresh */ +} H5VL_datatype_specific_t; + +/* Parameters for datatype 'specific' operations */ +typedef struct H5VL_datatype_specific_args_t { + H5VL_datatype_specific_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_DATATYPE_FLUSH */ + struct { + hid_t type_id; /* Named datatype ID (IN) */ + } flush; + + /* H5VL_DATATYPE_REFRESH */ + struct { + hid_t type_id; /* Named datatype ID (IN) */ + } refresh; + } args; +} H5VL_datatype_specific_args_t; /* Typedef and values for native VOL connector named datatype optional VOL operations */ typedef int H5VL_datatype_optional_t; /* (No optional named datatype VOL operations currently) */ -/* types for file GET callback */ +/* Info for H5VL_FILE_GET_CONT_INFO */ +typedef struct H5VL_file_cont_info_t { + unsigned version; /* version information (keep first) */ + uint64_t feature_flags; /* Container feature flags */ + /* (none currently defined) */ + size_t token_size; /* Size of tokens */ + size_t blob_id_size; /* Size of blob IDs */ +} H5VL_file_cont_info_t; + +/* Values for file 'get' operation */ typedef enum H5VL_file_get_t { H5VL_FILE_GET_CONT_INFO, /* file get container info */ H5VL_FILE_GET_FAPL, /* file access property list */ @@ -114,59 +381,296 @@ typedef enum H5VL_file_get_t { H5VL_FILE_GET_OBJ_IDS /* object ids in file */ } H5VL_file_get_t; -/* types for file SPECIFIC callback */ +/* Parameters for file 'get_name' operation */ +typedef struct H5VL_file_get_name_args_t { + H5I_type_t type; /* ID type of object pointer */ + size_t buf_size; /* Size of file name buffer (IN) */ + char * buf; /* Buffer for file name (OUT) */ + size_t * file_name_len; /* Actual length of file name (OUT) */ +} H5VL_file_get_name_args_t; + +/* Parameters for file 'get_obj_ids' operation */ +typedef struct H5VL_file_get_obj_ids_args_t { + unsigned types; /* Type of objects to count */ + size_t max_objs; /* Size of array of object IDs */ + hid_t * oid_list; /* Array of object IDs (OUT) */ + size_t * count; /* # of objects (OUT) */ +} H5VL_file_get_obj_ids_args_t; + +/* Parameters for file 'get' operations */ +typedef struct H5VL_file_get_args_t { + H5VL_file_get_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_FILE_GET_CONT_INFO */ + struct { + H5VL_file_cont_info_t *info; /* Container info (OUT) */ + } get_cont_info; + + /* H5VL_FILE_GET_FAPL */ + struct { + hid_t fapl_id; /* File access property list (OUT) */ + } get_fapl; + + /* H5VL_FILE_GET_FCPL */ + struct { + hid_t fcpl_id; /* File creation property list (OUT) */ + } get_fcpl; + + /* H5VL_FILE_GET_FILENO */ + struct { + unsigned long *fileno; /* File "number" (OUT) */ + } get_fileno; + + /* H5VL_FILE_GET_INTENT */ + struct { + unsigned *flags; /* File open/create intent flags (OUT) */ + } get_intent; + + /* H5VL_FILE_GET_NAME */ + H5VL_file_get_name_args_t get_name; + + /* H5VL_FILE_GET_OBJ_COUNT */ + struct { + unsigned types; /* Type of objects to count */ + size_t * count; /* # of objects (OUT) */ + } get_obj_count; + + /* H5VL_FILE_GET_OBJ_IDS */ + H5VL_file_get_obj_ids_args_t get_obj_ids; + } args; +} H5VL_file_get_args_t; + +/* Values for file 'specific' operation */ typedef enum H5VL_file_specific_t { H5VL_FILE_FLUSH, /* Flush file */ H5VL_FILE_REOPEN, /* Reopen the file */ - H5VL_FILE_MOUNT, /* Mount a file */ - H5VL_FILE_UNMOUNT, /* Unmount a file */ H5VL_FILE_IS_ACCESSIBLE, /* Check if a file is accessible */ H5VL_FILE_DELETE, /* Delete a file */ - H5VL_FILE_IS_EQUAL, /* Check if two files are the same */ - H5VL_FILE_WAIT /* Wait for async operations to complete */ + H5VL_FILE_IS_EQUAL /* Check if two files are the same */ } H5VL_file_specific_t; +/* Parameters for file 'specific' operations */ +typedef struct H5VL_file_specific_args_t { + H5VL_file_specific_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_FILE_FLUSH */ + struct { + H5I_type_t obj_type; /* Type of object to use */ + H5F_scope_t scope; /* Scope of flush operation */ + } flush; + + /* H5VL_FILE_REOPEN */ + struct { + void **file; /* File object for new file (OUT) */ + } reopen; + + /* H5VL_FILE_IS_ACCESSIBLE */ + struct { + const char *filename; /* Name of file to check */ + hid_t fapl_id; /* File access property list to use */ + hbool_t * accessible; /* Whether file is accessible with FAPL settings (OUT) */ + } is_accessible; + + /* H5VL_FILE_DELETE */ + struct { + const char *filename; /* Name of file to delete */ + hid_t fapl_id; /* File access property list to use */ + } del; + + /* H5VL_FILE_IS_EQUAL */ + struct { + void * obj2; /* Second file object to compare against */ + hbool_t *same_file; /* Whether files are the same (OUT) */ + } is_equal; + } args; +} H5VL_file_specific_args_t; + /* Typedef for VOL connector file optional VOL operations */ typedef int H5VL_file_optional_t; -/* types for group GET callback */ +/* Values for group 'get' operation */ typedef enum H5VL_group_get_t { H5VL_GROUP_GET_GCPL, /* group creation property list */ H5VL_GROUP_GET_INFO /* group info */ } H5VL_group_get_t; -/* types for group SPECFIC callback */ -typedef enum H5VL_group_specific_t { H5VL_GROUP_FLUSH, H5VL_GROUP_REFRESH } H5VL_group_specific_t; +/* Parameters for group 'get_info' operation */ +typedef struct H5VL_group_get_info_args_t { + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5G_info_t * ginfo; /* Group info (OUT) */ +} H5VL_group_get_info_args_t; + +/* Parameters for group 'get' operations */ +typedef struct H5VL_group_get_args_t { + H5VL_group_get_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_GROUP_GET_GCPL */ + struct { + hid_t gcpl_id; /* Group creation property list (OUT) */ + } get_gcpl; + + /* H5VL_GROUP_GET_INFO */ + H5VL_group_get_info_args_t get_info; /* Group info */ + } args; +} H5VL_group_get_args_t; + +/* Values for group 'specific' operation */ +typedef enum H5VL_group_specific_t { + H5VL_GROUP_MOUNT, /* Mount a file on a group */ + H5VL_GROUP_UNMOUNT, /* Unmount a file on a group */ + H5VL_GROUP_FLUSH, /* H5Gflush */ + H5VL_GROUP_REFRESH /* H5Grefresh */ +} H5VL_group_specific_t; + +/* Parameters for group 'mount' operation */ +typedef struct H5VL_group_spec_mount_args_t { + const char *name; /* Name of location to mount child file */ + void * child_file; /* Pointer to child file object */ + hid_t fmpl_id; /* File mount property list to use */ +} H5VL_group_spec_mount_args_t; + +/* Parameters for group 'specific' operations */ +typedef struct H5VL_group_specific_args_t { + H5VL_group_specific_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_GROUP_MOUNT */ + H5VL_group_spec_mount_args_t mount; + + /* H5VL_GROUP_UNMOUNT */ + struct { + const char *name; /* Name of location to unmount child file */ + } unmount; + + /* H5VL_GROUP_FLUSH */ + struct { + hid_t grp_id; /* Group ID (IN) */ + } flush; + + /* H5VL_GROUP_REFRESH */ + struct { + hid_t grp_id; /* Group ID (IN) */ + } refresh; + } args; +} H5VL_group_specific_args_t; /* Typedef for VOL connector group optional VOL operations */ typedef int H5VL_group_optional_t; -/* link create types for VOL */ -typedef enum H5VL_link_create_type_t { +/* Link create types for VOL */ +typedef enum H5VL_link_create_t { H5VL_LINK_CREATE_HARD, H5VL_LINK_CREATE_SOFT, H5VL_LINK_CREATE_UD -} H5VL_link_create_type_t; +} H5VL_link_create_t; -/* types for link GET callback */ +/* Parameters for link 'create' operations */ +typedef struct H5VL_link_create_args_t { + H5VL_link_create_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_LINK_CREATE_HARD */ + struct { + void * curr_obj; /* Current object */ + H5VL_loc_params_t curr_loc_params; /* Location parameters for current object */ + } hard; + + /* H5VL_LINK_CREATE_SOFT */ + struct { + const char *target; /* Target of soft link */ + } soft; + + /* H5VL_LINK_CREATE_UD */ + struct { + H5L_type_t type; /* Type of link to create */ + const void *buf; /* Buffer that contains link info */ + size_t buf_size; /* Size of link info buffer */ + } ud; + } args; +} H5VL_link_create_args_t; + +/* Values for link 'get' operation */ typedef enum H5VL_link_get_t { H5VL_LINK_GET_INFO, /* link info */ H5VL_LINK_GET_NAME, /* link name */ H5VL_LINK_GET_VAL /* link value */ } H5VL_link_get_t; -/* types for link SPECIFIC callback */ +/* Parameters for link 'get' operations */ +typedef struct H5VL_link_get_args_t { + H5VL_link_get_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_LINK_GET_INFO */ + struct { + H5L_info2_t *linfo; /* Pointer to link's info (OUT) */ + } get_info; + + /* H5VL_LINK_GET_NAME */ + struct { + size_t name_size; /* Size of link name buffer (IN) */ + char * name; /* Buffer for link name (OUT) */ + size_t *name_len; /* Actual length of link name (OUT) */ + } get_name; + + /* H5VL_LINK_GET_VAL */ + struct { + size_t buf_size; /* Size of link value buffer (IN) */ + void * buf; /* Buffer for link value (OUT) */ + } get_val; + } args; +} H5VL_link_get_args_t; + +/* Values for link 'specific' operation */ typedef enum H5VL_link_specific_t { H5VL_LINK_DELETE, /* H5Ldelete(_by_idx) */ H5VL_LINK_EXISTS, /* link existence */ H5VL_LINK_ITER /* H5Literate/visit(_by_name) */ } H5VL_link_specific_t; +/* Parameters for link 'iterate' operation */ +typedef struct H5VL_link_iterate_args_t { + hbool_t recursive; /* Whether iteration is recursive */ + H5_index_t idx_type; /* Type of index to iterate over */ + H5_iter_order_t order; /* Order of index iteration */ + hsize_t * idx_p; /* Start/stop iteration index (OUT) */ + H5L_iterate2_t op; /* Iteration callback function */ + void * op_data; /* Iteration callback context */ +} H5VL_link_iterate_args_t; + +/* Parameters for link 'specific' operations */ +typedef struct H5VL_link_specific_args_t { + H5VL_link_specific_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_LINK_DELETE */ + /* No args */ + + /* H5VL_LINK_EXISTS */ + struct { + hbool_t *exists; /* Whether link exists (OUT) */ + } exists; + + /* H5VL_LINK_ITER */ + H5VL_link_iterate_args_t iterate; + } args; +} H5VL_link_specific_args_t; + /* Typedef and values for native VOL connector link optional VOL operations */ typedef int H5VL_link_optional_t; /* (No optional link VOL operations currently) */ -/* types for object GET callback */ +/* Values for object 'get' operation */ typedef enum H5VL_object_get_t { H5VL_OBJECT_GET_FILE, /* object file */ H5VL_OBJECT_GET_NAME, /* object name */ @@ -174,7 +678,38 @@ typedef enum H5VL_object_get_t { H5VL_OBJECT_GET_INFO /* H5Oget_info(_by_idx|name) */ } H5VL_object_get_t; -/* types for object SPECIFIC callback */ +/* Parameters for object 'get' operations */ +typedef struct H5VL_object_get_args_t { + H5VL_object_get_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_OBJECT_GET_FILE */ + struct { + void **file; /* File object (OUT) */ + } get_file; + + /* H5VL_OBJECT_GET_NAME */ + struct { + size_t buf_size; /* Size of name buffer (IN) */ + char * buf; /* Buffer for name (OUT) */ + size_t *name_len; /* Actual length of name (OUT) */ + } get_name; + + /* H5VL_OBJECT_GET_TYPE */ + struct { + H5O_type_t *obj_type; /* Type of object (OUT) */ + } get_type; + + /* H5VL_OBJECT_GET_INFO */ + struct { + unsigned fields; /* Flags for fields to retrieve */ + H5O_info2_t *oinfo; /* Pointer to object info (OUT) */ + } get_info; + } args; +} H5VL_object_get_args_t; + +/* Values for object 'specific' operation */ typedef enum H5VL_object_specific_t { H5VL_OBJECT_CHANGE_REF_COUNT, /* H5Oincr/decr_refcount */ H5VL_OBJECT_EXISTS, /* H5Oexists_by_name */ @@ -184,6 +719,51 @@ typedef enum H5VL_object_specific_t { H5VL_OBJECT_REFRESH /* H5{D|G|O|T}refresh */ } H5VL_object_specific_t; +/* Parameters for object 'visit' operation */ +typedef struct H5VL_object_visit_args_t { + H5_index_t idx_type; /* Type of index to iterate over */ + H5_iter_order_t order; /* Order of index iteration */ + unsigned fields; /* Flags for fields to provide in 'info' object for 'op' callback */ + H5O_iterate2_t op; /* Iteration callback function */ + void * op_data; /* Iteration callback context */ +} H5VL_object_visit_args_t; + +/* Parameters for object 'specific' operations */ +typedef struct H5VL_object_specific_args_t { + H5VL_object_specific_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_OBJECT_CHANGE_REF_COUNT */ + struct { + int delta; /* Amount to modify object's refcount */ + } change_rc; + + /* H5VL_OBJECT_EXISTS */ + struct { + hbool_t *exists; /* Whether object exists (OUT) */ + } exists; + + /* H5VL_OBJECT_LOOKUP */ + struct { + H5O_token_t *token_ptr; /* Pointer to token for lookup (OUT) */ + } lookup; + + /* H5VL_OBJECT_VISIT */ + H5VL_object_visit_args_t visit; + + /* H5VL_OBJECT_FLUSH */ + struct { + hid_t obj_id; /* Object ID (IN) */ + } flush; + + /* H5VL_OBJECT_REFRESH */ + struct { + hid_t obj_id; /* Object ID (IN) */ + } refresh; + } args; +} H5VL_object_specific_args_t; + /* Typedef for VOL connector object optional VOL operations */ typedef int H5VL_object_optional_t; @@ -200,82 +780,64 @@ typedef enum H5VL_request_status_t { H5VL_REQUEST_STATUS_CANCELED /* Operation has not completed and was canceled */ } H5VL_request_status_t; -/* types for async request SPECIFIC callback */ +/* Values for async request 'specific' operation */ typedef enum H5VL_request_specific_t { - H5VL_REQUEST_WAITANY, /* Wait until any request completes */ - H5VL_REQUEST_WAITSOME, /* Wait until at least one requesst completes */ - H5VL_REQUEST_WAITALL, /* Wait until all requests complete */ - H5VL_REQUEST_GET_ERR_STACK /* Retrieve error stack for failed operation */ + H5VL_REQUEST_GET_ERR_STACK, /* Retrieve error stack for failed operation */ + H5VL_REQUEST_GET_EXEC_TIME /* Retrieve execution time for operation */ } H5VL_request_specific_t; +/* Parameters for request 'specific' operations */ +typedef struct H5VL_request_specific_args_t { + H5VL_request_specific_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_REQUEST_GET_ERR_STACK */ + struct { + hid_t err_stack_id; /* Error stack ID for operation (OUT) */ + } get_err_stack; + + /* H5VL_REQUEST_GET_EXEC_TIME */ + struct { + uint64_t *exec_ts; /* Timestamp for start of task execution (OUT) */ + uint64_t *exec_time; /* Duration of task execution (in ns) (OUT) */ + } get_exec_time; + } args; +} H5VL_request_specific_args_t; + /* Typedef and values for native VOL connector request optional VOL operations */ typedef int H5VL_request_optional_t; /* (No optional request VOL operations currently) */ -/* types for 'blob' SPECIFIC callback */ +/* Values for 'blob' 'specific' operation */ typedef enum H5VL_blob_specific_t { - H5VL_BLOB_DELETE, /* Delete a blob (by ID) */ - H5VL_BLOB_GETSIZE, /* Get size of blob */ - H5VL_BLOB_ISNULL, /* Check if a blob ID is "null" */ - H5VL_BLOB_SETNULL /* Set a blob ID to the connector's "null" blob ID value */ + H5VL_BLOB_DELETE, /* Delete a blob (by ID) */ + H5VL_BLOB_ISNULL, /* Check if a blob ID is "null" */ + H5VL_BLOB_SETNULL /* Set a blob ID to the connector's "null" blob ID value */ } H5VL_blob_specific_t; -/* Typedef and values for native VOL connector blob optional VOL operations */ -typedef int H5VL_blob_optional_t; -/* (No optional blob VOL operations currently) */ - -/* Types for different ways that objects are located in an HDF5 container */ -typedef enum H5VL_loc_type_t { - H5VL_OBJECT_BY_SELF, - H5VL_OBJECT_BY_NAME, - H5VL_OBJECT_BY_IDX, - H5VL_OBJECT_BY_TOKEN -} H5VL_loc_type_t; +/* Parameters for blob 'specific' operations */ +typedef struct H5VL_blob_specific_args_t { + H5VL_blob_specific_t op_type; /* Operation to perform */ -typedef struct H5VL_loc_by_name { - const char *name; - hid_t lapl_id; -} H5VL_loc_by_name_t; - -typedef struct H5VL_loc_by_idx { - const char * name; - H5_index_t idx_type; - H5_iter_order_t order; - hsize_t n; - hid_t lapl_id; -} H5VL_loc_by_idx_t; + /* Parameters for each operation */ + union { + /* H5VL_BLOB_DELETE */ + /* No args */ -typedef struct H5VL_loc_by_token { - H5O_token_t *token; -} H5VL_loc_by_token_t; + /* H5VL_BLOB_ISNULL */ + struct { + hbool_t *isnull; /* Whether blob ID is "null" (OUT) */ + } is_null; -/* Structure to hold parameters for object locations. - * Either: BY_SELF, BY_NAME, BY_IDX, BY_TOKEN - * - * Note: Leave loc_by_token as the first union member so we - * can perform the simplest initialization of the struct - * without raising warnings. - * - * Note: BY_SELF requires no union members. - */ -typedef struct H5VL_loc_params_t { - H5I_type_t obj_type; - H5VL_loc_type_t type; - union { - H5VL_loc_by_token_t loc_by_token; - H5VL_loc_by_name_t loc_by_name; - H5VL_loc_by_idx_t loc_by_idx; - } loc_data; -} H5VL_loc_params_t; + /* H5VL_BLOB_SETNULL */ + /* No args */ + } args; +} H5VL_blob_specific_args_t; -/* Info for H5VL_FILE_GET_CONT_INFO */ -typedef struct H5VL_file_cont_info_t { - unsigned version; /* version information (keep first) */ - uint64_t feature_flags; /* Container feature flags */ - /* (none currently defined) */ - size_t token_size; /* Size of tokens */ - size_t blob_id_size; /* Size of blob IDs */ -} H5VL_file_cont_info_t; +/* Typedef and values for native VOL connector blob optional VOL operations */ +typedef int H5VL_blob_optional_t; +/* (No optional blob VOL operations currently) */ /* VOL connector info fields & callbacks */ typedef struct H5VL_info_class_t { @@ -310,11 +872,10 @@ typedef struct H5VL_attr_class_t { hid_t dxpl_id, void **req); herr_t (*read)(void *attr, hid_t mem_type_id, void *buf, hid_t dxpl_id, void **req); herr_t (*write)(void *attr, hid_t mem_type_id, const void *buf, hid_t dxpl_id, void **req); - herr_t (*get)(void *obj, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); - herr_t (*specific)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_attr_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments); - herr_t (*optional)(void *obj, H5VL_attr_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments); + herr_t (*get)(void *obj, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req); + herr_t (*specific)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_attr_specific_args_t *args, + hid_t dxpl_id, void **req); + herr_t (*optional)(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req); herr_t (*close)(void *attr, hid_t dxpl_id, void **req); } H5VL_attr_class_t; @@ -328,11 +889,9 @@ typedef struct H5VL_dataset_class_t { void *buf, void **req); herr_t (*write)(void *dset, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, const void *buf, void **req); - herr_t (*get)(void *obj, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); - herr_t (*specific)(void *obj, H5VL_dataset_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); - herr_t (*optional)(void *obj, H5VL_dataset_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments); + herr_t (*get)(void *obj, H5VL_dataset_get_args_t *args, hid_t dxpl_id, void **req); + herr_t (*specific)(void *obj, H5VL_dataset_specific_args_t *args, hid_t dxpl_id, void **req); + herr_t (*optional)(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req); herr_t (*close)(void *dset, hid_t dxpl_id, void **req); } H5VL_dataset_class_t; @@ -342,11 +901,9 @@ typedef struct H5VL_datatype_class_t { hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t dxpl_id, void **req); void *(*open)(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t tapl_id, hid_t dxpl_id, void **req); - herr_t (*get)(void *obj, H5VL_datatype_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); - herr_t (*specific)(void *obj, H5VL_datatype_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); - herr_t (*optional)(void *obj, H5VL_datatype_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments); + herr_t (*get)(void *obj, H5VL_datatype_get_args_t *args, hid_t dxpl_id, void **req); + herr_t (*specific)(void *obj, H5VL_datatype_specific_args_t *args, hid_t dxpl_id, void **req); + herr_t (*optional)(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req); herr_t (*close)(void *dt, hid_t dxpl_id, void **req); } H5VL_datatype_class_t; @@ -355,11 +912,9 @@ typedef struct H5VL_file_class_t { void *(*create)(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id, void **req); void *(*open)(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req); - herr_t (*get)(void *obj, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); - herr_t (*specific)(void *obj, H5VL_file_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); - herr_t (*optional)(void *obj, H5VL_file_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments); + herr_t (*get)(void *obj, H5VL_file_get_args_t *args, hid_t dxpl_id, void **req); + herr_t (*specific)(void *obj, H5VL_file_specific_args_t *args, hid_t dxpl_id, void **req); + herr_t (*optional)(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req); herr_t (*close)(void *file, hid_t dxpl_id, void **req); } H5VL_file_class_t; @@ -369,30 +924,28 @@ typedef struct H5VL_group_class_t { hid_t gcpl_id, hid_t gapl_id, hid_t dxpl_id, void **req); void *(*open)(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t gapl_id, hid_t dxpl_id, void **req); - herr_t (*get)(void *obj, H5VL_group_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); - herr_t (*specific)(void *obj, H5VL_group_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); - herr_t (*optional)(void *obj, H5VL_group_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments); + herr_t (*get)(void *obj, H5VL_group_get_args_t *args, hid_t dxpl_id, void **req); + herr_t (*specific)(void *obj, H5VL_group_specific_args_t *args, hid_t dxpl_id, void **req); + herr_t (*optional)(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req); herr_t (*close)(void *grp, hid_t dxpl_id, void **req); } H5VL_group_class_t; /* H5L routines */ typedef struct H5VL_link_class_t { - herr_t (*create)(H5VL_link_create_type_t create_type, void *obj, const H5VL_loc_params_t *loc_params, - hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req, va_list arguments); + herr_t (*create)(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t *loc_params, + hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); herr_t (*copy)(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); herr_t (*move)(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); - herr_t (*get)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments); - herr_t (*specific)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments); - herr_t (*optional)(void *obj, H5VL_link_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments); + herr_t (*get)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_args_t *args, hid_t dxpl_id, + void **req); + herr_t (*specific)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_specific_args_t *args, + hid_t dxpl_id, void **req); + herr_t (*optional)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_optional_args_t *args, + hid_t dxpl_id, void **req); } H5VL_link_class_t; /* H5O routines */ @@ -402,12 +955,12 @@ typedef struct H5VL_object_class_t { herr_t (*copy)(void *src_obj, const H5VL_loc_params_t *loc_params1, const char *src_name, void *dst_obj, const H5VL_loc_params_t *loc_params2, const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req); - herr_t (*get)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments); - herr_t (*specific)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments); - herr_t (*optional)(void *obj, H5VL_object_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments); + herr_t (*get)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_args_t *args, hid_t dxpl_id, + void **req); + herr_t (*specific)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_specific_args_t *args, + hid_t dxpl_id, void **req); + herr_t (*optional)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_optional_args_t *args, + hid_t dxpl_id, void **req); } H5VL_object_class_t; /* Asynchronous request 'notify' callback */ @@ -427,6 +980,7 @@ struct H5VL_class_t; /* Container/connector introspection routines */ typedef struct H5VL_introspect_class_t { herr_t (*get_conn_cls)(void *obj, H5VL_get_conn_lvl_t lvl, const struct H5VL_class_t **conn_cls); + herr_t (*get_cap_flags)(const void *info, unsigned *cap_flags); herr_t (*opt_query)(void *obj, H5VL_subclass_t cls, int opt_type, uint64_t *flags); } H5VL_introspect_class_t; @@ -435,8 +989,8 @@ typedef struct H5VL_request_class_t { herr_t (*wait)(void *req, uint64_t timeout, H5VL_request_status_t *status); herr_t (*notify)(void *req, H5VL_request_notify_t cb, void *ctx); herr_t (*cancel)(void *req, H5VL_request_status_t *status); - herr_t (*specific)(void *req, H5VL_request_specific_t specific_type, va_list arguments); - herr_t (*optional)(void *req, H5VL_request_optional_t opt_type, va_list arguments); + herr_t (*specific)(void *req, H5VL_request_specific_args_t *args); + herr_t (*optional)(void *req, H5VL_optional_args_t *args); herr_t (*free)(void *req); } H5VL_request_class_t; @@ -444,8 +998,8 @@ typedef struct H5VL_request_class_t { typedef struct H5VL_blob_class_t { herr_t (*put)(void *obj, const void *buf, size_t size, void *blob_id, void *ctx); herr_t (*get)(void *obj, const void *blob_id, void *buf, size_t size, void *ctx); - herr_t (*specific)(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments); - herr_t (*optional)(void *obj, void *blob_id, H5VL_blob_optional_t opt_type, va_list arguments); + herr_t (*specific)(void *obj, void *blob_id, H5VL_blob_specific_args_t *args); + herr_t (*optional)(void *obj, void *blob_id, H5VL_optional_args_t *args); } H5VL_blob_class_t; /* Object token routines */ @@ -490,8 +1044,8 @@ typedef struct H5VL_class_t { H5VL_token_class_t token_cls; /**< VOL connector object token class callbacks */ /* Catch-all */ - herr_t (*optional)(void *obj, int op_type, hid_t dxpl_id, void **req, - va_list arguments); /**< Optional callback */ + herr_t (*optional)(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); /**< Optional callback */ } H5VL_class_t; //! <!-- [H5VL_class_t_snip] --> @@ -557,6 +1111,53 @@ H5_DLL hid_t H5VLpeek_connector_id_by_name(const char *name); */ H5_DLL hid_t H5VLpeek_connector_id_by_value(H5VL_class_value_t value); +/* User-defined optional operations */ +H5_DLL herr_t H5VLregister_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val); +H5_DLL herr_t H5VLfind_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val); +H5_DLL herr_t H5VLunregister_opt_operation(H5VL_subclass_t subcls, const char *op_name); +H5_DLL herr_t H5VLattr_optional_op(const char *app_file, const char *app_func, unsigned app_line, + hid_t attr_id, H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id); +H5_DLL herr_t H5VLdataset_optional_op(const char *app_file, const char *app_func, unsigned app_line, + hid_t dset_id, H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id); +H5_DLL herr_t H5VLdatatype_optional_op(const char *app_file, const char *app_func, unsigned app_line, + hid_t type_id, H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id); +H5_DLL herr_t H5VLfile_optional_op(const char *app_file, const char *app_func, unsigned app_line, + hid_t file_id, H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id); +H5_DLL herr_t H5VLgroup_optional_op(const char *app_file, const char *app_func, unsigned app_line, + hid_t group_id, H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id); +H5_DLL herr_t H5VLlink_optional_op(const char *app_file, const char *app_func, unsigned app_line, + hid_t loc_id, const char *name, hid_t lapl_id, H5VL_optional_args_t *args, + hid_t dxpl_id, hid_t es_id); +H5_DLL herr_t H5VLobject_optional_op(const char *app_file, const char *app_func, unsigned app_line, + hid_t loc_id, const char *name, hid_t lapl_id, + H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id); +H5_DLL herr_t H5VLrequest_optional_op(void *req, hid_t connector_id, H5VL_optional_args_t *args); + +/* API Wrappers for "optional_op" routines */ +/* (Must be defined _after_ the function prototype) */ +/* (And must only defined when included in application code, not the library) */ +#ifndef H5VL_MODULE +/* Inject application compile-time macros into function calls */ +#define H5VLattr_optional_op(...) H5VLattr_optional_op(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5VLdataset_optional_op(...) H5VLdataset_optional_op(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5VLdatatype_optional_op(...) H5VLdatatype_optional_op(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5VLfile_optional_op(...) H5VLfile_optional_op(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5VLgroup_optional_op(...) H5VLgroup_optional_op(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5VLlink_optional_op(...) H5VLlink_optional_op(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5VLobject_optional_op(...) H5VLobject_optional_op(__FILE__, __func__, __LINE__, __VA_ARGS__) + +/* Define "wrapper" versions of function calls, to allow compile-time values to + * be passed in by language wrapper or library layer on top of HDF5. + */ +#define H5VLattr_optional_op_wrap H5_NO_EXPAND(H5VLattr_optional_op) +#define H5VLdataset_optional_op_wrap H5_NO_EXPAND(H5VLdataset_optional_op) +#define H5VLdatatype_optional_op_wrap H5_NO_EXPAND(H5VLdatatype_optional_op) +#define H5VLfile_optional_op_wrap H5_NO_EXPAND(H5VLfile_optional_op) +#define H5VLgroup_optional_op_wrap H5_NO_EXPAND(H5VLgroup_optional_op) +#define H5VLlink_optional_op_wrap H5_NO_EXPAND(H5VLlink_optional_op) +#define H5VLobject_optional_op_wrap H5_NO_EXPAND(H5VLobject_optional_op) +#endif /* H5VL_MODULE */ + #ifdef __cplusplus } #endif diff --git a/src/H5VLconnector_passthru.h b/src/H5VLconnector_passthru.h index 720740f..17029f0 100644 --- a/src/H5VLconnector_passthru.h +++ b/src/H5VLconnector_passthru.h @@ -58,8 +58,9 @@ extern "C" { H5_DLL herr_t H5VLcmp_connector_cls(int *cmp, hid_t connector_id1, hid_t connector_id2); H5_DLL hid_t H5VLwrap_register(void *obj, H5I_type_t type); H5_DLL herr_t H5VLretrieve_lib_state(void **state); +H5_DLL herr_t H5VLstart_lib_state(void); H5_DLL herr_t H5VLrestore_lib_state(const void *state); -H5_DLL herr_t H5VLreset_lib_state(void); +H5_DLL herr_t H5VLfinish_lib_state(void); H5_DLL herr_t H5VLfree_lib_state(void *state); /* Pass-through callbacks */ @@ -92,13 +93,12 @@ H5_DLL herr_t H5VLattr_read(void *attr, hid_t connector_id, hid_t dtype_id, void void **req); H5_DLL herr_t H5VLattr_write(void *attr, hid_t connector_id, hid_t dtype_id, const void *buf, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VLattr_get(void *obj, hid_t connector_id, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); +H5_DLL herr_t H5VLattr_get(void *obj, hid_t connector_id, H5VL_attr_get_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VLattr_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, - H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -H5_DLL herr_t H5VLattr_optional(void *obj, hid_t connector_id, H5VL_attr_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); + H5VL_attr_specific_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VLattr_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VLattr_close(void *attr, hid_t connector_id, hid_t dxpl_id, void **req); /* Public wrappers for dataset callbacks */ @@ -111,12 +111,12 @@ H5_DLL herr_t H5VLdataset_read(void *dset, hid_t connector_id, hid_t mem_type_id hid_t file_space_id, hid_t plist_id, void *buf, void **req); H5_DLL herr_t H5VLdataset_write(void *dset, hid_t connector_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t plist_id, const void *buf, void **req); -H5_DLL herr_t H5VLdataset_get(void *dset, hid_t connector_id, H5VL_dataset_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments); -H5_DLL herr_t H5VLdataset_specific(void *obj, hid_t connector_id, H5VL_dataset_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments); -H5_DLL herr_t H5VLdataset_optional(void *obj, hid_t connector_id, H5VL_dataset_optional_t opt_type, - hid_t dxpl_id, void **req, va_list arguments); +H5_DLL herr_t H5VLdataset_get(void *dset, hid_t connector_id, H5VL_dataset_get_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VLdataset_specific(void *obj, hid_t connector_id, H5VL_dataset_specific_args_t *args, + hid_t dxpl_id, void **req); +H5_DLL herr_t H5VLdataset_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VLdataset_close(void *dset, hid_t connector_id, hid_t dxpl_id, void **req); /* Public wrappers for named datatype callbacks */ @@ -125,24 +125,24 @@ H5_DLL void * H5VLdatatype_commit(void *obj, const H5VL_loc_params_t *loc_params hid_t dxpl_id, void **req); H5_DLL void * H5VLdatatype_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, hid_t tapl_id, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VLdatatype_get(void *dt, hid_t connector_id, H5VL_datatype_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments); -H5_DLL herr_t H5VLdatatype_specific(void *obj, hid_t connector_id, H5VL_datatype_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments); -H5_DLL herr_t H5VLdatatype_optional(void *obj, hid_t connector_id, H5VL_datatype_optional_t opt_type, - hid_t dxpl_id, void **req, va_list arguments); +H5_DLL herr_t H5VLdatatype_get(void *dt, hid_t connector_id, H5VL_datatype_get_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VLdatatype_specific(void *obj, hid_t connector_id, H5VL_datatype_specific_args_t *args, + hid_t dxpl_id, void **req); +H5_DLL herr_t H5VLdatatype_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VLdatatype_close(void *dt, hid_t connector_id, hid_t dxpl_id, void **req); /* Public wrappers for file callbacks */ H5_DLL void * H5VLfile_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id, void **req); H5_DLL void * H5VLfile_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VLfile_get(void *file, hid_t connector_id, H5VL_file_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments); -H5_DLL herr_t H5VLfile_specific(void *obj, hid_t connector_id, H5VL_file_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments); -H5_DLL herr_t H5VLfile_optional(void *obj, hid_t connector_id, H5VL_file_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); +H5_DLL herr_t H5VLfile_get(void *file, hid_t connector_id, H5VL_file_get_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VLfile_specific(void *obj, hid_t connector_id, H5VL_file_specific_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VLfile_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VLfile_close(void *file, hid_t connector_id, hid_t dxpl_id, void **req); /* Public wrappers for group callbacks */ @@ -151,18 +151,17 @@ H5_DLL void * H5VLgroup_create(void *obj, const H5VL_loc_params_t *loc_params, h void **req); H5_DLL void * H5VLgroup_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, hid_t gapl_id, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VLgroup_get(void *obj, hid_t connector_id, H5VL_group_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments); -H5_DLL herr_t H5VLgroup_specific(void *obj, hid_t connector_id, H5VL_group_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments); -H5_DLL herr_t H5VLgroup_optional(void *obj, hid_t connector_id, H5VL_group_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); +H5_DLL herr_t H5VLgroup_get(void *obj, hid_t connector_id, H5VL_group_get_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VLgroup_specific(void *obj, hid_t connector_id, H5VL_group_specific_args_t *args, + hid_t dxpl_id, void **req); +H5_DLL herr_t H5VLgroup_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VLgroup_close(void *grp, hid_t connector_id, hid_t dxpl_id, void **req); /* Public wrappers for link callbacks */ -H5_DLL herr_t H5VLlink_create(H5VL_link_create_type_t create_type, void *obj, - const H5VL_loc_params_t *loc_params, hid_t connector_id, hid_t lcpl_id, - hid_t lapl_id, hid_t dxpl_id, void **req, va_list arguments); +H5_DLL herr_t H5VLlink_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t *loc_params, + hid_t connector_id, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); H5_DLL herr_t H5VLlink_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t connector_id, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); @@ -170,12 +169,11 @@ H5_DLL herr_t H5VLlink_move(void *src_obj, const H5VL_loc_params_t *loc_params1, const H5VL_loc_params_t *loc_params2, hid_t connector_id, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); H5_DLL herr_t H5VLlink_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, - H5VL_link_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); + H5VL_link_get_args_t *args, hid_t dxpl_id, void **req); H5_DLL herr_t H5VLlink_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, - H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -H5_DLL herr_t H5VLlink_optional(void *obj, hid_t connector_id, H5VL_link_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); + H5VL_link_specific_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VLlink_optional(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req); /* Public wrappers for object callbacks */ H5_DLL void * H5VLobject_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, @@ -184,16 +182,16 @@ H5_DLL herr_t H5VLobject_copy(void *src_obj, const H5VL_loc_params_t *loc_params void *dst_obj, const H5VL_loc_params_t *loc_params2, const char *dst_name, hid_t connector_id, hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req); H5_DLL herr_t H5VLobject_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, - H5VL_object_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); + H5VL_object_get_args_t *args, hid_t dxpl_id, void **req); H5_DLL herr_t H5VLobject_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, - H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -H5_DLL herr_t H5VLobject_optional(void *obj, hid_t connector_id, H5VL_object_optional_t opt_type, - hid_t dxpl_id, void **req, va_list arguments); + H5VL_object_specific_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VLobject_optional(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req); /* Public wrappers for connector/container introspection callbacks */ H5_DLL herr_t H5VLintrospect_get_conn_cls(void *obj, hid_t connector_id, H5VL_get_conn_lvl_t lvl, const H5VL_class_t **conn_cls); +H5_DLL herr_t H5VLintrospect_get_cap_flags(const void *info, hid_t connector_id, unsigned *cap_flags); H5_DLL herr_t H5VLintrospect_opt_query(void *obj, hid_t connector_id, H5VL_subclass_t subcls, int opt_type, uint64_t *flags); @@ -202,10 +200,8 @@ H5_DLL herr_t H5VLrequest_wait(void *req, hid_t connector_id, uint64_t timeout, H5VL_request_status_t *status); H5_DLL herr_t H5VLrequest_notify(void *req, hid_t connector_id, H5VL_request_notify_t cb, void *ctx); H5_DLL herr_t H5VLrequest_cancel(void *req, hid_t connector_id, H5VL_request_status_t *status); -H5_DLL herr_t H5VLrequest_specific(void *req, hid_t connector_id, H5VL_request_specific_t specific_type, - va_list arguments); -H5_DLL herr_t H5VLrequest_optional(void *req, hid_t connector_id, H5VL_request_optional_t opt_type, - va_list arguments); +H5_DLL herr_t H5VLrequest_specific(void *req, hid_t connector_id, H5VL_request_specific_args_t *args); +H5_DLL herr_t H5VLrequest_optional(void *req, hid_t connector_id, H5VL_optional_args_t *args); H5_DLL herr_t H5VLrequest_free(void *req, hid_t connector_id); /* Public wrappers for blob callbacks */ @@ -214,9 +210,8 @@ H5_DLL herr_t H5VLblob_put(void *obj, hid_t connector_id, const void *buf, size_ H5_DLL herr_t H5VLblob_get(void *obj, hid_t connector_id, const void *blob_id, void *buf, size_t size, void *ctx); H5_DLL herr_t H5VLblob_specific(void *obj, hid_t connector_id, void *blob_id, - H5VL_blob_specific_t specific_type, va_list arguments); -H5_DLL herr_t H5VLblob_optional(void *obj, hid_t connector_id, void *blob_id, H5VL_blob_optional_t opt_type, - va_list arguments); + H5VL_blob_specific_args_t *args); +H5_DLL herr_t H5VLblob_optional(void *obj, hid_t connector_id, void *blob_id, H5VL_optional_args_t *args); /* Public wrappers for token callbacks */ H5_DLL herr_t H5VLtoken_cmp(void *obj, hid_t connector_id, const H5O_token_t *token1, @@ -227,8 +222,8 @@ H5_DLL herr_t H5VLtoken_from_str(void *obj, H5I_type_t obj_type, hid_t connector H5O_token_t *token); /* Public wrappers for generic 'optional' callback */ -H5_DLL herr_t H5VLoptional(void *obj, hid_t connector_id, int op_type, hid_t dxpl_id, void **req, - va_list arguments); +H5_DLL herr_t H5VLoptional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); #ifdef __cplusplus } diff --git a/src/H5VLdyn_ops.c b/src/H5VLdyn_ops.c new file mode 100644 index 0000000..0992452 --- /dev/null +++ b/src/H5VLdyn_ops.c @@ -0,0 +1,334 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Purpose: The Virtual Object Layer as described in documentation. + * The pupose is to provide an abstraction on how to access the + * underlying HDF5 container, whether in a local file with + * a specific file format, or remotely on other machines, etc... + */ + +/****************/ +/* Module Setup */ +/****************/ + +#include "H5VLmodule.h" /* This source code file is part of the H5VL module */ + +/***********/ +/* Headers */ +/***********/ + +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FLprivate.h" /* Free lists */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5SLprivate.h" /* Skip lists */ +#include "H5VLpkg.h" /* Virtual Object Layer */ + +/****************/ +/* Local Macros */ +/****************/ + +/******************/ +/* Local Typedefs */ +/******************/ + +/* Dynamic operation info */ +typedef struct H5VL_dyn_op_t { + char *op_name; /* Name of operation */ + int op_val; /* Value of operation */ +} H5VL_dyn_op_t; + +/********************/ +/* Local Prototypes */ +/********************/ +static void H5VL__release_dyn_op(H5VL_dyn_op_t *dyn_op); + +/*********************/ +/* Package Variables */ +/*********************/ + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + +/*******************/ +/* Local Variables */ +/*******************/ + +/* The current optional operation values */ +static int H5VL_opt_vals_g[H5VL_SUBCLS_TOKEN + 1] = { + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_NONE */ + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_INFO */ + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_WRAP */ + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_ATTR */ + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_DATASET */ + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_DATATYPE */ + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_FILE */ + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_GROUP */ + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_LINK */ + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_OBJECT */ + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_REQUEST */ + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_BLOB */ + H5VL_RESERVED_NATIVE_OPTIONAL /* H5VL_SUBCLS_TOKEN */ +}; + +/* The current optional operations' info */ +static H5SL_t *H5VL_opt_ops_g[H5VL_SUBCLS_TOKEN + 1] = { + NULL, /* H5VL_SUBCLS_NONE */ + NULL, /* H5VL_SUBCLS_INFO */ + NULL, /* H5VL_SUBCLS_WRAP */ + NULL, /* H5VL_SUBCLS_ATTR */ + NULL, /* H5VL_SUBCLS_DATASET */ + NULL, /* H5VL_SUBCLS_DATATYPE */ + NULL, /* H5VL_SUBCLS_FILE */ + NULL, /* H5VL_SUBCLS_GROUP */ + NULL, /* H5VL_SUBCLS_LINK */ + NULL, /* H5VL_SUBCLS_OBJECT */ + NULL, /* H5VL_SUBCLS_REQUEST */ + NULL, /* H5VL_SUBCLS_BLOB */ + NULL /* H5VL_SUBCLS_TOKEN */ +}; + +/* Declare a free list to manage the H5VL_class_t struct */ +H5FL_DEFINE_STATIC(H5VL_dyn_op_t); + +/*--------------------------------------------------------------------------- + * Function: H5VL__release_dyn_op + * + * Purpose: Release a dynamic operation info node + * + * Return: Success: Non-negative + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +static void +H5VL__release_dyn_op(H5VL_dyn_op_t *dyn_op) +{ + FUNC_ENTER_STATIC_NOERR + + H5MM_xfree(dyn_op->op_name); + H5FL_FREE(H5VL_dyn_op_t, dyn_op); + + FUNC_LEAVE_NOAPI_VOID +} /* H5VL__release_dyn_op() */ + +/*--------------------------------------------------------------------------- + * Function: H5VL__term_opt_operation_cb + * + * Purpose: Callback for releasing a dynamically registered operation info + * + * Return: Success: Non-negative + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +static herr_t +H5VL__term_opt_operation_cb(void *_item, void H5_ATTR_UNUSED *key, void H5_ATTR_UNUSED *op_data) +{ + H5VL_dyn_op_t *item = (H5VL_dyn_op_t *)_item; /* Item to release */ + + FUNC_ENTER_STATIC_NOERR + + /* Release the dynamically registered operation info */ + H5VL__release_dyn_op(item); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5VL__term_opt_operation_cb() */ + +/*--------------------------------------------------------------------------- + * Function: H5VL__term_opt_operation + * + * Purpose: Terminate the dynamically registered optional operations, + * releasing all operations. + * + * Return: Success: Non-negative + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VL__term_opt_operation(void) +{ + size_t subcls; /* Index over the elements of operation array */ + + FUNC_ENTER_PACKAGE_NOERR + + /* Iterate over the VOL subclasses */ + for (subcls = 0; subcls < NELMTS(H5VL_opt_vals_g); subcls++) + if (H5VL_opt_ops_g[subcls]) + H5SL_destroy(H5VL_opt_ops_g[subcls], H5VL__term_opt_operation_cb, NULL); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5VL__term_opt_operation() */ + +/*--------------------------------------------------------------------------- + * Function: H5VL__register_opt_operation + * + * Purpose: Register a new optional operation for a VOL object subclass. + * + * Return: Success: Non-negative + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VL__register_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val) +{ + H5VL_dyn_op_t *new_op; /* Info about new operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity checks */ + HDassert(op_val); + HDassert(op_name && *op_name); + + /* Check for duplicate operation */ + if (H5VL_opt_ops_g[subcls]) { + if (NULL != H5SL_search(H5VL_opt_ops_g[subcls], op_name)) + HGOTO_ERROR(H5E_VOL, H5E_EXISTS, FAIL, "operation name already exists") + } /* end if */ + else { + /* Create skip list for operation of this subclass */ + if (NULL == (H5VL_opt_ops_g[subcls] = H5SL_create(H5SL_TYPE_STR, NULL))) + HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, FAIL, "can't create skip list for operations") + } /* end else */ + + /* Register new operation */ + if (NULL == (new_op = H5FL_CALLOC(H5VL_dyn_op_t))) + HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, "can't allocate memory for dynamic operation info") + if (NULL == (new_op->op_name = H5MM_strdup(op_name))) + HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, "can't allocate name for dynamic operation info") + new_op->op_val = H5VL_opt_vals_g[subcls]++; + + /* Insert into subclass's skip list */ + if (H5SL_insert(H5VL_opt_ops_g[subcls], new_op, new_op->op_name) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert operation info into skip list") + + /* Return the next operation value to the caller */ + *op_val = new_op->op_val; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5VL__register_opt_operation() */ + +/*--------------------------------------------------------------------------- + * Function: H5VL__num_opt_operation + * + * Purpose: Returns the # of currently registered optional operations + * + * Return: # of registered optional operations / <can't fail> + * + *--------------------------------------------------------------------------- + */ +size_t +H5VL__num_opt_operation(void) +{ + size_t subcls; /* Index over the elements of operation array */ + size_t ret_value = 0; /* Return value */ + + FUNC_ENTER_PACKAGE_NOERR + + /* Iterate over the VOL subclasses */ + for (subcls = 0; subcls < NELMTS(H5VL_opt_vals_g); subcls++) + if (H5VL_opt_ops_g[subcls]) + ret_value += H5SL_count(H5VL_opt_ops_g[subcls]); + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5VL__num_opt_operation() */ + +/*--------------------------------------------------------------------------- + * Function: H5VL__find_opt_operation + * + * Purpose: Look up a optional operation for a VOL object subclass, by name. + * + * Return: Success: Non-negative + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VL__find_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity checks */ + HDassert(op_val); + HDassert(op_name && *op_name); + + /* Check for dynamic operations in the VOL subclass */ + if (H5VL_opt_ops_g[subcls]) { + H5VL_dyn_op_t *dyn_op; /* Info about operation */ + + /* Search for dynamic operation with correct name */ + if (NULL == (dyn_op = H5SL_search(H5VL_opt_ops_g[subcls], op_name))) + HGOTO_ERROR(H5E_VOL, H5E_NOTFOUND, FAIL, "operation name isn't registered") + + /* Set operation value for user */ + *op_val = dyn_op->op_val; + } /* end if */ + else + HGOTO_ERROR(H5E_VOL, H5E_NOTFOUND, FAIL, "operation name isn't registered") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5VL__find_opt_operation() */ + +/*--------------------------------------------------------------------------- + * Function: H5VL__unregister_opt_operation + * + * Purpose: Unregister a optional operation for a VOL object subclass, by name. + * + * Return: Success: Non-negative + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VL__unregister_opt_operation(H5VL_subclass_t subcls, const char *op_name) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity checks */ + HDassert(op_name && *op_name); + + /* Check for dynamic operations in the VOL subclass */ + if (H5VL_opt_ops_g[subcls]) { + H5VL_dyn_op_t *dyn_op; /* Info about operation */ + + /* Search for dynamic operation with correct name */ + if (NULL == (dyn_op = H5SL_remove(H5VL_opt_ops_g[subcls], op_name))) + HGOTO_ERROR(H5E_VOL, H5E_NOTFOUND, FAIL, "operation name isn't registered") + + /* Release the info for the operation */ + H5VL__release_dyn_op(dyn_op); + + /* Close the skip list, if no more operations in it */ + if (0 == H5SL_count(H5VL_opt_ops_g[subcls])) { + if (H5SL_close(H5VL_opt_ops_g[subcls]) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEOBJ, FAIL, "can't close dyn op skip list") + H5VL_opt_ops_g[subcls] = NULL; + } /* end if */ + } /* end if */ + else + HGOTO_ERROR(H5E_VOL, H5E_NOTFOUND, FAIL, "operation name isn't registered") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5VL__unregister_opt_operation() */ diff --git a/src/H5VLint.c b/src/H5VLint.c index 500e075..70c8112 100644 --- a/src/H5VLint.c +++ b/src/H5VLint.c @@ -88,7 +88,6 @@ typedef struct { /********************/ static herr_t H5VL__free_cls(H5VL_class_t *cls, void **request); static int H5VL__get_connector_cb(void *obj, hid_t id, void *_op_data); -static herr_t H5VL__set_def_conn(void); static void * H5VL__wrap_obj(void *obj, H5I_type_t obj_type); static H5VL_object_t *H5VL__new_vol_obj(H5I_type_t type, void *object, H5VL_t *vol_connector, hbool_t wrap_obj); @@ -194,6 +193,10 @@ H5VL_init_phase2(void) if (H5M_init() < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize map interface") + /* Sanity check default VOL connector */ + HDassert(H5VL_def_conn_s.connector_id == (-1)); + HDassert(H5VL_def_conn_s.connector_info == NULL); + /* Set up the default VOL connector in the default FAPL */ if (H5VL__set_def_conn() < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "unable to set default VOL connector") @@ -261,15 +264,22 @@ H5VL_term_package(void) n++; } /* end if */ else { - /* Destroy the VOL connector ID group */ - n += (H5I_dec_type_ref(H5I_VOL) > 0); - - /* Mark interface as closed */ - if (0 == n) - H5_PKG_INIT_VAR = FALSE; - } /* end else */ - } /* end else */ - } /* end if */ + if (H5VL__num_opt_operation() > 0) { + /* Unregister all dynamically registered optional operations */ + (void)H5VL__term_opt_operation(); + n++; + } /* end if */ + else { + /* Destroy the VOL connector ID group */ + n += (H5I_dec_type_ref(H5I_VOL) > 0); + + /* Mark interface as closed */ + if (0 == n) + H5_PKG_INIT_VAR = FALSE; + } /* end else */ + } /* end else */ + } /* end else */ + } /* end if */ FUNC_LEAVE_NOAPI(n) } /* end H5VL_term_package() */ @@ -365,7 +375,7 @@ H5VL__get_connector_cb(void *obj, hid_t id, void *_op_data) * *------------------------------------------------------------------------- */ -static herr_t +herr_t H5VL__set_def_conn(void) { H5P_genplist_t *def_fapl; /* Default file access property list */ @@ -376,11 +386,16 @@ H5VL__set_def_conn(void) void * vol_info = NULL; /* VOL connector info */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC + FUNC_ENTER_PACKAGE - /* Sanity check */ - HDassert(H5VL_def_conn_s.connector_id == (-1)); - HDassert(H5VL_def_conn_s.connector_info == NULL); + /* Reset default VOL connector, if it's set already */ + /* (Can happen during testing -QAK) */ + if (H5VL_def_conn_s.connector_id > 0) { + /* Release the default VOL connector */ + (void)H5VL_conn_free(&H5VL_def_conn_s); + H5VL_def_conn_s.connector_id = -1; + H5VL_def_conn_s.connector_info = NULL; + } /* end if */ /* Check for environment variable set */ env_var = HDgetenv("HDF5_VOL_CONNECTOR"); @@ -760,51 +775,47 @@ done: } /* end H5VL_register_using_existing_id() */ /*------------------------------------------------------------------------- - * Function: H5VL_register_using_vol_id + * Function: H5VL_new_connector * - * Purpose: Utility function to create a user ID for an object created - * or opened through the VOL. Uses the VOL connector's ID to - * get the connector information instead of it being passed in. + * Purpose: Utility function to create a connector for a connector ID. * - * Return: Success: A valid HDF5 ID - * Failure: H5I_INVALID_HID + * Return: Success: Pointer to a new connector object + * Failure: NULL * *------------------------------------------------------------------------- */ -hid_t -H5VL_register_using_vol_id(H5I_type_t type, void *obj, hid_t connector_id, hbool_t app_ref) +H5VL_t * +H5VL_new_connector(hid_t connector_id) { - H5VL_class_t *cls = NULL; /* VOL connector class */ - H5VL_t * connector = NULL; /* VOL connector struct */ - hbool_t conn_id_incr = FALSE; /* Whether the VOL connector ID has been incremented */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_class_t *cls = NULL; /* VOL connector class */ + H5VL_t * connector = NULL; /* New VOL connector struct */ + hbool_t conn_id_incr = FALSE; /* Whether the VOL connector ID has been incremented */ + H5VL_t * ret_value = NULL; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_NOAPI(NULL) /* Get the VOL class object from the connector's ID */ if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) - HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, H5I_INVALID_HID, "not a VOL connector ID") + HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, NULL, "not a VOL connector ID") /* Setup VOL info struct */ if (NULL == (connector = H5FL_CALLOC(H5VL_t))) - HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, H5I_INVALID_HID, "can't allocate VOL info struct") + HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, NULL, "can't allocate VOL connector struct") connector->cls = cls; connector->id = connector_id; if (H5I_inc_ref(connector->id, FALSE) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTINC, H5I_INVALID_HID, "unable to increment ref count on VOL connector") + HGOTO_ERROR(H5E_VOL, H5E_CANTINC, NULL, "unable to increment ref count on VOL connector") conn_id_incr = TRUE; - /* Get an ID for the VOL object */ - if ((ret_value = H5VL_register(type, obj, connector, app_ref)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle") + /* Set return value */ + ret_value = connector; done: /* Clean up on error */ - if (ret_value < 0) { + if (NULL == ret_value) { /* Decrement VOL connector ID ref count on error */ if (conn_id_incr && H5I_dec_ref(connector_id) < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTDEC, H5I_INVALID_HID, - "unable to decrement ref count on VOL connector") + HDONE_ERROR(H5E_VOL, H5E_CANTDEC, NULL, "unable to decrement ref count on VOL connector") /* Free VOL connector struct */ if (NULL != connector) @@ -812,6 +823,45 @@ done: } /* end if */ FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_new_connector() */ + +/*------------------------------------------------------------------------- + * Function: H5VL_register_using_vol_id + * + * Purpose: Utility function to create a user ID for an object created + * or opened through the VOL. Uses the VOL connector's ID to + * get the connector information instead of it being passed in. + * + * Return: Success: A valid HDF5 ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5VL_register_using_vol_id(H5I_type_t type, void *obj, hid_t connector_id, hbool_t app_ref) +{ + H5VL_t *connector = NULL; /* VOL connector struct */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Create new VOL connector object, using the connector ID */ + if (NULL == (connector = H5VL_new_connector(connector_id))) + HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, H5I_INVALID_HID, "can't create VOL connector object") + + /* Get an ID for the VOL object */ + if ((ret_value = H5VL_register(type, obj, connector, app_ref)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle") + +done: + /* Clean up on error */ + if (H5I_INVALID_HID == ret_value) + /* Release newly created connector */ + if (connector && H5VL_conn_dec_rc(connector) < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTDEC, H5I_INVALID_HID, + "unable to decrement ref count on VOL connector") + + FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_register_using_vol_id() */ /*------------------------------------------------------------------------- @@ -1125,15 +1175,20 @@ H5VL_file_is_same(const H5VL_object_t *vol_obj1, const H5VL_object_t *vol_obj2, if (cmp_value) *same_file = FALSE; else { - void *obj2; /* Terminal object for second file */ + void * obj2; /* Terminal object for second file */ + H5VL_file_specific_args_t vol_cb_args; /* Arguments to VOL callback */ /* Get unwrapped (terminal) object for vol_obj2 */ if (NULL == (obj2 = H5VL_object_data(vol_obj2))) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get unwrapped object") - /* Make callback */ - if (H5VL_file_specific(vol_obj1, H5VL_FILE_IS_EQUAL, H5P_DATASET_XFER_DEFAULT, NULL, obj2, - same_file) < 0) + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_IS_EQUAL; + vol_cb_args.args.is_equal.obj2 = obj2; + vol_cb_args.args.is_equal.same_file = same_file; + + /* Make 'are files equal' callback */ + if (H5VL_file_specific(vol_obj1, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, NULL) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "file specific failed") } /* end else */ @@ -2047,6 +2102,36 @@ done: } /* end H5VL_retrieve_lib_state() */ /*------------------------------------------------------------------------- + * Function: H5VL_start_lib_state + * + * Purpose: Opens a new internal state for the HDF5 library. + * + * Note: Currently just pushes a new API context state, but could be + * expanded in the future. + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, February 5, 2021 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_start_lib_state(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Push a new API context on the stack */ + if (H5CX_push() < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't push API context") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_start_lib_state() */ + +/*------------------------------------------------------------------------- * Function: H5VL_restore_lib_state * * Purpose: Restore the state of the library. @@ -2071,10 +2156,6 @@ H5VL_restore_lib_state(const void *state) /* Sanity checks */ HDassert(state); - /* Push a new API context on the stack */ - if (H5CX_push() < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't push API context") - /* Restore the API context state */ if (H5CX_restore_state((const H5CX_state_t *)state) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set API context state") @@ -2084,16 +2165,16 @@ done: } /* end H5VL_restore_lib_state() */ /*------------------------------------------------------------------------- - * Function: H5VL_reset_lib_state + * Function: H5VL_finish_lib_state * - * Purpose: Reset the state of the library, undoing affects of - * H5VL_restore_lib_state. + * Purpose: Closes the state of the library, undoing affects of + * H5VL_start_lib_state. * * Note: Currently just resets the API context state, but could be * expanded in the future. * * Note: This routine must be called as a "pair" with - * H5VL_restore_lib_state. It can be called before / after / + * H5VL_start_lib_state. It can be called before / after / * independently of H5VL_free_lib_state. * * Return: SUCCEED / FAIL @@ -2104,7 +2185,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_reset_lib_state(void) +H5VL_finish_lib_state(void) { herr_t ret_value = SUCCEED; /* Return value */ @@ -2116,7 +2197,7 @@ H5VL_reset_lib_state(void) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5VL_reset_lib_state() */ +} /* end H5VL_finish_lib_state() */ /*------------------------------------------------------------------------- * Function: H5VL_free_lib_state @@ -2484,6 +2565,33 @@ done: } /* end H5VL_check_plugin_load() */ /*------------------------------------------------------------------------- + * Function: H5VL__is_default_conn + * + * Purpose: Check if the default connector will be used for a container. + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +void +H5VL__is_default_conn(hid_t fapl_id, hid_t connector_id, hbool_t *is_default) +{ + FUNC_ENTER_PACKAGE_NOERR + + /* Sanity checks */ + HDassert(is_default); + + /* Determine if the default VOL connector will be used, based on non-default + * values in the FAPL, connector ID, or the HDF5_VOL_CONNECTOR environment + * variable being set. + */ + *is_default = (H5VL_def_conn_s.connector_id == H5_DEFAULT_VOL) && + ((H5P_FILE_ACCESS_DEFAULT == fapl_id) || connector_id == H5_DEFAULT_VOL); + + FUNC_LEAVE_NOAPI_VOID +} /* end H5VL__is_default_conn() */ + +/*------------------------------------------------------------------------- * Function: H5VL_setup_args * * Purpose: Set up arguments to access an object @@ -2506,7 +2614,7 @@ H5VL_setup_args(hid_t loc_id, H5I_type_t id_type, H5VL_object_t **vol_obj) if (NULL == (*vol_obj = (H5VL_object_t *)H5I_object_verify(loc_id, id_type))) HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "not the correct type of ID") - /* Set up collective metadata (if appropriate */ + /* Set up collective metadata (if appropriate) */ if (H5CX_set_loc(loc_id) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set collective metadata read") @@ -2631,8 +2739,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_setup_name_args(hid_t loc_id, const char *name, const H5P_libclass_t *libclass, hbool_t is_collective, - hid_t acspl_id, H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params) +H5VL_setup_name_args(hid_t loc_id, const char *name, hbool_t is_collective, hid_t lapl_id, + H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params) { herr_t ret_value = SUCCEED; /* Return value */ @@ -2649,7 +2757,7 @@ H5VL_setup_name_args(hid_t loc_id, const char *name, const H5P_libclass_t *libcl HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be an empty string") /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&acspl_id, libclass, loc_id, is_collective) < 0) + if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, is_collective) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set access property list info") /* Get the location object */ @@ -2659,7 +2767,7 @@ H5VL_setup_name_args(hid_t loc_id, const char *name, const H5P_libclass_t *libcl /* Set up location parameters */ loc_params->type = H5VL_OBJECT_BY_NAME; loc_params->loc_data.loc_by_name.name = name; - loc_params->loc_data.loc_by_name.lapl_id = acspl_id; + loc_params->loc_data.loc_by_name.lapl_id = lapl_id; loc_params->obj_type = H5I_get_type(loc_id); done: @@ -2677,8 +2785,8 @@ done: */ herr_t H5VL_setup_idx_args(hid_t loc_id, const char *name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, - const H5P_libclass_t *libclass, hbool_t is_collective, hid_t acspl_id, - H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params) + hbool_t is_collective, hid_t lapl_id, H5VL_object_t **vol_obj, + H5VL_loc_params_t *loc_params) { herr_t ret_value = SUCCEED; /* Return value */ @@ -2699,7 +2807,7 @@ H5VL_setup_idx_args(hid_t loc_id, const char *name, H5_index_t idx_type, H5_iter HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&acspl_id, libclass, loc_id, is_collective) < 0) + if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, is_collective) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set access property list info") /* Get the location object */ @@ -2712,7 +2820,7 @@ H5VL_setup_idx_args(hid_t loc_id, const char *name, H5_index_t idx_type, H5_iter loc_params->loc_data.loc_by_idx.idx_type = idx_type; loc_params->loc_data.loc_by_idx.order = order; loc_params->loc_data.loc_by_idx.n = n; - loc_params->loc_data.loc_by_idx.lapl_id = acspl_id; + loc_params->loc_data.loc_by_idx.lapl_id = lapl_id; loc_params->obj_type = H5I_get_type(loc_id); done: @@ -2752,3 +2860,45 @@ H5VL_setup_token_args(hid_t loc_id, H5O_token_t *obj_token, H5VL_object_t **vol_ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_setup_token_args() */ + +/*------------------------------------------------------------------------- + * Function: H5VL_get_cap_flags + * + * Purpose: Query capability flags for connector property. + * + * Note: VOL connector set with HDF5_VOL_CONNECTOR overrides the + * property passed in. + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_get_cap_flags(const H5VL_connector_prop_t *connector_prop, unsigned *cap_flags) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(connector_prop); + + /* Copy the connector ID & info, if there is one */ + if (connector_prop->connector_id > 0) { + H5VL_class_t *connector; /* Pointer to connector */ + + /* Retrieve the connector for the ID */ + if (NULL == (connector = (H5VL_class_t *)H5I_object(connector_prop->connector_id))) + HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a VOL connector ID") + + /* Query the connector's capability flags */ + if (H5VL_introspect_get_cap_flags(connector_prop->connector_info, connector, cap_flags) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't query connector's capability flags") + } /* end if */ + else + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "connector ID not set?") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_get_cap_flags() */ diff --git a/src/H5VLmodule.h b/src/H5VLmodule.h index 009c0e5..8fcb961 100644 --- a/src/H5VLmodule.h +++ b/src/H5VLmodule.h @@ -27,14 +27,12 @@ #define H5_MY_PKG_ERR H5E_VOL #define H5_MY_PKG_INIT YES -/** - * \defgroup H5VL H5VL - * \brief Virtual Object Layer Interface - * \todo Describe concisely what the functions in this module are about. +/**\defgroup H5VL H5VL + * + * \todo Describe the VOL plugin life cycle. * * \defgroup ASYNC Asynchronous Functions * \brief Asynchronous Functions - * \todo Describe concisely what the functions in this module are about. * * \defgroup H5VLDEF Definitions * \ingroup H5VL diff --git a/src/H5VLnative.c b/src/H5VLnative.c index b70d489..18b5b9c 100644 --- a/src/H5VLnative.c +++ b/src/H5VLnative.c @@ -47,13 +47,13 @@ static herr_t H5VL__native_term(void); /* Native VOL connector class struct */ static const H5VL_class_t H5VL_native_cls_g = { - H5VL_VERSION, /* VOL class struct version */ - H5VL_NATIVE_VALUE, /* value */ - H5VL_NATIVE_NAME, /* name */ - H5VL_NATIVE_VERSION, /* connector version */ - 0, /* capability flags */ - NULL, /* initialize */ - H5VL__native_term, /* terminate */ + H5VL_VERSION, /* VOL class struct version */ + H5VL_NATIVE_VALUE, /* value */ + H5VL_NATIVE_NAME, /* name */ + H5VL_NATIVE_VERSION, /* connector version */ + H5VL_CAP_FLAG_NATIVE_FILES, /* capability flags */ + NULL, /* initialize */ + H5VL__native_term, /* terminate */ { /* info_cls */ (size_t)0, /* info size */ @@ -139,8 +139,9 @@ static const H5VL_class_t H5VL_native_cls_g = { }, { /* introspect_cls */ - H5VL__native_introspect_get_conn_cls, /* get_conn_cls */ - H5VL__native_introspect_opt_query, /* opt_query */ + H5VL__native_introspect_get_conn_cls, /* get_conn_cls */ + H5VL__native_introspect_get_cap_flags, /* get_cap_flags */ + H5VL__native_introspect_opt_query, /* opt_query */ }, { /* request_cls */ @@ -244,6 +245,32 @@ H5VL__native_introspect_get_conn_cls(void H5_ATTR_UNUSED *obj, H5VL_get_conn_lvl FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5VL__native_introspect_get_conn_cls() */ +/*--------------------------------------------------------------------------- + * Function: H5VL__native_introspect_get_cap_flags + * + * Purpose: Query the capability flags for this connector. + * + * Note: This routine is in this file so that it can return the field + * from the staticly declared class struct. + * + * Returns: SUCCEED (Can't fail) + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VL__native_introspect_get_cap_flags(const void H5_ATTR_UNUSED *info, unsigned *cap_flags) +{ + FUNC_ENTER_PACKAGE_NOERR + + /* Sanity check */ + HDassert(cap_flags); + + /* Set the flags from the connector's field */ + *cap_flags = H5VL_native_cls_g.cap_flags; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5VL__native_introspect_get_cap_flags() */ + /*------------------------------------------------------------------------- * Function: H5VL_native_get_file_addr_len * diff --git a/src/H5VLnative.h b/src/H5VLnative.h index 425d833..00ee930 100644 --- a/src/H5VLnative.h +++ b/src/H5VLnative.h @@ -18,6 +18,7 @@ #define H5VLnative_H /* Public headers needed by this file */ +#include "H5Apublic.h" /* Attributes */ #include "H5VLpublic.h" /* Virtual Object Layer */ /*****************/ @@ -43,24 +44,137 @@ * must be updated. */ +#ifndef H5_NO_DEPRECATED_SYMBOLS +/* Parameters for attribute 'iterate old' operation */ +typedef struct H5VL_native_attr_iterate_old_t { + hid_t loc_id; + unsigned * attr_num; + H5A_operator1_t op; + void * op_data; +} H5VL_native_attr_iterate_old_t; + +/* Parameters for native connector's attribute 'optional' operations */ +typedef union H5VL_native_attr_optional_args_t { + /* H5VL_NATIVE_ATTR_ITERATE_OLD */ + H5VL_native_attr_iterate_old_t iterate_old; +} H5VL_native_attr_optional_args_t; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + /* Values for native VOL connector dataset optional VOL operations */ /* NOTE: If new values are added here, the H5VL__native_introspect_opt_query * routine must be updated. */ -#define H5VL_NATIVE_DATASET_FORMAT_CONVERT 0 /* H5Dformat_convert (internal) */ -#define H5VL_NATIVE_DATASET_GET_CHUNK_INDEX_TYPE 1 /* H5Dget_chunk_index_type */ -#define H5VL_NATIVE_DATASET_GET_CHUNK_STORAGE_SIZE 2 /* H5Dget_chunk_storage_size */ -#define H5VL_NATIVE_DATASET_GET_NUM_CHUNKS 3 /* H5Dget_num_chunks */ -#define H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_IDX 4 /* H5Dget_chunk_info */ -#define H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_COORD 5 /* H5Dget_chunk_info_by_coord */ -#define H5VL_NATIVE_DATASET_CHUNK_READ 6 /* H5Dchunk_read */ -#define H5VL_NATIVE_DATASET_CHUNK_WRITE 7 /* H5Dchunk_write */ -#define H5VL_NATIVE_DATASET_GET_VLEN_BUF_SIZE 8 /* H5Dvlen_get_buf_size */ -#define H5VL_NATIVE_DATASET_GET_OFFSET 9 /* H5Dget_offset */ +#define H5VL_NATIVE_DATASET_FORMAT_CONVERT 0 /* H5Dformat_convert (internal) */ +#define H5VL_NATIVE_DATASET_GET_CHUNK_INDEX_TYPE 1 /* H5Dget_chunk_index_type */ +#define H5VL_NATIVE_DATASET_GET_CHUNK_STORAGE_SIZE 2 /* H5Dget_chunk_storage_size */ +#define H5VL_NATIVE_DATASET_GET_NUM_CHUNKS 3 /* H5Dget_num_chunks */ +#define H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_IDX 4 /* H5Dget_chunk_info */ +#define H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_COORD 5 /* H5Dget_chunk_info_by_coord */ +#define H5VL_NATIVE_DATASET_CHUNK_READ 6 /* H5Dchunk_read */ +#define H5VL_NATIVE_DATASET_CHUNK_WRITE 7 /* H5Dchunk_write */ +#define H5VL_NATIVE_DATASET_GET_VLEN_BUF_SIZE 8 /* H5Dvlen_get_buf_size */ +#define H5VL_NATIVE_DATASET_GET_OFFSET 9 /* H5Dget_offset */ +#define H5VL_NATIVE_DATASET_CHUNK_ITER 10 /* H5Dchunk_iter */ /* NOTE: If values over 1023 are added, the H5VL_RESERVED_NATIVE_OPTIONAL macro * must be updated. */ +/* Parameters for native connector's dataset 'chunk read' operation */ +typedef struct H5VL_native_dataset_chunk_read_t { + const hsize_t *offset; + uint32_t filters; + void * buf; +} H5VL_native_dataset_chunk_read_t; + +/* Parameters for native connector's dataset 'chunk write' operation */ +typedef struct H5VL_native_dataset_chunk_write_t { + const hsize_t *offset; + uint32_t filters; + uint32_t size; + const void * buf; +} H5VL_native_dataset_chunk_write_t; + +/* Parameters for native connector's dataset 'get vlen buf size' operation */ +typedef struct H5VL_native_dataset_get_vlen_buf_size_t { + hid_t type_id; + hid_t space_id; + hsize_t *size; /* Size of variable-length data buffer (OUT) */ +} H5VL_native_dataset_get_vlen_buf_size_t; + +/* Parameters for native connector's dataset 'get chunk storage size' operation */ +typedef struct H5VL_native_dataset_get_chunk_storage_size_t { + const hsize_t *offset; /* Offset of chunk */ + hsize_t * size; /* Size of chunk (OUT) */ +} H5VL_native_dataset_get_chunk_storage_size_t; + +/* Parameters for native connector's dataset 'get num chunks' operation */ +typedef struct H5VL_native_dataset_get_num_chunks_t { + hid_t space_id; /* Space selection */ + hsize_t *nchunks; /* # of chunk for space selection (OUT) */ +} H5VL_native_dataset_get_num_chunks_t; + +/* Parameters for native connector's dataset 'get chunk info by idx' operation */ +typedef struct H5VL_native_dataset_get_chunk_info_by_idx_t { + hid_t space_id; /* Space selection */ + hsize_t chk_index; /* Chunk index within space */ + hsize_t * offset; /* Chunk coordinates (OUT) */ + unsigned *filter_mask; /* Filter mask for chunk (OUT) */ + haddr_t * addr; /* Address of chunk in file (OUT) */ + hsize_t * size; /* Size of chunk in file (OUT) */ +} H5VL_native_dataset_get_chunk_info_by_idx_t; + +/* Parameters for native connector's dataset 'get chunk info by coord' operation */ +typedef struct H5VL_native_dataset_get_chunk_info_by_coord_t { + const hsize_t *offset; /* Chunk coordinates */ + unsigned * filter_mask; /* Filter mask for chunk (OUT) */ + haddr_t * addr; /* Address of chunk in file (OUT) */ + hsize_t * size; /* Size of chunk in file (OUT) */ +} H5VL_native_dataset_get_chunk_info_by_coord_t; + +/* Parameters for native connector's dataset 'optional' operations */ +typedef union H5VL_native_dataset_optional_args_t { + /* H5VL_NATIVE_DATASET_FORMAT_CONVERT */ + /* No args */ + + /* H5VL_NATIVE_DATASET_GET_CHUNK_INDEX_TYPE */ + struct { + H5D_chunk_index_t *idx_type; /* Type of chunk index (OUT) */ + } get_chunk_idx_type; + + /* H5VL_NATIVE_DATASET_GET_CHUNK_STORAGE_SIZE */ + H5VL_native_dataset_get_chunk_storage_size_t get_chunk_storage_size; + + /* H5VL_NATIVE_DATASET_GET_NUM_CHUNKS */ + H5VL_native_dataset_get_num_chunks_t get_num_chunks; + + /* H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_IDX */ + H5VL_native_dataset_get_chunk_info_by_idx_t get_chunk_info_by_idx; + + /* H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_COORD */ + H5VL_native_dataset_get_chunk_info_by_coord_t get_chunk_info_by_coord; + + /* H5VL_NATIVE_DATASET_CHUNK_READ */ + H5VL_native_dataset_chunk_read_t chunk_read; + + /* H5VL_NATIVE_DATASET_CHUNK_WRITE */ + H5VL_native_dataset_chunk_write_t chunk_write; + + /* H5VL_NATIVE_DATASET_GET_VLEN_BUF_SIZE */ + H5VL_native_dataset_get_vlen_buf_size_t get_vlen_buf_size; + + /* H5VL_NATIVE_DATASET_GET_OFFSET */ + struct { + haddr_t *offset; /* Contiguous dataset's offset in the file (OUT) */ + } get_offset; + + /* H5VL_NATIVE_DATASET_CHUNK_ITER */ + struct { + H5D_chunk_iter_op_t op; /* Chunk iteration callback */ + void * op_data; /* Context to pass to iteration callback */ + } chunk_iter; + +} H5VL_native_dataset_optional_args_t; + /* Values for native VOL connector file optional VOL operations */ /* NOTE: If new values are added here, the H5VL__native_introspect_opt_query * routine must be updated. @@ -103,6 +217,194 @@ * must be updated. */ +/* Parameters for native connector's file 'get file image' operation */ +typedef struct H5VL_native_file_get_file_image_t { + size_t buf_size; /* Size of file image buffer */ + void * buf; /* Buffer for file image (OUT) */ + size_t *image_len; /* Size of file image (OUT) */ +} H5VL_native_file_get_file_image_t; + +/* Parameters for native connector's file 'get free sections' operation */ +typedef struct H5VL_native_file_get_free_sections_t { + H5F_mem_t type; /* Type of file memory to query */ + H5F_sect_info_t *sect_info; /* Array of sections (OUT) */ + size_t nsects; /* Size of section array */ + size_t * sect_count; /* Actual # of sections of type (OUT) */ +} H5VL_native_file_get_free_sections_t; + +/* Parameters for native connector's file 'get freespace' operation */ +typedef struct H5VL_native_file_get_freespace_t { + hsize_t *size; /* Size of free space (OUT) */ +} H5VL_native_file_get_freespace_t; + +/* Parameters for native connector's file 'get info' operation */ +typedef struct H5VL_native_file_get_info_t { + H5I_type_t type; /* Type of object */ + H5F_info2_t *finfo; /* Pointer to file info (OUT) */ +} H5VL_native_file_get_info_t; + +/* Parameters for native connector's file 'get metadata cache size' operation */ +typedef struct H5VL_native_file_get_mdc_size_t { + size_t * max_size; /* Maximum amount of cached data (OUT) */ + size_t * min_clean_size; /* Minimum amount of cached data to keep clean (OUT) */ + size_t * cur_size; /* Current amount of cached data (OUT) */ + uint32_t *cur_num_entries; /* Current # of cached entries (OUT) */ +} H5VL_native_file_get_mdc_size_t; + +/* Parameters for native connector's file 'get VFD handle' operation */ +typedef struct H5VL_native_file_get_vfd_handle_t { + hid_t fapl_id; + void **file_handle; /* File handle from VFD (OUT) */ +} H5VL_native_file_get_vfd_handle_t; + +/* Parameters for native connector's file 'get MDC logging status' operation */ +typedef struct H5VL_native_file_get_mdc_logging_status_t { + hbool_t *is_enabled; /* Whether logging is enabled (OUT) */ + hbool_t *is_currently_logging; /* Whether currently logging (OUT) */ +} H5VL_native_file_get_mdc_logging_status_t; + +/* Parameters for native connector's file 'get page buffering stats' operation */ +typedef struct H5VL_native_file_get_page_buffering_stats_t { + unsigned *accesses; /* Metadata/raw data page access counts (OUT) */ + unsigned *hits; /* Metadata/raw data page hit counts (OUT) */ + unsigned *misses; /* Metadata/raw data page miss counts (OUT) */ + unsigned *evictions; /* Metadata/raw data page eviction counts (OUT) */ + unsigned *bypasses; /* Metadata/raw data page bypass counts (OUT) */ +} H5VL_native_file_get_page_buffering_stats_t; + +/* Parameters for native connector's file 'get MDC image info' operation */ +typedef struct H5VL_native_file_get_mdc_image_info_t { + haddr_t *addr; /* Address of image (OUT) */ + hsize_t *len; /* Length of image (OUT) */ +} H5VL_native_file_get_mdc_image_info_t; + +/* Parameters for native connector's file 'set libver bounds' operation */ +typedef struct H5VL_native_file_set_libver_bounds_t { + H5F_libver_t low; /* Lowest version possible */ + H5F_libver_t high; /* Highest version possible */ +} H5VL_native_file_set_libver_bounds_t; + +/* Parameters for native connector's file 'optional' operations */ +typedef union H5VL_native_file_optional_args_t { + /* H5VL_NATIVE_FILE_CLEAR_ELINK_CACHE */ + /* No args */ + + /* H5VL_NATIVE_FILE_GET_FILE_IMAGE */ + H5VL_native_file_get_file_image_t get_file_image; + + /* H5VL_NATIVE_FILE_GET_FREE_SECTIONS */ + H5VL_native_file_get_free_sections_t get_free_sections; + + /* H5VL_NATIVE_FILE_GET_FREE_SPACE */ + H5VL_native_file_get_freespace_t get_freespace; + + /* H5VL_NATIVE_FILE_GET_INFO */ + H5VL_native_file_get_info_t get_info; + + /* H5VL_NATIVE_FILE_GET_MDC_CONF */ + struct { + H5AC_cache_config_t *config; /* Pointer to MDC config (OUT) */ + } get_mdc_config; + + /* H5VL_NATIVE_FILE_GET_MDC_HR */ + struct { + double *hit_rate; /* Metadata cache hit rate (OUT) */ + } get_mdc_hit_rate; + + /* H5VL_NATIVE_FILE_GET_MDC_SIZE */ + H5VL_native_file_get_mdc_size_t get_mdc_size; + + /* H5VL_NATIVE_FILE_GET_SIZE */ + struct { + hsize_t *size; /* Size of file (OUT) */ + } get_size; + + /* H5VL_NATIVE_FILE_GET_VFD_HANDLE */ + H5VL_native_file_get_vfd_handle_t get_vfd_handle; + + /* H5VL_NATIVE_FILE_RESET_MDC_HIT_RATE */ + /* No args */ + + /* H5VL_NATIVE_FILE_SET_MDC_CONFIG */ + struct { + const H5AC_cache_config_t *config; /* Pointer to new MDC config */ + } set_mdc_config; + + /* H5VL_NATIVE_FILE_GET_METADATA_READ_RETRY_INFO */ + struct { + H5F_retry_info_t *info; /* Pointer to metadata read retry info (OUT) */ + } get_metadata_read_retry_info; + + /* H5VL_NATIVE_FILE_START_SWMR_WRITE */ + /* No args */ + + /* H5VL_NATIVE_FILE_START_MDC_LOGGING */ + /* No args */ + + /* H5VL_NATIVE_FILE_STOP_MDC_LOGGING */ + /* No args */ + + /* H5VL_NATIVE_FILE_GET_MDC_LOGGING_STATUS */ + H5VL_native_file_get_mdc_logging_status_t get_mdc_logging_status; + + /* H5VL_NATIVE_FILE_FORMAT_CONVERT */ + /* No args */ + + /* H5VL_NATIVE_FILE_RESET_PAGE_BUFFERING_STATS */ + /* No args */ + + /* H5VL_NATIVE_FILE_GET_PAGE_BUFFERING_STATS */ + H5VL_native_file_get_page_buffering_stats_t get_page_buffering_stats; + + /* H5VL_NATIVE_FILE_GET_MDC_IMAGE_INFO */ + H5VL_native_file_get_mdc_image_info_t get_mdc_image_info; + + /* H5VL_NATIVE_FILE_GET_EOA */ + struct { + haddr_t *eoa; /* End of allocated file address space (OUT) */ + } get_eoa; + + /* H5VL_NATIVE_FILE_INCR_FILESIZE */ + struct { + hsize_t increment; /* Amount to increment file size */ + } increment_filesize; + + /* H5VL_NATIVE_FILE_SET_LIBVER_BOUNDS */ + H5VL_native_file_set_libver_bounds_t set_libver_bounds; + + /* H5VL_NATIVE_FILE_GET_MIN_DSET_OHDR_FLAG */ + struct { + hbool_t *minimize; /* Flag whether dataset object headers are minimal (OUT) */ + } get_min_dset_ohdr_flag; + + /* H5VL_NATIVE_FILE_SET_MIN_DSET_OHDR_FLAG */ + struct { + hbool_t minimize; /* Flag whether dataset object headers should be minimal */ + } set_min_dset_ohdr_flag; + +#ifdef H5_HAVE_PARALLEL + /* H5VL_NATIVE_FILE_GET_MPI_ATOMICITY */ + struct { + hbool_t *flag; /* Flag whether MPI atomicity is set for files (OUT) */ + } get_mpi_atomicity; + + /* H5VL_NATIVE_FILE_SET_MPI_ATOMICITY */ + struct { + hbool_t flag; /* Flag whether to set MPI atomicity for files */ + } set_mpi_atomicity; +#endif /* H5_HAVE_PARALLEL */ + + /* H5VL_NATIVE_FILE_POST_OPEN */ + /* No args */ + + /* H5VL_NATIVE_FILE_VFD_SWMR_DISABLE_EOT */ + + /* H5VL_NATIVE_FILE_VFD_SWMR_ENABLE_EOT */ + + /* H5VL_NATIVE_FILE_VFD_SWMR_END_TICK */ + +} H5VL_native_file_optional_args_t; + /* Values for native VOL connector group optional VOL operations */ /* NOTE: If new values are added here, the H5VL__native_introspect_opt_query * routine must be updated. @@ -115,6 +417,33 @@ * must be updated. */ +#ifndef H5_NO_DEPRECATED_SYMBOLS +/* Parameters for group 'iterate old' operation */ +typedef struct H5VL_native_group_iterate_old_t { + H5VL_loc_params_t loc_params; /* Location parameters for iteration */ + hsize_t idx; /* Index of link to begin iteration at */ + hsize_t * last_obj; /* Index of last link looked at (OUT) */ + H5G_iterate_t op; /* Group (link) operator callback */ + void * op_data; /* Context to pass to iterator callback */ +} H5VL_native_group_iterate_old_t; + +/* Parameters for group 'get objinfo' operation */ +typedef struct H5VL_native_group_get_objinfo_t { + H5VL_loc_params_t loc_params; /* Location parameters for iteration */ + hbool_t follow_link; /* Whether to follow links for query */ + H5G_stat_t * statbuf; /* Pointer to object info struct (OUT) */ +} H5VL_native_group_get_objinfo_t; + +/* Parameters for native connector's group 'optional' operations */ +typedef union H5VL_native_group_optional_args_t { + /* H5VL_NATIVE_GROUP_ITERATE_OLD */ + H5VL_native_group_iterate_old_t iterate_old; + + /* H5VL_NATIVE_GROUP_GET_OBJINFO */ + H5VL_native_group_get_objinfo_t get_objinfo; +} H5VL_native_group_optional_args_t; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + /* Values for native VOL connector object optional VOL operations */ /* NOTE: If new values are added here, the H5VL__native_introspect_opt_query * routine must be updated. @@ -129,6 +458,44 @@ * must be updated. */ +/* Parameters for native connector's object 'get comment' operation */ +typedef struct H5VL_native_object_get_comment_t { + size_t buf_size; /* Size of comment buffer */ + void * buf; /* Buffer for comment (OUT) */ + size_t *comment_len; /* Actual size of comment (OUT) */ +} H5VL_native_object_get_comment_t; + +/* Parameters for object 'get native info' operation */ +typedef struct H5VL_native_object_get_native_info_t { + unsigned fields; /* Fields to retrieve */ + H5O_native_info_t *ninfo; /* Native info (OUT) */ +} H5VL_native_object_get_native_info_t; + +/* Parameters for native connector's object 'optional' operations */ +typedef union H5VL_native_object_optional_args_t { + /* H5VL_NATIVE_OBJECT_GET_COMMENT */ + H5VL_native_object_get_comment_t get_comment; + + /* H5VL_NATIVE_OBJECT_SET_COMMENT */ + struct { + const char *comment; /* Comment string to set for the object (IN) */ + } set_comment; + + /* H5VL_NATIVE_OBJECT_DISABLE_MDC_FLUSHES */ + /* No args */ + + /* H5VL_NATIVE_OBJECT_ENABLE_MDC_FLUSHES */ + /* No args */ + + /* H5VL_NATIVE_OBJECT_ARE_MDC_FLUSHES_DISABLED */ + struct { + hbool_t *flag; /* Flag whether metadata cache flushes are disabled for this object (OUT) */ + } are_mdc_flushes_disabled; + + /* H5VL_NATIVE_OBJECT_GET_NATIVE_INFO */ + H5VL_native_object_get_native_info_t get_native_info; +} H5VL_native_object_optional_args_t; + /*******************/ /* Public Typedefs */ /*******************/ diff --git a/src/H5VLnative_attr.c b/src/H5VLnative_attr.c index f5e5f29..834ae40 100644 --- a/src/H5VLnative_attr.c +++ b/src/H5VLnative_attr.c @@ -245,40 +245,37 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_attr_get(void *obj, H5VL_attr_get_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (get_type) { + switch (args->op_type) { /* H5Aget_space */ case H5VL_ATTR_GET_SPACE: { - hid_t *ret_id = HDva_arg(arguments, hid_t *); - H5A_t *attr = (H5A_t *)obj; + H5A_t *attr = (H5A_t *)obj; - if ((*ret_id = H5A_get_space(attr)) < 0) + if ((args->args.get_space.space_id = H5A_get_space(attr)) < 0) HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get space ID of attribute") break; } /* H5Aget_type */ case H5VL_ATTR_GET_TYPE: { - hid_t *ret_id = HDva_arg(arguments, hid_t *); - H5A_t *attr = (H5A_t *)obj; + H5A_t *attr = (H5A_t *)obj; - if ((*ret_id = H5A__get_type(attr)) < 0) + if ((args->args.get_type.type_id = H5A__get_type(attr)) < 0) HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get datatype ID of attribute") break; } /* H5Aget_create_plist */ case H5VL_ATTR_GET_ACPL: { - hid_t *ret_id = HDva_arg(arguments, hid_t *); - H5A_t *attr = (H5A_t *)obj; + H5A_t *attr = (H5A_t *)obj; - if ((*ret_id = H5A__get_create_plist(attr)) < 0) + if ((args->args.get_acpl.acpl_id = H5A__get_create_plist(attr)) < 0) HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get creation property list for attr") break; @@ -286,40 +283,37 @@ H5VL__native_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t H5_ATTR_UNUSED /* H5Aget_name */ case H5VL_ATTR_GET_NAME: { - const H5VL_loc_params_t *loc_params = HDva_arg(arguments, const H5VL_loc_params_t *); - size_t buf_size = HDva_arg(arguments, size_t); - char * buf = HDva_arg(arguments, char *); - ssize_t * ret_val = HDva_arg(arguments, ssize_t *); - H5A_t * attr = NULL; + H5VL_attr_get_name_args_t *get_name_args = &args->args.get_name; - if (H5VL_OBJECT_BY_SELF == loc_params->type) { - attr = (H5A_t *)obj; - /* Call private function in turn */ - if (0 > (*ret_val = H5A__get_name(attr, buf_size, buf))) + if (H5VL_OBJECT_BY_SELF == get_name_args->loc_params.type) { + if (H5A__get_name((H5A_t *)obj, get_name_args->buf_size, get_name_args->buf, + get_name_args->attr_name_len) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get attribute name") } - else if (H5VL_OBJECT_BY_IDX == loc_params->type) { + else if (H5VL_OBJECT_BY_IDX == get_name_args->loc_params.type) { H5G_loc_t loc; + H5A_t * attr; /* check arguments */ - if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + if (H5G_loc_real(obj, get_name_args->loc_params.obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") /* Open the attribute on the object header */ - if (NULL == (attr = H5A__open_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, - loc_params->loc_data.loc_by_idx.idx_type, - loc_params->loc_data.loc_by_idx.order, - loc_params->loc_data.loc_by_idx.n))) + if (NULL == (attr = H5A__open_by_idx(&loc, get_name_args->loc_params.loc_data.loc_by_idx.name, + get_name_args->loc_params.loc_data.loc_by_idx.idx_type, + get_name_args->loc_params.loc_data.loc_by_idx.order, + get_name_args->loc_params.loc_data.loc_by_idx.n))) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute") /* Get the length of the name */ - *ret_val = (ssize_t)HDstrlen(attr->shared->name); + *get_name_args->attr_name_len = HDstrlen(attr->shared->name); /* Copy the name into the user's buffer, if given */ - if (buf) { - HDstrncpy(buf, attr->shared->name, MIN((size_t)(*ret_val + 1), buf_size)); - if ((size_t)(*ret_val) >= buf_size) - buf[buf_size - 1] = '\0'; + if (get_name_args->buf) { + HDstrncpy(get_name_args->buf, attr->shared->name, + MIN((*get_name_args->attr_name_len + 1), get_name_args->buf_size)); + if (*get_name_args->attr_name_len >= get_name_args->buf_size) + get_name_args->buf[get_name_args->buf_size - 1] = '\0'; } /* end if */ /* Release resources */ @@ -334,52 +328,51 @@ H5VL__native_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t H5_ATTR_UNUSED /* H5Aget_info */ case H5VL_ATTR_GET_INFO: { - const H5VL_loc_params_t *loc_params = HDva_arg(arguments, const H5VL_loc_params_t *); - H5A_info_t * ainfo = HDva_arg(arguments, H5A_info_t *); - H5A_t * attr = NULL; + H5VL_attr_get_info_args_t *get_info_args = &args->args.get_info; + H5A_t * attr = NULL; - if (H5VL_OBJECT_BY_SELF == loc_params->type) { + if (H5VL_OBJECT_BY_SELF == get_info_args->loc_params.type) { attr = (H5A_t *)obj; - if (H5A__get_info(attr, ainfo) < 0) + if (H5A__get_info(attr, get_info_args->ainfo) < 0) HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get attribute info") } - else if (H5VL_OBJECT_BY_NAME == loc_params->type) { - char * attr_name = HDva_arg(arguments, char *); + else if (H5VL_OBJECT_BY_NAME == get_info_args->loc_params.type) { H5G_loc_t loc; /* check arguments */ - if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + if (H5G_loc_real(obj, get_info_args->loc_params.obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") /* Open the attribute on the object header */ if (NULL == - (attr = H5A__open_by_name(&loc, loc_params->loc_data.loc_by_name.name, attr_name))) + (attr = H5A__open_by_name(&loc, get_info_args->loc_params.loc_data.loc_by_name.name, + get_info_args->attr_name))) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute") /* Get the attribute information */ - if (H5A__get_info(attr, ainfo) < 0) + if (H5A__get_info(attr, get_info_args->ainfo) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info") /* Release resources */ if (attr && H5A__close(attr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") } - else if (H5VL_OBJECT_BY_IDX == loc_params->type) { + else if (H5VL_OBJECT_BY_IDX == get_info_args->loc_params.type) { H5G_loc_t loc; /* check arguments */ - if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + if (H5G_loc_real(obj, get_info_args->loc_params.obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") /* Open the attribute on the object header */ - if (NULL == (attr = H5A__open_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, - loc_params->loc_data.loc_by_idx.idx_type, - loc_params->loc_data.loc_by_idx.order, - loc_params->loc_data.loc_by_idx.n))) + if (NULL == (attr = H5A__open_by_idx(&loc, get_info_args->loc_params.loc_data.loc_by_idx.name, + get_info_args->loc_params.loc_data.loc_by_idx.idx_type, + get_info_args->loc_params.loc_data.loc_by_idx.order, + get_info_args->loc_params.loc_data.loc_by_idx.n))) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute") /* Get the attribute information */ - if (H5A__get_info(attr, ainfo) < 0) + if (H5A__get_info(attr, get_info_args->ainfo) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info") /* Release resources */ @@ -393,11 +386,10 @@ H5VL__native_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t H5_ATTR_UNUSED } case H5VL_ATTR_GET_STORAGE_SIZE: { - hsize_t *ret = HDva_arg(arguments, hsize_t *); - H5A_t * attr = (H5A_t *)obj; + H5A_t *attr = (H5A_t *)obj; - /* Set return value */ - *ret = attr->shared->data_size; + /* Set storage size */ + *args->args.get_storage_size.data_size = attr->shared->data_size; break; } @@ -419,8 +411,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_attr_specific_t specific_type, - hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_attr_specific_args_t *args, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) { H5G_loc_t loc; herr_t ret_value = SUCCEED; /* Return value */ @@ -431,48 +423,51 @@ H5VL__native_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_ if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - switch (specific_type) { + switch (args->op_type) { + /* H5Adelete/delete_by_name */ case H5VL_ATTR_DELETE: { - char *attr_name = HDva_arg(arguments, char *); - if (H5VL_OBJECT_BY_SELF == loc_params->type) { - /* H5Adelete */ /* Delete the attribute from the location */ - if (H5O__attr_remove(loc.oloc, attr_name) < 0) + if (H5O__attr_remove(loc.oloc, args->args.del.name) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") } /* end if */ else if (H5VL_OBJECT_BY_NAME == loc_params->type) { - /* H5Adelete_by_name */ /* Delete the attribute */ - if (H5A__delete_by_name(&loc, loc_params->loc_data.loc_by_name.name, attr_name) < 0) + if (H5A__delete_by_name(&loc, loc_params->loc_data.loc_by_name.name, args->args.del.name) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") } /* end else-if */ - else if (H5VL_OBJECT_BY_IDX == loc_params->type) { - /* H5Adelete_by_idx */ + else + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown attribute delete location") + break; + } + + /* H5Adelete_by_idx */ + case H5VL_ATTR_DELETE_BY_IDX: { + H5VL_attr_delete_by_idx_args_t *del_by_idx_args = + &args->args.delete_by_idx; /* Arguments to delete_by_idx operation */ + + if (H5VL_OBJECT_BY_NAME == loc_params->type) { /* Delete the attribute from the location */ - if (H5A__delete_by_idx( - &loc, loc_params->loc_data.loc_by_idx.name, loc_params->loc_data.loc_by_idx.idx_type, - loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n) < 0) + if (H5A__delete_by_idx(&loc, loc_params->loc_data.loc_by_name.name, del_by_idx_args->idx_type, + del_by_idx_args->order, del_by_idx_args->n) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") - } /* end else-if */ + } /* end if */ else - HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown attribute remove parameters") + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown attribute delete_by_idx location") break; } + /* H5Aexists/exists_by_name */ case H5VL_ATTR_EXISTS: { - const char *attr_name = HDva_arg(arguments, const char *); - hbool_t * attr_exists = HDva_arg(arguments, hbool_t *); - - if (loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Aexists */ + if (loc_params->type == H5VL_OBJECT_BY_SELF) { /* Check if the attribute exists */ - if (H5O__attr_exists(loc.oloc, attr_name, attr_exists) < 0) + if (H5O__attr_exists(loc.oloc, args->args.exists.name, args->args.exists.exists) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") - } /* end if */ - else if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Aexists_by_name */ + } /* end if */ + else if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* Check if the attribute exists */ - if (H5A__exists_by_name(loc, loc_params->loc_data.loc_by_name.name, attr_name, attr_exists) < - 0) + if (H5A__exists_by_name(loc, loc_params->loc_data.loc_by_name.name, args->args.exists.name, + args->args.exists.exists) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") } /* end else-if */ else @@ -480,42 +475,38 @@ H5VL__native_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_ break; } + /* H5Aiterate/iterate_by_name */ case H5VL_ATTR_ITER: { - H5_index_t idx_type = (H5_index_t)HDva_arg(arguments, int); /* enum work-around */ - H5_iter_order_t order = (H5_iter_order_t)HDva_arg(arguments, int); /* enum work-around */ - hsize_t * idx = HDva_arg(arguments, hsize_t *); - H5A_operator2_t op = HDva_arg(arguments, H5A_operator2_t); - void * op_data = HDva_arg(arguments, void *); - - if (loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Aiterate2 */ - /* Iterate over attributes */ - if ((ret_value = H5A__iterate(&loc, ".", idx_type, order, idx, op, op_data)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_BADITER, FAIL, "error iterating over attributes") - } /* end if */ - else if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Aiterate_by_name */ - /* Iterate over attributes by name */ - if ((ret_value = H5A__iterate(&loc, loc_params->loc_data.loc_by_name.name, idx_type, order, - idx, op, op_data)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_BADITER, FAIL, "attribute iteration failed"); - } /* end else-if */ + H5VL_attr_iterate_args_t *iter_args = &args->args.iterate; /* Arguments to iterate operation */ + static const char * self_name = "."; /* Name for 'self' location */ + const char * loc_name; /* Location name */ + + /* Set correct name, for type of location */ + if (loc_params->type == H5VL_OBJECT_BY_SELF) /* H5Aiterate2 */ + loc_name = self_name; + else if (loc_params->type == H5VL_OBJECT_BY_NAME) /* H5Aiterate_by_name */ + loc_name = loc_params->loc_data.loc_by_name.name; else - HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown parameters") + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unsupported location type") + + /* Iterate over attributes */ + if ((ret_value = H5A__iterate(&loc, loc_name, iter_args->idx_type, iter_args->order, + iter_args->idx, iter_args->op, iter_args->op_data)) < 0) + HERROR(H5E_ATTR, H5E_BADITER, "attribute iteration failed"); break; } /* H5Arename/rename_by_name */ case H5VL_ATTR_RENAME: { - const char *old_name = HDva_arg(arguments, const char *); - const char *new_name = HDva_arg(arguments, const char *); - if (loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Arename */ /* Call attribute rename routine */ - if (H5O__attr_rename(loc.oloc, old_name, new_name) < 0) + if (H5O__attr_rename(loc.oloc, args->args.rename.old_name, args->args.rename.new_name) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute") } /* end if */ else if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Arename_by_name */ /* Call attribute rename routine */ - if (H5A__rename_by_name(loc, loc_params->loc_data.loc_by_name.name, old_name, new_name) < 0) + if (H5A__rename_by_name(loc, loc_params->loc_data.loc_by_name.name, + args->args.rename.old_name, args->args.rename.new_name) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute") } /* end else-if */ else @@ -541,24 +532,24 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_attr_optional(void H5_ATTR_UNUSED *obj, H5VL_attr_optional_t opt_type, - hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, - va_list H5_ATTR_DEPRECATED_USED arguments) +H5VL__native_attr_optional(void H5_ATTR_UNUSED *obj, H5VL_optional_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { - herr_t ret_value = SUCCEED; /* Return value */ +#ifndef H5_NO_DEPRECATED_SYMBOLS + H5VL_native_attr_optional_args_t *opt_args = args->args; /* Pointer to native operation's arguments */ +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (opt_type) { + switch (args->op_type) { #ifndef H5_NO_DEPRECATED_SYMBOLS case H5VL_NATIVE_ATTR_ITERATE_OLD: { - hid_t loc_id = HDva_arg(arguments, hid_t); - unsigned * attr_num = HDva_arg(arguments, unsigned *); - H5A_operator1_t op = HDva_arg(arguments, H5A_operator1_t); - void * op_data = HDva_arg(arguments, void *); + H5VL_native_attr_iterate_old_t *iter_args = &opt_args->iterate_old; /* Call the actual iteration routine */ - if ((ret_value = H5A__iterate_old(loc_id, attr_num, op, op_data)) < 0) + if ((ret_value = H5A__iterate_old(iter_args->loc_id, iter_args->attr_num, iter_args->op, + iter_args->op_data)) < 0) HERROR(H5E_VOL, H5E_BADITER, "error iterating over attributes"); break; diff --git a/src/H5VLnative_blob.c b/src/H5VLnative_blob.c index 170a5bc..1107227 100644 --- a/src/H5VLnative_blob.c +++ b/src/H5VLnative_blob.c @@ -145,7 +145,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments) +H5VL__native_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_args_t *args) { H5F_t *f = (H5F_t *)obj; /* Retrieve file pointer */ herr_t ret_value = SUCCEED; /* Return value */ @@ -156,44 +156,24 @@ H5VL__native_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t specif HDassert(f); HDassert(blob_id); - switch (specific_type) { - case H5VL_BLOB_GETSIZE: { - const uint8_t *id = (const uint8_t *)blob_id; /* Pointer to the blob ID */ - size_t * size = HDva_arg(arguments, size_t *); - H5HG_t hobjid; /* blob's heap ID */ - - /* Get heap information */ - H5F_addr_decode(f, &id, &(hobjid.addr)); - UINT32DECODE(id, hobjid.idx); - - /* Get heap object's size */ - if (hobjid.addr > 0) { - if (H5HG_get_obj_size(f, &hobjid, size) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTREMOVE, FAIL, "unable to remove heap object") - } /* end if */ - else - *size = 0; /* Return '0' size for 'nil' blob ID */ - - break; - } - + switch (args->op_type) { case H5VL_BLOB_ISNULL: { - const uint8_t *id = (const uint8_t *)blob_id; /* Pointer to the blob ID */ - hbool_t * isnull = HDva_arg(arguments, hbool_t *); - haddr_t addr; /* Sequence's heap address */ + const uint8_t *id = (const uint8_t *)blob_id; /* Pointer to the blob ID */ + haddr_t addr; /* Sequence's heap address */ /* Get the heap address */ H5F_addr_decode(f, &id, &addr); /* Check if heap address is 'nil' */ - *isnull = (addr == 0 ? TRUE : FALSE); + *args->args.is_null.isnull = (addr == 0 ? TRUE : FALSE); break; } case H5VL_BLOB_SETNULL: { uint8_t *id = (uint8_t *)blob_id; /* Pointer to the blob ID */ - /* Encode the "nil" heap pointer information */ + + /* Encode the 'nil' heap pointer information */ H5F_addr_encode(f, &id, (haddr_t)0); UINT32ENCODE(id, 0); diff --git a/src/H5VLnative_dataset.c b/src/H5VLnative_dataset.c index 3a7f105..1375344 100644 --- a/src/H5VLnative_dataset.c +++ b/src/H5VLnative_dataset.c @@ -369,31 +369,26 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_dataset_get(void *obj, H5VL_dataset_get_t get_type, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_dataset_get(void *obj, H5VL_dataset_get_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { H5D_t *dset = (H5D_t *)obj; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (get_type) { + switch (args->op_type) { /* H5Dget_space */ case H5VL_DATASET_GET_SPACE: { - hid_t *ret_id = HDva_arg(arguments, hid_t *); - - if ((*ret_id = H5D__get_space(dset)) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get space ID of dataset") + if ((args->args.get_space.space_id = H5D__get_space(dset)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get space ID of dataset") break; } /* H5Dget_space_status */ case H5VL_DATASET_GET_SPACE_STATUS: { - H5D_space_status_t *allocation = HDva_arg(arguments, H5D_space_status_t *); - - /* Read data space address and return */ - if (H5D__get_space_status(dset, allocation) < 0) + if (H5D__get_space_status(dset, args->args.get_space_status.status) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get space status") break; @@ -401,40 +396,31 @@ H5VL__native_dataset_get(void *obj, H5VL_dataset_get_t get_type, hid_t H5_ATTR_U /* H5Dget_type */ case H5VL_DATASET_GET_TYPE: { - hid_t *ret_id = HDva_arg(arguments, hid_t *); - - if ((*ret_id = H5D__get_type(dset)) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get datatype ID of dataset") + if ((args->args.get_type.type_id = H5D__get_type(dset)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get datatype ID of dataset") break; } /* H5Dget_create_plist */ case H5VL_DATASET_GET_DCPL: { - hid_t *ret_id = HDva_arg(arguments, hid_t *); - - if ((*ret_id = H5D_get_create_plist(dset)) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get creation property list for dataset") + if ((args->args.get_dcpl.dcpl_id = H5D_get_create_plist(dset)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get creation property list for dataset") break; } /* H5Dget_access_plist */ case H5VL_DATASET_GET_DAPL: { - hid_t *ret_id = HDva_arg(arguments, hid_t *); - - if ((*ret_id = H5D_get_access_plist(dset)) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get access property list for dataset") + if ((args->args.get_dapl.dapl_id = H5D_get_access_plist(dset)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get access property list for dataset") break; } /* H5Dget_storage_size */ case H5VL_DATASET_GET_STORAGE_SIZE: { - hsize_t *ret = HDva_arg(arguments, hsize_t *); - - /* Set return value */ - if (H5D__get_storage_size(dset, ret) < 0) + if (H5D__get_storage_size(dset, args->args.get_storage_size.storage_size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get size of dataset's storage") break; } @@ -457,69 +443,38 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_dataset_specific(void *obj, H5VL_dataset_specific_t specific_type, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_dataset_specific(void *obj, H5VL_dataset_specific_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { H5D_t *dset = (H5D_t *)obj; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (specific_type) { - /* H5Dspecific_space */ - case H5VL_DATASET_SET_EXTENT: { /* H5Dset_extent (H5Dextend - deprecated) */ - const hsize_t *size = HDva_arg(arguments, const hsize_t *); - - if (H5D__set_extent(dset, size) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set extent of dataset") + switch (args->op_type) { + /* H5Dset_extent (H5Dextend - deprecated) */ + case H5VL_DATASET_SET_EXTENT: { + if (H5D__set_extent(dset, args->args.set_extent.size) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to set extent of dataset") break; } - case H5VL_DATASET_FLUSH: { /* H5Dflush */ - hid_t dset_id = HDva_arg(arguments, hid_t); - - /* Flush the dataset */ - if (H5D__flush(dset, dset_id) < 0) + /* H5Dflush */ + case H5VL_DATASET_FLUSH: { + if (H5D__flush(dset, args->args.flush.dset_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to flush dataset") break; } - case H5VL_DATASET_REFRESH: { /* H5Drefresh */ - hid_t dset_id = HDva_arg(arguments, hid_t); - - /* Refresh the dataset */ - if ((H5D__refresh(dset_id, dset)) < 0) + /* H5Drefresh */ + case H5VL_DATASET_REFRESH: { + if (H5D__refresh(dset, args->args.refresh.dset_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTLOAD, FAIL, "unable to refresh dataset") break; } - case H5VL_DATASET_WAIT: { /* H5Dwait */ - /* The native VOL connector doesn't support asynchronous - * operations, so this is a no-op. - */ - break; - } - - case H5VL_DATASET_CHUNK_ITER: { /* H5Dchunk_iter */ - H5D_chunk_iter_op_t cb = HDva_arg(arguments, H5D_chunk_iter_op_t); - void * op_data = HDva_arg(arguments, void *); - - HDassert(dset->shared); - - /* Make sure the dataset is chunked */ - if (H5D_CHUNKED != dset->shared->layout.type) { - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a chunked dataset") - } - - /* Call private function */ - if (H5D__chunk_iter(dset, cb, op_data) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't iterate over chunks") - - break; - } - default: HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid specific operation") } /* end switch */ @@ -538,11 +493,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_dataset_optional(void *obj, H5VL_dataset_optional_t optional_type, hid_t dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_dataset_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void H5_ATTR_UNUSED **req) { - H5D_t *dset = (H5D_t *)obj; /* Dataset */ - herr_t ret_value = SUCCEED; /* Return value */ + H5D_t * dset = (H5D_t *)obj; /* Dataset */ + H5VL_native_dataset_optional_args_t *opt_args = args->args; /* Pointer to native operation's arguments */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -552,13 +507,14 @@ H5VL__native_dataset_optional(void *obj, H5VL_dataset_optional_t optional_type, /* Set DXPL for operation */ H5CX_set_dxpl(dxpl_id); - switch (optional_type) { - case H5VL_NATIVE_DATASET_FORMAT_CONVERT: { /* H5Dformat_convert */ + switch (args->op_type) { + /* H5Dformat_convert */ + case H5VL_NATIVE_DATASET_FORMAT_CONVERT: { switch (dset->shared->layout.type) { case H5D_CHUNKED: /* Convert the chunk indexing type to version 1 B-tree if not */ if (dset->shared->layout.u.chunk.idx_type != H5D_CHUNK_IDX_BTREE) - if ((H5D__format_convert(dset)) < 0) + if (H5D__format_convert(dset) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTLOAD, FAIL, "unable to downgrade chunk indexing type for dataset") break; @@ -567,7 +523,7 @@ H5VL__native_dataset_optional(void *obj, H5VL_dataset_optional_t optional_type, case H5D_COMPACT: /* Downgrade the layout version to 3 if greater than 3 */ if (dset->shared->layout.version > H5O_LAYOUT_VERSION_DEFAULT) - if ((H5D__format_convert(dset)) < 0) + if (H5D__format_convert(dset) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTLOAD, FAIL, "unable to downgrade layout version for dataset") break; @@ -587,47 +543,46 @@ H5VL__native_dataset_optional(void *obj, H5VL_dataset_optional_t optional_type, break; } - case H5VL_NATIVE_DATASET_GET_CHUNK_INDEX_TYPE: { /* H5Dget_chunk_index_type */ - H5D_chunk_index_t *idx_type = HDva_arg(arguments, H5D_chunk_index_t *); - + /* H5Dget_chunk_index_type */ + case H5VL_NATIVE_DATASET_GET_CHUNK_INDEX_TYPE: { /* Make sure the dataset is chunked */ if (H5D_CHUNKED != dset->shared->layout.type) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a chunked dataset") /* Get the chunk indexing type */ - *idx_type = dset->shared->layout.u.chunk.idx_type; + *opt_args->get_chunk_idx_type.idx_type = dset->shared->layout.u.chunk.idx_type; break; } - case H5VL_NATIVE_DATASET_GET_CHUNK_STORAGE_SIZE: { /* H5Dget_chunk_storage_size */ - hsize_t *offset = HDva_arg(arguments, hsize_t *); - hsize_t *chunk_nbytes = HDva_arg(arguments, hsize_t *); + /* H5Dget_chunk_storage_size */ + case H5VL_NATIVE_DATASET_GET_CHUNK_STORAGE_SIZE: { + H5VL_native_dataset_get_chunk_storage_size_t *gcss_args = &opt_args->get_chunk_storage_size; /* Make sure the dataset is chunked */ if (H5D_CHUNKED != dset->shared->layout.type) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a chunked dataset") /* Call private function */ - if (H5D__get_chunk_storage_size(dset, offset, chunk_nbytes) < 0) + if (H5D__get_chunk_storage_size(dset, gcss_args->offset, gcss_args->size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get storage size of chunk") break; } - case H5VL_NATIVE_DATASET_GET_NUM_CHUNKS: { /* H5Dget_num_chunks */ - const H5S_t *space = NULL; - hid_t space_id = HDva_arg(arguments, hid_t); - hsize_t * nchunks = HDva_arg(arguments, hsize_t *); + /* H5Dget_num_chunks */ + case H5VL_NATIVE_DATASET_GET_NUM_CHUNKS: { + H5VL_native_dataset_get_num_chunks_t *gnc_args = &opt_args->get_num_chunks; + const H5S_t * space = NULL; HDassert(dset->shared); HDassert(dset->shared->space); /* When default dataspace is given, use the dataset's dataspace */ - if (space_id == H5S_ALL) + if (gnc_args->space_id == H5S_ALL) space = dset->shared->space; else /* otherwise, use the given space ID */ - if (NULL == (space = (const H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + if (NULL == (space = (const H5S_t *)H5I_object_verify(gnc_args->space_id, H5I_DATASPACE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a valid dataspace ID") /* Make sure the dataset is chunked */ @@ -635,29 +590,25 @@ H5VL__native_dataset_optional(void *obj, H5VL_dataset_optional_t optional_type, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a chunked dataset") /* Call private function */ - if (H5D__get_num_chunks(dset, space, nchunks) < 0) + if (H5D__get_num_chunks(dset, space, gnc_args->nchunks) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get number of chunks") break; } - case H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_IDX: { /* H5Dget_chunk_info */ - const H5S_t *space = NULL; - hid_t space_id = HDva_arg(arguments, hid_t); - hsize_t chk_index = HDva_arg(arguments, hsize_t); - hsize_t * offset = HDva_arg(arguments, hsize_t *); - unsigned * filter_mask = HDva_arg(arguments, unsigned *); - haddr_t * addr = HDva_arg(arguments, haddr_t *); - hsize_t * size = HDva_arg(arguments, hsize_t *); + /* H5Dget_chunk_info */ + case H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_IDX: { + H5VL_native_dataset_get_chunk_info_by_idx_t *gcibi_args = &opt_args->get_chunk_info_by_idx; + const H5S_t * space; HDassert(dset->shared); HDassert(dset->shared->space); /* When default dataspace is given, use the dataset's dataspace */ - if (space_id == H5S_ALL) + if (gcibi_args->space_id == H5S_ALL) space = dset->shared->space; else /* otherwise, use the given space ID */ - if (NULL == (space = (const H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + if (NULL == (space = (const H5S_t *)H5I_object_verify(gcibi_args->space_id, H5I_DATASPACE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a valid dataspace ID") /* Make sure the dataset is chunked */ @@ -665,16 +616,16 @@ H5VL__native_dataset_optional(void *obj, H5VL_dataset_optional_t optional_type, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a chunked dataset") /* Call private function */ - if (H5D__get_chunk_info(dset, space, chk_index, offset, filter_mask, addr, size) < 0) + if (H5D__get_chunk_info(dset, space, gcibi_args->chk_index, gcibi_args->offset, + gcibi_args->filter_mask, gcibi_args->addr, gcibi_args->size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk info by index") + break; } - case H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_COORD: { /* H5Dget_chunk_info_by_coord */ - hsize_t * offset = HDva_arg(arguments, hsize_t *); - unsigned *filter_mask = HDva_arg(arguments, unsigned *); - haddr_t * addr = HDva_arg(arguments, haddr_t *); - hsize_t * size = HDva_arg(arguments, hsize_t *); + /* H5Dget_chunk_info_by_coord */ + case H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_COORD: { + H5VL_native_dataset_get_chunk_info_by_coord_t *gcibc_args = &opt_args->get_chunk_info_by_coord; HDassert(dset->shared); @@ -683,17 +634,17 @@ H5VL__native_dataset_optional(void *obj, H5VL_dataset_optional_t optional_type, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a chunked dataset") /* Call private function */ - if (H5D__get_chunk_info_by_coord(dset, offset, filter_mask, addr, size) < 0) + if (H5D__get_chunk_info_by_coord(dset, gcibc_args->offset, gcibc_args->filter_mask, + gcibc_args->addr, gcibc_args->size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk info by its logical coordinates") break; } - case H5VL_NATIVE_DATASET_CHUNK_READ: { /* H5Dread_chunk */ - const hsize_t *offset = HDva_arg(arguments, hsize_t *); - uint32_t * filters = HDva_arg(arguments, uint32_t *); - void * buf = HDva_arg(arguments, void *); - hsize_t offset_copy[H5O_LAYOUT_NDIMS]; /* Internal copy of chunk offset */ + /* H5Dread_chunk */ + case H5VL_NATIVE_DATASET_CHUNK_READ: { + H5VL_native_dataset_chunk_read_t *chunk_read_args = &opt_args->chunk_read; + hsize_t offset_copy[H5O_LAYOUT_NDIMS]; /* Internal copy of chunk offset */ /* Check arguments */ if (NULL == dset->oloc.file) @@ -704,22 +655,21 @@ H5VL__native_dataset_optional(void *obj, H5VL_dataset_optional_t optional_type, /* Copy the user's offset array so we can be sure it's terminated properly. * (we don't want to mess with the user's buffer). */ - if (H5D__get_offset_copy(dset, offset, offset_copy) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "failure to copy offset array") + if (H5D__chunk_get_offset_copy(dset, chunk_read_args->offset, offset_copy) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "failure to copy offset array") /* Read the raw chunk */ - if (H5D__chunk_direct_read(dset, offset_copy, filters, buf) < 0) + if (H5D__chunk_direct_read(dset, offset_copy, &chunk_read_args->filters, chunk_read_args->buf) < + 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read unprocessed chunk data") break; } - case H5VL_NATIVE_DATASET_CHUNK_WRITE: { /* H5Dwrite_chunk */ - uint32_t filters = HDva_arg(arguments, uint32_t); - const hsize_t *offset = HDva_arg(arguments, const hsize_t *); - uint32_t data_size_32 = HDva_arg(arguments, uint32_t); - const void * buf = HDva_arg(arguments, const void *); - hsize_t offset_copy[H5O_LAYOUT_NDIMS]; /* Internal copy of chunk offset */ + /* H5Dwrite_chunk */ + case H5VL_NATIVE_DATASET_CHUNK_WRITE: { + H5VL_native_dataset_chunk_write_t *chunk_write_args = &opt_args->chunk_write; + hsize_t offset_copy[H5O_LAYOUT_NDIMS]; /* Internal copy of chunk offset */ /* Check arguments */ if (NULL == dset->oloc.file) @@ -730,34 +680,48 @@ H5VL__native_dataset_optional(void *obj, H5VL_dataset_optional_t optional_type, /* Copy the user's offset array so we can be sure it's terminated properly. * (we don't want to mess with the user's buffer). */ - if (H5D__get_offset_copy(dset, offset, offset_copy) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "failure to copy offset array") + if (H5D__chunk_get_offset_copy(dset, chunk_write_args->offset, offset_copy) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "failure to copy offset array") /* Write chunk */ - if (H5D__chunk_direct_write(dset, filters, offset_copy, data_size_32, buf) < 0) + if (H5D__chunk_direct_write(dset, chunk_write_args->filters, offset_copy, chunk_write_args->size, + chunk_write_args->buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write unprocessed chunk data") break; } - case H5VL_NATIVE_DATASET_GET_VLEN_BUF_SIZE: { /* H5Dvlen_get_buf_size */ - hid_t type_id = HDva_arg(arguments, hid_t); - hid_t space_id = HDva_arg(arguments, hid_t); - hsize_t *size = HDva_arg(arguments, hsize_t *); + /* H5Dvlen_get_buf_size */ + case H5VL_NATIVE_DATASET_GET_VLEN_BUF_SIZE: { + H5VL_native_dataset_get_vlen_buf_size_t *gvbs_args = &opt_args->get_vlen_buf_size; - if (H5D__vlen_get_buf_size(dset, type_id, space_id, size) < 0) + if (H5D__vlen_get_buf_size(dset, gvbs_args->type_id, gvbs_args->space_id, gvbs_args->size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get size of vlen buf needed") break; } /* H5Dget_offset */ case H5VL_NATIVE_DATASET_GET_OFFSET: { - haddr_t *ret = HDva_arg(arguments, haddr_t *); + /* Get offset */ + *opt_args->get_offset.offset = H5D__get_offset(dset); + + break; + } + + /* H5Dchunk_iter */ + case H5VL_NATIVE_DATASET_CHUNK_ITER: { + /* Sanity check */ + HDassert(dset->shared); + + /* Make sure the dataset is chunked */ + if (H5D_CHUNKED != dset->shared->layout.type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a chunked dataset") + + /* Call private function */ + if ((ret_value = H5D__chunk_iter(dset, opt_args->chunk_iter.op, opt_args->chunk_iter.op_data)) < + 0) + HERROR(H5E_DATASET, H5E_BADITER, "chunk iteration failed"); - /* Set return value */ - *ret = H5D__get_offset(dset); - if (!H5F_addr_defined(*ret)) - *ret = HADDR_UNDEF; break; } diff --git a/src/H5VLnative_datatype.c b/src/H5VLnative_datatype.c index 84b13c3..bf6f37c 100644 --- a/src/H5VLnative_datatype.c +++ b/src/H5VLnative_datatype.c @@ -175,32 +175,34 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_datatype_get(void *obj, H5VL_datatype_get_t get_type, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_datatype_get(void *obj, H5VL_datatype_get_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { H5T_t *dt = (H5T_t *)obj; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (get_type) { - case H5VL_DATATYPE_GET_BINARY: { - ssize_t *nalloc = HDva_arg(arguments, ssize_t *); - void * buf = HDva_arg(arguments, void *); - size_t size = HDva_arg(arguments, size_t); + switch (args->op_type) { + /* H5T_construct_datatype (library private routine) */ + case H5VL_DATATYPE_GET_BINARY_SIZE: { + if (H5T_encode(dt, NULL, args->args.get_binary_size.size) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't determine serialized length of datatype") + + break; + } - if (H5T_encode(dt, (unsigned char *)buf, &size) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't determine serialized length of datatype") + /* H5T_construct_datatype (library private routine) */ + case H5VL_DATATYPE_GET_BINARY: { + if (H5T_encode(dt, args->args.get_binary.buf, &args->args.get_binary.buf_size) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSERIALIZE, FAIL, "can't serialize datatype") - *nalloc = (ssize_t)size; break; } /* H5Tget_create_plist */ case H5VL_DATATYPE_GET_TCPL: { - hid_t *ret_id = HDva_arg(arguments, hid_t *); - - if (H5I_INVALID_HID == (*ret_id = H5T__get_create_plist(dt))) + if (H5I_INVALID_HID == (args->args.get_tcpl.tcpl_id = H5T__get_create_plist(dt))) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get object creation info"); break; @@ -224,30 +226,26 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_datatype_specific(void *obj, H5VL_datatype_specific_t specific_type, - hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_datatype_specific(void *obj, H5VL_datatype_specific_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { H5T_t *dt = (H5T_t *)obj; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (specific_type) { + switch (args->op_type) { + /* H5VL_DATATYPE_FLUSH */ case H5VL_DATATYPE_FLUSH: { - hid_t type_id = HDva_arg(arguments, hid_t); - - /* To flush metadata and invoke flush callback if there is */ - if (H5O_flush_common(&dt->oloc, type_id) < 0) + if (H5O_flush_common(&dt->oloc, args->args.flush.type_id) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFLUSH, FAIL, "unable to flush datatype") break; } + /* H5VL_DATATYPE_REFRESH */ case H5VL_DATATYPE_REFRESH: { - hid_t type_id = HDva_arg(arguments, hid_t); - - /* Call private function to refresh datatype object */ - if ((H5O_refresh_metadata(type_id, dt->oloc)) < 0) + if ((H5O_refresh_metadata(&dt->oloc, args->args.refresh.type_id)) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTLOAD, FAIL, "unable to refresh datatype") break; diff --git a/src/H5VLnative_file.c b/src/H5VLnative_file.c index 3bcaaba..4653bea 100644 --- a/src/H5VLnative_file.c +++ b/src/H5VLnative_file.c @@ -147,21 +147,18 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_file_get(void *obj, H5VL_file_get_t get_type, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_file_get(void *obj, H5VL_file_get_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { H5F_t *f = NULL; /* File struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (get_type) { + switch (args->op_type) { /* "get container info" */ case H5VL_FILE_GET_CONT_INFO: { - H5VL_file_cont_info_t *info = HDva_arg(arguments, H5VL_file_cont_info_t *); - - /* Retrieve the file's container info */ - if (H5F__get_cont_info((H5F_t *)obj, info) < 0) + if (H5F__get_cont_info((H5F_t *)obj, args->args.get_cont_info.info) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file container info") break; @@ -169,31 +166,22 @@ H5VL__native_file_get(void *obj, H5VL_file_get_t get_type, hid_t H5_ATTR_UNUSED /* H5Fget_access_plist */ case H5VL_FILE_GET_FAPL: { - H5P_genplist_t *new_plist; /* New property list */ - hid_t * plist_id = HDva_arg(arguments, hid_t *); - - f = (H5F_t *)obj; - - /* Retrieve the file's access property list */ - if ((*plist_id = H5F_get_access_plist(f, TRUE)) < 0) + if ((args->args.get_fapl.fapl_id = H5F_get_access_plist((H5F_t *)obj, TRUE)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file access property list") - if (NULL == (new_plist = (H5P_genplist_t *)H5I_object(*plist_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") break; } /* H5Fget_create_plist */ case H5VL_FILE_GET_FCPL: { H5P_genplist_t *plist; /* Property list */ - hid_t * plist_id = HDva_arg(arguments, hid_t *); f = (H5F_t *)obj; if (NULL == (plist = (H5P_genplist_t *)H5I_object(f->shared->fcpl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") /* Create the property list object to return */ - if ((*plist_id = H5P_copy_plist(plist, TRUE)) < 0) + if ((args->args.get_fcpl.fcpl_id = H5P_copy_plist(plist, TRUE)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to copy file creation properties") break; @@ -201,8 +189,6 @@ H5VL__native_file_get(void *obj, H5VL_file_get_t get_type, hid_t H5_ATTR_UNUSED /* H5Fget_intent */ case H5VL_FILE_GET_INTENT: { - unsigned *intent_flags = HDva_arg(arguments, unsigned *); - f = (H5F_t *)obj; /* HDF5 uses some flags internally that users don't know about. @@ -210,18 +196,18 @@ H5VL__native_file_get(void *obj, H5VL_file_get_t get_type, hid_t H5_ATTR_UNUSED * or H5F_ACC_RDONLY and any SWMR flags. */ if (H5F_INTENT(f) & H5F_ACC_RDWR) { - *intent_flags = H5F_ACC_RDWR; + *args->args.get_intent.flags = H5F_ACC_RDWR; /* Check for SWMR write access on the file */ if (H5F_INTENT(f) & H5F_ACC_SWMR_WRITE) - *intent_flags |= H5F_ACC_SWMR_WRITE; + *args->args.get_intent.flags |= H5F_ACC_SWMR_WRITE; } /* end if */ else { - *intent_flags = H5F_ACC_RDONLY; + *args->args.get_intent.flags = H5F_ACC_RDONLY; /* Check for SWMR read access on the file */ if (H5F_INTENT(f) & H5F_ACC_SWMR_READ) - *intent_flags |= H5F_ACC_SWMR_READ; + *args->args.get_intent.flags |= H5F_ACC_SWMR_READ; } /* end else */ break; @@ -229,71 +215,52 @@ H5VL__native_file_get(void *obj, H5VL_file_get_t get_type, hid_t H5_ATTR_UNUSED /* H5Fget_fileno */ case H5VL_FILE_GET_FILENO: { - unsigned long *fno = HDva_arg(arguments, unsigned long *); - unsigned long my_fileno = 0; + unsigned long fileno = 0; - f = (H5F_t *)obj; - H5F_GET_FILENO(f, my_fileno); - *fno = my_fileno; /* sigh */ + H5F_GET_FILENO((H5F_t *)obj, fileno); + *args->args.get_fileno.fileno = fileno; break; } /* H5Fget_name */ case H5VL_FILE_GET_NAME: { - H5I_type_t type = (H5I_type_t)HDva_arg(arguments, int); /* enum work-around */ - size_t size = HDva_arg(arguments, size_t); - char * name = HDva_arg(arguments, char *); - ssize_t * ret = HDva_arg(arguments, ssize_t *); - size_t len; + H5VL_file_get_name_args_t *file_args = &args->args.get_name; - if (H5VL_native_get_file_struct(obj, type, &f) < 0) + if (H5VL_native_get_file_struct(obj, file_args->type, &f) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - len = HDstrlen(H5F_OPEN_NAME(f)); + /* Get length of file name */ + *file_args->file_name_len = HDstrlen(H5F_OPEN_NAME(f)); - if (name) { - HDstrncpy(name, H5F_OPEN_NAME(f), MIN(len + 1, size)); - if (len >= size) - name[size - 1] = '\0'; + /* Populate buffer with name, if given */ + if (file_args->buf) { + HDstrncpy(file_args->buf, H5F_OPEN_NAME(f), + MIN(*file_args->file_name_len + 1, file_args->buf_size)); + if (*file_args->file_name_len >= file_args->buf_size) + file_args->buf[file_args->buf_size - 1] = '\0'; } /* end if */ - /* Set the return value for the API call */ - *ret = (ssize_t)len; break; } /* H5Fget_obj_count */ case H5VL_FILE_GET_OBJ_COUNT: { - unsigned types = HDva_arg(arguments, unsigned); - ssize_t *ret = HDva_arg(arguments, ssize_t *); - size_t obj_count = 0; /* Number of opened objects */ - - f = (H5F_t *)obj; - /* Perform the query */ - if (H5F_get_obj_count(f, types, TRUE, &obj_count) < 0) - HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F_get_obj_count failed") + if (H5F_get_obj_count((H5F_t *)obj, args->args.get_obj_count.types, TRUE, + args->args.get_obj_count.count) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve object count") - /* Set the return value */ - *ret = (ssize_t)obj_count; break; } /* H5Fget_obj_ids */ case H5VL_FILE_GET_OBJ_IDS: { - unsigned types = HDva_arg(arguments, unsigned); - size_t max_objs = HDva_arg(arguments, size_t); - hid_t * oid_list = HDva_arg(arguments, hid_t *); - ssize_t *ret = HDva_arg(arguments, ssize_t *); - size_t obj_count = 0; /* Number of opened objects */ + H5VL_file_get_obj_ids_args_t *file_args = &args->args.get_obj_ids; - f = (H5F_t *)obj; - /* Perform the query */ - if (H5F_get_obj_ids(f, types, max_objs, oid_list, TRUE, &obj_count) < 0) - HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F_get_obj_ids failed") + if (H5F_get_obj_ids((H5F_t *)obj, file_args->types, file_args->max_objs, file_args->oid_list, + TRUE, file_args->count) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve object IDs") - /* Set the return value */ - *ret = (ssize_t)obj_count; break; } @@ -315,22 +282,20 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_file_specific(void *obj, H5VL_file_specific_t specific_type, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_file_specific(void *obj, H5VL_file_specific_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (specific_type) { + switch (args->op_type) { /* H5Fflush */ case H5VL_FILE_FLUSH: { - H5I_type_t type = (H5I_type_t)HDva_arg(arguments, int); /* enum work-around */ - H5F_scope_t scope = (H5F_scope_t)HDva_arg(arguments, int); /* enum work-around */ - H5F_t * f = NULL; /* File to flush */ + H5F_t *f = NULL; /* File to flush */ /* Get the file for the object */ - if (H5VL_native_get_file_struct(obj, type, &f) < 0) + if (H5VL_native_get_file_struct(obj, args->args.flush.obj_type, &f) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") /* Nothing to do if the file is read only. This determination is @@ -341,7 +306,7 @@ H5VL__native_file_specific(void *obj, H5VL_file_specific_t specific_type, hid_t */ if (H5F_ACC_RDWR & H5F_INTENT(f)) { /* Flush other files, depending on scope */ - if (H5F_SCOPE_GLOBAL == scope) { + if (H5F_SCOPE_GLOBAL == args->args.flush.scope) { /* Call the flush routine for mounted file hierarchies */ if (H5F_flush_mounts(f) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush mounted file hierarchy") @@ -353,98 +318,55 @@ H5VL__native_file_specific(void *obj, H5VL_file_specific_t specific_type, hid_t "unable to flush file's cached information") } /* end else */ } /* end if */ + break; } /* H5Freopen */ case H5VL_FILE_REOPEN: { - void **ret = HDva_arg(arguments, void **); - H5F_t *new_file = NULL; + H5F_t *new_file; /* Reopen the file through the VOL connector */ if (NULL == (new_file = H5F__reopen((H5F_t *)obj))) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to reopen file") new_file->id_exists = TRUE; - *ret = (void *)new_file; - break; - } - - /* H5Fmount */ - case H5VL_FILE_MOUNT: { - H5I_type_t type = (H5I_type_t)HDva_arg(arguments, int); /* enum work-around */ - const char *name = HDva_arg(arguments, const char *); - H5F_t * child = HDva_arg(arguments, H5F_t *); - hid_t fmpl_id = HDva_arg(arguments, hid_t); - H5G_loc_t loc; - - if (H5G_loc_real(obj, type, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - - /* Do the mount */ - if (H5F__mount(&loc, name, child, fmpl_id) < 0) - HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to mount file") - - break; - } - - /* H5Funmount */ - case H5VL_FILE_UNMOUNT: { - H5I_type_t type = (H5I_type_t)HDva_arg(arguments, int); /* enum work-around */ - const char *name = HDva_arg(arguments, const char *); - H5G_loc_t loc; - - if (H5G_loc_real(obj, type, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - - /* Unmount */ - if (H5F__unmount(&loc, name) < 0) - HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to unmount file") + /* Set 'out' value */ + *args->args.reopen.file = new_file; break; } /* H5Fis_accessible */ case H5VL_FILE_IS_ACCESSIBLE: { - hid_t fapl_id = HDva_arg(arguments, hid_t); - const char *name = HDva_arg(arguments, const char *); - htri_t * result = HDva_arg(arguments, htri_t *); + htri_t result; + + if ((result = H5F__is_hdf5(args->args.is_accessible.filename, args->args.is_accessible.fapl_id)) < + 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "error in HDF5 file check") + + /* Set 'out' value */ + *args->args.is_accessible.accessible = (hbool_t)result; - /* Call private routine */ - if ((*result = H5F__is_hdf5(name, fapl_id)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "error in HDF5 file check") break; } /* H5Fdelete */ case H5VL_FILE_DELETE: { - hid_t fapl_id = HDva_arg(arguments, hid_t); - const char *name = HDva_arg(arguments, const char *); - herr_t * ret = HDva_arg(arguments, herr_t *); + if (H5F__delete(args->args.del.filename, args->args.del.fapl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTDELETEFILE, FAIL, "error in HDF5 file deletion") - /* Call private routine */ - if ((*ret = H5F_delete(name, fapl_id)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTDELETEFILE, FAIL, "error in HDF5 file check") break; } /* Check if two files are the same */ case H5VL_FILE_IS_EQUAL: { - H5F_t * file2 = (H5F_t *)HDva_arg(arguments, void *); - hbool_t *is_equal = HDva_arg(arguments, hbool_t *); - - if (!obj || !file2) - *is_equal = FALSE; + if (!obj || !args->args.is_equal.obj2) + *args->args.is_equal.same_file = FALSE; else - *is_equal = (((H5F_t *)obj)->shared == file2->shared); - break; - } + *args->args.is_equal.same_file = + (((H5F_t *)obj)->shared == ((H5F_t *)args->args.is_equal.obj2)->shared); - /* H5Fwait */ - case H5VL_FILE_WAIT: { - /* The native VOL connector doesn't support asynchronous - * operations, so this is a no-op. - */ break; } @@ -466,85 +388,78 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_file_optional(void *obj, H5VL_optional_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { - H5F_t *f = NULL; /* File */ - herr_t ret_value = SUCCEED; /* Return value */ + H5F_t * f = (H5F_t *)obj; /* File */ + H5VL_native_file_optional_args_t *opt_args = args->args; /* Pointer to native operation's arguments */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - f = (H5F_t *)obj; - switch (optional_type) { + switch (args->op_type) { /* H5Fget_filesize */ case H5VL_NATIVE_FILE_GET_SIZE: { - haddr_t max_eof_eoa; /* Maximum of the EOA & EOF */ - haddr_t base_addr; /* Base address for the file */ - hsize_t *size = HDva_arg(arguments, hsize_t *); + haddr_t max_eof_eoa; /* Maximum of the EOA & EOF */ + haddr_t base_addr; /* Base address for the file */ - /* Go get the actual file size */ + /* Get the actual file size & base address */ if (H5F__get_max_eof_eoa(f, &max_eof_eoa) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "file can't get max eof/eoa ") - base_addr = H5FD_get_base_addr(f->shared->lf); - if (size) - *size = (hsize_t)(max_eof_eoa + - base_addr); /* Convert relative base address for file to absolute address */ + /* Convert relative base address for file to absolute address */ + *opt_args->get_size.size = (hsize_t)(max_eof_eoa + base_addr); break; } /* H5Fget_file_image */ case H5VL_NATIVE_FILE_GET_FILE_IMAGE: { - void * buf_ptr = HDva_arg(arguments, void *); - ssize_t *ret = HDva_arg(arguments, ssize_t *); - size_t buf_len = HDva_arg(arguments, size_t); + H5VL_native_file_get_file_image_t *gfi_args = &opt_args->get_file_image; - /* Do the actual work */ - if ((*ret = H5F__get_file_image(f, buf_ptr, buf_len)) < 0) + /* Get file image */ + if (H5F__get_file_image(f, gfi_args->buf, gfi_args->buf_size, gfi_args->image_len) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "get file image failed") + break; } /* H5Fget_freespace */ case H5VL_NATIVE_FILE_GET_FREE_SPACE: { - hsize_t tot_space; /* Amount of free space in the file */ - hssize_t *ret = HDva_arg(arguments, hssize_t *); + H5VL_native_file_get_freespace_t *gfs_args = &opt_args->get_freespace; - /* Go get the actual amount of free space in the file */ - if (H5MF_get_freespace(f, &tot_space, NULL) < 0) + /* Get the actual amount of free space in the file */ + if (H5MF_get_freespace(f, gfs_args->size, NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to check free space for file") - *ret = (hssize_t)tot_space; + break; } /* H5Fget_free_sections */ case H5VL_NATIVE_FILE_GET_FREE_SECTIONS: { - H5F_sect_info_t *sect_info = HDva_arg(arguments, H5F_sect_info_t *); - ssize_t * ret = HDva_arg(arguments, ssize_t *); - H5F_mem_t type = (H5F_mem_t)HDva_arg(arguments, int); /* enum work-around */ - size_t nsects = HDva_arg(arguments, size_t); + H5VL_native_file_get_free_sections_t *gfs_args = &opt_args->get_free_sections; /* Go get the free-space section information in the file */ - if ((*ret = H5MF_get_free_sections(f, type, nsects, sect_info)) < 0) + if (H5MF_get_free_sections(f, gfs_args->type, gfs_args->nsects, gfs_args->sect_info, + gfs_args->sect_count) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to check free space for file") + break; } /* H5Fget_info1/2 */ case H5VL_NATIVE_FILE_GET_INFO: { - H5I_type_t type = (H5I_type_t)HDva_arg(arguments, int); /* enum work-around */ - H5F_info2_t *finfo = HDva_arg(arguments, H5F_info2_t *); + H5VL_native_file_get_info_t *gfi_args = &opt_args->get_info; /* Get the file struct. This call is careful to not return the file pointer * for the top file in a mount hierarchy. */ - if (H5VL_native_get_file_struct(obj, type, &f) < 0) + if (H5VL_native_get_file_struct(obj, gfi_args->type, &f) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not get a file struct") /* Get the file info */ - if (H5F__get_info(f, finfo) < 0) + if (H5F__get_info(f, gfi_args->finfo) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to retrieve file info") break; @@ -552,50 +467,42 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t /* H5Fget_mdc_config */ case H5VL_NATIVE_FILE_GET_MDC_CONF: { - H5AC_cache_config_t *config_ptr = HDva_arg(arguments, H5AC_cache_config_t *); + /* Get the metadata cache configuration */ + if (H5AC_get_cache_auto_resize_config(f->shared->cache, opt_args->get_mdc_config.config) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get metadata cache configuration") - /* Go get the resize configuration */ - if (H5AC_get_cache_auto_resize_config(f->shared->cache, config_ptr) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_get_cache_auto_resize_config() failed.") break; } /* H5Fget_mdc_hit_rate */ case H5VL_NATIVE_FILE_GET_MDC_HR: { - double *hit_rate_ptr = HDva_arg(arguments, double *); + /* Get the current hit rate */ + if (H5AC_get_cache_hit_rate(f->shared->cache, opt_args->get_mdc_hit_rate.hit_rate) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get metadata cache hit rate") - /* Go get the current hit rate */ - if (H5AC_get_cache_hit_rate(f->shared->cache, hit_rate_ptr) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_get_cache_hit_rate() failed.") break; } /* H5Fget_mdc_size */ case H5VL_NATIVE_FILE_GET_MDC_SIZE: { - size_t * max_size_ptr = HDva_arg(arguments, size_t *); - size_t * min_clean_size_ptr = HDva_arg(arguments, size_t *); - size_t * cur_size_ptr = HDva_arg(arguments, size_t *); - int * cur_num_entries_ptr = HDva_arg(arguments, int *); - uint32_t cur_num_entries; + H5VL_native_file_get_mdc_size_t *gms_args = &opt_args->get_mdc_size; - /* Go get the size data */ - if (H5AC_get_cache_size(f->shared->cache, max_size_ptr, min_clean_size_ptr, cur_size_ptr, - &cur_num_entries) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_get_cache_size() failed.") + /* Get the size data */ + if (H5AC_get_cache_size(f->shared->cache, gms_args->max_size, gms_args->min_clean_size, + gms_args->cur_size, gms_args->cur_num_entries) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get metadata cache size") - if (cur_num_entries_ptr != NULL) - *cur_num_entries_ptr = (int)cur_num_entries; break; } /* H5Fget_vfd_handle */ case H5VL_NATIVE_FILE_GET_VFD_HANDLE: { - void **file_handle = HDva_arg(arguments, void **); - hid_t fapl_id = HDva_arg(arguments, hid_t); + H5VL_native_file_get_vfd_handle_t *gvh_args = &opt_args->get_vfd_handle; /* Retrieve the VFD handle for the file */ - if (H5F_get_vfd_handle(f, fapl_id, file_handle) < 0) + if (H5F_get_vfd_handle(f, gvh_args->fapl_id, gvh_args->file_handle) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve VFD handle") + break; } @@ -605,6 +512,7 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t if (f->shared->efc) if (H5F__efc_release(f->shared->efc) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release external file cache") + break; } @@ -612,26 +520,24 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t case H5VL_NATIVE_FILE_RESET_MDC_HIT_RATE: { /* Reset the hit rate statistic */ if (H5AC_reset_cache_hit_rate_stats(f->shared->cache) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't reset cache hit rate") + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't reset cache hit rate") + break; } /* H5Fset_mdc_config */ case H5VL_NATIVE_FILE_SET_MDC_CONFIG: { - H5AC_cache_config_t *config_ptr = HDva_arg(arguments, H5AC_cache_config_t *); + /* Set the metadata cache configuration */ + if (H5AC_set_cache_auto_resize_config(f->shared->cache, opt_args->set_mdc_config.config) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set metadata cache configuration") - /* set the resize configuration */ - if (H5AC_set_cache_auto_resize_config(f->shared->cache, config_ptr) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "H5AC_set_cache_auto_resize_config() failed") break; } /* H5Fget_metadata_read_retry_info */ case H5VL_NATIVE_FILE_GET_METADATA_READ_RETRY_INFO: { - H5F_retry_info_t *info = HDva_arg(arguments, H5F_retry_info_t *); - - if (H5F_get_metadata_read_retry_info(f, info) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't get metadata read retry info") + if (H5F_get_metadata_read_retry_info(f, opt_args->get_metadata_read_retry_info.info) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get metadata read retry info") break; } @@ -639,7 +545,7 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t /* H5Fstart_swmr_write */ case H5VL_NATIVE_FILE_START_SWMR_WRITE: { if (H5F__start_swmr_write(f) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't start SWMR write") + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't start SWMR write") break; } @@ -664,11 +570,11 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t /* H5Fget_mdc_logging_status */ case H5VL_NATIVE_FILE_GET_MDC_LOGGING_STATUS: { - hbool_t *is_enabled = HDva_arg(arguments, hbool_t *); - hbool_t *is_currently_logging = HDva_arg(arguments, hbool_t *); + H5VL_native_file_get_mdc_logging_status_t *gmls_args = &opt_args->get_mdc_logging_status; /* Call mdc logging function */ - if (H5C_get_logging_status(f->shared->cache, is_enabled, is_currently_logging) < 0) + if (H5C_get_logging_status(f->shared->cache, gmls_args->is_enabled, + gmls_args->is_currently_logging) < 0) HGOTO_ERROR(H5E_FILE, H5E_LOGGING, FAIL, "unable to get logging status") break; @@ -698,18 +604,15 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t /* H5Fget_page_buffering_stats */ case H5VL_NATIVE_FILE_GET_PAGE_BUFFERING_STATS: { - unsigned *accesses = HDva_arg(arguments, unsigned *); - unsigned *hits = HDva_arg(arguments, unsigned *); - unsigned *misses = HDva_arg(arguments, unsigned *); - unsigned *evictions = HDva_arg(arguments, unsigned *); - unsigned *bypasses = HDva_arg(arguments, unsigned *); + H5VL_native_file_get_page_buffering_stats_t *gpbs_args = &opt_args->get_page_buffering_stats; /* Sanity check */ if (NULL == f->shared->page_buf) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "page buffering not enabled on file") /* Get the statistics */ - if (H5PB_get_stats(f->shared->page_buf, accesses, hits, misses, evictions, bypasses) < 0) + if (H5PB_get_stats(f->shared->page_buf, gpbs_args->accesses, gpbs_args->hits, gpbs_args->misses, + gpbs_args->evictions, gpbs_args->bypasses) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve stats for page buffering") break; @@ -717,11 +620,10 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t /* H5Fget_mdc_image_info */ case H5VL_NATIVE_FILE_GET_MDC_IMAGE_INFO: { - haddr_t *image_addr = HDva_arg(arguments, haddr_t *); - hsize_t *image_len = HDva_arg(arguments, hsize_t *); + H5VL_native_file_get_mdc_image_info_t *gmii_args = &opt_args->get_mdc_image_info; /* Go get the address and size of the cache image */ - if (H5AC_get_mdc_image_info(f->shared->cache, image_addr, image_len) < 0) + if (H5AC_get_mdc_image_info(f->shared->cache, gmii_args->addr, gmii_args->len) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve cache image info") break; @@ -729,11 +631,7 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t /* H5Fget_eoa */ case H5VL_NATIVE_FILE_GET_EOA: { - haddr_t *eoa = HDva_arg(arguments, haddr_t *); - haddr_t rel_eoa; /* Relative address of EOA */ - - /* Sanity check */ - HDassert(eoa); + haddr_t rel_eoa; /* Relative address of EOA */ /* This routine will work only for drivers with this feature enabled.*/ /* We might introduce a new feature flag in the future */ @@ -747,14 +645,13 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t /* Set return value */ /* (Note compensating for base address subtraction in internal routine) */ - *eoa = rel_eoa + H5F_get_base_addr(f); + *opt_args->get_eoa.eoa = rel_eoa + H5F_get_base_addr(f); break; } /* H5Fincrement_filesize */ case H5VL_NATIVE_FILE_INCR_FILESIZE: { - hsize_t increment = HDva_arg(arguments, hsize_t); haddr_t max_eof_eoa; /* Maximum of the relative EOA & EOF */ /* This public routine will work only for drivers with this feature enabled.*/ @@ -768,7 +665,7 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "file can't get max eof/eoa ") /* Set EOA to the maximum value + increment */ - if (H5F__set_eoa(f, H5FD_MEM_DEFAULT, max_eof_eoa + increment) < 0) + if (H5F__set_eoa(f, H5FD_MEM_DEFAULT, max_eof_eoa + opt_args->increment_filesize.increment) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "driver set_eoa request failed") break; @@ -776,11 +673,10 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t /* H5Fset_latest_format, H5Fset_libver_bounds */ case H5VL_NATIVE_FILE_SET_LIBVER_BOUNDS: { - H5F_libver_t low = (H5F_libver_t)HDva_arg(arguments, int); /* enum work-around */ - H5F_libver_t high = (H5F_libver_t)HDva_arg(arguments, int); /* enum work-around */ + H5VL_native_file_set_libver_bounds_t *slb_args = &opt_args->set_libver_bounds; /* Call internal set_libver_bounds function */ - if (H5F__set_libver_bounds(f, low, high) < 0) + if (H5F__set_libver_bounds(f, slb_args->low, slb_args->high) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "cannot set low/high bounds") break; @@ -788,34 +684,34 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t /* H5Fget_dset_no_attrs_hint */ case H5VL_NATIVE_FILE_GET_MIN_DSET_OHDR_FLAG: { - hbool_t *minimize = HDva_arg(arguments, hbool_t *); - *minimize = H5F_GET_MIN_DSET_OHDR(f); + *opt_args->get_min_dset_ohdr_flag.minimize = H5F_GET_MIN_DSET_OHDR(f); + break; } /* H5Fset_dset_no_attrs_hint */ case H5VL_NATIVE_FILE_SET_MIN_DSET_OHDR_FLAG: { - int minimize = HDva_arg(arguments, int); - if (H5F_set_min_dset_ohdr(f, (hbool_t)minimize) < 0) + if (H5F_set_min_dset_ohdr(f, opt_args->set_min_dset_ohdr_flag.minimize) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "cannot set file's dataset object header minimization flag") + break; } #ifdef H5_HAVE_PARALLEL /* H5Fget_mpi_atomicity */ case H5VL_NATIVE_FILE_GET_MPI_ATOMICITY: { - hbool_t *flag = (hbool_t *)HDva_arg(arguments, hbool_t *); - if (H5F_get_mpi_atomicity(f, flag) < 0) + if (H5F__get_mpi_atomicity(f, opt_args->get_mpi_atomicity.flag) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "cannot get MPI atomicity"); + break; } /* H5Fset_mpi_atomicity */ case H5VL_NATIVE_FILE_SET_MPI_ATOMICITY: { - hbool_t flag = (hbool_t)HDva_arg(arguments, int); - if (H5F_set_mpi_atomicity(f, flag) < 0) + if (H5F__set_mpi_atomicity(f, opt_args->set_mpi_atomicity.flag) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "cannot set MPI atomicity"); + break; } #endif /* H5_HAVE_PARALLEL */ @@ -823,31 +719,28 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t /* Finalize H5Fopen */ case H5VL_NATIVE_FILE_POST_OPEN: { /* Call package routine */ - if (H5F__post_open((H5F_t *)obj) < 0) + if (H5F__post_open(f) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "can't finish opening file") break; } /* H5Fvfd_swmr_disable_end_of_tick() */ case H5VL_NATIVE_FILE_VFD_SWMR_DISABLE_EOT: { - /* Call package routine */ - if (H5F__vfd_swmr_disable_end_of_tick((H5F_t *)obj) < 0) + if (H5F__vfd_swmr_disable_end_of_tick(f) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "can't disable EOT for VFD SWMR") break; } /* H5Fvfd_swmr_enable_end_of_tick() */ case H5VL_NATIVE_FILE_VFD_SWMR_ENABLE_EOT: { - /* Call package routine */ - if (H5F__vfd_swmr_enable_end_of_tick((H5F_t *)obj) < 0) + if (H5F__vfd_swmr_enable_end_of_tick(f) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "can't enable EOT for VFD SWMR") break; } /* H5Fvfd_swmr_end_tick() */ case H5VL_NATIVE_FILE_VFD_SWMR_END_TICK: { - /* Call package routine */ - if (H5F__vfd_swmr_end_tick((H5F_t *)obj) < 0) + if (H5F__vfd_swmr_end_tick(f) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "can't trigger EOT processing for VFD SWMR") break; } @@ -898,7 +791,7 @@ H5VL__native_file_close(void *file, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_U HGOTO_ERROR(H5E_ID, H5E_CANTGET, FAIL, "can't get ID ref count") if (nref == 1) if (H5F__flush(f) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush cache") } /* end if */ /* Close the file */ diff --git a/src/H5VLnative_group.c b/src/H5VLnative_group.c index 53f8459..54f8337 100644 --- a/src/H5VLnative_group.c +++ b/src/H5VLnative_group.c @@ -169,55 +169,54 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_group_get(void *obj, H5VL_group_get_t get_type, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_group_get(void *obj, H5VL_group_get_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (get_type) { + switch (args->op_type) { /* H5Gget_create_plist */ case H5VL_GROUP_GET_GCPL: { - hid_t *new_gcpl_id = HDva_arg(arguments, hid_t *); - H5G_t *grp = (H5G_t *)obj; + if ((args->args.get_gcpl.gcpl_id = H5G_get_create_plist((H5G_t *)obj)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get creation property list for group") - if ((*new_gcpl_id = H5G_get_create_plist(grp)) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get creation property list for group") break; } /* H5Gget_info */ case H5VL_GROUP_GET_INFO: { - const H5VL_loc_params_t *loc_params = HDva_arg(arguments, const H5VL_loc_params_t *); - H5G_info_t * group_info = HDva_arg(arguments, H5G_info_t *); - H5G_loc_t loc; + H5VL_group_get_info_args_t *get_info_args = &args->args.get_info; + H5G_loc_t loc; - if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + if (H5G_loc_real(obj, get_info_args->loc_params.obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - if (loc_params->type == H5VL_OBJECT_BY_SELF) { + if (get_info_args->loc_params.type == H5VL_OBJECT_BY_SELF) { /* H5Gget_info */ /* Retrieve the group's information */ - if (H5G__obj_info(loc.oloc, group_info) < 0) + if (H5G__obj_info(loc.oloc, get_info_args->ginfo) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info") } /* end if */ - else if (loc_params->type == H5VL_OBJECT_BY_NAME) { + else if (get_info_args->loc_params.type == H5VL_OBJECT_BY_NAME) { /* H5Gget_info_by_name */ /* Retrieve the group's information */ - if (H5G__get_info_by_name(&loc, loc_params->loc_data.loc_by_name.name, group_info) < 0) + if (H5G__get_info_by_name(&loc, get_info_args->loc_params.loc_data.loc_by_name.name, + get_info_args->ginfo) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info") } /* end else-if */ - else if (loc_params->type == H5VL_OBJECT_BY_IDX) { + else if (get_info_args->loc_params.type == H5VL_OBJECT_BY_IDX) { /* H5Gget_info_by_idx */ /* Retrieve the group's information */ - if (H5G__get_info_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, - loc_params->loc_data.loc_by_idx.idx_type, - loc_params->loc_data.loc_by_idx.order, - loc_params->loc_data.loc_by_idx.n, group_info) < 0) + if (H5G__get_info_by_idx(&loc, get_info_args->loc_params.loc_data.loc_by_idx.name, + get_info_args->loc_params.loc_data.loc_by_idx.idx_type, + get_info_args->loc_params.loc_data.loc_by_idx.order, + get_info_args->loc_params.loc_data.loc_by_idx.n, + get_info_args->ginfo) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info") } /* end else-if */ else @@ -243,30 +242,53 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_group_specific(void *obj, H5VL_group_specific_t specific_type, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_group_specific(void *obj, H5VL_group_specific_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { H5G_t *grp = (H5G_t *)obj; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (specific_type) { - case H5VL_GROUP_FLUSH: { - hid_t group_id = HDva_arg(arguments, hid_t); + switch (args->op_type) { + /* H5Fmount */ + case H5VL_GROUP_MOUNT: { + H5G_loc_t loc; + + if (H5G_loc_real(grp, H5I_GROUP, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group object") + + if (H5F_mount(&loc, args->args.mount.name, args->args.mount.child_file, + args->args.mount.fmpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to mount file") + + break; + } + + /* H5Funmount */ + case H5VL_GROUP_UNMOUNT: { + H5G_loc_t loc; + + if (H5G_loc_real(grp, H5I_GROUP, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group object") + + if (H5F_unmount(&loc, args->args.unmount.name) < 0) + HGOTO_ERROR(H5E_FILE, H5E_UNMOUNT, FAIL, "unable to unmount file") - /* Flush object's metadata to file */ - if (H5O_flush_common(&grp->oloc, group_id) < 0) + break; + } + + /* H5Gflush */ + case H5VL_GROUP_FLUSH: { + if (H5O_flush_common(&grp->oloc, args->args.flush.grp_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTFLUSH, FAIL, "unable to flush group") break; } + /* H5Grefresh */ case H5VL_GROUP_REFRESH: { - hid_t group_id = HDva_arg(arguments, hid_t); - - /* Call private function to refresh group object */ - if ((H5O_refresh_metadata(group_id, grp->oloc)) < 0) + if ((H5O_refresh_metadata(&grp->oloc, args->args.refresh.grp_id)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, "unable to refresh group") break; @@ -290,50 +312,53 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_group_optional(void H5_ATTR_UNUSED *obj, H5VL_group_optional_t optional_type, - hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, - va_list H5_ATTR_DEPRECATED_USED arguments) +H5VL__native_group_optional(void H5_ATTR_UNUSED *obj, H5VL_optional_args_t *args, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) { - herr_t ret_value = SUCCEED; /* Return value */ +#ifndef H5_NO_DEPRECATED_SYMBOLS + H5VL_native_group_optional_args_t *opt_args = args->args; /* Pointer to native operation's arguments */ +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (optional_type) { + switch (args->op_type) { #ifndef H5_NO_DEPRECATED_SYMBOLS /* H5Giterate (deprecated) */ case H5VL_NATIVE_GROUP_ITERATE_OLD: { - const H5VL_loc_params_t * loc_params = HDva_arg(arguments, const H5VL_loc_params_t *); - hsize_t idx = HDva_arg(arguments, hsize_t); - hsize_t * last_obj = HDva_arg(arguments, hsize_t *); - const H5G_link_iterate_t *lnk_op = HDva_arg(arguments, const H5G_link_iterate_t *); - void * op_data = HDva_arg(arguments, void *); - H5G_loc_t grp_loc; + H5VL_native_group_iterate_old_t *iter_args = &opt_args->iterate_old; + H5G_link_iterate_t lnk_op; /* Link operator */ + H5G_loc_t grp_loc; /* Get the location struct for the object */ - if (H5G_loc_real(obj, loc_params->obj_type, &grp_loc) < 0) + if (H5G_loc_real(obj, iter_args->loc_params.obj_type, &grp_loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + /* Set up link iteration callback struct */ + lnk_op.op_type = H5G_LINK_OP_OLD; + lnk_op.op_func.op_old = iter_args->op; + /* Call the actual iteration routine */ - if ((ret_value = H5G_iterate(&grp_loc, loc_params->loc_data.loc_by_name.name, H5_INDEX_NAME, - H5_ITER_INC, idx, last_obj, lnk_op, op_data)) < 0) - HERROR(H5E_VOL, H5E_BADITER, "error iterating over group's links"); + if ((ret_value = H5G_iterate(&grp_loc, iter_args->loc_params.loc_data.loc_by_name.name, + H5_INDEX_NAME, H5_ITER_INC, iter_args->idx, iter_args->last_obj, + &lnk_op, iter_args->op_data)) < 0) + HERROR(H5E_SYM, H5E_BADITER, "error iterating over group's links"); break; } /* H5Gget_objinfo (deprecated) */ case H5VL_NATIVE_GROUP_GET_OBJINFO: { - const H5VL_loc_params_t *loc_params = HDva_arg(arguments, const H5VL_loc_params_t *); - hbool_t follow_link = (hbool_t)HDva_arg(arguments, unsigned); - H5G_stat_t * statbuf = HDva_arg(arguments, H5G_stat_t *); - H5G_loc_t grp_loc; + H5VL_native_group_get_objinfo_t *goi_args = &opt_args->get_objinfo; + H5G_loc_t grp_loc; /* Get the location struct for the object */ - if (H5G_loc_real(obj, loc_params->obj_type, &grp_loc) < 0) + if (H5G_loc_real(obj, goi_args->loc_params.obj_type, &grp_loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") /* Call the actual group objinfo routine */ - if (H5G__get_objinfo(&grp_loc, loc_params->loc_data.loc_by_name.name, follow_link, statbuf) < 0) + if (H5G__get_objinfo(&grp_loc, goi_args->loc_params.loc_data.loc_by_name.name, + goi_args->follow_link, goi_args->statbuf) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "cannot stat object") break; diff --git a/src/H5VLnative_introspect.c b/src/H5VLnative_introspect.c index 45efcf8..fa11bea 100644 --- a/src/H5VLnative_introspect.c +++ b/src/H5VLnative_introspect.c @@ -52,8 +52,9 @@ /* Local Variables */ /*******************/ -/* Note: H5VL__native_introspect_get_conn_cls is in src/H5VLnative.c so that - * it can return the address of the staticly declared class struct. +/* Note: H5VL__native_introspect_get_conn_cls and H5VL__native_introspect_get_cap_flags + * are in src/H5VLnative.c so that they can work with the staticly declared + * class struct. */ /*--------------------------------------------------------------------------- diff --git a/src/H5VLnative_link.c b/src/H5VLnative_link.c index eaba18f..042c778 100644 --- a/src/H5VLnative_link.c +++ b/src/H5VLnative_link.c @@ -68,20 +68,20 @@ *------------------------------------------------------------------------- */ herr_t -H5VL__native_link_create(H5VL_link_create_type_t create_type, void *obj, const H5VL_loc_params_t *loc_params, +H5VL__native_link_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t H5_ATTR_UNUSED lapl_id, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) + void H5_ATTR_UNUSED **req) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (create_type) { + switch (args->op_type) { case H5VL_LINK_CREATE_HARD: { H5G_loc_t cur_loc; H5G_loc_t link_loc; - void * cur_obj = HDva_arg(arguments, void *); - H5VL_loc_params_t *cur_params = HDva_arg(arguments, H5VL_loc_params_t *); + void * cur_obj = args->args.hard.curr_obj; + H5VL_loc_params_t *cur_params = &args->args.hard.curr_loc_params; if (NULL != cur_obj && H5G_loc_real(cur_obj, cur_params->obj_type, &cur_loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") @@ -104,46 +104,40 @@ H5VL__native_link_create(H5VL_link_create_type_t create_type, void *obj, const H "source and destination should be in the same file.") /* Create the link */ - if ((ret_value = - H5L__create_hard(cur_loc_p, cur_params->loc_data.loc_by_name.name, link_loc_p, - loc_params->loc_data.loc_by_name.name, lcpl_id)) < 0) + if (H5L__create_hard(cur_loc_p, cur_params->loc_data.loc_by_name.name, link_loc_p, + loc_params->loc_data.loc_by_name.name, lcpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") } /* end if */ else { /* H5Olink */ /* Link to the object */ if (H5L_link(&link_loc, loc_params->loc_data.loc_by_name.name, &cur_loc, lcpl_id) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to create link") + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") } /* end else */ + break; } case H5VL_LINK_CREATE_SOFT: { - char * target_name = HDva_arg(arguments, char *); H5G_loc_t link_loc; /* Group location for new link */ if (H5G_loc_real(obj, loc_params->obj_type, &link_loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if (H5L__create_soft(args->args.soft.target, &link_loc, loc_params->loc_data.loc_by_name.name, + lcpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to create link") - /* Create the link */ - if ((ret_value = H5L__create_soft(target_name, &link_loc, loc_params->loc_data.loc_by_name.name, - lcpl_id)) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") break; } case H5VL_LINK_CREATE_UD: { - H5G_loc_t link_loc; /* Group location for new link */ - H5L_type_t link_type = (H5L_type_t)HDva_arg(arguments, int); - void * udata = HDva_arg(arguments, void *); - size_t udata_size = HDva_arg(arguments, size_t); + H5G_loc_t link_loc; /* Group location for new link */ if (H5G_loc_real(obj, loc_params->obj_type, &link_loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - - /* Create link */ - if (H5L__create_ud(&link_loc, loc_params->loc_data.loc_by_name.name, udata, udata_size, link_type, - lcpl_id) < 0) + if (H5L__create_ud(&link_loc, loc_params->loc_data.loc_by_name.name, args->args.ud.buf, + args->args.ud.buf_size, args->args.ud.type, lcpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") + break; } @@ -249,8 +243,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_t get_type, - hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_args_t *args, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) { H5G_loc_t loc; herr_t ret_value = SUCCEED; /* Return value */ @@ -260,20 +254,19 @@ H5VL__native_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_ if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - switch (get_type) { + switch (args->op_type) { /* H5Lget_info/H5Lget_info_by_idx */ case H5VL_LINK_GET_INFO: { - H5L_info2_t *linfo2 = HDva_arg(arguments, H5L_info2_t *); - /* Get the link information */ - if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Lget_info */ - if (H5L_get_info(&loc, loc_params->loc_data.loc_by_name.name, linfo2) < 0) + if (loc_params->type == H5VL_OBJECT_BY_NAME) { + if (H5L_get_info(&loc, loc_params->loc_data.loc_by_name.name, args->args.get_info.linfo) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info") - } /* end if */ - else if (loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Lget_info_by_idx */ - if (H5L__get_info_by_idx( - &loc, loc_params->loc_data.loc_by_idx.name, loc_params->loc_data.loc_by_idx.idx_type, - loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n, linfo2) < 0) + } /* end if */ + else if (loc_params->type == H5VL_OBJECT_BY_IDX) { + if (H5L__get_info_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, + loc_params->loc_data.loc_by_idx.idx_type, + loc_params->loc_data.loc_by_idx.order, + loc_params->loc_data.loc_by_idx.n, args->args.get_info.linfo) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info") } /* end else-if */ else @@ -284,15 +277,11 @@ H5VL__native_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_ /* H5Lget_name_by_idx */ case H5VL_LINK_GET_NAME: { - char * name = HDva_arg(arguments, char *); - size_t size = HDva_arg(arguments, size_t); - ssize_t *ret = HDva_arg(arguments, ssize_t *); - - /* Get the link name */ - if ((*ret = H5L__get_name_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, - loc_params->loc_data.loc_by_idx.idx_type, - loc_params->loc_data.loc_by_idx.order, - loc_params->loc_data.loc_by_idx.n, name, size)) < 0) + if (H5L__get_name_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, + loc_params->loc_data.loc_by_idx.idx_type, + loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n, + args->args.get_name.name, args->args.get_name.name_size, + args->args.get_name.name_len) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info") break; @@ -300,20 +289,17 @@ H5VL__native_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_ /* H5Lget_val/H5Lget_val_by_idx */ case H5VL_LINK_GET_VAL: { - void * buf = HDva_arg(arguments, void *); - size_t size = HDva_arg(arguments, size_t); - /* Get the link information */ - if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Lget_val */ - if (H5L__get_val(&loc, loc_params->loc_data.loc_by_name.name, buf, size) < 0) + if (loc_params->type == H5VL_OBJECT_BY_NAME) { + if (H5L__get_val(&loc, loc_params->loc_data.loc_by_name.name, args->args.get_val.buf, + args->args.get_val.buf_size) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link value") } - else if (loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Lget_val_by_idx */ - - if (H5L__get_val_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, - loc_params->loc_data.loc_by_idx.idx_type, - loc_params->loc_data.loc_by_idx.order, - loc_params->loc_data.loc_by_idx.n, buf, size) < 0) + else if (loc_params->type == H5VL_OBJECT_BY_IDX) { + if (H5L__get_val_by_idx( + &loc, loc_params->loc_data.loc_by_idx.name, loc_params->loc_data.loc_by_idx.idx_type, + loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n, + args->args.get_val.buf, args->args.get_val.buf_size) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link val") } else @@ -340,35 +326,28 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_link_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_specific_t specific_type, - hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_link_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_specific_args_t *args, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (specific_type) { + switch (args->op_type) { case H5VL_LINK_EXISTS: { - hbool_t * exists = HDva_arg(arguments, hbool_t *); H5G_loc_t loc; if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - - /* Check for the existence of the link */ - if (H5L__exists(&loc, loc_params->loc_data.loc_by_name.name, exists) < 0) + if (H5L__exists(&loc, loc_params->loc_data.loc_by_name.name, args->args.exists.exists) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to specific link info") + break; } case H5VL_LINK_ITER: { - H5G_loc_t loc; - hbool_t recursive = (hbool_t)HDva_arg(arguments, unsigned); - H5_index_t idx_type = (H5_index_t)HDva_arg(arguments, int); /* enum work-around */ - H5_iter_order_t order = (H5_iter_order_t)HDva_arg(arguments, int); /* enum work-around */ - hsize_t * idx_p = HDva_arg(arguments, hsize_t *); - H5L_iterate2_t op = HDva_arg(arguments, H5L_iterate2_t); - void * op_data = HDva_arg(arguments, void *); + H5VL_link_iterate_args_t *iter_args = &args->args.iterate; + H5G_loc_t loc; /* Get the location */ if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) @@ -376,28 +355,32 @@ H5VL__native_link_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_ /* Visit or iterate over the links */ if (loc_params->type == H5VL_OBJECT_BY_SELF) { - if (recursive) { + if (iter_args->recursive) { /* H5Lvisit */ - if ((ret_value = H5G_visit(&loc, ".", idx_type, order, op, op_data)) < 0) + if ((ret_value = H5G_visit(&loc, ".", iter_args->idx_type, iter_args->order, + iter_args->op, iter_args->op_data)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed") } /* end if */ else { /* H5Literate */ - if ((ret_value = H5L_iterate(&loc, ".", idx_type, order, idx_p, op, op_data)) < 0) + if ((ret_value = H5L_iterate(&loc, ".", iter_args->idx_type, iter_args->order, + iter_args->idx_p, iter_args->op, iter_args->op_data)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "error iterating over links") } /* end else */ } /* end if */ else if (loc_params->type == H5VL_OBJECT_BY_NAME) { - if (recursive) { + if (iter_args->recursive) { /* H5Lvisit_by_name */ - if ((ret_value = H5G_visit(&loc, loc_params->loc_data.loc_by_name.name, idx_type, order, - op, op_data)) < 0) + if ((ret_value = + H5G_visit(&loc, loc_params->loc_data.loc_by_name.name, iter_args->idx_type, + iter_args->order, iter_args->op, iter_args->op_data)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed") } /* end if */ else { /* H5Literate_by_name */ - if ((ret_value = H5L_iterate(&loc, loc_params->loc_data.loc_by_name.name, idx_type, order, - idx_p, op, op_data)) < 0) + if ((ret_value = H5L_iterate(&loc, loc_params->loc_data.loc_by_name.name, + iter_args->idx_type, iter_args->order, iter_args->idx_p, + iter_args->op, iter_args->op_data)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "error iterating over links") } /* end else */ } /* end else-if */ diff --git a/src/H5VLnative_object.c b/src/H5VLnative_object.c index 95d4fff..d237617 100644 --- a/src/H5VLnative_object.c +++ b/src/H5VLnative_object.c @@ -169,8 +169,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_t get_type, - hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_args_t *args, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) { herr_t ret_value = SUCCEED; /* Return value */ H5G_loc_t loc; /* Location of group */ @@ -180,14 +180,12 @@ H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_obj if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - switch (get_type) { + switch (args->op_type) { /* Object file */ case H5VL_OBJECT_GET_FILE: { - void **ret = HDva_arg(arguments, void **); - if (loc_params->type == H5VL_OBJECT_BY_SELF) { - *ret = (void *)loc.oloc->file; + *args->args.get_file.file = (void *)loc.oloc->file; /* TODO we currently need to set id_exists to TRUE because * the upper layer will create an ID from the returned @@ -197,18 +195,16 @@ H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_obj } else HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown get_file parameters") + break; } /* Object name */ case H5VL_OBJECT_GET_NAME: { - ssize_t *ret = HDva_arg(arguments, ssize_t *); - char * name = HDva_arg(arguments, char *); - size_t size = HDva_arg(arguments, size_t); - if (loc_params->type == H5VL_OBJECT_BY_SELF) { /* Retrieve object's name */ - if ((*ret = H5G_get_name(&loc, name, size, NULL)) < 0) + if (H5G_get_name(&loc, args->args.get_name.buf, args->args.get_name.buf_size, + args->args.get_name.name_len, NULL) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't retrieve object name") } /* end if */ else if (loc_params->type == H5VL_OBJECT_BY_TOKEN) { @@ -225,18 +221,18 @@ H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_obj "can't deserialize object token into address") /* Retrieve object's name */ - if ((*ret = H5G_get_name_by_addr(loc.oloc->file, &obj_oloc, name, size)) < 0) + if (H5G_get_name_by_addr(loc.oloc->file, &obj_oloc, args->args.get_name.buf, + args->args.get_name.buf_size, args->args.get_name.name_len) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't determine object name") } /* end else-if */ else HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown get_name parameters") + break; } /* Object type */ case H5VL_OBJECT_GET_TYPE: { - H5O_type_t *obj_type = HDva_arg(arguments, H5O_type_t *); - if (loc_params->type == H5VL_OBJECT_BY_TOKEN) { H5O_loc_t obj_oloc; /* Object location */ unsigned rc; /* Reference count of object */ @@ -253,35 +249,30 @@ H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_obj /* Get the # of links for object, and its type */ /* (To check to make certain that this object hasn't been deleted) */ - if (H5O_get_rc_and_type(&obj_oloc, &rc, obj_type) < 0 || 0 == rc) + if (H5O_get_rc_and_type(&obj_oloc, &rc, args->args.get_type.obj_type) < 0 || 0 == rc) HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, FAIL, "dereferencing deleted object") } else HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown get_type parameters") + break; } /* H5Oget_info(_name|_by_idx)3 */ case H5VL_OBJECT_GET_INFO: { - H5O_info2_t *oinfo = HDva_arg(arguments, H5O_info2_t *); - unsigned fields = HDva_arg(arguments, unsigned); - - /* Use the original H5Oget_info code to get the data */ - - if (loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Oget_info */ - /* Retrieve the object's information */ - if (H5G_loc_info(&loc, ".", oinfo, fields) < 0) + if (loc_params->type == H5VL_OBJECT_BY_SELF) { + if (H5G_loc_info(&loc, ".", args->args.get_info.oinfo, args->args.get_info.fields) < 0) HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") - } /* end if */ - else if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Oget_info_by_name */ - /* Retrieve the object's information */ - if (H5G_loc_info(&loc, loc_params->loc_data.loc_by_name.name, oinfo, fields) < 0) + } /* end if */ + else if (loc_params->type == H5VL_OBJECT_BY_NAME) { + if (H5G_loc_info(&loc, loc_params->loc_data.loc_by_name.name, args->args.get_info.oinfo, + args->args.get_info.fields) < 0) HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") - } /* end else-if */ - else if (loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Oget_info_by_idx */ - H5G_loc_t obj_loc; /* Location used to open group */ - H5G_name_t obj_path; /* Opened object group hier. path */ - H5O_loc_t obj_oloc; /* Opened object object location */ + } /* end else-if */ + else if (loc_params->type == H5VL_OBJECT_BY_IDX) { + H5G_loc_t obj_loc; /* Location used to open group */ + H5G_name_t obj_path; /* Opened object group hier. path */ + H5O_loc_t obj_oloc; /* Opened object object location */ /* Set up opened group location to fill in */ obj_loc.oloc = &obj_oloc; @@ -296,7 +287,7 @@ H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_obj HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "group not found") /* Retrieve the object's information */ - if (H5O_get_info(obj_loc.oloc, oinfo, fields) < 0) { + if (H5O_get_info(obj_loc.oloc, args->args.get_info.oinfo, args->args.get_info.fields) < 0) { H5G_loc_free(&obj_loc); HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object info") } /* end if */ @@ -307,6 +298,7 @@ H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_obj } /* end else-if */ else HGOTO_ERROR(H5E_OHDR, H5E_UNSUPPORTED, FAIL, "unknown get info parameters") + break; } @@ -329,8 +321,8 @@ done: */ herr_t H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_object_specific_t specific_type, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) + H5VL_object_specific_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { H5G_loc_t loc; herr_t ret_value = SUCCEED; /* Return value */ @@ -340,13 +332,10 @@ H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - switch (specific_type) { + switch (args->op_type) { /* H5Oincr_refcount / H5Odecr_refcount */ case H5VL_OBJECT_CHANGE_REF_COUNT: { - int update_ref = HDva_arg(arguments, int); - H5O_loc_t *oloc = loc.oloc; - - if (H5O_link(oloc, update_ref) < 0) + if (H5O_link(loc.oloc, args->args.change_rc.delta) < 0) HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "modifying object link count failed") break; @@ -354,25 +343,20 @@ H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, /* H5Oexists_by_name */ case H5VL_OBJECT_EXISTS: { - htri_t *ret = HDva_arg(arguments, htri_t *); - if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* Check if the object exists */ - if ((*ret = H5G_loc_exists(&loc, loc_params->loc_data.loc_by_name.name)) < 0) + if (H5G_loc_exists(&loc, loc_params->loc_data.loc_by_name.name, args->args.exists.exists) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to determine if '%s' exists", loc_params->loc_data.loc_by_name.name) } /* end if */ else HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown object exists parameters") + break; } /* Lookup object */ case H5VL_OBJECT_LOOKUP: { - H5O_token_t *token = HDva_arg(arguments, H5O_token_t *); - - HDassert(token); - if (loc_params->type == H5VL_OBJECT_BY_NAME) { H5G_loc_t obj_loc; /* Group hier. location of object */ H5G_name_t obj_path; /* Object group hier. path */ @@ -388,7 +372,8 @@ H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") /* Encode token */ - if (H5VL_native_addr_to_token(loc.oloc->file, H5I_FILE, obj_loc.oloc->addr, token) < 0) + if (H5VL_native_addr_to_token(loc.oloc->file, H5I_FILE, obj_loc.oloc->addr, + args->args.lookup.token_ptr) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSERIALIZE, FAIL, "can't serialize address into object token") @@ -401,46 +386,39 @@ H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, break; } + /* H5Ovisit/H5Ovisit_by_name */ case H5VL_OBJECT_VISIT: { - H5_index_t idx_type = (H5_index_t)HDva_arg(arguments, int); /* enum work-around */ - H5_iter_order_t order = (H5_iter_order_t)HDva_arg(arguments, int); /* enum work-around */ - H5O_iterate2_t op = HDva_arg(arguments, H5O_iterate2_t); - void * op_data = HDva_arg(arguments, void *); - unsigned fields = HDva_arg(arguments, unsigned); + H5VL_object_visit_args_t *visit_args = &args->args.visit; /* Call internal object visitation routine */ if (loc_params->type == H5VL_OBJECT_BY_SELF) { - /* H5Ovisit */ - if ((ret_value = H5O__visit(&loc, ".", idx_type, order, op, op_data, fields)) < 0) + if ((ret_value = H5O__visit(&loc, ".", visit_args->idx_type, visit_args->order, + visit_args->op, visit_args->op_data, visit_args->fields)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object visitation failed") } /* end if */ else if (loc_params->type == H5VL_OBJECT_BY_NAME) { - /* H5Ovisit_by_name */ - if ((ret_value = H5O__visit(&loc, loc_params->loc_data.loc_by_name.name, idx_type, order, op, - op_data, fields)) < 0) + if ((ret_value = H5O__visit(&loc, loc_params->loc_data.loc_by_name.name, visit_args->idx_type, + visit_args->order, visit_args->op, visit_args->op_data, + visit_args->fields)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object visitation failed") } /* end else-if */ else HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown object visit params"); + break; } case H5VL_OBJECT_FLUSH: { - hid_t oid = HDva_arg(arguments, hid_t); - /* Flush the object's metadata */ - if (H5O_flush(loc.oloc, oid) < 0) + if (H5O_flush(loc.oloc, args->args.flush.obj_id) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object") break; } case H5VL_OBJECT_REFRESH: { - hid_t oid = HDva_arg(arguments, hid_t); - H5O_loc_t *oloc = loc.oloc; - /* Refresh the metadata */ - if (H5O_refresh_metadata(oid, *oloc) < 0) + if (H5O_refresh_metadata(loc.oloc, args->args.refresh.obj_id) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object") break; @@ -464,64 +442,59 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_object_optional(void *obj, H5VL_object_optional_t optional_type, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_object_optional(void *obj, const H5VL_loc_params_t *loc_params, H5VL_optional_args_t *args, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) { - H5VL_loc_params_t *loc_params = HDva_arg(arguments, H5VL_loc_params_t *); - H5G_loc_t loc; /* Location of group */ - herr_t ret_value = SUCCEED; /* Return value */ + H5G_loc_t loc; /* Location of group */ + H5VL_native_object_optional_args_t *opt_args = args->args; /* Pointer to native operation's arguments */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - switch (optional_type) { + switch (args->op_type) { /* H5Oget_comment / H5Oget_comment_by_name */ case H5VL_NATIVE_OBJECT_GET_COMMENT: { - char * comment = HDva_arg(arguments, char *); - size_t bufsize = HDva_arg(arguments, size_t); - ssize_t *ret = HDva_arg(arguments, ssize_t *); + H5VL_native_object_get_comment_t *gc_args = &opt_args->get_comment; /* Retrieve the object's comment */ if (loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Oget_comment */ - if ((*ret = H5G_loc_get_comment(&loc, ".", comment /*out*/, bufsize)) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") + if (H5G_loc_get_comment(&loc, ".", gc_args->buf, gc_args->buf_size, gc_args->comment_len) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get comment for object") } /* end if */ else if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Oget_comment_by_name */ - if ((*ret = H5G_loc_get_comment(&loc, loc_params->loc_data.loc_by_name.name, comment /*out*/, - bufsize)) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") + if (H5G_loc_get_comment(&loc, loc_params->loc_data.loc_by_name.name, gc_args->buf, + gc_args->buf_size, gc_args->comment_len) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get comment for object") } /* end else-if */ else HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown set_coment parameters") + break; } /* H5Oset_comment */ case H5VL_NATIVE_OBJECT_SET_COMMENT: { - const char *comment = HDva_arg(arguments, char *); - if (loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Oset_comment */ - /* (Re)set the object's comment */ - if (H5G_loc_set_comment(&loc, ".", comment) < 0) + if (H5G_loc_set_comment(&loc, ".", opt_args->set_comment.comment) < 0) HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") } /* end if */ else if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Oset_comment_by_name */ - /* (Re)set the object's comment */ - if (H5G_loc_set_comment(&loc, loc_params->loc_data.loc_by_name.name, comment) < 0) + if (H5G_loc_set_comment(&loc, loc_params->loc_data.loc_by_name.name, + opt_args->set_comment.comment) < 0) HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") } /* end else-if */ else HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown set_coment parameters") + break; } /* H5Odisable_mdc_flushes */ case H5VL_NATIVE_OBJECT_DISABLE_MDC_FLUSHES: { - H5O_loc_t *oloc = loc.oloc; - - if (H5O_disable_mdc_flushes(oloc) < 0) + if (H5O__disable_mdc_flushes(loc.oloc) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCORK, FAIL, "unable to cork the metadata cache"); break; @@ -529,9 +502,7 @@ H5VL__native_object_optional(void *obj, H5VL_object_optional_t optional_type, hi /* H5Oenable_mdc_flushes */ case H5VL_NATIVE_OBJECT_ENABLE_MDC_FLUSHES: { - H5O_loc_t *oloc = loc.oloc; - - if (H5O_enable_mdc_flushes(oloc) < 0) + if (H5O__enable_mdc_flushes(loc.oloc) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTUNCORK, FAIL, "unable to uncork the metadata cache"); break; @@ -539,10 +510,7 @@ H5VL__native_object_optional(void *obj, H5VL_object_optional_t optional_type, hi /* H5Oare_mdc_flushes_disabled */ case H5VL_NATIVE_OBJECT_ARE_MDC_FLUSHES_DISABLED: { - H5O_loc_t *oloc = loc.oloc; - hbool_t * are_disabled = (hbool_t *)HDva_arg(arguments, hbool_t *); - - if (H5O_are_mdc_flushes_disabled(oloc, are_disabled) < 0) + if (H5O__are_mdc_flushes_disabled(loc.oloc, opt_args->are_mdc_flushes_disabled.flag) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to determine metadata cache cork status"); break; @@ -550,19 +518,16 @@ H5VL__native_object_optional(void *obj, H5VL_object_optional_t optional_type, hi /* H5Oget_native_info(_name|_by_idx) */ case H5VL_NATIVE_OBJECT_GET_NATIVE_INFO: { - H5O_native_info_t *native_info = HDva_arg(arguments, H5O_native_info_t *); - unsigned fields = HDva_arg(arguments, unsigned); + H5VL_native_object_get_native_info_t *gni_args = &opt_args->get_native_info; /* Use the original H5Oget_info code to get the data */ - - if (loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Oget_info */ - /* Retrieve the object's information */ - if (H5G_loc_native_info(&loc, ".", native_info, fields) < 0) + if (loc_params->type == H5VL_OBJECT_BY_SELF) { + if (H5G_loc_native_info(&loc, ".", gni_args->ninfo, gni_args->fields) < 0) HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") } /* end if */ else if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Oget_info_by_name */ - /* Retrieve the object's information */ - if (H5G_loc_native_info(&loc, loc_params->loc_data.loc_by_name.name, native_info, fields) < 0) + if (H5G_loc_native_info(&loc, loc_params->loc_data.loc_by_name.name, gni_args->ninfo, + gni_args->fields) < 0) HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") } /* end else-if */ else if (loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Oget_info_by_idx */ @@ -582,8 +547,7 @@ H5VL__native_object_optional(void *obj, H5VL_object_optional_t optional_type, hi loc_params->loc_data.loc_by_idx.n, &obj_loc /*out*/) < 0) HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "group not found") - /* Retrieve the object's information */ - if (H5O_get_native_info(obj_loc.oloc, native_info, fields) < 0) { + if (H5O_get_native_info(obj_loc.oloc, gni_args->ninfo, gni_args->fields) < 0) { H5G_loc_free(&obj_loc); HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object info") } /* end if */ diff --git a/src/H5VLnative_private.h b/src/H5VLnative_private.h index 687221a..1fd90c8 100644 --- a/src/H5VLnative_private.h +++ b/src/H5VLnative_private.h @@ -49,13 +49,10 @@ void * H5VL__native_attr_open(void *obj, const H5VL_loc_params_t *loc_par hid_t aapl_id, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_attr_read(void *attr, hid_t dtype_id, void *buf, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_attr_write(void *attr, hid_t dtype_id, const void *buf, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VL__native_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); +H5_DLL herr_t H5VL__native_attr_get(void *obj, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -H5_DLL herr_t H5VL__native_attr_optional(void *obj, H5VL_attr_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments); + H5VL_attr_specific_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL__native_attr_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_attr_close(void *attr, hid_t dxpl_id, void **req); /* Dataset callbacks */ @@ -68,12 +65,11 @@ H5_DLL herr_t H5VL__native_dataset_read(void *dset, hid_t mem_type_id, hid_t mem hid_t file_space_id, hid_t plist_id, void *buf, void **req); H5_DLL herr_t H5VL__native_dataset_write(void *dset, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t plist_id, const void *buf, void **req); -H5_DLL herr_t H5VL__native_dataset_get(void *dset, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); -H5_DLL herr_t H5VL__native_dataset_specific(void *dset, H5VL_dataset_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments); -H5_DLL herr_t H5VL__native_dataset_optional(void *dset, H5VL_dataset_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); +H5_DLL herr_t H5VL__native_dataset_get(void *dset, H5VL_dataset_get_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL__native_dataset_specific(void *dset, H5VL_dataset_specific_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VL__native_dataset_optional(void *dset, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VL__native_dataset_close(void *dset, hid_t dxpl_id, void **req); /* Datatype callbacks */ @@ -82,10 +78,9 @@ H5_DLL void * H5VL__native_datatype_commit(void *obj, const H5VL_loc_params_t *l hid_t dxpl_id, void **req); H5_DLL void * H5VL__native_datatype_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t tapl_id, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VL__native_datatype_get(void *dt, H5VL_datatype_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); -H5_DLL herr_t H5VL__native_datatype_specific(void *dt, H5VL_datatype_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments); +H5_DLL herr_t H5VL__native_datatype_get(void *dt, H5VL_datatype_get_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL__native_datatype_specific(void *dt, H5VL_datatype_specific_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VL__native_datatype_close(void *dt, hid_t dxpl_id, void **req); /* File callbacks */ @@ -93,12 +88,10 @@ H5_DLL void * H5VL__native_file_create(const char *name, unsigned flags, hid_t f hid_t dxpl_id, void **req); H5_DLL void * H5VL__native_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VL__native_file_get(void *file, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); -H5_DLL herr_t H5VL__native_file_specific(void *file, H5VL_file_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments); -H5_DLL herr_t H5VL__native_file_optional(void *file, H5VL_file_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments); +H5_DLL herr_t H5VL__native_file_get(void *file, H5VL_file_get_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL__native_file_specific(void *file, H5VL_file_specific_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VL__native_file_optional(void *file, H5VL_optional_args_t *args, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_file_close(void *file, hid_t dxpl_id, void **req); /* Group callbacks */ @@ -107,29 +100,26 @@ H5_DLL void * H5VL__native_group_create(void *obj, const H5VL_loc_params_t *loc_ void **req); H5_DLL void * H5VL__native_group_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t gapl_id, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VL__native_group_get(void *obj, H5VL_group_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); -H5_DLL herr_t H5VL__native_group_specific(void *obj, H5VL_group_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments); -H5_DLL herr_t H5VL__native_group_optional(void *obj, H5VL_group_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); +H5_DLL herr_t H5VL__native_group_get(void *obj, H5VL_group_get_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL__native_group_specific(void *obj, H5VL_group_specific_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VL__native_group_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_group_close(void *grp, hid_t dxpl_id, void **req); /* Link callbacks */ -H5_DLL herr_t H5VL__native_link_create(H5VL_link_create_type_t create_type, void *obj, +H5_DLL herr_t H5VL__native_link_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t lapl_id, - hid_t dxpl_id, void **req, va_list arguments); + hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_link_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_link_move(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VL__native_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_t get_type, - hid_t dxpl_id, void **req, va_list arguments); +H5_DLL herr_t H5VL__native_link_get(void *obj, const H5VL_loc_params_t *loc_params, + H5VL_link_get_args_t *args, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_link_specific(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); + H5VL_link_specific_args_t *args, hid_t dxpl_id, void **req); /* Object callbacks */ H5_DLL void *H5VL__native_object_open(void *obj, const H5VL_loc_params_t *loc_params, H5I_type_t *opened_type, @@ -139,25 +129,23 @@ H5_DLL herr_t H5VL__native_object_copy(void *src_obj, const H5VL_loc_params_t *l const H5VL_loc_params_t *loc_params2, const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_object_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); + H5VL_object_get_args_t *args, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -H5_DLL herr_t H5VL__native_object_optional(void *obj, H5VL_object_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); + H5VL_object_specific_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL__native_object_optional(void *obj, const H5VL_loc_params_t *loc_params, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req); /* Connector/container introspection functions */ H5_DLL herr_t H5VL__native_introspect_get_conn_cls(void *obj, H5VL_get_conn_lvl_t lvl, const H5VL_class_t **conn_cls); +H5_DLL herr_t H5VL__native_introspect_get_cap_flags(const void *info, unsigned *cap_flags); H5_DLL herr_t H5VL__native_introspect_opt_query(void *obj, H5VL_subclass_t cls, int opt_type, uint64_t *flags); /* Blob callbacks */ H5_DLL herr_t H5VL__native_blob_put(void *obj, const void *buf, size_t size, void *blob_id, void *ctx); H5_DLL herr_t H5VL__native_blob_get(void *obj, const void *blob_id, void *buf, size_t size, void *ctx); -H5_DLL herr_t H5VL__native_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, - va_list arguments); +H5_DLL herr_t H5VL__native_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_args_t *args); /* Token callbacks */ H5_DLL herr_t H5VL__native_token_cmp(void *obj, const H5O_token_t *token1, const H5O_token_t *token2, diff --git a/src/H5VLpassthru.c b/src/H5VLpassthru.c index 5ccc082..681531e 100644 --- a/src/H5VLpassthru.c +++ b/src/H5VLpassthru.c @@ -77,15 +77,6 @@ typedef struct H5VL_pass_through_wrap_ctx_t { /********************* */ /* Helper routines */ -static herr_t H5VL_pass_through_file_specific_reissue(void *obj, hid_t connector_id, - H5VL_file_specific_t specific_type, hid_t dxpl_id, - void **req, ...); -static herr_t H5VL_pass_through_request_specific_reissue(void *obj, hid_t connector_id, - H5VL_request_specific_t specific_type, ...); -static herr_t H5VL_pass_through_link_create_reissue(H5VL_link_create_type_t create_type, void *obj, - const H5VL_loc_params_t *loc_params, hid_t connector_id, - hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req, - ...); static H5VL_pass_through_t *H5VL_pass_through_new_obj(void *under_obj, hid_t under_vol_id); static herr_t H5VL_pass_through_free_obj(H5VL_pass_through_t *obj); @@ -117,13 +108,11 @@ static herr_t H5VL_pass_through_attr_read(void *attr, hid_t mem_type_id, void *b void **req); static herr_t H5VL_pass_through_attr_write(void *attr, hid_t mem_type_id, const void *buf, hid_t dxpl_id, void **req); -static herr_t H5VL_pass_through_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); +static herr_t H5VL_pass_through_attr_get(void *obj, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req); static herr_t H5VL_pass_through_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -static herr_t H5VL_pass_through_attr_optional(void *obj, H5VL_attr_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); + H5VL_attr_specific_args_t *args, hid_t dxpl_id, void **req); +static herr_t H5VL_pass_through_attr_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); static herr_t H5VL_pass_through_attr_close(void *attr, hid_t dxpl_id, void **req); /* Dataset callbacks */ @@ -137,12 +126,12 @@ static herr_t H5VL_pass_through_dataset_read(void *dset, hid_t mem_type_id, hid_ static herr_t H5VL_pass_through_dataset_write(void *dset, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t plist_id, const void *buf, void **req); -static herr_t H5VL_pass_through_dataset_get(void *dset, H5VL_dataset_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments); -static herr_t H5VL_pass_through_dataset_specific(void *obj, H5VL_dataset_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments); -static herr_t H5VL_pass_through_dataset_optional(void *obj, H5VL_dataset_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); +static herr_t H5VL_pass_through_dataset_get(void *dset, H5VL_dataset_get_args_t *args, hid_t dxpl_id, + void **req); +static herr_t H5VL_pass_through_dataset_specific(void *obj, H5VL_dataset_specific_args_t *args, hid_t dxpl_id, + void **req); +static herr_t H5VL_pass_through_dataset_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); static herr_t H5VL_pass_through_dataset_close(void *dset, hid_t dxpl_id, void **req); /* Datatype callbacks */ @@ -151,12 +140,12 @@ static void *H5VL_pass_through_datatype_commit(void *obj, const H5VL_loc_params_ hid_t tapl_id, hid_t dxpl_id, void **req); static void *H5VL_pass_through_datatype_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t tapl_id, hid_t dxpl_id, void **req); -static herr_t H5VL_pass_through_datatype_get(void *dt, H5VL_datatype_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments); -static herr_t H5VL_pass_through_datatype_specific(void *obj, H5VL_datatype_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments); -static herr_t H5VL_pass_through_datatype_optional(void *obj, H5VL_datatype_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); +static herr_t H5VL_pass_through_datatype_get(void *dt, H5VL_datatype_get_args_t *args, hid_t dxpl_id, + void **req); +static herr_t H5VL_pass_through_datatype_specific(void *obj, H5VL_datatype_specific_args_t *args, + hid_t dxpl_id, void **req); +static herr_t H5VL_pass_through_datatype_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); static herr_t H5VL_pass_through_datatype_close(void *dt, hid_t dxpl_id, void **req); /* File callbacks */ @@ -164,12 +153,11 @@ static void * H5VL_pass_through_file_create(const char *name, unsigned flags, hi hid_t dxpl_id, void **req); static void * H5VL_pass_through_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req); -static herr_t H5VL_pass_through_file_get(void *file, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); -static herr_t H5VL_pass_through_file_specific(void *file, H5VL_file_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments); -static herr_t H5VL_pass_through_file_optional(void *file, H5VL_file_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); +static herr_t H5VL_pass_through_file_get(void *file, H5VL_file_get_args_t *args, hid_t dxpl_id, void **req); +static herr_t H5VL_pass_through_file_specific(void *file, H5VL_file_specific_args_t *args, hid_t dxpl_id, + void **req); +static herr_t H5VL_pass_through_file_optional(void *file, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); static herr_t H5VL_pass_through_file_close(void *file, hid_t dxpl_id, void **req); /* Group callbacks */ @@ -178,18 +166,17 @@ static void * H5VL_pass_through_group_create(void *obj, const H5VL_loc_params_t void **req); static void * H5VL_pass_through_group_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t gapl_id, hid_t dxpl_id, void **req); -static herr_t H5VL_pass_through_group_get(void *obj, H5VL_group_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); -static herr_t H5VL_pass_through_group_specific(void *obj, H5VL_group_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments); -static herr_t H5VL_pass_through_group_optional(void *obj, H5VL_group_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); +static herr_t H5VL_pass_through_group_get(void *obj, H5VL_group_get_args_t *args, hid_t dxpl_id, void **req); +static herr_t H5VL_pass_through_group_specific(void *obj, H5VL_group_specific_args_t *args, hid_t dxpl_id, + void **req); +static herr_t H5VL_pass_through_group_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); static herr_t H5VL_pass_through_group_close(void *grp, hid_t dxpl_id, void **req); /* Link callbacks */ -static herr_t H5VL_pass_through_link_create(H5VL_link_create_type_t create_type, void *obj, +static herr_t H5VL_pass_through_link_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t lapl_id, - hid_t dxpl_id, void **req, va_list arguments); + hid_t dxpl_id, void **req); static herr_t H5VL_pass_through_link_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); @@ -197,13 +184,11 @@ static herr_t H5VL_pass_through_link_move(void *src_obj, const H5VL_loc_params_t const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); static herr_t H5VL_pass_through_link_get(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_link_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); + H5VL_link_get_args_t *args, hid_t dxpl_id, void **req); static herr_t H5VL_pass_through_link_specific(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -static herr_t H5VL_pass_through_link_optional(void *obj, H5VL_link_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); + H5VL_link_specific_args_t *args, hid_t dxpl_id, void **req); +static herr_t H5VL_pass_through_link_optional(void *obj, const H5VL_loc_params_t *loc_params, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req); /* Object callbacks */ static void * H5VL_pass_through_object_open(void *obj, const H5VL_loc_params_t *loc_params, @@ -213,17 +198,16 @@ static herr_t H5VL_pass_through_object_copy(void *src_obj, const H5VL_loc_params const H5VL_loc_params_t *dst_loc_params, const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req); static herr_t H5VL_pass_through_object_get(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_object_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); + H5VL_object_get_args_t *args, hid_t dxpl_id, void **req); static herr_t H5VL_pass_through_object_specific(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_object_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments); -static herr_t H5VL_pass_through_object_optional(void *obj, H5VL_object_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); + H5VL_object_specific_args_t *args, hid_t dxpl_id, void **req); +static herr_t H5VL_pass_through_object_optional(void *obj, const H5VL_loc_params_t *loc_params, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req); /* Container/connector introspection callbacks */ static herr_t H5VL_pass_through_introspect_get_conn_cls(void *obj, H5VL_get_conn_lvl_t lvl, const H5VL_class_t **conn_cls); +static herr_t H5VL_pass_through_introspect_get_cap_flags(const void *info, unsigned *cap_flags); static herr_t H5VL_pass_through_introspect_opt_query(void *obj, H5VL_subclass_t cls, int opt_type, uint64_t *flags); @@ -231,19 +215,15 @@ static herr_t H5VL_pass_through_introspect_opt_query(void *obj, H5VL_subclass_t static herr_t H5VL_pass_through_request_wait(void *req, uint64_t timeout, H5VL_request_status_t *status); static herr_t H5VL_pass_through_request_notify(void *obj, H5VL_request_notify_t cb, void *ctx); static herr_t H5VL_pass_through_request_cancel(void *req, H5VL_request_status_t *status); -static herr_t H5VL_pass_through_request_specific(void *req, H5VL_request_specific_t specific_type, - va_list arguments); -static herr_t H5VL_pass_through_request_optional(void *req, H5VL_request_optional_t opt_type, - va_list arguments); +static herr_t H5VL_pass_through_request_specific(void *req, H5VL_request_specific_args_t *args); +static herr_t H5VL_pass_through_request_optional(void *req, H5VL_optional_args_t *args); static herr_t H5VL_pass_through_request_free(void *req); /* Blob callbacks */ static herr_t H5VL_pass_through_blob_put(void *obj, const void *buf, size_t size, void *blob_id, void *ctx); static herr_t H5VL_pass_through_blob_get(void *obj, const void *blob_id, void *buf, size_t size, void *ctx); -static herr_t H5VL_pass_through_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, - va_list arguments); -static herr_t H5VL_pass_through_blob_optional(void *obj, void *blob_id, H5VL_blob_optional_t opt_type, - va_list arguments); +static herr_t H5VL_pass_through_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_args_t *args); +static herr_t H5VL_pass_through_blob_optional(void *obj, void *blob_id, H5VL_optional_args_t *args); /* Token callbacks */ static herr_t H5VL_pass_through_token_cmp(void *obj, const H5O_token_t *token1, const H5O_token_t *token2, @@ -254,8 +234,7 @@ static herr_t H5VL_pass_through_token_from_str(void *obj, H5I_type_t obj_type, c H5O_token_t *token); /* Generic optional callback */ -static herr_t H5VL_pass_through_optional(void *obj, int op_type, hid_t dxpl_id, void **req, - va_list arguments); +static herr_t H5VL_pass_through_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req); /*******************/ /* Local variables */ @@ -355,8 +334,9 @@ static const H5VL_class_t H5VL_pass_through_g = { }, { /* introspect_cls */ - H5VL_pass_through_introspect_get_conn_cls, /* get_conn_cls */ - H5VL_pass_through_introspect_opt_query, /* opt_query */ + H5VL_pass_through_introspect_get_conn_cls, /* get_conn_cls */ + H5VL_pass_through_introspect_get_cap_flags, /* get_cap_flags */ + H5VL_pass_through_introspect_opt_query, /* opt_query */ }, { /* request_cls */ @@ -1025,7 +1005,7 @@ H5VL_pass_through_attr_write(void *attr, hid_t mem_type_id, const void *buf, hid *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, va_list arguments) +H5VL_pass_through_attr_get(void *obj, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -1034,7 +1014,7 @@ H5VL_pass_through_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t dxpl_id, v printf("------- PASS THROUGH VOL ATTRIBUTE Get\n"); #endif - ret_value = H5VLattr_get(o->under_object, o->under_vol_id, get_type, dxpl_id, req, arguments); + ret_value = H5VLattr_get(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -1055,8 +1035,7 @@ H5VL_pass_through_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t dxpl_id, v */ static herr_t H5VL_pass_through_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments) + H5VL_attr_specific_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -1065,8 +1044,7 @@ H5VL_pass_through_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, printf("------- PASS THROUGH VOL ATTRIBUTE Specific\n"); #endif - ret_value = H5VLattr_specific(o->under_object, loc_params, o->under_vol_id, specific_type, dxpl_id, req, - arguments); + ret_value = H5VLattr_specific(o->under_object, loc_params, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -1086,8 +1064,7 @@ H5VL_pass_through_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_attr_optional(void *obj, H5VL_attr_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_attr_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -1096,7 +1073,7 @@ H5VL_pass_through_attr_optional(void *obj, H5VL_attr_optional_t opt_type, hid_t printf("------- PASS THROUGH VOL ATTRIBUTE Optional\n"); #endif - ret_value = H5VLattr_optional(o->under_object, o->under_vol_id, opt_type, dxpl_id, req, arguments); + ret_value = H5VLattr_optional(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -1285,8 +1262,7 @@ H5VL_pass_through_dataset_write(void *dset, hid_t mem_type_id, hid_t mem_space_i *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_dataset_get(void *dset, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_dataset_get(void *dset, H5VL_dataset_get_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)dset; herr_t ret_value; @@ -1295,7 +1271,7 @@ H5VL_pass_through_dataset_get(void *dset, H5VL_dataset_get_t get_type, hid_t dxp printf("------- PASS THROUGH VOL DATASET Get\n"); #endif - ret_value = H5VLdataset_get(o->under_object, o->under_vol_id, get_type, dxpl_id, req, arguments); + ret_value = H5VLdataset_get(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -1315,8 +1291,7 @@ H5VL_pass_through_dataset_get(void *dset, H5VL_dataset_get_t get_type, hid_t dxp *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_dataset_specific(void *obj, H5VL_dataset_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL_pass_through_dataset_specific(void *obj, H5VL_dataset_specific_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; hid_t under_vol_id; @@ -1326,12 +1301,12 @@ H5VL_pass_through_dataset_specific(void *obj, H5VL_dataset_specific_t specific_t printf("------- PASS THROUGH VOL H5Dspecific\n"); #endif - // Save copy of underlying VOL connector ID and prov helper, in case of - // refresh destroying the current object + /* Save copy of underlying VOL connector ID, in case of + * 'refresh' operation destroying the current object + */ under_vol_id = o->under_vol_id; - ret_value = - H5VLdataset_specific(o->under_object, o->under_vol_id, specific_type, dxpl_id, req, arguments); + ret_value = H5VLdataset_specific(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -1351,8 +1326,7 @@ H5VL_pass_through_dataset_specific(void *obj, H5VL_dataset_specific_t specific_t *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_dataset_optional(void *obj, H5VL_dataset_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_dataset_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -1361,7 +1335,7 @@ H5VL_pass_through_dataset_optional(void *obj, H5VL_dataset_optional_t opt_type, printf("------- PASS THROUGH VOL DATASET Optional\n"); #endif - ret_value = H5VLdataset_optional(o->under_object, o->under_vol_id, opt_type, dxpl_id, req, arguments); + ret_value = H5VLdataset_optional(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -1488,8 +1462,7 @@ H5VL_pass_through_datatype_open(void *obj, const H5VL_loc_params_t *loc_params, *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_datatype_get(void *dt, H5VL_datatype_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_datatype_get(void *dt, H5VL_datatype_get_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)dt; herr_t ret_value; @@ -1498,7 +1471,7 @@ H5VL_pass_through_datatype_get(void *dt, H5VL_datatype_get_t get_type, hid_t dxp printf("------- PASS THROUGH VOL DATATYPE Get\n"); #endif - ret_value = H5VLdatatype_get(o->under_object, o->under_vol_id, get_type, dxpl_id, req, arguments); + ret_value = H5VLdatatype_get(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -1518,8 +1491,7 @@ H5VL_pass_through_datatype_get(void *dt, H5VL_datatype_get_t get_type, hid_t dxp *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_datatype_specific(void *obj, H5VL_datatype_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL_pass_through_datatype_specific(void *obj, H5VL_datatype_specific_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; hid_t under_vol_id; @@ -1529,12 +1501,12 @@ H5VL_pass_through_datatype_specific(void *obj, H5VL_datatype_specific_t specific printf("------- PASS THROUGH VOL DATATYPE Specific\n"); #endif - // Save copy of underlying VOL connector ID and prov helper, in case of - // refresh destroying the current object + /* Save copy of underlying VOL connector ID, in case of + * 'refresh' operation destroying the current object + */ under_vol_id = o->under_vol_id; - ret_value = - H5VLdatatype_specific(o->under_object, o->under_vol_id, specific_type, dxpl_id, req, arguments); + ret_value = H5VLdatatype_specific(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -1554,8 +1526,7 @@ H5VL_pass_through_datatype_specific(void *obj, H5VL_datatype_specific_t specific *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_datatype_optional(void *obj, H5VL_datatype_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_datatype_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -1564,7 +1535,7 @@ H5VL_pass_through_datatype_optional(void *obj, H5VL_datatype_optional_t opt_type printf("------- PASS THROUGH VOL DATATYPE Optional\n"); #endif - ret_value = H5VLdatatype_optional(o->under_object, o->under_vol_id, opt_type, dxpl_id, req, arguments); + ret_value = H5VLdatatype_optional(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -1732,7 +1703,7 @@ H5VL_pass_through_file_open(const char *name, unsigned flags, hid_t fapl_id, hid *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_file_get(void *file, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, va_list arguments) +H5VL_pass_through_file_get(void *file, H5VL_file_get_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)file; herr_t ret_value; @@ -1741,7 +1712,7 @@ H5VL_pass_through_file_get(void *file, H5VL_file_get_t get_type, hid_t dxpl_id, printf("------- PASS THROUGH VOL FILE Get\n"); #endif - ret_value = H5VLfile_get(o->under_object, o->under_vol_id, get_type, dxpl_id, req, arguments); + ret_value = H5VLfile_get(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -1751,31 +1722,6 @@ H5VL_pass_through_file_get(void *file, H5VL_file_get_t get_type, hid_t dxpl_id, } /* end H5VL_pass_through_file_get() */ /*------------------------------------------------------------------------- - * Function: H5VL_pass_through_file_specific_reissue - * - * Purpose: Re-wrap vararg arguments into a va_list and reissue the - * file specific callback to the underlying VOL connector. - * - * Return: Success: 0 - * Failure: -1 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5VL_pass_through_file_specific_reissue(void *obj, hid_t connector_id, H5VL_file_specific_t specific_type, - hid_t dxpl_id, void **req, ...) -{ - va_list arguments; - herr_t ret_value; - - va_start(arguments, req); - ret_value = H5VLfile_specific(obj, connector_id, specific_type, dxpl_id, req, arguments); - va_end(arguments); - - return ret_value; -} /* end H5VL_pass_through_file_specific_reissue() */ - -/*------------------------------------------------------------------------- * Function: H5VL_pass_through_file_specific * * Purpose: Specific operation on file @@ -1786,106 +1732,109 @@ H5VL_pass_through_file_specific_reissue(void *obj, hid_t connector_id, H5VL_file *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_file_specific(void *file, H5VL_file_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_file_specific(void *file, H5VL_file_specific_args_t *args, hid_t dxpl_id, void **req) { - H5VL_pass_through_t *o = (H5VL_pass_through_t *)file; - hid_t under_vol_id = -1; - herr_t ret_value; + H5VL_pass_through_t * o = (H5VL_pass_through_t *)file; + H5VL_pass_through_t * new_o; + H5VL_file_specific_args_t my_args; + H5VL_file_specific_args_t *new_args; + H5VL_pass_through_info_t * info; + hid_t under_vol_id = -1; + herr_t ret_value; #ifdef ENABLE_PASSTHRU_LOGGING printf("------- PASS THROUGH VOL FILE Specific\n"); #endif - /* Unpack arguments to get at the child file pointer when mounting a file */ - if (specific_type == H5VL_FILE_MOUNT) { - H5I_type_t loc_type; - const char * name; - H5VL_pass_through_t *child_file; - hid_t plist_id; - - /* Retrieve parameters for 'mount' operation, so we can unwrap the child file */ - loc_type = (H5I_type_t)va_arg(arguments, int); /* enum work-around */ - name = va_arg(arguments, const char *); - child_file = (H5VL_pass_through_t *)va_arg(arguments, void *); - plist_id = va_arg(arguments, hid_t); - - /* Keep the correct underlying VOL ID for possible async request token */ - under_vol_id = o->under_vol_id; - - /* Re-issue 'file specific' call, using the unwrapped pieces */ - ret_value = H5VL_pass_through_file_specific_reissue(o->under_object, o->under_vol_id, specific_type, - dxpl_id, req, (int)loc_type, name, - child_file->under_object, plist_id); - } /* end if */ - else if (specific_type == H5VL_FILE_IS_ACCESSIBLE || specific_type == H5VL_FILE_DELETE) { - H5VL_pass_through_info_t *info; - hid_t fapl_id, under_fapl_id; - const char * name; - htri_t * ret; - - /* Get the arguments for the 'is accessible' check */ - fapl_id = va_arg(arguments, hid_t); - name = va_arg(arguments, const char *); - ret = va_arg(arguments, htri_t *); + if (args->op_type == H5VL_FILE_IS_ACCESSIBLE) { + /* Shallow copy the args */ + memcpy(&my_args, args, sizeof(my_args)); /* Get copy of our VOL info from FAPL */ - H5Pget_vol_info(fapl_id, (void **)&info); + H5Pget_vol_info(args->args.is_accessible.fapl_id, (void **)&info); /* Make sure we have info about the underlying VOL to be used */ if (!info) return (-1); + /* Keep the correct underlying VOL ID for later */ + under_vol_id = info->under_vol_id; + /* Copy the FAPL */ - under_fapl_id = H5Pcopy(fapl_id); + my_args.args.is_accessible.fapl_id = H5Pcopy(args->args.is_accessible.fapl_id); /* Set the VOL ID and info for the underlying FAPL */ - H5Pset_vol(under_fapl_id, info->under_vol_id, info->under_vol_info); + H5Pset_vol(my_args.args.is_accessible.fapl_id, info->under_vol_id, info->under_vol_info); - /* Keep the correct underlying VOL ID for possible async request token */ + /* Set argument pointer to new arguments */ + new_args = &my_args; + + /* Set object pointer for operation */ + new_o = NULL; + } /* end else-if */ + else if (args->op_type == H5VL_FILE_DELETE) { + /* Shallow copy the args */ + memcpy(&my_args, args, sizeof(my_args)); + + /* Get copy of our VOL info from FAPL */ + H5Pget_vol_info(args->args.del.fapl_id, (void **)&info); + + /* Make sure we have info about the underlying VOL to be used */ + if (!info) + return (-1); + + /* Keep the correct underlying VOL ID for later */ under_vol_id = info->under_vol_id; - /* Re-issue 'file specific' call */ - ret_value = H5VL_pass_through_file_specific_reissue(NULL, info->under_vol_id, specific_type, dxpl_id, - req, under_fapl_id, name, ret); + /* Copy the FAPL */ + my_args.args.del.fapl_id = H5Pcopy(args->args.del.fapl_id); - /* Close underlying FAPL */ - H5Pclose(under_fapl_id); + /* Set the VOL ID and info for the underlying FAPL */ + H5Pset_vol(my_args.args.del.fapl_id, info->under_vol_id, info->under_vol_info); - /* Release copy of our VOL info */ - H5VL_pass_through_info_free(info); + /* Set argument pointer to new arguments */ + new_args = &my_args; + + /* Set object pointer for operation */ + new_o = NULL; } /* end else-if */ else { - va_list my_arguments; - - /* Make a copy of the argument list for later, if reopening */ - if (specific_type == H5VL_FILE_REOPEN) - va_copy(my_arguments, arguments); - - /* Keep the correct underlying VOL ID for possible async request token */ + /* Keep the correct underlying VOL ID for later */ under_vol_id = o->under_vol_id; - ret_value = - H5VLfile_specific(o->under_object, o->under_vol_id, specific_type, dxpl_id, req, arguments); - - /* Wrap file struct pointer, if we reopened one */ - if (specific_type == H5VL_FILE_REOPEN) { - if (ret_value >= 0) { - void **ret = va_arg(my_arguments, void **); + /* Set argument pointer to current arguments */ + new_args = args; - if (ret && *ret) - *ret = H5VL_pass_through_new_obj(*ret, o->under_vol_id); - } /* end if */ + /* Set object pointer for operation */ + new_o = o->under_object; + } /* end else */ - /* Finish use of copied vararg list */ - va_end(my_arguments); - } /* end if */ - } /* end else */ + ret_value = H5VLfile_specific(new_o, under_vol_id, new_args, dxpl_id, req); /* Check for async request */ if (req && *req) *req = H5VL_pass_through_new_obj(*req, under_vol_id); + if (args->op_type == H5VL_FILE_IS_ACCESSIBLE) { + /* Close underlying FAPL */ + H5Pclose(my_args.args.is_accessible.fapl_id); + + /* Release copy of our VOL info */ + H5VL_pass_through_info_free(info); + } /* end else-if */ + else if (args->op_type == H5VL_FILE_DELETE) { + /* Close underlying FAPL */ + H5Pclose(my_args.args.del.fapl_id); + + /* Release copy of our VOL info */ + H5VL_pass_through_info_free(info); + } /* end else-if */ + else if (args->op_type == H5VL_FILE_REOPEN) { + /* Wrap file struct pointer for 'reopen' operation, if we reopened one */ + if (ret_value >= 0 && *args->args.reopen.file) + *args->args.reopen.file = H5VL_pass_through_new_obj(*args->args.reopen.file, under_vol_id); + } /* end else */ + return ret_value; } /* end H5VL_pass_through_file_specific() */ @@ -1900,8 +1849,7 @@ H5VL_pass_through_file_specific(void *file, H5VL_file_specific_t specific_type, *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_file_optional(void *file, H5VL_file_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_file_optional(void *file, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)file; herr_t ret_value; @@ -1910,7 +1858,7 @@ H5VL_pass_through_file_optional(void *file, H5VL_file_optional_t opt_type, hid_t printf("------- PASS THROUGH VOL File Optional\n"); #endif - ret_value = H5VLfile_optional(o->under_object, o->under_vol_id, opt_type, dxpl_id, req, arguments); + ret_value = H5VLfile_optional(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -2036,8 +1984,7 @@ H5VL_pass_through_group_open(void *obj, const H5VL_loc_params_t *loc_params, con *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_group_get(void *obj, H5VL_group_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_group_get(void *obj, H5VL_group_get_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -2046,7 +1993,7 @@ H5VL_pass_through_group_get(void *obj, H5VL_group_get_t get_type, hid_t dxpl_id, printf("------- PASS THROUGH VOL GROUP Get\n"); #endif - ret_value = H5VLgroup_get(o->under_object, o->under_vol_id, get_type, dxpl_id, req, arguments); + ret_value = H5VLgroup_get(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -2066,8 +2013,7 @@ H5VL_pass_through_group_get(void *obj, H5VL_group_get_t get_type, hid_t dxpl_id, *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_group_specific(void *obj, H5VL_group_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_group_specific(void *obj, H5VL_group_specific_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; hid_t under_vol_id; @@ -2077,11 +2023,27 @@ H5VL_pass_through_group_specific(void *obj, H5VL_group_specific_t specific_type, printf("------- PASS THROUGH VOL GROUP Specific\n"); #endif - // Save copy of underlying VOL connector ID and prov helper, in case of - // refresh destroying the current object + /* Save copy of underlying VOL connector ID, in case of + * 'refresh' operation destroying the current object + */ under_vol_id = o->under_vol_id; - ret_value = H5VLgroup_specific(o->under_object, o->under_vol_id, specific_type, dxpl_id, req, arguments); + /* Unpack arguments to get at the child file pointer when mounting a file */ + if (args->op_type == H5VL_GROUP_MOUNT) { + H5VL_group_specific_args_t vol_cb_args; /* New group specific arg struct */ + + /* Set up new VOL callback arguments */ + vol_cb_args.op_type = H5VL_GROUP_MOUNT; + vol_cb_args.args.mount.name = args->args.mount.name; + vol_cb_args.args.mount.child_file = + ((H5VL_pass_through_t *)args->args.mount.child_file)->under_object; + vol_cb_args.args.mount.fmpl_id = args->args.mount.fmpl_id; + + /* Re-issue 'group specific' call, using the unwrapped pieces */ + ret_value = H5VLgroup_specific(o->under_object, under_vol_id, &vol_cb_args, dxpl_id, req); + } /* end if */ + else + ret_value = H5VLgroup_specific(o->under_object, under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -2101,8 +2063,7 @@ H5VL_pass_through_group_specific(void *obj, H5VL_group_specific_t specific_type, *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_group_optional(void *obj, H5VL_group_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_group_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -2111,7 +2072,7 @@ H5VL_pass_through_group_optional(void *obj, H5VL_group_optional_t opt_type, hid_ printf("------- PASS THROUGH VOL GROUP Optional\n"); #endif - ret_value = H5VLgroup_optional(o->under_object, o->under_vol_id, opt_type, dxpl_id, req, arguments); + ret_value = H5VLgroup_optional(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -2154,33 +2115,6 @@ H5VL_pass_through_group_close(void *grp, hid_t dxpl_id, void **req) } /* end H5VL_pass_through_group_close() */ /*------------------------------------------------------------------------- - * Function: H5VL_pass_through_link_create_reissue - * - * Purpose: Re-wrap vararg arguments into a va_list and reissue the - * link create callback to the underlying VOL connector. - * - * Return: Success: 0 - * Failure: -1 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5VL_pass_through_link_create_reissue(H5VL_link_create_type_t create_type, void *obj, - const H5VL_loc_params_t *loc_params, hid_t connector_id, hid_t lcpl_id, - hid_t lapl_id, hid_t dxpl_id, void **req, ...) -{ - va_list arguments; - herr_t ret_value; - - va_start(arguments, req); - ret_value = H5VLlink_create(create_type, obj, loc_params, connector_id, lcpl_id, lapl_id, dxpl_id, req, - arguments); - va_end(arguments); - - return ret_value; -} /* end H5VL_pass_through_link_create_reissue() */ - -/*------------------------------------------------------------------------- * Function: H5VL_pass_through_link_create * * Purpose: Creates a hard / soft / UD / external link. @@ -2191,9 +2125,8 @@ H5VL_pass_through_link_create_reissue(H5VL_link_create_type_t create_type, void *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_link_create(H5VL_link_create_type_t create_type, void *obj, - const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t lapl_id, - hid_t dxpl_id, void **req, va_list arguments) +H5VL_pass_through_link_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t *loc_params, + hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; hid_t under_vol_id = -1; @@ -2208,32 +2141,22 @@ H5VL_pass_through_link_create(H5VL_link_create_type_t create_type, void *obj, under_vol_id = o->under_vol_id; /* Fix up the link target object for hard link creation */ - if (H5VL_LINK_CREATE_HARD == create_type) { - void * cur_obj; - H5VL_loc_params_t *cur_params; + if (H5VL_LINK_CREATE_HARD == args->op_type) { + void *cur_obj = args->args.hard.curr_obj; - /* Retrieve the object & loc params for the link target */ - cur_obj = va_arg(arguments, void *); - cur_params = va_arg(arguments, H5VL_loc_params_t *); - - /* If it's a non-NULL pointer, find the 'under object' and re-set the property */ + /* If cur_obj is a non-NULL pointer, find its 'under object' and update the pointer */ if (cur_obj) { - /* Check if we still need the "under" VOL ID */ + /* Check if we still haven't set the "under" VOL ID */ if (under_vol_id < 0) under_vol_id = ((H5VL_pass_through_t *)cur_obj)->under_vol_id; - /* Set the object for the link target */ - cur_obj = ((H5VL_pass_through_t *)cur_obj)->under_object; + /* Update the object for the link target */ + args->args.hard.curr_obj = ((H5VL_pass_through_t *)cur_obj)->under_object; } /* end if */ + } /* end if */ - /* Re-issue 'link create' call, using the unwrapped pieces */ - ret_value = H5VL_pass_through_link_create_reissue(create_type, (o ? o->under_object : NULL), - loc_params, under_vol_id, lcpl_id, lapl_id, dxpl_id, - req, cur_obj, cur_params); - } /* end if */ - else - ret_value = H5VLlink_create(create_type, (o ? o->under_object : NULL), loc_params, under_vol_id, - lcpl_id, lapl_id, dxpl_id, req, arguments); + ret_value = H5VLlink_create(args, (o ? o->under_object : NULL), loc_params, under_vol_id, lcpl_id, + lapl_id, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -2347,8 +2270,8 @@ H5VL_pass_through_link_move(void *src_obj, const H5VL_loc_params_t *loc_params1, *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_t get_type, - hid_t dxpl_id, void **req, va_list arguments) +H5VL_pass_through_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_args_t *args, + hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -2357,7 +2280,7 @@ H5VL_pass_through_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_ printf("------- PASS THROUGH VOL LINK Get\n"); #endif - ret_value = H5VLlink_get(o->under_object, loc_params, o->under_vol_id, get_type, dxpl_id, req, arguments); + ret_value = H5VLlink_get(o->under_object, loc_params, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -2378,8 +2301,7 @@ H5VL_pass_through_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_ */ static herr_t H5VL_pass_through_link_specific(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments) + H5VL_link_specific_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -2388,8 +2310,7 @@ H5VL_pass_through_link_specific(void *obj, const H5VL_loc_params_t *loc_params, printf("------- PASS THROUGH VOL LINK Specific\n"); #endif - ret_value = H5VLlink_specific(o->under_object, loc_params, o->under_vol_id, specific_type, dxpl_id, req, - arguments); + ret_value = H5VLlink_specific(o->under_object, loc_params, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -2409,8 +2330,8 @@ H5VL_pass_through_link_specific(void *obj, const H5VL_loc_params_t *loc_params, *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_link_optional(void *obj, H5VL_link_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_link_optional(void *obj, const H5VL_loc_params_t *loc_params, H5VL_optional_args_t *args, + hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -2419,7 +2340,7 @@ H5VL_pass_through_link_optional(void *obj, H5VL_link_optional_t opt_type, hid_t printf("------- PASS THROUGH VOL LINK Optional\n"); #endif - ret_value = H5VLlink_optional(o->under_object, o->under_vol_id, opt_type, dxpl_id, req, arguments); + ret_value = H5VLlink_optional(o->under_object, loc_params, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -2509,8 +2430,8 @@ H5VL_pass_through_object_copy(void *src_obj, const H5VL_loc_params_t *src_loc_pa *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_t get_type, - hid_t dxpl_id, void **req, va_list arguments) +H5VL_pass_through_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_args_t *args, + hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -2519,8 +2440,7 @@ H5VL_pass_through_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5V printf("------- PASS THROUGH VOL OBJECT Get\n"); #endif - ret_value = - H5VLobject_get(o->under_object, loc_params, o->under_vol_id, get_type, dxpl_id, req, arguments); + ret_value = H5VLobject_get(o->under_object, loc_params, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -2541,8 +2461,7 @@ H5VL_pass_through_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5V */ static herr_t H5VL_pass_through_object_specific(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments) + H5VL_object_specific_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; hid_t under_vol_id; @@ -2552,12 +2471,12 @@ H5VL_pass_through_object_specific(void *obj, const H5VL_loc_params_t *loc_params printf("------- PASS THROUGH VOL OBJECT Specific\n"); #endif - // Save copy of underlying VOL connector ID and prov helper, in case of - // refresh destroying the current object + /* Save copy of underlying VOL connector ID, in case of + * 'refresh' operation destroying the current object + */ under_vol_id = o->under_vol_id; - ret_value = H5VLobject_specific(o->under_object, loc_params, o->under_vol_id, specific_type, dxpl_id, req, - arguments); + ret_value = H5VLobject_specific(o->under_object, loc_params, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -2577,8 +2496,8 @@ H5VL_pass_through_object_specific(void *obj, const H5VL_loc_params_t *loc_params *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_object_optional(void *obj, H5VL_object_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_object_optional(void *obj, const H5VL_loc_params_t *loc_params, H5VL_optional_args_t *args, + hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -2587,7 +2506,7 @@ H5VL_pass_through_object_optional(void *obj, H5VL_object_optional_t opt_type, hi printf("------- PASS THROUGH VOL OBJECT Optional\n"); #endif - ret_value = H5VLobject_optional(o->under_object, o->under_vol_id, opt_type, dxpl_id, req, arguments); + ret_value = H5VLobject_optional(o->under_object, loc_params, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -2597,7 +2516,7 @@ H5VL_pass_through_object_optional(void *obj, H5VL_object_optional_t opt_type, hi } /* end H5VL_pass_through_object_optional() */ /*------------------------------------------------------------------------- - * Function: H5VL_pass_through_introspect_get_conn_clss + * Function: H5VL_pass_through_introspect_get_conn_cls * * Purpose: Query the connector class. * @@ -2627,6 +2546,36 @@ H5VL_pass_through_introspect_get_conn_cls(void *obj, H5VL_get_conn_lvl_t lvl, co } /* end H5VL_pass_through_introspect_get_conn_cls() */ /*------------------------------------------------------------------------- + * Function: H5VL_pass_through_introspect_get_cap_flags + * + * Purpose: Query the capability flags for this connector and any + * underlying connector(s). + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_pass_through_introspect_get_cap_flags(const void *_info, unsigned *cap_flags) +{ + const H5VL_pass_through_info_t *info = (const H5VL_pass_through_info_t *)_info; + herr_t ret_value; + +#ifdef ENABLE_PASSTHRU_LOGGING + printf("------- PASS THROUGH VOL INTROSPECT GetCapFlags\n"); +#endif + + /* Invoke the query on the underlying VOL connector */ + ret_value = H5VLintrospect_get_cap_flags(info->under_vol_info, info->under_vol_id, cap_flags); + + /* Bitwise OR our capability flags in */ + if (ret_value >= 0) + *cap_flags |= H5VL_pass_through_g.cap_flags; + + return ret_value; +} /* end H5VL_pass_through_introspect_get_cap_flags() */ + +/*------------------------------------------------------------------------- * Function: H5VL_pass_through_introspect_opt_query * * Purpose: Query if an optional operation is supported by this connector @@ -2743,31 +2692,6 @@ H5VL_pass_through_request_cancel(void *obj, H5VL_request_status_t *status) } /* end H5VL_pass_through_request_cancel() */ /*------------------------------------------------------------------------- - * Function: H5VL_pass_through_request_specific_reissue - * - * Purpose: Re-wrap vararg arguments into a va_list and reissue the - * request specific callback to the underlying VOL connector. - * - * Return: Success: 0 - * Failure: -1 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5VL_pass_through_request_specific_reissue(void *obj, hid_t connector_id, - H5VL_request_specific_t specific_type, ...) -{ - va_list arguments; - herr_t ret_value; - - va_start(arguments, specific_type); - ret_value = H5VLrequest_specific(obj, connector_id, specific_type, arguments); - va_end(arguments); - - return ret_value; -} /* end H5VL_pass_through_request_specific_reissue() */ - -/*------------------------------------------------------------------------- * Function: H5VL_pass_through_request_specific * * Purpose: Specific operation on a request @@ -2778,139 +2702,16 @@ H5VL_pass_through_request_specific_reissue(void *obj, hid_t connector_id, *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_request_specific(void *obj, H5VL_request_specific_t specific_type, va_list arguments) +H5VL_pass_through_request_specific(void *obj, H5VL_request_specific_args_t *args) { - herr_t ret_value = -1; + H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; + herr_t ret_value = -1; #ifdef ENABLE_PASSTHRU_LOGGING printf("------- PASS THROUGH VOL REQUEST Specific\n"); #endif - if (H5VL_REQUEST_WAITANY == specific_type || H5VL_REQUEST_WAITSOME == specific_type || - H5VL_REQUEST_WAITALL == specific_type) { - va_list tmp_arguments; - size_t req_count; - - /* Sanity check */ - assert(obj == NULL); - - /* Get enough info to call the underlying connector */ - va_copy(tmp_arguments, arguments); - req_count = va_arg(tmp_arguments, size_t); - - /* Can only use a request to invoke the underlying VOL connector when there's >0 requests */ - if (req_count > 0) { - void ** req_array; - void ** under_req_array; - uint64_t timeout; - H5VL_pass_through_t *o; - size_t u; /* Local index variable */ - - /* Get the request array */ - req_array = va_arg(tmp_arguments, void **); - - /* Get a request to use for determining the underlying VOL connector */ - o = (H5VL_pass_through_t *)req_array[0]; - - /* Create array of underlying VOL requests */ - under_req_array = (void **)malloc(req_count * sizeof(void **)); - for (u = 0; u < req_count; u++) - under_req_array[u] = ((H5VL_pass_through_t *)req_array[u])->under_object; - - /* Remove the timeout value from the vararg list (it's used in all the calls below) */ - timeout = va_arg(tmp_arguments, uint64_t); - - /* Release requests that have completed */ - if (H5VL_REQUEST_WAITANY == specific_type) { - size_t * idx; /* Pointer to the index of completed request */ - H5VL_request_status_t *status; /* Pointer to the request's status */ - - /* Retrieve the remaining arguments */ - idx = va_arg(tmp_arguments, size_t *); - assert(*idx <= req_count); - status = va_arg(tmp_arguments, H5VL_request_status_t *); - - /* Reissue the WAITANY 'request specific' call */ - ret_value = H5VL_pass_through_request_specific_reissue(o->under_object, o->under_vol_id, - specific_type, req_count, - under_req_array, timeout, idx, status); - - /* Release the completed request, if it completed */ - if (ret_value >= 0 && *status != H5ES_STATUS_IN_PROGRESS) { - H5VL_pass_through_t *tmp_o; - - tmp_o = (H5VL_pass_through_t *)req_array[*idx]; - H5VL_pass_through_free_obj(tmp_o); - } /* end if */ - } /* end if */ - else if (H5VL_REQUEST_WAITSOME == specific_type) { - size_t * outcount; /* # of completed requests */ - unsigned * array_of_indices; /* Array of indices for completed requests */ - H5VL_request_status_t *array_of_statuses; /* Array of statuses for completed requests */ - - /* Retrieve the remaining arguments */ - outcount = va_arg(tmp_arguments, size_t *); - assert(*outcount <= req_count); - array_of_indices = va_arg(tmp_arguments, unsigned *); - array_of_statuses = va_arg(tmp_arguments, H5VL_request_status_t *); - - /* Reissue the WAITSOME 'request specific' call */ - ret_value = H5VL_pass_through_request_specific_reissue( - o->under_object, o->under_vol_id, specific_type, req_count, under_req_array, timeout, - outcount, array_of_indices, array_of_statuses); - - /* If any requests completed, release them */ - if (ret_value >= 0 && *outcount > 0) { - unsigned *idx_array; /* Array of indices of completed requests */ - - /* Retrieve the array of completed request indices */ - idx_array = va_arg(tmp_arguments, unsigned *); - - /* Release the completed requests */ - for (u = 0; u < *outcount; u++) { - H5VL_pass_through_t *tmp_o; - - tmp_o = (H5VL_pass_through_t *)req_array[idx_array[u]]; - H5VL_pass_through_free_obj(tmp_o); - } /* end for */ - } /* end if */ - } /* end else-if */ - else { /* H5VL_REQUEST_WAITALL == specific_type */ - H5VL_request_status_t *array_of_statuses; /* Array of statuses for completed requests */ - - /* Retrieve the remaining arguments */ - array_of_statuses = va_arg(tmp_arguments, H5VL_request_status_t *); - - /* Reissue the WAITALL 'request specific' call */ - ret_value = H5VL_pass_through_request_specific_reissue( - o->under_object, o->under_vol_id, specific_type, req_count, under_req_array, timeout, - array_of_statuses); - - /* Release the completed requests */ - if (ret_value >= 0) { - for (u = 0; u < req_count; u++) { - if (array_of_statuses[u] != H5ES_STATUS_IN_PROGRESS) { - H5VL_pass_through_t *tmp_o; - - tmp_o = (H5VL_pass_through_t *)req_array[u]; - H5VL_pass_through_free_obj(tmp_o); - } /* end if */ - } /* end for */ - } /* end if */ - } /* end else */ - - /* Release array of requests for underlying connector */ - free(under_req_array); - } /* end if */ - - /* Finish use of copied vararg list */ - va_end(tmp_arguments); - } /* end if */ - else { - H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; - - ret_value = H5VLrequest_specific(o->under_object, o->under_vol_id, specific_type, arguments); - } /* end else */ + ret_value = H5VLrequest_specific(o->under_object, o->under_vol_id, args); return ret_value; } /* end H5VL_pass_through_request_specific() */ @@ -2926,7 +2727,7 @@ H5VL_pass_through_request_specific(void *obj, H5VL_request_specific_t specific_t *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_request_optional(void *obj, H5VL_request_optional_t opt_type, va_list arguments) +H5VL_pass_through_request_optional(void *obj, H5VL_optional_args_t *args) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -2935,7 +2736,7 @@ H5VL_pass_through_request_optional(void *obj, H5VL_request_optional_t opt_type, printf("------- PASS THROUGH VOL REQUEST Optional\n"); #endif - ret_value = H5VLrequest_optional(o->under_object, o->under_vol_id, opt_type, arguments); + ret_value = H5VLrequest_optional(o->under_object, o->under_vol_id, args); return ret_value; } /* end H5VL_pass_through_request_optional() */ @@ -3027,8 +2828,7 @@ H5VL_pass_through_blob_get(void *obj, const void *blob_id, void *buf, size_t siz *------------------------------------------------------------------------- */ herr_t -H5VL_pass_through_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, - va_list arguments) +H5VL_pass_through_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_args_t *args) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -3037,7 +2837,7 @@ H5VL_pass_through_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t s printf("------- PASS THROUGH VOL BLOB Specific\n"); #endif - ret_value = H5VLblob_specific(o->under_object, o->under_vol_id, blob_id, specific_type, arguments); + ret_value = H5VLblob_specific(o->under_object, o->under_vol_id, blob_id, args); return ret_value; } /* end H5VL_pass_through_blob_specific() */ @@ -3052,7 +2852,7 @@ H5VL_pass_through_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t s *------------------------------------------------------------------------- */ herr_t -H5VL_pass_through_blob_optional(void *obj, void *blob_id, H5VL_blob_optional_t opt_type, va_list arguments) +H5VL_pass_through_blob_optional(void *obj, void *blob_id, H5VL_optional_args_t *args) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -3061,7 +2861,7 @@ H5VL_pass_through_blob_optional(void *obj, void *blob_id, H5VL_blob_optional_t o printf("------- PASS THROUGH VOL BLOB Optional\n"); #endif - ret_value = H5VLblob_optional(o->under_object, o->under_vol_id, blob_id, opt_type, arguments); + ret_value = H5VLblob_optional(o->under_object, o->under_vol_id, blob_id, args); return ret_value; } /* end H5VL_pass_through_blob_optional() */ @@ -3168,7 +2968,7 @@ H5VL_pass_through_token_from_str(void *obj, H5I_type_t obj_type, const char *tok *------------------------------------------------------------------------- */ herr_t -H5VL_pass_through_optional(void *obj, int op_type, hid_t dxpl_id, void **req, va_list arguments) +H5VL_pass_through_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -3177,7 +2977,7 @@ H5VL_pass_through_optional(void *obj, int op_type, hid_t dxpl_id, void **req, va printf("------- PASS THROUGH VOL generic Optional\n"); #endif - ret_value = H5VLoptional(o->under_object, o->under_vol_id, op_type, dxpl_id, req, arguments); + ret_value = H5VLoptional(o->under_object, o->under_vol_id, args, dxpl_id, req); return ret_value; } /* end H5VL_pass_through_optional() */ diff --git a/src/H5VLpkg.h b/src/H5VLpkg.h index 7b8a877..5a4ccc1 100644 --- a/src/H5VLpkg.h +++ b/src/H5VLpkg.h @@ -43,6 +43,7 @@ /******************************/ /* Package Private Prototypes */ /******************************/ +H5_DLL herr_t H5VL__set_def_conn(void); H5_DLL hid_t H5VL__register_connector(const void *cls, hbool_t app_ref, hid_t vipl_id); H5_DLL hid_t H5VL__register_connector_by_class(const H5VL_class_t *cls, hbool_t app_ref, hid_t vipl_id); H5_DLL hid_t H5VL__register_connector_by_name(const char *name, hbool_t app_ref, hid_t vipl_id); @@ -56,5 +57,16 @@ H5_DLL hid_t H5VL__peek_connector_id_by_name(const char *name); H5_DLL hid_t H5VL__peek_connector_id_by_value(H5VL_class_value_t value); H5_DLL herr_t H5VL__connector_str_to_info(const char *str, hid_t connector_id, void **info); H5_DLL ssize_t H5VL__get_connector_name(hid_t id, char *name /*out*/, size_t size); +H5_DLL void H5VL__is_default_conn(hid_t fapl_id, hid_t connector_id, hbool_t *is_default); +H5_DLL herr_t H5VL__register_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val); +H5_DLL size_t H5VL__num_opt_operation(void); +H5_DLL herr_t H5VL__find_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val); +H5_DLL herr_t H5VL__unregister_opt_operation(H5VL_subclass_t subcls, const char *op_name); +H5_DLL herr_t H5VL__term_opt_operation(void); + +/* Testing functions */ +#ifdef H5VL_TESTING +H5_DLL herr_t H5VL__reparse_def_vol_conn_variable_test(void); +#endif /* H5VL_TESTING */ #endif /* H5VLpkg_H */ diff --git a/src/H5VLprivate.h b/src/H5VLprivate.h index 34fb13d..f929d03 100644 --- a/src/H5VLprivate.h +++ b/src/H5VLprivate.h @@ -16,6 +16,11 @@ /* Include package's public header */ #include "H5VLpublic.h" /* Generic Functions */ +/* Include connector author public header(s) */ +#include "H5VLconnector.h" /* VOL connector author routines */ +#include "H5VLconnector_passthru.h" /* Pass-through VOL connector author routines */ +#include "H5VLnative.h" /* Native VOL connector macros, for VOL connector authors */ + /* Private headers needed by this file */ /**************************/ @@ -61,13 +66,15 @@ typedef enum H5VL_get_connector_kind_t { /******************************/ /* Utility functions */ -H5_DLL herr_t H5VL_init_phase1(void); -H5_DLL herr_t H5VL_init_phase2(void); +H5_DLL herr_t H5VL_init_phase1(void); +H5_DLL herr_t H5VL_init_phase2(void); +H5_DLL H5VL_t *H5VL_new_connector(hid_t connector_id); H5_DLL herr_t H5VL_cmp_connector_cls(int *cmp_value, const H5VL_class_t *cls1, const H5VL_class_t *cls2); H5_DLL herr_t H5VL_conn_copy(H5VL_connector_prop_t *value); H5_DLL int64_t H5VL_conn_inc_rc(H5VL_t *connector); H5_DLL int64_t H5VL_conn_dec_rc(H5VL_t *connector); H5_DLL herr_t H5VL_conn_free(const H5VL_connector_prop_t *info); +H5_DLL herr_t H5VL_get_cap_flags(const H5VL_connector_prop_t *prop, unsigned *cap_flags); /* Functions that deal with VOL connectors */ union H5PL_key_t; @@ -109,8 +116,9 @@ H5_DLL herr_t H5VL_reset_vol_wrapper(void); /* Library state functions */ H5_DLL herr_t H5VL_retrieve_lib_state(void **state); +H5_DLL herr_t H5VL_start_lib_state(void); H5_DLL herr_t H5VL_restore_lib_state(const void *state); -H5_DLL herr_t H5VL_reset_lib_state(void); +H5_DLL herr_t H5VL_finish_lib_state(void); H5_DLL herr_t H5VL_free_lib_state(void *state); /* ID registration functions */ @@ -127,12 +135,11 @@ H5_DLL herr_t H5VL_setup_loc_args(hid_t loc_id, H5VL_object_t **vol_obj, H5VL_lo H5_DLL herr_t H5VL_setup_acc_args(hid_t loc_id, const struct H5P_libclass_t *libclass, hbool_t is_collective, hid_t *acspl_id, H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params); H5_DLL herr_t H5VL_setup_self_args(hid_t loc_id, H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params); -H5_DLL herr_t H5VL_setup_name_args(hid_t loc_id, const char *name, const struct H5P_libclass_t *libclass, - hbool_t is_collective, hid_t acspl_id, H5VL_object_t **vol_obj, - H5VL_loc_params_t *loc_params); +H5_DLL herr_t H5VL_setup_name_args(hid_t loc_id, const char *name, hbool_t is_collective, hid_t lapl_id, + H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params); H5_DLL herr_t H5VL_setup_idx_args(hid_t loc_id, const char *name, H5_index_t idx_type, H5_iter_order_t order, - hsize_t n, const struct H5P_libclass_t *libclass, hbool_t is_collective, - hid_t acspl_id, H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params); + hsize_t n, hbool_t is_collective, hid_t lapl_id, H5VL_object_t **vol_obj, + H5VL_loc_params_t *loc_params); H5_DLL herr_t H5VL_setup_token_args(hid_t loc_id, H5O_token_t *obj_token, H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params); @@ -156,12 +163,12 @@ H5_DLL herr_t H5VL_attr_read(const H5VL_object_t *vol_obj, hid_t dtype_id, void void **req); H5_DLL herr_t H5VL_attr_write(const H5VL_object_t *vol_obj, hid_t dtype_id, const void *buf, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VL_attr_get(const H5VL_object_t *vol_obj, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, - ...); +H5_DLL herr_t H5VL_attr_get(const H5VL_object_t *vol_obj, H5VL_attr_get_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VL_attr_specific(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, - H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req, ...); -H5_DLL herr_t H5VL_attr_optional(const H5VL_object_t *vol_obj, H5VL_attr_optional_t opt_type, hid_t dxpl_id, - void **req, ...); + H5VL_attr_specific_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL_attr_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VL_attr_close(const H5VL_object_t *vol_obj, hid_t dxpl_id, void **req); /* Dataset functions */ @@ -174,12 +181,12 @@ H5_DLL herr_t H5VL_dataset_read(const H5VL_object_t *vol_obj, hid_t mem_type_id, hid_t file_space_id, hid_t dxpl_id, void *buf, void **req); H5_DLL herr_t H5VL_dataset_write(const H5VL_object_t *vol_obj, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, const void *buf, void **req); -H5_DLL herr_t H5VL_dataset_get(const H5VL_object_t *vol_obj, H5VL_dataset_get_t get_type, hid_t dxpl_id, - void **req, ...); -H5_DLL herr_t H5VL_dataset_specific(const H5VL_object_t *cls, H5VL_dataset_specific_t specific_type, - hid_t dxpl_id, void **req, ...); -H5_DLL herr_t H5VL_dataset_optional(const H5VL_object_t *vol_obj, H5VL_dataset_optional_t opt_type, - hid_t dxpl_id, void **req, ...); +H5_DLL herr_t H5VL_dataset_get(const H5VL_object_t *vol_obj, H5VL_dataset_get_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VL_dataset_specific(const H5VL_object_t *cls, H5VL_dataset_specific_args_t *args, + hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL_dataset_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VL_dataset_close(const H5VL_object_t *vol_obj, hid_t dxpl_id, void **req); /* Datatype functions */ @@ -188,12 +195,14 @@ H5_DLL void * H5VL_datatype_commit(const H5VL_object_t *vol_obj, const H5VL_loc_ hid_t tapl_id, hid_t dxpl_id, void **req); H5_DLL void * H5VL_datatype_open(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t tapl_id, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VL_datatype_get(const H5VL_object_t *vol_obj, H5VL_datatype_get_t get_type, hid_t dxpl_id, - void **req, ...); -H5_DLL herr_t H5VL_datatype_specific(const H5VL_object_t *vol_obj, H5VL_datatype_specific_t specific_type, - hid_t dxpl_id, void **req, ...); -H5_DLL herr_t H5VL_datatype_optional(const H5VL_object_t *vol_obj, H5VL_datatype_optional_t opt_type, - hid_t dxpl_id, void **req, ...); +H5_DLL herr_t H5VL_datatype_get(const H5VL_object_t *vol_obj, H5VL_datatype_get_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VL_datatype_specific(const H5VL_object_t *vol_obj, H5VL_datatype_specific_args_t *args, + hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL_datatype_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VL_datatype_optional_op(H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req, H5VL_object_t **vol_obj_ptr); H5_DLL herr_t H5VL_datatype_close(const H5VL_object_t *vol_obj, hid_t dxpl_id, void **req); /* File functions */ @@ -201,12 +210,12 @@ H5_DLL void * H5VL_file_create(const H5VL_connector_prop_t *connector_prop, cons hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id, void **req); H5_DLL void * H5VL_file_open(H5VL_connector_prop_t *connector_prop, const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VL_file_get(const H5VL_object_t *vol_obj, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, - ...); -H5_DLL herr_t H5VL_file_specific(const H5VL_object_t *vol_obj, H5VL_file_specific_t specific_type, - hid_t dxpl_id, void **req, ...); -H5_DLL herr_t H5VL_file_optional(const H5VL_object_t *vol_obj, H5VL_file_optional_t opt_type, hid_t dxpl_id, - void **req, ...); +H5_DLL herr_t H5VL_file_get(const H5VL_object_t *vol_obj, H5VL_file_get_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VL_file_specific(const H5VL_object_t *vol_obj, H5VL_file_specific_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VL_file_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VL_file_close(const H5VL_object_t *vol_obj, hid_t dxpl_id, void **req); /* Group functions */ @@ -215,18 +224,18 @@ H5_DLL void * H5VL_group_create(const H5VL_object_t *vol_obj, const H5VL_loc_par void **req); H5_DLL void * H5VL_group_open(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t gapl_id, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VL_group_get(const H5VL_object_t *vol_obj, H5VL_group_get_t get_type, hid_t dxpl_id, - void **req, ...); -H5_DLL herr_t H5VL_group_specific(const H5VL_object_t *vol_obj, H5VL_group_specific_t specific_type, - hid_t dxpl_id, void **req, ...); -H5_DLL herr_t H5VL_group_optional(const H5VL_object_t *vol_obj, H5VL_group_optional_t opt_type, hid_t dxpl_id, - void **req, ...); +H5_DLL herr_t H5VL_group_get(const H5VL_object_t *vol_obj, H5VL_group_get_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VL_group_specific(const H5VL_object_t *vol_obj, H5VL_group_specific_args_t *args, + hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL_group_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VL_group_close(const H5VL_object_t *vol_obj, hid_t dxpl_id, void **req); /* Link functions */ -H5_DLL herr_t H5VL_link_create(H5VL_link_create_type_t create_type, const H5VL_object_t *vol_obj, +H5_DLL herr_t H5VL_link_create(H5VL_link_create_args_t *args, const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t lapl_id, - hid_t dxpl_id, void **req, ...); + hid_t dxpl_id, void **req); H5_DLL herr_t H5VL_link_copy(const H5VL_object_t *src_vol_obj, const H5VL_loc_params_t *loc_params1, const H5VL_object_t *dst_vol_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); @@ -234,11 +243,11 @@ H5_DLL herr_t H5VL_link_move(const H5VL_object_t *src_vol_obj, const H5VL_loc_pa const H5VL_object_t *dst_vol_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL_link_get(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, - H5VL_link_get_t get_type, hid_t dxpl_id, void **req, ...); + H5VL_link_get_args_t *args, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL_link_specific(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, - H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req, ...); -H5_DLL herr_t H5VL_link_optional(const H5VL_object_t *vol_obj, H5VL_link_optional_t opt_type, hid_t dxpl_id, - void **req, ...); + H5VL_link_specific_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL_link_optional(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req); /* Object functions */ H5_DLL void * H5VL_object_open(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *params, @@ -248,15 +257,16 @@ H5_DLL herr_t H5VL_object_copy(const H5VL_object_t *src_obj, const H5VL_loc_para const H5VL_loc_params_t *dst_loc_params, const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL_object_get(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, - H5VL_object_get_t get_type, hid_t dxpl_id, void **req, ...); + H5VL_object_get_args_t *args, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL_object_specific(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, - H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req, ...); -H5_DLL herr_t H5VL_object_optional(const H5VL_object_t *vol_obj, H5VL_object_optional_t opt_type, - hid_t dxpl_id, void **req, ...); + H5VL_object_specific_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL_object_optional(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req); /* Connector/container introspection functions */ H5_DLL herr_t H5VL_introspect_get_conn_cls(const H5VL_object_t *vol_obj, H5VL_get_conn_lvl_t lvl, const H5VL_class_t **conn_cls); +H5_DLL herr_t H5VL_introspect_get_cap_flags(const void *info, const H5VL_class_t *cls, unsigned *cap_flags); H5_DLL herr_t H5VL_introspect_opt_query(const H5VL_object_t *vol_obj, H5VL_subclass_t subcls, int opt_type, uint64_t *flags); @@ -265,8 +275,8 @@ H5_DLL herr_t H5VL_request_wait(const H5VL_object_t *vol_obj, uint64_t timeout, H5VL_request_status_t *status); H5_DLL herr_t H5VL_request_notify(const H5VL_object_t *vol_obj, H5VL_request_notify_t cb, void *ctx); H5_DLL herr_t H5VL_request_cancel(const H5VL_object_t *vol_obj, H5VL_request_status_t *status); -H5_DLL herr_t H5VL_request_specific(const H5VL_object_t *vol_obj, H5VL_request_specific_t specific_type, ...); -H5_DLL herr_t H5VL_request_optional(const H5VL_object_t *vol_obj, H5VL_request_optional_t opt_type, ...); +H5_DLL herr_t H5VL_request_specific(const H5VL_object_t *vol_obj, H5VL_request_specific_args_t *args); +H5_DLL herr_t H5VL_request_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args); H5_DLL herr_t H5VL_request_free(const H5VL_object_t *vol_obj); /* Blob functions */ @@ -275,9 +285,8 @@ H5_DLL herr_t H5VL_blob_put(const H5VL_object_t *vol_obj, const void *buf, size_ H5_DLL herr_t H5VL_blob_get(const H5VL_object_t *vol_obj, const void *blob_id, void *buf, size_t size, void *ctx); H5_DLL herr_t H5VL_blob_specific(const H5VL_object_t *vol_obj, void *blob_id, - H5VL_blob_specific_t specific_type, ...); -H5_DLL herr_t H5VL_blob_optional(const H5VL_object_t *vol_obj, void *blob_id, H5VL_blob_optional_t opt_type, - ...); + H5VL_blob_specific_args_t *args); +H5_DLL herr_t H5VL_blob_optional(const H5VL_object_t *vol_obj, void *blob_id, H5VL_optional_args_t *args); /* Token functions */ H5_DLL herr_t H5VL_token_cmp(const H5VL_object_t *vol_obj, const H5O_token_t *token1, @@ -288,6 +297,7 @@ H5_DLL herr_t H5VL_token_from_str(const H5VL_object_t *vol_obj, H5I_type_t obj_t H5O_token_t *token); /* Generic functions */ -H5_DLL herr_t H5VL_optional(const H5VL_object_t *vol_obj, int op_type, hid_t dxpl_id, void **req, ...); +H5_DLL herr_t H5VL_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); #endif /* H5VLprivate_H */ diff --git a/src/H5VLpublic.h b/src/H5VLpublic.h index c5f85dc..78e39e3 100644 --- a/src/H5VLpublic.h +++ b/src/H5VLpublic.h @@ -116,6 +116,9 @@ typedef enum H5VL_subclass_t { H5VL_SUBCLS_REQUEST, /**< 'Request' subclass */ H5VL_SUBCLS_BLOB, /**< 'Blob' subclass */ H5VL_SUBCLS_TOKEN /**< 'Token' subclass */ + /* NOTE: if more operations are added, the + * H5VL_opt_vals_g[] array size should be updated. + */ } H5VL_subclass_t; /********************/ @@ -358,9 +361,4 @@ H5_DLL herr_t H5VLquery_optional(hid_t obj_id, H5VL_subclass_t subcls, int opt_t } #endif -/* Semi-public headers mainly for VOL connector authors */ -#include "H5VLconnector.h" /* VOL connector author routines */ -#include "H5VLconnector_passthru.h" /* Pass-through VOL connector author routines */ -#include "H5VLnative.h" /* Native VOL connector macros, for VOL connector authors */ - #endif /* H5VLpublic_H */ diff --git a/src/H5VLtest.c b/src/H5VLtest.c new file mode 100644 index 0000000..1f99ce5 --- /dev/null +++ b/src/H5VLtest.c @@ -0,0 +1,96 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5VLtest.c + * Jan 3 2021 + * Quincey Koziol + * + * Purpose: Virtual Object Layer (VOL) testing routines. + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#include "H5VLmodule.h" /* This source code file is part of the H5VL module */ +#define H5VL_TESTING /* Suppress warning about H5VL testing funcs */ + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5VLpkg.h" /* Virtual Object Layer */ + +/****************/ +/* Local Macros */ +/****************/ + +/******************/ +/* Local Typedefs */ +/******************/ + +/********************/ +/* Package Typedefs */ +/********************/ + +/********************/ +/* Local Prototypes */ +/********************/ + +/*********************/ +/* Package Variables */ +/*********************/ + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + +/*******************/ +/* Local Variables */ +/*******************/ + +/*------------------------------------------------------------------------- + * Function: H5VL__reparse_def_vol_conn_variable_test + * + * Purpose: Re-parse the default VOL connector environment variable. + * + * Since getenv(3) is fairly expensive, we only parse it once, + * when the library opens. This test function is used to + * re-parse the environment variable after we've changed it + * with setenv(3). + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * Feb 3, 2021 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL__reparse_def_vol_conn_variable_test(void) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + /* Re-check for the HDF5_VOL_CONNECTOR environment variable */ + if (H5VL__set_def_conn() < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize default VOL connector") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__reparse_def_vol_conn_variable_test() */ diff --git a/src/H5Zmodule.h b/src/H5Zmodule.h index 76a2380..9312b72 100644 --- a/src/H5Zmodule.h +++ b/src/H5Zmodule.h @@ -29,57 +29,80 @@ #define H5_MY_PKG_ERR H5E_PLINE #define H5_MY_PKG_INIT YES -/** - * \defgroup H5Z H5Z +/**\defgroup H5Z H5Z * + * Use the functions in this module to manage HDF5 filters. * - * \brief Filter and Compression Interface + * User-defined filters are created by registering a filter descriptor of + * type #H5Z_class_t with the library. * - * \details The functions in this module let you configure filters that process - * data during I/O operation. + * Available filters can be read or examined at runtime. * - * HDF5 supports a filter pipeline that provides the capability for - * standard and customized raw data processing during I/O operations. - * HDF5 is distributed with a small set of standard filters such as - * compression (gzip, SZIP, and a shuffling algorithm) and error - * checking (Fletcher32 checksum). For further flexibility, the - * library allows a user application to extend the pipeline through - * the creation and registration of customized filters. + * It is conceivable that filters are stateful and that that state be + * updated at runtime. * - * The flexibility of the filter pipeline implementation enables the - * definition of additional filters by a user application. A filter - * \li is associated with a dataset when the dataset is created, - * \li can be used only with chunked data (i.e., datasets stored in - * the #H5D_CHUNKED storage layout), and - * \li is applied independently to each chunk of the dataset. + * Filters are deleted by unregistering. * - * The HDF5 library does not support filters for contiguous datasets - * because of the difficulty of implementing random access for partial - * I/O. Compact dataset filters are not supported because it would not - * produce significant results. + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5Z_examples.c filter + * \snippet{lineno} H5Z_examples.c create + * </td> + * <td> + * \snippet{lineno} H5Z_examples.c read + * </td> + * </tr> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5Z_examples.c update + * </td> + * <td> + * \snippet{lineno} H5Z_examples.c delete + * </tr> + * </table> * - * Filter identifiers for the filters distributed with the HDF5 - * Library are as follows: - * <table> - * <tr><td>#H5Z_FILTER_DEFLATE</td><td>The gzip compression, or - * deflation, filter</td></tr> - * <tr><td>#H5Z_FILTER_SZIP</td><td>The SZIP compression - * filter</td></tr> - * <tr><td>#H5Z_FILTER_NBIT</td><td>The N-bit compression - * filter</td></tr> - * <tr><td>#H5Z_FILTER_SCALEOFFSET</td><td>The scale-offset - * compression filter</td></tr> - * <tr><td>#H5Z_FILTER_SHUFFLE</td><td>The shuffle algorithm - * filter</td></tr> - * <tr><td>#H5Z_FILTER_FLETCHER32</td><td>The Fletcher32 checksum, - * or error checking, filter</td></tr> - * </table> - * Custom filters that have been registered with the library will have - * additional unique identifiers. + * HDF5 supports a filter pipeline that provides the capability for standard and + * customized raw data processing during I/O operations. HDF5 is distributed + * with a small set of standard filters such as compression (gzip, SZIP, and a + * shuffling algorithm) and error checking (Fletcher32 checksum). For further + * flexibility, the library allows a user application to extend the pipeline + * through the creation and registration of customized filters. * - * See \ref_dld_filters for more information on how an HDF5 - * application can apply a filter that is not registered with the HDF5 - * library. + * The flexibility of the filter pipeline implementation enables the definition + * of additional filters by a user application. A filter + * \li is associated with a dataset when the dataset is created, + * \li can be used only with chunked data (i.e., datasets stored in the + * #H5D_CHUNKED storage layout), and + * \li is applied independently to each chunk of the dataset. + * + * The HDF5 library does not support filters for contiguous datasets because of + * the difficulty of implementing random access for partial I/O. Compact dataset + * filters are not supported because it would not produce significant results. + * + * Filter identifiers for the filters distributed with the HDF5 + * Library are as follows: + * <table> + * <tr><td>#H5Z_FILTER_DEFLATE</td><td>The gzip compression, or + * deflation, filter</td></tr> + * <tr><td>#H5Z_FILTER_SZIP</td><td>The SZIP compression + * filter</td></tr> + * <tr><td>#H5Z_FILTER_NBIT</td><td>The N-bit compression + * filter</td></tr> + * <tr><td>#H5Z_FILTER_SCALEOFFSET</td><td>The scale-offset + * compression filter</td></tr> + * <tr><td>#H5Z_FILTER_SHUFFLE</td><td>The shuffle algorithm + * filter</td></tr> + * <tr><td>#H5Z_FILTER_FLETCHER32</td><td>The Fletcher32 checksum, + * or error checking, filter</td></tr> + * </table> + * Custom filters that have been registered with the library will have + * additional unique identifiers. + * + * See \ref_dld_filters for more information on how an HDF5 application can + * apply a filter that is not registered with the HDF5 library. * * \defgroup H5ZPRE Predefined Filters * \ingroup H5Z diff --git a/src/H5Zscaleoffset.c b/src/H5Zscaleoffset.c index 2e1a474..a8a63bf 100644 --- a/src/H5Zscaleoffset.c +++ b/src/H5Zscaleoffset.c @@ -425,22 +425,22 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ #define H5Z_scaleoffset_check_3(i, type, pow_fun, round_fun, max, min, minbits, D_val) \ { \ if (sizeof(type) == sizeof(int)) { \ - if (round_fun(max * pow_fun(10.0f, (type)D_val) - min * pow_fun(10.0f, (type)D_val)) > \ - pow_fun(2.0f, (type)(sizeof(int) * 8 - 1))) { \ + if (round_fun(max * pow_fun(10.0F, (type)D_val) - min * pow_fun(10.0F, (type)D_val)) > \ + pow_fun(2.0F, (type)(sizeof(int) * 8 - 1))) { \ *minbits = sizeof(int) * 8; \ goto done; \ } \ } \ else if (sizeof(type) == sizeof(long)) { \ - if (round_fun(max * pow_fun(10.0f, (type)D_val) - min * pow_fun(10.0f, (type)D_val)) > \ - pow_fun(2.0f, (type)(sizeof(long) * 8 - 1))) { \ + if (round_fun(max * pow_fun(10.0F, (type)D_val) - min * pow_fun(10.0F, (type)D_val)) > \ + pow_fun(2.0F, (type)(sizeof(long) * 8 - 1))) { \ *minbits = sizeof(long) * 8; \ goto done; \ } \ } \ else if (sizeof(type) == sizeof(long long)) { \ - if (round_fun(max * pow_fun(10.0f, (type)D_val) - min * pow_fun(10.0f, (type)D_val)) > \ - pow_fun(2.0f, (type)(sizeof(long long) * 8 - 1))) { \ + if (round_fun(max * pow_fun(10.0F, (type)D_val) - min * pow_fun(10.0F, (type)D_val)) > \ + pow_fun(2.0F, (type)(sizeof(long long) * 8 - 1))) { \ *minbits = sizeof(long long) * 8; \ goto done; \ } \ @@ -530,27 +530,27 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ { \ if (sizeof(type) == sizeof(int)) \ for (i = 0; i < d_nelmts; i++) { \ - if (abs_fun(buf[i] - filval) < pow_fun(10.0f, (type)-D_val)) \ + if (abs_fun(buf[i] - filval) < pow_fun(10.0F, (type)-D_val)) \ *(int *)((void *)&buf[i]) = (int)(((unsigned int)1 << *minbits) - 1); \ else \ - *(int *)((void *)&buf[i]) = (int)lround_fun(buf[i] * pow_fun(10.0f, (type)D_val) - \ - min * pow_fun(10.0f, (type)D_val)); \ + *(int *)((void *)&buf[i]) = (int)lround_fun(buf[i] * pow_fun(10.0F, (type)D_val) - \ + min * pow_fun(10.0F, (type)D_val)); \ } \ else if (sizeof(type) == sizeof(long)) \ for (i = 0; i < d_nelmts; i++) { \ - if (abs_fun(buf[i] - filval) < pow_fun(10.0f, (type)-D_val)) \ + if (abs_fun(buf[i] - filval) < pow_fun(10.0F, (type)-D_val)) \ *(long *)((void *)&buf[i]) = (long)(((unsigned long)1 << *minbits) - 1); \ else \ - *(long *)((void *)&buf[i]) = lround_fun(buf[i] * pow_fun(10.0f, (type)D_val) - \ - min * pow_fun(10.0f, (type)D_val)); \ + *(long *)((void *)&buf[i]) = lround_fun(buf[i] * pow_fun(10.0F, (type)D_val) - \ + min * pow_fun(10.0F, (type)D_val)); \ } \ else if (sizeof(type) == sizeof(long long)) \ for (i = 0; i < d_nelmts; i++) { \ - if (abs_fun(buf[i] - filval) < pow_fun(10.0f, (type)-D_val)) \ + if (abs_fun(buf[i] - filval) < pow_fun(10.0F, (type)-D_val)) \ *(long long *)((void *)&buf[i]) = (long long)(((unsigned long long)1 << *minbits) - 1); \ else \ - *(long long *)((void *)&buf[i]) = llround_fun(buf[i] * pow_fun(10.0f, (type)D_val) - \ - min * pow_fun(10.0f, (type)D_val)); \ + *(long long *)((void *)&buf[i]) = llround_fun(buf[i] * pow_fun(10.0F, (type)D_val) - \ + min * pow_fun(10.0F, (type)D_val)); \ } \ else \ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype") \ @@ -561,16 +561,16 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ { \ if (sizeof(type) == sizeof(int)) \ for (i = 0; i < d_nelmts; i++) \ - *(int *)((void *)&buf[i]) = (int)lround_fun(buf[i] * pow_fun(10.0f, (type)D_val) - \ - min * pow_fun(10.0f, (type)D_val)); \ + *(int *)((void *)&buf[i]) = (int)lround_fun(buf[i] * pow_fun(10.0F, (type)D_val) - \ + min * pow_fun(10.0F, (type)D_val)); \ else if (sizeof(type) == sizeof(long)) \ for (i = 0; i < d_nelmts; i++) \ *(long *)((void *)&buf[i]) = \ - lround_fun(buf[i] * pow_fun(10.0f, (type)D_val) - min * pow_fun(10.0f, (type)D_val)); \ + lround_fun(buf[i] * pow_fun(10.0F, (type)D_val) - min * pow_fun(10.0F, (type)D_val)); \ else if (sizeof(type) == sizeof(long long)) \ for (i = 0; i < d_nelmts; i++) \ *(long long *)((void *)&buf[i]) = \ - llround_fun(buf[i] * pow_fun(10.0f, (type)D_val) - min * pow_fun(10.0f, (type)D_val)); \ + llround_fun(buf[i] * pow_fun(10.0F, (type)D_val) - min * pow_fun(10.0F, (type)D_val)); \ else \ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype") \ } @@ -606,8 +606,8 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ H5Z_scaleoffset_get_filval_2(type, cd_values, filval) \ H5Z_scaleoffset_max_min_3(i, d_nelmts, buf, filval, max, min, D_val) \ H5Z_scaleoffset_check_3(i, type, pow_fun, round_fun, max, min, minbits, D_val) span = \ - (unsigned long long)(llround_fun(max * pow_fun(10.0f, (type)D_val) - \ - min * pow_fun(10.0f, (type)D_val)) + \ + (unsigned long long)(llround_fun(max * pow_fun(10.0F, (type)D_val) - \ + min * pow_fun(10.0F, (type)D_val)) + \ 1); \ *minbits = H5Z__scaleoffset_log2(span + 1); \ if (*minbits != sizeof(type) * 8) /* change values if minbits != full precision */ \ @@ -617,8 +617,8 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ else { /* fill value undefined */ \ H5Z_scaleoffset_max_min_2(i, d_nelmts, buf, max, min) \ H5Z_scaleoffset_check_3(i, type, pow_fun, round_fun, max, min, minbits, D_val) span = \ - (unsigned long long)(llround_fun(max * pow_fun(10.0f, (type)D_val) - \ - min * pow_fun(10.0f, (type)D_val)) + \ + (unsigned long long)(llround_fun(max * pow_fun(10.0F, (type)D_val) - \ + min * pow_fun(10.0F, (type)D_val)) + \ 1); \ *minbits = H5Z__scaleoffset_log2(span); \ if (*minbits != sizeof(type) * 8) /* change values if minbits != full precision */ \ @@ -685,19 +685,19 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ buf[i] = \ (type)((*(int *)((void *)&buf[i]) == (int)(((unsigned int)1 << minbits) - 1)) \ ? filval \ - : (type)(*(int *)((void *)&buf[i])) / pow_fun(10.0f, (type)D_val) + min); \ + : (type)(*(int *)((void *)&buf[i])) / pow_fun(10.0F, (type)D_val) + min); \ else if (sizeof(type) == sizeof(long)) \ for (i = 0; i < d_nelmts; i++) \ buf[i] = \ (type)((*(long *)((void *)&buf[i]) == (long)(((unsigned long)1 << minbits) - 1)) \ ? filval \ - : (type)(*(long *)((void *)&buf[i])) / pow_fun(10.0f, (type)D_val) + min); \ + : (type)(*(long *)((void *)&buf[i])) / pow_fun(10.0F, (type)D_val) + min); \ else if (sizeof(type) == sizeof(long long)) \ for (i = 0; i < d_nelmts; i++) \ buf[i] = (type)( \ (*(long long *)((void *)&buf[i]) == (long long)(((unsigned long long)1 << minbits) - 1)) \ ? filval \ - : (type)(*(long long *)((void *)&buf[i])) / pow_fun(10.0f, (type)D_val) + min); \ + : (type)(*(long long *)((void *)&buf[i])) / pow_fun(10.0F, (type)D_val) + min); \ else \ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype") \ } @@ -707,13 +707,13 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ { \ if (sizeof(type) == sizeof(int)) \ for (i = 0; i < d_nelmts; i++) \ - buf[i] = ((type)(*(int *)((void *)&buf[i])) / pow_fun(10.0f, (type)D_val) + min); \ + buf[i] = ((type)(*(int *)((void *)&buf[i])) / pow_fun(10.0F, (type)D_val) + min); \ else if (sizeof(type) == sizeof(long)) \ for (i = 0; i < d_nelmts; i++) \ - buf[i] = ((type)(*(long *)((void *)&buf[i])) / pow_fun(10.0f, (type)D_val) + min); \ + buf[i] = ((type)(*(long *)((void *)&buf[i])) / pow_fun(10.0F, (type)D_val) + min); \ else if (sizeof(type) == sizeof(long long)) \ for (i = 0; i < d_nelmts; i++) \ - buf[i] = ((type)(*(long long *)((void *)&buf[i])) / pow_fun(10.0f, (type)D_val) + min); \ + buf[i] = ((type)(*(long long *)((void *)&buf[i])) / pow_fun(10.0F, (type)D_val) + min); \ else \ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype") \ } diff --git a/src/H5Ztrans.c b/src/H5Ztrans.c index 7d55efd..ab7e9be 100644 --- a/src/H5Ztrans.c +++ b/src/H5Ztrans.c @@ -1547,11 +1547,11 @@ H5Z_xform_create(const char *expr) (HDisdigit(expr[i - 1]) || (expr[i - 1] == '.')) && (HDisdigit(expr[i + 1]) || (expr[i + 1] == '-') || (expr[i + 1] == '+'))) continue; - } + } /* end if */ count++; - } - } + } /* end if */ + } /* end for */ /* When there are no "x"'s in the equation (ie, simple transform case), * we don't need to allocate any space since no array will have to be @@ -1749,11 +1749,19 @@ done: hbool_t H5Z_xform_noop(const H5Z_data_xform_t *data_xform_prop) { - hbool_t ret_value = FALSE; /* Return value */ + hbool_t ret_value = TRUE; /* Return value */ FUNC_ENTER_NOAPI_NOINIT_NOERR - ret_value = (data_xform_prop ? FALSE : TRUE); + if (data_xform_prop) { + ret_value = FALSE; + + /* Check for trivial data tranformation: expression = "x" */ + if ((HDstrlen(data_xform_prop->xform_exp) == 1) && data_xform_prop->dat_val_pointers && + (data_xform_prop->dat_val_pointers->num_ptrs == 1)) { + ret_value = TRUE; + } /* end if */ + } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* H5Z_xform_noop() */ diff --git a/src/H5detect.c b/src/H5detect.c index 2e893cf..e8cded7 100644 --- a/src/H5detect.c +++ b/src/H5detect.c @@ -52,7 +52,7 @@ static const char *FileHeader = "\n\ /* Disable warning about cast increasing the alignment of the target type, * that's _exactly_ what this code is probing. -QAK */ -H5_GCC_DIAG_OFF("cast-align") +H5_GCC_CLANG_DIAG_OFF("cast-align") #if defined(__has_attribute) #if __has_attribute(no_sanitize_address) @@ -300,10 +300,10 @@ precision(detected_t *d) for (_byte_mask = (unsigned char)1; _byte_mask; _byte_mask = (unsigned char)(_byte_mask << 1)) { \ _buf1[_i] ^= _byte_mask; \ HDmemcpy((void *)&_v2, (const void *)_buf1, sizeof(TYPE)); \ - H5_GCC_DIAG_OFF("float-equal") \ + H5_GCC_CLANG_DIAG_OFF("float-equal") \ if (_v1 != _v2) \ _pad_mask[_i] |= _byte_mask; \ - H5_GCC_DIAG_ON("float-equal") \ + H5_GCC_CLANG_DIAG_ON("float-equal") \ _buf1[_i] ^= _byte_mask; \ } /* end for */ \ \ @@ -414,10 +414,10 @@ precision(detected_t *d) HDmemcpy(_buf + align_g[_ano] + (INFO.offset / 8), ((char *)&_val) + (INFO.offset / 8), \ (size_t)(INFO.precision / 8)); \ _val2 = *((TYPE *)(_buf + align_g[_ano])); \ - H5_GCC_DIAG_OFF("float-equal") \ + H5_GCC_CLANG_DIAG_OFF("float-equal") \ if (_val != _val2) \ H5LONGJMP(jbuf_g, 1); \ - H5_GCC_DIAG_ON("float-equal") \ + H5_GCC_CLANG_DIAG_ON("float-equal") \ /* End Cray Check */ \ (INFO.align) = align_g[_ano]; \ } \ @@ -1567,4 +1567,4 @@ main(int argc, char *argv[]) return EXIT_SUCCESS; } -H5_GCC_DIAG_ON("cast-align") +H5_GCC_CLANG_DIAG_ON("cast-align") diff --git a/src/H5module.h b/src/H5module.h index 64081bf..6d3cba8 100644 --- a/src/H5module.h +++ b/src/H5module.h @@ -27,8 +27,31 @@ #define H5_MY_PKG_INIT YES /**\defgroup H5 H5 - * \brief General Library Functions - * \todo Describe concisely what the functions in this module are about. + * + * Use the functions in this module to manage the life cycle of HDF5 library + * instances. + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5_examples.c create + * </td> + * <td> + * \snippet{lineno} H5_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5_examples.c update + * </td> + * <td> + * \snippet{lineno} H5_examples.c closing_shop + * \snippet{lineno} H5_examples.c delete + * </td> + * </tr> + * </table> + * */ #endif /* H5module_H */ diff --git a/src/H5mpi.c b/src/H5mpi.c index 9749721..4a8aa44 100644 --- a/src/H5mpi.c +++ b/src/H5mpi.c @@ -523,7 +523,7 @@ H5_mpio_create_large_type(hsize_t num_elements, MPI_Aint stride_bytes, MPI_Datat MPI_Type_get_extent(old_type, &unused_lb_arg, &old_extent); } - /* Set up the arguments for MPI_Type_struct constructor */ + /* Set up the arguments for MPI_Type_create_struct() */ type[0] = outer_type; type[1] = leftover_type; block_len[0] = 1; diff --git a/src/H5private.h b/src/H5private.h index bb416ef..7c76483 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -44,7 +44,9 @@ #include <sys/time.h> #endif #ifdef H5_HAVE_UNISTD_H +#ifdef H5_HAVE_PWD_H #include <pwd.h> +#endif #include <unistd.h> #include <sys/wait.h> #endif @@ -456,7 +458,7 @@ #define LOCK_UN 0x08 #endif /* H5_HAVE_FLOCK */ -/* Macros for enabling/disabling particular GCC warnings +/* Macros for enabling/disabling particular GCC / clang warnings * * These are duplicated in H5FDmulti.c (we don't want to put them in the * public header and the multi VFD can't use private headers). If you make @@ -466,19 +468,45 @@ * http://www.dbp-consulting.com/tutorials/SuppressingGCCWarnings.html * http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragmas */ -/* These pragmas are only implemented usefully in gcc 4.6+ */ -#if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406 -#define H5_GCC_DIAG_JOINSTR(x, y) x y -#define H5_GCC_DIAG_DO_PRAGMA(x) _Pragma(#x) -#define H5_GCC_DIAG_PRAGMA(x) H5_GCC_DIAG_DO_PRAGMA(GCC diagnostic x) - -#define H5_GCC_DIAG_OFF(x) H5_GCC_DIAG_PRAGMA(push) H5_GCC_DIAG_PRAGMA(ignored H5_GCC_DIAG_JOINSTR("-W", x)) -#define H5_GCC_DIAG_ON(x) H5_GCC_DIAG_PRAGMA(pop) +#define H5_DIAG_JOINSTR(x, y) x y +#define H5_DIAG_DO_PRAGMA(x) _Pragma(#x) +#define H5_DIAG_PRAGMA(x) H5_DIAG_DO_PRAGMA(GCC diagnostic x) + +#define H5_DIAG_OFF(x) H5_DIAG_PRAGMA(push) H5_DIAG_PRAGMA(ignored H5_DIAG_JOINSTR("-W", x)) +#define H5_DIAG_ON(x) H5_DIAG_PRAGMA(pop) + +/* Macros for enabling/disabling particular GCC-only warnings. + * These pragmas are only implemented usefully in gcc 4.6+ + */ +#if (((__GNUC__ * 100) + __GNUC_MINOR__) >= 406) +#define H5_GCC_DIAG_OFF(x) H5_DIAG_OFF(x) +#define H5_GCC_DIAG_ON(x) H5_DIAG_ON(x) #else #define H5_GCC_DIAG_OFF(x) #define H5_GCC_DIAG_ON(x) #endif +/* Macros for enabling/disabling particular clang-only warnings. + */ +#if defined(__clang__) +#define H5_CLANG_DIAG_OFF(x) H5_DIAG_OFF(x) +#define H5_CLANG_DIAG_ON(x) H5_DIAG_ON(x) +#else +#define H5_CLANG_DIAG_OFF(x) +#define H5_CLANG_DIAG_ON(x) +#endif + +/* Macros for enabling/disabling particular GCC / clang warnings. + * These macros should be used for warnings supported by both gcc and clang. + */ +#if (((__GNUC__ * 100) + __GNUC_MINOR__) >= 406) || defined(__clang__) +#define H5_GCC_CLANG_DIAG_OFF(x) H5_DIAG_OFF(x) +#define H5_GCC_CLANG_DIAG_ON(x) H5_DIAG_ON(x) +#else +#define H5_GCC_CLANG_DIAG_OFF(x) +#define H5_GCC_CLANG_DIAG_ON(x) +#endif + /* Typedefs and functions for timing certain parts of the library. */ /* A set of elapsed/user/system times emitted as a time point by the @@ -2227,7 +2255,7 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props); * Use this macro for API functions that shouldn't perform _any_ initialization * of the library or an interface, or push themselves on the function * stack, or perform tracing, etc. This macro _only_ sanity checks the - * API name itself. Examples are: H5TSmutex_acquire, + * API name itself. Examples are: H5TSmutex_acquire, * */ #define FUNC_ENTER_API_NAMECHECK_ONLY \ @@ -2323,7 +2351,7 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props); * Use this macro for non-API functions that shouldn't perform _any_ initialization * of the library or an interface, or push themselves on the function * stack, or perform tracing, etc. This macro _only_ sanity checks the - * API name itself. Examples are private routines in the H5TS package. + * API name itself. Examples are private routines in the H5TS package. * */ #define FUNC_ENTER_NOAPI_NAMECHECK_ONLY \ @@ -2401,7 +2429,7 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props); * Use this macro for non-API functions that shouldn't perform _any_ initialization * of the library or an interface, or push themselves on the function * stack, or perform tracing, etc. This macro _only_ sanity checks the - * API name itself. Examples are static routines in the H5TS package. + * API name itself. Examples are static routines in the H5TS package. * */ #define FUNC_ENTER_STATIC_NAMECHECK_ONLY \ diff --git a/src/H5public.h b/src/H5public.h index e192de0..65709c6 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -56,8 +56,12 @@ #ifdef H5_HAVE_PARALLEL /* Don't link against MPI C++ bindings */ +#ifndef MPICH_SKIP_MPICXX #define MPICH_SKIP_MPICXX 1 -#define OMPI_SKIP_MPICXX 1 +#endif +#ifndef OMPI_SKIP_MPICXX +#define OMPI_SKIP_MPICXX 1 +#endif #include <mpi.h> #ifndef MPI_FILE_NULL /* MPIO may be defined in mpi.h already */ #include <mpio.h> @@ -168,8 +172,9 @@ * Status return values. Failed integer functions in HDF5 result almost * always in a negative value (unsigned failing functions sometimes return * zero for failure) while successful return is non-negative (often zero). - * The negative failure value is most commonly -1, but don't bet on it. The - * proper way to detect failure is something like: + * The negative failure value is most commonly -1, but don't bet on it. + * + * The proper way to detect failure is something like: * \code * if((dset = H5Dopen2(file, name)) < 0) * fprintf(stderr, "unable to open the requested dataset\n"); @@ -178,11 +183,17 @@ typedef int herr_t; /** - * Boolean type. Successful return values are zero (false) or positive - * (true). The typical true value is 1 but don't bet on it. Boolean - * functions cannot fail. Functions that return #htri_t however return zero - * (false), positive (true), or negative (failure). The proper way to test - * for truth from a #htri_t function is: + * C99-style Boolean type. Successful return values are zero (false) or positive + * (true). The typical true value is 1 but don't bet on it. + * \attention Boolean functions cannot fail. + */ +#include <stdbool.h> +typedef bool hbool_t; +/** + * Three-valued Boolean type. Functions that return #htri_t however return zero + * (false), positive (true), or negative (failure). + * + * The proper way to test for truth from a #htri_t function is: * \code * if ((retval = H5Tcommitted(type)) > 0) { * printf("data type is committed\n"); @@ -193,8 +204,7 @@ typedef int herr_t; * } * \endcode */ -typedef bool hbool_t; -typedef int htri_t; +typedef int htri_t; /* The signed version of size_t * @@ -281,9 +291,9 @@ typedef enum { /* (Actually, any positive value will cause the iterator to stop and pass back * that positive value to the function that called the iterator) */ -#define H5_ITER_ERROR (-1) -#define H5_ITER_CONT (0) -#define H5_ITER_STOP (1) +#define H5_ITER_ERROR (-1) /**< Error, stop iteration */ +#define H5_ITER_CONT (0) /**< Continue iteration */ +#define H5_ITER_STOP (1) /**< Stop iteration, short-circuit success */ //! <!-- [H5_index_t_snip] --> /** diff --git a/src/H5system.c b/src/H5system.c index adfb758..e671ea9 100644 --- a/src/H5system.c +++ b/src/H5system.c @@ -732,8 +732,8 @@ H5_build_extpath(const char *name, char **extpath /*out*/) HDstrncpy(full_path, cwdpath, cwdlen + 1); if (!H5_CHECK_DELIMITER(cwdpath[cwdlen - 1])) - HDstrncat(full_path, H5_DIR_SEPS, HDstrlen(H5_DIR_SEPS)); - HDstrncat(full_path, new_name, HDstrlen(new_name)); + HDstrncat(full_path, H5_DIR_SEPS, path_len - (cwdlen + 1)); + HDstrncat(full_path, new_name, path_len - (cwdlen + 1) - HDstrlen(H5_DIR_SEPS)); } /* end if */ } /* end else */ @@ -1098,8 +1098,8 @@ const char *H5_optarg; /* Flag argument (or value) */ int H5_get_option(int argc, const char **argv, const char *opts, const struct h5_long_options *l_opts) { - static int sp = 1; /* character index in current token */ - int optopt = '?'; /* option character passed back to user */ + static int sp = 1; /* character index in current token */ + int optchar = '?'; /* option character passed back to user */ if (sp == 1) { /* check for more flag-like tokens */ @@ -1130,7 +1130,7 @@ H5_get_option(int argc, const char **argv, const char *opts, const struct h5_lon for (i = 0; l_opts && l_opts[i].name; i++) { if (HDstrcmp(arg, l_opts[i].name) == 0) { /* we've found a matching long command line flag */ - optopt = l_opts[i].shortval; + optchar = l_opts[i].shortval; if (l_opts[i].has_arg != no_arg) { if (H5_optarg == NULL) { @@ -1143,7 +1143,7 @@ H5_get_option(int argc, const char **argv, const char *opts, const struct h5_lon if (H5_opterr) HDfprintf(stderr, "%s: option required for \"--%s\" flag\n", argv[0], arg); - optopt = '?'; + optchar = '?'; } } } @@ -1152,7 +1152,7 @@ H5_get_option(int argc, const char **argv, const char *opts, const struct h5_lon if (H5_opterr) HDfprintf(stderr, "%s: no option required for \"%s\" flag\n", argv[0], arg); - optopt = '?'; + optchar = '?'; } } break; @@ -1164,7 +1164,7 @@ H5_get_option(int argc, const char **argv, const char *opts, const struct h5_lon if (H5_opterr) HDfprintf(stderr, "%s: unknown option \"%s\"\n", argv[0], arg); - optopt = '?'; + optchar = '?'; } H5_optind++; @@ -1176,11 +1176,11 @@ H5_get_option(int argc, const char **argv, const char *opts, const struct h5_lon register char *cp; /* pointer into current token */ /* short command line option */ - optopt = argv[H5_optind][sp]; + optchar = argv[H5_optind][sp]; - if (optopt == ':' || (cp = HDstrchr(opts, optopt)) == 0) { + if (optchar == ':' || (cp = HDstrchr(opts, optchar)) == 0) { if (H5_opterr) - HDfprintf(stderr, "%s: unknown option \"%c\"\n", argv[0], optopt); + HDfprintf(stderr, "%s: unknown option \"%c\"\n", argv[0], optchar); /* if no chars left in this token, move to next token */ if (argv[H5_optind][++sp] == '\0') { @@ -1198,9 +1198,9 @@ H5_get_option(int argc, const char **argv, const char *opts, const struct h5_lon } else if (++H5_optind >= argc) { if (H5_opterr) - HDfprintf(stderr, "%s: value expected for option \"%c\"\n", argv[0], optopt); + HDfprintf(stderr, "%s: value expected for option \"%c\"\n", argv[0], optchar); - optopt = '?'; + optchar = '?'; } else { /* flag value is next token */ @@ -1238,5 +1238,5 @@ H5_get_option(int argc, const char **argv, const char *opts, const struct h5_lon } /* return the current flag character found */ - return optopt; + return optchar; } diff --git a/src/H5trace.c b/src/H5trace.c index e33bc12..3a5d420 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -1083,6 +1083,15 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) } /* end block */ break; + case 'C': /* H5ES_event_complete_func_t */ + { + H5ES_event_complete_func_t cfunc = + (H5ES_event_complete_func_t)HDva_arg(ap, H5ES_event_complete_func_t); + + H5RS_asprintf_cat(rs, "%p", (void *)(uintptr_t)cfunc); + } /* end block */ + break; + case 'd': /* H5E_direction_t */ { H5E_direction_t direction = (H5E_direction_t)HDva_arg(ap, int); @@ -1111,6 +1120,15 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) } /* end block */ break; + case 'I': /* H5ES_event_insert_func_t */ + { + H5ES_event_insert_func_t ifunc = + (H5ES_event_insert_func_t)HDva_arg(ap, H5ES_event_insert_func_t); + + H5RS_asprintf_cat(rs, "%p", (void *)(uintptr_t)ifunc); + } /* end block */ + break; + case 's': /* H5ES_status_t */ { H5ES_status_t status = (H5ES_status_t)HDva_arg(ap, int); @@ -1124,6 +1142,10 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) H5RS_acat(rs, "H5ES_STATUS_SUCCEED"); break; + case H5ES_STATUS_CANCELED: + H5RS_acat(rs, "H5ES_STATUS_CANCELED"); + break; + case H5ES_STATUS_FAIL: H5RS_acat(rs, "H5ES_STATUS_FAIL"); break; @@ -1467,6 +1489,14 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) } /* end block */ break; + case 'c': /* H5_atclose_func_t */ + { + H5_atclose_func_t cfunc = (H5_atclose_func_t)HDva_arg(ap, H5_atclose_func_t); + + H5RS_asprintf_cat(rs, "%p", (void *)(uintptr_t)cfunc); + } /* end block */ + break; + case 's': /* hssize_t */ { hssize_t hssize = HDva_arg(ap, hssize_t); @@ -2873,6 +2903,10 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) H5RS_acat(rs, "H5VL_ATTR_DELETE"); break; + case H5VL_ATTR_DELETE_BY_IDX: + H5RS_acat(rs, "H5VL_ATTR_DELETE_BY_IDX"); + break; + case H5VL_ATTR_EXISTS: H5RS_acat(rs, "H5VL_ATTR_EXISTS"); break; @@ -2901,10 +2935,6 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) H5RS_acat(rs, "H5VL_BLOB_DELETE"); break; - case H5VL_BLOB_GETSIZE: - H5RS_acat(rs, "H5VL_BLOB_GETSIZE"); - break; - case H5VL_BLOB_ISNULL: H5RS_acat(rs, "H5VL_BLOB_ISNULL"); break; @@ -2985,10 +3015,6 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) H5RS_acat(rs, "H5VL_DATASET_REFRESH"); break; - case H5VL_DATASET_WAIT: - H5RS_acat(rs, "H5VL_DATASET_WAIT"); - break; - default: H5RS_asprintf_cat(rs, "%ld", (long)specific); break; @@ -3001,6 +3027,10 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) H5VL_datatype_get_t get = (H5VL_datatype_get_t)HDva_arg(ap, int); switch (get) { + case H5VL_DATATYPE_GET_BINARY_SIZE: + H5RS_acat(rs, "H5VL_DATATYPE_GET_BINARY_SIZE"); + break; + case H5VL_DATATYPE_GET_BINARY: H5RS_acat(rs, "H5VL_DATATYPE_GET_BINARY"); break; @@ -3093,14 +3123,6 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) H5RS_acat(rs, "H5VL_FILE_REOPEN"); break; - case H5VL_FILE_MOUNT: - H5RS_acat(rs, "H5VL_FILE_MOUNT"); - break; - - case H5VL_FILE_UNMOUNT: - H5RS_acat(rs, "H5VL_FILE_UNMOUNT"); - break; - case H5VL_FILE_IS_ACCESSIBLE: H5RS_acat(rs, "H5VL_FILE_IS_ACCESSIBLE"); break; @@ -3113,10 +3135,6 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) H5RS_acat(rs, "H5VL_FILE_IS_EQUAL"); break; - case H5VL_FILE_WAIT: - H5RS_acat(rs, "H5VL_FILE_WAIT"); - break; - default: H5RS_asprintf_cat(rs, "%ld", (long)specific); break; @@ -3149,6 +3167,14 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) H5VL_group_specific_t specific = (H5VL_group_specific_t)HDva_arg(ap, int); switch (specific) { + case H5VL_GROUP_MOUNT: + H5RS_acat(rs, "H5VL_GROUP_MOUNT"); + break; + + case H5VL_GROUP_UNMOUNT: + H5RS_acat(rs, "H5VL_GROUP_UNMOUNT"); + break; + case H5VL_GROUP_FLUSH: H5RS_acat(rs, "H5VL_GROUP_FLUSH"); break; @@ -3164,9 +3190,9 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) } /* end block */ break; - case 'k': /* H5VL_link_create_type_t */ + case 'k': /* H5VL_link_create_t */ { - H5VL_link_create_type_t create = (H5VL_link_create_type_t)HDva_arg(ap, int); + H5VL_link_create_t create = (H5VL_link_create_t)HDva_arg(ap, int); switch (create) { case H5VL_LINK_CREATE_HARD: @@ -3334,22 +3360,14 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) H5VL_request_specific_t specific = (H5VL_request_specific_t)HDva_arg(ap, int); switch (specific) { - case H5VL_REQUEST_WAITANY: - H5RS_acat(rs, "H5VL_REQUEST_WAITANY"); - break; - - case H5VL_REQUEST_WAITSOME: - H5RS_acat(rs, "H5VL_REQUEST_WAITSOME"); - break; - - case H5VL_REQUEST_WAITALL: - H5RS_acat(rs, "H5VL_REQUEST_WAITALL"); - break; - case H5VL_REQUEST_GET_ERR_STACK: H5RS_acat(rs, "H5VL_REQUEST_GET_ERR_STACK"); break; + case H5VL_REQUEST_GET_EXEC_TIME: + H5RS_acat(rs, "H5VL_REQUEST_GET_EXEC_TIME"); + break; + default: H5RS_asprintf_cat(rs, "%ld", (long)specific); break; diff --git a/src/H5win32defs.h b/src/H5win32defs.h index 030b65b..44cf50c 100644 --- a/src/H5win32defs.h +++ b/src/H5win32defs.h @@ -80,7 +80,7 @@ struct timezone { #define HDstrtok_r(X, Y, Z) strtok_s(X, Y, Z) #define HDtzset() _tzset() #define HDunlink(S) _unlink(S) -#define HDunsetenv(N, V, O) Wsetenv(N, "", 1) +#define HDunsetenv(N) Wsetenv(N, "", 1) #define HDwrite(F, M, Z) _write(F, M, Z) #ifndef H5_HAVE_MINGW diff --git a/src/Makefile.am b/src/Makefile.am index 37ff850..ae058f4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -108,11 +108,11 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5lib_settings.c H5system.c \ H5Torder.c H5Tref.c H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvisit.c \ H5Tvlen.c \ H5TS.c \ - H5VL.c H5VLcallback.c H5VLint.c H5VLnative.c \ + H5VL.c H5VLcallback.c H5VLdyn_ops.c H5VLint.c H5VLnative.c \ H5VLnative_attr.c H5VLnative_blob.c H5VLnative_dataset.c \ H5VLnative_datatype.c H5VLnative_file.c H5VLnative_group.c \ H5VLnative_link.c H5VLnative_introspect.c H5VLnative_object.c \ - H5VLnative_token.c H5VLpassthru.c \ + H5VLnative_token.c H5VLpassthru.c H5VLtest.c \ H5VM.c H5WB.c H5Z.c \ H5Zdeflate.c H5Zfletcher32.c H5Znbit.c H5Zshuffle.c H5Zscaleoffset.c \ H5Zszip.c H5Ztrans.c @@ -160,7 +160,7 @@ include_HEADERS = hdf5.h H5api_adpt.h H5overflow.h H5pubconf.h H5public.h H5vers H5Zpublic.h # Public component author headers -include_HEADERS += H5FDdevelop.h H5Idevelop.h H5Ldevelop.h \ +include_HEADERS += H5ESdevelop.h H5FDdevelop.h H5Idevelop.h H5Ldevelop.h \ H5Tdevelop.h H5TSdevelop.h H5Zdevelop.h # install libhdf5.settings in lib directory diff --git a/src/hdf5.h b/src/hdf5.h index b4ece16..9236f2c 100644 --- a/src/hdf5.h +++ b/src/hdf5.h @@ -42,6 +42,7 @@ #include "H5Zpublic.h" /* Data filters */ /* Plugin/component developer headers */ +#include "H5ESdevelop.h" /* Event Sets */ #include "H5FDdevelop.h" /* File drivers */ #include "H5Idevelop.h" /* ID management */ #include "H5Ldevelop.h" /* Links */ @@ -52,6 +53,7 @@ /* Virtual object layer (VOL) connector developer support */ #include "H5VLconnector.h" /* VOL connector author routines */ #include "H5VLconnector_passthru.h" /* Pass-through VOL connector author routines */ +#include "H5VLnative.h" /* Native VOL connector macros, for VOL connector authors */ /* Predefined file drivers */ #include "H5FDcore.h" /* Files stored entirely in memory */ diff --git a/test/CMakeTests.cmake b/test/CMakeTests.cmake index 17931cf..bb5356d 100644 --- a/test/CMakeTests.cmake +++ b/test/CMakeTests.cmake @@ -402,6 +402,8 @@ set (test_CLEANFILES mirror_rw/* mirror_wo/* event_set_*.h5 + h5s_block.h5 + h5s_plist.h5 ) # Remove any output file left over from previous test run @@ -647,10 +649,10 @@ set_tests_properties (H5TEST-tcheck_version-minor PROPERTIES WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST WILL_FAIL "true" ) +# release + 1 should pass add_test (NAME H5TEST-tcheck_version-release COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:tcheck_version> "-tr") set_tests_properties (H5TEST-tcheck_version-release PROPERTIES WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST - WILL_FAIL "true" ) ############################################################################## diff --git a/test/Makefile.am b/test/Makefile.am index 6df1653..87b2925 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -216,7 +216,7 @@ CHECK_CLEANFILES+=accum.h5 cmpd_dset.h5 compact_dataset.h5 dataset.h5 dset_offse zero_chunk.h5 chunk_single.h5 swmr_non_latest.h5 \ earray_hdr_fd.h5 farray_hdr_fd.h5 bt2_hdr_fd.h5 \ storage_size.h5 dls_01_strings.h5 power2up.h5 version_bounds.h5 \ - alloc_0sized.h5 \ + alloc_0sized.h5 h5s_block.h5 h5s_plist.h5 \ extend.h5 istore.h5 extlinks*.h5 frspace.h5 links*.h5 \ sys_file1 tfile[1-7].h5 th5s[1-4].h5 lheap.h5 fheap.h5 ohdr.h5 \ stab.h5 extern_[1-5].h5 extern_[1-4][rw].raw gheap[0-4].h5 \ diff --git a/test/ShellTests.cmake b/test/ShellTests.cmake index 812121e..9614152 100644 --- a/test/ShellTests.cmake +++ b/test/ShellTests.cmake @@ -19,7 +19,8 @@ if (UNIX) find_program (SH_PROGRAM bash) if (SH_PROGRAM) - + set (srcdir ${HDF5_TEST_SOURCE_DIR}) + set (bindir ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) ############################################################################## # configure scripts to test dir ############################################################################## @@ -33,13 +34,8 @@ if (UNIX) ############################################################################## # copy test programs to test dir ############################################################################## - add_custom_command ( - TARGET swmr_check_compat_vfd - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:swmr_check_compat_vfd>" "${HDF5_TEST_BINARY_DIR}/H5TEST/swmr_check_compat_vfd" - ) - + #shell script creates dir + #file (MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/H5TEST/swmr_test") add_custom_command ( TARGET swmr_check_compat_vfd POST_BUILD @@ -47,118 +43,12 @@ if (UNIX) ARGS -E copy_if_different "${HDF5_SOURCE_DIR}/bin/output_filter.sh" "${HDF5_TEST_BINARY_DIR}/H5TEST/bin/output_filter.sh" ) - file (MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/H5TEST/flushrefresh_test") - add_custom_command ( - TARGET flushrefresh - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:flushrefresh>" "${HDF5_TEST_BINARY_DIR}/H5TEST/flushrefresh" - ) - #shell script creates dir #file (MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/H5TEST/usecases_test") - add_custom_command ( - TARGET use_append_mchunks - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:use_append_mchunks>" "${HDF5_TEST_BINARY_DIR}/H5TEST/use_append_mchunks" - ) - add_custom_command ( - TARGET use_disable_mdc_flushes - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:use_disable_mdc_flushes>" "${HDF5_TEST_BINARY_DIR}/H5TEST/use_disable_mdc_flushes" - ) - add_custom_command ( - TARGET twriteorder - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:twriteorder>" "${HDF5_TEST_BINARY_DIR}/H5TEST/twriteorder" - ) - add_custom_command ( - TARGET use_append_chunk - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:use_append_chunk>" "${HDF5_TEST_BINARY_DIR}/H5TEST/use_append_chunk" - ) file (MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/H5TEST/swmr_test") - add_custom_command ( - TARGET swmr_generator - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:swmr_generator>" "${HDF5_TEST_BINARY_DIR}/H5TEST/swmr_test/swmr_generator" - ) - add_custom_command ( - TARGET swmr_start_write - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:swmr_start_write>" "${HDF5_TEST_BINARY_DIR}/H5TEST/swmr_test/swmr_start_write" - ) - add_custom_command ( - TARGET swmr_reader - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:swmr_reader>" "${HDF5_TEST_BINARY_DIR}/H5TEST/swmr_test/swmr_reader" - ) - add_custom_command ( - TARGET swmr_writer - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:swmr_writer>" "${HDF5_TEST_BINARY_DIR}/H5TEST/swmr_test/swmr_writer" - ) - add_custom_command ( - TARGET swmr_remove_reader - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:swmr_remove_reader>" "${HDF5_TEST_BINARY_DIR}/H5TEST/swmr_test/swmr_remove_reader" - ) - add_custom_command ( - TARGET swmr_remove_writer - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:swmr_remove_writer>" "${HDF5_TEST_BINARY_DIR}/H5TEST/swmr_test/swmr_remove_writer" - ) - add_custom_command ( - TARGET swmr_addrem_writer - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:swmr_addrem_writer>" "${HDF5_TEST_BINARY_DIR}/H5TEST/swmr_test/swmr_addrem_writer" - ) - add_custom_command ( - TARGET swmr_sparse_reader - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:swmr_sparse_reader>" "${HDF5_TEST_BINARY_DIR}/H5TEST/swmr_test/swmr_sparse_reader" - ) - add_custom_command ( - TARGET swmr_sparse_writer - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:swmr_sparse_writer>" "${HDF5_TEST_BINARY_DIR}/H5TEST/swmr_test/swmr_sparse_writer" - ) file (MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/H5TEST/vds_swmr_test") - add_custom_command ( - TARGET vds_swmr_gen - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:vds_swmr_gen>" "${HDF5_TEST_BINARY_DIR}/H5TEST/vds_swmr_gen" - ) - add_custom_command ( - TARGET vds_swmr_writer - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:vds_swmr_writer>" "${HDF5_TEST_BINARY_DIR}/H5TEST/vds_swmr_writer" - ) - add_custom_command ( - TARGET vds_swmr_reader - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:vds_swmr_reader>" "${HDF5_TEST_BINARY_DIR}/H5TEST/vds_swmr_reader" - ) - - ############################################################################## ############################################################################## diff --git a/test/big.c b/test/big.c index 36fb27d..6f8ce67 100644 --- a/test/big.c +++ b/test/big.c @@ -56,8 +56,8 @@ #define DNAME "big.data" #define WRT_N 50 -#define WRT_SIZE 4 * 1024 -#define FAMILY_SIZE 1024 * 1024 * 1024 +#define WRT_SIZE (4 * 1024) +#define FAMILY_SIZE (1024 * 1024 * 1024) #define GB (HDoff_t)0x40000000L @@ -277,7 +277,7 @@ error: * 'name' in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("format-nonliteral") +H5_GCC_CLANG_DIAG_OFF("format-nonliteral") static int enough_room(hid_t fapl) { @@ -319,7 +319,7 @@ done: return ret_value; } -H5_GCC_DIAG_ON("format-nonliteral") +H5_GCC_CLANG_DIAG_ON("format-nonliteral") /*------------------------------------------------------------------------- * Function: writer diff --git a/test/cache.c b/test/cache.c index 6ded559..6989564 100644 --- a/test/cache.c +++ b/test/cache.c @@ -1046,7 +1046,7 @@ smoke_check_5(int express_test, unsigned paged) /* hbool_t set_initial_size = */ TRUE, /* size_t initial_size = */ (2 * 1024 * 1024), - /* double min_clean_fraction = */ 0.1f, + /* double min_clean_fraction = */ 0.1, /* size_t max_size = */ (32 * 1024 * 1025), /* size_t min_size = */ (512 * 1024), @@ -1055,23 +1055,23 @@ smoke_check_5(int express_test, unsigned paged) /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, - /* double lower_hr_threshold = */ 0.75f, + /* double lower_hr_threshold = */ 0.75, - /* double increment = */ 2.0f, + /* double increment = */ 2.0, /* hbool_t apply_max_increment = */ TRUE, /* size_t max_increment = */ (4 * 1024 * 1024), /* enum H5C_cache_flash_incr_mode */ /* flash_incr_mode = */ H5C_flash_incr__off, - /* double flash_multiple = */ 2.0f, - /* double flash_threshold = */ 0.5f, + /* double flash_multiple = */ 2.0, + /* double flash_threshold = */ 0.5, /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__threshold, - /* double upper_hr_threshold = */ 0.995f, + /* double upper_hr_threshold = */ 0.995, - /* double decrement = */ 0.9f, + /* double decrement = */ 0.9, /* hbool_t apply_max_decrement = */ TRUE, /* size_t max_decrement = */ (1 * 1024 * 1024), @@ -1079,7 +1079,7 @@ smoke_check_5(int express_test, unsigned paged) /* int32_t epochs_before_eviction = */ 3, /* hbool_t apply_empty_reserve = */ TRUE, - /* double empty_reserve = */ 0.5f + /* double empty_reserve = */ 0.5 }; if (paged) @@ -1278,7 +1278,7 @@ smoke_check_6(int express_test, unsigned paged) /* hbool_t set_initial_size = */ TRUE, /* size_t initial_size = */ (2 * 1024 * 1024), - /* double min_clean_fraction = */ 0.1f, + /* double min_clean_fraction = */ 0.1, /* size_t max_size = */ (32 * 1024 * 1025), /* size_t min_size = */ (512 * 1024), @@ -1287,23 +1287,23 @@ smoke_check_6(int express_test, unsigned paged) /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, - /* double lower_hr_threshold = */ 0.75f, + /* double lower_hr_threshold = */ 0.75, - /* double increment = */ 2.0f, + /* double increment = */ 2.0, /* hbool_t apply_max_increment = */ TRUE, /* size_t max_increment = */ (4 * 1024 * 1024), /* enum H5C_cache_flash_incr_mode */ /* flash_incr_mode = */ H5C_flash_incr__off, - /* double flash_multiple = */ 2.0f, - /* double flash_threshold = */ 0.5f, + /* double flash_multiple = */ 2.0, + /* double flash_threshold = */ 0.5, /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__threshold, - /* double upper_hr_threshold = */ 0.995f, + /* double upper_hr_threshold = */ 0.995, - /* double decrement = */ 0.9f, + /* double decrement = */ 0.9, /* hbool_t apply_max_decrement = */ TRUE, /* size_t max_decrement = */ (1 * 1024 * 1024), @@ -1311,7 +1311,7 @@ smoke_check_6(int express_test, unsigned paged) /* int32_t epochs_before_eviction = */ 3, /* hbool_t apply_empty_reserve = */ TRUE, - /* double empty_reserve = */ 0.05f + /* double empty_reserve = */ 0.05 }; if (paged) @@ -1510,7 +1510,7 @@ smoke_check_7(int express_test, unsigned paged) /* hbool_t set_initial_size = */ TRUE, /* size_t initial_size = */ (2 * 1024 * 1024), - /* double min_clean_fraction = */ 0.1f, + /* double min_clean_fraction = */ 0.1, /* size_t max_size = */ (32 * 1024 * 1025), /* size_t min_size = */ (512 * 1024), @@ -1519,24 +1519,24 @@ smoke_check_7(int express_test, unsigned paged) /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, - /* double lower_hr_threshold = */ 0.75f, + /* double lower_hr_threshold = */ 0.75, - /* double increment = */ 2.0f, + /* double increment = */ 2.0, /* hbool_t apply_max_increment = */ TRUE, /* size_t max_increment = */ (8 * 1024 * 1024), /* enum H5C_cache_flash_incr_mode */ /* flash_incr_mode = */ H5C_flash_incr__off, - /* double flash_multiple = */ 2.0f, - /* double flash_threshold = */ 0.5f, + /* double flash_multiple = */ 2.0, + /* double flash_threshold = */ 0.5, /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, - /* double upper_hr_threshold = */ 0.995f, + /* double upper_hr_threshold = */ 0.995, - /* double decrement = */ 0.9f, + /* double decrement = */ 0.9, /* hbool_t apply_max_decrement = */ TRUE, /* size_t max_decrement = */ (1 * 1024 * 1024), @@ -1544,7 +1544,7 @@ smoke_check_7(int express_test, unsigned paged) /* int32_t epochs_before_eviction = */ 3, /* hbool_t apply_empty_reserve = */ TRUE, - /* double empty_reserve = */ 0.1f + /* double empty_reserve = */ 0.1 }; if (paged) @@ -1743,7 +1743,7 @@ smoke_check_8(int express_test, unsigned paged) /* hbool_t set_initial_size = */ TRUE, /* size_t initial_size = */ (2 * 1024 * 1024), - /* double min_clean_fraction = */ 0.1f, + /* double min_clean_fraction = */ 0.1, /* size_t max_size = */ (32 * 1024 * 1025), /* size_t min_size = */ (512 * 1024), @@ -1752,24 +1752,24 @@ smoke_check_8(int express_test, unsigned paged) /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, - /* double lower_hr_threshold = */ 0.75f, + /* double lower_hr_threshold = */ 0.75, - /* double increment = */ 2.0f, + /* double increment = */ 2.0, /* hbool_t apply_max_increment = */ TRUE, /* size_t max_increment = */ (4 * 1024 * 1024), /* enum H5C_cache_flash_incr_mode */ /* flash_incr_mode = */ H5C_flash_incr__off, - /* double flash_multiple = */ 2.0f, - /* double flash_threshold = */ 0.5f, + /* double flash_multiple = */ 2.0, + /* double flash_threshold = */ 0.5, /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, - /* double upper_hr_threshold = */ 0.995f, + /* double upper_hr_threshold = */ 0.995, - /* double decrement = */ 0.9f, + /* double decrement = */ 0.9, /* hbool_t apply_max_decrement = */ TRUE, /* size_t max_decrement = */ (1 * 1024 * 1024), @@ -1777,7 +1777,7 @@ smoke_check_8(int express_test, unsigned paged) /* int32_t epochs_before_eviction = */ 3, /* hbool_t apply_empty_reserve = */ TRUE, - /* double empty_reserve = */ 0.1f + /* double empty_reserve = */ 0.1 }; if (paged) @@ -17004,7 +17004,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) /* hbool_t set_initial_size = */ TRUE, /* size_t initial_size = */ (512 * 1024), - /* double min_clean_fraction = */ 0.5f, + /* double min_clean_fraction = */ 0.5, /* size_t max_size = */ (14 * 1024 * 1024), /* size_t min_size = */ (512 * 1024), @@ -17013,23 +17013,23 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, - /* double lower_hr_threshold = */ 0.75f, + /* double lower_hr_threshold = */ 0.75, - /* double increment = */ 2.0f, + /* double increment = */ 2.0, /* hbool_t apply_max_increment = */ TRUE, /* size_t max_increment = */ (4 * 1024 * 1024), /* enum H5C_cache_flash_incr_mode */ /* flash_incr_mode = */ H5C_flash_incr__off, - /* double flash_multiple = */ 2.0f, - /* double flash_threshold = */ 0.5f, + /* double flash_multiple = */ 2.0, + /* double flash_threshold = */ 0.5, /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__threshold, - /* double upper_hr_threshold = */ 0.995f, + /* double upper_hr_threshold = */ 0.995, - /* double decrement = */ 0.1f, + /* double decrement = */ 0.1, /* hbool_t apply_max_decrement = */ TRUE, /* size_t max_decrement = */ (1 * 1024 * 1024), @@ -17037,7 +17037,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) /* int32_t epochs_before_eviction = */ 3, /* hbool_t apply_empty_reserve = */ TRUE, - /* double empty_reserve = */ 0.05f}; + /* double empty_reserve = */ 0.05}; if (paged) TESTING("automatic cache resizing (paged aggregation)") @@ -17361,7 +17361,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1000 * 1000 + 10; - auto_size_ctl.min_clean_fraction = 0.1f; + auto_size_ctl.min_clean_fraction = 0.1; auto_size_ctl.max_size = 8 * 1000 * 1000; auto_size_ctl.min_size = 500 * 1000; @@ -17370,22 +17370,22 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1000 * 1000); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1000 * 1000); @@ -17393,7 +17393,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); if (result != SUCCEED) { @@ -17676,7 +17676,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -17685,22 +17685,22 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 4.0f; + auto_size_ctl.increment = 4.0; auto_size_ctl.apply_max_increment = FALSE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.25f; + auto_size_ctl.decrement = 0.25; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -17708,7 +17708,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); if (result != SUCCEED) { @@ -17852,7 +17852,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 8 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 8 * 1024 * 1024; auto_size_ctl.min_size = 512 * 1024; @@ -17861,22 +17861,22 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -17884,7 +17884,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = FALSE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); if (result != SUCCEED) { @@ -18220,7 +18220,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 8 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 8 * 1024 * 1024; auto_size_ctl.min_size = 512 * 1024; @@ -18229,22 +18229,22 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -18252,7 +18252,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = FALSE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -18702,7 +18702,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 8 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 8 * 1024 * 1024; auto_size_ctl.min_size = 512 * 1024; @@ -18711,22 +18711,22 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -18734,7 +18734,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.5f; /* for ease of testing */ + auto_size_ctl.empty_reserve = 0.5; /* for ease of testing */ result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -19079,7 +19079,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 8 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 8 * 1024 * 1024; auto_size_ctl.min_size = 512 * 1024; @@ -19088,16 +19088,16 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.incr_mode = H5C_incr__off; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out_with_threshold; @@ -19106,7 +19106,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) */ auto_size_ctl.upper_hr_threshold = 0.999; /* for ease of testing */ - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -19114,7 +19114,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.epochs_before_eviction = 1; /* for ease of testing */ auto_size_ctl.apply_empty_reserve = FALSE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); if (result != SUCCEED) { @@ -19326,7 +19326,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 8 * 1000 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 8 * 1000 * 1024; auto_size_ctl.min_size = 512 * 1024; @@ -19335,22 +19335,22 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out_with_threshold; - auto_size_ctl.upper_hr_threshold = 0.999f; /* for ease of testing */ + auto_size_ctl.upper_hr_threshold = 0.999; /* for ease of testing */ - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1000 * 1024); @@ -19358,7 +19358,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.epochs_before_eviction = 1; /* for ease of testing */ auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.5f; /* for ease of testing */ + auto_size_ctl.empty_reserve = 0.5; /* for ease of testing */ result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); if (result != SUCCEED) { @@ -19868,7 +19868,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 64 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 1024 * 1024; auto_size_ctl.min_size = 5 * 1024; @@ -19877,22 +19877,22 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (32 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__add_space; - auto_size_ctl.flash_multiple = 1.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 1.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out_with_threshold; - auto_size_ctl.upper_hr_threshold = 0.999f; /* for ease of testing */ + auto_size_ctl.upper_hr_threshold = 0.999; /* for ease of testing */ - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1000 * 1024); @@ -19900,7 +19900,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.epochs_before_eviction = 1; /* for ease of testing */ auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.5f; /* for ease of testing */ + auto_size_ctl.empty_reserve = 0.5; /* for ease of testing */ result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); if (result != SUCCEED) { @@ -20602,7 +20602,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 20 * 1024; auto_size_ctl.min_size = 4 * 1024; @@ -20611,22 +20611,22 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__add_space; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.4f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.4; auto_size_ctl.decr_mode = H5C_decr__age_out_with_threshold; - auto_size_ctl.upper_hr_threshold = 0.999f; /* for ease of testing */ + auto_size_ctl.upper_hr_threshold = 0.999; /* for ease of testing */ - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (2 * 1024); @@ -20634,7 +20634,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.epochs_before_eviction = 1; /* for ease of testing */ auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.5f; /* for ease of testing */ + auto_size_ctl.empty_reserve = 0.5; /* for ease of testing */ result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); if (result != SUCCEED) { @@ -20859,7 +20859,7 @@ check_auto_cache_resize_disable(unsigned paged) /* hbool_t set_initial_size = */ TRUE, /* size_t initial_size = */ (512 * 1024), - /* double min_clean_fraction = */ 0.5f, + /* double min_clean_fraction = */ 0.5, /* size_t max_size = */ (14 * 1024 * 1024), /* size_t min_size = */ (512 * 1024), @@ -20868,23 +20868,23 @@ check_auto_cache_resize_disable(unsigned paged) /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, - /* double lower_hr_threshold = */ 0.75f, + /* double lower_hr_threshold = */ 0.75, - /* double increment = */ 2.0f, + /* double increment = */ 2.0, /* hbool_t apply_max_increment = */ TRUE, /* size_t max_increment = */ (4 * 1024 * 1024), /* enum H5C_cache_flash_incr_mode */ /* flash_incr_mode = */ H5C_flash_incr__off, - /* double flash_multiple = */ 1.0f, - /* double flash_threshold = */ 0.25f, + /* double flash_multiple = */ 1.0, + /* double flash_threshold = */ 0.25, /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__threshold, - /* double upper_hr_threshold = */ 0.995f, + /* double upper_hr_threshold = */ 0.995, - /* double decrement = */ 0.1f, + /* double decrement = */ 0.1, /* hbool_t apply_max_decrement = */ TRUE, /* size_t max_decrement = */ (1 * 1024 * 1024), @@ -20892,7 +20892,7 @@ check_auto_cache_resize_disable(unsigned paged) /* int32_t epochs_before_eviction = */ 3, /* hbool_t apply_empty_reserve = */ TRUE, - /* double empty_reserve = */ 0.05f}; + /* double empty_reserve = */ 0.05}; if (paged) TESTING("automatic cache resize disable (paged aggregation)") @@ -20964,7 +20964,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -20973,22 +20973,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 1.0f; /* disable size increases */ + auto_size_ctl.increment = 1.0; /* disable size increases */ auto_size_ctl.apply_max_increment = FALSE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -20996,7 +20996,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -21116,7 +21116,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -21125,21 +21125,21 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.0f; /* disable size increases */ + auto_size_ctl.lower_hr_threshold = 0.0; /* disable size increases */ - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = FALSE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.upper_hr_threshold = 0.995; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -21147,7 +21147,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -21267,7 +21267,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -21276,22 +21276,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__off; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = FALSE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -21299,7 +21299,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -21418,7 +21418,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -21427,22 +21427,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 1.0f; /* disable size decreases */ + auto_size_ctl.decrement = 1.0; /* disable size decreases */ auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -21450,7 +21450,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -21572,7 +21572,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -21581,22 +21581,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 1.0f; /* disable size decreases */ + auto_size_ctl.upper_hr_threshold = 1.0; /* disable size decreases */ - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -21604,7 +21604,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -21722,7 +21722,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -21731,22 +21731,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__off; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -21754,7 +21754,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -21874,7 +21874,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -21883,22 +21883,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = 0; /* disable decrement */ @@ -21906,7 +21906,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 1; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -22091,7 +22091,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -22100,22 +22100,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -22123,7 +22123,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 1; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 1.0f; /* disable decrement */ + auto_size_ctl.empty_reserve = 1.0; /* disable decrement */ result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -22315,7 +22315,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -22324,22 +22324,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out_with_threshold; - auto_size_ctl.upper_hr_threshold = 1.0f; + auto_size_ctl.upper_hr_threshold = 1.0; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -22347,7 +22347,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 1; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -22541,7 +22541,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 2 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -22550,22 +22550,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.0f; /* disable size increases */ + auto_size_ctl.lower_hr_threshold = 0.0; /* disable size increases */ - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 1.0f; /* disable size decreases */ + auto_size_ctl.upper_hr_threshold = 1.0; /* disable size decreases */ - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -22573,7 +22573,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -22661,7 +22661,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.25f; + auto_size_ctl.min_clean_fraction = 0.25; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -22670,22 +22670,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 1.0f; /* disable size increment */ + auto_size_ctl.increment = 1.0; /* disable size increment */ auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 1.0f; /* disable size decrement */ + auto_size_ctl.decrement = 1.0; /* disable size decrement */ auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -22693,7 +22693,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -22781,7 +22781,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = FALSE; auto_size_ctl.initial_size = 2 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 6 * 1024 * 1024; /* no resize */ auto_size_ctl.min_size = 6 * 1024 * 1024; /* no resize */ @@ -22790,22 +22790,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -22813,7 +22813,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -22901,7 +22901,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.25f; + auto_size_ctl.min_clean_fraction = 0.25; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -22910,22 +22910,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 1.0f; /* disable size increment */ + auto_size_ctl.increment = 1.0; /* disable size increment */ auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 1.0f; /* disable size decrement */ + auto_size_ctl.upper_hr_threshold = 1.0; /* disable size decrement */ - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -22933,7 +22933,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -23021,7 +23021,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -23030,22 +23030,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.0f; /* disable size increment */ + auto_size_ctl.lower_hr_threshold = 0.0; /* disable size increment */ - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 1.0f; /* disable size decrement */ + auto_size_ctl.decrement = 1.0; /* disable size decrement */ auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -23053,7 +23053,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -23141,7 +23141,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -23150,22 +23150,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__off; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__off; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -23173,7 +23173,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -23288,7 +23288,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 64 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 256 * 1024; auto_size_ctl.min_size = 32 * 1024; @@ -23297,22 +23297,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 1.0f; - auto_size_ctl.flash_threshold = 0.25f; + auto_size_ctl.flash_multiple = 1.0; + auto_size_ctl.flash_threshold = 0.25; auto_size_ctl.decr_mode = H5C_decr__age_out_with_threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024); @@ -23320,7 +23320,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -23458,7 +23458,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) /* hbool_t set_initial_size = */ TRUE, /* size_t initial_size = */ (512 * 1024), - /* double min_clean_fraction = */ 0.5f, + /* double min_clean_fraction = */ 0.5, /* size_t max_size = */ (14 * 1024 * 1024), /* size_t min_size = */ (512 * 1024), @@ -23467,23 +23467,23 @@ check_auto_cache_resize_epoch_markers(unsigned paged) /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, - /* double lower_hr_threshold = */ 0.75f, + /* double lower_hr_threshold = */ 0.75, - /* double increment = */ 2.0f, + /* double increment = */ 2.0, /* hbool_t apply_max_increment = */ TRUE, /* size_t max_increment = */ (4 * 1024 * 1024), /* enum H5C_cache_flash_incr_mode */ /* flash_incr_mode = */ H5C_flash_incr__off, - /* double flash_multiple = */ 2.0f, - /* double flash_threshold = */ 0.5f, + /* double flash_multiple = */ 2.0, + /* double flash_threshold = */ 0.5, /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__threshold, - /* double upper_hr_threshold = */ 0.995f, + /* double upper_hr_threshold = */ 0.995, - /* double decrement = */ 0.1f, + /* double decrement = */ 0.1, /* hbool_t apply_max_decrement = */ TRUE, /* size_t max_decrement = */ (1 * 1024 * 1024), @@ -23491,7 +23491,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) /* int32_t epochs_before_eviction = */ 3, /* hbool_t apply_empty_reserve = */ TRUE, - /* double empty_reserve = */ 0.05f}; + /* double empty_reserve = */ 0.05}; if (paged) TESTING("automatic cache resize epoch marker management (paged aggr)") @@ -23545,7 +23545,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 8 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 8 * 1024 * 1024; auto_size_ctl.min_size = 512 * 1024; @@ -23554,22 +23554,22 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__off; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -23577,7 +23577,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.epochs_before_eviction = 10; auto_size_ctl.apply_empty_reserve = FALSE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -23709,7 +23709,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 8 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 8 * 1024 * 1024; auto_size_ctl.min_size = 512 * 1024; @@ -23718,22 +23718,22 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__off; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -23741,7 +23741,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.epochs_before_eviction = 1; auto_size_ctl.apply_empty_reserve = FALSE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -23827,7 +23827,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 8 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 8 * 1024 * 1024; auto_size_ctl.min_size = 512 * 1024; @@ -23836,22 +23836,22 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__off; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -23859,7 +23859,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.epochs_before_eviction = 1; auto_size_ctl.apply_empty_reserve = FALSE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -23905,7 +23905,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 8 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 8 * 1024 * 1024; auto_size_ctl.min_size = 512 * 1024; @@ -23914,22 +23914,22 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__off; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out_with_threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -23937,7 +23937,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.epochs_before_eviction = 10; auto_size_ctl.apply_empty_reserve = FALSE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -24014,7 +24014,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 8 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 8 * 1024 * 1024; auto_size_ctl.min_size = 512 * 1024; @@ -24023,22 +24023,22 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__off; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__off; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24046,7 +24046,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.epochs_before_eviction = 10; auto_size_ctl.apply_empty_reserve = FALSE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -24146,7 +24146,7 @@ check_auto_cache_resize_input_errs(unsigned paged) /* hbool_t set_initial_size = */ TRUE, /* size_t initial_size = */ (512 * 1024), - /* double min_clean_fraction = */ 0.5f, + /* double min_clean_fraction = */ 0.5, /* size_t max_size = */ (16 * 1024 * 1024), /* size_t min_size = */ (512 * 1024), @@ -24155,23 +24155,23 @@ check_auto_cache_resize_input_errs(unsigned paged) /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, - /* double lower_hr_threshold = */ 0.75f, + /* double lower_hr_threshold = */ 0.75, - /* double increment = */ 2.0f, + /* double increment = */ 2.0, /* hbool_t apply_max_increment = */ TRUE, /* size_t max_increment = */ (4 * 1024 * 1024), /* enum H5C_cache_flash_incr_mode */ /* flash_incr_mode = */ H5C_flash_incr__off, - /* double flash_multiple = */ 2.0f, - /* double flash_threshold = */ 0.5f, + /* double flash_multiple = */ 2.0, + /* double flash_threshold = */ 0.5, /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__threshold, - /* double upper_hr_threshold = */ 0.995f, + /* double upper_hr_threshold = */ 0.995, - /* double decrement = */ 0.1f, + /* double decrement = */ 0.1, /* hbool_t apply_max_decrement = */ TRUE, /* size_t max_decrement = */ (1 * 1024 * 1024), @@ -24179,7 +24179,7 @@ check_auto_cache_resize_input_errs(unsigned paged) /* int32_t epochs_before_eviction = */ 3, /* hbool_t apply_empty_reserve = */ TRUE, - /* double empty_reserve = */ 0.05f}; + /* double empty_reserve = */ 0.05}; H5C_auto_size_ctl_t invalid_auto_size_ctl; H5C_auto_size_ctl_t test_auto_size_ctl; @@ -24249,7 +24249,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.5f; + invalid_auto_size_ctl.min_clean_fraction = 0.5; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -24258,22 +24258,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.7f; + invalid_auto_size_ctl.lower_hr_threshold = 0.7; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24281,7 +24281,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(NULL, &invalid_auto_size_ctl); @@ -24318,7 +24318,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.5f; + invalid_auto_size_ctl.min_clean_fraction = 0.5; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -24327,22 +24327,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.7f; + invalid_auto_size_ctl.lower_hr_threshold = 0.7; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24350,7 +24350,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -24388,7 +24388,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.initial_size = 16 * 1024 * 1024 + 1; /* INVALID */ - invalid_auto_size_ctl.min_clean_fraction = 0.5f; + invalid_auto_size_ctl.min_clean_fraction = 0.5; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -24397,22 +24397,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24420,7 +24420,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -24456,7 +24456,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.initial_size = 1 * 1024 * 1024 - 1; /* INVALID */ - invalid_auto_size_ctl.min_clean_fraction = 0.5f; + invalid_auto_size_ctl.min_clean_fraction = 0.5; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -24465,22 +24465,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24488,7 +24488,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -24525,7 +24525,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 1.00001f; /* INVALID */ + invalid_auto_size_ctl.min_clean_fraction = 1.00001; /* INVALID */ invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -24534,22 +24534,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24557,7 +24557,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -24592,7 +24592,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = -0.00001f; /* INVALID */ + invalid_auto_size_ctl.min_clean_fraction = -0.00001; /* INVALID */ invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -24601,22 +24601,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24624,7 +24624,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -24661,7 +24661,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.5f; + invalid_auto_size_ctl.min_clean_fraction = 0.5; invalid_auto_size_ctl.max_size = H5C__MAX_MAX_CACHE_SIZE + 1; /* INVALID */ @@ -24671,22 +24671,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24694,7 +24694,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -24729,7 +24729,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.5f; + invalid_auto_size_ctl.min_clean_fraction = 0.5; invalid_auto_size_ctl.max_size = 1 * 1024 * 1024; /* INVALID */ invalid_auto_size_ctl.min_size = 1 * 1024 * 1024 + 1; /*PAIR */ @@ -24738,22 +24738,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24761,7 +24761,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -24796,7 +24796,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.5f; + invalid_auto_size_ctl.min_clean_fraction = 0.5; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = H5C__MIN_MAX_CACHE_SIZE - 1; @@ -24805,22 +24805,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24828,7 +24828,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -24865,7 +24865,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -24875,22 +24875,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24898,7 +24898,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -24933,7 +24933,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -24943,22 +24943,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24966,7 +24966,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25003,7 +25003,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25012,22 +25012,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = (enum H5C_cache_incr_mode) - 1; /* INVALID */ - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25035,7 +25035,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25070,7 +25070,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25079,22 +25079,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = (enum H5C_cache_incr_mode)2; /* INVALID */ - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25102,7 +25102,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25139,7 +25139,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.5f; + invalid_auto_size_ctl.min_clean_fraction = 0.5; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25148,22 +25148,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.7f; + invalid_auto_size_ctl.lower_hr_threshold = 0.7; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 1.01f; /* INVALID */ + invalid_auto_size_ctl.upper_hr_threshold = 1.01; /* INVALID */ - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25171,7 +25171,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25206,7 +25206,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.5f; + invalid_auto_size_ctl.min_clean_fraction = 0.5; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25215,22 +25215,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.8f; /* INVALID */ + invalid_auto_size_ctl.lower_hr_threshold = 0.8; /* INVALID */ - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.7f; /* INVALID */ + invalid_auto_size_ctl.upper_hr_threshold = 0.7; /* INVALID */ - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25238,7 +25238,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25273,7 +25273,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.5f; + invalid_auto_size_ctl.min_clean_fraction = 0.5; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25282,22 +25282,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = -0.0001f; /* INVALID */ + invalid_auto_size_ctl.lower_hr_threshold = -0.0001; /* INVALID */ - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25305,7 +25305,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25342,7 +25342,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25351,22 +25351,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 0.99999f; /* INVALID */ + invalid_auto_size_ctl.increment = 0.99999; /* INVALID */ invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25374,7 +25374,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25411,7 +25411,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25420,22 +25420,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = (enum H5C_cache_flash_incr_mode) - 1; /* INVALID */ - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25443,7 +25443,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25480,7 +25480,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25489,22 +25489,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__add_space; - invalid_auto_size_ctl.flash_multiple = 0.09f; /* INVALID */ - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 0.09; /* INVALID */ + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25512,7 +25512,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25547,7 +25547,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25556,22 +25556,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__add_space; - invalid_auto_size_ctl.flash_multiple = 10.01f; /* INVALID */ - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 10.01; /* INVALID */ + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25579,7 +25579,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25616,7 +25616,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25625,22 +25625,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__add_space; - invalid_auto_size_ctl.flash_multiple = 1.0f; - invalid_auto_size_ctl.flash_threshold = 0.09f; /* INVALID */ + invalid_auto_size_ctl.flash_multiple = 1.0; + invalid_auto_size_ctl.flash_threshold = 0.09; /* INVALID */ invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25648,7 +25648,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25683,7 +25683,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25692,22 +25692,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__add_space; - invalid_auto_size_ctl.flash_multiple = 1.0f; - invalid_auto_size_ctl.flash_threshold = 1.001f; /* INVALID */ + invalid_auto_size_ctl.flash_multiple = 1.0; + invalid_auto_size_ctl.flash_threshold = 1.001; /* INVALID */ invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25715,7 +25715,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25752,7 +25752,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25761,22 +25761,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = (enum H5C_cache_decr_mode) - 1; /* INVALID */ - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25784,7 +25784,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25819,7 +25819,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25828,22 +25828,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = (enum H5C_cache_decr_mode)4; /* INVALID */ - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25851,7 +25851,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25888,7 +25888,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25897,22 +25897,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 1.000001f; /* INVALID */ + invalid_auto_size_ctl.decrement = 1.000001; /* INVALID */ invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25920,7 +25920,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25955,7 +25955,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25964,22 +25964,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = -0.000001f; /* INVALID */ + invalid_auto_size_ctl.decrement = -0.000001; /* INVALID */ invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25987,7 +25987,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -26024,7 +26024,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -26033,22 +26033,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__age_out; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -26056,7 +26056,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 0; /* INVALID */ invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -26091,7 +26091,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -26100,22 +26100,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__age_out_with_threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -26123,7 +26123,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = H5C__MAX_EPOCH_MARKERS + 1; /* INVALID */ invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -26160,7 +26160,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -26169,22 +26169,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__age_out; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -26192,7 +26192,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = -0.0000001f; /* INVALID */ + invalid_auto_size_ctl.empty_reserve = -0.0000001; /* INVALID */ result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -26227,7 +26227,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -26236,22 +26236,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__age_out_with_threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -26259,7 +26259,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = H5C__MAX_EPOCH_MARKERS + 1; /* INVALID */ invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -26387,7 +26387,7 @@ check_auto_cache_resize_aux_fcns(unsigned paged) /* hbool_t set_initial_size = */ TRUE, /* size_t initial_size = */ (1 * 1024 * 1024), - /* double min_clean_fraction = */ 0.5f, + /* double min_clean_fraction = */ 0.5, /* size_t max_size = */ (16 * 1024 * 1025), /* size_t min_size = */ (512 * 1024), @@ -26396,23 +26396,23 @@ check_auto_cache_resize_aux_fcns(unsigned paged) /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__off, - /* double lower_hr_threshold = */ 0.75f, + /* double lower_hr_threshold = */ 0.75, - /* double increment = */ 2.0f, + /* double increment = */ 2.0, /* hbool_t apply_max_increment = */ TRUE, /* size_t max_increment = */ (4 * 1024 * 1024), /* enum H5C_cache_flash_incr_mode */ /* flash_incr_mode = */ H5C_flash_incr__off, - /* double flash_multiple = */ 2.0f, - /* double flash_threshold = */ 0.5f, + /* double flash_multiple = */ 2.0, + /* double flash_threshold = */ 0.5, /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__off, - /* double upper_hr_threshold = */ 0.995f, + /* double upper_hr_threshold = */ 0.995, - /* double decrement = */ 0.9f, + /* double decrement = */ 0.9, /* hbool_t apply_max_decrement = */ TRUE, /* size_t max_decrement = */ (1 * 1024 * 1024), @@ -26420,7 +26420,7 @@ check_auto_cache_resize_aux_fcns(unsigned paged) /* int32_t epochs_before_eviction = */ 3, /* hbool_t apply_empty_reserve = */ TRUE, - /* double empty_reserve = */ 0.5f + /* double empty_reserve = */ 0.5 }; if (paged) @@ -34313,7 +34313,7 @@ cedds__H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t *file_ptr) /* hbool_t set_initial_size = */ TRUE, /* size_t initial_size = */ (2 * 1024 * 1024), - /* double min_clean_fraction = */ 0.5f, + /* double min_clean_fraction = */ 0.5, /* size_t max_size = */ (8 * 1024 * 1024), /* size_t min_size = */ (1 * 1024 * 1024), @@ -34322,23 +34322,23 @@ cedds__H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t *file_ptr) /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, - /* double lower_hr_threshold = */ 0.75f, + /* double lower_hr_threshold = */ 0.75, - /* double increment = */ 2.0f, + /* double increment = */ 2.0, /* hbool_t apply_max_increment = */ TRUE, /* size_t max_increment = */ (4 * 1024 * 1024), /* enum H5C_cache_flash_incr_mode */ /* flash_incr_mode = */ H5C_flash_incr__off, - /* double flash_multiple = */ 2.0f, - /* double flash_threshold = */ 0.5f, + /* double flash_multiple = */ 2.0, + /* double flash_threshold = */ 0.5, /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out, - /* double upper_hr_threshold = */ 0.995f, + /* double upper_hr_threshold = */ 0.995, - /* double decrement = */ 0.5f, + /* double decrement = */ 0.5, /* hbool_t apply_max_decrement = */ FALSE, /* size_t max_decrement = */ (1 * 1024 * 1024), @@ -34346,7 +34346,7 @@ cedds__H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t *file_ptr) /* int32_t epochs_before_eviction = */ 1, /* hbool_t apply_empty_reserve = */ TRUE, - /* double empty_reserve = */ 0.05f}; + /* double empty_reserve = */ 0.05}; if (pass) { diff --git a/test/chunk_info.c b/test/chunk_info.c index 7104941..a1c4160 100644 --- a/test/chunk_info.c +++ b/test/chunk_info.c @@ -482,10 +482,10 @@ test_get_chunk_info_highest_v18(hid_t fapl) unsigned flt_msk = 0; /* Filter mask */ unsigned read_flt_msk = 0; /* Filter mask after direct read */ int fillvalue = -1; /* Fill value */ - int aggression = 9; /* Compression aggression setting */ hsize_t offset[2] = {0, 0}; /* Offset coordinates of a chunk */ #ifdef H5_HAVE_FILTER_DEFLATE - const Bytef *z_src = (const Bytef *)(direct_buf); + int aggression = 9; /* Compression aggression setting */ + const Bytef *z_src = (const Bytef *)(direct_buf); Bytef * z_dst; /* Destination buffer */ uLongf z_dst_nbytes = (uLongf)DEFLATE_SIZE_ADJUST(CHK_SIZE); uLong z_src_nbytes = (uLong)CHK_SIZE; @@ -568,7 +568,8 @@ test_get_chunk_info_highest_v18(hid_t fapl) } #else /* Allocate input (non-compressed) buffer */ - inbuf = HDcalloc(1, CHK_SIZE); + if (NULL == (inbuf = HDcalloc(1, CHK_SIZE))) + TEST_ERROR HDmemcpy(inbuf, direct_buf, CHK_SIZE); #endif /* end H5_HAVE_FILTER_DEFLATE */ @@ -1490,21 +1491,24 @@ typedef struct chunk_iter_info_t { uint32_t nbytes; } chunk_iter_info_t; +typedef struct chunk_iter_udata_t { + chunk_iter_info_t *chunk_info; + int last_index; +} chunk_iter_udata_t; + static int iter_cb(const hsize_t *offset, uint32_t filter_mask, haddr_t addr, uint32_t nbytes, void *op_data) { - chunk_iter_info_t **chunk_info = (chunk_iter_info_t **)op_data; + chunk_iter_udata_t *cidata = (chunk_iter_udata_t *)op_data; + int idx = cidata->last_index + 1; - (*chunk_info)->offset[0] = offset[0]; - (*chunk_info)->offset[1] = offset[1]; - (*chunk_info)->filter_mask = filter_mask; - (*chunk_info)->addr = addr; - (*chunk_info)->nbytes = nbytes; + cidata->chunk_info[idx].offset[0] = offset[0]; + cidata->chunk_info[idx].offset[1] = offset[1]; + cidata->chunk_info[idx].filter_mask = filter_mask; + cidata->chunk_info[idx].addr = addr; + cidata->chunk_info[idx].nbytes = nbytes; - /* printf("offset: [%lld, %lld], addr: %ld, size: %d, filter mask: %d\n", offset[0], offset[1], addr, - * nbytes, filter_mask); */ - - *chunk_info += 1; + cidata->last_index++; return H5_ITER_CONT; } @@ -1564,8 +1568,9 @@ test_basic_query(hid_t fapl) haddr_t addr = 0; /* Address of an allocated/written chunk */ hsize_t chk_index = 0; /* Index of a chunk */ hsize_t ii, jj; /* Array indices */ - chunk_iter_info_t chunk_infos[2]; /* chunk infos filled up by iterator */ - chunk_iter_info_t *cptr; /* pointer to array of chunks */ + chunk_iter_info_t chunk_infos[2]; /* Chunk infos filled up by iterator */ + chunk_iter_info_t *cptr; /* Pointer to array of chunks */ + chunk_iter_udata_t udata; /* udata for iteration */ herr_t ret; /* Temporary returned value for verifying failure */ TESTING("basic operations"); @@ -1674,12 +1679,13 @@ test_basic_query(hid_t fapl) if (verify_empty_chunk_info(dset, offset) == FAIL) FAIL_PUTS_ERROR("Verification of H5Dget_chunk_info_by_coord on empty chunk failed\n"); - /* iterate over all chunks */ - cptr = &(chunk_infos[0]); - if (H5Dchunk_iter(dset, &iter_cb, &cptr) < 0) + /* Iterate over all chunks */ + udata.chunk_info = chunk_infos; + udata.last_index = -1; + if (H5Dchunk_iter(dset, H5P_DEFAULT, &iter_cb, &udata) < 0) TEST_ERROR; - VERIFY(cptr, &(chunk_infos[2]), "Iterator did not iterate all chunks"); + VERIFY(udata.last_index, 1, "Iterator did not iterate all chunks"); VERIFY(chunk_infos[0].offset[0], 0, "Offset mismatch"); VERIFY(chunk_infos[0].offset[1], 0, "Offset mismatch"); VERIFY(chunk_infos[0].filter_mask, 0, "Filter mismatch"); @@ -1688,17 +1694,17 @@ test_basic_query(hid_t fapl) VERIFY(chunk_infos[1].offset[0], 1, "Offset mismatch"); VERIFY(chunk_infos[1].offset[1], 1, "Offset mismatch"); - /* iterate and stop after one iteration */ + /* Iterate and stop after one iteration */ cptr = &(chunk_infos[0]); - if (H5Dchunk_iter(dset, &iter_cb_stop, &cptr) < 0) + if (H5Dchunk_iter(dset, H5P_DEFAULT, &iter_cb_stop, &cptr) < 0) TEST_ERROR; VERIFY(cptr, &(chunk_infos[1]), "Verification of halted iterator failed\n"); - /* iterate and fail after one iteration */ + /* Iterate and fail after one iteration */ cptr = &(chunk_infos[0]); H5E_BEGIN_TRY { - ret = H5Dchunk_iter(dset, &iter_cb_fail, &cptr); + ret = H5Dchunk_iter(dset, H5P_DEFAULT, &iter_cb_fail, &cptr); } H5E_END_TRY; if (ret >= 0) diff --git a/test/cmpd_dset.c b/test/cmpd_dset.c index 4c3233d..8777096 100644 --- a/test/cmpd_dset.c +++ b/test/cmpd_dset.c @@ -110,8 +110,8 @@ typedef struct { long long r, s, t; } stype4; -#define NX 100u -#define NY 2000u +#define NX 100U +#define NY 2000U #define PACK_NMEMBS 100 /*------------------------------------------------------------------------- diff --git a/test/cve_2020_10810.h5 b/test/cve_2020_10810.h5 new file mode 100644 index 0000000..5cface3 Binary files /dev/null and b/test/cve_2020_10810.h5 differ diff --git a/test/dsets.c b/test/dsets.c index 3a17575..922f370 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -83,6 +83,8 @@ const char *FILENAME[] = {"dataset", /* 0 */ "power2up", /* 24 */ "version_bounds", /* 25 */ "alloc_0sized", /* 26 */ + "h5s_block", /* 27 */ + "h5s_plist", /* 28 */ NULL}; #define OHMIN_FILENAME_A "ohdr_min_a" @@ -1394,10 +1396,10 @@ test_conv_buffer(hid_t fid) cf->a[j][k][l] = 10 * (j + 1) + l + k; for (j = 0; j < DIM2; j++) - cf->b[j] = 100.0f * (float)(j + 1) + 0.01f * (float)j; + cf->b[j] = 100.0F * (float)(j + 1) + 0.01F * (float)j; for (j = 0; j < DIM3; j++) - cf->c[j] = 100.0f * (float)(j + 1) + 0.02f * (float)j; + cf->c[j] = 100.0F * (float)(j + 1) + 0.02F * (float)j; /* Create data space */ if ((space = H5Screate(H5S_SCALAR)) < 0) @@ -3322,8 +3324,8 @@ test_nbit_float(hid_t file) /* orig_data[] are initialized to be within the range that can be represented by * dataset datatype (no precision loss during datatype conversion) */ - float orig_data[2][5] = {{188384.0f, 19.103516f, -1.0831790e9f, -84.242188f, 5.2045898f}, - {-49140.0f, 2350.25f, -3.2110596e-1f, 6.4998865e-5f, -0.0f}}; + float orig_data[2][5] = {{188384.0F, 19.103516F, -1.0831790e9F, -84.242188F, 5.2045898F}, + {-49140.0F, 2350.25F, -3.2110596e-1F, 6.4998865e-5F, -0.0F}}; float new_data[2][5]; size_t precision, offset; size_t i, j; @@ -11640,7 +11642,7 @@ test_unfiltered_edge_chunks(hid_t fapl) TEST_ERROR /* Add "count" filter */ - if (H5Pset_filter(dcpl, H5Z_FILTER_COUNT, 0u, (size_t)0, NULL) < 0) + if (H5Pset_filter(dcpl, H5Z_FILTER_COUNT, 0U, (size_t)0, NULL) < 0) TEST_ERROR /* Disable filters on partial chunks */ @@ -14971,6 +14973,370 @@ error: } /* end test_object_header_minimization_dcpl() */ /*----------------------------------------------------------------------------- + * Function: test_h5s_block + * + * Purpose: Test the H5S_BLOCK feature. + * + * Return: Success/pass: 0 + * Failure/error: -1 + * + * Programmer: Quincey Koziol + * 3 November 2020 + * + *----------------------------------------------------------------------------- + */ +static herr_t +test_h5s_block(void) +{ + hid_t file_id = H5I_INVALID_HID; /* File ID */ + char filename[FILENAME_BUF_SIZE] = ""; + hid_t dset_id = H5I_INVALID_HID; /* Dataset ID */ + hsize_t dims[1] = {20}; /* Dataset's dataspace size */ + hsize_t start = 2; /* Starting offset of hyperslab selection */ + hsize_t count = 10; /* Count of hyperslab selection */ + hid_t file_space_id = H5I_INVALID_HID; /* File dataspace ID */ + int buf[20]; /* Memory buffer for I/O */ + unsigned u; /* Local index variable */ + herr_t ret; + + TESTING("contiguous memory buffers with H5S_BLOCK"); + + /*********/ + /* SETUP */ + /*********/ + if (NULL == h5_fixname(FILENAME[27], H5P_DEFAULT, filename, sizeof(filename))) + TEST_ERROR + if (H5I_INVALID_HID == (file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT))) + FAIL_STACK_ERROR + if ((file_space_id = H5Screate_simple(1, dims, NULL)) < 0) + FAIL_STACK_ERROR + if ((dset_id = H5Dcreate2(file_id, "dset", H5T_NATIVE_INT, file_space_id, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + + for (u = 0; u < 20; u++) + buf[u] = (int)u; + + /*********/ + /* TESTS */ + /*********/ + + /* Check error cases */ + H5E_BEGIN_TRY + { + ret = H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_BLOCK, H5P_DEFAULT, buf); + } + H5E_END_TRY; + if (ret == SUCCEED) + TEST_ERROR + + /* Write the entire dataset */ + if (H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_ALL, H5P_DEFAULT, buf) < 0) + FAIL_STACK_ERROR + + /* Reset the memory buffer */ + HDmemset(buf, 0, sizeof(buf)); + + /* Read the entire dataset */ + if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_ALL, H5P_DEFAULT, buf) < 0) + FAIL_STACK_ERROR + + /* Verify the data read in */ + for (u = 0; u < 20; u++) + if (buf[u] != (int)u) + TEST_ERROR + + /* Read a hyperslab from the file to the first 10 elements of the buffer */ + if (H5Sselect_hyperslab(file_space_id, H5S_SELECT_SET, &start, NULL, &count, NULL) < 0) + FAIL_STACK_ERROR + if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, file_space_id, H5P_DEFAULT, buf) < 0) + FAIL_STACK_ERROR + + /* Verify the data read in */ + for (u = 0; u < count; u++) + if (buf[u] != (int)(u + start)) + TEST_ERROR + + /* Verify that reading 0 elements is handled correctly and doesn't modify buffer */ + if (H5Sselect_none(file_space_id) < 0) + FAIL_STACK_ERROR + if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, file_space_id, H5P_DEFAULT, buf) < 0) + FAIL_STACK_ERROR + + /* Verify the data read in */ + for (u = 0; u < count; u++) + if (buf[u] != (int)(u + start)) + TEST_ERROR + + /************/ + /* TEARDOWN */ + /************/ + if (FAIL == H5Sclose(file_space_id)) + FAIL_STACK_ERROR + if (FAIL == H5Dclose(dset_id)) + FAIL_STACK_ERROR + if (FAIL == H5Fclose(file_id)) + FAIL_STACK_ERROR + + PASSED(); + + return SUCCEED; + +error: + H5E_BEGIN_TRY + { + H5Sclose(file_space_id); + H5Dclose(dset_id); + H5Fclose(file_id); + } + H5E_END_TRY; + + return FAIL; +} /* end test_h5s_block() */ + +/*----------------------------------------------------------------------------- + * Function: test_h5s_plist + * + * Purpose: Test the H5S_PLIST feature. + * + * Return: Success/pass: 0 + * Failure/error: -1 + * + * Programmer: Quincey Koziol + * 28 January 2021 + * + *----------------------------------------------------------------------------- + */ +static herr_t +test_h5s_plist(void) +{ + hid_t file_id = H5I_INVALID_HID; /* File ID */ + char filename[FILENAME_BUF_SIZE] = ""; + hid_t dset_id = H5I_INVALID_HID; /* Dataset ID */ + hsize_t dims[1] = {20}; /* Dataset's dataspace size */ + hid_t dxpl_id = H5I_INVALID_HID; /* Dataset xfer property list ID */ + hid_t dxpl_id_copy = H5I_INVALID_HID; /* Copy of dataset xfer property list ID */ + hsize_t start = 2; /* Starting offset of hyperslab selection */ + hsize_t stride = 1; /* Stride of hyperslab selection */ + hsize_t count = 10; /* Count of hyperslab selection */ + hsize_t start2 = 14; /* Starting offset of hyperslab selection */ + hsize_t count2 = 4; /* Count of hyperslab selection */ + hsize_t block = 1; /* Block size of hyperslab selection */ + hid_t file_space_id = H5I_INVALID_HID; /* File dataspace ID */ + int buf[20]; /* Memory buffer for I/O */ + unsigned u; /* Local index variable */ + herr_t ret; + + TESTING("dataset's dataspace selection for I/O in DXPL with H5S_PLIST"); + + /*********/ + /* SETUP */ + /*********/ + if (NULL == h5_fixname(FILENAME[28], H5P_DEFAULT, filename, sizeof(filename))) + TEST_ERROR + if (H5I_INVALID_HID == (file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT))) + FAIL_STACK_ERROR + if ((file_space_id = H5Screate_simple(1, dims, NULL)) < 0) + FAIL_STACK_ERROR + if ((dset_id = H5Dcreate2(file_id, "dset", H5T_NATIVE_INT, file_space_id, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + if ((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) + FAIL_STACK_ERROR + + for (u = 0; u < 20; u++) + buf[u] = (int)u; + + /*********/ + /* TESTS */ + /*********/ + + /* Check error cases */ + H5E_BEGIN_TRY + { + /* Bad rank */ + ret = H5Pset_dataset_io_hyperslab_selection(dxpl_id, 0, H5S_SELECT_SET, &start, &stride, &count, + &block); + } + H5E_END_TRY; + if (ret == SUCCEED) + TEST_ERROR + H5E_BEGIN_TRY + { + /* Bad selection operator */ + ret = H5Pset_dataset_io_hyperslab_selection(dxpl_id, 1, H5S_SELECT_NOOP, &start, &stride, &count, + &block); + } + H5E_END_TRY; + if (ret == SUCCEED) + TEST_ERROR + H5E_BEGIN_TRY + { + /* Bad start pointer */ + ret = + H5Pset_dataset_io_hyperslab_selection(dxpl_id, 1, H5S_SELECT_SET, NULL, &stride, &count, &block); + } + H5E_END_TRY; + if (ret == SUCCEED) + TEST_ERROR + H5E_BEGIN_TRY + { + /* Bad stride value (stride of NULL is OK) */ + stride = 0; + ret = H5Pset_dataset_io_hyperslab_selection(dxpl_id, 1, H5S_SELECT_SET, &start, &stride, &count, + &block); + stride = 1; + } + H5E_END_TRY; + if (ret == SUCCEED) + TEST_ERROR + H5E_BEGIN_TRY + { + /* Bad count pointer */ + ret = + H5Pset_dataset_io_hyperslab_selection(dxpl_id, 1, H5S_SELECT_SET, &start, &stride, NULL, &block); + } + H5E_END_TRY; + if (ret == SUCCEED) + TEST_ERROR + + /* Block pointer is allowed to be NULL */ + + H5E_BEGIN_TRY + { + /* H5S_PLIST for memory dataspace */ + ret = H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_PLIST, H5S_ALL, H5P_DEFAULT, buf); + } + H5E_END_TRY; + if (ret == SUCCEED) + TEST_ERROR + + /* Write the entire dataset */ + if (H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_ALL, H5P_DEFAULT, buf) < 0) + FAIL_STACK_ERROR + + /* Reset the memory buffer */ + HDmemset(buf, 0, sizeof(buf)); + + /* Read the entire dataset */ + if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_ALL, H5P_DEFAULT, buf) < 0) + FAIL_STACK_ERROR + + /* Verify the data read in */ + for (u = 0; u < 20; u++) + if (buf[u] != (int)u) + TEST_ERROR + + /* Reset the memory buffer */ + HDmemset(buf, 0, sizeof(buf)); + + /* Set valid selection in DXPL */ + if (H5Pset_dataset_io_hyperslab_selection(dxpl_id, 1, H5S_SELECT_SET, &start, &stride, &count, &block) < + 0) + FAIL_STACK_ERROR + + /* Read a hyperslab from the file to the first 10 elements of the buffer */ + if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_PLIST, dxpl_id, buf) < 0) + FAIL_STACK_ERROR + + /* Verify the data read in */ + for (u = 0; u < count; u++) + if (buf[u] != (int)(u + start)) + TEST_ERROR + + /* Reset the memory buffer */ + HDmemset(buf, 0, sizeof(buf)); + + /* Check for copying property list w/selection */ + if ((dxpl_id_copy = H5Pcopy(dxpl_id)) < 0) + FAIL_STACK_ERROR + + /* Read a hyperslab from the file to the first 10 elements of the buffer */ + if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_PLIST, dxpl_id_copy, buf) < 0) + FAIL_STACK_ERROR + + /* Verify the data read in */ + for (u = 0; u < count; u++) + if (buf[u] != (int)(u + start)) + TEST_ERROR + + /* Attempt to 'OR' block with invalid dimensions into the selection */ + H5E_BEGIN_TRY + { + ret = H5Pset_dataset_io_hyperslab_selection(dxpl_id_copy, 2, H5S_SELECT_OR, &start, &stride, &count, + &block); + } + H5E_END_TRY; + if (ret == SUCCEED) + TEST_ERROR + + /* Set new valid selection in DXPL */ + if (H5Pset_dataset_io_hyperslab_selection(dxpl_id_copy, 1, H5S_SELECT_SET, &start, &stride, &count, + &block) < 0) + FAIL_STACK_ERROR + + /* Read a hyperslab from the file to the first 10 elements of the buffer */ + if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_PLIST, dxpl_id_copy, buf) < 0) + FAIL_STACK_ERROR + + /* Verify the data read in */ + for (u = 0; u < count; u++) + if (buf[u] != (int)(u + start)) + TEST_ERROR + + /* Close the copy */ + if (FAIL == H5Pclose(dxpl_id_copy)) + FAIL_STACK_ERROR + dxpl_id_copy = H5I_INVALID_HID; + + /* 'OR' valid block into the existing selection in original DXPL */ + if (H5Pset_dataset_io_hyperslab_selection(dxpl_id, 1, H5S_SELECT_OR, &start2, &stride, &count2, &block) < + 0) + FAIL_STACK_ERROR + + /* Read a disjoint hyperslab from the file to the first 10 elements of the buffer */ + if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_PLIST, dxpl_id, buf) < 0) + FAIL_STACK_ERROR + + /* Verify the data read in */ + for (u = 0; u < count; u++) + if (buf[u] != (int)(u + start)) + TEST_ERROR + for (u = 0; u < count2; u++) + if (buf[u + count] != (int)(u + start2)) + TEST_ERROR + + /************/ + /* TEARDOWN */ + /************/ + if (FAIL == H5Pclose(dxpl_id)) + FAIL_STACK_ERROR + if (FAIL == H5Sclose(file_space_id)) + FAIL_STACK_ERROR + if (FAIL == H5Dclose(dset_id)) + FAIL_STACK_ERROR + if (FAIL == H5Fclose(file_id)) + FAIL_STACK_ERROR + + PASSED(); + + return SUCCEED; + +error: + H5E_BEGIN_TRY + { + H5Pclose(dxpl_id_copy); + H5Pclose(dxpl_id); + H5Sclose(file_space_id); + H5Dclose(dset_id); + H5Fclose(file_id); + } + H5E_END_TRY; + + return FAIL; +} /* end test_h5s_plist() */ + +/*----------------------------------------------------------------------------- * Function: test_0sized_dset_metadata_alloc * * Purpose: Tests the metadata allocation for 0-sized datasets. @@ -15417,6 +15783,8 @@ main(void) /* Tests that use their own file */ nerrors += (test_object_header_minimization_dcpl() < 0 ? 1 : 0); + nerrors += (test_h5s_block() < 0 ? 1 : 0); + nerrors += (test_h5s_plist() < 0 ? 1 : 0); /* Run misc tests */ nerrors += (dls_01_main() < 0 ? 1 : 0); diff --git a/test/dt_arith.c b/test/dt_arith.c index 7b79102..91e31d5 100644 --- a/test/dt_arith.c +++ b/test/dt_arith.c @@ -53,7 +53,7 @@ const char *FILENAME[] = {"dt_arith1", "dt_arith2", NULL}; * endian. If local variable `endian' is H5T_ORDER_BE then the result will * be I, otherwise the result will be Z-(I+1). */ -#define ENDIAN(Z, I, E) (H5T_ORDER_BE == E ? (I) : (Z) - ((I) + 1)) +#define ENDIAN(Z, I, E) (H5T_ORDER_BE == (E) ? (I) : (Z) - ((I) + 1)) typedef enum dtype_t { INT_SCHAR, @@ -3058,10 +3058,10 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) /* Check the software results against the hardware */ for (j = 0; j < nelmts; j++) { underflow = 0; - hw_f = 911.0f; - hw_d = 911.0f; + hw_f = 911.0F; + hw_d = 911.0F; #if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE - hw_ld = 911.0f; + hw_ld = 911.0L; #endif /* The hardware conversion */ diff --git a/test/dtransform.c b/test/dtransform.c index 9445d83..743103f 100644 --- a/test/dtransform.c +++ b/test/dtransform.c @@ -32,30 +32,30 @@ hid_t dset_id_int_chunk = -1; hid_t dset_id_float_chunk = -1; const float windchillFfloat[ROWS][COLS] = { - {36.0f, 31.0f, 25.0f, 19.0f, 13.0f, 7.0f, 1.0f, -5.0f, -11.0f, -16.0f, -22.0f, -28.0f, -34.0f, -40.0f, - -46.0f, -52.0f, -57.0f, -63.0f}, - {34.0f, 27.0f, 21.0f, 15.0f, 9.0f, 3.0f, -4.0f, -10.0f, -16.0f, -22.0f, -28.0f, -35.0f, -41.0f, -47.0f, - -53.0f, -59.0f, -66.0f, -72.0f}, - {32.0f, 25.0f, 19.0f, 13.0f, 6.0f, 0.0f, -7.0f, -13.0f, -19.0f, -26.0f, -32.0f, -39.0f, -45.0f, -51.0f, - -58.0f, -64.0f, -71.0f, -77.0f}, - {30.0f, 24.0f, 17.0f, 11.0f, 4.0f, -2.0f, -9.0f, -15.0f, -22.0f, -29.0f, -35.0f, -42.0f, -48.0f, -55.0f, - -61.0f, -68.0f, -74.0f, -81.0f}, - {29.0f, 23.0f, 16.0f, 9.0f, 3.0f, -4.0f, -11.0f, -17.0f, -24.0f, -31.0f, -37.0f, -44.0f, -51.0f, -58.0f, - -64.0f, -71.0f, -78.0f, -84.0f}, - {28.0f, 22.0f, 15.0f, 8.0f, 1.0f, -5.0f, -12.0f, -19.0f, -26.0f, -33.0f, -39.0f, -46.0f, -53.0f, -60.0f, - -67.0f, -73.0f, -80.0f, -87.0f}, - {28.0f, 21.0f, 14.0f, 7.0f, 0.0f, -7.0f, -14.0f, -21.0f, -27.0f, -34.0f, -41.0f, -48.0f, -55.0f, -62.0f, - -69.0f, -76.0f, -82.0f, -89.0f}, - {27.0f, 20.0f, 13.0f, 6.0f, -1.0f, -8.0f, -15.0f, -22.0f, -29.0f, -36.0f, -43.0f, -50.0f, -57.0f, -64.0f, - -71.0f, -78.0f, -84.0f, -91.0f}, - {26.0f, 19.0f, 12.0f, 5.0f, -2.0f, -9.0f, -16.0f, -23.0f, -30.0f, -37.0f, -44.0f, -51.0f, -58.0f, -65.0f, - -72.0f, -79.0f, -86.0f, -93.0f}, - {26.0f, 19.0f, 12.0f, 4.0f, -3.0f, -10.0f, -17.0f, -24.0f, -31.0f, -38.0f, -45.0f, -52.0f, -60.0f, -67.0f, - -74.0f, -81.0f, -88.0f, -95.0f}, - {25.0f, 18.0f, 11.0f, 4.0f, -3.0f, -11.0f, -18.0f, -25.0f, -32.0f, -39.0f, -46.0f, -54.0f, -61.0f, -68.0f, - -75.0f, -82.0f, -89.0f, -97.0f}, - {25.0f, 17.0f, 10.0f, 3.0f, -4.0f, -11.0f, -19.0f, -26.0f, -33.0f, -40.0f, -48.0f, -55.0f, -62.0f, -69.0f, - -76.0f, -84.0f, -91.0f, -98.0f}}; + {36.0F, 31.0F, 25.0F, 19.0F, 13.0F, 7.0F, 1.0F, -5.0F, -11.0F, -16.0F, -22.0F, -28.0F, -34.0F, -40.0F, + -46.0F, -52.0F, -57.0F, -63.0F}, + {34.0F, 27.0F, 21.0F, 15.0F, 9.0F, 3.0F, -4.0F, -10.0F, -16.0F, -22.0F, -28.0F, -35.0F, -41.0F, -47.0F, + -53.0F, -59.0F, -66.0F, -72.0F}, + {32.0F, 25.0F, 19.0F, 13.0F, 6.0F, 0.0F, -7.0F, -13.0F, -19.0F, -26.0F, -32.0F, -39.0F, -45.0F, -51.0F, + -58.0F, -64.0F, -71.0F, -77.0F}, + {30.0F, 24.0F, 17.0F, 11.0F, 4.0F, -2.0F, -9.0F, -15.0F, -22.0F, -29.0F, -35.0F, -42.0F, -48.0F, -55.0F, + -61.0F, -68.0F, -74.0F, -81.0F}, + {29.0F, 23.0F, 16.0F, 9.0F, 3.0F, -4.0F, -11.0F, -17.0F, -24.0F, -31.0F, -37.0F, -44.0F, -51.0F, -58.0F, + -64.0F, -71.0F, -78.0F, -84.0F}, + {28.0F, 22.0F, 15.0F, 8.0F, 1.0F, -5.0F, -12.0F, -19.0F, -26.0F, -33.0F, -39.0F, -46.0F, -53.0F, -60.0F, + -67.0F, -73.0F, -80.0F, -87.0F}, + {28.0F, 21.0F, 14.0F, 7.0F, 0.0F, -7.0F, -14.0F, -21.0F, -27.0F, -34.0F, -41.0F, -48.0F, -55.0F, -62.0F, + -69.0F, -76.0F, -82.0F, -89.0F}, + {27.0F, 20.0F, 13.0F, 6.0F, -1.0F, -8.0F, -15.0F, -22.0F, -29.0F, -36.0F, -43.0F, -50.0F, -57.0F, -64.0F, + -71.0F, -78.0F, -84.0F, -91.0F}, + {26.0F, 19.0F, 12.0F, 5.0F, -2.0F, -9.0F, -16.0F, -23.0F, -30.0F, -37.0F, -44.0F, -51.0F, -58.0F, -65.0F, + -72.0F, -79.0F, -86.0F, -93.0F}, + {26.0F, 19.0F, 12.0F, 4.0F, -3.0F, -10.0F, -17.0F, -24.0F, -31.0F, -38.0F, -45.0F, -52.0F, -60.0F, -67.0F, + -74.0F, -81.0F, -88.0F, -95.0F}, + {25.0F, 18.0F, 11.0F, 4.0F, -3.0F, -11.0F, -18.0F, -25.0F, -32.0F, -39.0F, -46.0F, -54.0F, -61.0F, -68.0F, + -75.0F, -82.0F, -89.0F, -97.0F}, + {25.0F, 17.0F, 10.0F, 3.0F, -4.0F, -11.0F, -19.0F, -26.0F, -33.0F, -40.0F, -48.0F, -55.0F, -62.0F, -69.0F, + -76.0F, -84.0F, -91.0F, -98.0F}}; const int transformData[ROWS][COLS] = {{36, 31, 25, 19, 13, 7, 1, 5, 11, 16, 22, 28, 34, 40, 46, 52, 57, 63}, {34, 27, 21, 15, 9, 3, 4, 10, 16, 22, 28, 35, 41, 47, 53, 59, 66, 1}, @@ -77,9 +77,9 @@ const int transformData[ROWS][COLS] = {{36, 31, 25, 19, 13, 7, 1, 5, 11, 16, 22, for (i = 0; i < ROWS; i++) \ for (j = 0; j < COLS; j++) { \ if (!((((VAR1)[i][j] >= (TYPE)((VAR2)[i][j])) && \ - (((VAR1)[i][j] - TOL) < (TYPE)((VAR2)[i][j]))) || \ + (((VAR1)[i][j] - (TOL)) < (TYPE)((VAR2)[i][j]))) || \ (((VAR1)[i][j] <= (TYPE)((VAR2)[i][j])) && \ - (((VAR1)[i][j] + TOL) > (TYPE)((VAR2)[i][j]))))) { \ + (((VAR1)[i][j] + (TOL)) > (TYPE)((VAR2)[i][j]))))) { \ H5_FAILED(); \ HDfprintf(stderr, " ERROR: Conversion failed to match computed data\n"); \ goto error; \ @@ -94,8 +94,8 @@ const int transformData[ROWS][COLS] = {{36, 31, 25, 19, 13, 7, 1, 5, 11, 16, 22, \ for (i = 0; i < ROWS; i++) \ for (j = 0; j < COLS; j++) { \ - if (!(((VAR1)[i][j] <= ((TYPE)(VAR2)[i][j] + TOL)) && \ - ((VAR1)[i][j] >= ((TYPE)(VAR2)[i][j] - TOL)))) { \ + if (!(((VAR1)[i][j] <= ((TYPE)(VAR2)[i][j] + (TOL))) && \ + ((VAR1)[i][j] >= ((TYPE)(VAR2)[i][j] - (TOL))))) { \ H5_FAILED(); \ HDfprintf(stderr, " ERROR: Conversion failed to match computed data\n"); \ goto error; \ @@ -540,19 +540,19 @@ test_poly(const hid_t dxpl_id_polynomial) for (row = 0; row < ROWS; row++) for (col = 0; col < COLS; col++) { - windchillC = (int)((5.0f / 9.0f) * (windchillFfloat[row][col] - 32)); - polyflres[row][col] = ((2.0f + (float)windchillC) * (((float)windchillC - 8.0f) / 2.0f)); + windchillC = (int)((5.0F / 9.0F) * (windchillFfloat[row][col] - 32)); + polyflres[row][col] = ((2.0F + (float)windchillC) * (((float)windchillC - 8.0F) / 2.0F)); } TESTING("data transform, polynomial transform (int->float)") if (H5Dread(dset_id_int, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, dxpl_id_polynomial, polyflread) < 0) TEST_ERROR - COMPARE(float, polyflread, polyflres, 2.0f) + COMPARE(float, polyflread, polyflres, 2.0F) for (row = 0; row < ROWS; row++) for (col = 0; col < COLS; col++) { - windchillC = (int)((5.0f / 9.0f) * (windchillFfloat[row][col] - 32)); + windchillC = (int)((5.0F / 9.0F) * (windchillFfloat[row][col] - 32)); polyflres[row][col] = (float)((2 + windchillC) * ((windchillC - 8) / 2)); } @@ -582,6 +582,7 @@ test_specials(hid_t file) const char *special4 = "-x"; const char *special5 = "+x"; const char *special6 = "2e+1*x"; + const char *special7 = "x"; TESTING("data transform of some special cases") @@ -729,6 +730,32 @@ test_specials(hid_t file) if (H5Dclose(dset_id) < 0) TEST_ERROR + /*----------------------------- + * Operation 7: x + * This operation will be + * treated if no function has + * been specified. + *----------------------------*/ + if (H5Pset_data_transform(dxpl_id, special7) < 0) + TEST_ERROR; + + for (row = 0; row < ROWS; row++) + for (col = 0; col < COLS; col++) + data_res[row][col] = transformData[row][col]; + + if ((dset_id = H5Dcreate2(file, "/special7", H5T_NATIVE_INT, dataspace, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) + TEST_ERROR + if (H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl_id, transformData) < 0) + TEST_ERROR + if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, read_buf) < 0) + TEST_ERROR + + COMPARE_INT(read_buf, data_res) + + if (H5Dclose(dset_id) < 0) + TEST_ERROR + if (H5Pclose(dxpl_id) < 0) TEST_ERROR if (H5Sclose(dataspace) < 0) @@ -752,7 +779,7 @@ test_copy(const hid_t dxpl_id_c_to_f_copy, const hid_t dxpl_id_polynomial_copy) for (row = 0; row < ROWS; row++) for (col = 0; col < COLS; col++) { - windchillC = (int)((5.0f / 9.0f) * (windchillFfloat[row][col] - 32)); + windchillC = (int)((5.0F / 9.0F) * (windchillFfloat[row][col] - 32)); polyflres[row][col] = (float)((2 + windchillC) * ((windchillC - 8) / 2)); } @@ -786,7 +813,7 @@ test_trivial(const hid_t dxpl_id_simple) TEST_ERROR for (row = 0; row < ROWS; row++) for (col = 0; col < COLS; col++) { - if ((windchillFfloatread[row][col] - 4.8f) > FLOAT_TOL) + if ((windchillFfloatread[row][col] - 4.8F) > FLOAT_TOL) FAIL_PUTS_ERROR(" ERROR: Conversion failed to match computed data\n"); } @@ -843,7 +870,7 @@ test_getset(const hid_t dxpl_id_c_to_f) for (row = 0; row < ROWS; row++) for (col = 0; col < COLS; col++) { - if ((windchillFfloatread[row][col] - 4.8f) > FLOAT_TOL) + if ((windchillFfloatread[row][col] - 4.8F) > FLOAT_TOL) FAIL_PUTS_ERROR(" ERROR: Conversion failed to match computed data\n") } diff --git a/test/dtypes.c b/test/dtypes.c index 2a18302..8b3101c 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -70,7 +70,7 @@ FAIL_STACK_ERROR \ if ((NMEMBS) != H5I_nmembers(H5I_DATATYPE)) { \ H5_FAILED(); \ - HDprintf(" #dtype ids expected: %lld; found: %lld\n", (long long)NMEMBS, \ + HDprintf(" #dtype ids expected: %lld; found: %lld\n", (long long)(NMEMBS), \ (long long)H5I_nmembers(H5I_DATATYPE)); \ goto error; \ } @@ -6683,13 +6683,13 @@ static int test_int_float_except(void) { #if H5_SIZEOF_INT == 4 && H5_SIZEOF_FLOAT == 4 - float buf[CONVERT_SIZE] = {(float)INT_MIN - 172.0f, (float)INT_MAX - 32.0f, (float)INT_MAX - 68.0f, - (float)4.5f}; + float buf[CONVERT_SIZE] = {(float)INT_MIN - 172.0F, (float)INT_MAX - 32.0F, (float)INT_MAX - 68.0F, + (float)4.5F}; int buf_int[CONVERT_SIZE] = {INT_MIN, INT_MAX, INT_MAX - 127, 4}; - float buf_float[CONVERT_SIZE] = {(float)INT_MIN, (float)INT_MAX + 1.0f, (float)INT_MAX - 127.0f, 4}; + float buf_float[CONVERT_SIZE] = {(float)INT_MIN, (float)INT_MAX + 1.0F, (float)INT_MAX - 127.0F, 4}; int * intp; /* Pointer to buffer, as integers */ int buf2[CONVERT_SIZE] = {INT_MIN, INT_MAX, INT_MAX - 72, 0}; - float buf2_float[CONVERT_SIZE] = {(float)INT_MIN, (float)INT_MAX, (float)INT_MAX - 127.0f, (float)0.0f}; + float buf2_float[CONVERT_SIZE] = {(float)INT_MIN, (float)INT_MAX, (float)INT_MAX - 127.0F, (float)0.0F}; int buf2_int[CONVERT_SIZE] = {INT_MIN, INT_MAX, INT_MAX - 127, 0}; float *floatp; /* Pointer to buffer #2, as floats */ hid_t dxpl; /* Dataset transfer property list */ diff --git a/test/enc_dec_plist.c b/test/enc_dec_plist.c index 9b4879e..60b229a 100644 --- a/test/enc_dec_plist.c +++ b/test/enc_dec_plist.c @@ -350,7 +350,7 @@ main(void) TESTING("DXPL Encoding/Decoding"); - if ((H5Pset_btree_ratios(dxpl, 0.2f, 0.6f, 0.2f)) < 0) + if ((H5Pset_btree_ratios(dxpl, 0.2, 0.6, 0.2)) < 0) FAIL_STACK_ERROR if ((H5Pset_hyper_vector_size(dxpl, 5)) < 0) FAIL_STACK_ERROR @@ -544,7 +544,7 @@ main(void) FAIL_STACK_ERROR if ((H5Pset_alignment(fapl, 2, 1024)) < 0) FAIL_STACK_ERROR - if ((H5Pset_cache(fapl, 1024, 128, 10485760, 0.3f)) < 0) + if ((H5Pset_cache(fapl, 1024, 128, 10485760, 0.3)) < 0) FAIL_STACK_ERROR if ((H5Pset_elink_file_cache_size(fapl, 10485760)) < 0) FAIL_STACK_ERROR diff --git a/test/error_test.c b/test/error_test.c index cf1e82c..f4dc340 100644 --- a/test/error_test.c +++ b/test/error_test.c @@ -319,7 +319,7 @@ long_desc_cb(unsigned H5_ATTR_UNUSED n, const H5E_error2_t *err_desc, void *clie * 'full_desc' in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("format-nonliteral") +H5_GCC_CLANG_DIAG_OFF("format-nonliteral") static herr_t test_long_desc(void) { @@ -375,7 +375,7 @@ error: return -1; } /* end test_long_desc() */ -H5_GCC_DIAG_ON("format-nonliteral") +H5_GCC_CLANG_DIAG_ON("format-nonliteral") /*------------------------------------------------------------------------- * Function: dump_error diff --git a/test/event_set.c b/test/event_set.c index 6568663..5df49e9 100644 --- a/test/event_set.c +++ b/test/event_set.c @@ -94,6 +94,71 @@ error: } /*------------------------------------------------------------------------- + * Function: test_es_none + * + * Purpose: Tests for passing H5ES_NONE to H5ES routines + * + * Return: Success: 0 + * Failure: number of errors + * + * Programmer: Quincey Koziol + * Friday, February 26, 2021 + * + *------------------------------------------------------------------------- + */ +static int +test_es_none(void) +{ + TESTING("event set H5ES_NONE"); + + /* Wait */ + if (H5ESwait(H5ES_NONE, 0, NULL, NULL) < 0) + TEST_ERROR; + + /* Cancel */ + if (H5EScancel(H5ES_NONE, NULL, NULL) < 0) + TEST_ERROR; + + /* Get count */ + if (H5ESget_count(H5ES_NONE, NULL) < 0) + TEST_ERROR; + + /* Get op counter */ + if (H5ESget_op_counter(H5ES_NONE, NULL) < 0) + TEST_ERROR; + + /* Get error status */ + if (H5ESget_err_status(H5ES_NONE, NULL) < 0) + TEST_ERROR; + + /* Get error count */ + if (H5ESget_err_count(H5ES_NONE, NULL) < 0) + TEST_ERROR; + + /* Get error info */ + if (H5ESget_err_info(H5ES_NONE, 0, NULL, NULL) < 0) + TEST_ERROR; + + /* Register insert function */ + if (H5ESregister_insert_func(H5ES_NONE, NULL, NULL) < 0) + TEST_ERROR; + + /* Register complete function */ + if (H5ESregister_complete_func(H5ES_NONE, NULL, NULL) < 0) + TEST_ERROR; + + /* Close */ + if (H5ESclose(H5ES_NONE) < 0) + TEST_ERROR; + + PASSED(); + return 0; + +error: + return 1; +} + +/*------------------------------------------------------------------------- * Function: main * * Purpose: Tests event sets @@ -118,6 +183,7 @@ main(void) /* Tests */ nerrors += test_es_create(); + nerrors += test_es_none(); /* Cleanup */ h5_cleanup(FILENAME, fapl_id); diff --git a/test/fheap.c b/test/fheap.c index cb9c080..86a555d 100644 --- a/test/fheap.c +++ b/test/fheap.c @@ -553,7 +553,7 @@ get_fill_size(const fheap_test_param_t *tparam) * test_desc in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("format-nonliteral") +H5_GCC_CLANG_DIAG_OFF("format-nonliteral") static int begin_test(fheap_test_param_t *tparam, const char *base_desc, fheap_heap_ids_t *keep_ids, size_t *fill_size) { @@ -581,7 +581,7 @@ begin_test(fheap_test_param_t *tparam, const char *base_desc, fheap_heap_ids_t * /* Success */ return (0); } /* end begin_test() */ -H5_GCC_DIAG_ON("format-nonliteral") +H5_GCC_CLANG_DIAG_ON("format-nonliteral") /*------------------------------------------------------------------------- * Function: reopen_file diff --git a/test/file_image.c b/test/file_image.c index 0373468..0d031f5 100644 --- a/test/file_image.c +++ b/test/file_image.c @@ -712,7 +712,7 @@ error: * 'member_file_name' in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("format-nonliteral") +H5_GCC_CLANG_DIAG_OFF("format-nonliteral") static int test_get_file_image(const char *test_banner, const int file_name_num, hid_t fapl, hbool_t user) { @@ -976,7 +976,7 @@ test_get_file_image(const char *test_banner, const int file_name_num, hid_t fapl error: return 1; } /* end test_get_file_image() */ -H5_GCC_DIAG_ON("format-nonliteral") +H5_GCC_CLANG_DIAG_ON("format-nonliteral") /****************************************************************************** * Function: test_get_file_image_error_rejection diff --git a/test/fillval.c b/test/fillval.c index 4215c89..8de6ef1 100644 --- a/test/fillval.c +++ b/test/fillval.c @@ -1050,7 +1050,7 @@ test_rdwr_cases(hid_t file, hid_t dcpl, const char *dname, void *_fillval, H5D_f for (u = 0; u < nelmts; u++) { buf_c[u].a = 1111.11F; buf_c[u].x = 2222; - buf_c[u].y = 3333.3333F; + buf_c[u].y = 3333.3333; buf_c[u].z = 'd'; } if (H5Dwrite(dset2, ctype_id, mspace, fspace, H5P_DEFAULT, buf_c) < 0) @@ -1304,7 +1304,7 @@ test_rdwr(hid_t fapl, const char *base_name, H5D_layout_t layout) if (H5Pset_fill_time(dcpl, H5D_FILL_TIME_ALLOC) < 0) goto error; HDmemset(&fill_ctype, 0, sizeof(fill_ctype)); - fill_ctype.y = 4444.4444F; + fill_ctype.y = 4444.4444; if (H5Pset_fill_value(dcpl, ctype_id, &fill_ctype) < 0) goto error; nerrors += test_rdwr_cases(file, dcpl, "dset11", &fill_ctype, H5D_FILL_TIME_ALLOC, layout, @@ -1370,7 +1370,7 @@ test_rdwr(hid_t fapl, const char *base_name, H5D_layout_t layout) if (H5Pset_fill_time(dcpl, H5D_FILL_TIME_ALLOC) < 0) goto error; HDmemset(&fill_ctype, 0, sizeof(fill_ctype)); - fill_ctype.y = 4444.4444F; + fill_ctype.y = 4444.4444; if (H5Pset_fill_value(dcpl, ctype_id, &fill_ctype) < 0) goto error; nerrors += test_rdwr_cases(file, dcpl, "dset12", &fill_ctype, H5D_FILL_TIME_ALLOC, layout, H5T_COMPOUND, diff --git a/test/gheap.c b/test/gheap.c index 95594ee..567fd65 100644 --- a/test/gheap.c +++ b/test/gheap.c @@ -503,7 +503,7 @@ test_ooo_indices(hid_t fapl) GHEAP_REPEATED_ERR(" Unable to insert object into global heap") /* Check that the index is as expected */ - if (obj[j].idx != ((1000 * i) + j - (1000 * ((~i & 1)))) % ((1u << 16) - 1) + 1) + if (obj[j].idx != ((1000 * i) + j - (1000 * ((~i & 1)))) % ((1U << 16) - 1) + 1) GHEAP_REPEATED_ERR(" Unexpected global heap index"); } diff --git a/test/h5test.c b/test/h5test.c index 755ae93..09fb5b5 100644 --- a/test/h5test.c +++ b/test/h5test.c @@ -1305,7 +1305,7 @@ h5_dump_info_object(MPI_Info info) * temp in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("format-nonliteral") +H5_GCC_CLANG_DIAG_OFF("format-nonliteral") h5_stat_size_t h5_get_file_size(const char *filename, hid_t fapl) { @@ -1410,7 +1410,7 @@ h5_get_file_size(const char *filename, hid_t fapl) return (-1); } /* end get_file_size() */ -H5_GCC_DIAG_ON("format-nonliteral") +H5_GCC_CLANG_DIAG_ON("format-nonliteral") /* * This routine is designed to provide equivalent functionality to 'printf' diff --git a/test/hyperslab.c b/test/hyperslab.c index 1f57e3b..1c55259 100644 --- a/test/hyperslab.c +++ b/test/hyperslab.c @@ -585,10 +585,10 @@ test_multifill(size_t nx) for (i = 0; i < nx; i++) { src[i].left = 1111111; - src[i].mid = 12345.6789F; + src[i].mid = 12345.6789; src[i].right = 2222222; dst[i].left = 3333333; - dst[i].mid = 98765.4321F; + dst[i].mid = 98765.4321; dst[i].right = 4444444; } /* end for */ @@ -597,7 +597,7 @@ test_multifill(size_t nx) * over and over again. */ fill.left = 55555555; - fill.mid = 3.1415927F; + fill.mid = 3.1415927; fill.right = 66666666; src_stride = 0; diff --git a/test/null_vol_connector.c b/test/null_vol_connector.c index 2b375d8..6555763 100644 --- a/test/null_vol_connector.c +++ b/test/null_vol_connector.c @@ -116,6 +116,7 @@ static const H5VL_class_t null_vol_g = { { /* introspect_cls */ NULL, /* get_conn_cls */ + NULL, /* get_cap_flags */ NULL, /* opt_query */ }, { diff --git a/test/ohdr.c b/test/ohdr.c index b7af77f..d28b11e 100644 --- a/test/ohdr.c +++ b/test/ohdr.c @@ -457,6 +457,59 @@ error: } /* test_ohdr_swmr() */ /* + * Tests bad object header messages. + * + * Currently tests for CVE-2020-10810 fixes but can be expanded to handle + * other CVE badness. + */ + +/* This is a generated file that can be obtained from: + * + * https://nvd.nist.gov/vuln/detail/CVE-2020-10810 + * + * It was formerly named H5AC_unpin_entry_POC + */ +#define CVE_2020_10810_FILENAME "cve_2020_10810.h5" + +static herr_t +test_ohdr_badness(hid_t fapl) +{ + hid_t fid = H5I_INVALID_HID; + + /* CVE-2020-10810 involved a malformed fsinfo message + * This test ensures the fundamental problem is fixed. Running it under + * valgrind et al. will ensure that the memory leaks and invalid access + * are fixed. + */ + TESTING("Fix for CVE-2020-10810"); + + H5E_BEGIN_TRY + { + /* This should fail due to the malformed fsinfo message. It should + * fail gracefully and not segfault. + */ + fid = H5Fopen(CVE_2020_10810_FILENAME, H5F_ACC_RDWR, fapl); + } + H5E_END_TRY; + + if (fid >= 0) + FAIL_PUTS_ERROR("should not have been able to open malformed file"); + + PASSED(); + + return SUCCEED; + +error: + H5E_BEGIN_TRY + { + H5Fclose(fid); + } + H5E_END_TRY; + + return FAIL; +} + +/* * To test objects with unknown messages in a file with: * a) H5O_BOGUS_VALID_ID: * --the bogus_id is within the range of H5O_msg_class_g[] @@ -488,7 +541,7 @@ test_unknown(unsigned bogus_id, char *filename, hid_t fapl) done in the source directory. */ HDstrncpy(testfile, FILE_BOGUS, TESTFILE_LEN); testfile[TESTFILE_LEN - 1] = '\0'; - HDstrncat(testfile, ".copy", 5); + HDstrncat(testfile, ".copy", sizeof(testfile) - HDstrlen(testfile) - 1); /* Make a copy of the data file from svn. */ if (h5_make_local_copy(FILE_BOGUS, testfile) < 0) @@ -2047,6 +2100,9 @@ main(void) } /* high */ } /* low */ + /* Verify bad ohdr message fixes work */ + test_ohdr_badness(fapl); + /* Verify symbol table messages are cached */ if (h5_verify_cached_stabs(FILENAME, fapl) < 0) TEST_ERROR diff --git a/test/pool.c b/test/pool.c index 9ce1846..c508025 100644 --- a/test/pool.c +++ b/test/pool.c @@ -34,7 +34,7 @@ #define MPOOL_LARGE_BLOCK (MPOOL_PAGE_SIZE * 3) #define MPOOL_NUM_SMALL_BLOCKS 64 #define MPOOL_SMALL_BLOCK 1 -#define MPOOL_NUM_RANDOM 10 * 1024 +#define MPOOL_NUM_RANDOM (10 * 1024) #define MPOOL_RANDOM_MAX_SIZE (MPOOL_PAGE_SIZE * 2) /*------------------------------------------------------------------------- diff --git a/test/set_extent.c b/test/set_extent.c index 5a07362..3078c2d 100644 --- a/test/set_extent.c +++ b/test/set_extent.c @@ -39,7 +39,7 @@ const char *FILENAME[] = {"set_extent1", "set_extent2", "set_extent3", "set_exte #define CONFIG_EARLY_ALLOC 0x04u #define CONFIG_UNFILT_EDGE 0x08u #define CONFIG_ALL (CONFIG_COMPRESS + CONFIG_FILL + CONFIG_EARLY_ALLOC + CONFIG_UNFILT_EDGE) -#define FILL_VALUE -1 +#define FILL_VALUE (-1) #define DO_RANKS_PRINT_CONFIG(TEST) \ { \ HDprintf(" Config:\n"); \ @@ -134,11 +134,11 @@ main(void) TEST_ERROR /* Set chunk cache so only part of the chunks can be cached on fapl */ - if (H5Pset_cache(fapl, 0, (size_t)8, 256 * sizeof(int), 0.75F) < 0) + if (H5Pset_cache(fapl, 0, (size_t)8, 256 * sizeof(int), 0.75) < 0) TEST_ERROR /* Disable chunk caching on fapl2 */ - if (H5Pset_cache(fapl2, 0, (size_t)0, (size_t)0, 0.0F) < 0) + if (H5Pset_cache(fapl2, 0, (size_t)0, (size_t)0, 0.0) < 0) TEST_ERROR /* Set the "use the latest version of the format" bounds for creating objects in the file */ diff --git a/test/swmr_common.c b/test/swmr_common.c index 46c80cf..3d35227 100644 --- a/test/swmr_common.c +++ b/test/swmr_common.c @@ -111,7 +111,7 @@ choose_dataset(unsigned *levelp, unsigned *offsetp, hbool_t verbose) ++ncalls; if ((ncalls % 1000) == 0 && verbose) { - fprintf(stderr, "%s: call %u chose level %u offset %u\n", __func__, ncalls, level, offset); + HDfprintf(stderr, "%s: call %u chose level %u offset %u\n", __func__, ncalls, level, offset); } if (levelp != NULL) *levelp = level; diff --git a/test/swmr_common.h b/test/swmr_common.h index 3a3f41d..c8c033a 100644 --- a/test/swmr_common.h +++ b/test/swmr_common.h @@ -64,7 +64,7 @@ H5TEST_DLLVAR unsigned symbol_count[NLEVELS]; extern "C" { #endif -H5TEST_DLL symbol_info_t *choose_dataset(unsigned *, unsigned *, hbool_t); +H5TEST_DLL symbol_info_t *choose_dataset(unsigned *levelp, unsigned *offsetp, hbool_t verbose); H5TEST_DLL hid_t create_symbol_datatype(void); H5TEST_DLL int generate_name(char *name_buf, unsigned level, unsigned count); H5TEST_DLL int generate_symbols(void); diff --git a/test/tattr.c b/test/tattr.c index b602222..756e139 100644 --- a/test/tattr.c +++ b/test/tattr.c @@ -95,8 +95,7 @@ int attr_data2[ATTR2_DIM1][ATTR2_DIM2] = {{7614, -416}, {197814, -3}}; /* Test d #define ATTR3_DIM2 2 #define ATTR3_DIM3 2 double attr_data3[ATTR3_DIM1][ATTR3_DIM2][ATTR3_DIM3] = { - {{2.3F, -26.1F}, {0.123F, -10.0F}}, - {{973.23F, -0.91827F}, {2.0F, 23.0F}}}; /* Test data for 3rd attribute */ + {{2.3, -26.1}, {0.123, -10.0}}, {{973.23, -0.91827}, {2.0, 23.0}}}; /* Test data for 3rd attribute */ #define ATTR4_NAME "Attr4" #define ATTR4_RANK 2 @@ -113,8 +112,8 @@ struct attr4_struct { double d; char c; } attr_data4[ATTR4_DIM1][ATTR4_DIM2] = { - {{3, -26.1F, 'd'}, {-100000, 0.123F, '3'}}, - {{-23, 981724.2F, 'Q'}, {0, 2.0F, '\n'}}}; /* Test data for 4th attribute */ + {{3, -26.1, 'd'}, {-100000, 0.123, '3'}}, + {{-23, 981724.2, 'Q'}, {0, 2.0, '\n'}}}; /* Test data for 4th attribute */ #define ATTR5_NAME "Attr5" #define ATTR5_RANK 0 diff --git a/test/tconfig.c b/test/tconfig.c index e3c6a2c..101de9a 100644 --- a/test/tconfig.c +++ b/test/tconfig.c @@ -37,8 +37,9 @@ /* verify if the sizeof(type) matches size defined in macro. */ /* Needs this extra step so that we can print the macro name. */ #define vrfy_macrosize(type, macro, macroname) \ - if (sizeof(type) != macro) \ - TestErrPrintf("Error: sizeof(%s) is %zu but %s is %d\n", #type, sizeof(type), macroname, (int)macro); + if (sizeof(type) != (macro)) \ + TestErrPrintf("Error: sizeof(%s) is %zu but %s is %d\n", #type, sizeof(type), macroname, \ + (int)(macro)); /* local routine prototypes */ void test_config_ctypes(void); diff --git a/test/test_usecases.sh.in b/test/test_usecases.sh.in index bb53697..eaa875e 100644 --- a/test/test_usecases.sh.in +++ b/test/test_usecases.sh.in @@ -22,10 +22,16 @@ # exit codes are okay (0). srcdir=@srcdir@ +bindir=@bindir@ + +# If the bindir directory is not set just use current (.). +if test -z "$bindir"; then + bindir=. +fi # Check to see if the VFD specified by the HDF5_DRIVER environment variable # supports SWMR. -./swmr_check_compat_vfd +$bindir/swmr_check_compat_vfd rc=$? if [[ $rc != 0 ]] ; then echo @@ -85,7 +91,7 @@ TOOLTEST() { # Run test. TESTING $program $@ ( - $RUNSERIAL ./$program "$@" + $RUNSERIAL $bindir/$program "$@" ) >$actual 2>$actual_err exit_code=$? @@ -178,14 +184,14 @@ fi # main body for p in $USECASES_PROGRAMS; do - TOOLTEST ./$p - TOOLTEST ./$p -z 256 + TOOLTEST $p + TOOLTEST $p -z 256 tmpfile=/tmp/datatfile.$$ - TOOLTEST ./$p -f $tmpfile; rm -f $tmpfile - TOOLTEST ./$p -l w - TOOLTEST ./$p -l r + TOOLTEST $p -f $tmpfile; rm -f $tmpfile + TOOLTEST $p -l w + TOOLTEST $p -l r # use case 1.9, testing with multi-planes chunks - TOOLTEST ./$p -z 256 -y 5 # 5 planes chunks + TOOLTEST $p -z 256 -y 5 # 5 planes chunks # cleanup temp datafile if test -z "$HDF5_NOCLEANUP"; then rm -f $p.h5 diff --git a/test/testcheck_version.sh.in b/test/testcheck_version.sh.in index 43d1b46..6378ee5 100644 --- a/test/testcheck_version.sh.in +++ b/test/testcheck_version.sh.in @@ -15,7 +15,7 @@ # Tests for the H5check_version function. # # Programmer: Albert Cheng -# Sep 28, 2009 +# Sep 28, 2009 srcdir=@srcdir@ @@ -24,7 +24,7 @@ srcdir=@srcdir@ Shared_Lib=@enable_shared@ Static_Lib=@enable_static@ Static_exec=@STATIC_EXEC@ -h5haveexitcode=yes # default is yes +h5haveexitcode=yes # default is yes CMP='cmp -s' DIFF='diff -c' @@ -103,10 +103,10 @@ WarnMesg2(){ # mismatch). # # Expected results: -# Value of $HDF5_DISABLE_VERSION_CHECK -# unset "" -1 0 1 2 3 -# Matched OK OK OK OK OK OK OK -# Mismatched W/A W/A W/A W/A W2/OK OK W2/OK +# Value of $HDF5_DISABLE_VERSION_CHECK +# unset "" -1 0 1 2 3 +# Matched OK OK OK OK OK OK OK +# Mismatched W/A W/A W/A W/A W2/OK OK W2/OK # Result codes: # OK: No warning, exit 0. # W/A: Warning, abort and exit non-0. @@ -130,42 +130,42 @@ TESTING() { xxh5versrelease=$h5versrelease if [ "$h5DisableVersion" = unset ]; then - envcmd="" # noop + envcmd="" # noop else - envcmd="env HDF5_DISABLE_VERSION_CHECK=$h5DisableVersion" + envcmd="env HDF5_DISABLE_VERSION_CHECK=$h5DisableVersion" fi if [ "$wrongversionnumbers" = none ]; then - # OK: No warning, exit 0 - cp /dev/null $expect - expect_code=0 + # OK: No warning, exit 0 + cp /dev/null $expect + expect_code=0 else - arguments=-t"$wrongversionnumbers" - # calculate mismatched version numbers by listing. - case $wrongversionnumbers in - "M") xxh5versmajor=`expr $h5versmajor + 1` - ;; - "m") xxh5versminor=`expr $h5versminor + 1` - ;; - "r") xxh5versrelease=`expr $h5versrelease + 1` - ;; - esac - case "$h5DisableVersion" in - 1) - # W2/OK: Different Warning, exit 0. - WarnMesg2 > $expect - expect_code=0 - ;; - [2-9]|[1-9][0-9]*) - # OK: No warning, exit 0 - cp /dev/null $expect - expect_code=0 - ;; - *) # W/A: Warning, abort and exit non-0. - WarnMesg > $expect - expect_code=6 # Signal Abort exit code (128+6) - ;; - esac + arguments=-t"$wrongversionnumbers" + # calculate mismatched version numbers by listing. + case $wrongversionnumbers in + "M") xxh5versmajor=`expr $h5versmajor + 1` + ;; + "m") xxh5versminor=`expr $h5versminor + 1` + ;; + "r") xxh5versrelease=`expr $h5versrelease + 1` + ;; + esac + case "$h5DisableVersion" in + 1) + # W2/OK: Different Warning, exit 0. + WarnMesg2 > $expect + expect_code=0 + ;; + [2-9]|[1-9][0-9]*) + # OK: No warning, exit 0 + cp /dev/null $expect + expect_code=0 + ;; + *) # W/A: Warning, abort and exit non-0. + WarnMesg > $expect + expect_code=6 # Signal Abort exit code (128+6) + ;; + esac fi # Run test. @@ -177,23 +177,23 @@ TESTING() { cat $actual_err >> $actual if [ $h5haveexitcode = 'yes' -a \( $expect_code -ne $ret_code \) ]; then - echo "*FAILED*" - echo " Expected exit code ($expect_code) differs from actual code ($ret_code)" - nerrors="`expr $nerrors + 1`" + echo "*FAILED*" + echo " Expected exit code ($expect_code) differs from actual code ($ret_code)" + nerrors="`expr $nerrors + 1`" elif $CMP $expect $actual; then - echo " PASSED" + echo " PASSED" else - echo "*FAILED*" - echo " Expected result differs from actual result" - nerrors="`expr $nerrors + 1`" - test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' + echo "*FAILED*" + echo " Expected result differs from actual result" + nerrors="`expr $nerrors + 1`" + test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' fi # Clean up output file. # Also clean the core file generated by H5check_version's abort. if test -z "$HDF5_NOCLEANUP"; then - $RM $expect $actual $actual_err - $RM core + $RM $expect $actual $actual_err + $RM core fi } @@ -201,15 +201,15 @@ TESTING() { # Echo parameters for debugging if verbose mode is on. DEBUGPRINT() { if [ -n "$debugmode" ]; then - echo $* + echo $* fi } # MAIN Body nerrors=0 -verbose=yes # default on -debugmode= # default off +verbose=yes # default on +debugmode= # default off H5_HAVE_EMBEDDED_LIBINFO=`grep '#define H5_HAVE_EMBEDDED_LIBINFO ' ../src/H5pubconf.h` h5libsettings=../src/libhdf5.settings @@ -240,13 +240,13 @@ fi # Three Categories of tests: # Normal: where the version numbers all matched (wrong_version == none). # Mismatched version numbers (could be Major or minor version -# or release numbers or a combination of all three.) +# or release numbers or a combination of all three.) # Test all the above with different values of the environment variable, # HDF5_DISABLE_VERSION_CHECK, as unset, "", -1, 0, 1, 2, 3 for val_disable_version_check in unset "" -1 0 1 2 3; do - for wrong_version in none M m r; do - TESTING "$val_disable_version_check" "$wrong_version" + for wrong_version in none M m; do + TESTING "$val_disable_version_check" "$wrong_version" done done diff --git a/test/testhdf5.h b/test/testhdf5.h index 5fb01a8..ba5fa71 100644 --- a/test/testhdf5.h +++ b/test/testhdf5.h @@ -136,7 +136,7 @@ "%s \n", \ (where), (int)__LINE__, __FILE__, x); \ } \ - if (HDstrcmp(x, val)) { \ + if (HDstrcmp(x, val) != 0) { \ TestErrPrintf("*** UNEXPECTED VALUE from %s should be %s, but is %s at line %4d " \ "in %s\n", \ where, val, x, (int)__LINE__, __FILE__); \ diff --git a/test/testswmr.sh.in b/test/testswmr.sh.in index 2df23c6..37e8f9c 100644 --- a/test/testswmr.sh.in +++ b/test/testswmr.sh.in @@ -17,6 +17,7 @@ # Albert Cheng, 2009/07/22 srcdir=@srcdir@ +bindir=@bindir@ ############################################################################### ## test parameters @@ -97,9 +98,14 @@ if test -z "$srcdir"; then srcdir=. fi +# If the bindir directory is not set just use current (.). +if test -z "$bindir"; then + bindir=. +fi + # Check to see if the VFD specified by the HDF5_DRIVER environment variable # supports SWMR. -./swmr_check_compat_vfd +$bindir/swmr_check_compat_vfd rc=$? if [ $rc -ne 0 ] ; then echo @@ -172,7 +178,7 @@ do echo "###############################################################################" # Launch the Generator without SWMR_WRITE echo launch the swmr_generator - ./swmr_generator $compress $index_type + $bindir/swmr_generator $compress $index_type if test $? -ne 0; then echo generator had error nerrors=`expr $nerrors + 1` @@ -180,7 +186,7 @@ do # Launch the Generator with SWMR_WRITE echo launch the swmr_generator with SWMR_WRITE - ./swmr_generator -s $compress $index_type + $bindir/swmr_generator -s $compress $index_type if test $? -ne 0; then echo generator had error nerrors=`expr $nerrors + 1` @@ -204,7 +210,7 @@ do # Launch the Writer echo launch the swmr_start_writer seed="" # Put -r <random seed> command here - ./swmr_start_write $compress $index_type $Nrecords $seed 2>&1 |tee swmr_writer.out & + $bindir/swmr_start_write $compress $index_type $Nrecords $seed 2>&1 |tee swmr_writer.out & pid_writer=$! $DPRINT pid_writer=$pid_writer @@ -220,7 +226,7 @@ do while [ $n -lt $Nreaders ]; do #seed="-r ${seeds[$n]}" seed="" - ./swmr_reader $Nsecs_add $seed 2>&1 |tee swmr_reader.out.$n & + $bindir/swmr_reader $Nsecs_add $seed 2>&1 |tee swmr_reader.out.$n & pid_readers="$pid_readers $!" n=`expr $n + 1` done @@ -265,7 +271,7 @@ do # Launch the Generator echo launch the swmr_generator - ./swmr_generator -s $compress $index_type + $bindir/swmr_generator -s $compress $index_type if test $? -ne 0; then echo generator had error nerrors=`expr $nerrors + 1` @@ -277,7 +283,7 @@ do # Launch the Writer echo launch the swmr_writer seed="" # Put -r <random seed> command here - ./swmr_writer -o $Nrecords $seed 2>&1 |tee swmr_writer.out & + $bindir/swmr_writer -o $Nrecords $seed 2>&1 |tee swmr_writer.out & pid_writer=$! $DPRINT pid_writer=$pid_writer @@ -292,7 +298,7 @@ do while [ $n -lt $Nreaders ]; do #seed="-r ${seeds[$n]}" seed="" - ./swmr_reader $Nsecs_add $seed 2>&1 |tee swmr_reader.out.$n & + $bindir/swmr_reader $Nsecs_add $seed 2>&1 |tee swmr_reader.out.$n & pid_readers="$pid_readers $!" n=`expr $n + 1` done @@ -340,7 +346,7 @@ do # Launch the Remove Writer echo launch the swmr_remove_writer seed="" # Put -r <random seed> command here - ./swmr_remove_writer -o $Nrecs_rem $seed 2>&1 |tee swmr_writer.out & + $bindir/swmr_remove_writer -o $Nrecs_rem $seed 2>&1 |tee swmr_writer.out & pid_writer=$! $DPRINT pid_writer=$pid_writer @@ -355,7 +361,7 @@ do while [ $n -lt $Nreaders ]; do #seed="-r ${seeds[$n]}" seed="" - ./swmr_remove_reader $Nsecs_rem $seed 2>&1 |tee swmr_reader.out.$n & + $bindir/swmr_remove_reader $Nsecs_rem $seed 2>&1 |tee swmr_reader.out.$n & pid_readers="$pid_readers $!" n=`expr $n + 1` done @@ -400,7 +406,7 @@ do # Launch the Generator echo launch the swmr_generator - ./swmr_generator $compress $index_type + $bindir/swmr_generator $compress $index_type if test $? -ne 0; then echo generator had error nerrors=`expr $nerrors + 1` @@ -409,7 +415,7 @@ do # Launch the Writer (not in parallel - just to rebuild the datasets) echo launch the swmr_writer seed="" # Put -r <random seed> command here - ./swmr_writer $Nrecords $seed + $bindir/swmr_writer $Nrecords $seed if test $? -ne 0; then echo writer had error nerrors=`expr $nerrors + 1` @@ -421,7 +427,7 @@ do # Launch the Add/Remove Writer echo launch the swmr_addrem_writer seed="" # Put -r <random seed> command here - ./swmr_addrem_writer $Nrecords $seed 2>&1 |tee swmr_writer.out & + $bindir/swmr_addrem_writer $Nrecords $seed 2>&1 |tee swmr_writer.out & pid_writer=$! $DPRINT pid_writer=$pid_writer @@ -436,7 +442,7 @@ do while [ $n -lt $Nreaders ]; do #seed="-r ${seeds[$n]}" seed="" - ./swmr_remove_reader $Nsecs_addrem $seed 2>&1 |tee swmr_reader.out.$n & + $bindir/swmr_remove_reader $Nsecs_addrem $seed 2>&1 |tee swmr_reader.out.$n & pid_readers="$pid_readers $!" n=`expr $n + 1` done @@ -484,7 +490,7 @@ do # created by the generator. echo launch the swmr_generator seed="" # Put -r <random seed> command here - ./swmr_generator $compress $index_type $seed + $bindir/swmr_generator $compress $index_type $seed if test $? -ne 0; then echo generator had error nerrors=`expr $nerrors + 1` @@ -494,7 +500,7 @@ do rm -f $WRITER_MESSAGE # Launch the Sparse writer echo launch the swmr_sparse_writer - nice -n 20 ./swmr_sparse_writer $Nrecs_spa 2>&1 |tee swmr_writer.out & + nice -n 20 $bindir/swmr_sparse_writer $Nrecs_spa 2>&1 |tee swmr_writer.out & pid_writer=$! $DPRINT pid_writer=$pid_writer @@ -507,7 +513,7 @@ do echo launch $Nrdrs_spa swmr_sparse_readers while [ $n -lt $Nrdrs_spa ]; do # The sparse reader spits out a LOT of data so it's set to 'quiet' - ./swmr_sparse_reader -q $Nrecs_spa 2>&1 |tee swmr_reader.out.$n & + $bindir/swmr_sparse_reader -q $Nrecs_spa 2>&1 |tee swmr_reader.out.$n & pid_readers="$pid_readers $!" n=`expr $n + 1` done diff --git a/test/testvdsswmr.sh.in b/test/testvdsswmr.sh.in index 9673aa3..5399903 100644 --- a/test/testvdsswmr.sh.in +++ b/test/testvdsswmr.sh.in @@ -17,6 +17,7 @@ # Dana Robinson, November 2015 srcdir=@srcdir@ +bindir=@bindir@ ############################################################################### ## test parameters @@ -30,7 +31,7 @@ nerrors=0 ## definitions for message file to coordinate test runs ############################################################################### WRITER_MESSAGE=SWMR_WRITER_MESSAGE # The message file created by writer that the open is complete - # This should be the same as the define in "./swmr_common.h" + # This should be the same as the define in "$bindir/swmr_common.h" MESSAGE_TIMEOUT=300 # Message timeout length in secs # This should be the same as the define in "./h5test.h" @@ -83,9 +84,14 @@ if test -z "$srcdir"; then srcdir=. fi +# If the bindir directory is not set just use current (.). +if test -z "$bindir"; then + bindir=. +fi + # Check to see if the VFD specified by the HDF5_DRIVER environment variable # supports SWMR. -./swmr_check_compat_vfd +$bindir/swmr_check_compat_vfd rc=$? if [ $rc -ne 0 ] ; then echo @@ -148,7 +154,7 @@ echo "########################################################################## # Launch the file generator echo launch the generator -./vds_swmr_gen +$bindir/vds_swmr_gen if test $? -ne 0; then echo generator had error nerrors=`expr $nerrors + 1` @@ -166,7 +172,7 @@ echo "launch the $Nwriters SWMR VDS writers (1 per source)" pid_writers="" n=0 while [ $n -lt $Nwriters ]; do - ./vds_swmr_writer $n & + $bindir/vds_swmr_writer $n & pid_writers="$pid_writers $!" n=`expr $n + 1` done @@ -181,7 +187,7 @@ echo launch $Nreaders SWMR readers pid_readers="" n=0 while [ $n -lt $Nreaders ]; do - ./vds_swmr_reader & + $bindir/vds_swmr_reader & pid_readers="$pid_readers $!" n=`expr $n + 1` done diff --git a/test/tfile.c b/test/tfile.c index d85d188..656e956 100644 --- a/test/tfile.c +++ b/test/tfile.c @@ -125,7 +125,7 @@ #define TEST_THRESHOLD10 10 /* Free space section threshold */ #define FSP_SIZE_DEF 4096 /* File space page size default */ #define FSP_SIZE512 512 /* File space page size */ -#define FSP_SIZE1G 1024 * 1024 * 1024 /* File space page size */ +#define FSP_SIZE1G (1024 * 1024 * 1024) /* File space page size */ /* Declaration for test_libver_macros2() */ #define FILE6 "tfile6.h5" /* Test file */ diff --git a/test/timer.c b/test/timer.c index bb474ca..11b7427 100644 --- a/test/timer.c +++ b/test/timer.c @@ -43,55 +43,55 @@ test_time_formatting(void) TESTING("Time string formats"); /* < 0, N/A */ - s = H5_timer_get_time_string(-1.0F); + s = H5_timer_get_time_string(-1.0); if (NULL == s || HDstrcmp(s, "N/A") != 0) TEST_ERROR; HDfree(s); /* 0 0 */ - s = H5_timer_get_time_string(0.0F); + s = H5_timer_get_time_string(0.0); if (NULL == s || HDstrcmp(s, "0.0 s") != 0) TEST_ERROR; HDfree(s); /* < 1 us nanoseconds */ - s = H5_timer_get_time_string(123.0E-9F); + s = H5_timer_get_time_string(123.0E-9); if (NULL == s || HDstrcmp(s, "123 ns") != 0) TEST_ERROR; HDfree(s); /* < 1 ms microseconds */ - s = H5_timer_get_time_string(23.456E-6F); + s = H5_timer_get_time_string(23.456E-6); if (NULL == s || HDstrcmp(s, "23.5 us") != 0) TEST_ERROR; HDfree(s); /* < 1 s milliseconds */ - s = H5_timer_get_time_string(4.56789E-3F); + s = H5_timer_get_time_string(4.56789E-3); if (NULL == s || HDstrcmp(s, "4.6 ms") != 0) TEST_ERROR; HDfree(s); /* < 1 min seconds */ - s = H5_timer_get_time_string(3.14F); + s = H5_timer_get_time_string(3.14); if (NULL == s || HDstrcmp(s, "3.14 s") != 0) TEST_ERROR; HDfree(s); /* < 1 hr mins, secs */ - s = H5_timer_get_time_string(2521.0F); + s = H5_timer_get_time_string(2521.0); if (NULL == s || HDstrcmp(s, "42 m 1 s") != 0) TEST_ERROR; HDfree(s); /* < 1 d hrs, mins, secs */ - s = H5_timer_get_time_string(9756.0F); + s = H5_timer_get_time_string(9756.0); if (NULL == s || HDstrcmp(s, "2 h 42 m 36 s") != 0) TEST_ERROR; HDfree(s); /* > 1 d days, hrs, mins, secs */ - s = H5_timer_get_time_string(280802.0F); + s = H5_timer_get_time_string(280802.0); if (NULL == s || HDstrcmp(s, "3 d 6 h 0 m 2 s") != 0) TEST_ERROR; HDfree(s); diff --git a/test/tmeta.c b/test/tmeta.c index 2609703..e70db16 100644 --- a/test/tmeta.c +++ b/test/tmeta.c @@ -22,9 +22,9 @@ #include "testhdf5.h" #include "H5Fprivate.h" -#define TEST_INT16_VALUE -7641 +#define TEST_INT16_VALUE (-7641) #define TEST_UINT16_VALUE 45002 -#define TEST_INT32_VALUE -981236 +#define TEST_INT32_VALUE (-981236) #define TEST_UINT32_VALUE 3476589 uint8_t compar_buffer[] = { diff --git a/test/tmisc.c b/test/tmisc.c index 302da0d..b267330 100644 --- a/test/tmisc.c +++ b/test/tmisc.c @@ -5276,7 +5276,7 @@ test_misc28(void) * bytes). */ fapl = H5Pcreate(H5P_FILE_ACCESS); CHECK(fapl, FAIL, "H5Pcreate"); - ret = H5Pset_cache(fapl, MISC28_NSLOTS, MISC28_NSLOTS, MISC28_SIZE, 0.75F); + ret = H5Pset_cache(fapl, MISC28_NSLOTS, MISC28_NSLOTS, MISC28_SIZE, 0.75); CHECK(ret, FAIL, "H5Pset_cache"); /* Create the dcpl and set the chunk size */ diff --git a/test/tsohm.c b/test/tsohm.c index fcbb06a..b4ece0b 100644 --- a/test/tsohm.c +++ b/test/tsohm.c @@ -622,7 +622,7 @@ size1_helper(hid_t file, const char *filename, hid_t fapl_id, hbool_t test_file_ HDprintf("Can't read data\n"); \ goto error; \ } \ - if ((rdata.i1 != wdata.i1) || (rdata.i2 != wdata.i2) || HDstrcmp(rdata.str, wdata.str)) { \ + if ((rdata.i1 != wdata.i1) || (rdata.i2 != wdata.i2) || HDstrcmp(rdata.str, wdata.str) != 0) { \ H5_FAILED(); \ AT(); \ HDprintf("incorrect read data\n"); \ diff --git a/test/tunicode.c b/test/tunicode.c index 52341bb..1b696ac 100644 --- a/test/tunicode.c +++ b/test/tunicode.c @@ -33,7 +33,7 @@ #define RANK 1 #define COMP_INT_VAL 7 -#define COMP_FLOAT_VAL -42.0F +#define COMP_FLOAT_VAL (-42.0F) #define COMP_DOUBLE_VAL 42.0F /* Test function prototypes */ diff --git a/test/tvltypes.c b/test/tvltypes.c index 50b2d7a..03a8ad3 100644 --- a/test/tvltypes.c +++ b/test/tvltypes.c @@ -2526,10 +2526,10 @@ test_vltypes_fill_value(void) hsize_t small_dims[] = {SPACE4_DIM_SMALL}; hsize_t large_dims[] = {SPACE4_DIM_LARGE}; size_t dset_elmts = 0; /* Number of elements in a particular dataset */ - const dtype1_struct fill1 = {1, 2, "foobar", "", NULL, "\0", "dead", - 3, 4.0F, 100.0F, 1.0F, "liquid", "meter"}; - const dtype1_struct wdata = {3, 4, "", NULL, "\0", "foo", "two", 6, 8.0F, 200.0F, 2.0F, "solid", "yard"}; - dtype1_struct * rbuf = NULL; /* Buffer for reading data */ + const dtype1_struct fill1 = {1, 2, "foobar", "", NULL, "\0", "dead", + 3, 4.0, 100.0, 1.0, "liquid", "meter"}; + const dtype1_struct wdata = {3, 4, "", NULL, "\0", "foo", "two", 6, 8.0, 200.0, 2.0, "solid", "yard"}; + dtype1_struct * rbuf = NULL; /* Buffer for reading data */ size_t mem_used = 0; /* Memory used during allocation */ H5D_layout_t layout; /* Dataset storage layout */ char dset_name1[64], dset_name2[64]; /* Dataset names */ diff --git a/test/vds.c b/test/vds.c index 88ac4eb..ac9bb5d 100644 --- a/test/vds.c +++ b/test/vds.c @@ -78,12 +78,12 @@ char vds_test_str_g[128] = ""; #endif /* VDS_TEST_VERBOSE */ /* I/O test config flags */ -#define TEST_IO_CLOSE_SRC 0x01u -#define TEST_IO_DIFFERENT_FILE 0x02u -#define TEST_IO_REOPEN_VIRT 0x04u -#define TEST_IO_FCLOSE_SEMI 0x08u -#define TEST_IO_FCLOSE_STRONG 0x10u -#define TEST_IO_NTESTS 0x20u +#define TEST_IO_CLOSE_SRC 0x01U +#define TEST_IO_DIFFERENT_FILE 0x02U +#define TEST_IO_REOPEN_VIRT 0x04U +#define TEST_IO_FCLOSE_SEMI 0x08U +#define TEST_IO_FCLOSE_STRONG 0x10U +#define TEST_IO_NTESTS 0x20U #define LIST_DOUBLE_SIZE (H5D_VIRTUAL_DEF_LIST_SIZE + 1) diff --git a/test/vfd.c b/test/vfd.c index 8484bfd..f4cb988 100644 --- a/test/vfd.c +++ b/test/vfd.c @@ -859,7 +859,7 @@ error: * 'first_name' in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("format-nonliteral") +H5_GCC_CLANG_DIAG_OFF("format-nonliteral") static herr_t test_family_opens(char *fname, hid_t fa_pl) { @@ -924,7 +924,7 @@ test_family_opens(char *fname, hid_t fa_pl) error: return -1; } /* end test_family_opens() */ -H5_GCC_DIAG_ON("format-nonliteral") +H5_GCC_CLANG_DIAG_ON("format-nonliteral") /*------------------------------------------------------------------------- * Function: test_family @@ -1150,7 +1150,7 @@ error: * 'newname_individual', etc. in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("format-nonliteral") +H5_GCC_CLANG_DIAG_OFF("format-nonliteral") static herr_t test_family_compat(void) { @@ -1236,7 +1236,7 @@ error: return -1; } /* end test_family_compat() */ -H5_GCC_DIAG_ON("format-nonliteral") +H5_GCC_CLANG_DIAG_ON("format-nonliteral") /*------------------------------------------------------------------------- * Function: test_family_member_fapl @@ -1376,7 +1376,7 @@ error: * 'sf_name' in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("format-nonliteral") +H5_GCC_CLANG_DIAG_OFF("format-nonliteral") static herr_t test_multi_opens(char *fname) { @@ -1396,7 +1396,7 @@ test_multi_opens(char *fname) return (fid >= 0 ? FAIL : SUCCEED); } /* end test_multi_opens() */ -H5_GCC_DIAG_ON("format-nonliteral") +H5_GCC_CLANG_DIAG_ON("format-nonliteral") /*------------------------------------------------------------------------- * Function: test_multi diff --git a/test/vol.c b/test/vol.c index d975243..c7586d5 100644 --- a/test/vol.c +++ b/test/vol.c @@ -20,6 +20,12 @@ /* Headers needed */ #include "h5test.h" +#include "H5Iprivate.h" /* IDs */ +#define H5T_FRIEND /* Suppress error about including H5Tpkg */ +#include "H5Tpkg.h" /* Datatypes */ +#define H5VL_FRIEND /* Suppress error about including H5VLpkg */ +#define H5VL_TESTING +#include "H5VLpkg.h" /* Virtual Object Layer */ /* Filename */ const char *FILENAME[] = {"native_vol_test", NULL}; @@ -35,6 +41,136 @@ const char *FILENAME[] = {"native_vol_test", NULL}; #define N_ELEMENTS 10 +/* A VOL class struct to verify registering optional operations */ +static int reg_opt_curr_op_val; +static herr_t reg_opt_op_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req); +static herr_t reg_opt_link_optional(void *obj, const H5VL_loc_params_t *loc_params, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req); +static herr_t reg_opt_datatype_get(void *obj, H5VL_datatype_get_args_t *args, hid_t dxpl_id, void **req); +#define REG_OPT_VOL_NAME "reg_opt" +#define REG_OPT_VOL_VALUE ((H5VL_class_value_t)502) +static const H5VL_class_t reg_opt_vol_g = { + H5VL_VERSION, /* VOL class struct version */ + REG_OPT_VOL_VALUE, /* value */ + REG_OPT_VOL_NAME, /* name */ + 0, /* version */ + 0, /* capability flags */ + NULL, /* initialize */ + NULL, /* terminate */ + { + /* info_cls */ + (size_t)0, /* size */ + NULL, /* copy */ + NULL, /* compare */ + NULL, /* free */ + NULL, /* to_str */ + NULL, /* from_str */ + }, + { + /* wrap_cls */ + NULL, /* get_object */ + NULL, /* get_wrap_ctx */ + NULL, /* wrap_object */ + NULL, /* unwrap_object */ + NULL, /* free_wrap_ctx */ + }, + { + /* attribute_cls */ + NULL, /* create */ + NULL, /* open */ + NULL, /* read */ + NULL, /* write */ + NULL, /* get */ + NULL, /* specific */ + reg_opt_op_optional, /* optional */ + NULL /* close */ + }, + { + /* dataset_cls */ + NULL, /* create */ + NULL, /* open */ + NULL, /* read */ + NULL, /* write */ + NULL, /* get */ + NULL, /* specific */ + reg_opt_op_optional, /* optional */ + NULL /* close */ + }, + { + /* datatype_cls */ + NULL, /* commit */ + NULL, /* open */ + reg_opt_datatype_get, /* get */ + NULL, /* specific */ + reg_opt_op_optional, /* optional */ + NULL /* close */ + }, + { + /* file_cls */ + NULL, /* create */ + NULL, /* open */ + NULL, /* get */ + NULL, /* specific */ + reg_opt_op_optional, /* optional */ + NULL /* close */ + }, + { + /* group_cls */ + NULL, /* create */ + NULL, /* open */ + NULL, /* get */ + NULL, /* specific */ + reg_opt_op_optional, /* optional */ + NULL /* close */ + }, + { + /* link_cls */ + NULL, /* create */ + NULL, /* copy */ + NULL, /* move */ + NULL, /* get */ + NULL, /* specific */ + reg_opt_link_optional /* optional */ + }, + { + /* object_cls */ + NULL, /* open */ + NULL, /* copy */ + NULL, /* get */ + NULL, /* specific */ + reg_opt_link_optional /* optional */ + }, + { + /* introspect_cls */ + NULL, /* get_conn_cls */ + NULL, /* get_cap_flags */ + NULL, /* opt_query */ + }, + { + /* request_cls */ + NULL, /* wait */ + NULL, /* notify */ + NULL, /* cancel */ + NULL, /* specific */ + NULL, /* optional */ + NULL /* free */ + }, + { + /* blob_cls */ + NULL, /* put */ + NULL, /* get */ + NULL, /* specific */ + NULL /* optional */ + }, + { + /* token_cls */ + NULL, /* cmp */ + NULL, /* to_str */ + NULL /* from_str */ + }, + NULL /* optional */ +}; + #define FAKE_VOL_NAME "fake" #define FAKE_VOL_VALUE ((H5VL_class_value_t)501) @@ -90,6 +226,136 @@ static const H5VL_class_t fake_vol_g = { }, { /* datatype_cls */ + NULL, /* commit */ + NULL, /* open */ + reg_opt_datatype_get, /* get */ + NULL, /* specific */ + NULL, /* optional */ + NULL /* close */ + }, + { + /* file_cls */ + NULL, /* create */ + NULL, /* open */ + NULL, /* get */ + NULL, /* specific */ + NULL, /* optional */ + NULL /* close */ + }, + { + /* group_cls */ + NULL, /* create */ + NULL, /* open */ + NULL, /* get */ + NULL, /* specific */ + NULL, /* optional */ + NULL /* close */ + }, + { + /* link_cls */ + NULL, /* create */ + NULL, /* copy */ + NULL, /* move */ + NULL, /* get */ + NULL, /* specific */ + NULL /* optional */ + }, + { + /* object_cls */ + NULL, /* open */ + NULL, /* copy */ + NULL, /* get */ + NULL, /* specific */ + NULL /* optional */ + }, + { + /* introspect_cls */ + NULL, /* get_conn_cls */ + NULL, /* get_cap_flags */ + NULL, /* opt_query */ + }, + { + /* request_cls */ + NULL, /* wait */ + NULL, /* notify */ + NULL, /* cancel */ + NULL, /* specific */ + NULL, /* optional */ + NULL /* free */ + }, + { + /* blob_cls */ + NULL, /* put */ + NULL, /* get */ + NULL, /* specific */ + NULL /* optional */ + }, + { + /* token_cls */ + NULL, /* cmp */ + NULL, /* to_str */ + NULL /* from_str */ + }, + NULL /* optional */ +}; + +static herr_t fake_async_get_cap_flags(const void *info, unsigned *cap_flags); + +#define FAKE_ASYNC_VOL_NAME "fake_async" +#define FAKE_ASYNC_VOL_VALUE ((H5VL_class_value_t)503) + +/* A VOL class struct that describes a VOL class with no + * functionality except to set the async capability flag. + */ +static const H5VL_class_t fake_async_vol_g = { + H5VL_VERSION, /* VOL class struct version */ + FAKE_ASYNC_VOL_VALUE, /* value */ + FAKE_ASYNC_VOL_NAME, /* name */ + 0, /* connector version */ + H5VL_CAP_FLAG_ASYNC, /* capability flags */ + NULL, /* initialize */ + NULL, /* terminate */ + { + /* info_cls */ + (size_t)0, /* size */ + NULL, /* copy */ + NULL, /* compare */ + NULL, /* free */ + NULL, /* to_str */ + NULL, /* from_str */ + }, + { + /* wrap_cls */ + NULL, /* get_object */ + NULL, /* get_wrap_ctx */ + NULL, /* wrap_object */ + NULL, /* unwrap_object */ + NULL, /* free_wrap_ctx */ + }, + { + /* attribute_cls */ + NULL, /* create */ + NULL, /* open */ + NULL, /* read */ + NULL, /* write */ + NULL, /* get */ + NULL, /* specific */ + NULL, /* optional */ + NULL /* close */ + }, + { + /* dataset_cls */ + NULL, /* create */ + NULL, /* open */ + NULL, /* read */ + NULL, /* write */ + NULL, /* get */ + NULL, /* specific */ + NULL, /* optional */ + NULL /* close */ + }, + { + /* datatype_cls */ NULL, /* commit */ NULL, /* open */ NULL, /* get */ @@ -134,8 +400,9 @@ static const H5VL_class_t fake_vol_g = { }, { /* introspect_cls */ - NULL, /* get_conn_cls */ - NULL, /* opt_query */ + NULL, /* get_conn_cls */ + fake_async_get_cap_flags, /* get_cap_flags */ + NULL, /* opt_query */ }, { /* request_cls */ @@ -163,6 +430,146 @@ static const H5VL_class_t fake_vol_g = { }; /*------------------------------------------------------------------------- + * Function: reg_opt_op_optional_verify + * + * Purpose: Common verification routine for dynamic optional operations + * + * Return: Success: 0 + * Failure: -1 + * + *------------------------------------------------------------------------- + */ +static herr_t +reg_opt_op_optional_verify(void *obj, H5VL_optional_args_t *args) +{ + int *o = (int *)obj; + int *op_args; + + /* Check for receiving correct operation value */ + if (args->op_type != reg_opt_curr_op_val) + return -1; + + /* Check that the object is correct */ + if ((-1) != *o) + return -1; + + /* Update the object, with the operation value */ + *o = args->op_type; + + /* Check that the argument is correct */ + op_args = args->args; + if (NULL == op_args) + return -1; + if ((-1) != *op_args) + return -1; + + /* Update the argument return parameter */ + *op_args = args->op_type; + + return 0; +} /* end reg_opt_op_optional_verify() */ + +/*------------------------------------------------------------------------- + * Function: reg_opt_op_optional + * + * Purpose: Common callback to perform a connector-specific operation + * on an object + * + * Return: Success: 0 + * Failure: -1 + * + *------------------------------------------------------------------------- + */ +static herr_t +reg_opt_op_optional(void *obj, H5VL_optional_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) +{ + /* Invoke the common value verification routine */ + return reg_opt_op_optional_verify(obj, args); +} /* end reg_opt_op_optional() */ + +/*------------------------------------------------------------------------- + * Function: reg_opt_link_optional + * + * Purpose: Callback to perform a connector-specific operation + * on a link + * + * Return: Success: 0 + * Failure: -1 + * + *------------------------------------------------------------------------- + */ +static herr_t +reg_opt_link_optional(void *obj, const H5VL_loc_params_t *loc_params, H5VL_optional_args_t *args, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) +{ + /* Check for receiving correct loc_params info */ + if (loc_params->type != H5VL_OBJECT_BY_NAME) + return -1; + if (loc_params->obj_type != H5I_GROUP) + return -1; + if (HDstrcmp(loc_params->loc_data.loc_by_name.name, ".") != 0) + return -1; + if (loc_params->loc_data.loc_by_name.lapl_id != H5P_LINK_ACCESS_DEFAULT) + return -1; + + /* Invoke the common value verification routine */ + return reg_opt_op_optional_verify(obj, args); +} /* end reg_opt_link_optional() */ + +/*------------------------------------------------------------------------- + * Function: reg_opt_datatype_get + * + * Purpose: Handles the datatype get callback + * + * Note: This is _strictly_ a testing fixture to support the + * exercise_reg_opt_oper() testing routine. It fakes just + * enough of the named datatype VOL callback for the + * H5VL_register_using_vol_id() call in that test routine to + * succeed. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +reg_opt_datatype_get(void H5_ATTR_UNUSED *obj, H5VL_datatype_get_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + if (H5VL_DATATYPE_GET_BINARY_SIZE == args->op_type) { + if (H5Tencode(H5T_NATIVE_INT, NULL, args->args.get_binary_size.size) < 0) + ret_value = FAIL; + } /* end if */ + else if (H5VL_DATATYPE_GET_BINARY == args->op_type) { + if (H5Tencode(H5T_NATIVE_INT, args->args.get_binary.buf, &args->args.get_binary.buf_size) < 0) + ret_value = FAIL; + } /* end if */ + else + ret_value = FAIL; + + return ret_value; +} /* end reg_opt_datatype_get() */ + +/*------------------------------------------------------------------------- + * Function: fake_async_get_cap_flags + * + * Purpose: Return the capability flags for the 'fake async' connector + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +fake_async_get_cap_flags(const void H5_ATTR_UNUSED *info, unsigned *cap_flags) +{ + *cap_flags = fake_async_vol_g.cap_flags; + + return SUCCEED; +} /* end fake_async_get_cap_flags() */ + +/*------------------------------------------------------------------------- * Function: test_vol_registration() * * Purpose: Tests if we can load, register, and close a simple @@ -1176,6 +1583,519 @@ error: } /* end test_basic_datatype_operation() */ +typedef herr_t (*reg_opt_obj_oper_t)(const char *app_file, const char *app_func, unsigned app_line, + hid_t obj_id, H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id); +typedef herr_t (*reg_opt_link_oper_t)(const char *app_file, const char *app_func, unsigned app_line, + hid_t obj_id, const char *name, hid_t lapl_id, + H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id); +typedef union { + reg_opt_obj_oper_t obj_op; + reg_opt_link_oper_t link_op; +} reg_opt_oper_t; + +/*------------------------------------------------------------------------- + * Function: exercise_reg_opt_oper() + * + * Purpose: Exercise a particular optional operation for a type. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +exercise_reg_opt_oper(hid_t fake_vol_id, hid_t reg_opt_vol_id, H5VL_subclass_t subcls, + const char *subcls_name, H5I_type_t id_type, reg_opt_oper_t reg_opt_op) +{ + char op_name[256]; /* Operation name to register */ + hid_t obj_id = H5I_INVALID_HID; + H5VL_object_t * vol_obj; + H5VL_optional_args_t vol_cb_args; + int fake_obj, fake_arg; + int op_val = -1, op_val2 = -1; + int find_op_val; + herr_t ret = SUCCEED; + + /* Test registering optional operation */ + HDsnprintf(op_name, sizeof(op_name), "%s-op1", subcls_name); + if (H5VLregister_opt_operation(subcls, op_name, &op_val) < 0) + TEST_ERROR; + + /* Verify that the reserved amount of optional operations is obeyed */ + /* (The first optional operation registered should be at the lower limit) */ + if (op_val != H5VL_RESERVED_NATIVE_OPTIONAL) + TEST_ERROR; + + /* Look up 1st registered optional operation */ + find_op_val = 0; + if (H5VLfind_opt_operation(subcls, op_name, &find_op_val) < 0) + TEST_ERROR; + + /* Verify that the operation was looked up successfully */ + if (op_val != find_op_val) + TEST_ERROR; + + /* Test registering second optional operation */ + HDsnprintf(op_name, sizeof(op_name), "%s-op2", subcls_name); + if (H5VLregister_opt_operation(subcls, op_name, &op_val2) < 0) + TEST_ERROR; + + /* Verify that the reserved amount of optional operations is obeyed */ + /* (The 2nd optional operation registered should be at the lower limit + 1) */ + if (op_val2 != (H5VL_RESERVED_NATIVE_OPTIONAL + 1)) + TEST_ERROR; + + /* Look up 2nd registered optional operation */ + find_op_val = 0; + if (H5VLfind_opt_operation(subcls, op_name, &find_op_val) < 0) + TEST_ERROR; + + /* Verify that the operation was looked up successfully */ + if (op_val2 != find_op_val) + TEST_ERROR; + + /* Push a new API context on the stack */ + /* (Necessary for the named datatype construction routines) */ + if (H5VL_SUBCLS_DATATYPE == subcls) + H5CX_push(); + + /* Create fake object on fake VOL connector */ + if (H5I_INVALID_HID == (obj_id = H5VL_register_using_vol_id(id_type, &fake_obj, fake_vol_id, TRUE))) + TEST_ERROR; + + /* Pop the API context off the stack */ + if (H5VL_SUBCLS_DATATYPE == subcls) + H5CX_pop(FALSE); + + /* Attempt to issue operation on fake VOL connector */ + fake_obj = -1; + fake_arg = -1; + vol_cb_args.op_type = op_val; + vol_cb_args.args = &fake_arg; + H5E_BEGIN_TRY + { + if (H5VL_SUBCLS_LINK == subcls || H5VL_SUBCLS_OBJECT == subcls) + ret = (*reg_opt_op.link_op)(__FILE__, __func__, __LINE__, obj_id, ".", H5P_DEFAULT, &vol_cb_args, + H5P_DEFAULT, H5ES_NONE); + else + ret = (*reg_opt_op.obj_op)(__FILE__, __func__, __LINE__, obj_id, &vol_cb_args, H5P_DEFAULT, + H5ES_NONE); + } + H5E_END_TRY; + if (FAIL != ret) + FAIL_PUTS_ERROR("should not be able to perform an optional operation with a NULL callback"); + if ((-1) != fake_obj) + FAIL_PUTS_ERROR("'fake_obj' changed during failed operation?"); + if ((-1) != fake_arg) + FAIL_PUTS_ERROR("'fake_arg' changed during failed operation?"); + + /* Named datatypes must be destroyed differently */ + if (H5VL_SUBCLS_DATATYPE == subcls) { + H5T_t *dt; + + /* Destroy fake datatype object */ + if (NULL == (dt = H5I_remove(obj_id))) + TEST_ERROR; + if (H5VL_free_object(dt->vol_obj) < 0) + TEST_ERROR; + dt->vol_obj = NULL; + if (H5T_close(dt) < 0) + TEST_ERROR; + } /* end if */ + else { + /* Destroy fake object */ + if (NULL == (vol_obj = H5I_remove(obj_id))) + TEST_ERROR; + if (H5VL_free_object(vol_obj) < 0) + TEST_ERROR; + } /* end else */ + + /* Push a new API context on the stack */ + /* (Necessary for the named datatype construction routines) */ + if (H5VL_SUBCLS_DATATYPE == subcls) + H5CX_push(); + + /* Create fake object on reg_opt VOL connector */ + if (H5I_INVALID_HID == (obj_id = H5VL_register_using_vol_id(id_type, &fake_obj, reg_opt_vol_id, TRUE))) + TEST_ERROR; + + /* Pop the API context off the stack */ + if (H5VL_SUBCLS_DATATYPE == subcls) + H5CX_pop(FALSE); + + /* Issue first operation */ + fake_obj = -1; + fake_arg = -1; + reg_opt_curr_op_val = op_val; + vol_cb_args.op_type = op_val; + vol_cb_args.args = &fake_arg; + if (H5VL_SUBCLS_LINK == subcls || H5VL_SUBCLS_OBJECT == subcls) + ret = (*reg_opt_op.link_op)(__FILE__, __func__, __LINE__, obj_id, ".", H5P_DEFAULT, &vol_cb_args, + H5P_DEFAULT, H5ES_NONE); + else + ret = + (*reg_opt_op.obj_op)(__FILE__, __func__, __LINE__, obj_id, &vol_cb_args, H5P_DEFAULT, H5ES_NONE); + if (ret < 0) + TEST_ERROR; + + /* Verify that fake object & argument were modified correctly */ + if (op_val != fake_obj) + FAIL_PUTS_ERROR("'fake_obj' not updated"); + if (op_val != fake_arg) + FAIL_PUTS_ERROR("'fake_arg' not updated"); + + /* Issue second operation */ + fake_obj = -1; + fake_arg = -1; + reg_opt_curr_op_val = op_val2; + vol_cb_args.op_type = op_val2; + vol_cb_args.args = &fake_arg; + if (H5VL_SUBCLS_LINK == subcls || H5VL_SUBCLS_OBJECT == subcls) + ret = (*reg_opt_op.link_op)(__FILE__, __func__, __LINE__, obj_id, ".", H5P_DEFAULT, &vol_cb_args, + H5P_DEFAULT, H5ES_NONE); + else + ret = + (*reg_opt_op.obj_op)(__FILE__, __func__, __LINE__, obj_id, &vol_cb_args, H5P_DEFAULT, H5ES_NONE); + if (ret < 0) + TEST_ERROR; + + /* Verify that fake object & argument were modified correctly */ + if (op_val2 != fake_obj) + FAIL_PUTS_ERROR("'fake_obj' not updated"); + if (op_val2 != fake_arg) + FAIL_PUTS_ERROR("'fake_arg' not updated"); + + /* Named datatypes must be destroyed differently */ + if (H5VL_SUBCLS_DATATYPE == subcls) { + H5T_t *dt; + + /* Destroy fake datatype object */ + if (NULL == (dt = H5I_remove(obj_id))) + TEST_ERROR; + if (H5VL_free_object(dt->vol_obj) < 0) + TEST_ERROR; + dt->vol_obj = NULL; + if (H5T_close(dt) < 0) + TEST_ERROR; + } /* end if */ + else { + /* Destroy fake object */ + if (NULL == (vol_obj = H5I_remove(obj_id))) + TEST_ERROR; + if (H5VL_free_object(vol_obj) < 0) + TEST_ERROR; + } /* end else */ + + /* Unregister 2nd registered optional operation */ + if (H5VLunregister_opt_operation(subcls, op_name) < 0) + TEST_ERROR; + + return SUCCEED; + +error: + return FAIL; +} /* end exercise_reg_opt_oper() */ + +/*------------------------------------------------------------------------- + * Function: test_register_opt_operation() + * + * Purpose: Tests if we can load, register, and close a simple + * VOL connector. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +test_register_opt_operation(void) +{ + hid_t fake_vol_id = H5I_INVALID_HID; + hid_t reg_opt_vol_id = H5I_INVALID_HID; + struct { + H5VL_subclass_t subcls; + const char * subcls_name; + H5I_type_t id_type; + reg_opt_oper_t reg_opt_op; + } test_params[] = {{H5VL_SUBCLS_ATTR, "attr", H5I_ATTR, {.obj_op = H5VLattr_optional_op}}, + {H5VL_SUBCLS_DATASET, "dataset", H5I_DATASET, {.obj_op = H5VLdataset_optional_op}}, + {H5VL_SUBCLS_DATATYPE, "datatype", H5I_DATATYPE, {.obj_op = H5VLdatatype_optional_op}}, + {H5VL_SUBCLS_FILE, "file", H5I_FILE, {.obj_op = H5VLfile_optional_op}}, + {H5VL_SUBCLS_GROUP, "group", H5I_GROUP, {.obj_op = H5VLgroup_optional_op}}, + {H5VL_SUBCLS_LINK, "link", H5I_GROUP, {.link_op = H5VLlink_optional_op}}, + {H5VL_SUBCLS_OBJECT, "object", H5I_GROUP, {.link_op = H5VLobject_optional_op}}}; + int op_val = -1; + unsigned u; + herr_t ret = SUCCEED; + + TESTING("dynamically registering optional operations"); + + /* Register the VOL connectors for testing */ + if ((fake_vol_id = H5VLregister_connector(&fake_vol_g, H5P_DEFAULT)) < 0) + TEST_ERROR; + if ((reg_opt_vol_id = H5VLregister_connector(®_opt_vol_g, H5P_DEFAULT)) < 0) + TEST_ERROR; + + /* Test registering invalid optional VOL subclass operations */ + H5E_BEGIN_TRY + { + ret = H5VLregister_opt_operation(H5VL_SUBCLS_NONE, "fail", &op_val); + } + H5E_END_TRY; + if (FAIL != ret) + FAIL_PUTS_ERROR("should not be able to register an optional operation for the 'NONE' VOL subclass"); + if ((-1) != op_val) + FAIL_PUTS_ERROR("'op_val' changed during failed operation?"); + H5E_BEGIN_TRY + { + ret = H5VLregister_opt_operation(H5VL_SUBCLS_INFO, "fail2", &op_val); + } + H5E_END_TRY; + if (FAIL != ret) + FAIL_PUTS_ERROR("should not be able to register an optional operation for the 'INFO' VOL subclass"); + if ((-1) != op_val) + FAIL_PUTS_ERROR("'op_val' changed during failed operation?"); + H5E_BEGIN_TRY + { + ret = H5VLregister_opt_operation(H5VL_SUBCLS_WRAP, "fail3", &op_val); + } + H5E_END_TRY; + if (FAIL != ret) + FAIL_PUTS_ERROR("should not be able to register an optional operation for the 'WRAP' VOL subclass"); + if ((-1) != op_val) + FAIL_PUTS_ERROR("'op_val' changed during failed operation?"); + H5E_BEGIN_TRY + { + ret = H5VLregister_opt_operation(H5VL_SUBCLS_BLOB, "fail4", &op_val); + } + H5E_END_TRY; + if (FAIL != ret) + FAIL_PUTS_ERROR("should not be able to register an optional operation for the 'BLOB' VOL subclass"); + if ((-1) != op_val) + FAIL_PUTS_ERROR("'op_val' changed during failed operation?"); + H5E_BEGIN_TRY + { + ret = H5VLregister_opt_operation(H5VL_SUBCLS_TOKEN, "fail5", &op_val); + } + H5E_END_TRY; + if (FAIL != ret) + FAIL_PUTS_ERROR("should not be able to register an optional operation for the 'TOKEN' VOL subclass"); + if ((-1) != op_val) + FAIL_PUTS_ERROR("'op_val' changed during failed operation?"); + + /* Test registering valid optional VOL subclass operation with NULL op_val ptr*/ + H5E_BEGIN_TRY + { + ret = H5VLregister_opt_operation(H5VL_SUBCLS_FILE, "fail6", NULL); + } + H5E_END_TRY; + if (FAIL != ret) + FAIL_PUTS_ERROR("should not be able to register an optional operation with a NULL 'op_val'"); + + /* Try finding a non-existent optional VOL subclass operation */ + H5E_BEGIN_TRY + { + ret = H5VLfind_opt_operation(H5VL_SUBCLS_DATASET, "fail", &op_val); + } + H5E_END_TRY; + if (FAIL != ret) + FAIL_PUTS_ERROR("should not be able to find a non-existent optional operation"); + + /* Try unregistering a non-existent optional VOL subclass operation */ + H5E_BEGIN_TRY + { + ret = H5VLunregister_opt_operation(H5VL_SUBCLS_DATASET, "fail"); + } + H5E_END_TRY; + if (FAIL != ret) + FAIL_PUTS_ERROR("should not be able to unregister a non-existent optional operation"); + + /* Optional operations on requests are supported (but difficult to test further) */ + if (H5VLregister_opt_operation(H5VL_SUBCLS_REQUEST, "req_op", &op_val) < 0) + TEST_ERROR; + + /* Register & test calling optional operations for each valid VOL subclass */ + /* (Table-driven, with test_params array) */ + for (u = 0; u < NELMTS(test_params); u++) + /* Exercise appropriate callback, for each VOL subclass */ + if (exercise_reg_opt_oper(fake_vol_id, reg_opt_vol_id, test_params[u].subcls, + test_params[u].subcls_name, test_params[u].id_type, + test_params[u].reg_opt_op) < 0) + TEST_ERROR; + + /* Unregister the VOL connectors */ + if (H5VLunregister_connector(fake_vol_id) < 0) + TEST_ERROR; + if (H5VLunregister_connector(reg_opt_vol_id) < 0) + TEST_ERROR; + + PASSED(); + + return SUCCEED; + +error: + H5E_BEGIN_TRY + { + H5VLunregister_connector(fake_vol_id); + H5VLunregister_connector(reg_opt_vol_id); + } + H5E_END_TRY; + + return FAIL; +} /* end test_register_opt_operation() */ + +/*------------------------------------------------------------------------- + * Function: test_async_vol_props() + * + * Purpose: Test properties related to asynchronous VOL connector operation + * + * Note: Overrides the HDF5_VOL_CONNECTOR environment variable, to + * provide stable testing environment. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +test_async_vol_props(void) +{ + hid_t fapl_id = H5I_INVALID_HID; + hid_t vol_id = H5I_INVALID_HID; + H5VL_pass_through_info_t passthru_info; + unsigned cap_flags = 0; + char * conn_env_str = NULL; + + TESTING("Async VOL props"); + + /* Retrieve the file access property for testing */ + fapl_id = h5_fileaccess(); + + /* Test 'capability flags' property */ + + /* Test query w/NULL for cap_flags parameter */ + if (H5Pget_vol_cap_flags(fapl_id, NULL) < 0) + FAIL_STACK_ERROR; + + /* Override possible environment variable & re-initialize default VOL connector */ + conn_env_str = HDgetenv("HDF5_VOL_CONNECTOR"); + if (conn_env_str) { + if (NULL == (conn_env_str = HDstrdup(conn_env_str))) + TEST_ERROR + if (HDunsetenv("HDF5_VOL_CONNECTOR") < 0) + TEST_ERROR + if (H5VL__reparse_def_vol_conn_variable_test() < 0) + TEST_ERROR + } /* end if */ + + /* Test query w/default VOL, which should indicate no async, since native connector + * doesn't support async. + */ + if (H5Pget_vol_cap_flags(fapl_id, &cap_flags) < 0) + FAIL_STACK_ERROR; + if ((cap_flags & H5VL_CAP_FLAG_ASYNC) > 0) + TEST_ERROR + if ((cap_flags & H5VL_CAP_FLAG_NATIVE_FILES) == 0) + TEST_ERROR + + /* Close FAPL */ + if (H5Pclose(fapl_id) < 0) + FAIL_STACK_ERROR; + + /* Register a fake VOL connector that sets the async capability flag */ + if ((vol_id = H5VLregister_connector(&fake_async_vol_g, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR; + + /* Set environment variable to use 'fake async' connector & re-init default connector */ + if (HDsetenv("HDF5_VOL_CONNECTOR", "fake_async", TRUE) < 0) + TEST_ERROR + if (H5VL__reparse_def_vol_conn_variable_test() < 0) + TEST_ERROR + + /* Retrieve the file access property again */ + fapl_id = h5_fileaccess(); + + /* Test query w/fake async VOL, which should succeed */ + cap_flags = 0; + if (H5Pget_vol_cap_flags(fapl_id, &cap_flags) < 0) + FAIL_STACK_ERROR; + if ((cap_flags & H5VL_CAP_FLAG_ASYNC) == 0) + TEST_ERROR + if ((cap_flags & H5VL_CAP_FLAG_NATIVE_FILES) > 0) + TEST_ERROR + + /* Reset environment variable & re-init default connector */ + if (HDunsetenv("HDF5_VOL_CONNECTOR") < 0) + TEST_ERROR + if (H5VL__reparse_def_vol_conn_variable_test() < 0) + TEST_ERROR + + /* Close FAPL */ + if (H5Pclose(fapl_id) < 0) + FAIL_STACK_ERROR; + + /* Retrieve the file access property again */ + fapl_id = h5_fileaccess(); + + /* Set the VOL connector for the FAPL to the fake async connector */ + if (H5Pset_vol(fapl_id, vol_id, NULL) < 0) + FAIL_STACK_ERROR; + + /* Test query w/fake async VOL, which should succeed */ + cap_flags = 0; + if (H5Pget_vol_cap_flags(fapl_id, &cap_flags) < 0) + FAIL_STACK_ERROR; + if ((cap_flags & H5VL_CAP_FLAG_ASYNC) == 0) + TEST_ERROR + if ((cap_flags & H5VL_CAP_FLAG_NATIVE_FILES) > 0) + TEST_ERROR + + /* Stack the [internal] passthrough VOL connector on top of the fake async connector */ + passthru_info.under_vol_id = vol_id; + passthru_info.under_vol_info = NULL; + if (H5Pset_vol(fapl_id, H5VL_PASSTHRU, &passthru_info) < 0) + FAIL_STACK_ERROR; + + /* Test query w/passthru -> fake async VOL, which should succeed */ + cap_flags = 0; + if (H5Pget_vol_cap_flags(fapl_id, &cap_flags) < 0) + FAIL_STACK_ERROR; + if ((cap_flags & H5VL_CAP_FLAG_ASYNC) == 0) + TEST_ERROR + if ((cap_flags & H5VL_CAP_FLAG_NATIVE_FILES) > 0) + TEST_ERROR + + /* Unregister the fake async VOL ID */ + if (H5VLunregister_connector(vol_id) < 0) + TEST_ERROR; + + /* Close FAPL */ + if (H5Pclose(fapl_id) < 0) + FAIL_STACK_ERROR; + + /* Restore environment variable, if there was one */ + if (conn_env_str) { + if (HDsetenv("HDF5_VOL_CONNECTOR", conn_env_str, TRUE) < 0) + TEST_ERROR + HDfree(conn_env_str); + + if (H5VL__reparse_def_vol_conn_variable_test() < 0) + TEST_ERROR + } /* end if */ + + PASSED(); + + return SUCCEED; + +error: + H5E_BEGIN_TRY + { + H5Pclose(fapl_id); + H5VLunregister_connector(vol_id); + } + H5E_END_TRY; + HDfree(conn_env_str); + + return FAIL; +} /* end test_async_vol_props() */ + /*------------------------------------------------------------------------- * Function: main * @@ -1201,6 +2121,7 @@ main(void) HDputs("Testing basic Virtual Object Layer (VOL) functionality."); nerrors += test_vol_registration() < 0 ? 1 : 0; + nerrors += test_register_opt_operation() < 0 ? 1 : 0; nerrors += test_native_vol_init() < 0 ? 1 : 0; nerrors += test_basic_file_operation(env_h5_drvr) < 0 ? 1 : 0; nerrors += test_basic_group_operation() < 0 ? 1 : 0; @@ -1209,6 +2130,7 @@ main(void) nerrors += test_basic_object_operation() < 0 ? 1 : 0; nerrors += test_basic_link_operation() < 0 ? 1 : 0; nerrors += test_basic_datatype_operation() < 0 ? 1 : 0; + nerrors += test_async_vol_props() < 0 ? 1 : 0; if (nerrors) { HDprintf("***** %d Virtual Object Layer TEST%s FAILED! *****\n", nerrors, nerrors > 1 ? "S" : ""); diff --git a/testpar/t_filters_parallel.c b/testpar/t_filters_parallel.c index 694992a..78af0fb 100644 --- a/testpar/t_filters_parallel.c +++ b/testpar/t_filters_parallel.c @@ -62,6 +62,7 @@ static void test_write_filtered_dataset_single_no_selection(void); static void test_write_filtered_dataset_all_no_selection(void); static void test_write_filtered_dataset_point_selection(void); static void test_write_filtered_dataset_interleaved_write(void); +static void test_write_transformed_filtered_dataset_no_overlap(void); static void test_write_3d_filtered_dataset_no_overlap_separate_pages(void); static void test_write_3d_filtered_dataset_no_overlap_same_pages(void); static void test_write_3d_filtered_dataset_overlap(void); @@ -79,6 +80,7 @@ static void test_read_filtered_dataset_single_no_selection(void); static void test_read_filtered_dataset_all_no_selection(void); static void test_read_filtered_dataset_point_selection(void); static void test_read_filtered_dataset_interleaved_read(void); +static void test_read_transformed_filtered_dataset_no_overlap(void); static void test_read_3d_filtered_dataset_no_overlap_separate_pages(void); static void test_read_3d_filtered_dataset_no_overlap_same_pages(void); static void test_read_3d_filtered_dataset_overlap(void); @@ -120,6 +122,7 @@ static void (*tests[])(void) = { test_write_filtered_dataset_all_no_selection, test_write_filtered_dataset_point_selection, test_write_filtered_dataset_interleaved_write, + test_write_transformed_filtered_dataset_no_overlap, test_write_3d_filtered_dataset_no_overlap_separate_pages, test_write_3d_filtered_dataset_no_overlap_same_pages, test_write_3d_filtered_dataset_overlap, @@ -135,6 +138,7 @@ static void (*tests[])(void) = { test_read_filtered_dataset_all_no_selection, test_read_filtered_dataset_point_selection, test_read_filtered_dataset_interleaved_read, + test_read_transformed_filtered_dataset_no_overlap, test_read_3d_filtered_dataset_no_overlap_separate_pages, test_read_3d_filtered_dataset_no_overlap_same_pages, test_read_3d_filtered_dataset_overlap, @@ -428,7 +432,7 @@ test_write_filtered_dataset_no_overlap(void) /* Select hyperslab in the file */ filespace = H5Dget_space(dset_id); - VRFY((dset_id >= 0), "File dataspace retrieval succeeded"); + VRFY((filespace >= 0), "File dataspace retrieval succeeded"); VRFY((H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, stride, count, block) >= 0), "Hyperslab selection succeeded"); @@ -1288,6 +1292,177 @@ test_write_filtered_dataset_interleaved_write(void) } /* + * Tests parallel write of transformed and filtered data + * in the case where only one process is writing to a + * particular chunk in the operation. Normally, a data + * transform function will cause the parallel library to + * break to independent I/O and this isn't allowed when + * there are filters in the pipeline. However, in this + * case the parallel library recognizes that the used + * data transform function "x" is the same as not applying + * the transform function. Therefore it does not apply + * the transform function resulting in not breaking to + * independent I/O. + * + * Programmer: Jan-Willem Blokland + * 08/20/2021 + */ +static void +test_write_transformed_filtered_dataset_no_overlap(void) +{ + C_DATATYPE *data = NULL; + C_DATATYPE *read_buf = NULL; + C_DATATYPE *correct_buf = NULL; + hsize_t dataset_dims[WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t chunk_dims[WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t sel_dims[WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t start[WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t stride[WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t count[WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t block[WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + size_t i, data_size, correct_buf_size; + hid_t file_id = -1, dset_id = -1, plist_id = -1; + hid_t filespace = -1, memspace = -1; + + if (MAINPROCESS) + HDputs("Testing write to unshared transformed and filtered chunks"); + + CHECK_CUR_FILTER_AVAIL(); + + /* Set up file access property list with parallel I/O access */ + plist_id = H5Pcreate(H5P_FILE_ACCESS); + VRFY((plist_id >= 0), "FAPL creation succeeded"); + + VRFY((H5Pset_fapl_mpio(plist_id, comm, info) >= 0), "Set FAPL MPIO succeeded"); + + VRFY((H5Pset_libver_bounds(plist_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) >= 0), + "Set libver bounds succeeded"); + + file_id = H5Fopen(filenames[0], H5F_ACC_RDWR, plist_id); + VRFY((file_id >= 0), "Test file open succeeded"); + + VRFY((H5Pclose(plist_id) >= 0), "FAPL close succeeded"); + + /* Create the dataspace for the dataset */ + dataset_dims[0] = (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NROWS; + dataset_dims[1] = (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NCOLS; + chunk_dims[0] = (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS; + chunk_dims[1] = (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NCOLS; + sel_dims[0] = (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS; + sel_dims[1] = (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NCOLS; + + filespace = H5Screate_simple(WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS, dataset_dims, NULL); + VRFY((filespace >= 0), "File dataspace creation succeeded"); + + memspace = H5Screate_simple(WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS, sel_dims, NULL); + VRFY((memspace >= 0), "Memory dataspace creation succeeded"); + + /* Create chunked dataset */ + plist_id = H5Pcreate(H5P_DATASET_CREATE); + VRFY((plist_id >= 0), "DCPL creation succeeded"); + + VRFY((H5Pset_chunk(plist_id, WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS, chunk_dims) >= 0), + "Chunk size set"); + + /* Add test filter to the pipeline */ + VRFY((set_dcpl_filter(plist_id) >= 0), "Filter set"); + + dset_id = H5Dcreate2(file_id, WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_NAME, HDF5_DATATYPE_NAME, + filespace, H5P_DEFAULT, plist_id, H5P_DEFAULT); + VRFY((dset_id >= 0), "Dataset creation succeeded"); + + VRFY((H5Pclose(plist_id) >= 0), "DCPL close succeeded"); + VRFY((H5Sclose(filespace) >= 0), "File dataspace close succeeded"); + + /* Each process defines the dataset selection in memory and writes + * it to the hyperslab in the file + */ + count[0] = 1; + count[1] = (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NCOLS / + (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NCOLS; + stride[0] = (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS; + stride[1] = (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NCOLS; + block[0] = (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS; + block[1] = (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NCOLS; + start[0] = ((hsize_t)mpi_rank * (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS * count[0]); + start[1] = 0; + + if (VERBOSE_MED) { + HDprintf("Process %d is writing with count[ %" PRIuHSIZE ", %" PRIuHSIZE " ], stride[ %" PRIuHSIZE + ", %" PRIuHSIZE " ], start[ %" PRIuHSIZE ", %" PRIuHSIZE " ], block size[ %" PRIuHSIZE + ", %" PRIuHSIZE " ]\n", + mpi_rank, count[0], count[1], stride[0], stride[1], start[0], start[1], block[0], block[1]); + HDfflush(stdout); + } + + /* Select hyperslab in the file */ + filespace = H5Dget_space(dset_id); + VRFY((filespace >= 0), "File dataspace retrieval succeeded"); + + VRFY((H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, stride, count, block) >= 0), + "Hyperslab selection succeeded"); + + /* Fill data buffer */ + data_size = sel_dims[0] * sel_dims[1] * sizeof(*data); + correct_buf_size = dataset_dims[0] * dataset_dims[1] * sizeof(*correct_buf); + + data = (C_DATATYPE *)HDcalloc(1, data_size); + VRFY((NULL != data), "HDcalloc succeeded"); + + correct_buf = (C_DATATYPE *)HDcalloc(1, correct_buf_size); + VRFY((NULL != correct_buf), "HDcalloc succeeded"); + + for (i = 0; i < data_size / sizeof(*data); i++) + data[i] = (C_DATATYPE)GEN_DATA(i); + + for (i = 0; i < correct_buf_size / sizeof(*correct_buf); i++) + correct_buf[i] = (C_DATATYPE)((i % (dataset_dims[0] / (hsize_t)mpi_size * dataset_dims[1])) + + (i / (dataset_dims[0] / (hsize_t)mpi_size * dataset_dims[1]))); + + /* Create property list for collective dataset write and data transform */ + plist_id = H5Pcreate(H5P_DATASET_XFER); + VRFY((plist_id >= 0), "DXPL creation succeeded"); + + VRFY((H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_COLLECTIVE) >= 0), "Set DXPL MPIO succeeded"); + + /* Set data transform expression */ + VRFY((H5Pset_data_transform(plist_id, "x") >= 0), "Set data transform expression succeeded"); + + VRFY((H5Dwrite(dset_id, HDF5_DATATYPE_NAME, memspace, filespace, plist_id, data) >= 0), + "Dataset write succeeded"); + + if (data) + HDfree(data); + + VRFY((H5Dclose(dset_id) >= 0), "Dataset close succeeded"); + + /* Verify the correct data was written */ + read_buf = (C_DATATYPE *)HDcalloc(1, correct_buf_size); + VRFY((NULL != read_buf), "HDcalloc succeeded"); + + dset_id = H5Dopen2(file_id, "/" WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_NAME, H5P_DEFAULT); + VRFY((dset_id >= 0), "Dataset open succeeded"); + + VRFY((H5Dread(dset_id, HDF5_DATATYPE_NAME, H5S_ALL, H5S_ALL, plist_id, read_buf) >= 0), + "Dataset read succeeded"); + + VRFY((0 == HDmemcmp(read_buf, correct_buf, correct_buf_size)), "Data verification succeeded"); + + if (correct_buf) + HDfree(correct_buf); + if (read_buf) + HDfree(read_buf); + + VRFY((H5Dclose(dset_id) >= 0), "Dataset close succeeded"); + VRFY((H5Sclose(filespace) >= 0), "File dataspace close succeeded"); + VRFY((H5Sclose(memspace) >= 0), "Memory dataspace close succeeded"); + VRFY((H5Pclose(plist_id) >= 0), "DXPL close succeeded"); + VRFY((H5Fclose(file_id) >= 0), "File close succeeded"); + + return; +} + +/* * Tests parallel write of filtered data in the case where * the dataset has 3 dimensions and each process writes * to its own "page" in the 3rd dimension. @@ -4224,6 +4399,232 @@ test_read_3d_filtered_dataset_no_overlap_separate_pages(void) } /* + * Tests parallel read of transformed and filtered data in the + * case where only one process is reading from a particular + * chunk in the operation. Normally, a data transform function + * will cause the parallel library to break to independent I/O + * and this isn't allowed when there are filters in the pipeline. + * However, in this case the parallel library recognizes that + * the used data transform function "x" is the same as not + * applying the transform function. Therefore it does not apply + * the transform function resulting in not breaking to + * independent I/O. + * + * The MAINPROCESS rank will first write out all of the + * data to the dataset. Then, each rank reads a part of + * the dataset and contributes its piece to a global buffer + * that is checked for consistency. + * + * Programmer: Jan-Willem Blokland + * 08/20/2021 + */ +static void +test_read_transformed_filtered_dataset_no_overlap(void) +{ + C_DATATYPE *read_buf = NULL; + C_DATATYPE *correct_buf = NULL; + C_DATATYPE *global_buf = NULL; + hsize_t dataset_dims[READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t chunk_dims[READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t sel_dims[READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t start[READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t stride[READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t count[READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t block[READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t flat_dims[1]; + size_t i, read_buf_size, correct_buf_size; + hid_t file_id = -1, dset_id = -1, plist_id = -1; + hid_t filespace = -1, memspace = -1; + int * recvcounts = NULL; + int * displs = NULL; + + if (MAINPROCESS) + HDputs("Testing read from unshared transformed and filtered chunks"); + + CHECK_CUR_FILTER_AVAIL(); + + dataset_dims[0] = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NROWS; + dataset_dims[1] = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NCOLS; + + /* Setup the buffer for writing and for comparison */ + correct_buf_size = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NROWS * + (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NCOLS * sizeof(*correct_buf); + + correct_buf = (C_DATATYPE *)HDcalloc(1, correct_buf_size); + VRFY((NULL != correct_buf), "HDcalloc succeeded"); + + for (i = 0; i < correct_buf_size / sizeof(*correct_buf); i++) + correct_buf[i] = (C_DATATYPE)((i % (dataset_dims[0] / (hsize_t)mpi_size * dataset_dims[1])) + + (i / (dataset_dims[0] / (hsize_t)mpi_size * dataset_dims[1]))); + + if (MAINPROCESS) { + plist_id = H5Pcreate(H5P_FILE_ACCESS); + VRFY((plist_id >= 0), "FAPL creation succeeded"); + + VRFY((H5Pset_libver_bounds(plist_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) >= 0), + "Set libver bounds succeeded"); + + file_id = H5Fopen(filenames[0], H5F_ACC_RDWR, plist_id); + VRFY((file_id >= 0), "Test file open succeeded"); + + VRFY((H5Pclose(plist_id) >= 0), "FAPL close succeeded"); + + /* Create the dataspace for the dataset */ + filespace = + H5Screate_simple(READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS, dataset_dims, NULL); + VRFY((filespace >= 0), "File dataspace creation succeeded"); + + /* Create chunked dataset */ + chunk_dims[0] = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS; + chunk_dims[1] = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NCOLS; + + plist_id = H5Pcreate(H5P_DATASET_CREATE); + VRFY((plist_id >= 0), "DCPL creation succeeded"); + + VRFY( + (H5Pset_chunk(plist_id, READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS, chunk_dims) >= 0), + "Chunk size set"); + + /* Add test filter to the pipeline */ + VRFY((set_dcpl_filter(plist_id) >= 0), "Filter set"); + + dset_id = H5Dcreate2(file_id, READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_NAME, + HDF5_DATATYPE_NAME, filespace, H5P_DEFAULT, plist_id, H5P_DEFAULT); + VRFY((dset_id >= 0), "Dataset creation succeeded"); + + VRFY((H5Pclose(plist_id) >= 0), "DCPL close succeeded"); + VRFY((H5Sclose(filespace) >= 0), "File dataspace close succeeded"); + + /* Create property list for collective dataset read */ + plist_id = H5Pcreate(H5P_DATASET_XFER); + VRFY((plist_id >= 0), "DXPL creation succeeded"); + + /* Set data transform expression */ + VRFY((H5Pset_data_transform(plist_id, "x") >= 0), "Set data transform expression succeeded"); + + VRFY((H5Dwrite(dset_id, HDF5_DATATYPE_NAME, H5S_ALL, H5S_ALL, plist_id, correct_buf) >= 0), + "Dataset write succeeded"); + + VRFY((H5Pclose(plist_id) >= 0), "DXPL close succeeded"); + VRFY((H5Dclose(dset_id) >= 0), "Dataset close succeeded"); + VRFY((H5Fclose(file_id) >= 0), "File close succeeded"); + } + + /* Set up file access property list with parallel I/O access */ + plist_id = H5Pcreate(H5P_FILE_ACCESS); + VRFY((plist_id >= 0), "FAPL creation succeeded"); + + VRFY((H5Pset_fapl_mpio(plist_id, comm, info) >= 0), "Set FAPL MPIO succeeded"); + + VRFY((H5Pset_libver_bounds(plist_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) >= 0), + "Set libver bounds succeeded"); + + file_id = H5Fopen(filenames[0], H5F_ACC_RDONLY, plist_id); + VRFY((file_id >= 0), "Test file open succeeded"); + + VRFY((H5Pclose(plist_id) >= 0), "FAPL close succeeded"); + + dset_id = H5Dopen2(file_id, "/" READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_NAME, H5P_DEFAULT); + VRFY((dset_id >= 0), "Dataset open succeeded"); + + sel_dims[0] = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS; + sel_dims[1] = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NCOLS; + + /* Setup one-dimensional memory dataspace for reading the dataset data into a contiguous buffer */ + flat_dims[0] = sel_dims[0] * sel_dims[1]; + + memspace = H5Screate_simple(1, flat_dims, NULL); + VRFY((memspace >= 0), "Memory dataspace creation succeeded"); + + /* Select hyperslab in the file */ + filespace = H5Dget_space(dset_id); + VRFY((filespace >= 0), "File dataspace retrieval succeeded"); + + /* + * Each process defines the dataset selection in the file and reads + * it to the selection in memory + */ + count[0] = 1; + count[1] = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NCOLS / + (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NCOLS; + stride[0] = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS; + stride[1] = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NCOLS; + block[0] = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS; + block[1] = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NCOLS; + start[0] = ((hsize_t)mpi_rank * (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS * count[0]); + start[1] = 0; + + if (VERBOSE_MED) { + HDprintf("Process %d is reading with count[ %" PRIuHSIZE ", %" PRIuHSIZE " ], stride[ %" PRIuHSIZE + ", %" PRIuHSIZE " ], start[ %" PRIuHSIZE ", %" PRIuHSIZE " ], block size[ %" PRIuHSIZE + ", %" PRIuHSIZE " ]\n", + mpi_rank, count[0], count[1], stride[0], stride[1], start[0], start[1], block[0], block[1]); + HDfflush(stdout); + } + + VRFY((H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, stride, count, block) >= 0), + "Hyperslab selection succeeded"); + + /* Create property list for collective dataset read and data transform */ + plist_id = H5Pcreate(H5P_DATASET_XFER); + VRFY((plist_id >= 0), "DXPL creation succeeded"); + + VRFY((H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_COLLECTIVE) >= 0), "Set DXPL MPIO succeeded"); + + /* Set data transform expression */ + VRFY((H5Pset_data_transform(plist_id, "x") >= 0), "Set data transform expression succeeded"); + + read_buf_size = flat_dims[0] * sizeof(*read_buf); + + read_buf = (C_DATATYPE *)HDcalloc(1, read_buf_size); + VRFY((NULL != read_buf), "HDcalloc succeeded"); + + VRFY((H5Dread(dset_id, HDF5_DATATYPE_NAME, memspace, filespace, plist_id, read_buf) >= 0), + "Dataset read succeeded"); + + global_buf = (C_DATATYPE *)HDcalloc(1, correct_buf_size); + VRFY((NULL != global_buf), "HDcalloc succeeded"); + + /* Collect each piece of data from all ranks into a global buffer on all ranks */ + recvcounts = (int *)HDcalloc(1, (size_t)mpi_size * sizeof(*recvcounts)); + VRFY((NULL != recvcounts), "HDcalloc succeeded"); + + for (i = 0; i < (size_t)mpi_size; i++) + recvcounts[i] = (int)flat_dims[0]; + + displs = (int *)HDcalloc(1, (size_t)mpi_size * sizeof(*displs)); + VRFY((NULL != displs), "HDcalloc succeeded"); + + for (i = 0; i < (size_t)mpi_size; i++) + displs[i] = (int)(i * flat_dims[0]); + + VRFY((MPI_SUCCESS == MPI_Allgatherv(read_buf, (int)flat_dims[0], C_DATATYPE_MPI, global_buf, recvcounts, + displs, C_DATATYPE_MPI, comm)), + "MPI_Allgatherv succeeded"); + + VRFY((0 == HDmemcmp(global_buf, correct_buf, correct_buf_size)), "Data verification succeeded"); + + if (displs) + HDfree(displs); + if (recvcounts) + HDfree(recvcounts); + if (global_buf) + HDfree(global_buf); + if (read_buf) + HDfree(read_buf); + if (correct_buf) + HDfree(correct_buf); + + VRFY((H5Dclose(dset_id) >= 0), "Dataset close succeeded"); + VRFY((H5Sclose(filespace) >= 0), "File dataspace close succeeded"); + VRFY((H5Sclose(memspace) >= 0), "Memory dataspace close succeeded"); + VRFY((H5Pclose(plist_id) >= 0), "DXPL close succeeded"); + VRFY((H5Fclose(file_id) >= 0), "File close succeeded"); + + return; +} + +/* * Tests parallel read of filtered data in the case where * the dataset has 3 dimensions and each process reads from * each "page" in the 3rd dimension. However, no chunk on a diff --git a/testpar/t_filters_parallel.h b/testpar/t_filters_parallel.h index 3804c09..7eb34ed 100644 --- a/testpar/t_filters_parallel.h +++ b/testpar/t_filters_parallel.h @@ -138,6 +138,16 @@ typedef struct { #define INTERLEAVED_WRITE_FILTERED_DATASET_NCOLS \ (INTERLEAVED_WRITE_FILTERED_DATASET_CH_NCOLS * DIM1_SCALE_FACTOR) +/* Defines for the unshared transformed and filtered chunks write test */ +#define WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_NAME "unshared_transformed_filtered_chunks_write" +#define WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS 2 +#define WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NROWS (mpi_size * DIM0_SCALE_FACTOR) +#define WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NCOLS (mpi_size * DIM1_SCALE_FACTOR) +#define WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS \ + (WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NROWS / mpi_size) +#define WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NCOLS \ + (WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NCOLS / mpi_size) + /* Defines for the 3D unshared filtered dataset separate page write test */ #define WRITE_UNSHARED_FILTERED_CHUNKS_3D_SEP_PAGE_DATASET_NAME \ "3D_unshared_filtered_chunks_separate_pages_write" @@ -280,6 +290,16 @@ typedef struct { #define INTERLEAVED_READ_FILTERED_DATASET_NCOLS \ (INTERLEAVED_READ_FILTERED_DATASET_CH_NCOLS * DIM1_SCALE_FACTOR) +/* Defines for the unshared transformed and filtered chunks read test */ +#define READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_NAME "unshared_transformed_filtered_chunks_read" +#define READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS 2 +#define READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NROWS (mpi_size * DIM0_SCALE_FACTOR) +#define READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NCOLS (mpi_size * DIM1_SCALE_FACTOR) +#define READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS \ + (READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NROWS / mpi_size) +#define READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NCOLS \ + (READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NCOLS / mpi_size) + /* Defines for the 3D unshared filtered dataset separate page read test */ #define READ_UNSHARED_FILTERED_CHUNKS_3D_SEP_PAGE_DATASET_NAME \ "3D_unshared_filtered_chunks_separate_pages_read" diff --git a/tools/lib/h5diff_array.c b/tools/lib/h5diff_array.c index 43ded12..2d6c66c 100644 --- a/tools/lib/h5diff_array.c +++ b/tools/lib/h5diff_array.c @@ -104,9 +104,9 @@ static hbool_t not_comparable; per = -1; \ not_comparable = FALSE; \ both_zero = FALSE; \ - if (H5_DBL_ABS_EQUAL(0, (double)A) && H5_DBL_ABS_EQUAL(0, (double)B)) \ + if (H5_DBL_ABS_EQUAL(0, (double)(A)) && H5_DBL_ABS_EQUAL(0, (double)(B))) \ both_zero = TRUE; \ - if (!H5_DBL_ABS_EQUAL(0, (double)A)) \ + if (!H5_DBL_ABS_EQUAL(0, (double)(A))) \ per = (double)ABS((double)((B) - (A)) / (double)(A)); \ else \ not_comparable = TRUE; \ @@ -117,9 +117,9 @@ static hbool_t not_comparable; per = -1; \ not_comparable = FALSE; \ both_zero = FALSE; \ - if (H5_DBL_ABS_EQUAL(0, (double)A) && H5_DBL_ABS_EQUAL(0, (double)B)) \ + if (H5_DBL_ABS_EQUAL(0, (double)(A)) && H5_DBL_ABS_EQUAL(0, (double)(B))) \ both_zero = TRUE; \ - if (!H5_DBL_ABS_EQUAL(0, (double)A)) \ + if (!H5_DBL_ABS_EQUAL(0, (double)(A))) \ per = ABS((double)((TYPE)((B) - (A))) / (double)(A)); \ else \ not_comparable = TRUE; \ diff --git a/tools/lib/h5tools_str.c b/tools/lib/h5tools_str.c index 5fcaee6..abc0058 100644 --- a/tools/lib/h5tools_str.c +++ b/tools/lib/h5tools_str.c @@ -258,7 +258,8 @@ h5tools_str_fmt(h5tools_str_t *str /*in,out*/, size_t start, const char *fmt) HDassert(temp); } - HDstrncpy(temp, str->s + start, n); + HDstrncpy(temp, str->s + start, n - 1); + temp[n - 1] = '\0'; } /* Reset the output string and append a formatted version */ diff --git a/tools/libtest/Makefile.am b/tools/libtest/Makefile.am index a93e25d..1a08a01 100644 --- a/tools/libtest/Makefile.am +++ b/tools/libtest/Makefile.am @@ -1,16 +1,16 @@ # -# Read-Only S3 Virtual File Driver (VFD) -# Copyright (c) 2017-2018, The HDF Group. -# +# Copyright by The HDF Group. # All rights reserved. # # NOTICE: -# All information contained herein is, and remains, the property of The HDF -# Group. The intellectual and technical concepts contained herein are -# proprietary to The HDF Group. Dissemination of this information or -# reproduction of this material is strictly forbidden unless prior written -# permission is obtained from The HDF Group. -## +# +# 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. +# ## Makefile.am ## Run automake to generate a Makefile.in from this file. # diff --git a/tools/libtest/h5tools_test_utils.c b/tools/libtest/h5tools_test_utils.c index ba3877e..66d7ac7 100644 --- a/tools/libtest/h5tools_test_utils.c +++ b/tools/libtest/h5tools_test_utils.c @@ -69,7 +69,7 @@ * *****************************************************************************/ -H5_GCC_DIAG_OFF("format") +H5_GCC_CLANG_DIAG_OFF("format") /*---------------------------------------------------------------------------- * @@ -1255,7 +1255,7 @@ error: #undef UTIL_TEST_DEFAULT #undef UTIL_TEST_CREATE } /* test_set_configured_fapl */ -H5_GCC_DIAG_ON("format") +H5_GCC_CLANG_DIAG_ON("format") /*---------------------------------------------------------------------------- * diff --git a/tools/src/CMakeLists.txt b/tools/src/CMakeLists.txt index 8c3e361..e291f61 100644 --- a/tools/src/CMakeLists.txt +++ b/tools/src/CMakeLists.txt @@ -13,7 +13,7 @@ add_subdirectory (misc) #-- Add the h5import and test executables add_subdirectory (h5import) -#-- h5Repack executables +#-- h5repack executables add_subdirectory (h5repack) #-- Add the h5dump and test executables @@ -30,3 +30,6 @@ add_subdirectory (h5dump) #-- Add the h5format_convert and test executables add_subdirectory (h5format_convert) + +#-- h5perf executables +add_subdirectory (h5perf) diff --git a/tools/src/Makefile.am b/tools/src/Makefile.am index 397bd31..5af7d06 100644 --- a/tools/src/Makefile.am +++ b/tools/src/Makefile.am @@ -23,6 +23,6 @@ CONFIG=ordered # All subdirectories SUBDIRS=h5diff h5ls h5dump misc h5import h5repack h5jam h5copy \ - h5format_convert h5stat + h5format_convert h5stat h5perf include $(top_srcdir)/config/conclude.am diff --git a/tools/src/h5dump/h5dump.c b/tools/src/h5dump/h5dump.c index 70f03df..36114ba 100644 --- a/tools/src/h5dump/h5dump.c +++ b/tools/src/h5dump/h5dump.c @@ -82,124 +82,46 @@ struct handler_t { /* "xxx" "yyy" into "xxxyyy". */ static const char * s_opts = "a:b*c:d:ef:g:hik:l:m:n*o*pq:rs:t:uvw:xyz:A*BCD:E*F:G:HM:N:O*RS:VX:"; static struct h5_long_options l_opts[] = {{"attribute", require_arg, 'a'}, - {"attribut", require_arg, 'a'}, - {"attribu", require_arg, 'a'}, - {"attrib", require_arg, 'a'}, - {"attri", require_arg, 'a'}, - {"attr", require_arg, 'a'}, - {"att", require_arg, 'a'}, - {"at", require_arg, 'a'}, {"binary", optional_arg, 'b'}, {"count", require_arg, 'c'}, - {"coun", require_arg, 'c'}, - {"cou", require_arg, 'c'}, - {"co", require_arg, 'c'}, {"dataset", require_arg, 'd'}, - {"datase", require_arg, 'd'}, - {"datas", require_arg, 'd'}, {"escape", no_arg, 'e'}, {"filedriver", require_arg, 'f'}, - {"filedrive", require_arg, 'f'}, - {"filedriv", require_arg, 'f'}, - {"filedri", require_arg, 'f'}, - {"filedr", require_arg, 'f'}, - {"filed", require_arg, 'f'}, - {"file", require_arg, 'f'}, - {"fil", require_arg, 'f'}, - {"fi", require_arg, 'f'}, {"group", require_arg, 'g'}, - {"grou", require_arg, 'g'}, - {"gro", require_arg, 'g'}, - {"gr", require_arg, 'g'}, {"help", no_arg, 'h'}, - {"hel", no_arg, 'h'}, {"object-ids", no_arg, 'i'}, - {"object-id", no_arg, 'i'}, - {"object-i", no_arg, 'i'}, - {"object", no_arg, 'i'}, - {"objec", no_arg, 'i'}, - {"obje", no_arg, 'i'}, - {"obj", no_arg, 'i'}, - {"ob", no_arg, 'i'}, {"block", require_arg, 'k'}, - {"bloc", require_arg, 'k'}, - {"blo", require_arg, 'k'}, - {"bl", require_arg, 'k'}, {"soft-link", require_arg, 'l'}, - {"soft-lin", require_arg, 'l'}, - {"soft-li", require_arg, 'l'}, - {"soft-l", require_arg, 'l'}, - {"soft", require_arg, 'l'}, - {"sof", require_arg, 'l'}, {"format", require_arg, 'm'}, {"contents", optional_arg, 'n'}, {"output", optional_arg, 'o'}, - {"outpu", optional_arg, 'o'}, - {"outp", optional_arg, 'o'}, - {"out", optional_arg, 'o'}, - {"ou", optional_arg, 'o'}, {"properties", no_arg, 'p'}, {"sort_by", require_arg, 'q'}, {"string", no_arg, 'r'}, - {"strin", no_arg, 'r'}, {"start", require_arg, 's'}, - {"star", require_arg, 's'}, - {"sta", require_arg, 's'}, {"datatype", require_arg, 't'}, - {"datatyp", require_arg, 't'}, - {"dataty", require_arg, 't'}, - {"datat", require_arg, 't'}, {"use-dtd", no_arg, 'u'}, - {"use-dt", no_arg, 'u'}, - {"use-d", no_arg, 'u'}, - {"use-", no_arg, 'u'}, - {"use", no_arg, 'u'}, - {"us", no_arg, 'u'}, - {"u", no_arg, 'u'}, {"vds-view-first-missing", no_arg, 'v'}, {"width", require_arg, 'w'}, - {"widt", require_arg, 'w'}, - {"wid", require_arg, 'w'}, - {"wi", require_arg, 'w'}, {"xml", no_arg, 'x'}, - {"xm", no_arg, 'x'}, {"noindex", no_arg, 'y'}, {"sort_order", require_arg, 'z'}, {"onlyattr", optional_arg, 'A'}, {"superblock", no_arg, 'B'}, {"boot-block", no_arg, 'B'}, - {"boot-bloc", no_arg, 'B'}, - {"boot-blo", no_arg, 'B'}, - {"boot-bl", no_arg, 'B'}, - {"boot-b", no_arg, 'B'}, - {"boot", no_arg, 'B'}, - {"boo", no_arg, 'B'}, - {"bo", no_arg, 'B'}, {"no-compact-subset", no_arg, 'C'}, {"xml-dtd", require_arg, 'D'}, - {"xml-dt", require_arg, 'D'}, - {"xml-d", require_arg, 'D'}, {"enable-error-stack", optional_arg, 'E'}, {"form", require_arg, 'F'}, {"vds-gap-size", require_arg, 'G'}, {"header", no_arg, 'H'}, - {"heade", no_arg, 'H'}, - {"head", no_arg, 'H'}, - {"hea", no_arg, 'H'}, {"packed-bits", require_arg, 'M'}, {"any_path", require_arg, 'N'}, {"ddl", optional_arg, 'O'}, {"region", no_arg, 'R'}, {"stride", require_arg, 'S'}, - {"strid", require_arg, 'S'}, {"version", no_arg, 'V'}, - {"versio", no_arg, 'V'}, - {"versi", no_arg, 'V'}, - {"vers", no_arg, 'V'}, - {"ver", no_arg, 'V'}, - {"ve", no_arg, 'V'}, {"xml-ns", require_arg, 'X'}, - {"xml-n", require_arg, 'X'}, {"s3-cred", require_arg, '$'}, {"hdfs-attrs", require_arg, '#'}, {"vol-value", require_arg, '1'}, diff --git a/tools/src/h5dump/h5dump_ddl.c b/tools/src/h5dump/h5dump_ddl.c index 2a69ca6..638a738 100644 --- a/tools/src/h5dump/h5dump_ddl.c +++ b/tools/src/h5dump/h5dump_ddl.c @@ -1343,13 +1343,21 @@ attr_search(hid_t oid, const char *attr_name, const H5A_info_t H5_ATTR_UNUSED *a ret = FAIL; } else { + size_t buffer_space = w - 1; + HDmemset(obj_name, '\0', w); if (op_name[0] != '/') { - HDstrncat(obj_name, buf, u + 1); - if (buf[u - 1] != '/') - HDstrncat(obj_name, "/", (size_t)2); + HDstrncat(obj_name, buf, buffer_space); + buffer_space -= MIN(buffer_space, u); + + if (buf[u - 1] != '/') { + HDstrncat(obj_name, "/", buffer_space); + buffer_space -= MIN(buffer_space, 2); + } } - HDstrncat(obj_name, op_name, v + 1); + + HDstrncat(obj_name, op_name, buffer_space); + buffer_space -= MIN(buffer_space, v); handle_attributes(oid, obj_name, NULL, 0, NULL); HDfree(obj_name); @@ -1421,10 +1429,10 @@ lnk_search(const char *path, const H5L_info2_t *li, void *_op_data) else { if (k == 2) { HDstrcpy(search_name, "/"); - HDstrncat(search_name, op_name, search_len + 1); + HDstrcat(search_name, op_name); } else - HDstrncpy(search_name, op_name, search_len + 1); + HDstrcpy(search_name, op_name); search_name[search_len + k - 1] = '\0'; if (HDstrcmp(path, search_name) == 0) { diff --git a/tools/src/h5dump/h5dump_xml.c b/tools/src/h5dump/h5dump_xml.c index 5507dcc..0e881df 100644 --- a/tools/src/h5dump/h5dump_xml.c +++ b/tools/src/h5dump/h5dump_xml.c @@ -2365,14 +2365,21 @@ xml_dump_named_datatype(hid_t type, const char *name) h5tools_context_t ctx; /* print context */ h5tool_format_t * outputformat = &xml_dataformat; h5tool_format_t string_dataformat; - char * tmp; - char * dtxid; - char * parentxid; - char * t_tmp; - char * t_prefix; - char * t_name; + char * tmp = NULL; + char * dtxid = NULL; + char * parentxid = NULL; + char * t_tmp = NULL; + char * t_prefix = NULL; + char * t_name = NULL; tmp = (char *)HDmalloc(HDstrlen(prefix) + HDstrlen(name) + 2); + if (tmp == NULL) { + indentation(dump_indent); + error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } + HDstrcpy(tmp, prefix); HDstrcat(tmp, "/"); HDstrcat(tmp, name); @@ -2627,6 +2634,13 @@ xml_dump_group(hid_t gid, const char *name) } else { tmp = (char *)HDmalloc(HDstrlen(prefix) + HDstrlen(name) + 2); + if (tmp == NULL) { + indentation(dump_indent); + error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__); + h5tools_setstatus(EXIT_FAILURE); + return; + } + HDstrcpy(tmp, prefix); par = HDstrdup(tmp); cp = HDstrrchr(par, '/'); @@ -3146,8 +3160,11 @@ xml_print_strs(hid_t did, int source) } bp = (char *)buf; - if (!is_vlstr) + if (!is_vlstr) { onestring = (char *)HDcalloc(tsiz, sizeof(char)); + if (onestring == NULL) + goto error; + } /* setup */ HDmemset(&buffer, 0, sizeof(h5tools_str_t)); @@ -3768,6 +3785,14 @@ xml_dump_dataset(hid_t did, const char *name, struct subset_t H5_ATTR_UNUSED *ss char *pstr = (char *)HDmalloc((size_t)100); tmp = (char *)HDmalloc(HDstrlen(prefix) + HDstrlen(name) + 2); + if (tmp == NULL) { + error_msg("buffer allocation failed\n"); + h5tools_setstatus(EXIT_FAILURE); + HDfree(rstr); + HDfree(pstr); + return; + } + HDstrcpy(tmp, prefix); HDstrcat(tmp, "/"); HDstrcat(tmp, name); diff --git a/tools/src/h5format_convert/h5format_convert.c b/tools/src/h5format_convert/h5format_convert.c index 3430c55..ddf129c 100644 --- a/tools/src/h5format_convert/h5format_convert.c +++ b/tools/src/h5format_convert/h5format_convert.c @@ -39,26 +39,9 @@ static int verbose_g = 0; * parameters. */ static const char * s_opts = "hVvd:n"; -static struct h5_long_options l_opts[] = {{"help", no_arg, 'h'}, - {"hel", no_arg, 'h'}, - {"he", no_arg, 'h'}, - {"version", no_arg, 'V'}, - {"version", no_arg, 'V'}, - {"versio", no_arg, 'V'}, - {"versi", no_arg, 'V'}, - {"vers", no_arg, 'V'}, - {"verbose", no_arg, 'v'}, - {"verbos", no_arg, 'v'}, - {"verbo", no_arg, 'v'}, - {"verb", no_arg, 'v'}, - {"dname", require_arg, 'd'}, - {"dnam", require_arg, 'd'}, - {"dna", require_arg, 'd'}, - {"dn", require_arg, 'd'}, - {"noop", no_arg, 'n'}, - {"noo", no_arg, 'n'}, - {"no", no_arg, 'n'}, - {"enable-error-stack", no_arg, 'E'}, +static struct h5_long_options l_opts[] = {{"help", no_arg, 'h'}, {"version", no_arg, 'V'}, + {"verbose", no_arg, 'v'}, {"dname", require_arg, 'd'}, + {"noop", no_arg, 'n'}, {"enable-error-stack", no_arg, 'E'}, {NULL, 0, '\0'}}; /*------------------------------------------------------------------------- diff --git a/tools/src/h5import/h5import.c b/tools/src/h5import/h5import.c index 04e1c35..6517e43 100644 --- a/tools/src/h5import/h5import.c +++ b/tools/src/h5import/h5import.c @@ -3771,6 +3771,7 @@ getCompressionParameter(struct Input *in, FILE *strm) static int getExternalFilename(struct Input *in, FILE *strm) { + size_t temp_len; char temp[255]; const char *err1 = "Unable to get 'string' value.\n"; @@ -3779,8 +3780,10 @@ getExternalFilename(struct Input *in, FILE *strm) return (-1); } - in->externFilename = (char *)HDmalloc((size_t)(HDstrlen(temp) + 1) * sizeof(char)); - (void)HDstrncpy(in->externFilename, temp, HDstrlen(temp) + 1); + temp_len = HDstrlen(temp); + in->externFilename = (char *)HDmalloc((temp_len + 1) * sizeof(char)); + (void)HDstrcpy(in->externFilename, temp); + in->externFilename[temp_len] = '\0'; return (0); } diff --git a/tools/src/h5jam/h5jam.c b/tools/src/h5jam/h5jam.c index 0a2ea5d..7f3385c 100644 --- a/tools/src/h5jam/h5jam.c +++ b/tools/src/h5jam/h5jam.c @@ -34,14 +34,10 @@ char *ub_file = NULL; * parameters. The long-named ones can be partially spelled. When * adding more, make sure that they don't clash with each other. */ -static const char * s_opts = "hi:u:o:c:V"; /* add more later ? */ -static struct h5_long_options l_opts[] = { - {"help", no_arg, 'h'}, {"hel", no_arg, 'h'}, {"i", require_arg, 'i'}, /* input file */ - {"u", require_arg, 'u'}, /* user block file */ - {"o", require_arg, 'o'}, /* output file */ - {"clobber", no_arg, 'c'}, /* clobber existing UB */ - {"clobbe", no_arg, 'c'}, {"clobb", no_arg, 'c'}, {"clob", no_arg, 'c'}, - {"clo", no_arg, 'c'}, {"cl", no_arg, 'c'}, {NULL, 0, '\0'}}; +static const char * s_opts = "hi:u:o:c:V"; +static struct h5_long_options l_opts[] = {{"help", no_arg, 'h'}, {"i", require_arg, 'i'}, + {"u", require_arg, 'u'}, {"o", require_arg, 'o'}, + {"clobber", no_arg, 'c'}, {NULL, 0, '\0'}}; /*------------------------------------------------------------------------- * Function: usage diff --git a/tools/src/h5jam/h5unjam.c b/tools/src/h5jam/h5unjam.c index 38d1a5e..fa23b06 100644 --- a/tools/src/h5jam/h5unjam.c +++ b/tools/src/h5jam/h5unjam.c @@ -36,13 +36,9 @@ char *ub_file = NULL; * adding more, make sure that they don't clash with each other. */ static const char * s_opts = "hu:i:o:d:V"; -static struct h5_long_options l_opts[] = { - {"help", no_arg, 'h'}, {"hel", no_arg, 'h'}, {"i", require_arg, 'i'}, /* input file */ - {"u", require_arg, 'u'}, /* user block file */ - {"o", require_arg, 'o'}, /* output file */ - {"delete", no_arg, 'd'}, /* delete ub */ - {"delet", no_arg, 'd'}, {"dele", no_arg, 'd'}, {"del", no_arg, 'd'}, - {"de", no_arg, 'd'}, {NULL, 0, '\0'}}; +static struct h5_long_options l_opts[] = {{"help", no_arg, 'h'}, {"i", require_arg, 'i'}, + {"u", require_arg, 'u'}, {"o", require_arg, 'o'}, + {"delete", no_arg, 'd'}, {NULL, 0, '\0'}}; /*------------------------------------------------------------------------- * Function: usage diff --git a/tools/src/h5perf/CMakeLists.txt b/tools/src/h5perf/CMakeLists.txt new file mode 100644 index 0000000..36b0b2f --- /dev/null +++ b/tools/src/h5perf/CMakeLists.txt @@ -0,0 +1,103 @@ +cmake_minimum_required (VERSION 3.12) +project (HDF5_TOOLS_SRC_H5PERF C) + +# -------------------------------------------------------------------- +# Add the executables +# -------------------------------------------------------------------- +#-- Adding test for h5perf_serial +set (h5perf_serial_SOURCES + ${HDF5_TOOLS_SRC_H5PERF_SOURCE_DIR}/sio_perf.c + ${HDF5_TOOLS_SRC_H5PERF_SOURCE_DIR}/sio_engine.c +) +add_executable (h5perf_serial ${h5perf_serial_SOURCES}) +target_include_directories (h5perf_serial PRIVATE "${HDF5_TEST_SRC_DIR};${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") +if (NOT ONLY_SHARED_LIBS) + TARGET_C_PROPERTIES (h5perf_serial STATIC) + target_link_libraries (h5perf_serial PRIVATE ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET}) +else () + TARGET_C_PROPERTIES (h5perf_serial SHARED) + target_link_libraries (h5perf_serial PRIVATE ${HDF5_TOOLS_LIBSH_TARGET} ${HDF5_LIBSH_TARGET}) +endif () +set_target_properties (h5perf_serial PROPERTIES FOLDER perform) +set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5perf_serial") + +set (H5_DEP_EXECUTABLES h5perf_serial) + +#----------------------------------------------------------------------------- +# Add Target to clang-format +#----------------------------------------------------------------------------- +if (HDF5_ENABLE_FORMATTERS) + clang_format (HDF5_TOOLS_SRC_H5PERF_h5perf_serial_FORMAT h5perf_serial) +endif () + +if (H5_HAVE_PARALLEL) + if (UNIX) + #-- Adding test for perf - only on unix systems + set (perf_SOURCES + ${HDF5_TOOLS_SRC_H5PERF_SOURCE_DIR}/perf.c + ) + add_executable (perf ${perf_SOURCES}) + target_include_directories (perf PRIVATE "${HDF5_TEST_SRC_DIR};${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") + if (NOT ONLY_SHARED_LIBS) + TARGET_C_PROPERTIES (perf STATIC) + target_link_libraries (perf PRIVATE ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET} "$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_LIBRARIES}>") + else () + TARGET_C_PROPERTIES (perf SHARED) + target_link_libraries (perf PRIVATE ${HDF5_TOOLS_LIBSH_TARGET} ${HDF5_LIBSH_TARGET} "$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_LIBRARIES}>") + endif () + set_target_properties (perf PROPERTIES FOLDER perform) + set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};perf") + + set (H5_DEP_EXECUTABLES perf) + + #----------------------------------------------------------------------------- + # Add Target to clang-format + #----------------------------------------------------------------------------- + if (HDF5_ENABLE_FORMATTERS) + clang_format (HDF5_TOOLS_SRC_H5PERF_perf_FORMAT perf) + endif () + endif () + + #-- Adding test for h5perf + set (h5perf_SOURCES + ${HDF5_TOOLS_SRC_H5PERF_SOURCE_DIR}/pio_perf.c + ${HDF5_TOOLS_SRC_H5PERF_SOURCE_DIR}/pio_engine.c + ) + add_executable (h5perf ${h5perf_SOURCES}) + target_include_directories (h5perf PRIVATE "${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") + if (NOT ONLY_SHARED_LIBS) + TARGET_C_PROPERTIES (h5perf STATIC) + target_link_libraries (h5perf PRIVATE ${LINK_LIBS} ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET} "$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_LIBRARIES}>") + else () + TARGET_C_PROPERTIES (h5perf SHARED) + target_link_libraries (h5perf PRIVATE ${LINK_LIBS} ${HDF5_TOOLS_LIBSH_TARGET} ${HDF5_LIBSH_TARGET} "$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_LIBRARIES}>") + endif () + set_target_properties (h5perf PROPERTIES FOLDER perform) + set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5perf") + + set (H5_DEP_EXECUTABLES h5perf) + + #----------------------------------------------------------------------------- + # Add Target to clang-format + #----------------------------------------------------------------------------- + if (HDF5_ENABLE_FORMATTERS) + clang_format (HDF5_TOOLS_SRC_H5PERF_h5perf_FORMAT h5perf) + endif () +endif () + +#----------------------------------------------------------------------------- +# Rules for Installation of tools using make Install target +#----------------------------------------------------------------------------- +if (HDF5_EXPORTED_TARGETS) + foreach (exec ${H5_DEP_EXECUTABLES}) + INSTALL_PROGRAM_PDB (${exec} ${HDF5_INSTALL_BIN_DIR} toolsapplications) + endforeach () + + install ( + TARGETS + ${H5_DEP_EXECUTABLES} + EXPORT + ${HDF5_EXPORTED_TARGETS} + RUNTIME DESTINATION ${HDF5_INSTALL_BIN_DIR} COMPONENT toolsapplications + ) +endif () diff --git a/tools/src/h5perf/Makefile.am b/tools/src/h5perf/Makefile.am new file mode 100644 index 0000000..e8a9fdd --- /dev/null +++ b/tools/src/h5perf/Makefile.am @@ -0,0 +1,63 @@ +# +# Copyright by The HDF Group. +# Copyright by the Board of Trustees of the University of Illinois. +# All rights reserved. +# +# This file is part of HDF5. The full HDF5 copyright notice, including +# terms governing use, modification, and redistribution, is contained in +# the 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. +## +## Makefile.am +## Run automake to generate a Makefile.in from this file. +## +# +# HDF5 Library Performance Makefile(.in) +# + +include $(top_srcdir)/config/commence.am + +AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/test -I$(top_srcdir)/tools/lib + +# bin_PROGRAMS will be installed. +if BUILD_PARALLEL_CONDITIONAL + bin_PROGRAMS=h5perf_serial perf h5perf +else + bin_PROGRAMS=h5perf_serial +endif + +# Add h5perf and h5perf_serial specific linker flags here +h5perf_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS) +h5perf_serial_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS) + +# Some programs are not built or run by default, but can be built by hand or by +# specifying --enable-build-all at configure time. +# Also, some of these programs should only be built in parallel. +# Currently there is no such program. +if BUILD_PARALLEL_CONDITIONAL + PARA_BUILD_ALL= +endif +if BUILD_ALL_CONDITIONAL + BUILD_ALL_PROGS=$(PARA_BUILD_ALL) +endif + +# Define programs that will be run in 'make check' +# List them in the order they should be run. +# Parallel test programs. +if BUILD_PARALLEL_CONDITIONAL + TEST_PROG_PARA=h5perf perf +endif + +h5perf_SOURCES=pio_perf.c pio_engine.c +h5perf_serial_SOURCES=sio_perf.c sio_engine.c + +# All of the programs depend on the main hdf5 library, and some of them +# depend on test or tools library. +LDADD=$(LIBHDF5) +h5perf_LDADD=$(LIBH5TOOLS) $(LIBHDF5) +h5perf_serial_LDADD=$(LIBH5TOOLS) $(LIBHDF5) +perf_LDADD=$(LIBHDF5) + +include $(top_srcdir)/config/conclude.am diff --git a/tools/src/h5perf/perf.c b/tools/src/h5perf/perf.c new file mode 100644 index 0000000..83d4ab0 --- /dev/null +++ b/tools/src/h5perf/perf.c @@ -0,0 +1,796 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Author: Albert Cheng of NCSA, May 1, 2001. + * This is derived from code given to me by Robert Ross. + * + * NOTE: This code assumes that all command line arguments make it out to all + * the processes that make up the parallel job, which isn't always the case. + * So if it doesn't work on some platform, that might be why. + */ + +#include "hdf5.h" +#include "H5private.h" + +#ifdef H5_HAVE_PARALLEL + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#ifdef H5_HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif + +#ifdef H5_HAVE_SYS_TIME_H +#include <sys/time.h> +#endif + +#ifdef H5_HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#ifdef H5_HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include <mpi.h> +#ifndef MPI_FILE_NULL /*MPIO may be defined in mpi.h already */ +#include <mpio.h> +#endif + +/* Macro definitions */ +/* Verify: + * if val is false (0), print mesg and if fatal is true (non-zero), die. + */ +#define H5FATAL 1 +#define VRFY(val, mesg, fatal) \ + do { \ + if (!val) { \ + printf("Proc %d: ", mynod); \ + printf("*** Assertion failed (%s) at line %4d in %s\n", mesg, (int)__LINE__, __FILE__); \ + if (fatal) { \ + fflush(stdout); \ + goto die_jar_jar_die; \ + } \ + } \ + } while (0) +#define RANK 1 +#define MAX_PATH 1024 + +hsize_t dims[RANK]; /* dataset dim sizes */ +hsize_t block[RANK], stride[RANK], count[RANK]; +hsize_t start[RANK]; +hid_t fid; /* HDF5 file ID */ +hid_t acc_tpl; /* File access templates */ +hid_t sid; /* Dataspace ID */ +hid_t file_dataspace; /* File dataspace ID */ +hid_t mem_dataspace; /* memory dataspace ID */ +hid_t dataset; /* Dataset ID */ +hsize_t opt_alignment = 1; +hsize_t opt_threshold = 1; +int opt_split_vfd = 0; +char * meta_ext, *raw_ext; /* holds the meta and raw file extension if */ + /* opt_split_vfd is set */ + +/* DEFAULT VALUES FOR OPTIONS */ +int64_t opt_block = 1048576 * 16; +int opt_iter = 1; +int opt_stripe = -1; +int opt_correct = 0; +int amode = O_RDWR | O_CREAT; +char opt_file[256] = "perftest.out"; +char opt_pvfstab[256] = "notset"; +int opt_pvfstab_set = 0; + +const char *FILENAME[] = {opt_file, NULL}; + +/* function prototypes */ +static int parse_args(int argc, char **argv); + +#ifndef H5_HAVE_UNISTD_H +/* globals needed for getopt */ +extern char *optarg; +#endif + +#ifndef HDF5_PARAPREFIX +#define HDF5_PARAPREFIX "" +#endif +char * paraprefix = NULL; /* for command line option para-prefix */ +MPI_Info h5_io_info_g = MPI_INFO_NULL; /* MPI INFO object for IO */ + +static char *h5_fixname_real(const char *base_name, hid_t fapl, const char *_suffix, char *fullname, + size_t size, hbool_t nest_printf, hbool_t subst_for_superblock); + +int +main(int argc, char **argv) +{ + char * buf, *tmp, *buf2 = NULL, *tmp2 = NULL, *check; + int i, j, mynod = 0, nprocs = 1, my_correct = 1, correct, myerrno; + double stim, etim; + double write_tim = 0; + double read_tim = 0; + double read_bw, write_bw; + double max_read_tim, max_write_tim; + double min_read_tim, min_write_tim; + double ave_read_tim, ave_write_tim; + int64_t iter_jump = 0; + char filename[MAX_PATH]; + herr_t ret; /* Generic return value */ + + /* startup MPI and determine the rank of this process */ + MPI_Init(&argc, &argv); + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + MPI_Comm_rank(MPI_COMM_WORLD, &mynod); + + /* parse the command line arguments */ + parse_args(argc, argv); + + if (mynod == 0) + printf("# Using hdf5-io calls.\n"); + +#ifdef H5_HAVE_UNISTD_H + /* Kind of a weird hack- if the location of the pvfstab file was + * specified on the command line, then spit out this location into + * the appropriate environment variable. + */ + if (opt_pvfstab_set) { + if ((setenv("PVFSTAB_FILE", opt_pvfstab, 1)) < 0) { + perror("setenv"); + goto die_jar_jar_die; + } + } +#endif + + /* this is how much of the file data is covered on each iteration of + * the test. used to help determine the seek offset on each + * iteration */ + iter_jump = nprocs * opt_block; + + /* setup a buffer of data to write */ + if (!(tmp = (char *)malloc((size_t)opt_block + 256))) { + perror("malloc"); + goto die_jar_jar_die; + } + buf = tmp + 128 - (((long)tmp) % 128); /* align buffer */ + + if (opt_correct) { + /* do the same buffer setup for verifiable data */ + if (!(tmp2 = (char *)malloc((size_t)opt_block + 256))) { + perror("malloc2"); + goto die_jar_jar_die; + } + buf2 = tmp + 128 - (((long)tmp) % 128); + } + + /* setup file access template with parallel IO access. */ + if (opt_split_vfd) { + hid_t mpio_pl; + + mpio_pl = H5Pcreate(H5P_FILE_ACCESS); + VRFY((acc_tpl >= 0), "", H5FATAL); + ret = H5Pset_fapl_mpio(mpio_pl, MPI_COMM_WORLD, MPI_INFO_NULL); + VRFY((ret >= 0), "", H5FATAL); + + /* set optional allocation alignment */ + if (opt_alignment * opt_threshold != 1) { + ret = H5Pset_alignment(acc_tpl, opt_threshold, opt_alignment); + VRFY((ret >= 0), "H5Pset_alignment succeeded", !H5FATAL); + } + + /* setup file access template */ + acc_tpl = H5Pcreate(H5P_FILE_ACCESS); + VRFY((acc_tpl >= 0), "", H5FATAL); + ret = H5Pset_fapl_split(acc_tpl, meta_ext, mpio_pl, raw_ext, mpio_pl); + VRFY((ret >= 0), "H5Pset_fapl_split succeeded", H5FATAL); + ret = H5Pclose(mpio_pl); + VRFY((ret >= 0), "H5Pclose mpio_pl succeeded", H5FATAL); + } + else { + /* setup file access template */ + acc_tpl = H5Pcreate(H5P_FILE_ACCESS); + VRFY((acc_tpl >= 0), "", H5FATAL); + ret = H5Pset_fapl_mpio(acc_tpl, MPI_COMM_WORLD, MPI_INFO_NULL); + VRFY((ret >= 0), "", H5FATAL); + + /* set optional allocation alignment */ + if (opt_alignment * opt_threshold != 1) { + ret = H5Pset_alignment(acc_tpl, opt_threshold, opt_alignment); + VRFY((ret >= 0), "H5Pset_alignment succeeded", !H5FATAL); + } + } + + h5_fixname_real(FILENAME[0], acc_tpl, NULL, filename, sizeof filename, FALSE, FALSE); + + /* create the parallel file */ + fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl); + VRFY((fid >= 0), "H5Fcreate succeeded", H5FATAL); + + /* define a contiquous dataset of opt_iter*nprocs*opt_block chars */ + dims[0] = (hsize_t)opt_iter * (hsize_t)nprocs * (hsize_t)opt_block; + sid = H5Screate_simple(RANK, dims, NULL); + VRFY((sid >= 0), "H5Screate_simple succeeded", H5FATAL); + dataset = H5Dcreate2(fid, "Dataset1", H5T_NATIVE_CHAR, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + VRFY((dataset >= 0), "H5Dcreate2 succeeded", H5FATAL); + + /* create the memory dataspace and the file dataspace */ + dims[0] = (hsize_t)opt_block; + mem_dataspace = H5Screate_simple(RANK, dims, NULL); + VRFY((mem_dataspace >= 0), "", H5FATAL); + file_dataspace = H5Dget_space(dataset); + VRFY((file_dataspace >= 0), "H5Dget_space succeeded", H5FATAL); + + /* now each process writes a block of opt_block chars in round robbin + * fashion until the whole dataset is covered. + */ + for (j = 0; j < opt_iter; j++) { + /* setup a file dataspace selection */ + start[0] = (hsize_t)((j * iter_jump) + (mynod * opt_block)); + stride[0] = block[0] = (hsize_t)opt_block; + count[0] = 1; + ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block); + VRFY((ret >= 0), "H5Sset_hyperslab succeeded", H5FATAL); + + if (opt_correct) /* fill in buffer for iteration */ { + for (i = mynod + j, check = buf; i < opt_block; i++, check++) + *check = (char)i; + } + + /* discover the starting time of the operation */ + MPI_Barrier(MPI_COMM_WORLD); + stim = MPI_Wtime(); + + /* write data */ + ret = H5Dwrite(dataset, H5T_NATIVE_CHAR, mem_dataspace, file_dataspace, H5P_DEFAULT, buf); + VRFY((ret >= 0), "H5Dwrite dataset1 succeeded", !H5FATAL); + + /* discover the ending time of the operation */ + etim = MPI_Wtime(); + + write_tim += (etim - stim); + + /* we are done with this "write" iteration */ + } + + /* close dataset and file */ + ret = H5Dclose(dataset); + VRFY((ret >= 0), "H5Dclose succeeded", H5FATAL); + ret = H5Fclose(fid); + VRFY((ret >= 0), "H5Fclose succeeded", H5FATAL); + + /* wait for everyone to synchronize at this point */ + MPI_Barrier(MPI_COMM_WORLD); + + /* reopen the file for reading */ + fid = H5Fopen(filename, H5F_ACC_RDONLY, acc_tpl); + VRFY((fid >= 0), "", H5FATAL); + + /* open the dataset */ + dataset = H5Dopen2(fid, "Dataset1", H5P_DEFAULT); + VRFY((dataset >= 0), "H5Dopen succeeded", H5FATAL); + + /* we can re-use the same mem_dataspace and file_dataspace + * the H5Dwrite used since the dimension size is the same. + */ + + /* we are going to repeat the read the same pattern the write used */ + for (j = 0; j < opt_iter; j++) { + /* setup a file dataspace selection */ + start[0] = (hsize_t)((j * iter_jump) + (mynod * opt_block)); + stride[0] = block[0] = (hsize_t)opt_block; + count[0] = 1; + ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block); + VRFY((ret >= 0), "H5Sset_hyperslab succeeded", H5FATAL); + /* seek to the appropriate spot give the current iteration and + * rank within the MPI processes */ + + /* discover the start time */ + MPI_Barrier(MPI_COMM_WORLD); + stim = MPI_Wtime(); + + /* read in the file data */ + if (!opt_correct) { + ret = H5Dread(dataset, H5T_NATIVE_CHAR, mem_dataspace, file_dataspace, H5P_DEFAULT, buf); + } + else { + ret = H5Dread(dataset, H5T_NATIVE_CHAR, mem_dataspace, file_dataspace, H5P_DEFAULT, buf2); + } + myerrno = errno; + + /* discover the end time */ + etim = MPI_Wtime(); + read_tim += (etim - stim); + VRFY((ret >= 0), "H5Dwrite dataset1 succeeded", !H5FATAL); + + if (ret < 0) + HDfprintf(stderr, "node %d, read error, loc = %" PRId64 ": %s\n", mynod, mynod * opt_block, + strerror(myerrno)); + + /* if the user wanted to check correctness, compare the write + * buffer to the read buffer */ + if (opt_correct && memcmp(buf, buf2, (size_t)opt_block)) { + HDfprintf(stderr, "node %d, correctness test failed\n", mynod); + my_correct = 0; + MPI_Allreduce(&my_correct, &correct, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD); + } + + /* we are done with this read iteration */ + } + + /* close dataset and file */ + ret = H5Dclose(dataset); + VRFY((ret >= 0), "H5Dclose succeeded", H5FATAL); + ret = H5Fclose(fid); + VRFY((ret >= 0), "H5Fclose succeeded", H5FATAL); + ret = H5Pclose(acc_tpl); + VRFY((ret >= 0), "H5Pclose succeeded", H5FATAL); + + /* compute the read and write times */ + MPI_Allreduce(&read_tim, &max_read_tim, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); + MPI_Allreduce(&read_tim, &min_read_tim, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); + MPI_Allreduce(&read_tim, &ave_read_tim, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + + /* calculate the average from the sum */ + ave_read_tim = ave_read_tim / nprocs; + + MPI_Allreduce(&write_tim, &max_write_tim, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); + MPI_Allreduce(&write_tim, &min_write_tim, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); + MPI_Allreduce(&write_tim, &ave_write_tim, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + + /* calculate the average from the sum */ + ave_write_tim = ave_write_tim / nprocs; + + /* print out the results on one node */ + if (mynod == 0) { + read_bw = (double)((int64_t)(opt_block * nprocs * opt_iter)) / (max_read_tim * 1000000.0); + write_bw = (double)((int64_t)(opt_block * nprocs * opt_iter)) / (max_write_tim * 1000000.0); + + printf("nr_procs = %d, nr_iter = %d, blk_sz = %ld\n", nprocs, opt_iter, (long)opt_block); + + printf("# total_size = %ld\n", (long)(opt_block * nprocs * opt_iter)); + + printf("# Write: min_time = %f, max_time = %f, mean_time = %f\n", min_write_tim, max_write_tim, + ave_write_tim); + printf("# Read: min_time = %f, max_time = %f, mean_time = %f\n", min_read_tim, max_read_tim, + ave_read_tim); + + printf("Write bandwidth = %f Mbytes/sec\n", write_bw); + printf("Read bandwidth = %f Mbytes/sec\n", read_bw); + + if (opt_correct) { + printf("Correctness test %s.\n", correct ? "passed" : "failed"); + } + } + +die_jar_jar_die: + +#ifdef H5_HAVE_UNISTD + /* Clear the environment variable if it was set earlier */ + if (opt_pvfstab_set) { + unsetenv("PVFSTAB_FILE"); + } +#endif + + free(tmp); + if (opt_correct) + free(tmp2); + + MPI_Finalize(); + + return (0); +} + +static int +parse_args(int argc, char **argv) +{ + int c; + + while ((c = getopt(argc, argv, "s:b:i:f:p:a:2:c")) != EOF) { + switch (c) { + case 's': /* stripe */ + opt_stripe = atoi(optarg); + break; + case 'b': /* block size */ + opt_block = atoi(optarg); + break; + case 'i': /* iterations */ + opt_iter = atoi(optarg); + break; + case 'f': /* filename */ + strncpy(opt_file, optarg, 255); + FILENAME[0] = opt_file; + break; + case 'p': /* pvfstab file */ + strncpy(opt_pvfstab, optarg, 255); + opt_pvfstab_set = 1; + break; + case 'a': /* aligned allocation. + * syntax: -a<alignment>/<threshold> + * e.g., -a4096/512 allocate at 4096 bytes + * boundary if request size >= 512. + */ + { + char *p; + + opt_alignment = (hsize_t)HDatoi(optarg); + if (NULL != (p = (char *)HDstrchr(optarg, '/'))) + opt_threshold = (hsize_t)HDatoi(p + 1); + } + HDfprintf(stdout, "alignment/threshold=%" PRIuHSIZE "/%" PRIuHSIZE "\n", opt_alignment, + opt_threshold); + break; + case '2': /* use 2-files, i.e., split file driver */ + opt_split_vfd = 1; + /* get meta and raw file extension. */ + /* syntax is <raw_ext>,<meta_ext> */ + meta_ext = raw_ext = optarg; + while (*raw_ext != '\0') { + if (*raw_ext == ',') { + *raw_ext = '\0'; + raw_ext++; + break; + } + raw_ext++; + } + printf("split-file-vfd used: %s,%s\n", meta_ext, raw_ext); + break; + case 'c': /* correctness */ + opt_correct = 1; + break; + case '?': /* unknown */ + default: + break; + } + } + + return (0); +} +/*------------------------------------------------------------------------- + * Function: getenv_all + * + * Purpose: Used to get the environment that the root MPI task has. + * name specifies which environment variable to look for + * val is the string to which the value of that environment + * variable will be copied. + * + * NOTE: The pointer returned by this function is only + * valid until the next call to getenv_all and the data + * stored there must be copied somewhere else before any + * further calls to getenv_all take place. + * + * Return: pointer to a string containing the value of the environment variable + * NULL if the varialbe doesn't exist in task 'root's environment. + * + * Programmer: Leon Arber + * 4/4/05 + * + * Modifications: + * Use original getenv if MPI is not initialized. This happens + * one uses the PHDF5 library to build a serial nature code. + * Albert 2006/04/07 + * + *------------------------------------------------------------------------- + */ +char * +getenv_all(MPI_Comm comm, int root, const char *name) +{ + int mpi_size, mpi_rank, mpi_initialized, mpi_finalized; + int len; + static char *env = NULL; + + HDassert(name); + + MPI_Initialized(&mpi_initialized); + MPI_Finalized(&mpi_finalized); + + if (mpi_initialized && !mpi_finalized) { + MPI_Comm_rank(comm, &mpi_rank); + MPI_Comm_size(comm, &mpi_size); + HDassert(root < mpi_size); + + /* The root task does the getenv call + * and sends the result to the other tasks */ + if (mpi_rank == root) { + env = HDgetenv(name); + if (env) { + len = (int)HDstrlen(env); + MPI_Bcast(&len, 1, MPI_INT, root, comm); + MPI_Bcast(env, len, MPI_CHAR, root, comm); + } + else { + /* len -1 indicates that the variable was not in the environment */ + len = -1; + MPI_Bcast(&len, 1, MPI_INT, root, comm); + } + } + else { + MPI_Bcast(&len, 1, MPI_INT, root, comm); + if (len >= 0) { + if (env == NULL) + env = (char *)HDmalloc((size_t)len + 1); + else if (HDstrlen(env) < (size_t)len) + env = (char *)HDrealloc(env, (size_t)len + 1); + + MPI_Bcast(env, len, MPI_CHAR, root, comm); + env[len] = '\0'; + } + else { + if (env) + HDfree(env); + env = NULL; + } + } +#ifndef NDEBUG + MPI_Barrier(comm); +#endif + } + else { + /* use original getenv */ + if (env) + HDfree(env); + env = HDgetenv(name); + } /* end if */ + + return env; +} + +/*------------------------------------------------------------------------- + * Function: h5_fixname_real + * + * Purpose: Create a file name from a file base name like `test' and + * return it through the FULLNAME (at most SIZE characters + * counting the null terminator). The full name is created by + * prepending the contents of HDF5_PREFIX (separated from the + * base name by a slash) and appending a file extension based on + * the driver supplied, resulting in something like + * `ufs:/u/matzke/test.h5'. + * + * Return: Success: The FULLNAME pointer. + * + * Failure: NULL if BASENAME or FULLNAME is the null + * pointer or if FULLNAME isn't large enough for + * the result. + * + * Programmer: Robb Matzke + * Thursday, November 19, 1998 + * + *------------------------------------------------------------------------- + */ +static char * +h5_fixname_real(const char *base_name, hid_t fapl, const char *_suffix, char *fullname, size_t size, + hbool_t nest_printf, hbool_t subst_for_superblock) +{ + const char *prefix = NULL; + const char *env = NULL; /* HDF5_DRIVER environment variable */ + char * ptr, last = '\0'; + const char *suffix = _suffix; + size_t i, j; + hid_t driver = -1; + int isppdriver = 0; /* if the driver is MPI parallel */ + + if (!base_name || !fullname || size < 1) + return NULL; + + HDmemset(fullname, 0, size); + + /* figure out the suffix */ + if (H5P_DEFAULT != fapl) { + if ((driver = H5Pget_driver(fapl)) < 0) + return NULL; + + if (suffix) { + if (H5FD_FAMILY == driver) { + if (subst_for_superblock) + suffix = "00000.h5"; + else + suffix = nest_printf ? "%%05d.h5" : "%05d.h5"; + } + else if (H5FD_MULTI == driver) { + + /* Get the environment variable, if it exists, in case + * we are using the split driver since both of those + * use the multi VFD under the hood. + */ + env = HDgetenv("HDF5_DRIVER"); +#ifdef HDF5_DRIVER + /* Use the environment variable, then the compile-time constant */ + if (!env) + env = HDF5_DRIVER; +#endif + if (env && !HDstrcmp(env, "split")) { + /* split VFD */ + if (subst_for_superblock) + suffix = "-m.h5"; + else + suffix = NULL; + } + else { + /* multi VFD */ + if (subst_for_superblock) + suffix = "-s.h5"; + else + suffix = NULL; + } + } + } + } + + /* Must first check fapl is not H5P_DEFAULT (-1) because H5FD_XXX + * could be of value -1 if it is not defined. + */ + isppdriver = H5P_DEFAULT != fapl && (H5FD_MPIO == driver); + + /* Check what prefix to use for test files. Process HDF5_PARAPREFIX and + * HDF5_PREFIX. + * Use different ones depending on parallel or serial driver used. + * (The #ifdef is needed to prevent compile failure in case MPI is not + * configured.) + */ + if (isppdriver) { + /* + * For parallel: + * First use command line option, then the environment + * variable, then try the constant + */ + static int explained = 0; + + prefix = (paraprefix ? paraprefix : getenv_all(MPI_COMM_WORLD, 0, "HDF5_PARAPREFIX")); + + if (!prefix && !explained) { + /* print hint by process 0 once. */ + int mpi_rank; + + MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); + + if (mpi_rank == 0) + HDprintf("*** Hint ***\n" + "You can use environment variable HDF5_PARAPREFIX to " + "run parallel test files in a\n" + "different directory or to add file type prefix. e.g.,\n" + " HDF5_PARAPREFIX=pfs:/PFS/user/me\n" + " export HDF5_PARAPREFIX\n" + "*** End of Hint ***\n"); + + explained = TRUE; +#ifdef HDF5_PARAPREFIX + prefix = HDF5_PARAPREFIX; +#endif /* HDF5_PARAPREFIX */ + } + } + else { + /* + * For serial: + * First use the environment variable, then try the constant + */ + prefix = HDgetenv("HDF5_PREFIX"); + +#ifdef HDF5_PREFIX + if (!prefix) + prefix = HDF5_PREFIX; +#endif /* HDF5_PREFIX */ + } + + /* Prepend the prefix value to the base name */ + if (prefix && *prefix) { + if (isppdriver) { + /* This is a parallel system */ + char *subdir; + + if (!HDstrcmp(prefix, HDF5_PARAPREFIX)) { + /* + * If the prefix specifies the HDF5_PARAPREFIX directory, then + * default to using the "/tmp/$USER" or "/tmp/$LOGIN" + * directory instead. + */ + char *user, *login; + + user = HDgetenv("USER"); + login = HDgetenv("LOGIN"); + subdir = (user ? user : login); + + if (subdir) { + for (i = 0; i < size && prefix[i]; i++) + fullname[i] = prefix[i]; + + fullname[i++] = '/'; + + for (j = 0; i < size && subdir[j]; ++i, ++j) + fullname[i] = subdir[j]; + } + } + + if (!fullname[0]) { + /* We didn't append the prefix yet */ + HDstrncpy(fullname, prefix, size); + fullname[size - 1] = '\0'; + } + + if (HDstrlen(fullname) + HDstrlen(base_name) + 1 < size) { + /* + * Append the base_name with a slash first. Multiple + * slashes are handled below. + */ + h5_stat_t buf; + + if (HDstat(fullname, &buf) < 0) + /* The directory doesn't exist just yet */ + if (HDmkdir(fullname, (mode_t)0755) < 0 && errno != EEXIST) + /* + * We couldn't make the "/tmp/${USER,LOGIN}" + * subdirectory. Default to PREFIX's original + * prefix value. + */ + HDstrcpy(fullname, prefix); + + HDstrcat(fullname, "/"); + HDstrcat(fullname, base_name); + } + else { + /* Buffer is too small */ + return NULL; + } + } + else { + if (HDsnprintf(fullname, size, "%s/%s", prefix, base_name) == (int)size) + /* Buffer is too small */ + return NULL; + } + } + else if (HDstrlen(base_name) >= size) { + /* Buffer is too small */ + return NULL; + } + else { + HDstrcpy(fullname, base_name); + } + + /* Append a suffix */ + if (suffix) { + if (HDstrlen(fullname) + HDstrlen(suffix) >= size) + return NULL; + + HDstrcat(fullname, suffix); + } + + /* Remove any double slashes in the filename */ + for (ptr = fullname, i = j = 0; ptr && i < size; i++, ptr++) { + if (*ptr != '/' || last != '/') + fullname[j++] = *ptr; + + last = *ptr; + } + + return fullname; +} + +/* + * Local variables: + * c-indent-level: 3 + * c-basic-offset: 3 + * tab-width: 3 + * End: + */ + +#else /* H5_HAVE_PARALLEL */ +/* dummy program since H5_HAVE_PARALLEL is not configured in */ +int +main(int H5_ATTR_UNUSED argc, char H5_ATTR_UNUSED **argv) +{ + printf("No parallel performance because parallel is not configured in\n"); + return (0); +} +#endif /* H5_HAVE_PARALLEL */ diff --git a/tools/src/h5perf/pio_engine.c b/tools/src/h5perf/pio_engine.c new file mode 100644 index 0000000..cac36d7 --- /dev/null +++ b/tools/src/h5perf/pio_engine.c @@ -0,0 +1,2745 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Author: Albert Cheng of NCSA, Oct 24, 2001. + */ + +#include "hdf5.h" + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> + +#ifdef H5_HAVE_UNISTD_H +#include <sys/types.h> +#include <unistd.h> +#endif + +#ifdef H5_HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif + +#ifdef H5_HAVE_PARALLEL + +#include <mpi.h> + +#ifndef MPI_FILE_NULL /*MPIO may be defined in mpi.h already */ +#include <mpio.h> +#endif /* !MPI_FILE_NULL */ + +#include "pio_perf.h" + +/* Macro definitions */ + +#if H5_VERS_MAJOR == 1 && H5_VERS_MINOR == 6 +#define H5DCREATE(fd, name, type, space, dcpl) H5Dcreate(fd, name, type, space, dcpl) +#define H5DOPEN(fd, name) H5Dopen(fd, name) +#else +#define H5DCREATE(fd, name, type, space, dcpl) \ + H5Dcreate2(fd, name, type, space, H5P_DEFAULT, dcpl, H5P_DEFAULT) +#define H5DOPEN(fd, name) H5Dopen2(fd, name, H5P_DEFAULT) +#endif + +/* sizes of various items. these sizes won't change during program execution */ +/* The following three must have the same type */ +#define ELMT_H5_TYPE H5T_NATIVE_UCHAR + +#define GOTOERROR(errcode) \ + { \ + ret_code = errcode; \ + goto done; \ + } +#define ERRMSG(mesg) \ + { \ + HDfprintf(stderr, "Proc %d: ", pio_mpi_rank_g); \ + HDfprintf(stderr, "*** Assertion failed (%s) at line %4d in %s\n", mesg, (int)__LINE__, __FILE__); \ + } + +/* verify: if val is false (0), print mesg. */ +#define VRFY(val, mesg) \ + do { \ + if (!val) { \ + ERRMSG(mesg); \ + GOTOERROR(FAIL); \ + } \ + } while (0) + +/* POSIX I/O macros */ +#ifdef H5_HAVE_WIN32_API +/* Can't link against the library, so this test will use the older, non-Unicode + * _open() call on Windows. + */ +#define HDopen(S, F, ...) _open(S, F | _O_BINARY, __VA_ARGS__) +#endif /* H5_HAVE_WIN32_API */ +#define POSIXCREATE(fn) HDopen(fn, O_CREAT | O_TRUNC | O_RDWR, 0600) +#define POSIXOPEN(fn, F) HDopen(fn, F, 0600) +#define POSIXCLOSE(F) HDclose(F) +#define POSIXSEEK(F, L) HDlseek(F, L, SEEK_SET) +#define POSIXWRITE(F, B, S) HDwrite(F, B, S) +#define POSIXREAD(F, B, S) HDread(F, B, S) + +enum { PIO_CREATE = 1, PIO_WRITE = 2, PIO_READ = 4 }; + +/* Global variables */ +static int clean_file_g = -1; /*whether to cleanup temporary test */ +/*files. -1 is not defined; */ +/*0 is no cleanup; 1 is do cleanup */ + +/* + * In a parallel machine, the filesystem suitable for compiling is + * unlikely a parallel file system that is suitable for parallel I/O. + * There is no standard pathname for the parallel file system. /tmp + * is about the best guess. + */ +#ifndef HDF5_PARAPREFIX +#define HDF5_PARAPREFIX "" +#endif /* !HDF5_PARAPREFIX */ + +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif /* !MIN */ + +/* the different types of file descriptors we can expect */ +typedef union _file_descr { + int posixfd; /* POSIX file handle*/ + MPI_File mpifd; /* MPI file */ + hid_t h5fd; /* HDF5 file */ +} file_descr; + +/* local functions */ +static char * pio_create_filename(iotype iot, const char *base_name, char *fullname, size_t size); +static herr_t do_write(results *res, file_descr *fd, parameters *parms, long ndsets, off_t nelmts, + size_t buf_size, void *buffer); +static herr_t do_read(results *res, file_descr *fd, parameters *parms, long ndsets, off_t nelmts, + size_t buf_size, void *buffer /*out*/); +static herr_t do_fopen(parameters *param, char *fname, file_descr *fd /*out*/, int flags); +static herr_t do_fclose(iotype iot, file_descr *fd); +static void do_cleanupfile(iotype iot, char *fname); +static off_t sqrto(off_t); + +/* + * Function: do_pio + * Purpose: PIO Engine where Parallel IO are executed. + * Return: results + * Programmer: Albert Cheng, Bill Wendling 2001/12/12 + * Modifications: + * Added 2D testing (Christian Chilan, 10. August 2005) + */ +results +do_pio(parameters param) +{ + /* return codes */ + herr_t ret_code = 0; /*return code */ + results res; + + file_descr fd; + iotype iot; + + char fname[FILENAME_MAX]; + long nf; + long ndsets; + off_t nbytes; /*number of bytes per dataset */ + off_t snbytes; /*general dataset size */ + /*for 1D, it is the actual dataset size */ + /*for 2D, it is the size of a side of the dataset square */ + char * buffer = NULL; /*data buffer pointer */ + size_t buf_size; /*general buffer size in bytes */ + /*for 1D, it is the actual buffer size */ + /*for 2D, it is the length of the buffer rectangle */ + size_t blk_size; /*data block size in bytes */ + size_t bsize; /*actual buffer size */ + + /* HDF5 variables */ + herr_t hrc; /*HDF5 return code */ + + /* Sanity check parameters */ + + /* IO type */ + iot = param.io_type; + + switch (iot) { + case MPIO: + fd.mpifd = MPI_FILE_NULL; + res.timers = io_time_new(MPI_CLOCK); + break; + case POSIXIO: + fd.posixfd = -1; + res.timers = io_time_new(MPI_CLOCK); + break; + case PHDF5: + fd.h5fd = -1; + res.timers = io_time_new(MPI_CLOCK); + break; + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", iot); + GOTOERROR(FAIL); + } + + ndsets = param.num_dsets; /* number of datasets per file */ + nbytes = param.num_bytes; /* number of bytes per dataset */ + buf_size = param.buf_size; + blk_size = param.blk_size; + + if (!param.dim2d) { + snbytes = nbytes; /* General dataset size */ + bsize = buf_size; /* Actual buffer size */ + } + else { + snbytes = sqrto(nbytes); /* General dataset size */ + bsize = buf_size * blk_size; /* Actual buffer size */ + } + + if (param.num_files < 0) { + HDfprintf(stderr, "number of files must be >= 0 (%ld)\n", param.num_files); + GOTOERROR(FAIL); + } + + if (ndsets < 0) { + HDfprintf(stderr, "number of datasets per file must be >= 0 (%ld)\n", ndsets); + GOTOERROR(FAIL); + } + + if (param.num_procs <= 0) { + HDfprintf(stderr, "maximum number of process to use must be > 0 (%d)\n", param.num_procs); + GOTOERROR(FAIL); + } + + /* Validate transfer buffer size & block size*/ + if (blk_size <= 0) { + HDfprintf(stderr, "Transfer block size (%zu) must be > 0\n", blk_size); + GOTOERROR(FAIL); + } + if (buf_size <= 0) { + HDfprintf(stderr, "Transfer buffer size (%zu) must be > 0\n", buf_size); + GOTOERROR(FAIL); + } + if ((buf_size % blk_size) != 0) { + HDfprintf(stderr, + "Transfer buffer size (%zu) must be a multiple of the " + "interleaved I/O block size (%zu)\n", + buf_size, blk_size); + GOTOERROR(FAIL); + } + if ((snbytes % pio_mpi_nprocs_g) != 0) { + HDfprintf(stderr, + "Dataset size (%" H5_PRINTF_LL_WIDTH "d) must be a multiple of the " + "number of processes (%d)\n", + (long long)snbytes, pio_mpi_nprocs_g); + GOTOERROR(FAIL); + } + + if (!param.dim2d) { + if (((size_t)(snbytes / pio_mpi_nprocs_g) % buf_size) != 0) { + HDfprintf(stderr, + "Dataset size/process (%" H5_PRINTF_LL_WIDTH "d) must be a multiple of the " + "trasfer buffer size (%zu)\n", + (long long)(snbytes / pio_mpi_nprocs_g), buf_size); + GOTOERROR(FAIL); + } + } + else { + if (((size_t)snbytes % buf_size) != 0) { + HDfprintf(stderr, + "Dataset side size (%" H5_PRINTF_LL_WIDTH "d) must be a multiple of the " + "trasfer buffer size (%zu)\n", + (long long)snbytes, buf_size); + GOTOERROR(FAIL); + } + } + + /* Allocate transfer buffer */ + if ((buffer = malloc(bsize)) == NULL) { + HDfprintf(stderr, "malloc for transfer buffer size (%zu) failed\n", bsize); + GOTOERROR(FAIL); + } + + if (pio_debug_level >= 4) { + int myrank; + + MPI_Comm_rank(pio_comm_g, &myrank); + + /* output all of the times for all iterations */ + if (myrank == 0) + HDfprintf(output, "Timer details:\n"); + } + + for (nf = 1; nf <= param.num_files; nf++) { + /* + * Write performance measurement + */ + /* Open file for write */ + char base_name[256]; + + HDsprintf(base_name, "#pio_tmp_%lu", nf); + pio_create_filename(iot, base_name, fname, sizeof(fname)); + if (pio_debug_level > 0) + HDfprintf(output, "rank %d: data filename=%s\n", pio_mpi_rank_g, fname); + + /* Need barrier to make sure everyone starts at the same time */ + MPI_Barrier(pio_comm_g); + + io_time_set(res.timers, HDF5_GROSS_WRITE_FIXED_DIMS, TSTART); + hrc = do_fopen(¶m, fname, &fd, PIO_CREATE | PIO_WRITE); + + VRFY((hrc == SUCCESS), "do_fopen failed"); + + io_time_set(res.timers, HDF5_FINE_WRITE_FIXED_DIMS, TSTART); + hrc = do_write(&res, &fd, ¶m, ndsets, nbytes, buf_size, buffer); + io_time_set(res.timers, HDF5_FINE_WRITE_FIXED_DIMS, TSTOP); + + VRFY((hrc == SUCCESS), "do_write failed"); + + /* Close file for write */ + hrc = do_fclose(iot, &fd); + + io_time_set(res.timers, HDF5_GROSS_WRITE_FIXED_DIMS, TSTOP); + VRFY((hrc == SUCCESS), "do_fclose failed"); + + if (!param.h5_write_only) { + /* + * Read performance measurement + */ + /* Need barrier to make sure everyone is done writing and has + * closed the file. Also to make sure everyone starts reading + * at the same time. + */ + MPI_Barrier(pio_comm_g); + + /* Open file for read */ + io_time_set(res.timers, HDF5_GROSS_READ_FIXED_DIMS, TSTART); + hrc = do_fopen(¶m, fname, &fd, PIO_READ); + + VRFY((hrc == SUCCESS), "do_fopen failed"); + + io_time_set(res.timers, HDF5_FINE_READ_FIXED_DIMS, TSTART); + hrc = do_read(&res, &fd, ¶m, ndsets, nbytes, buf_size, buffer); + io_time_set(res.timers, HDF5_FINE_READ_FIXED_DIMS, TSTOP); + VRFY((hrc == SUCCESS), "do_read failed"); + + /* Close file for read */ + hrc = do_fclose(iot, &fd); + + io_time_set(res.timers, HDF5_GROSS_READ_FIXED_DIMS, TSTOP); + VRFY((hrc == SUCCESS), "do_fclose failed"); + } + + /* Need barrier to make sure everyone is done with the file */ + /* before it may be removed by do_cleanupfile */ + MPI_Barrier(pio_comm_g); + do_cleanupfile(iot, fname); + } + +done: + /* clean up */ + /* release HDF5 objects */ + + /* close any opened files */ + /* no remove(fname) because that should have happened normally. */ + switch (iot) { + case POSIXIO: + if (fd.posixfd != -1) + hrc = do_fclose(iot, &fd); + break; + case MPIO: + if (fd.mpifd != MPI_FILE_NULL) + hrc = do_fclose(iot, &fd); + break; + case PHDF5: + if (fd.h5fd != -1) + hrc = do_fclose(iot, &fd); + break; + default: + break; + } + + /* release generic resources */ + if (buffer) + HDfree(buffer); + res.ret_code = ret_code; + return res; +} + +/* + * Function: pio_create_filename + * Purpose: Create a new filename to write to. Determine the correct + * suffix to append to the filename by the type of I/O we're + * doing. Also, place in the /tmp/{$USER,$LOGIN} directory if + * USER or LOGIN are specified in the environment. + * Return: Pointer to filename or NULL + * Programmer: Bill Wendling, 21. November 2001 + * Modifications: + */ +static char * +pio_create_filename(iotype iot, const char *base_name, char *fullname, size_t size) +{ + const char *prefix, *suffix = ""; + char * ptr, last = '\0'; + size_t i, j; + + if (!base_name || !fullname || size < 1) + return NULL; + + HDmemset(fullname, 0, size); + + switch (iot) { + case POSIXIO: + suffix = ".posix"; + break; + case MPIO: + suffix = ".mpio"; + break; + case PHDF5: + suffix = ".h5"; + break; + default: + break; + } + + /* First use the environment variable and then try the constant */ + prefix = HDgetenv("HDF5_PARAPREFIX"); + +#ifdef HDF5_PARAPREFIX + if (!prefix) + prefix = HDF5_PARAPREFIX; +#endif /* HDF5_PARAPREFIX */ + + /* Prepend the prefix value to the base name */ + if (prefix && *prefix) { + /* If the prefix specifies the HDF5_PARAPREFIX directory, then + * default to using the "/tmp/$USER" or "/tmp/$LOGIN" + * directory instead. */ + register char *user, *login, *subdir; + + user = HDgetenv("USER"); + login = HDgetenv("LOGIN"); + subdir = (user ? user : login); + + if (subdir) { + for (i = 0; i < size - 1 && prefix[i]; i++) + fullname[i] = prefix[i]; + + fullname[i++] = '/'; + + for (j = 0; i < size && subdir[j]; i++, j++) + fullname[i] = subdir[j]; + } + else { + /* We didn't append the prefix yet */ + HDstrncpy(fullname, prefix, size); + fullname[size - 1] = '\0'; + } + + if ((HDstrlen(fullname) + HDstrlen(base_name) + 1) < size) { + /* Append the base_name with a slash first. Multiple slashes are + * handled below. */ + h5_stat_t buf; + + if (HDstat(fullname, &buf) < 0) + /* The directory doesn't exist just yet */ + if (HDmkdir(fullname, (mode_t)0755) < 0 && errno != EEXIST) { + /* We couldn't make the "/tmp/${USER,LOGIN}" subdirectory. + * Default to PREFIX's original prefix value. */ + HDstrcpy(fullname, prefix); + } + + HDstrcat(fullname, "/"); + HDstrcat(fullname, base_name); + } + else { + /* Buffer is too small */ + return NULL; + } + } + else if (HDstrlen(base_name) >= size) { + /* Buffer is too small */ + return NULL; + } + else { + HDstrcpy(fullname, base_name); + } + + /* Append a suffix */ + if (suffix) { + if (HDstrlen(fullname) + HDstrlen(suffix) >= size) + return NULL; + + HDstrcat(fullname, suffix); + } + + /* Remove any double slashes in the filename */ + for (ptr = fullname, i = j = 0; ptr && i < size; i++, ptr++) { + if (*ptr != '/' || last != '/') + fullname[j++] = *ptr; + + last = *ptr; + } + + return fullname; +} + +/* + * Function: do_write + * Purpose: Write the required amount of data to the file. + * Return: SUCCESS or FAIL + * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 + * Modifications: + * Added 2D testing (Christian Chilan, 10. August 2005) + */ +static herr_t +do_write(results *res, file_descr *fd, parameters *parms, long ndsets, off_t nbytes, size_t buf_size, + void *buffer) +{ + int ret_code = SUCCESS; + int rc; /*routine return code */ + long ndset; + size_t blk_size; /* The block size to subdivide the xfer buffer into */ + off_t nbytes_xfer; /* Total number of bytes transferred so far */ + size_t nbytes_xfer_advance; /* Number of bytes transferred in a single I/O operation */ + size_t nbytes_toxfer; /* Number of bytes to transfer a particular time */ + char dname[64]; + off_t dset_offset = 0; /*dataset offset in a file */ + off_t bytes_begin[2]; /*first elmt this process transfer */ + off_t bytes_count; /*number of elmts this process transfer */ + off_t snbytes = 0; /*size of a side of the dataset square */ + unsigned char *buf_p; /* Current buffer pointer */ + + /* POSIX variables */ + off_t file_offset; /* File offset of the next transfer */ + off_t file_offset_advance; /* File offset advance after each I/O operation */ + off_t posix_file_offset; /* Base file offset of the next transfer */ + + /* MPI variables */ + MPI_Offset mpi_file_offset; /* Base file offset of the next transfer*/ + MPI_Offset mpi_offset; /* Offset in MPI file */ + MPI_Offset mpi_offset_advance; /* Offset advance after each I/O operation */ + MPI_Datatype mpi_file_type; /* MPI derived type for 1D file */ + MPI_Datatype mpi_blk_type; /* MPI derived type for 1D buffer */ + MPI_Datatype mpi_cont_type; /* MPI derived type for 2D contiguous file */ + MPI_Datatype mpi_partial_buffer_cont; /* MPI derived type for partial 2D contiguous buffer */ + MPI_Datatype mpi_inter_type; /* MPI derived type for 2D interleaved file */ + MPI_Datatype mpi_partial_buffer_inter; /* MPI derived type for partial 2D interleaved buffer */ + MPI_Datatype mpi_full_buffer; /* MPI derived type for 2D full buffer */ + MPI_Datatype mpi_full_chunk; /* MPI derived type for 2D full chunk */ + MPI_Datatype mpi_chunk_inter_type; /* MPI derived type for 2D chunk interleaved file */ + MPI_Datatype mpi_collective_type; /* Generic MPI derived type for 2D collective access */ + MPI_Status mpi_status; + int mrc; /* MPI return code */ + + /* HDF5 variables */ + herr_t hrc; /*HDF5 return code */ + hsize_t h5dims[2]; /*dataset dim sizes */ + hid_t h5dset_space_id = H5I_INVALID_HID; /*dataset space ID */ + hid_t h5mem_space_id = H5I_INVALID_HID; /*memory dataspace ID */ + hid_t h5ds_id = H5I_INVALID_HID; /*dataset handle */ + hsize_t h5block[2]; /*dataspace selection */ + hsize_t h5stride[2]; + hsize_t h5count[2]; + hsize_t h5start[2]; + hssize_t h5offset[2]; /* Selection offset within dataspace */ + hid_t h5dcpl = H5I_INVALID_HID; /* Dataset creation property list */ + hid_t h5dxpl = H5I_INVALID_HID; /* Dataset transfer property list */ + + /* Get the parameters from the parameter block */ + blk_size = parms->blk_size; + + /* There are two kinds of transfer patterns, contiguous and interleaved. + * Let 0,1,2,...,n be data accessed by process 0,1,2,...,n + * where n is rank of the last process. + * In contiguous pattern, data are accessed as + * 000...111...222...nnn... + * In interleaved pattern, data are accessed as + * 012...n012...n... + * These are all in the scope of one dataset. + */ + + /* 1D dataspace */ + if (!parms->dim2d) { + /* Contiguous Pattern: */ + if (!parms->interleaved) { + bytes_begin[0] = (off_t)(((double)nbytes * pio_mpi_rank_g) / pio_mpi_nprocs_g); + } /* end if */ + /* Interleaved Pattern: */ + else { + bytes_begin[0] = (off_t)(blk_size * (size_t)pio_mpi_rank_g); + } /* end else */ + + /* Prepare buffer for verifying data */ + if (parms->verify) + memset(buffer, pio_mpi_rank_g + 1, buf_size); + } /* end if */ + /* 2D dataspace */ + else { + /* nbytes is always the number of bytes per dataset (1D or 2D). If the + dataspace is 2D, snbytes is the size of a side of the dataset square. + */ + snbytes = sqrto(nbytes); + + /* Contiguous Pattern: */ + if (!parms->interleaved) { + bytes_begin[0] = (off_t)((double)snbytes * pio_mpi_rank_g / pio_mpi_nprocs_g); + bytes_begin[1] = 0; + } /* end if */ + /* Interleaved Pattern: */ + else { + bytes_begin[0] = 0; + + if (!parms->h5_use_chunks || parms->io_type == PHDF5) + bytes_begin[1] = (off_t)(blk_size * (size_t)pio_mpi_rank_g); + else + bytes_begin[1] = (off_t)(blk_size * blk_size * (size_t)pio_mpi_rank_g); + } /* end else */ + + /* Prepare buffer for verifying data */ + if (parms->verify) + HDmemset(buffer, pio_mpi_rank_g + 1, buf_size * blk_size); + } /* end else */ + + /* Calculate the total number of bytes (bytes_count) to be + * transferred by this process. It may be different for different + * transfer pattern due to rounding to integral values. + */ + /* + * Calculate the beginning bytes of this process and the next. + * bytes_count is the difference between these two beginnings. + * This way, it eliminates any rounding errors. + * (This is tricky, don't mess with the formula, rounding errors + * can easily get introduced) */ + bytes_count = (off_t)(((double)nbytes * (pio_mpi_rank_g + 1)) / pio_mpi_nprocs_g) - + (off_t)(((double)nbytes * pio_mpi_rank_g) / pio_mpi_nprocs_g); + + /* debug */ + if (pio_debug_level >= 4) { + HDprint_rank(output); + if (!parms->dim2d) { + HDfprintf(output, + "Debug(do_write): " + "buf_size=%zu, bytes_begin=%" H5_PRINTF_LL_WIDTH "d, bytes_count=%" H5_PRINTF_LL_WIDTH + "d\n", + buf_size, (long long)bytes_begin[0], (long long)bytes_count); + } + else { + HDfprintf(output, + "Debug(do_write): " + "linear buf_size=%zu, bytes_begin=(%" H5_PRINTF_LL_WIDTH "d,%" H5_PRINTF_LL_WIDTH + "d), bytes_count=%" H5_PRINTF_LL_WIDTH "d\n", + buf_size * blk_size, (long long)bytes_begin[0], (long long)bytes_begin[1], + (long long)bytes_count); + } + } + + /* I/O Access specific setup */ + switch (parms->io_type) { + case POSIXIO: + /* No extra setup */ + break; + + case MPIO: /* MPI-I/O setup */ + /* 1D dataspace */ + if (!parms->dim2d) { + /* Build block's derived type */ + mrc = MPI_Type_contiguous((int)blk_size, MPI_BYTE, &mpi_blk_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Build file's derived type */ + mrc = MPI_Type_vector((int)(buf_size / blk_size), (int)1, (int)pio_mpi_nprocs_g, mpi_blk_type, + &mpi_file_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit file type */ + mrc = MPI_Type_commit(&mpi_file_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Commit buffer type */ + mrc = MPI_Type_commit(&mpi_blk_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + } /* end if */ + /* 2D dataspace */ + else { + /* Build partial buffer derived type for contiguous access */ + + mrc = MPI_Type_contiguous((int)buf_size, MPI_BYTE, &mpi_partial_buffer_cont); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit partial buffer derived type */ + mrc = MPI_Type_commit(&mpi_partial_buffer_cont); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build contiguous file's derived type */ + mrc = MPI_Type_vector((int)blk_size, (int)1, (int)((size_t)snbytes / buf_size), + mpi_partial_buffer_cont, &mpi_cont_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit contiguous file type */ + mrc = MPI_Type_commit(&mpi_cont_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build partial buffer derived type for interleaved access */ + mrc = MPI_Type_contiguous((int)blk_size, MPI_BYTE, &mpi_partial_buffer_inter); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit partial buffer derived type */ + mrc = MPI_Type_commit(&mpi_partial_buffer_inter); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build interleaved file's derived type */ + mrc = MPI_Type_vector((int)buf_size, (int)1, (int)((size_t)snbytes / blk_size), + mpi_partial_buffer_inter, &mpi_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit interleaved file type */ + mrc = MPI_Type_commit(&mpi_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build full buffer derived type */ + mrc = MPI_Type_contiguous((int)(blk_size * buf_size), MPI_BYTE, &mpi_full_buffer); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit full buffer derived type */ + mrc = MPI_Type_commit(&mpi_full_buffer); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build full chunk derived type */ + mrc = MPI_Type_contiguous((int)(blk_size * blk_size), MPI_BYTE, &mpi_full_chunk); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit full chunk derived type */ + mrc = MPI_Type_commit(&mpi_full_chunk); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build chunk interleaved file's derived type */ + mrc = MPI_Type_vector((int)(buf_size / blk_size), (int)1, (int)((size_t)snbytes / blk_size), + mpi_full_chunk, &mpi_chunk_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit chunk interleaved file type */ + mrc = MPI_Type_commit(&mpi_chunk_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + } /* end else */ + break; + + case PHDF5: /* HDF5 setup */ + /* 1D dataspace */ + if (!parms->dim2d) { + if (nbytes > 0) { + /* define a contiguous dataset of nbytes native bytes */ + h5dims[0] = (hsize_t)nbytes; + h5dset_space_id = H5Screate_simple(1, h5dims, NULL); + VRFY((h5dset_space_id >= 0), "H5Screate_simple"); + + /* Set up the file dset space id to select the pattern to access */ + if (!parms->interleaved) { + /* Contiguous pattern */ + h5start[0] = (hsize_t)bytes_begin[0]; + h5stride[0] = h5block[0] = blk_size; + h5count[0] = buf_size / blk_size; + } /* end if */ + else { + /* Interleaved access pattern */ + /* Skip offset over blocks of other processes */ + h5start[0] = (hsize_t)bytes_begin[0]; + h5stride[0] = blk_size * (size_t)pio_mpi_nprocs_g; + h5block[0] = blk_size; + h5count[0] = buf_size / blk_size; + } /* end else */ + hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, + h5block); + VRFY((hrc >= 0), "H5Sselect_hyperslab"); + } /* end if */ + else { + h5dset_space_id = H5Screate(H5S_SCALAR); + VRFY((h5dset_space_id >= 0), "H5Screate"); + } /* end else */ + + /* Create the memory dataspace that corresponds to the xfer buffer */ + if (buf_size > 0) { + h5dims[0] = buf_size; + h5mem_space_id = H5Screate_simple(1, h5dims, NULL); + VRFY((h5mem_space_id >= 0), "H5Screate_simple"); + } /* end if */ + else { + h5mem_space_id = H5Screate(H5S_SCALAR); + VRFY((h5mem_space_id >= 0), "H5Screate"); + } /* end else */ + } /* end if */ + /* 2D dataspace */ + else { + if (nbytes > 0) { + /* define a contiguous dataset of nbytes native bytes */ + h5dims[0] = (hsize_t)snbytes; + h5dims[1] = (hsize_t)snbytes; + h5dset_space_id = H5Screate_simple(2, h5dims, NULL); + VRFY((h5dset_space_id >= 0), "H5Screate_simple"); + + /* Set up the file dset space id to select the pattern to access */ + if (!parms->interleaved) { + /* Contiguous pattern */ + h5start[0] = (hsize_t)bytes_begin[0]; + h5start[1] = (hsize_t)bytes_begin[1]; + h5stride[0] = 1; + h5stride[1] = h5block[0] = h5block[1] = blk_size; + h5count[0] = 1; + h5count[1] = buf_size / blk_size; + } /* end if */ + else { + /* Interleaved access pattern */ + /* Skip offset over blocks of other processes */ + h5start[0] = (hsize_t)bytes_begin[0]; + h5start[1] = (hsize_t)bytes_begin[1]; + h5stride[0] = blk_size; + h5stride[1] = blk_size * (size_t)pio_mpi_nprocs_g; + h5block[0] = h5block[1] = blk_size; + h5count[0] = buf_size / blk_size; + h5count[1] = 1; + } /* end else */ + hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, + h5block); + VRFY((hrc >= 0), "H5Sselect_hyperslab"); + } /* end if */ + else { + h5dset_space_id = H5Screate(H5S_SCALAR); + VRFY((h5dset_space_id >= 0), "H5Screate"); + } /* end else */ + + /* Create the memory dataspace that corresponds to the xfer buffer */ + if (buf_size > 0) { + if (!parms->interleaved) { + h5dims[0] = blk_size; + h5dims[1] = buf_size; + } + else { + h5dims[0] = buf_size; + h5dims[1] = blk_size; + } + h5mem_space_id = H5Screate_simple(2, h5dims, NULL); + VRFY((h5mem_space_id >= 0), "H5Screate_simple"); + } /* end if */ + else { + h5mem_space_id = H5Screate(H5S_SCALAR); + VRFY((h5mem_space_id >= 0), "H5Screate"); + } /* end else */ + } /* end else */ + + /* Create the dataset transfer property list */ + h5dxpl = H5Pcreate(H5P_DATASET_XFER); + if (h5dxpl < 0) { + HDfprintf(stderr, "HDF5 Property List Create failed\n"); + GOTOERROR(FAIL); + } + + /* Change to collective I/O, if asked */ + if (parms->collective) { + hrc = H5Pset_dxpl_mpio(h5dxpl, H5FD_MPIO_COLLECTIVE); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Property List Set failed\n"); + GOTOERROR(FAIL); + } /* end if */ + } /* end if */ + break; + + default: + break; + } /* end switch */ + + for (ndset = 1; ndset <= ndsets; ++ndset) { + + /* Calculate dataset offset within a file */ + + /* create dataset */ + switch (parms->io_type) { + case POSIXIO: + case MPIO: + /* both posix and mpi io just need dataset offset in file*/ + dset_offset = (ndset - 1) * nbytes; + break; + + case PHDF5: + h5dcpl = H5Pcreate(H5P_DATASET_CREATE); + if (h5dcpl < 0) { + HDfprintf(stderr, "HDF5 Property List Create failed\n"); + GOTOERROR(FAIL); + } + /* 1D dataspace */ + if (!parms->dim2d) { + /* Make the dataset chunked if asked */ + if (parms->h5_use_chunks) { + /* Set the chunk size to be the same as the buffer size */ + h5dims[0] = blk_size; + hrc = H5Pset_chunk(h5dcpl, 1, h5dims); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Property List Set failed\n"); + GOTOERROR(FAIL); + } /* end if */ + } /* end if */ + } /* end if */ + else { + /* 2D dataspace */ + if (parms->h5_use_chunks) { + /* Set the chunk size to be the same as the block size */ + h5dims[0] = blk_size; + h5dims[1] = blk_size; + hrc = H5Pset_chunk(h5dcpl, 2, h5dims); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Property List Set failed\n"); + GOTOERROR(FAIL); + } /* end if */ + } /* end if */ + } /* end else */ + + HDsprintf(dname, "Dataset_%ld", ndset); + h5ds_id = H5DCREATE(fd->h5fd, dname, ELMT_H5_TYPE, h5dset_space_id, h5dcpl); + + if (h5ds_id < 0) { + HDfprintf(stderr, "HDF5 Dataset Create failed\n"); + GOTOERROR(FAIL); + } + + hrc = H5Pclose(h5dcpl); + /* verifying the close of the dcpl */ + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Property List Close failed\n"); + GOTOERROR(FAIL); + } + break; + + default: + break; + } + + /* The task is to transfer bytes_count bytes, starting at + * bytes_begin position, using transfer buffer of buf_size bytes. + * If interleaved, select buf_size at a time, in round robin + * fashion, according to number of process. Otherwise, select + * all bytes_count in contiguous. + */ + nbytes_xfer = 0; + + /* 1D dataspace */ + if (!parms->dim2d) { + /* Set base file offset for all I/O patterns and POSIX access */ + posix_file_offset = dset_offset + bytes_begin[0]; + + /* Set base file offset for all I/O patterns and MPI access */ + mpi_file_offset = (MPI_Offset)(dset_offset + bytes_begin[0]); + } /* end if */ + else { + /* Set base file offset for all I/O patterns and POSIX access */ + posix_file_offset = dset_offset + bytes_begin[0] * snbytes + bytes_begin[1]; + + /* Set base file offset for all I/O patterns and MPI access */ + mpi_file_offset = (MPI_Offset)(dset_offset + bytes_begin[0] * snbytes + bytes_begin[1]); + } /* end else */ + + /* Start "raw data" write timer */ + io_time_set(res->timers, HDF5_RAW_WRITE_FIXED_DIMS, TSTART); + + while (nbytes_xfer < bytes_count) { + /* Write */ + /* Calculate offset of write within a dataset/file */ + switch (parms->io_type) { + case POSIXIO: + /* 1D dataspace */ + if (!parms->dim2d) { + /* Contiguous pattern */ + if (!parms->interleaved) { + /* Compute file offset */ + file_offset = posix_file_offset + (off_t)nbytes_xfer; + + /* only care if seek returns error */ + rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; + VRFY((rc == 0), "POSIXSEEK"); + + /* check if all bytes are written */ + rc = ((ssize_t)buf_size == POSIXWRITE(fd->posixfd, buffer, buf_size)); + VRFY((rc != 0), "POSIXWRITE"); + + /* Advance global offset in dataset */ + nbytes_xfer += (ssize_t)buf_size; + } /* end if */ + /* Interleaved access pattern */ + else { + /* Set the base of user's buffer */ + buf_p = (unsigned char *)buffer; + + /* Set the number of bytes to transfer this time */ + nbytes_toxfer = buf_size; + + /* Loop over the buffers to write */ + while (nbytes_toxfer > 0) { + /* Skip offset over blocks of other processes */ + file_offset = posix_file_offset + (off_t)(nbytes_xfer * pio_mpi_nprocs_g); + + /* only care if seek returns error */ + rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; + VRFY((rc == 0), "POSIXSEEK"); + + /* check if all bytes are written */ + rc = ((ssize_t)blk_size == POSIXWRITE(fd->posixfd, buf_p, blk_size)); + VRFY((rc != 0), "POSIXWRITE"); + + /* Advance location in buffer */ + buf_p += blk_size; + + /* Advance global offset in dataset */ + nbytes_xfer += (ssize_t)blk_size; + + /* Decrement number of bytes left this time */ + nbytes_toxfer -= blk_size; + } /* end while */ + } /* end else */ + } /* end if */ + /* 2D dataspace */ + else { + /* Contiguous storage */ + if (!parms->h5_use_chunks) { + /* Contiguous access pattern */ + if (!parms->interleaved) { + /* Compute file offset */ + file_offset = posix_file_offset + + (off_t)((((size_t)nbytes_xfer / blk_size) / (size_t)snbytes) * + (blk_size * (size_t)snbytes) + + (((size_t)nbytes_xfer / blk_size) % (size_t)snbytes)); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = buf_size; + + /* Global offset advance after each I/O operation */ + file_offset_advance = (off_t)snbytes; + } /* end if */ + /* Interleaved access pattern */ + else { + /* Compute file offset */ + file_offset = + posix_file_offset + + (off_t)(((((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) / + (size_t)snbytes) * + (buf_size * (size_t)snbytes) + + (((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) % + (size_t)snbytes); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size; + + /* Global offset advance after each I/O operation */ + file_offset_advance = (off_t)snbytes; + } /* end else */ + } /* end if */ + /* Chunked storage */ + else { + /*Contiguous access pattern */ + if (!parms->interleaved) { + /* Compute file offset */ + file_offset = posix_file_offset + (off_t)nbytes_xfer; + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size * buf_size; + + /* Global offset advance after each I/O operation */ + file_offset_advance = 0; + } /* end if */ + /*Interleaved access pattern */ + else { + /* Compute file offset */ + /* Before simplification */ + /* file_offset=posix_file_offset+(off_t)((nbytes_xfer/(buf_size/blk_size) + *pio_mpi_nprocs_g)/(snbytes/blk_size*(blk_size*blk_size))*(buf_size/blk_size + *snbytes/blk_size*(blk_size*blk_size))+((nbytes_xfer/(buf_size/blk_size)) + *pio_mpi_nprocs_g)%(snbytes/blk_size*(blk_size*blk_size))); */ + + file_offset = posix_file_offset + + (off_t)((((size_t)nbytes_xfer / (buf_size / blk_size) * + (size_t)pio_mpi_nprocs_g) / + ((size_t)snbytes * blk_size)) * + (buf_size * (size_t)snbytes) + + (((size_t)nbytes_xfer / (buf_size / blk_size)) * + (size_t)pio_mpi_nprocs_g) % + ((size_t)snbytes * blk_size)); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size * blk_size; + + /* Global offset advance after each I/O operation */ + /* file_offset_advance = (off_t)(snbytes/blk_size*(blk_size*blk_size)); */ + file_offset_advance = (off_t)snbytes * (off_t)blk_size; + } /* end else */ + } /* end else */ + + /* Common code for file access */ + + /* Set the base of user's buffer */ + buf_p = (unsigned char *)buffer; + + /* Set the number of bytes to transfer this time */ + nbytes_toxfer = buf_size * blk_size; + + /* Loop over portions of the buffer to write */ + while (nbytes_toxfer > 0) { + /* only care if seek returns error */ + rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; + VRFY((rc == 0), "POSIXSEEK"); + + /* check if all bytes are written */ + rc = ((ssize_t)nbytes_xfer_advance == + POSIXWRITE(fd->posixfd, buf_p, nbytes_xfer_advance)); + VRFY((rc != 0), "POSIXWRITE"); + + /* Advance location in buffer */ + buf_p += nbytes_xfer_advance; + + /* Advance global offset in dataset */ + nbytes_xfer += (ssize_t)nbytes_xfer_advance; + + /* Decrement number of bytes left this time */ + nbytes_toxfer -= nbytes_xfer_advance; + + /* Partially advance file offset */ + file_offset += file_offset_advance; + } /* end while */ + + } /* end else */ + + break; + + case MPIO: + /* 1D dataspace */ + if (!parms->dim2d) { + /* Independent file access */ + if (!parms->collective) { + /* Contiguous pattern */ + if (!parms->interleaved) { + /* Compute offset in file */ + mpi_offset = mpi_file_offset + nbytes_xfer; + + /* Perform independent write */ + mrc = + MPI_File_write_at(fd->mpifd, mpi_offset, buffer, + (int)(buf_size / blk_size), mpi_blk_type, &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); + + /* Advance global offset in dataset */ + nbytes_xfer += (ssize_t)buf_size; + } /* end if */ + /* Interleaved access pattern */ + else { + /* Set the base of user's buffer */ + buf_p = (unsigned char *)buffer; + + /* Set the number of bytes to transfer this time */ + nbytes_toxfer = buf_size; + + /* Loop over the buffers to write */ + while (nbytes_toxfer > 0) { + /* Skip offset over blocks of other processes */ + mpi_offset = mpi_file_offset + (nbytes_xfer * pio_mpi_nprocs_g); + + /* Perform independent write */ + mrc = MPI_File_write_at(fd->mpifd, mpi_offset, buf_p, (int)1, + mpi_blk_type, &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); + + /* Advance location in buffer */ + buf_p += blk_size; + + /* Advance global offset in dataset */ + nbytes_xfer += (ssize_t)blk_size; + + /* Decrement number of bytes left this time */ + nbytes_toxfer -= blk_size; + } /* end while */ + } /* end else */ + } /* end if */ + /* Collective file access */ + else { + /* Contiguous access pattern */ + if (!parms->interleaved) { + /* Compute offset in file */ + mpi_offset = mpi_file_offset + nbytes_xfer; + + /* Perform independent write */ + mrc = MPI_File_write_at_all(fd->mpifd, mpi_offset, buffer, + (int)(buf_size / blk_size), mpi_blk_type, + &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); + + /* Advance global offset in dataset */ + nbytes_xfer += (ssize_t)buf_size; + } /* end if */ + /* Interleaved access pattern */ + else { + /* Compute offset in file */ + mpi_offset = mpi_file_offset + (nbytes_xfer * pio_mpi_nprocs_g); + + /* Set the file view */ + mrc = MPI_File_set_view(fd->mpifd, mpi_offset, mpi_blk_type, mpi_file_type, + (char *)"native", h5_io_info_g); + VRFY((mrc == MPI_SUCCESS), "MPIO_VIEW"); + + /* Perform write */ + mrc = MPI_File_write_at_all(fd->mpifd, 0, buffer, (int)(buf_size / blk_size), + mpi_blk_type, &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); + + /* Advance global offset in dataset */ + nbytes_xfer += (ssize_t)buf_size; + } /* end else */ + } /* end else */ + } /* end if */ + /* 2D dataspace */ + else { + /* Contiguous storage */ + if (!parms->h5_use_chunks) { + /* Contiguous access pattern */ + if (!parms->interleaved) { + /* Compute offset in file */ + mpi_offset = + mpi_file_offset + + (MPI_Offset)((((size_t)nbytes_xfer / blk_size) / (size_t)snbytes) * + (blk_size * (size_t)snbytes)) + + (MPI_Offset)(((size_t)nbytes_xfer / blk_size) % (size_t)snbytes); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = buf_size; + + /* Global offset advance after each I/O operation */ + mpi_offset_advance = snbytes; + + /* MPI type to be used for collective access */ + mpi_collective_type = mpi_cont_type; + } /* end if */ + /* Interleaved access pattern */ + else { + /* Compute offset in file */ + mpi_offset = + mpi_file_offset + + (MPI_Offset)( + ((((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) / + (size_t)snbytes) * + (buf_size * (size_t)snbytes)) + + (MPI_Offset)( + (((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) % + (size_t)snbytes); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size; + + /* Global offset advance after each I/O operation */ + mpi_offset_advance = snbytes; + + /* MPI type to be used for collective access */ + mpi_collective_type = mpi_inter_type; + } /* end else */ + } /* end if */ + /* Chunked storage */ + else { + /*Contiguous access pattern */ + if (!parms->interleaved) { + /* Compute offset in file */ + mpi_offset = mpi_file_offset + nbytes_xfer; + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size * buf_size; + + /* Global offset advance after each I/O operation */ + mpi_offset_advance = 0; + + /* MPI type to be used for collective access */ + mpi_collective_type = mpi_full_buffer; + } /* end if */ + /*Interleaved access pattern */ + else { + /* Compute offset in file */ + /* Before simplification */ + /* mpi_offset=mpi_file_offset+(nbytes_xfer/(buf_size/blk_size) + *pio_mpi_nprocs_g)/(snbytes/blk_size*(blk_size*blk_size))* + (buf_size/blk_size*snbytes/blk_size*(blk_size*blk_size))+ + ((nbytes_xfer/(buf_size/blk_size))*pio_mpi_nprocs_g)%(snbytes + /blk_size*(blk_size*blk_size)); */ + mpi_offset = mpi_file_offset + + (MPI_Offset)((((size_t)nbytes_xfer / (buf_size / blk_size) * + (size_t)pio_mpi_nprocs_g) / + ((size_t)snbytes * blk_size)) * + (buf_size * (size_t)snbytes)) + + (MPI_Offset)((((size_t)nbytes_xfer / (buf_size / blk_size)) * + (size_t)pio_mpi_nprocs_g) % + ((size_t)snbytes * blk_size)); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size * blk_size; + + /* Global offset advance after each I/O operation */ + /* mpi_offset_advance = (MPI_Offset)(snbytes/blk_size*(blk_size*blk_size)); */ + mpi_offset_advance = (MPI_Offset)((size_t)snbytes * blk_size); + + /* MPI type to be used for collective access */ + mpi_collective_type = mpi_chunk_inter_type; + } /* end else */ + } /* end else */ + + /* Common code for independent file access */ + if (!parms->collective) { + /* Set the base of user's buffer */ + buf_p = (unsigned char *)buffer; + + /* Set the number of bytes to transfer this time */ + nbytes_toxfer = buf_size * blk_size; + + /* Loop over portions of the buffer to write */ + while (nbytes_toxfer > 0) { + /* Perform independent write */ + mrc = MPI_File_write_at(fd->mpifd, mpi_offset, buf_p, + (int)nbytes_xfer_advance, MPI_BYTE, &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); + + /* Advance location in buffer */ + buf_p += nbytes_xfer_advance; + + /* Advance global offset in dataset */ + nbytes_xfer += (ssize_t)nbytes_xfer_advance; + + /* Decrement number of bytes left this time */ + nbytes_toxfer -= nbytes_xfer_advance; + + /* Partially advance global offset in dataset */ + mpi_offset += mpi_offset_advance; + } /* end while */ + } /* end if */ + + /* Common code for collective file access */ + else { + /* Set the file view */ + mrc = MPI_File_set_view(fd->mpifd, mpi_offset, MPI_BYTE, mpi_collective_type, + (char *)"native", h5_io_info_g); + VRFY((mrc == MPI_SUCCESS), "MPIO_VIEW"); + + /* Perform write */ + MPI_File_write_at_all(fd->mpifd, 0, buffer, (int)(buf_size * blk_size), MPI_BYTE, + &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); + + /* Advance global offset in dataset */ + nbytes_xfer += (off_t)buf_size * (off_t)blk_size; + } /* end else */ + + } /* end else */ + + break; + + case PHDF5: + /* 1D dataspace */ + if (!parms->dim2d) { + /* Set up the file dset space id to move the selection to process */ + if (!parms->interleaved) { + /* Contiguous pattern */ + h5offset[0] = nbytes_xfer; + } /* end if */ + else { + /* Interleaved access pattern */ + /* Skip offset over blocks of other processes */ + h5offset[0] = (nbytes_xfer * pio_mpi_nprocs_g); + } /* end else */ + hrc = H5Soffset_simple(h5dset_space_id, h5offset); + VRFY((hrc >= 0), "H5Soffset_simple"); + + /* Write the buffer out */ + hrc = + H5Dwrite(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); + VRFY((hrc >= 0), "H5Dwrite"); + + /* Increment number of bytes transferred */ + nbytes_xfer += (ssize_t)buf_size; + } /* end if */ + /* 2D dataspace */ + else { + /* Set up the file dset space id to move the selection to process */ + if (!parms->interleaved) { + /* Contiguous pattern */ + h5offset[0] = + (hssize_t)(((size_t)nbytes_xfer / ((size_t)snbytes * blk_size)) * blk_size); + h5offset[1] = + (hssize_t)(((size_t)nbytes_xfer % ((size_t)snbytes * blk_size)) / blk_size); + + } /* end if */ + else { + /* Interleaved access pattern */ + /* Skip offset over blocks of other processes */ + h5offset[0] = (hssize_t)((((size_t)nbytes_xfer * (size_t)pio_mpi_nprocs_g) / + ((size_t)snbytes * buf_size)) * + buf_size); + h5offset[1] = (hssize_t)((((size_t)nbytes_xfer * (size_t)pio_mpi_nprocs_g) % + ((size_t)snbytes * buf_size)) / + buf_size); + + } /* end else */ + hrc = H5Soffset_simple(h5dset_space_id, h5offset); + VRFY((hrc >= 0), "H5Soffset_simple"); + + /* Write the buffer out */ + hrc = + H5Dwrite(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); + VRFY((hrc >= 0), "H5Dwrite"); + + /* Increment number of bytes transferred */ + nbytes_xfer += (off_t)buf_size * (off_t)blk_size; + + } /* end else */ + + break; + + default: + break; + } /* switch (parms->io_type) */ + } /* end while */ + + /* Stop "raw data" write timer */ + io_time_set(res->timers, HDF5_RAW_WRITE_FIXED_DIMS, TSTOP); + + /* Calculate write time */ + + /* Close dataset. Only HDF5 needs to do an explicit close. */ + if (parms->io_type == PHDF5) { + hrc = H5Dclose(h5ds_id); + + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Close failed\n"); + GOTOERROR(FAIL); + } + + h5ds_id = H5I_INVALID_HID; + } /* end if */ + } /* end for */ + +done: + /* release MPI-I/O objects */ + if (parms->io_type == MPIO) { + /* 1D dataspace */ + if (!parms->dim2d) { + /* Free file type */ + mrc = MPI_Type_free(&mpi_file_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free buffer type */ + mrc = MPI_Type_free(&mpi_blk_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + } /* end if */ + /* 2D dataspace */ + else { + /* Free partial buffer type for contiguous access */ + mrc = MPI_Type_free(&mpi_partial_buffer_cont); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free contiguous file type */ + mrc = MPI_Type_free(&mpi_cont_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free partial buffer type for interleaved access */ + mrc = MPI_Type_free(&mpi_partial_buffer_inter); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free interleaved file type */ + mrc = MPI_Type_free(&mpi_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free full buffer type */ + mrc = MPI_Type_free(&mpi_full_buffer); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free full chunk type */ + mrc = MPI_Type_free(&mpi_full_chunk); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free chunk interleaved file type */ + mrc = MPI_Type_free(&mpi_chunk_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + } /* end else */ + } /* end if */ + + /* release HDF5 objects */ + if (h5dset_space_id != -1) { + hrc = H5Sclose(h5dset_space_id); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Space Close failed\n"); + ret_code = FAIL; + } + else { + h5dset_space_id = H5I_INVALID_HID; + } + } + + if (h5mem_space_id != -1) { + hrc = H5Sclose(h5mem_space_id); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Memory Space Close failed\n"); + ret_code = FAIL; + } + else { + h5mem_space_id = H5I_INVALID_HID; + } + } + + if (h5dxpl != -1) { + hrc = H5Pclose(h5dxpl); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Transfer Property List Close failed\n"); + ret_code = FAIL; + } + else { + h5dxpl = H5I_INVALID_HID; + } + } + + return ret_code; +} + +static off_t +sqrto(off_t x) +{ + double root_x = sqrt((double)x); + return (off_t)root_x; +} + +/* + * Function: do_read + * Purpose: read the required amount of data from the file. + * Return: SUCCESS or FAIL + * Programmer: Albert Cheng 2001/12/13 + * Modifications: + * Added 2D testing (Christian Chilan, 10. August 2005) + */ +static herr_t +do_read(results *res, file_descr *fd, parameters *parms, long ndsets, off_t nbytes, size_t buf_size, + void *buffer /*out*/) +{ + int ret_code = SUCCESS; + int rc; /*routine return code */ + long ndset; + size_t blk_size; /* The block size to subdivide the xfer buffer into */ + size_t bsize; /* Size of the actual buffer */ + off_t nbytes_xfer; /* Total number of bytes transferred so far */ + size_t nbytes_xfer_advance; /* Number of bytes transferred in a single I/O operation */ + size_t nbytes_toxfer; /* Number of bytes to transfer a particular time */ + char dname[64]; + off_t dset_offset = 0; /*dataset offset in a file */ + off_t bytes_begin[2]; /*first elmt this process transfer */ + off_t bytes_count; /*number of elmts this process transfer */ + off_t snbytes = 0; /*size of a side of the dataset square */ + unsigned char *buf_p; /* Current buffer pointer */ + + /* POSIX variables */ + off_t file_offset; /* File offset of the next transfer */ + off_t file_offset_advance; /* File offset advance after each I/O operation */ + off_t posix_file_offset; /* Base file offset of the next transfer */ + + /* MPI variables */ + MPI_Offset mpi_file_offset; /* Base file offset of the next transfer*/ + MPI_Offset mpi_offset; /* Offset in MPI file */ + MPI_Offset mpi_offset_advance; /* Offset advance after each I/O operation */ + MPI_Datatype mpi_file_type; /* MPI derived type for 1D file */ + MPI_Datatype mpi_blk_type; /* MPI derived type for 1D buffer */ + MPI_Datatype mpi_cont_type; /* MPI derived type for 2D contiguous file */ + MPI_Datatype mpi_partial_buffer_cont; /* MPI derived type for partial 2D contiguous buffer */ + MPI_Datatype mpi_inter_type; /* MPI derived type for 2D interleaved file */ + MPI_Datatype mpi_partial_buffer_inter; /* MPI derived type for partial 2D interleaved buffer */ + MPI_Datatype mpi_full_buffer; /* MPI derived type for 2D full buffer */ + MPI_Datatype mpi_full_chunk; /* MPI derived type for 2D full chunk */ + MPI_Datatype mpi_chunk_inter_type; /* MPI derived type for 2D chunk interleaved file */ + MPI_Datatype mpi_collective_type; /* Generic MPI derived type for 2D collective access */ + MPI_Status mpi_status; + int mrc; /* MPI return code */ + + /* HDF5 variables */ + herr_t hrc; /*HDF5 return code */ + hsize_t h5dims[2]; /*dataset dim sizes */ + hid_t h5dset_space_id = H5I_INVALID_HID; /*dataset space ID */ + hid_t h5mem_space_id = H5I_INVALID_HID; /*memory dataspace ID */ + hid_t h5ds_id = H5I_INVALID_HID; /*dataset handle */ + hsize_t h5block[2]; /*dataspace selection */ + hsize_t h5stride[2]; + hsize_t h5count[2]; + hsize_t h5start[2]; + hssize_t h5offset[2]; /* Selection offset within dataspace */ + hid_t h5dxpl = H5I_INVALID_HID; /* Dataset transfer property list */ + + /* Get the parameters from the parameter block */ + blk_size = parms->blk_size; + + /* There are two kinds of transfer patterns, contiguous and interleaved. + * Let 0,1,2,...,n be data accessed by process 0,1,2,...,n + * where n is rank of the last process. + * In contiguous pattern, data are accessed as + * 000...111...222...nnn... + * In interleaved pattern, data are accessed as + * 012...n012...n... + * These are all in the scope of one dataset. + */ + + /* 1D dataspace */ + if (!parms->dim2d) { + bsize = buf_size; + /* Contiguous Pattern: */ + if (!parms->interleaved) { + bytes_begin[0] = (off_t)(((double)nbytes * pio_mpi_rank_g) / pio_mpi_nprocs_g); + } /* end if */ + /* Interleaved Pattern: */ + else { + bytes_begin[0] = (off_t)blk_size * (off_t)pio_mpi_rank_g; + } /* end else */ + } /* end if */ + /* 2D dataspace */ + else { + /* nbytes is always the number of bytes per dataset (1D or 2D). If the + dataspace is 2D, snbytes is the size of a side of the 'dataset square'. + */ + snbytes = sqrto(nbytes); + + bsize = buf_size * blk_size; + + /* Contiguous Pattern: */ + if (!parms->interleaved) { + bytes_begin[0] = (off_t)((double)snbytes * pio_mpi_rank_g / pio_mpi_nprocs_g); + bytes_begin[1] = 0; + } /* end if */ + /* Interleaved Pattern: */ + else { + bytes_begin[0] = 0; + + if (!parms->h5_use_chunks || parms->io_type == PHDF5) + bytes_begin[1] = (off_t)blk_size * (off_t)pio_mpi_rank_g; + else + bytes_begin[1] = (off_t)blk_size * (off_t)blk_size * (off_t)pio_mpi_rank_g; + } /* end else */ + } /* end else */ + + /* Calculate the total number of bytes (bytes_count) to be + * transferred by this process. It may be different for different + * transfer pattern due to rounding to integral values. + */ + /* + * Calculate the beginning bytes of this process and the next. + * bytes_count is the difference between these two beginnings. + * This way, it eliminates any rounding errors. + * (This is tricky, don't mess with the formula, rounding errors + * can easily get introduced) */ + bytes_count = (off_t)(((double)nbytes * (pio_mpi_rank_g + 1)) / pio_mpi_nprocs_g) - + (off_t)(((double)nbytes * pio_mpi_rank_g) / pio_mpi_nprocs_g); + + /* debug */ + if (pio_debug_level >= 4) { + HDprint_rank(output); + if (!parms->dim2d) { + HDfprintf(output, + "Debug(do_write): " + "buf_size=%zu, bytes_begin=%" H5_PRINTF_LL_WIDTH "d, bytes_count=%" H5_PRINTF_LL_WIDTH + "d\n", + buf_size, (long long)bytes_begin[0], (long long)bytes_count); + } + else { + HDfprintf(output, + "Debug(do_write): " + "linear buf_size=%zu, bytes_begin=(%" H5_PRINTF_LL_WIDTH "d,%" H5_PRINTF_LL_WIDTH + "d), bytes_count=%" H5_PRINTF_LL_WIDTH "d\n", + buf_size * blk_size, (long long)bytes_begin[0], (long long)bytes_begin[1], + (long long)bytes_count); + } + } + + /* I/O Access specific setup */ + switch (parms->io_type) { + case POSIXIO: + /* No extra setup */ + break; + + case MPIO: /* MPI-I/O setup */ + /* 1D dataspace */ + if (!parms->dim2d) { + /* Build block's derived type */ + mrc = MPI_Type_contiguous((int)blk_size, MPI_BYTE, &mpi_blk_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Build file's derived type */ + mrc = MPI_Type_vector((int)(buf_size / blk_size), (int)1, (int)pio_mpi_nprocs_g, mpi_blk_type, + &mpi_file_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit file type */ + mrc = MPI_Type_commit(&mpi_file_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Commit buffer type */ + mrc = MPI_Type_commit(&mpi_blk_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + } /* end if */ + /* 2D dataspace */ + else { + /* Build partial buffer derived type for contiguous access */ + mrc = MPI_Type_contiguous((int)buf_size, MPI_BYTE, &mpi_partial_buffer_cont); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit partial buffer derived type */ + mrc = MPI_Type_commit(&mpi_partial_buffer_cont); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build contiguous file's derived type */ + mrc = MPI_Type_vector((int)blk_size, (int)1, (int)((size_t)snbytes / buf_size), + mpi_partial_buffer_cont, &mpi_cont_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit contiguous file type */ + mrc = MPI_Type_commit(&mpi_cont_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build partial buffer derived type for interleaved access */ + mrc = MPI_Type_contiguous((int)blk_size, MPI_BYTE, &mpi_partial_buffer_inter); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit partial buffer derived type */ + mrc = MPI_Type_commit(&mpi_partial_buffer_inter); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build interleaved file's derived type */ + mrc = MPI_Type_vector((int)buf_size, (int)1, (int)((size_t)snbytes / blk_size), + mpi_partial_buffer_inter, &mpi_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit interleaved file type */ + mrc = MPI_Type_commit(&mpi_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build full buffer derived type */ + mrc = MPI_Type_contiguous((int)(blk_size * buf_size), MPI_BYTE, &mpi_full_buffer); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit full buffer derived type */ + mrc = MPI_Type_commit(&mpi_full_buffer); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build full chunk derived type */ + mrc = MPI_Type_contiguous((int)(blk_size * blk_size), MPI_BYTE, &mpi_full_chunk); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit full chunk derived type */ + mrc = MPI_Type_commit(&mpi_full_chunk); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build chunk interleaved file's derived type */ + mrc = MPI_Type_vector((int)(buf_size / blk_size), (int)1, (int)((size_t)snbytes / blk_size), + mpi_full_chunk, &mpi_chunk_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit chunk interleaved file type */ + mrc = MPI_Type_commit(&mpi_chunk_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + } /* end else */ + break; + + case PHDF5: /* HDF5 setup */ + /* 1D dataspace */ + if (!parms->dim2d) { + if (nbytes > 0) { + /* define a contiguous dataset of nbytes native bytes */ + h5dims[0] = (hsize_t)nbytes; + h5dset_space_id = H5Screate_simple(1, h5dims, NULL); + VRFY((h5dset_space_id >= 0), "H5Screate_simple"); + + /* Set up the file dset space id to select the pattern to access */ + if (!parms->interleaved) { + /* Contiguous pattern */ + h5start[0] = (hsize_t)bytes_begin[0]; + h5stride[0] = h5block[0] = blk_size; + h5count[0] = buf_size / blk_size; + } /* end if */ + else { + /* Interleaved access pattern */ + /* Skip offset over blocks of other processes */ + h5start[0] = (hsize_t)bytes_begin[0]; + h5stride[0] = blk_size * (size_t)pio_mpi_nprocs_g; + h5block[0] = blk_size; + h5count[0] = buf_size / blk_size; + } /* end else */ + hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, + h5block); + VRFY((hrc >= 0), "H5Sselect_hyperslab"); + } /* end if */ + else { + h5dset_space_id = H5Screate(H5S_SCALAR); + VRFY((h5dset_space_id >= 0), "H5Screate"); + } /* end else */ + + /* Create the memory dataspace that corresponds to the xfer buffer */ + if (buf_size > 0) { + h5dims[0] = buf_size; + h5mem_space_id = H5Screate_simple(1, h5dims, NULL); + VRFY((h5mem_space_id >= 0), "H5Screate_simple"); + } /* end if */ + else { + h5mem_space_id = H5Screate(H5S_SCALAR); + VRFY((h5mem_space_id >= 0), "H5Screate"); + } /* end else */ + } /* end if */ + /* 2D dataspace */ + else { + if (nbytes > 0) { + /* define a contiguous dataset of nbytes native bytes */ + h5dims[0] = (hsize_t)snbytes; + h5dims[1] = (hsize_t)snbytes; + h5dset_space_id = H5Screate_simple(2, h5dims, NULL); + VRFY((h5dset_space_id >= 0), "H5Screate_simple"); + + /* Set up the file dset space id to select the pattern to access */ + if (!parms->interleaved) { + /* Contiguous pattern */ + h5start[0] = (hsize_t)bytes_begin[0]; + h5start[1] = (hsize_t)bytes_begin[1]; + h5stride[0] = 1; + h5stride[1] = h5block[0] = h5block[1] = blk_size; + h5count[0] = 1; + h5count[1] = buf_size / blk_size; + } /* end if */ + else { + /* Interleaved access pattern */ + /* Skip offset over blocks of other processes */ + h5start[0] = (hsize_t)bytes_begin[0]; + h5start[1] = (hsize_t)bytes_begin[1]; + h5stride[0] = blk_size; + h5stride[1] = blk_size * (size_t)pio_mpi_nprocs_g; + h5block[0] = h5block[1] = blk_size; + h5count[0] = buf_size / blk_size; + h5count[1] = 1; + } /* end else */ + hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, + h5block); + VRFY((hrc >= 0), "H5Sselect_hyperslab"); + } /* end if */ + else { + h5dset_space_id = H5Screate(H5S_SCALAR); + VRFY((h5dset_space_id >= 0), "H5Screate"); + } /* end else */ + + /* Create the memory dataspace that corresponds to the xfer buffer */ + if (buf_size > 0) { + if (!parms->interleaved) { + h5dims[0] = blk_size; + h5dims[1] = buf_size; + } + else { + h5dims[0] = buf_size; + h5dims[1] = blk_size; + } + h5mem_space_id = H5Screate_simple(2, h5dims, NULL); + VRFY((h5mem_space_id >= 0), "H5Screate_simple"); + } /* end if */ + else { + h5mem_space_id = H5Screate(H5S_SCALAR); + VRFY((h5mem_space_id >= 0), "H5Screate"); + } /* end else */ + } /* end else */ + + /* Create the dataset transfer property list */ + h5dxpl = H5Pcreate(H5P_DATASET_XFER); + if (h5dxpl < 0) { + HDfprintf(stderr, "HDF5 Property List Create failed\n"); + GOTOERROR(FAIL); + } + + /* Change to collective I/O, if asked */ + if (parms->collective) { + hrc = H5Pset_dxpl_mpio(h5dxpl, H5FD_MPIO_COLLECTIVE); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Property List Set failed\n"); + GOTOERROR(FAIL); + } /* end if */ + } /* end if */ + break; + + default: + break; + } /* end switch */ + + for (ndset = 1; ndset <= ndsets; ++ndset) { + + /* Calculate dataset offset within a file */ + + /* create dataset */ + switch (parms->io_type) { + case POSIXIO: + case MPIO: + /* both posix and mpi io just need dataset offset in file*/ + dset_offset = (ndset - 1) * nbytes; + break; + + case PHDF5: + HDsprintf(dname, "Dataset_%ld", ndset); + h5ds_id = H5DOPEN(fd->h5fd, dname); + if (h5ds_id < 0) { + HDfprintf(stderr, "HDF5 Dataset open failed\n"); + GOTOERROR(FAIL); + } + break; + + default: + break; + } + + /* The task is to transfer bytes_count bytes, starting at + * bytes_begin position, using transfer buffer of buf_size bytes. + * If interleaved, select buf_size at a time, in round robin + * fashion, according to number of process. Otherwise, select + * all bytes_count in contiguous. + */ + nbytes_xfer = 0; + + /* 1D dataspace */ + if (!parms->dim2d) { + /* Set base file offset for all I/O patterns and POSIX access */ + posix_file_offset = dset_offset + bytes_begin[0]; + + /* Set base file offset for all I/O patterns and MPI access */ + mpi_file_offset = (MPI_Offset)(dset_offset + bytes_begin[0]); + } /* end if */ + else { + /* Set base file offset for all I/O patterns and POSIX access */ + posix_file_offset = dset_offset + bytes_begin[0] * snbytes + bytes_begin[1]; + + /* Set base file offset for all I/O patterns and MPI access */ + mpi_file_offset = (MPI_Offset)(dset_offset + bytes_begin[0] * snbytes + bytes_begin[1]); + } /* end else */ + + /* Start "raw data" read timer */ + io_time_set(res->timers, HDF5_RAW_READ_FIXED_DIMS, TSTART); + + while (nbytes_xfer < bytes_count) { + /* Read */ + /* Calculate offset of read within a dataset/file */ + switch (parms->io_type) { + case POSIXIO: + /* 1D dataspace */ + if (!parms->dim2d) { + /* Contiguous pattern */ + if (!parms->interleaved) { + /* Compute file offset */ + file_offset = posix_file_offset + (off_t)nbytes_xfer; + + /* only care if seek returns error */ + rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; + VRFY((rc == 0), "POSIXSEEK"); + + /* check if all bytes are read */ + rc = ((ssize_t)buf_size == POSIXREAD(fd->posixfd, buffer, buf_size)); + VRFY((rc != 0), "POSIXREAD"); + + /* Advance global offset in dataset */ + nbytes_xfer += (off_t)buf_size; + } /* end if */ + /* Interleaved access pattern */ + else { + /* Set the base of user's buffer */ + buf_p = (unsigned char *)buffer; + + /* Set the number of bytes to transfer this time */ + nbytes_toxfer = buf_size; + + /* Loop over the buffers to read */ + while (nbytes_toxfer > 0) { + /* Skip offset over blocks of other processes */ + file_offset = posix_file_offset + (off_t)(nbytes_xfer * pio_mpi_nprocs_g); + + /* only care if seek returns error */ + rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; + VRFY((rc == 0), "POSIXSEEK"); + + /* check if all bytes are read */ + rc = ((ssize_t)blk_size == POSIXREAD(fd->posixfd, buf_p, blk_size)); + VRFY((rc != 0), "POSIXREAD"); + + /* Advance location in buffer */ + buf_p += blk_size; + + /* Advance global offset in dataset */ + nbytes_xfer += (off_t)blk_size; + + /* Decrement number of bytes left this time */ + nbytes_toxfer -= blk_size; + } /* end while */ + } /* end else */ + } /* end if */ + /* 2D dataspace */ + else { + /* Contiguous storage */ + if (!parms->h5_use_chunks) { + /* Contiguous access pattern */ + if (!parms->interleaved) { + /* Compute file offset */ + file_offset = posix_file_offset + + (off_t)((((size_t)nbytes_xfer / blk_size) / (size_t)snbytes) * + (blk_size * (size_t)snbytes) + + (((size_t)nbytes_xfer / blk_size) % (size_t)snbytes)); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = buf_size; + + /* Global offset advance after each I/O operation */ + file_offset_advance = (off_t)snbytes; + } /* end if */ + /* Interleaved access pattern */ + else { + /* Compute file offset */ + file_offset = + posix_file_offset + + (off_t)(((((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) / + (size_t)snbytes) * + (buf_size * (size_t)snbytes) + + (((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) % + (size_t)snbytes); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size; + + /* Global offset advance after each I/O operation */ + file_offset_advance = (off_t)snbytes; + } /* end else */ + } /* end if */ + /* Chunked storage */ + else { + /*Contiguous access pattern */ + if (!parms->interleaved) { + /* Compute file offset */ + file_offset = posix_file_offset + (off_t)nbytes_xfer; + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size * buf_size; + + /* Global offset advance after each I/O operation */ + file_offset_advance = 0; + } /* end if */ + /*Interleaved access pattern */ + else { + /* Compute file offset */ + /* Before simplification */ + /* file_offset=posix_file_offset+(off_t)((nbytes_xfer/(buf_size/blk_size) + *pio_mpi_nprocs_g)/(snbytes/blk_size*(blk_size*blk_size))*(buf_size/blk_size + *snbytes/blk_size*(blk_size*blk_size))+((nbytes_xfer/(buf_size/blk_size)) + *pio_mpi_nprocs_g)%(snbytes/blk_size*(blk_size*blk_size))); */ + + file_offset = posix_file_offset + + (off_t)((((size_t)nbytes_xfer / (buf_size / blk_size) * + (size_t)pio_mpi_nprocs_g) / + ((size_t)snbytes * blk_size)) * + (buf_size * (size_t)snbytes) + + (((size_t)nbytes_xfer / (buf_size / blk_size)) * + (size_t)pio_mpi_nprocs_g) % + ((size_t)snbytes * blk_size)); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size * blk_size; + + /* Global offset advance after each I/O operation */ + /* file_offset_advance = (off_t)(snbytes/blk_size*(blk_size*blk_size)); */ + file_offset_advance = (off_t)((size_t)snbytes * blk_size); + } /* end else */ + } /* end else */ + + /* Common code for file access */ + + /* Set the base of user's buffer */ + buf_p = (unsigned char *)buffer; + + /* Set the number of bytes to transfer this time */ + nbytes_toxfer = buf_size * blk_size; + + /* Loop over portions of the buffer to read */ + while (nbytes_toxfer > 0) { + /* only care if seek returns error */ + rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; + VRFY((rc == 0), "POSIXSEEK"); + + /* check if all bytes are read */ + rc = ((ssize_t)nbytes_xfer_advance == + POSIXREAD(fd->posixfd, buf_p, nbytes_xfer_advance)); + VRFY((rc != 0), "POSIXREAD"); + + /* Advance location in buffer */ + buf_p += nbytes_xfer_advance; + + /* Advance global offset in dataset */ + nbytes_xfer += (off_t)nbytes_xfer_advance; + + /* Decrement number of bytes left this time */ + nbytes_toxfer -= nbytes_xfer_advance; + + /* Partially advance file offset */ + file_offset += file_offset_advance; + } /* end while */ + + } /* end else */ + break; + + case MPIO: + /* 1D dataspace */ + if (!parms->dim2d) { + /* Independent file access */ + if (!parms->collective) { + /* Contiguous pattern */ + if (!parms->interleaved) { + /* Compute offset in file */ + mpi_offset = mpi_file_offset + nbytes_xfer; + + /* Perform independent read */ + mrc = MPI_File_read_at(fd->mpifd, mpi_offset, buffer, + (int)(buf_size / blk_size), mpi_blk_type, &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); + + /* Advance global offset in dataset */ + nbytes_xfer += (off_t)buf_size; + } /* end if */ + /* Interleaved access pattern */ + else { + /* Set the base of user's buffer */ + buf_p = (unsigned char *)buffer; + + /* Set the number of bytes to transfer this time */ + nbytes_toxfer = buf_size; + + /* Loop over the buffers to read */ + while (nbytes_toxfer > 0) { + /* Skip offset over blocks of other processes */ + mpi_offset = mpi_file_offset + (nbytes_xfer * pio_mpi_nprocs_g); + + /* Perform independent read */ + mrc = MPI_File_read_at(fd->mpifd, mpi_offset, buf_p, (int)1, mpi_blk_type, + &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); + + /* Advance location in buffer */ + buf_p += blk_size; + + /* Advance global offset in dataset */ + nbytes_xfer += (off_t)blk_size; + + /* Decrement number of bytes left this time */ + nbytes_toxfer -= blk_size; + } /* end while */ + } /* end else */ + } /* end if */ + /* Collective file access */ + else { + /* Contiguous access pattern */ + if (!parms->interleaved) { + /* Compute offset in file */ + mpi_offset = mpi_file_offset + nbytes_xfer; + + /* Perform collective read */ + mrc = MPI_File_read_at_all(fd->mpifd, mpi_offset, buffer, + (int)(buf_size / blk_size), mpi_blk_type, + &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); + + /* Advance global offset in dataset */ + nbytes_xfer += (off_t)buf_size; + } /* end if */ + /* Interleaved access pattern */ + else { + /* Compute offset in file */ + mpi_offset = mpi_file_offset + (nbytes_xfer * pio_mpi_nprocs_g); + + /* Set the file view */ + mrc = MPI_File_set_view(fd->mpifd, mpi_offset, mpi_blk_type, mpi_file_type, + (char *)"native", h5_io_info_g); + VRFY((mrc == MPI_SUCCESS), "MPIO_VIEW"); + + /* Perform collective read */ + mrc = MPI_File_read_at_all(fd->mpifd, 0, buffer, (int)(buf_size / blk_size), + mpi_blk_type, &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); + + /* Advance global offset in dataset */ + nbytes_xfer += (off_t)buf_size; + } /* end else */ + } /* end else */ + } /* end if */ + /* 2D dataspace */ + else { + /* Contiguous storage */ + if (!parms->h5_use_chunks) { + /* Contiguous access pattern */ + if (!parms->interleaved) { + /* Compute offset in file */ + mpi_offset = + mpi_file_offset + + (MPI_Offset)((((size_t)nbytes_xfer / blk_size) / (size_t)snbytes) * + (blk_size * (size_t)snbytes)) + + (MPI_Offset)(((size_t)nbytes_xfer / blk_size) % (size_t)snbytes); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = buf_size; + + /* Global offset advance after each I/O operation */ + mpi_offset_advance = snbytes; + + /* MPI type to be used for collective access */ + mpi_collective_type = mpi_cont_type; + } /* end if */ + /* Interleaved access pattern */ + else { + /* Compute offset in file */ + mpi_offset = + mpi_file_offset + + (MPI_Offset)( + ((((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) / + (size_t)snbytes) * + (buf_size * (size_t)snbytes)) + + (MPI_Offset)( + (((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) % + (size_t)snbytes); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size; + + /* Global offset advance after each I/O operation */ + mpi_offset_advance = snbytes; + + /* MPI type to be used for collective access */ + mpi_collective_type = mpi_inter_type; + } /* end else */ + } /* end if */ + /* Chunked storage */ + else { + /*Contiguous access pattern */ + if (!parms->interleaved) { + /* Compute offset in file */ + mpi_offset = mpi_file_offset + nbytes_xfer; + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size * buf_size; + + /* Global offset advance after each I/O operation */ + mpi_offset_advance = 0; + + /* MPI type to be used for collective access */ + mpi_collective_type = mpi_full_buffer; + } /* end if */ + /*Interleaved access pattern */ + else { + /* Compute offset in file */ + /* Before simplification */ + /* mpi_offset=mpi_file_offset+(nbytes_xfer/(buf_size/blk_size) + *pio_mpi_nprocs_g)/(snbytes/blk_size*(blk_size*blk_size))* + (buf_size/blk_size*snbytes/blk_size*(blk_size*blk_size))+ + ((nbytes_xfer/(buf_size/blk_size))*pio_mpi_nprocs_g)%(snbytes + /blk_size*(blk_size*blk_size)); */ + mpi_offset = mpi_file_offset + + (MPI_Offset)((((size_t)nbytes_xfer / (buf_size / blk_size) * + (size_t)pio_mpi_nprocs_g) / + ((size_t)snbytes * blk_size)) * + (buf_size * (size_t)snbytes)) + + (MPI_Offset)((((size_t)nbytes_xfer / (buf_size / blk_size)) * + (size_t)pio_mpi_nprocs_g) % + ((size_t)snbytes * blk_size)); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size * blk_size; + + /* Global offset advance after each I/O operation */ + /* mpi_offset_advance = (MPI_Offset)(snbytes/blk_size*(blk_size*blk_size)); */ + mpi_offset_advance = (MPI_Offset)((size_t)snbytes * blk_size); + + /* MPI type to be used for collective access */ + mpi_collective_type = mpi_chunk_inter_type; + } /* end else */ + } /* end else */ + + /* Common code for independent file access */ + if (!parms->collective) { + /* Set the base of user's buffer */ + buf_p = (unsigned char *)buffer; + + /* Set the number of bytes to transfer this time */ + nbytes_toxfer = buf_size * blk_size; + + /* Loop over portions of the buffer to read */ + while (nbytes_toxfer > 0) { + /* Perform independent read */ + mrc = MPI_File_read_at(fd->mpifd, mpi_offset, buf_p, (int)nbytes_xfer_advance, + MPI_BYTE, &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); + + /* Advance location in buffer */ + buf_p += nbytes_xfer_advance; + + /* Advance global offset in dataset */ + nbytes_xfer += (off_t)nbytes_xfer_advance; + + /* Decrement number of bytes left this time */ + nbytes_toxfer -= nbytes_xfer_advance; + + /* Partially advance global offset in dataset */ + mpi_offset += mpi_offset_advance; + } /* end while */ + } /* end if */ + + /* Common code for collective file access */ + else { + /* Set the file view */ + mrc = MPI_File_set_view(fd->mpifd, mpi_offset, MPI_BYTE, mpi_collective_type, + (char *)"native", h5_io_info_g); + VRFY((mrc == MPI_SUCCESS), "MPIO_VIEW"); + + /* Perform read */ + MPI_File_read_at_all(fd->mpifd, 0, buffer, (int)(buf_size * blk_size), MPI_BYTE, + &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); + + /* Advance global offset in dataset */ + nbytes_xfer += (off_t)buf_size * (off_t)blk_size; + } /* end else */ + + } /* end else */ + break; + + case PHDF5: + /* 1D dataspace */ + if (!parms->dim2d) { + /* Set up the file dset space id to move the selection to process */ + if (!parms->interleaved) { + /* Contiguous pattern */ + h5offset[0] = nbytes_xfer; + } /* end if */ + else { + /* Interleaved access pattern */ + /* Skip offset over blocks of other processes */ + h5offset[0] = (nbytes_xfer * pio_mpi_nprocs_g); + } /* end else */ + hrc = H5Soffset_simple(h5dset_space_id, h5offset); + VRFY((hrc >= 0), "H5Soffset_simple"); + + /* Read the buffer in */ + hrc = H5Dread(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); + VRFY((hrc >= 0), "H5Dread"); + + /* Increment number of bytes transferred */ + nbytes_xfer += (off_t)buf_size; + } /* end if */ + /* 2D dataspace */ + else { + /* Set up the file dset space id to move the selection to process */ + if (!parms->interleaved) { + /* Contiguous pattern */ + h5offset[0] = + (hssize_t)(((size_t)nbytes_xfer / ((size_t)snbytes * blk_size)) * blk_size); + h5offset[1] = + (hssize_t)(((size_t)nbytes_xfer % ((size_t)snbytes * blk_size)) / blk_size); + } /* end if */ + else { + /* Interleaved access pattern */ + /* Skip offset over blocks of other processes */ + h5offset[0] = (hssize_t)((((size_t)nbytes_xfer * (size_t)pio_mpi_nprocs_g) / + ((size_t)snbytes * buf_size)) * + buf_size); + h5offset[1] = (hssize_t)((((size_t)nbytes_xfer * (size_t)pio_mpi_nprocs_g) % + ((size_t)snbytes * buf_size)) / + buf_size); + + } /* end else */ + hrc = H5Soffset_simple(h5dset_space_id, h5offset); + VRFY((hrc >= 0), "H5Soffset_simple"); + + /* Write the buffer out */ + hrc = H5Dread(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); + VRFY((hrc >= 0), "H5Dread"); + + /* Increment number of bytes transferred */ + nbytes_xfer += (off_t)buf_size * (off_t)blk_size; + + } /* end else */ + break; + + default: + break; + } /* switch (parms->io_type) */ + + /* Verify raw data, if asked */ + if (parms->verify) { + /* Verify data read */ + unsigned char *ucharptr = (unsigned char *)buffer; + size_t i; + int nerror = 0; + + for (i = 0; i < bsize; ++i) { + if (*ucharptr++ != pio_mpi_rank_g + 1) { + if (++nerror < 20) { + /* report at most 20 errors */ + HDprint_rank(output); + HDfprintf(output, + "read data error, expected (%d), " + "got (%d)\n", + pio_mpi_rank_g + 1, (int)*(ucharptr - 1)); + } /* end if */ + } /* end if */ + } /* end for */ + if (nerror >= 20) { + HDprint_rank(output); + HDfprintf(output, "..."); + HDfprintf(output, "total read data errors=%d\n", nerror); + } /* end if */ + } /* if (parms->verify) */ + + } /* end while */ + + /* Stop "raw data" read timer */ + io_time_set(res->timers, HDF5_RAW_READ_FIXED_DIMS, TSTOP); + + /* Calculate read time */ + + /* Close dataset. Only HDF5 needs to do an explicit close. */ + if (parms->io_type == PHDF5) { + hrc = H5Dclose(h5ds_id); + + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Close failed\n"); + GOTOERROR(FAIL); + } + + h5ds_id = H5I_INVALID_HID; + } /* end if */ + } /* end for */ + +done: + /* release MPI-I/O objects */ + if (parms->io_type == MPIO) { + /* 1D dataspace */ + if (!parms->dim2d) { + /* Free file type */ + mrc = MPI_Type_free(&mpi_file_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free buffer type */ + mrc = MPI_Type_free(&mpi_blk_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + } /* end if */ + /* 2D dataspace */ + else { + /* Free partial buffer type for contiguous access */ + mrc = MPI_Type_free(&mpi_partial_buffer_cont); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free contiguous file type */ + mrc = MPI_Type_free(&mpi_cont_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free partial buffer type for interleaved access */ + mrc = MPI_Type_free(&mpi_partial_buffer_inter); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free interleaved file type */ + mrc = MPI_Type_free(&mpi_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free full buffer type */ + mrc = MPI_Type_free(&mpi_full_buffer); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free full chunk type */ + mrc = MPI_Type_free(&mpi_full_chunk); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free chunk interleaved file type */ + mrc = MPI_Type_free(&mpi_chunk_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + } /* end else */ + } /* end if */ + + /* release HDF5 objects */ + if (h5dset_space_id != -1) { + hrc = H5Sclose(h5dset_space_id); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Space Close failed\n"); + ret_code = FAIL; + } + else { + h5dset_space_id = H5I_INVALID_HID; + } + } + + if (h5mem_space_id != -1) { + hrc = H5Sclose(h5mem_space_id); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Memory Space Close failed\n"); + ret_code = FAIL; + } + else { + h5mem_space_id = H5I_INVALID_HID; + } + } + + if (h5dxpl != -1) { + hrc = H5Pclose(h5dxpl); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Transfer Property List Close failed\n"); + ret_code = FAIL; + } + else { + h5dxpl = H5I_INVALID_HID; + } + } + + return ret_code; +} + +/* + * Function: do_fopen + * Purpose: Open the specified file. + * Return: SUCCESS or FAIL + * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 + * Modifications: + */ +static herr_t +do_fopen(parameters *param, char *fname, file_descr *fd /*out*/, int flags) +{ + int ret_code = SUCCESS, mrc; + hid_t acc_tpl = H5I_INVALID_HID; /* file access templates */ + + switch (param->io_type) { + case POSIXIO: + if (flags & (PIO_CREATE | PIO_WRITE)) + fd->posixfd = POSIXCREATE(fname); + else + fd->posixfd = POSIXOPEN(fname, O_RDONLY); + + if (fd->posixfd < 0) { + HDfprintf(stderr, "POSIX File Open failed(%s)\n", fname); + GOTOERROR(FAIL); + } + + /* The perils of POSIX I/O in a parallel environment. The problem is: + * + * - Process n opens a file with truncation and then starts + * writing to the file. + * - Process m also opens the file with truncation, but after + * process n has already started to write to the file. Thus, + * all of the stuff process n wrote is now lost. + */ + MPI_Barrier(pio_comm_g); + + break; + + case MPIO: + if (flags & (PIO_CREATE | PIO_WRITE)) { + MPI_File_delete(fname, h5_io_info_g); + mrc = MPI_File_open(pio_comm_g, fname, MPI_MODE_CREATE | MPI_MODE_RDWR, h5_io_info_g, + &fd->mpifd); + + if (mrc != MPI_SUCCESS) { + HDfprintf(stderr, "MPI File Open failed(%s)\n", fname); + GOTOERROR(FAIL); + } + + /*since MPI_File_open with MPI_MODE_CREATE does not truncate */ + /*filesize , set size to 0 explicitedly. */ + mrc = MPI_File_set_size(fd->mpifd, (MPI_Offset)0); + if (mrc != MPI_SUCCESS) { + HDfprintf(stderr, "MPI_File_set_size failed\n"); + GOTOERROR(FAIL); + } + } + else { + mrc = MPI_File_open(pio_comm_g, fname, MPI_MODE_RDONLY, h5_io_info_g, &fd->mpifd); + if (mrc != MPI_SUCCESS) { + HDfprintf(stderr, "MPI File Open failed(%s)\n", fname); + GOTOERROR(FAIL); + } + } + + break; + + case PHDF5: + if ((acc_tpl = H5Pcreate(H5P_FILE_ACCESS)) < 0) { + HDfprintf(stderr, "HDF5 Property List Create failed\n"); + GOTOERROR(FAIL); + } + + /* Set the file driver to the MPI-IO driver */ + if (H5Pset_fapl_mpio(acc_tpl, pio_comm_g, h5_io_info_g) < 0) { + HDfprintf(stderr, "HDF5 Property List Set failed\n"); + GOTOERROR(FAIL); + } + + /* Set the alignment of objects in HDF5 file */ + if (H5Pset_alignment(acc_tpl, param->h5_thresh, param->h5_align) < 0) { + HDfprintf(stderr, "HDF5 Property List Set failed\n"); + GOTOERROR(FAIL); + } + + /* create the parallel file */ + if (flags & (PIO_CREATE | PIO_WRITE)) + fd->h5fd = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl); + else + fd->h5fd = H5Fopen(fname, H5F_ACC_RDONLY, acc_tpl); + if (fd->h5fd < 0) { + HDfprintf(stderr, "HDF5 File Create failed(%s)\n", fname); + GOTOERROR(FAIL); + } + + /* verifying the close of the acc_tpl */ + if (H5Pclose(acc_tpl) < 0) { + HDfprintf(stderr, "HDF5 Property List Close failed\n"); + GOTOERROR(FAIL); + } + + break; + + default: + break; + } + +done: + return ret_code; +} + +/* + * Function: do_fclose + * Purpose: Close the specified file descriptor. + * Return: SUCCESS or FAIL + * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 + * Modifications: + */ +static herr_t +do_fclose(iotype iot, file_descr *fd /*out*/) +{ + herr_t ret_code = SUCCESS, hrc; + int mrc = 0, rc = 0; + + switch (iot) { + case POSIXIO: + rc = POSIXCLOSE(fd->posixfd); + + if (rc != 0) { + HDfprintf(stderr, "POSIX File Close failed\n"); + GOTOERROR(FAIL); + } + + fd->posixfd = -1; + break; + + case MPIO: + mrc = MPI_File_close(&fd->mpifd); + + if (mrc != MPI_SUCCESS) { + HDfprintf(stderr, "MPI File close failed\n"); + GOTOERROR(FAIL); + } + + fd->mpifd = MPI_FILE_NULL; + break; + + case PHDF5: + hrc = H5Fclose(fd->h5fd); + + if (hrc < 0) { + HDfprintf(stderr, "HDF5 File Close failed\n"); + GOTOERROR(FAIL); + } + + fd->h5fd = -1; + break; + + default: + break; + } + +done: + return ret_code; +} + +/* + * Function: do_fclose + * Purpose: Cleanup temporary file unless HDF5_NOCLEANUP is set. + * Only Proc 0 of the PIO communicator will do the cleanup. + * Other processes just return. + * Return: void + * Programmer: Albert Cheng 2001/12/12 + * Modifications: + */ +static void +do_cleanupfile(iotype iot, char *fname) +{ + if (pio_mpi_rank_g != 0) + return; + + if (clean_file_g == -1) + clean_file_g = (getenv("HDF5_NOCLEANUP") == NULL) ? 1 : 0; + + if (clean_file_g) { + switch (iot) { + case POSIXIO: + HDremove(fname); + break; + case MPIO: + case PHDF5: + MPI_File_delete(fname, h5_io_info_g); + break; + default: + break; + } + } +} + +#ifdef TIME_MPI +/* instrument the MPI_File_wrirte_xxx and read_xxx calls to measure + * pure time spent in MPI_File code. + */ +int +MPI_File_read_at(MPI_File fh, MPI_Offset offset, void *buf, int count, MPI_Datatype datatype, + MPI_Status *status) +{ + int err; + io_time_set(timer_g, HDF5_MPI_READ, TSTART); + err = PMPI_File_read_at(fh, offset, buf, count, datatype, status); + io_time_set(timer_g, HDF5_MPI_READ, TSTOP); + return err; +} + +int +MPI_File_read_at_all(MPI_File fh, MPI_Offset offset, void *buf, int count, MPI_Datatype datatype, + MPI_Status *status) +{ + int err; + io_time_set(timer_g, HDF5_MPI_READ, TSTART); + err = PMPI_File_read_at_all(fh, offset, buf, count, datatype, status); + io_time_set(timer_g, HDF5_MPI_READ, TSTOP); + return err; +} + +int +MPI_File_write_at(MPI_File fh, MPI_Offset offset, void *buf, int count, MPI_Datatype datatype, + MPI_Status *status) +{ + int err; + io_time_set(timer_g, HDF5_MPI_WRITE, TSTART); + err = PMPI_File_write_at(fh, offset, buf, count, datatype, status); + io_time_set(timer_g, HDF5_MPI_WRITE, TSTOP); + return err; +} + +int +MPI_File_write_at_all(MPI_File fh, MPI_Offset offset, void *buf, int count, MPI_Datatype datatype, + MPI_Status *status) +{ + int err; + io_time_set(timer_g, HDF5_MPI_WRITE, TSTART); + err = PMPI_File_write_at_all(fh, offset, buf, count, datatype, status); + io_time_set(timer_g, HDF5_MPI_WRITE, TSTOP); + return err; +} + +#endif /* TIME_MPI */ +#endif /* H5_HAVE_PARALLEL */ diff --git a/tools/src/h5perf/pio_perf.c b/tools/src/h5perf/pio_perf.c new file mode 100644 index 0000000..41245d9 --- /dev/null +++ b/tools/src/h5perf/pio_perf.c @@ -0,0 +1,1718 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Parallel HDF5 Performance Testing Code + * -------------------------------------- + * + * Portable code to test performance on the different platforms we support. + * This is what the report should look like: + * + * nprocs = Max#Procs + * IO API = POSIXIO + * # Files = 1, # of dsets = 1000, Elements per dset = 37000 + * Write Results = x MB/s + * Read Results = x MB/s + * # Files = 1, # of dsets = 3000, Elements per dset = 37000 + * Write Results = x MB/s + * Read Results = x MB/s + * + * . . . + * + * IO API = MPIO + * # Files = 1, # of dsets = 1000, Elements per dset = 37000 + * Write Results = x MB/s + * Read Results = x MB/s + * # Files = 1, # of dsets = 3000, Elements per dset = 37000 + * Write Results = x MB/s + * Read Results = x MB/s + * + * . . . + * + * IO API = PHDF5 + * # Files = 1, # of dsets = 1000, Elements per dset = 37000 + * Write Results = x MB/s + * Read Results = x MB/s + * # Files = 1, # of dsets = 3000, Elements per dset = 37000 + * Write Results = x MB/s + * Read Results = x MB/s + * + * . . . + * + * nprocs = Max#Procs / 2 + * + * . . . + * + */ + +/* system header files */ +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> + +#include "hdf5.h" + +#ifdef H5_HAVE_PARALLEL + +/* library header files */ +#include <mpi.h> + +/* our header files */ +#include "pio_perf.h" + +/* useful macros */ +#define TAB_SPACE 4 + +#define ONE_KB 1024 +#define ONE_MB (ONE_KB * ONE_KB) +#define ONE_GB (ONE_MB * ONE_KB) + +#define PIO_POSIX 0x1 +#define PIO_MPI 0x2 +#define PIO_HDF5 0x4 + +#ifdef STANDALONE +#define DBL_EPSILON 2.2204460492503131e-16 +#define H5_DBL_ABS_EQUAL(X, Y) (fabs((X) - (Y)) < DBL_EPSILON) +#endif + +/* report 0.0 in case t is zero too */ +#define MB_PER_SEC(bytes, t) (H5_DBL_ABS_EQUAL((t), 0.0) ? 0.0 : ((((double)bytes) / ONE_MB) / (t))) + +#ifndef TRUE +#define TRUE 1 +#endif /* TRUE */ +#ifndef FALSE +#define FALSE (!TRUE) +#endif /* FALSE */ + +/* global variables */ +FILE * output; /* output file */ +int comm_world_rank_g; /* my rank in MPI_COMM_RANK */ +int comm_world_nprocs_g; /* num. of processes of MPI_COMM_WORLD */ +MPI_Comm pio_comm_g; /* Communicator to run the PIO */ +int pio_mpi_rank_g; /* MPI rank of pio_comm_g */ +int pio_mpi_nprocs_g; /* Number of processes of pio_comm_g */ +int pio_debug_level = 0; /* The debug level: + * 0 - Off + * 1 - Minimal + * 2 - Some more + * 3 - Maximal + * 4 - Maximal & then some + */ + +/* local variables */ +static const char *progname = "h5perf"; + +#ifndef HDF5_PARAPREFIX +#define HDF5_PARAPREFIX "" +#endif +char * paraprefix = NULL; /* for command line option para-prefix */ +MPI_Info h5_io_info_g = MPI_INFO_NULL; /* MPI INFO object for IO */ + +/* + * Command-line options: The user can specify short or long-named + * parameters. The long-named ones can be partially spelled. When + * adding more, make sure that they don't clash with each other. + */ +#if 1 +static const char *s_opts = "a:A:B:cCd:D:e:F:ghi:Imno:p:P:stT:wx:X:"; +#else +static const char *s_opts = "a:A:bB:cCd:D:e:F:ghi:Imno:p:P:stT:wx:X:"; +#endif /* 1 */ +static struct h5_long_options l_opts[] = {{"align", require_arg, 'a'}, + {"api", require_arg, 'A'}, +#if 0 + /* a sighting of the elusive binary option */ + { "binary", no_arg, 'b' }, +#endif /* 0 */ + {"block-size", require_arg, 'B'}, + {"chunk", no_arg, 'c'}, + {"collective", no_arg, 'C'}, + {"debug", require_arg, 'D'}, + {"geometry", no_arg, 'g'}, + {"help", no_arg, 'h'}, + {"interleaved", require_arg, 'I'}, + {"max-num-processes", require_arg, 'P'}, + {"min-num-processes", require_arg, 'p'}, + {"max-xfer-size", require_arg, 'X'}, + {"min-xfer-size", require_arg, 'x'}, + {"num-bytes", require_arg, 'e'}, + {"num-dsets", require_arg, 'd'}, + {"num-files", require_arg, 'F'}, + {"num-iterations", require_arg, 'i'}, + {"output", require_arg, 'o'}, + {"threshold", require_arg, 'T'}, + {"write-only", require_arg, 'w'}, + {NULL, 0, '\0'}}; + +struct options { + long io_types; /* bitmask of which I/O types to test */ + const char *output_file; /* file to print report to */ + long num_dsets; /* number of datasets */ + long num_files; /* number of files */ + off_t num_bpp; /* number of bytes per proc per dset */ + int num_iters; /* number of iterations */ + int max_num_procs; /* maximum number of processes to use */ + int min_num_procs; /* minimum number of processes to use */ + size_t max_xfer_size; /* maximum transfer buffer size */ + size_t min_xfer_size; /* minimum transfer buffer size */ + size_t blk_size; /* Block size */ + unsigned interleaved; /* Interleaved vs. contiguous blocks */ + unsigned collective; /* Collective vs. independent I/O */ + unsigned dim2d; /* 1D vs. 2D geometry */ + int print_times; /* print times as well as throughputs */ + int print_raw; /* print raw data throughput info */ + off_t h5_alignment; /* alignment in HDF5 file */ + off_t h5_threshold; /* threshold for alignment in HDF5 file */ + int h5_use_chunks; /* Make HDF5 dataset chunked */ + int h5_write_only; /* Perform the write tests only */ + int verify; /* Verify data correctness */ +}; + +typedef struct _minmax { + double min; + double max; + double sum; + int num; +} minmax; + +/* local functions */ +static off_t parse_size_directive(const char *size); +static struct options *parse_command_line(int argc, char *argv[]); +static void run_test_loop(struct options *options); +static int run_test(iotype iot, parameters parms, struct options *opts); +static void output_all_info(minmax *mm, int count, int indent_level); +static void get_minmax(minmax *mm, double val); +static minmax accumulate_minmax_stuff(minmax *mm, int count); +static int create_comm_world(int num_procs, int *doing_pio); +static int destroy_comm_world(void); +static void output_results(const struct options *options, const char *name, minmax *table, int table_size, + off_t data_size); +static void output_times(const struct options *options, const char *name, minmax *table, int table_size); +static void output_report(const char *fmt, ...); +static void print_indent(register int indent); +static void usage(const char *prog); +static void report_parameters(struct options *opts); +static off_t squareo(off_t); + +/* + * Function: main + * Purpose: Start things up. Initialize MPI and then call the test looping + * function. + * Return: EXIT_SUCCESS or EXIT_FAILURE + * Programmer: Bill Wendling, 30. October 2001 + * Modifications: + */ +int +main(int argc, char *argv[]) +{ + int ret; + int exit_value = EXIT_SUCCESS; + struct options *opts = NULL; + +#ifndef STANDALONE + /* Initialize h5tools lib */ + h5tools_init(); +#endif + + output = stdout; + + /* initialize MPI and get the maximum num of processors we started with */ + MPI_Init(&argc, &argv); + ret = MPI_Comm_size(MPI_COMM_WORLD, &comm_world_nprocs_g); + + if (ret != MPI_SUCCESS) { + HDfprintf(stderr, "%s: MPI_Comm_size call failed\n", progname); + + if (ret == MPI_ERR_COMM) + HDfprintf(stderr, "invalid MPI communicator\n"); + else + HDfprintf(stderr, "invalid argument\n"); + + exit_value = EXIT_FAILURE; + goto finish; + } + + ret = MPI_Comm_rank(MPI_COMM_WORLD, &comm_world_rank_g); + + if (ret != MPI_SUCCESS) { + HDfprintf(stderr, "%s: MPI_Comm_rank call failed\n", progname); + + if (ret == MPI_ERR_COMM) + HDfprintf(stderr, "invalid MPI communicator\n"); + else + HDfprintf(stderr, "invalid argument\n"); + + exit_value = EXIT_FAILURE; + goto finish; + } + + pio_comm_g = MPI_COMM_WORLD; + + h5_set_info_object(); + opts = parse_command_line(argc, argv); + + if (!opts) { + exit_value = EXIT_FAILURE; + goto finish; + } + + if (opts->output_file) { + if ((output = HDfopen(opts->output_file, "w")) == NULL) { + HDfprintf(stderr, "%s: cannot open output file\n", progname); + perror(opts->output_file); + goto finish; + } + } + + if ((pio_debug_level == 0 && comm_world_rank_g == 0) || pio_debug_level > 0) + report_parameters(opts); + + run_test_loop(opts); + +finish: + MPI_Finalize(); + free(opts); + return exit_value; +} + +off_t +squareo(off_t x) +{ + return x * x; +} + +/* + * Function: run_test_loop + * Purpose: Run the I/O tests. Write the results to OUTPUT. + * + * - The slowest changing part of the test is the number of + * processors to use. For each loop iteration, we divide that + * number by 2 and rerun the test. + * + * - The second slowest is what type of IO API to perform. We have + * three choices: POSIXIO, MPI-IO, and PHDF5. + * + * - Then we change the size of the buffer. This information is + * inferred from the number of datasets to create and the number + * of integers to put into each dataset. The backend code figures + * this out. + * + * Return: Nothing + * Programmer: Bill Wendling, 30. October 2001 + * Modifications: + * Added 2D testing (Christian Chilan, 10. August 2005) + */ +static void +run_test_loop(struct options *opts) +{ + parameters parms; + int num_procs; + int doing_pio; /* if this process is doing PIO */ + + parms.num_files = opts->num_files; + parms.num_dsets = opts->num_dsets; + parms.num_iters = opts->num_iters; + parms.blk_size = opts->blk_size; + parms.interleaved = opts->interleaved; + parms.collective = opts->collective; + parms.dim2d = opts->dim2d; + parms.h5_align = (hsize_t)opts->h5_alignment; + parms.h5_thresh = (hsize_t)opts->h5_threshold; + parms.h5_use_chunks = opts->h5_use_chunks; + parms.h5_write_only = opts->h5_write_only; + parms.verify = opts->verify; + + /* start with max_num_procs and decrement it by half for each loop. */ + /* if performance needs restart, fewer processes may be needed. */ + for (num_procs = opts->max_num_procs; num_procs >= opts->min_num_procs; num_procs >>= 1) { + register size_t buf_size; + + parms.num_procs = num_procs; + + if (create_comm_world(parms.num_procs, &doing_pio) != SUCCESS) { + /* do something harsh */ + } + + /* only processes doing PIO will run the tests */ + if (doing_pio) { + output_report("Number of processors = %ld\n", parms.num_procs); + + /* multiply the xfer buffer size by 2 for each loop iteration */ + for (buf_size = opts->min_xfer_size; buf_size <= opts->max_xfer_size; buf_size <<= 1) { + parms.buf_size = buf_size; + + if (parms.dim2d) { + parms.num_bytes = squareo(opts->num_bpp * parms.num_procs); + if (parms.interleaved) + output_report("Transfer Buffer Size: %ldx%ld bytes, File size: %.2f MB\n", buf_size, + opts->blk_size, + ((double)parms.num_dsets * (double)parms.num_bytes) / ONE_MB); + else + output_report("Transfer Buffer Size: %ldx%ld bytes, File size: %.2f MB\n", + opts->blk_size, buf_size, + ((double)parms.num_dsets * (double)parms.num_bytes) / ONE_MB); + + print_indent(1); + output_report(" # of files: %ld, # of datasets: %ld, dataset size: %.2fx%.2f KB\n", + parms.num_files, parms.num_dsets, + (double)(opts->num_bpp * parms.num_procs) / ONE_KB, + (double)(opts->num_bpp * parms.num_procs) / ONE_KB); + } + else { + parms.num_bytes = (off_t)opts->num_bpp * parms.num_procs; + output_report("Transfer Buffer Size: %ld bytes, File size: %.2f MB\n", buf_size, + ((double)parms.num_dsets * (double)parms.num_bytes) / ONE_MB); + + print_indent(1); + output_report(" # of files: %ld, # of datasets: %ld, dataset size: %.2f MB\n", + parms.num_files, parms.num_dsets, + (double)(opts->num_bpp * parms.num_procs) / ONE_MB); + } + + if (opts->io_types & PIO_POSIX) + run_test(POSIXIO, parms, opts); + + if (opts->io_types & PIO_MPI) + run_test(MPIO, parms, opts); + + if (opts->io_types & PIO_HDF5) + run_test(PHDF5, parms, opts); + + /* Run the tests once if buf_size==0, but then break out */ + if (buf_size == 0) + break; + } + + if (destroy_comm_world() != SUCCESS) { + /* do something harsh */ + } + } + } +} + +/* + * Function: run_test + * Purpose: Inner loop call to actually run the I/O test. + * Return: Nothing + * Programmer: Bill Wendling, 18. December 2001 + * Modifications: + */ +static int +run_test(iotype iot, parameters parms, struct options *opts) +{ + results res; + register int i, ret_value = SUCCESS; + int comm_size; + off_t raw_size; + minmax * write_mpi_mm_table = NULL; + minmax * write_mm_table = NULL; + minmax * write_gross_mm_table = NULL; + minmax * write_raw_mm_table = NULL; + minmax * read_mpi_mm_table = NULL; + minmax * read_mm_table = NULL; + minmax * read_gross_mm_table = NULL; + minmax * read_raw_mm_table = NULL; + minmax * read_open_mm_table = NULL; + minmax * read_close_mm_table = NULL; + minmax * write_open_mm_table = NULL; + minmax * write_close_mm_table = NULL; + minmax write_mpi_mm = {0.0, 0.0, 0.0, 0}; + minmax write_mm = {0.0, 0.0, 0.0, 0}; + minmax write_gross_mm = {0.0, 0.0, 0.0, 0}; + minmax write_raw_mm = {0.0, 0.0, 0.0, 0}; + minmax read_mpi_mm = {0.0, 0.0, 0.0, 0}; + minmax read_mm = {0.0, 0.0, 0.0, 0}; + minmax read_gross_mm = {0.0, 0.0, 0.0, 0}; + minmax read_raw_mm = {0.0, 0.0, 0.0, 0}; + minmax read_open_mm = {0.0, 0.0, 0.0, 0}; + minmax read_close_mm = {0.0, 0.0, 0.0, 0}; + minmax write_open_mm = {0.0, 0.0, 0.0, 0}; + minmax write_close_mm = {0.0, 0.0, 0.0, 0}; + + raw_size = parms.num_files * (off_t)parms.num_dsets * (off_t)parms.num_bytes; + parms.io_type = iot; + print_indent(2); + output_report("IO API = "); + + switch (iot) { + case POSIXIO: + output_report("POSIX\n"); + break; + case MPIO: + output_report("MPIO\n"); + break; + case PHDF5: + output_report("PHDF5 (w/MPI-IO driver)\n"); + break; + default: + break; + } + + MPI_Comm_size(pio_comm_g, &comm_size); + + /* allocate space for tables minmax and that it is sufficient */ + /* to initialize all elements to zeros by calloc. */ + write_mpi_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + write_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + write_gross_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + write_raw_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + write_open_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + write_close_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + if (!parms.h5_write_only) { + read_mpi_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + read_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + read_gross_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + read_raw_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + read_open_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + read_close_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + } + + /* Do IO iteration times, collecting statistics each time */ + for (i = 0; i < parms.num_iters; ++i) { + double t; + + MPI_Barrier(pio_comm_g); + res = do_pio(parms); + + /* gather all of the "mpi write" times */ + t = io_time_get(res.timers, HDF5_MPI_WRITE); + get_minmax(&write_mpi_mm, t); + + write_mpi_mm_table[i] = write_mpi_mm; + + /* gather all of the "write" times */ + t = io_time_get(res.timers, HDF5_FINE_WRITE_FIXED_DIMS); + get_minmax(&write_mm, t); + + write_mm_table[i] = write_mm; + + /* gather all of the "write" times from open to close */ + t = io_time_get(res.timers, HDF5_GROSS_WRITE_FIXED_DIMS); + get_minmax(&write_gross_mm, t); + + write_gross_mm_table[i] = write_gross_mm; + + /* gather all of the raw "write" times */ + t = io_time_get(res.timers, HDF5_RAW_WRITE_FIXED_DIMS); + get_minmax(&write_raw_mm, t); + + write_raw_mm_table[i] = write_raw_mm; + + /* gather all of the file open times (time from open to first write) */ + t = io_time_get(res.timers, HDF5_FILE_WRITE_OPEN); + get_minmax(&write_open_mm, t); + + write_open_mm_table[i] = write_open_mm; + + /* gather all of the file close times (time from last write to close) */ + t = io_time_get(res.timers, HDF5_FILE_WRITE_CLOSE); + get_minmax(&write_close_mm, t); + + write_close_mm_table[i] = write_close_mm; + + if (!parms.h5_write_only) { + /* gather all of the "mpi read" times */ + t = io_time_get(res.timers, HDF5_MPI_READ); + get_minmax(&read_mpi_mm, t); + + read_mpi_mm_table[i] = read_mpi_mm; + + /* gather all of the "read" times */ + t = io_time_get(res.timers, HDF5_FINE_READ_FIXED_DIMS); + get_minmax(&read_mm, t); + + read_mm_table[i] = read_mm; + + /* gather all of the "read" times from open to close */ + t = io_time_get(res.timers, HDF5_GROSS_READ_FIXED_DIMS); + get_minmax(&read_gross_mm, t); + + read_gross_mm_table[i] = read_gross_mm; + + /* gather all of the raw "read" times */ + t = io_time_get(res.timers, HDF5_RAW_READ_FIXED_DIMS); + get_minmax(&read_raw_mm, t); + + read_raw_mm_table[i] = read_raw_mm; + + /* gather all of the file open times (time from open to first read) */ + t = io_time_get(res.timers, HDF5_FILE_READ_OPEN); + get_minmax(&read_open_mm, t); + + read_open_mm_table[i] = read_open_mm; + + /* gather all of the file close times (time from last read to close) */ + t = io_time_get(res.timers, HDF5_FILE_READ_CLOSE); + get_minmax(&read_close_mm, t); + + read_close_mm_table[i] = read_close_mm; + } + + io_time_destroy(res.timers); + } + + /* + * Show various statistics + */ + /* Write statistics */ + /* Print the raw data throughput if desired */ + if (opts->print_raw) { + /* accumulate and output the max, min, and average "raw write" times */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Raw Data Write details:\n"); + output_all_info(write_raw_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Raw Data Write", write_raw_mm_table, parms.num_iters, raw_size); + } /* end if */ + + /* show mpi write statics */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("MPI Write details:\n"); + output_all_info(write_mpi_mm_table, parms.num_iters, 4); + } + + /* We don't currently output the MPI write results */ + + /* accumulate and output the max, min, and average "write" times */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Write details:\n"); + output_all_info(write_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Write", write_mm_table, parms.num_iters, raw_size); + + /* accumulate and output the max, min, and average "gross write" times */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Write Open-Close details:\n"); + output_all_info(write_gross_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Write Open-Close", write_gross_mm_table, parms.num_iters, raw_size); + + if (opts->print_times) { + output_times(opts, "Write File Open", write_open_mm_table, parms.num_iters); + output_times(opts, "Write File Close", write_close_mm_table, parms.num_iters); + } + + /* Print out time from open to first write */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Write file open details:\n"); + output_all_info(write_open_mm_table, parms.num_iters, 4); + } + + /* Print out time from last write to close */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Write file close details:\n"); + output_all_info(write_close_mm_table, parms.num_iters, 4); + } + + if (!parms.h5_write_only) { + /* Read statistics */ + /* Print the raw data throughput if desired */ + if (opts->print_raw) { + /* accumulate and output the max, min, and average "raw read" times */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Raw Data Read details:\n"); + output_all_info(read_raw_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Raw Data Read", read_raw_mm_table, parms.num_iters, raw_size); + } /* end if */ + + /* show mpi read statics */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("MPI Read details:\n"); + output_all_info(read_mpi_mm_table, parms.num_iters, 4); + } + + /* We don't currently output the MPI read results */ + + /* accumulate and output the max, min, and average "read" times */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Read details:\n"); + output_all_info(read_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Read", read_mm_table, parms.num_iters, raw_size); + + /* accumulate and output the max, min, and average "gross read" times */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Read Open-Close details:\n"); + output_all_info(read_gross_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Read Open-Close", read_gross_mm_table, parms.num_iters, raw_size); + + if (opts->print_times) { + output_times(opts, "Read File Open", read_open_mm_table, parms.num_iters); + output_times(opts, "Read File Close", read_close_mm_table, parms.num_iters); + } + + /* Print out time from open to first read */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Read file open details:\n"); + output_all_info(read_open_mm_table, parms.num_iters, 4); + } + + /* Print out time from last read to close */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Read file close details:\n"); + output_all_info(read_close_mm_table, parms.num_iters, 4); + } + } + + /* clean up our mess */ + free(write_mpi_mm_table); + free(write_mm_table); + free(write_gross_mm_table); + free(write_raw_mm_table); + free(write_open_mm_table); + free(write_close_mm_table); + + if (!parms.h5_write_only) { + free(read_mpi_mm_table); + free(read_mm_table); + free(read_gross_mm_table); + free(read_raw_mm_table); + free(read_open_mm_table); + free(read_close_mm_table); + } + + return ret_value; +} + +/* + * Function: output_all_info + * Purpose: + * Return: Nothing + * Programmer: Bill Wendling, 29. January 2002 + * Modifications: + */ +static void +output_all_info(minmax *mm, int count, int indent_level) +{ + int i; + + for (i = 0; i < count; ++i) { + print_indent(indent_level); + output_report("Iteration %d:\n", i + 1); + print_indent(indent_level + 1); + output_report("Minimum Time: %.2fs\n", mm[i].min); + print_indent(indent_level + 1); + output_report("Maximum Time: %.2fs\n", mm[i].max); + } +} + +/* + * Function: h5_set_info_object + * Purpose: Process environment variables setting to set up MPI Info + * object. + * Return: 0 if all is fine; otherwise non-zero. + * Programmer: Albert Cheng, 2002/05/21. + * Modifications: + * Bill Wendling, 2002/05/31 + * Modified so that the HDF5_MPI_INFO environment variable can + * be a semicolon separated list of "key=value" pairings. Most + * of the code is to remove any whitespaces which might be + * surrounding the "key=value" pairs. + */ +int +h5_set_info_object(void) +{ + char *envp; /* environment pointer */ + int ret_value = 0; + + /* handle any MPI INFO hints via $HDF5_MPI_INFO */ + if ((envp = HDgetenv("HDF5_MPI_INFO")) != NULL) { + char *next, *valp; + + valp = envp = next = HDstrdup(envp); + + if (!valp) + return 0; + + /* create an INFO object if not created yet */ + if (h5_io_info_g == MPI_INFO_NULL) + MPI_Info_create(&h5_io_info_g); + + do { + size_t len; + char * key_val, *endp, *namep; + + if (*valp == ';') + valp++; + + /* copy key/value pair into temporary buffer */ + len = strcspn(valp, ";"); + next = &valp[len]; + key_val = (char *)HDcalloc(1, len + 1); + + /* increment the next pointer past the terminating semicolon */ + if (*next == ';') + ++next; + + namep = HDstrncpy(key_val, valp, len); + + /* pass up any beginning whitespaces */ + while (*namep && (*namep == ' ' || *namep == '\t')) + namep++; + + if (!*namep) + continue; /* was all white space, so move to next k/v pair */ + + /* eat up any ending white spaces */ + endp = &namep[HDstrlen(namep) - 1]; + + while (endp && (*endp == ' ' || *endp == '\t')) + *endp-- = '\0'; + + /* find the '=' */ + valp = HDstrchr(namep, '='); + + if (valp != NULL) { /* it's a valid key/value pairing */ + char *tmp_val = valp + 1; + + /* change '=' to \0, move valp down one */ + *valp-- = '\0'; + + /* eat up ending whitespace on the "key" part */ + while (*valp == ' ' || *valp == '\t') + *valp-- = '\0'; + + valp = tmp_val; + + /* eat up beginning whitespace on the "value" part */ + while (*valp == ' ' || *valp == '\t') + *valp++ = '\0'; + + /* actually set the darned thing */ + if (MPI_SUCCESS != MPI_Info_set(h5_io_info_g, namep, valp)) { + HDprintf("MPI_Info_set failed\n"); + ret_value = -1; + } + } + + valp = next; + HDfree(key_val); + } while (next && *next); + + HDfree(envp); + } + + return ret_value; +} + +/* + * Function: h5_dump_info_object + * Purpose: Display content of an MPI Info object + * Return: void + * Programmer: Albert Cheng 2002/05/21 + * Modifications: + */ +void +h5_dump_info_object(MPI_Info info) +{ + char key[MPI_MAX_INFO_KEY + 1]; + char value[MPI_MAX_INFO_VAL + 1]; + int flag; + int i, nkeys; + + HDprintf("Dumping MPI Info Object (up to %d bytes per item):\n", MPI_MAX_INFO_VAL); + if (info == MPI_INFO_NULL) { + HDprintf("object is MPI_INFO_NULL\n"); + } + else { + MPI_Info_get_nkeys(info, &nkeys); + HDprintf("object has %d items\n", nkeys); + for (i = 0; i < nkeys; i++) { + MPI_Info_get_nthkey(info, i, key); + MPI_Info_get(info, key, MPI_MAX_INFO_VAL, value, &flag); + HDprintf("%s=%s\n", key, value); + } + } +} + +/* + * Function: get_minmax + * Purpose: Gather all the min, max and total of val. + * Return: Nothing + * Programmer: Bill Wendling, 21. December 2001 + * Modifications: + * Use MPI_Allreduce to do it. -akc, 2002/01/11 + */ +static void +get_minmax(minmax *mm, double val) +{ + int myrank; + + MPI_Comm_rank(pio_comm_g, &myrank); + MPI_Comm_size(pio_comm_g, &mm->num); + + MPI_Allreduce(&val, &mm->max, 1, MPI_DOUBLE, MPI_MAX, pio_comm_g); + MPI_Allreduce(&val, &mm->min, 1, MPI_DOUBLE, MPI_MIN, pio_comm_g); + MPI_Allreduce(&val, &mm->sum, 1, MPI_DOUBLE, MPI_SUM, pio_comm_g); +} + +/* + * Function: accumulate_minmax_stuff + * Purpose: Accumulate the minimum, maximum, and average of the times + * across all processes. + * Return: TOTAL_MM - the total of all of these. + * Programmer: Bill Wendling, 21. December 2001 + * Modifications: + * Changed to use seconds instead of MB/s - QAK, 5/9/02 + */ +static minmax +accumulate_minmax_stuff(minmax *mm, int count) +{ + int i; + minmax total_mm; + + total_mm.sum = 0.0f; + total_mm.max = -DBL_MAX; + total_mm.min = DBL_MAX; + total_mm.num = count; + + for (i = 0; i < count; ++i) { + double m = mm[i].max; + + total_mm.sum += m; + + if (m < total_mm.min) + total_mm.min = m; + + if (m > total_mm.max) + total_mm.max = m; + } + + return total_mm; +} + +/* + * Function: create_comm_world + * Purpose: Create an MPI Comm world and store it in pio_comm_g, which + * is a global variable. + * Return: SUCCESS on success. + * FAIL otherwise. + * Programmer: Bill Wendling, 19. December 2001 + * Modifications: + */ +static int +create_comm_world(int num_procs, int *doing_pio) +{ + /* MPI variables */ + int mrc; /* return values */ + int color; /* for communicator creation */ + int myrank, nprocs; + + pio_comm_g = MPI_COMM_NULL; + + /* + * Create a sub communicator for this PIO run. Easier to use the first N + * processes. + */ + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + + if (num_procs > nprocs) { + HDfprintf(stderr, "number of process(%d) must be <= number of processes in MPI_COMM_WORLD(%d)\n", + num_procs, nprocs); + goto error_done; + } + + MPI_Comm_rank(MPI_COMM_WORLD, &myrank); + color = (myrank < num_procs); + mrc = MPI_Comm_split(MPI_COMM_WORLD, color, myrank, &pio_comm_g); + + if (mrc != MPI_SUCCESS) { + HDfprintf(stderr, "MPI_Comm_split failed\n"); + goto error_done; + } + + if (!color) { + /* not involved in this run */ + mrc = destroy_comm_world(); + goto done; + } + + /* determine the MPI rank in the PIO communicator */ + MPI_Comm_size(pio_comm_g, &pio_mpi_nprocs_g); + MPI_Comm_rank(pio_comm_g, &pio_mpi_rank_g); + +done: + *doing_pio = color; + return SUCCESS; + +error_done: + destroy_comm_world(); + return FAIL; +} + +/* + * Function: destroy_comm_world + * Purpose: Destroy the created MPI Comm world which is stored in the + * pio_comm_g global variable. + * Return: SUCCESS on success. + * FAIL otherwise. + * Programmer: Bill Wendling, 19. December 2001 + * Modifications: + */ +static int +destroy_comm_world(void) +{ + int mrc = SUCCESS; /* return code */ + + /* release MPI resources */ + if (pio_comm_g != MPI_COMM_NULL) + mrc = (MPI_Comm_free(&pio_comm_g) == MPI_SUCCESS ? SUCCESS : FAIL); + + return mrc; +} + +/* + * Function: output_results + * Purpose: Print information about the time & bandwidth for a given + * minmax & # of iterations. + * Return: Nothing + * Programmer: Quincey Koziol, 9. May 2002 + * Modifications: + */ +static void +output_results(const struct options *opts, const char *name, minmax *table, int table_size, off_t data_size) +{ + minmax total_mm; + + total_mm = accumulate_minmax_stuff(table, table_size); + + print_indent(3); + output_report("%s (%d iteration(s)):\n", name, table_size); + + /* Note: The maximum throughput uses the minimum amount of time & vice versa */ + + print_indent(4); + output_report("Maximum Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.min)); + if (opts->print_times) + output_report(" (%7.3f s)\n", total_mm.min); + else + output_report("\n"); + + print_indent(4); + output_report("Average Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.sum / total_mm.num)); + if (opts->print_times) + output_report(" (%7.3f s)\n", (total_mm.sum / total_mm.num)); + else + output_report("\n"); + + print_indent(4); + output_report("Minimum Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.max)); + if (opts->print_times) + output_report(" (%7.3f s)\n", total_mm.max); + else + output_report("\n"); +} + +static void +output_times(const struct options *opts, const char *name, minmax *table, int table_size) +{ + minmax total_mm; + + total_mm = accumulate_minmax_stuff(table, table_size); + + print_indent(3); + output_report("%s (%d iteration(s)):\n", name, table_size); + + /* Note: The maximum throughput uses the minimum amount of time & vice versa */ + + print_indent(4); + output_report("Minimum Accumulated Time using %d file(s): %7.5f s\n", opts->num_files, (total_mm.min)); + + print_indent(4); + output_report("Average Accumulated Time using %d file(s): %7.5f s\n", opts->num_files, + (total_mm.sum / total_mm.num)); + + print_indent(4); + output_report("Maximum Accumulated Time using %d file(s): %7.5f s\n", opts->num_files, (total_mm.max)); +} + +/* + * Function: output_report + * Purpose: Print a line of the report. Only do so if I'm the 0 process. + * Return: Nothing + * Programmer: Bill Wendling, 19. December 2001 + * Modifications: + */ +static void +output_report(const char *fmt, ...) +{ + int myrank; + + MPI_Comm_rank(pio_comm_g, &myrank); + + if (myrank == 0) { + va_list ap; + + HDva_start(ap, fmt); + HDvfprintf(output, fmt, ap); + HDva_end(ap); + } +} + +/* + * Function: print_indent + * Purpose: Print spaces to indent a new line of text for pretty printing + * things. + * Return: Nothing + * Programmer: Bill Wendling, 29. October 2001 + * Modifications: + */ +static void +print_indent(register int indent) +{ + int myrank; + + MPI_Comm_rank(pio_comm_g, &myrank); + + if (myrank == 0) { + indent *= TAB_SPACE; + + for (; indent > 0; --indent) + HDfputc(' ', output); + } +} + +static void +recover_size_and_print(long long val, const char *end) +{ + if (val >= ONE_KB && (val % ONE_KB) == 0) { + if (val >= ONE_MB && (val % ONE_MB) == 0) { + if (val >= ONE_GB && (val % ONE_GB) == 0) + HDfprintf(output, + "%" H5_PRINTF_LL_WIDTH "d" + "GB%s", + val / ONE_GB, end); + else + HDfprintf(output, + "%" H5_PRINTF_LL_WIDTH "d" + "MB%s", + val / ONE_MB, end); + } + else { + HDfprintf(output, + "%" H5_PRINTF_LL_WIDTH "d" + "KB%s", + val / ONE_KB, end); + } + } + else { + HDfprintf(output, + "%" H5_PRINTF_LL_WIDTH "d" + "%s", + val, end); + } +} + +static void +print_io_api(long io_types) +{ + if (io_types & PIO_POSIX) + HDfprintf(output, "posix "); + if (io_types & PIO_MPI) + HDfprintf(output, "mpiio "); + if (io_types & PIO_HDF5) + HDfprintf(output, "phdf5 "); + HDfprintf(output, "\n"); +} + +static void +report_parameters(struct options *opts) +{ + int rank = comm_world_rank_g; + + print_version("HDF5 Library"); /* print library version */ + HDfprintf(output, "rank %d: ==== Parameters ====\n", rank); + + HDfprintf(output, "rank %d: IO API=", rank); + print_io_api(opts->io_types); + + HDfprintf(output, "rank %d: Number of files=%ld\n", rank, opts->num_files); + HDfprintf(output, "rank %d: Number of datasets=%ld\n", rank, opts->num_dsets); + HDfprintf(output, "rank %d: Number of iterations=%d\n", rank, opts->num_iters); + HDfprintf(output, "rank %d: Number of processes=%d:%d\n", rank, opts->min_num_procs, opts->max_num_procs); + + if (opts->dim2d) { + HDfprintf(output, "rank %d: Number of bytes per process per dataset=", rank); + recover_size_and_print((long long)(opts->num_bpp * opts->num_bpp * opts->min_num_procs), ":"); + recover_size_and_print((long long)(opts->num_bpp * opts->num_bpp * opts->max_num_procs), "\n"); + + HDfprintf(output, "rank %d: Size of dataset(s)=", rank); + recover_size_and_print((long long)(opts->num_bpp * opts->min_num_procs), "x"); + recover_size_and_print((long long)(opts->num_bpp * opts->min_num_procs), ":"); + recover_size_and_print((long long)(opts->num_bpp * opts->max_num_procs), "x"); + recover_size_and_print((long long)(opts->num_bpp * opts->max_num_procs), "\n"); + + HDfprintf(output, "rank %d: File size=", rank); + recover_size_and_print((long long)(squareo(opts->num_bpp * opts->min_num_procs) * opts->num_dsets), + ":"); + recover_size_and_print((long long)(squareo(opts->num_bpp * opts->max_num_procs) * opts->num_dsets), + "\n"); + + HDfprintf(output, "rank %d: Transfer buffer size=", rank); + if (opts->interleaved) { + recover_size_and_print((long long)opts->min_xfer_size, "x"); + recover_size_and_print((long long)opts->blk_size, ":"); + recover_size_and_print((long long)opts->max_xfer_size, "x"); + recover_size_and_print((long long)opts->blk_size, "\n"); + } + else { + recover_size_and_print((long long)opts->blk_size, "x"); + recover_size_and_print((long long)opts->min_xfer_size, ":"); + recover_size_and_print((long long)opts->blk_size, "x"); + recover_size_and_print((long long)opts->max_xfer_size, "\n"); + } + HDfprintf(output, "rank %d: Block size=", rank); + recover_size_and_print((long long)opts->blk_size, "x"); + recover_size_and_print((long long)opts->blk_size, "\n"); + } + else { + HDfprintf(output, "rank %d: Number of bytes per process per dataset=", rank); + recover_size_and_print((long long)opts->num_bpp, "\n"); + + HDfprintf(output, "rank %d: Size of dataset(s)=", rank); + recover_size_and_print((long long)(opts->num_bpp * opts->min_num_procs), ":"); + recover_size_and_print((long long)(opts->num_bpp * opts->max_num_procs), "\n"); + + HDfprintf(output, "rank %d: File size=", rank); + recover_size_and_print((long long)(opts->num_bpp * opts->min_num_procs * opts->num_dsets), ":"); + recover_size_and_print((long long)(opts->num_bpp * opts->max_num_procs * opts->num_dsets), "\n"); + + HDfprintf(output, "rank %d: Transfer buffer size=", rank); + recover_size_and_print((long long)opts->min_xfer_size, ":"); + recover_size_and_print((long long)opts->max_xfer_size, "\n"); + HDfprintf(output, "rank %d: Block size=", rank); + recover_size_and_print((long long)opts->blk_size, "\n"); + } + + HDfprintf(output, "rank %d: Block Pattern in Dataset=", rank); + if (opts->interleaved) + HDfprintf(output, "Interleaved\n"); + else + HDfprintf(output, "Contiguous\n"); + + HDfprintf(output, "rank %d: I/O Method for MPI and HDF5=", rank); + if (opts->collective) + HDfprintf(output, "Collective\n"); + else + HDfprintf(output, "Independent\n"); + + HDfprintf(output, "rank %d: Geometry=", rank); + if (opts->dim2d) + HDfprintf(output, "2D\n"); + else + HDfprintf(output, "1D\n"); + + HDfprintf(output, "rank %d: VFL used for HDF5 I/O=%s\n", rank, "MPI-IO driver"); + + HDfprintf(output, "rank %d: Data storage method in HDF5=", rank); + if (opts->h5_use_chunks) + HDfprintf(output, "Chunked\n"); + else + HDfprintf(output, "Contiguous\n"); + + { + char *prefix = HDgetenv("HDF5_PARAPREFIX"); + + HDfprintf(output, "rank %d: Env HDF5_PARAPREFIX=%s\n", rank, (prefix ? prefix : "not set")); + } + + HDfprintf(output, "rank %d: ", rank); + h5_dump_info_object(h5_io_info_g); + + HDfprintf(output, "rank %d: ==== End of Parameters ====\n", rank); + HDfprintf(output, "\n"); +} + +/* + * Function: parse_command_line + * Purpose: Parse the command line options and return a STRUCT OPTIONS + * structure which will need to be freed by the calling function. + * Return: Pointer to an OPTIONS structure + * Programmer: Bill Wendling, 31. October 2001 + * Modifications: + * Added 2D testing (Christian Chilan, 10. August 2005) + */ +static struct options * +parse_command_line(int argc, char *argv[]) +{ + register int opt; + struct options *cl_opts; + + cl_opts = (struct options *)malloc(sizeof(struct options)); + + cl_opts->output_file = NULL; + cl_opts->io_types = 0; /* will set default after parsing options */ + cl_opts->num_dsets = 1; + cl_opts->num_files = 1; + cl_opts->num_bpp = 0; + cl_opts->num_iters = 1; + cl_opts->max_num_procs = comm_world_nprocs_g; + cl_opts->min_num_procs = 1; + cl_opts->max_xfer_size = 0; + cl_opts->min_xfer_size = 0; + cl_opts->blk_size = 0; + cl_opts->interleaved = 0; /* Default to contiguous blocks in dataset */ + cl_opts->collective = 0; /* Default to independent I/O access */ + cl_opts->dim2d = 0; /* Default to 1D */ + cl_opts->print_times = FALSE; /* Printing times is off by default */ + cl_opts->print_raw = FALSE; /* Printing raw data throughput is off by default */ + cl_opts->h5_alignment = 1; /* No alignment for HDF5 objects by default */ + cl_opts->h5_threshold = 1; /* No threshold for aligning HDF5 objects by default */ + cl_opts->h5_use_chunks = FALSE; /* Don't chunk the HDF5 dataset by default */ + cl_opts->h5_write_only = FALSE; /* Do both read and write by default */ + cl_opts->verify = FALSE; /* No Verify data correctness by default */ + + while ((opt = H5_get_option(argc, (const char **)argv, s_opts, l_opts)) != EOF) { + switch ((char)opt) { + case 'a': + cl_opts->h5_alignment = parse_size_directive(H5_optarg); + break; + case 'A': { + const char *end = H5_optarg; + + while (end && *end != '\0') { + char buf[10]; + int i; + + HDmemset(buf, '\0', sizeof(buf)); + + for (i = 0; *end != '\0' && *end != ','; ++end) + if (isalnum(*end) && i < 10) + buf[i++] = *end; + + if (!HDstrcasecmp(buf, "phdf5")) { + cl_opts->io_types |= PIO_HDF5; + } + else if (!HDstrcasecmp(buf, "mpiio")) { + cl_opts->io_types |= PIO_MPI; + } + else if (!HDstrcasecmp(buf, "posix")) { + cl_opts->io_types |= PIO_POSIX; + } + else { + HDfprintf(stderr, "pio_perf: invalid --api option %s\n", buf); + HDexit(EXIT_FAILURE); + } + + if (*end == '\0') + break; + + end++; + } + } + + break; +#if 0 + case 'b': + /* the future "binary" option */ + break; +#endif /* 0 */ + case 'B': + cl_opts->blk_size = (size_t)parse_size_directive(H5_optarg); + break; + case 'c': + /* Turn on chunked HDF5 dataset creation */ + cl_opts->h5_use_chunks = TRUE; + break; + case 'C': + cl_opts->collective = 1; + break; + case 'd': + cl_opts->num_dsets = atoi(H5_optarg); + break; + case 'D': { + const char *end = H5_optarg; + + while (end && *end != '\0') { + char buf[10]; + int i; + + HDmemset(buf, '\0', sizeof(buf)); + + for (i = 0; *end != '\0' && *end != ','; ++end) + if (HDisalnum(*end) && i < 10) + buf[i++] = *end; + + if (HDstrlen(buf) > 1 || HDisdigit(buf[0])) { + size_t j; + + for (j = 0; j < 10 && buf[j] != '\0'; ++j) + if (!isdigit(buf[j])) { + HDfprintf(stderr, "pio_perf: invalid --debug option %s\n", buf); + HDexit(EXIT_FAILURE); + } + + pio_debug_level = atoi(buf); + + if (pio_debug_level > 4) + pio_debug_level = 4; + else if (pio_debug_level < 0) + pio_debug_level = 0; + } + else { + switch (*buf) { + case 'r': + /* Turn on raw data throughput info */ + cl_opts->print_raw = TRUE; + break; + case 't': + /* Turn on time printing */ + cl_opts->print_times = TRUE; + break; + case 'v': + /* Turn on verify data correctness*/ + cl_opts->verify = TRUE; + break; + default: + HDfprintf(stderr, "pio_perf: invalid --debug option %s\n", buf); + HDexit(EXIT_FAILURE); + } + } + + if (*end == '\0') + break; + + end++; + } + } + + break; + case 'e': + cl_opts->num_bpp = parse_size_directive(H5_optarg); + break; + case 'F': + cl_opts->num_files = HDatoi(H5_optarg); + break; + case 'g': + cl_opts->dim2d = 1; + break; + case 'i': + cl_opts->num_iters = HDatoi(H5_optarg); + break; + case 'I': + cl_opts->interleaved = 1; + break; + case 'o': + cl_opts->output_file = H5_optarg; + break; + case 'p': + cl_opts->min_num_procs = HDatoi(H5_optarg); + break; + case 'P': + cl_opts->max_num_procs = HDatoi(H5_optarg); + break; + case 'T': + cl_opts->h5_threshold = parse_size_directive(H5_optarg); + break; + case 'w': + cl_opts->h5_write_only = TRUE; + break; + case 'x': + cl_opts->min_xfer_size = (size_t)parse_size_directive(H5_optarg); + break; + case 'X': + cl_opts->max_xfer_size = (size_t)parse_size_directive(H5_optarg); + break; + case 'h': + case '?': + default: + usage(progname); + HDfree(cl_opts); + return NULL; + } + } + + if (cl_opts->num_bpp == 0) { + if (cl_opts->dim2d == 0) + cl_opts->num_bpp = 256 * ONE_KB; + else + cl_opts->num_bpp = 8 * ONE_KB; + } + + if (cl_opts->max_xfer_size == 0) + cl_opts->max_xfer_size = (size_t)cl_opts->num_bpp; + + if (cl_opts->min_xfer_size == 0) + cl_opts->min_xfer_size = (size_t)(cl_opts->num_bpp) / 2; + + if (cl_opts->blk_size == 0) + cl_opts->blk_size = (size_t)(cl_opts->num_bpp) / 2; + + /* set default if none specified yet */ + if (!cl_opts->io_types) + cl_opts->io_types = PIO_HDF5 | PIO_MPI | PIO_POSIX; /* run all API */ + + /* verify parameters sanity. Adjust if needed. */ + /* cap xfer_size with bytes per process */ + if (!cl_opts->dim2d) { + if (cl_opts->min_xfer_size > (size_t)cl_opts->num_bpp) + cl_opts->min_xfer_size = (size_t)cl_opts->num_bpp; + if (cl_opts->max_xfer_size > (size_t)cl_opts->num_bpp) + cl_opts->max_xfer_size = (size_t)cl_opts->num_bpp; + } + if (cl_opts->min_xfer_size > cl_opts->max_xfer_size) + cl_opts->min_xfer_size = cl_opts->max_xfer_size; + if (cl_opts->blk_size > (size_t)cl_opts->num_bpp) + cl_opts->blk_size = (size_t)cl_opts->num_bpp; + /* check range of number of processes */ + if (cl_opts->min_num_procs <= 0) + cl_opts->min_num_procs = 1; + if (cl_opts->max_num_procs <= 0) + cl_opts->max_num_procs = 1; + if (cl_opts->min_num_procs > cl_opts->max_num_procs) + cl_opts->min_num_procs = cl_opts->max_num_procs; + /* check iteration */ + if (cl_opts->num_iters <= 0) + cl_opts->num_iters = 1; + + return cl_opts; +} + +/* + * Function: parse_size_directive + * Purpose: Parse the size directive passed on the commandline. The size + * directive is an integer followed by a size indicator: + * + * K, k - Kilobyte + * M, m - Megabyte + * G, g - Gigabyte + * + * Return: The size as a off_t because this is related to file size. + * If an unknown size indicator is used, then the program will + * exit with EXIT_FAILURE as the return value. + * Programmer: Bill Wendling, 18. December 2001 + * Modifications: + */ +static off_t +parse_size_directive(const char *size) +{ + off_t s; + char *endptr; + + s = HDstrtol(size, &endptr, 10); + + if (endptr && *endptr) { + while (*endptr != '\0' && (*endptr == ' ' || *endptr == '\t')) + ++endptr; + + switch (*endptr) { + case 'K': + case 'k': + s *= ONE_KB; + break; + case 'M': + case 'm': + s *= ONE_MB; + break; + case 'G': + case 'g': + s *= ONE_GB; + break; + default: + HDfprintf(stderr, "Illegal size specifier '%c'\n", *endptr); + HDexit(EXIT_FAILURE); + } + } + + return s; +} + +/* + * Function: usage + * Purpose: Print a usage message and then exit. + * Return: Nothing + * Programmer: Bill Wendling, 31. October 2001 + * Modifications: + * Added 2D testing (Christian Chilan, 10. August 2005) + */ +static void +usage(const char *prog) +{ + int myrank; + + MPI_Comm_rank(pio_comm_g, &myrank); + + if (myrank == 0) { + print_version(prog); + HDprintf("usage: %s [OPTIONS]\n", prog); + HDprintf(" OPTIONS\n"); + HDprintf(" -h, --help Print a usage message and exit\n"); + HDprintf(" -a S, --align=S Alignment of objects in HDF5 file [default: 1]\n"); + HDprintf(" -A AL, --api=AL Which APIs to test [default: all of them]\n"); +#if 0 + HDprintf(" -b, --binary The elusive binary option\n"); +#endif /* 0 */ + HDprintf(" -B S, --block-size=S Block size within transfer buffer\n"); + HDprintf(" (see below for description)\n"); + HDprintf(" [default: half the number of bytes per process\n"); + HDprintf(" per dataset]\n"); + HDprintf(" -c, --chunk Create HDF5 datasets using chunked storage\n"); + HDprintf(" [default: contiguous storage]\n"); + HDprintf(" -C, --collective Use collective I/O for MPI and HDF5 APIs\n"); + HDprintf(" [default: independent I/O)\n"); + HDprintf(" -d N, --num-dsets=N Number of datasets per file [default: 1]\n"); + HDprintf(" -D DL, --debug=DL Indicate the debugging level\n"); + HDprintf(" [default: no debugging]\n"); + HDprintf(" -e S, --num-bytes=S Number of bytes per process per dataset\n"); + HDprintf(" (see below for description)\n"); + HDprintf(" [default: 256K for 1D, 8K for 2D]\n"); + HDprintf(" -F N, --num-files=N Number of files [default: 1]\n"); + HDprintf(" -g, --geometry Use 2D geometry [default: 1D geometry]\n"); + HDprintf(" -i N, --num-iterations=N Number of iterations to perform [default: 1]\n"); + HDprintf(" -I, --interleaved Interleaved access pattern\n"); + HDprintf(" (see below for example)\n"); + HDprintf(" [default: Contiguous access pattern]\n"); + HDprintf(" -o F, --output=F Output raw data into file F [default: none]\n"); + HDprintf(" -p N, --min-num-processes=N Minimum number of processes to use [default: 1]\n"); + HDprintf(" -P N, --max-num-processes=N Maximum number of processes to use\n"); + HDprintf(" [default: all MPI_COMM_WORLD processes ]\n"); + HDprintf(" -T S, --threshold=S Threshold for alignment of objects in HDF5 file\n"); + HDprintf(" [default: 1]\n"); + HDprintf(" -w, --write-only Perform write tests not the read tests\n"); + HDprintf(" -x S, --min-xfer-size=S Minimum transfer buffer size\n"); + HDprintf(" (see below for description)\n"); + HDprintf(" [default: half the number of bytes per process\n"); + HDprintf(" per dataset]\n"); + HDprintf(" -X S, --max-xfer-size=S Maximum transfer buffer size\n"); + HDprintf(" [default: the number of bytes per process per\n"); + HDprintf(" dataset]\n"); + HDprintf("\n"); + HDprintf(" F - is a filename.\n"); + HDprintf(" N - is an integer >=0.\n"); + HDprintf(" S - is a size specifier, an integer >=0 followed by a size indicator:\n"); + HDprintf(" K - Kilobyte (%d)\n", ONE_KB); + HDprintf(" M - Megabyte (%d)\n", ONE_MB); + HDprintf(" G - Gigabyte (%d)\n", ONE_GB); + HDprintf("\n"); + HDprintf(" Example: '37M' is 37 megabytes or %d bytes\n", 37 * ONE_MB); + HDprintf("\n"); + HDprintf(" AL - is an API list. Valid values are:\n"); + HDprintf(" phdf5 - Parallel HDF5\n"); + HDprintf(" mpiio - MPI-I/O\n"); + HDprintf(" posix - POSIX\n"); + HDprintf("\n"); + HDprintf(" Example: --api=mpiio,phdf5\n"); + HDprintf("\n"); + HDprintf(" Dataset size:\n"); + HDprintf(" Depending on the selected geometry, each test dataset is either a linear\n"); + HDprintf(" array of size bytes-per-process * num-processes, or a square array of size\n"); + HDprintf(" (bytes-per-process * num-processes) x (bytes-per-process * num-processes).\n"); + HDprintf("\n"); + HDprintf(" Block size vs. Transfer buffer size:\n"); + HDprintf(" buffer-size controls the size of the memory buffer, which is broken into\n"); + HDprintf(" blocks and written to the file. Depending on the selected geometry, each\n"); + HDprintf(" block can be a linear array of size block-size or a square array of size\n"); + HDprintf(" block-size x block-size. The arrangement in which blocks are written is\n"); + HDprintf(" determined by the access pattern.\n"); + HDprintf("\n"); + HDprintf(" In 1D geometry, the transfer buffer is a linear array of size buffer-size.\n"); + HDprintf(" In 2D geometry, it is a rectangular array of size block-size x buffer-size\n"); + HDprintf(" or buffer-size x block-size if interleaved pattern is selected.\n"); + HDprintf("\n"); + HDprintf(" Interleaved and Contiguous patterns in 1D geometry:\n"); + HDprintf(" When contiguous access pattern is chosen, the dataset is evenly divided\n"); + HDprintf(" into num-processes regions and each process writes data to its own region.\n"); + HDprintf(" When interleaved blocks are written to a dataset, space for the first\n"); + HDprintf(" block of the first process is allocated in the dataset, then space is\n"); + HDprintf(" allocated for the first block of the second process, etc. until space is\n"); + HDprintf(" allocated for the first block of each process, then space is allocated for\n"); + HDprintf(" the second block of the first process, the second block of the second\n"); + HDprintf(" process, etc.\n"); + HDprintf("\n"); + HDprintf(" For example, with a 3 process run, 512KB bytes-per-process, 256KB transfer\n"); + HDprintf(" buffer size, and 64KB block size, each process must issue 2 transfer\n"); + HDprintf(" requests to complete access to the dataset.\n"); + HDprintf(" Contiguous blocks of the first transfer request are written like so:\n"); + HDprintf(" 1111----2222----3333----\n"); + HDprintf(" Interleaved blocks of the first transfer request are written like so:\n"); + HDprintf(" 123123123123------------\n"); + HDprintf(" The actual number of I/O operations involved in a transfer request\n"); + HDprintf(" depends on the access pattern and communication mode.\n"); + HDprintf(" When using independent I/O with interleaved pattern, each process\n"); + HDprintf(" performs 4 small non-contiguous I/O operations per transfer request.\n"); + HDprintf(" If collective I/O is turned on, the combined content of the buffers of\n"); + HDprintf(" the 3 processes will be written using one collective I/O operation\n"); + HDprintf(" per transfer request.\n"); + HDprintf("\n"); + HDprintf(" For information about access patterns in 2D geometry, please refer to the\n"); + HDprintf(" HDF5 Reference Manual.\n"); + HDprintf("\n"); + HDprintf(" DL - is a list of debugging flags. Valid values are:\n"); + HDprintf(" 1 - Minimal\n"); + HDprintf(" 2 - Not quite everything\n"); + HDprintf(" 3 - Everything\n"); + HDprintf(" 4 - The kitchen sink\n"); + HDprintf(" r - Raw data I/O throughput information\n"); + HDprintf(" t - Times as well as throughputs\n"); + HDprintf(" v - Verify data correctness\n"); + HDprintf("\n"); + HDprintf(" Example: --debug=2,r,t\n"); + HDprintf("\n"); + HDprintf(" Environment variables:\n"); + HDprintf(" HDF5_NOCLEANUP Do not remove data files if set [default remove]\n"); + HDprintf(" HDF5_MPI_INFO MPI INFO object key=value separated by ;\n"); + HDprintf(" HDF5_PARAPREFIX Paralllel data files prefix\n"); + fflush(stdout); + } /* end if */ +} /* end usage() */ + +#else /* H5_HAVE_PARALLEL */ + +/* + * Function: main + * Purpose: Dummy main() function for if HDF5 was configured without + * parallel stuff. + * Return: EXIT_SUCCESS + * Programmer: Bill Wendling, 14. November 2001 + */ +int +main(void) +{ + HDprintf("No parallel IO performance because parallel is not configured\n"); + return EXIT_SUCCESS; +} /* end main */ + +#endif /* !H5_HAVE_PARALLEL */ diff --git a/tools/src/h5perf/pio_perf.h b/tools/src/h5perf/pio_perf.h new file mode 100644 index 0000000..8924c20 --- /dev/null +++ b/tools/src/h5perf/pio_perf.h @@ -0,0 +1,109 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef PIO_PERF_H +#define PIO_PERF_H + +#ifndef STANDALONE +#include "io_timer.h" +#include "H5private.h" +#include "h5tools.h" +#include "h5tools_utils.h" +#else +#include "io_timer.h" +#include "pio_standalone.h" +#endif + +#ifdef H5_HAVE_PARALLEL +extern MPI_Info h5_io_info_g; /* MPI INFO object for IO */ +#endif + +#ifdef H5_HAVE_PARALLEL +int h5_set_info_object(void); +void h5_dump_info_object(MPI_Info info); +#endif + +/* setup the dataset no fill option if this is v1.5 or more */ +#if H5_VERS_MAJOR > 1 || H5_VERS_MINOR > 4 +#define H5_HAVE_NOFILL 1 +#endif + +typedef enum iotype_ { + POSIXIO, + MPIO, + PHDF5 + /*NUM_TYPES*/ +} iotype; + +typedef struct parameters_ { + iotype io_type; /* The type of IO test to perform */ + int num_procs; /* Maximum number of processes to use */ + long num_files; /* Number of files to create */ + long num_dsets; /* Number of datasets to create */ + off_t num_bytes; /* Number of bytes in each dset */ + int num_iters; /* Number of times to loop doing the IO */ + size_t buf_size; /* Buffer size */ + size_t blk_size; /* Block size */ + unsigned interleaved; /* Interleaved vs. contiguous blocks */ + unsigned collective; /* Collective vs. independent I/O */ + unsigned dim2d; /* 1D vs. 2D */ + hsize_t h5_align; /* HDF5 object alignment */ + hsize_t h5_thresh; /* HDF5 object alignment threshold */ + int h5_use_chunks; /* Make HDF5 dataset chunked */ + int h5_write_only; /* Perform the write tests only */ + int verify; /* Verify data correctness */ +} parameters; + +typedef struct results_ { + herr_t ret_code; + io_time_t *timers; +} results; + +#ifndef SUCCESS +#define SUCCESS 0 +#endif /* !SUCCESS */ + +#ifndef FAIL +#define FAIL -1 +#endif /* !FAIL */ + +extern FILE * output; /* output file */ +extern io_time_t *timer_g; /* timer: global for stub functions */ +extern int comm_world_rank_g; /* my rank in MPI_COMM_RANK */ +extern int comm_world_nprocs_g; /* num. of processes of MPI_COMM_WORLD */ +extern MPI_Comm pio_comm_g; /* Communicator to run the PIO */ +extern int pio_mpi_rank_g; /* MPI rank of pio_comm_g */ +extern int pio_mpi_nprocs_g; /* number of processes of pio_comm_g */ +extern int pio_debug_level; /* The debug level: + * 0 - Off + * 1 - Minimal + * 2 - Some more + * 3 - Maximal + * 4 - Even More Debugging (timer stuff) + */ + +#define HDprint_rank(f) /* print rank in MPI_COMM_WORLD */ HDfprintf(f, "%d: ", comm_world_rank_g); +#define HDprint_size(f) /* print size of MPI_COMM_WORLD */ HDfprintf(f, "%d", comm_world_nprocs_g); +#define HDprint_rank_size(f) /* print rank/size of MPI_COMM_WORLD */ \ + HDfprintf(f, "%d/%d: ", comm_world_rank_g, comm_world_nprocs_g); + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +extern results do_pio(parameters param); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* PIO_PERF_H */ diff --git a/tools/src/h5perf/sio_engine.c b/tools/src/h5perf/sio_engine.c new file mode 100644 index 0000000..e69a7cd --- /dev/null +++ b/tools/src/h5perf/sio_engine.c @@ -0,0 +1,1328 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Author: Christian Chilan, April 2008 + */ + +#include "hdf5.h" + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> + +#ifdef H5_HAVE_UNISTD_H +#include <sys/types.h> +#include <unistd.h> +#endif + +#ifdef H5_HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif + +#include "sio_perf.h" + +/* Macro definitions */ + +/* sizes of various items. these sizes won't change during program execution */ +#define ELMT_H5_TYPE H5T_NATIVE_UCHAR + +#define GOTOERROR(errcode) \ + { \ + ret_code = errcode; \ + goto done; \ + } +#define ERRMSG(mesg) \ + { \ + HDfprintf(stderr, "*** Assertion failed (%s) at line %4d in %s\n", mesg, (int)__LINE__, __FILE__); \ + } + +/* verify: if val is false (0), print mesg. */ +#define VRFY(val, mesg) \ + do { \ + if (!(val)) { \ + ERRMSG(mesg); \ + GOTOERROR(FAIL); \ + } \ + } while (0) + +/* POSIX I/O macros */ +#ifdef H5_HAVE_WIN32_API +/* Can't link against the library, so this test will use the older, non-Unicode + * _open() call on Windows. + */ +#define HDopen(S, F, ...) _open(S, F | _O_BINARY, __VA_ARGS__) +#endif /* H5_HAVE_WIN32_API */ +#define POSIXCREATE(fn) HDopen(fn, O_CREAT | O_TRUNC | O_RDWR, 0600) +#define POSIXOPEN(fn, F) HDopen(fn, F, 0600) +#define POSIXCLOSE(F) HDclose(F) +#define POSIXSEEK(F, L) HDlseek(F, L, SEEK_SET) +#define POSIXWRITE(F, B, S) HDwrite(F, B, S) +#define POSIXREAD(F, B, S) HDread(F, B, S) + +enum { SIO_CREATE = 1, SIO_WRITE = 2, SIO_READ = 4 }; + +/* Global variables */ +static int clean_file_g = -1; /*whether to cleanup temporary test */ +/*files. -1 is not defined; */ +/*0 is no cleanup; 1 is do cleanup */ + +/* the different types of file descriptors we can expect */ +typedef union { + int posixfd; /* POSIX file handle*/ + hid_t h5fd; /* HDF5 file */ +} file_descr; + +/* local functions */ +static char * sio_create_filename(iotype iot, const char *base_name, char *fullname, size_t size, + parameters *param); +static herr_t do_write(results *res, file_descr *fd, parameters *parms, void *buffer); +static herr_t do_read(results *res, file_descr *fd, parameters *parms, void *buffer); +static herr_t dset_write(int local_dim, file_descr *fd, parameters *parms, void *buffer); +static herr_t posix_buffer_write(int local_dim, file_descr *fd, parameters *parms, void *buffer); +static herr_t dset_read(int localrank, file_descr *fd, parameters *parms, void *buffer, const char *buffer2); +static herr_t posix_buffer_read(int local_dim, file_descr *fd, parameters *parms, void *buffer); +static herr_t do_fopen(parameters *param, char *fname, file_descr *fd /*out*/, int flags); +hid_t set_vfd(parameters *param); +static herr_t do_fclose(iotype iot, file_descr *fd); +static void do_cleanupfile(iotype iot, char *fname); + +/* global variables */ +static HDoff_t offset[MAX_DIMS]; /* dataset size in bytes */ +static size_t buf_offset[MAX_DIMS]; /* dataset size in bytes */ +static int order[MAX_DIMS]; /* dimension access order */ +static size_t linear_buf_size; /* linear buffer size */ +static int cont_dim; /* lowest dimension for contiguous POSIX + access */ +static size_t cont_size; /* size of contiguous POSIX access */ +static hid_t fapl; /* file access list */ +static unsigned char *buf_p; /* buffer pointer */ +static const char * multi_letters = "msbrglo"; /* string for multi driver */ + +/* HDF5 global variables */ +static hsize_t h5count[MAX_DIMS]; /*selection count */ +static hssize_t h5offset[MAX_DIMS]; /* Selection offset within dataspace */ +static hid_t h5dset_space_id = H5I_INVALID_HID; /*dataset space ID */ +static hid_t h5mem_space_id = H5I_INVALID_HID; /*memory dataspace ID */ +static hid_t h5ds_id = H5I_INVALID_HID; /*dataset handle */ +static hid_t h5dcpl = H5I_INVALID_HID; /* Dataset creation property list */ +static hid_t h5dxpl = H5I_INVALID_HID; /* Dataset transfer property list */ + +/* + * Function: do_sio + * Purpose: SIO Engine where IO are executed. + * Return: results + * Programmer: Christian Chilan, April, 2008 + * Modifications: + */ +void +do_sio(parameters param, results *res) +{ + char * buffer = NULL; /*data buffer pointer */ + size_t buf_size[MAX_DIMS]; /* general buffer size in bytes */ + file_descr fd; /* file handles */ + iotype iot; /* API type */ + char base_name[256]; /* test file base name */ + /* return codes */ + herr_t ret_code = 0; /*return code */ + + char fname[FILENAME_MAX]; /* test file name */ + int i; + /* HDF5 variables */ + herr_t hrc; /*HDF5 return code */ + + /* Sanity check parameters */ + + /* IO type */ + iot = param.io_type; + + switch (iot) { + case POSIXIO: + fd.posixfd = -1; + res->timers = io_time_new(SYS_CLOCK); + break; + case HDF5: + fd.h5fd = -1; + res->timers = io_time_new(SYS_CLOCK); + break; + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); + GOTOERROR(FAIL); + } + + linear_buf_size = 1; + + for (i = 0; i < param.rank; i++) { + buf_size[i] = param.buf_size[i]; + order[i] = param.order[i]; + linear_buf_size *= buf_size[i]; + buf_offset[i] = 0; + offset[i] = 0; + + /* Validate transfer buffer size */ + if (param.buf_size[i] <= 0) { + HDfprintf(stderr, "Transfer buffer size[%d] (%zu) must be > 0\n", i, buf_size[i]); + GOTOERROR(FAIL); + } + + if ((param.dset_size[i] % param.buf_size[i]) != 0) { + HDfprintf(stderr, + "Dataset size[%d] (%" H5_PRINTF_LL_WIDTH "d) must be a multiple of the " + "trasfer buffer size[%d] (%zu)\n", + param.rank, (long long)param.dset_size[i], param.rank, param.buf_size[i]); + GOTOERROR(FAIL); + } + } + + /* Allocate transfer buffer */ + if ((buffer = (char *)malloc(linear_buf_size)) == NULL) { + HDfprintf(stderr, "malloc for transfer buffer size (%zu) failed\n", linear_buf_size); + GOTOERROR(FAIL); + } + + if (sio_debug_level >= 4) + + /* output all of the times for all iterations */ + HDfprintf(output, "Timer details:\n"); + + /* + * Write performance measurement + */ + /* Open file for write */ + + HDstrcpy(base_name, "#sio_tmp"); + sio_create_filename(iot, base_name, fname, sizeof(fname), ¶m); + + if (sio_debug_level > 0) + HDfprintf(output, "data filename=%s\n", fname); + + io_time_set(res->timers, HDF5_GROSS_WRITE_FIXED_DIMS, TSTART); + hrc = do_fopen(¶m, fname, &fd, SIO_CREATE | SIO_WRITE); + VRFY((hrc == SUCCESS), "do_fopen failed"); + + io_time_set(res->timers, HDF5_FINE_WRITE_FIXED_DIMS, TSTART); + hrc = do_write(res, &fd, ¶m, buffer); + io_time_set(res->timers, HDF5_FINE_WRITE_FIXED_DIMS, TSTOP); + VRFY((hrc == SUCCESS), "do_write failed"); + + /* Close file for write */ + hrc = do_fclose(iot, &fd); + io_time_set(res->timers, HDF5_GROSS_WRITE_FIXED_DIMS, TSTOP); + VRFY((hrc == SUCCESS), "do_fclose failed"); + + if (!param.h5_write_only) { + /* + * Read performance measurement + */ + + /* Open file for read */ + io_time_set(res->timers, HDF5_GROSS_READ_FIXED_DIMS, TSTART); + hrc = do_fopen(¶m, fname, &fd, SIO_READ); + VRFY((hrc == SUCCESS), "do_fopen failed"); + + io_time_set(res->timers, HDF5_FINE_READ_FIXED_DIMS, TSTART); + hrc = do_read(res, &fd, ¶m, buffer); + io_time_set(res->timers, HDF5_FINE_READ_FIXED_DIMS, TSTOP); + VRFY((hrc == SUCCESS), "do_read failed"); + + /* Close file for read */ + hrc = do_fclose(iot, &fd); + + io_time_set(res->timers, HDF5_GROSS_READ_FIXED_DIMS, TSTOP); + VRFY((hrc == SUCCESS), "do_fclose failed"); + } + + do_cleanupfile(iot, fname); + +done: + /* clean up */ + /* release HDF5 objects */ + + /* close any opened files */ + /* no remove(fname) because that should have happened normally. */ + switch (iot) { + case POSIXIO: + if (fd.posixfd != -1) + hrc = do_fclose(iot, &fd); + break; + case HDF5: + if (fd.h5fd != -1) + hrc = do_fclose(iot, &fd); + break; + default: + /* unknown request */ + HDassert(0 && "Unknown IO type"); + break; + } + + /* release generic resources */ + if (buffer) + free(buffer); + + res->ret_code = ret_code; +} + +/* + * Function: sio_create_filename + * Purpose: Create a new filename to write to. Determine the correct + * suffix to append to the filename by the type of I/O we're + * doing. Also, place in the /tmp/{$USER,$LOGIN} directory if + * USER or LOGIN are specified in the environment. + * Return: Pointer to filename or NULL + * Programmer: Bill Wendling, 21. November 2001 + * Modifications: Support for file drivers. Christian Chilan, April, 2008 + */ +static char * +sio_create_filename(iotype iot, const char *base_name, char *fullname, size_t size, parameters *param) +{ + const char *prefix, *suffix = ""; + char * ptr, last = '\0'; + size_t i, j; + vfdtype vfd; + vfd = param->vfd; + + if (!base_name || !fullname || size < 1) + return NULL; + + memset(fullname, 0, size); + + switch (iot) { + case POSIXIO: + suffix = ".posix"; + break; + case HDF5: + suffix = ".h5"; + if (vfd == family) + suffix = "%05d.h5"; + else if (vfd == multi) + suffix = NULL; + break; + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); + HDassert(0 && "Unknown IO type"); + break; + } + + /* First use the environment variable and then try the constant */ + prefix = HDgetenv("HDF5_PREFIX"); + +#ifdef HDF5_PREFIX + if (!prefix) + prefix = HDF5_PREFIX; +#endif /* HDF5_PREFIX */ + + /* Prepend the prefix value to the base name */ + if (prefix && *prefix) { + /* If the prefix specifies the HDF5_PREFIX directory, then + * default to using the "/tmp/$USER" or "/tmp/$LOGIN" + * directory instead. */ + register char *user, *login, *subdir; + + user = HDgetenv("USER"); + login = HDgetenv("LOGIN"); + subdir = (user ? user : login); + + if (subdir) { + for (i = 0; i < size - 1 && prefix[i]; i++) + fullname[i] = prefix[i]; + + fullname[i++] = '/'; + + for (j = 0; i < size && subdir[j]; i++, j++) + fullname[i] = subdir[j]; + } + else { + /* We didn't append the prefix yet */ + HDstrncpy(fullname, prefix, size); + fullname[size - 1] = '\0'; + } + + if ((HDstrlen(fullname) + HDstrlen(base_name) + 1) < size) { + /* Append the base_name with a slash first. Multiple slashes are + * handled below. */ + h5_stat_t buf; + + if (HDstat(fullname, &buf) < 0) + /* The directory doesn't exist just yet */ + if (HDmkdir(fullname, 0755) < 0 && errno != EEXIST) { + /* We couldn't make the "/tmp/${USER,LOGIN}" subdirectory. + * Default to PREFIX's original prefix value. */ + HDstrcpy(fullname, prefix); + } + + HDstrcat(fullname, "/"); + HDstrcat(fullname, base_name); + } + else { + /* Buffer is too small */ + return NULL; + } + } + else if (strlen(base_name) >= size) { + /* Buffer is too small */ + return NULL; + } + else { + HDstrcpy(fullname, base_name); + } + + /* Append a suffix */ + if (suffix) { + if (HDstrlen(fullname) + HDstrlen(suffix) >= size) + return NULL; + + HDstrcat(fullname, suffix); + } + + /* Remove any double slashes in the filename */ + for (ptr = fullname, i = j = 0; ptr && (i < size); i++, ptr++) { + if (*ptr != '/' || last != '/') + fullname[j++] = *ptr; + + last = *ptr; + } + + return fullname; +} + +/* + * Function: do_write + * Purpose: Write the required amount of data to the file. + * Return: SUCCESS or FAIL + * Programmer: Christian Chilan, April, 2008 + * Modifications: + */ +static herr_t +do_write(results *res, file_descr *fd, parameters *parms, void *buffer) +{ + int ret_code = SUCCESS; + char dname[64]; + int i; + size_t u; + /* HDF5 variables */ + herr_t hrc; /*HDF5 return code */ + hsize_t h5dims[MAX_DIMS]; /*dataset dim sizes */ + hsize_t h5chunk[MAX_DIMS]; /*dataset dim sizes */ + hsize_t h5block[MAX_DIMS]; /*dataspace selection */ + hsize_t h5stride[MAX_DIMS]; /*selection stride */ + hsize_t h5start[MAX_DIMS]; /*selection start */ + hsize_t h5maxdims[MAX_DIMS]; + int rank; /*rank of dataset */ + + /* Prepare buffer for verifying data */ + /* if (parms->verify) + memset(buffer,1,linear_buf_size); */ + + buf_p = (unsigned char *)buffer; + + for (u = 0; u < linear_buf_size; u++) + buf_p[u] = u % 128; + + rank = parms->rank; + + for (i = 0; i < rank; i++) + h5offset[i] = offset[i] = 0; + + /* I/O Access specific setup */ + switch (parms->io_type) { + case POSIXIO: + + /* determine lowest dimension for contiguous POSIX access */ + cont_dim = rank; + + for (i = rank - 1; i >= 0; i--) { + if (parms->buf_size[i] == parms->dset_size[i]) + cont_dim = i; + else + break; + } + + /* determine size of the contiguous POSIX access */ + cont_size = (!cont_dim) ? 1 : parms->buf_size[cont_dim - 1]; + for (i = cont_dim; i < rank; i++) + cont_size *= parms->buf_size[i]; + + break; + + case HDF5: /* HDF5 setup */ + + for (i = 0; i < rank; i++) { + h5dims[i] = parms->dset_size[i]; + h5start[i] = 0; + h5stride[i] = 1; + h5block[i] = 1; + h5count[i] = parms->buf_size[i]; + h5chunk[i] = parms->chk_size[i]; + h5maxdims[i] = H5S_UNLIMITED; + } + + if (parms->h5_use_chunks && parms->h5_extendable) { + h5dset_space_id = H5Screate_simple(rank, h5count, h5maxdims); + VRFY((h5dset_space_id >= 0), "H5Screate_simple"); + } + else { + h5dset_space_id = H5Screate_simple(rank, h5dims, NULL); + VRFY((h5dset_space_id >= 0), "H5Screate_simple"); + } + + hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, h5block); + VRFY((hrc >= 0), "H5Sselect_hyperslab"); + + /* Create the memory dataspace that corresponds to the xfer buffer */ + h5mem_space_id = H5Screate_simple(rank, h5count, NULL); + VRFY((h5mem_space_id >= 0), "H5Screate_simple"); + + /* Create the dataset transfer property list */ + h5dxpl = H5Pcreate(H5P_DATASET_XFER); + if (h5dxpl < 0) { + HDfprintf(stderr, "HDF5 Property List Create failed\n"); + GOTOERROR(FAIL); + } + + break; + + default: + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); + GOTOERROR(FAIL); + break; + } /* end switch */ + + /* create dataset */ + switch (parms->io_type) { + case POSIXIO: + break; + + case HDF5: + h5dcpl = H5Pcreate(H5P_DATASET_CREATE); + + if (h5dcpl < 0) { + HDfprintf(stderr, "HDF5 Property List Create failed\n"); + GOTOERROR(FAIL); + } + + if (parms->h5_use_chunks) { + /* Set the chunk size to be the same as the buffer size */ + hrc = H5Pset_chunk(h5dcpl, rank, h5chunk); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Property List Set failed\n"); + GOTOERROR(FAIL); + } /* end if */ + } /* end if */ + + HDsprintf(dname, "Dataset_%ld", (unsigned long)parms->num_bytes); + h5ds_id = + H5Dcreate2(fd->h5fd, dname, ELMT_H5_TYPE, h5dset_space_id, H5P_DEFAULT, h5dcpl, H5P_DEFAULT); + + if (h5ds_id < 0) { + HDfprintf(stderr, "HDF5 Dataset Create failed\n"); + GOTOERROR(FAIL); + } + + hrc = H5Pclose(h5dcpl); + /* verifying the close of the dcpl */ + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Property List Close failed\n"); + GOTOERROR(FAIL); + } + break; + + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); + GOTOERROR(FAIL); + break; + } + + /* Start "raw data" write timer */ + io_time_set(res->timers, HDF5_RAW_WRITE_FIXED_DIMS, TSTART); + + /* Perform write */ + hrc = dset_write(rank - 1, fd, parms, buffer); + + if (hrc < 0) { + HDfprintf(stderr, "Error in dataset write\n"); + GOTOERROR(FAIL); + } + + /* Stop "raw data" write timer */ + io_time_set(res->timers, HDF5_RAW_WRITE_FIXED_DIMS, TSTOP); + + /* Calculate write time */ + + /* Close dataset. Only HDF5 needs to do an explicit close. */ + if (parms->io_type == HDF5) { + hrc = H5Dclose(h5ds_id); + + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Close failed\n"); + GOTOERROR(FAIL); + } + + h5ds_id = H5I_INVALID_HID; + } /* end if */ + +done: + + /* release HDF5 objects */ + if (h5dset_space_id != -1) { + hrc = H5Sclose(h5dset_space_id); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Space Close failed\n"); + ret_code = FAIL; + } + else { + h5dset_space_id = H5I_INVALID_HID; + } + } + + if (h5mem_space_id != -1) { + hrc = H5Sclose(h5mem_space_id); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Memory Space Close failed\n"); + ret_code = FAIL; + } + else { + h5mem_space_id = H5I_INVALID_HID; + } + } + + if (h5dxpl != -1) { + hrc = H5Pclose(h5dxpl); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Transfer Property List Close failed\n"); + ret_code = FAIL; + } + else { + h5dxpl = H5I_INVALID_HID; + } + } + + return ret_code; +} + +/* + * Function: dset_write + * Purpose: Write buffer into the dataset. + * Return: SUCCESS or FAIL + * Programmer: Christian Chilan, April, 2008 + * Modifications: + */ +static herr_t +dset_write(int local_dim, file_descr *fd, parameters *parms, void *buffer) +{ + int cur_dim = order[local_dim] - 1; + int ret_code = SUCCESS; + int k; + hsize_t dims[MAX_DIMS], maxdims[MAX_DIMS]; + hsize_t i; + int j; + herr_t hrc; + + /* iterates according to the dimensions in order array */ + for (i = 0; i < parms->dset_size[cur_dim]; i += parms->buf_size[cur_dim]) { + + h5offset[cur_dim] = (hssize_t)i; + offset[cur_dim] = (HDoff_t)i; + + if (local_dim > 0) { + + dset_write(local_dim - 1, fd, parms, buffer); + } + else { + + switch (parms->io_type) { + + case POSIXIO: + /* initialize POSIX offset in the buffer */ + for (j = 0; j < parms->rank; j++) + buf_offset[j] = 0; + buf_p = (unsigned char *)buffer; + /* write POSIX buffer */ + posix_buffer_write(0, fd, parms, buffer); + break; + + case HDF5: + /* if dimensions are extendable, extend them as needed during access */ + if (parms->h5_use_chunks && parms->h5_extendable) { + + hrc = H5Sget_simple_extent_dims(h5dset_space_id, dims, maxdims); + VRFY((hrc >= 0), "H5Sget_simple_extent_dims"); + + for (k = 0; k < parms->rank; k++) { + + HDassert(h5offset[k] >= 0); + if (dims[k] <= (hsize_t)h5offset[k]) { + dims[k] = dims[k] + h5count[k]; + hrc = H5Sset_extent_simple(h5dset_space_id, parms->rank, dims, maxdims); + VRFY((hrc >= 0), "H5Sset_extent_simple"); + hrc = H5Dset_extent(h5ds_id, dims); + VRFY((hrc >= 0), "H5Dextend"); + } + } + } + /* applies offset */ + hrc = H5Soffset_simple(h5dset_space_id, h5offset); + VRFY((hrc >= 0), "H5Soffset_simple"); + + /* Write the buffer out */ + hrc = H5Sget_simple_extent_dims(h5dset_space_id, dims, maxdims); + hrc = H5Dwrite(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); + VRFY((hrc >= 0), "H5Dwrite"); + + break; + + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); + HDassert(0 && "Unknown IO type"); + break; + } /* switch (parms->io_type) */ + } + } +done: + return ret_code; +} + +/* + * Function: posix_buffer_write + * Purpose: Write buffer into the POSIX file considering contiguity. + * Return: SUCCESS or FAIL + * Programmer: Christian Chilan, April, 2008 + * Modifications: + */ + +static herr_t +posix_buffer_write(int local_dim, file_descr *fd, parameters *parms, void *buffer) +{ + int ret_code = SUCCESS; + + /* if dimension is not contiguous, call recursively */ + if (local_dim < parms->rank - 1 && local_dim != cont_dim) { + size_t u; + + for (u = 0; u < parms->buf_size[local_dim]; u++) { + buf_offset[local_dim] = u; + posix_buffer_write(local_dim + 1, fd, parms, buffer); + + /* if next dimension is cont_dim, it will fill out the buffer + traversing the entire dimension local_dim without the need + of performing iteration */ + if (local_dim + 1 == cont_dim) + break; + } + /* otherwise, perform contiguous POSIX access */ + } + else { + HDoff_t d_offset; + HDoff_t linear_dset_offset = 0; + int i, j, rc; + + buf_offset[local_dim] = 0; + + /* determine offset in the buffer */ + for (i = 0; i < parms->rank; i++) { + d_offset = 1; + + for (j = i + 1; j < parms->rank; j++) + d_offset *= (HDoff_t)parms->dset_size[j]; + + linear_dset_offset += (offset[i] + (HDoff_t)buf_offset[i]) * d_offset; + } + + /* only care if seek returns error */ + rc = POSIXSEEK(fd->posixfd, linear_dset_offset) < 0 ? -1 : 0; + VRFY((rc == 0), "POSIXSEEK"); + /* check if all bytes are written */ + rc = ((ssize_t)cont_size == POSIXWRITE(fd->posixfd, buf_p, cont_size)); + VRFY((rc != 0), "POSIXWRITE"); + + /* Advance location in buffer */ + buf_p += cont_size; + } + +done: + return ret_code; +} + +/* + * Function: do_read + * Purpose: Read the required amount of data to the file. + * Return: SUCCESS or FAIL + * Programmer: Christian Chilan, April, 2008 + * Modifications: + */ +static herr_t +do_read(results *res, file_descr *fd, parameters *parms, void *buffer) +{ + char * buffer2 = NULL; /* Buffer for data verification */ + int ret_code = SUCCESS; + char dname[64]; + int i; + size_t u; + /* HDF5 variables */ + herr_t hrc; /*HDF5 return code */ + hsize_t h5dims[MAX_DIMS]; /*dataset dim sizes */ + hsize_t h5block[MAX_DIMS]; /*dataspace selection */ + hsize_t h5stride[MAX_DIMS]; /*selection stride */ + hsize_t h5start[MAX_DIMS]; /*selection start */ + int rank; + + /* Allocate data verification buffer */ + if (NULL == (buffer2 = (char *)malloc(linear_buf_size))) { + HDfprintf(stderr, "malloc for data verification buffer size (%zu) failed\n", linear_buf_size); + GOTOERROR(FAIL); + } /* end if */ + + /* Prepare buffer for verifying data */ + for (u = 0; u < linear_buf_size; u++) + buffer2[u] = (char)(u % 128); + + rank = parms->rank; + for (i = 0; i < rank; i++) + h5offset[i] = offset[i] = 0; + + /* I/O Access specific setup */ + switch (parms->io_type) { + case POSIXIO: + cont_dim = rank; + + for (i = rank - 1; i >= 0; i--) { + if (parms->buf_size[i] == parms->dset_size[i]) + cont_dim = i; + else + break; + } + cont_size = (!cont_dim) ? 1 : parms->buf_size[cont_dim - 1]; + for (i = cont_dim; i < rank; i++) + cont_size *= parms->buf_size[i]; + + break; + + case HDF5: /* HDF5 setup */ + for (i = 0; i < rank; i++) { + h5dims[i] = parms->dset_size[i]; + h5start[i] = 0; + h5stride[i] = 1; + h5block[i] = 1; + h5count[i] = parms->buf_size[i]; + } + + h5dset_space_id = H5Screate_simple(rank, h5dims, NULL); + VRFY((h5dset_space_id >= 0), "H5Screate_simple"); + + hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, h5block); + VRFY((hrc >= 0), "H5Sselect_hyperslab"); + + /* Create the memory dataspace that corresponds to the xfer buffer */ + h5mem_space_id = H5Screate_simple(rank, h5count, NULL); + VRFY((h5mem_space_id >= 0), "H5Screate_simple"); + + /* Create the dataset transfer property list */ + h5dxpl = H5Pcreate(H5P_DATASET_XFER); + if (h5dxpl < 0) { + HDfprintf(stderr, "HDF5 Property List Create failed\n"); + GOTOERROR(FAIL); + } + break; + + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); + GOTOERROR(FAIL); + break; + } /* end switch */ + + /* create dataset */ + switch (parms->io_type) { + case POSIXIO: + break; + + case HDF5: + HDsprintf(dname, "Dataset_%ld", (long)parms->num_bytes); + h5ds_id = H5Dopen2(fd->h5fd, dname, H5P_DEFAULT); + if (h5ds_id < 0) { + HDfprintf(stderr, "HDF5 Dataset open failed\n"); + GOTOERROR(FAIL); + } + break; + + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); + GOTOERROR(FAIL); + break; + } /* end switch */ + + /* Start "raw data" read timer */ + io_time_set(res->timers, HDF5_RAW_READ_FIXED_DIMS, TSTART); + hrc = dset_read(rank - 1, fd, parms, buffer, buffer2); + + if (hrc < 0) { + HDfprintf(stderr, "Error in dataset read\n"); + GOTOERROR(FAIL); + } + + /* Stop "raw data" read timer */ + io_time_set(res->timers, HDF5_RAW_READ_FIXED_DIMS, TSTOP); + + /* Calculate read time */ + + /* Close dataset. Only HDF5 needs to do an explicit close. */ + if (parms->io_type == HDF5) { + hrc = H5Dclose(h5ds_id); + + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Close failed\n"); + GOTOERROR(FAIL); + } + + h5ds_id = H5I_INVALID_HID; + } /* end if */ + +done: + + /* release HDF5 objects */ + if (h5dset_space_id != -1) { + hrc = H5Sclose(h5dset_space_id); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Space Close failed\n"); + ret_code = FAIL; + } + else { + h5dset_space_id = H5I_INVALID_HID; + } + } + + if (h5mem_space_id != -1) { + hrc = H5Sclose(h5mem_space_id); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Memory Space Close failed\n"); + ret_code = FAIL; + } + else { + h5mem_space_id = H5I_INVALID_HID; + } + } + + if (h5dxpl != -1) { + hrc = H5Pclose(h5dxpl); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Transfer Property List Close failed\n"); + ret_code = FAIL; + } + else { + h5dxpl = H5I_INVALID_HID; + } + } + + /* release generic resources */ + if (buffer2) + free(buffer2); + + return ret_code; +} + +/* + * Function: dset_read + * Purpose: Read buffer into the dataset. + * Return: SUCCESS or FAIL + * Programmer: Christian Chilan, April, 2008 + * Modifications: + */ + +static herr_t +dset_read(int local_dim, file_descr *fd, parameters *parms, void *buffer, const char *buffer2) +{ + int cur_dim = order[local_dim] - 1; + hsize_t i; + int j; + herr_t hrc; + int ret_code = SUCCESS; + + /* iterate on the current dimension */ + for (i = 0; i < parms->dset_size[cur_dim]; i += parms->buf_size[cur_dim]) { + + h5offset[cur_dim] = (hssize_t)i; + offset[cur_dim] = (HDoff_t)i; + + /* if traverse in order array is incomplete, recurse */ + if (local_dim > 0) { + + ret_code = dset_read(local_dim - 1, fd, parms, buffer, buffer2); + + /* otherwise, write buffer into dataset */ + } + else { + + switch (parms->io_type) { + + case POSIXIO: + for (j = 0; j < parms->rank; j++) { + buf_offset[j] = 0; + } + buf_p = (unsigned char *)buffer; + posix_buffer_read(0, fd, parms, buffer); + break; + + case HDF5: + hrc = H5Soffset_simple(h5dset_space_id, h5offset); + VRFY((hrc >= 0), "H5Soffset_simple"); + /* Read the buffer out */ + hrc = H5Dread(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); + VRFY((hrc >= 0), "H5Dread"); + break; + + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); + HDassert(0 && "Unknown IO type"); + break; + } /* switch (parms->io_type) */ + } + } +done: + return ret_code; +} + +/* + * Function: posix_buffer_read + * Purpose: Read buffer into the POSIX file considering contiguity. + * Return: SUCCESS or FAIL + * Programmer: Christian Chilan, April, 2008 + * Modifications: + */ + +static herr_t +posix_buffer_read(int local_dim, file_descr *fd, parameters *parms, void *buffer) +{ + int ret_code = SUCCESS; + + /* if local dimension is not contiguous, recurse */ + if (local_dim < parms->rank - 1 && local_dim != cont_dim) { + size_t u; + + for (u = 0; u < parms->buf_size[local_dim]; u++) { + buf_offset[local_dim] = u; + ret_code = posix_buffer_read(local_dim + 1, fd, parms, buffer); + if (local_dim + 1 == cont_dim) + break; + } + /* otherwise, perform contiguous POSIX access */ + } + else { + HDoff_t d_offset; + HDoff_t linear_dset_offset = 0; + int i, j, rc; + + buf_offset[local_dim] = 0; + /* determine offset in buffer */ + for (i = 0; i < parms->rank; i++) { + d_offset = 1; + + for (j = i + 1; j < parms->rank; j++) + d_offset *= (HDoff_t)parms->dset_size[j]; + + linear_dset_offset += (offset[i] + (HDoff_t)buf_offset[i]) * d_offset; + } + + /* only care if seek returns error */ + rc = POSIXSEEK(fd->posixfd, linear_dset_offset) < 0 ? -1 : 0; + VRFY((rc == 0), "POSIXSEEK"); + /* check if all bytes are read */ + rc = ((ssize_t)cont_size == POSIXREAD(fd->posixfd, buf_p, cont_size)); + VRFY((rc != 0), "POSIXREAD"); + + /* Advance location in buffer */ + buf_p += cont_size; + } +done: + return ret_code; +} + +/* + * Function: do_fopen + * Purpose: Open the specified file. + * Return: SUCCESS or FAIL + * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 + * Modifications: Support for file drivers, Christian Chilan, April, 2008 + */ +static herr_t +do_fopen(parameters *param, char *fname, file_descr *fd /*out*/, int flags) +{ + int ret_code = SUCCESS; + hid_t fcpl; + + switch (param->io_type) { + case POSIXIO: + if (flags & (SIO_CREATE | SIO_WRITE)) + fd->posixfd = POSIXCREATE(fname); + else + fd->posixfd = POSIXOPEN(fname, O_RDONLY); + + if (fd->posixfd < 0) { + HDfprintf(stderr, "POSIX File Open failed(%s)\n", fname); + GOTOERROR(FAIL); + } + + break; + + case HDF5: + + fapl = set_vfd(param); + + if (fapl < 0) { + HDfprintf(stderr, "HDF5 Property List Create failed\n"); + GOTOERROR(FAIL); + } + + fcpl = H5Pcreate(H5P_FILE_CREATE); + if (param->page_size) { + H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, 0, (hsize_t)1); + H5Pset_file_space_page_size(fcpl, param->page_size); + if (param->page_buffer_size) + H5Pset_page_buffer_size(fapl, param->page_buffer_size, 0, 0); + } + + /* create the parallel file */ + if (flags & (SIO_CREATE | SIO_WRITE)) { + fd->h5fd = H5Fcreate(fname, H5F_ACC_TRUNC, fcpl, fapl); + } + else { + fd->h5fd = H5Fopen(fname, H5F_ACC_RDONLY, fapl); + } + + if (fd->h5fd < 0) { + HDfprintf(stderr, "HDF5 File Create failed(%s)\n", fname); + GOTOERROR(FAIL); + } + break; + + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)param->io_type); + GOTOERROR(FAIL); + break; + } + +done: + return ret_code; +} + +/* + * Function: set_vfd + * Purpose: Sets file driver. + * Return: SUCCESS or FAIL + * Programmer: Christian Chilan, April, 2008 + * Modifications: + */ + +hid_t +set_vfd(parameters *param) +{ + hid_t my_fapl = H5I_INVALID_HID; + vfdtype vfd; + + vfd = param->vfd; + + if ((my_fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) + return -1; + + if (vfd == sec2) { + /* Unix read() and write() system calls */ + if (H5Pset_fapl_sec2(my_fapl) < 0) + return -1; + } + else if (vfd == stdio) { + /* Standard C fread() and fwrite() system calls */ + if (H5Pset_fapl_stdio(my_fapl) < 0) + return -1; + } + else if (vfd == core) { + /* In-core temporary file with 1MB increment */ + if (H5Pset_fapl_core(my_fapl, (size_t)1024 * 1024, TRUE) < 0) + return -1; + } + else if (vfd == split) { + /* Split meta data and raw data each using default driver */ + if (H5Pset_fapl_split(my_fapl, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT) < 0) + return -1; + } + else if (vfd == multi) { + /* Multi-file driver, general case of the split driver */ + H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; + hid_t memb_fapl[H5FD_MEM_NTYPES]; + const char *memb_name[H5FD_MEM_NTYPES]; + char sv[H5FD_MEM_NTYPES][1024]; + haddr_t memb_addr[H5FD_MEM_NTYPES]; + H5FD_mem_t mt; + + HDmemset(memb_map, 0, sizeof memb_map); + HDmemset(memb_fapl, 0, sizeof memb_fapl); + HDmemset(memb_name, 0, sizeof memb_name); + HDmemset(memb_addr, 0, sizeof memb_addr); + + HDassert(HDstrlen(multi_letters) == H5FD_MEM_NTYPES); + for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt++) { + memb_fapl[mt] = H5P_DEFAULT; + HDsprintf(sv[mt], "%%s-%c.h5", multi_letters[mt]); + memb_name[mt] = sv[mt]; + memb_addr[mt] = (haddr_t)MAX(mt - 1, 0) * (HADDR_MAX / 10); + } + + if (H5Pset_fapl_multi(my_fapl, memb_map, memb_fapl, memb_name, memb_addr, FALSE) < 0) { + return -1; + } + } + else if (vfd == family) { + hsize_t fam_size = 1 * 1024 * 1024; /*100 MB*/ + + /* Family of files, each 1MB and using the default driver */ + /* if ((val=HDstrtok(NULL, " \t\n\r"))) + fam_size = (hsize_t)(HDstrtod(val, NULL) * 1024*1024); */ + if (H5Pset_fapl_family(my_fapl, fam_size, H5P_DEFAULT) < 0) + return -1; + } + else if (vfd == direct) { +#ifdef H5_HAVE_DIRECT + /* Linux direct read() and write() system calls. Set memory boundary, file block size, + * and copy buffer size to the default values. */ + if (H5Pset_fapl_direct(my_fapl, 1024, 4096, 8 * 4096) < 0) + return -1; +#endif + } + else { + /* Unknown driver */ + return -1; + } + + return my_fapl; +} + +/* + * Function: do_fclose + * Purpose: Close the specified file descriptor. + * Return: SUCCESS or FAIL + * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 + * Modifications: + */ +static herr_t +do_fclose(iotype iot, file_descr *fd /*out*/) +{ + herr_t ret_code = SUCCESS, hrc; + int rc = 0; + + switch (iot) { + case POSIXIO: + rc = POSIXCLOSE(fd->posixfd); + + if (rc != 0) { + HDfprintf(stderr, "POSIX File Close failed\n"); + GOTOERROR(FAIL); + } + + fd->posixfd = -1; + break; + + case HDF5: + hrc = H5Fclose(fd->h5fd); + + if (hrc < 0) { + HDfprintf(stderr, "HDF5 File Close failed\n"); + GOTOERROR(FAIL); + } + + fd->h5fd = -1; + break; + + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); + GOTOERROR(FAIL); + break; + } + +done: + return ret_code; +} + +/* + * Function: do_cleanupfile + * Purpose: Cleanup temporary file unless HDF5_NOCLEANUP is set. + * Return: void + * Programmer: Albert Cheng 2001/12/12 + * Modifications: Support for file drivers. Christian Chilan, April, 2008 + */ +static void +do_cleanupfile(iotype iot, char *filename) +{ + char temp[2048]; + int j; + hid_t driver; + + if (clean_file_g == -1) + clean_file_g = (HDgetenv("HDF5_NOCLEANUP") == NULL) ? 1 : 0; + + if (clean_file_g) { + + switch (iot) { + case POSIXIO: + HDremove(filename); + break; + + case HDF5: + driver = H5Pget_driver(fapl); + + if (driver == H5FD_FAMILY) { + for (j = 0; /*void*/; j++) { + HDsnprintf(temp, sizeof temp, filename, j); + + if (HDaccess(temp, F_OK) < 0) + break; + + HDremove(temp); + } + } + else if (driver == H5FD_CORE) { + hbool_t backing; /* Whether the core file has backing store */ + + H5Pget_fapl_core(fapl, NULL, &backing); + + /* If the file was stored to disk with bacing store, remove it */ + if (backing) + HDremove(filename); + } + else if (driver == H5FD_MULTI) { + H5FD_mem_t mt; + assert(HDstrlen(multi_letters) == H5FD_MEM_NTYPES); + + for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt++) { + HDsnprintf(temp, sizeof temp, "%s-%c.h5", filename, multi_letters[mt]); + HDremove(temp); /*don't care if it fails*/ + } + } + else { + HDremove(filename); + } + H5Pclose(fapl); + break; + + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); + HDassert(0 && "Unknown IO type"); + break; + } + } +} diff --git a/tools/src/h5perf/sio_perf.c b/tools/src/h5perf/sio_perf.c new file mode 100644 index 0000000..1b200b0 --- /dev/null +++ b/tools/src/h5perf/sio_perf.c @@ -0,0 +1,1301 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Serial HDF5 Performance Testing Code + * -------------------------------------- + * + * Portable code to test performance on the different platforms we support. + * This is what the report should look like: + * + * nprocs = Max#Procs + * IO API = POSIXIO + * # Files = 1, # of dsets = 1000, Elements per dset = 37000 + * Write Results = x MB/s + * Read Results = x MB/s + * # Files = 1, # of dsets = 3000, Elements per dset = 37000 + * Write Results = x MB/s + * Read Results = x MB/s + * + * . . . + * + * + * IO API = HDF5 + * # Files = 1, # of dsets = 1000, Elements per dset = 37000 + * Write Results = x MB/s + * Read Results = x MB/s + * # Files = 1, # of dsets = 3000, Elements per dset = 37000 + * Write Results = x MB/s + * Read Results = x MB/s + * + * . . . + * + * + * . . . + * + */ + +/* system header files */ +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> + +#include "hdf5.h" + +/* our header files */ +#include "sio_perf.h" + +/* useful macros */ +#define TAB_SPACE 4 + +#define ONE_KB 1024 +#define ONE_MB (ONE_KB * ONE_KB) +#define ONE_GB (ONE_MB * ONE_KB) + +#define SIO_POSIX 0x1 +#define SIO_HDF5 0x4 + +/* report 0.0 in case t is zero too */ +#define MB_PER_SEC(bytes, t) (H5_DBL_ABS_EQUAL(t, 0.0) ? 0.0 : ((((double)(bytes)) / (double)ONE_MB) / (t))) + +#ifndef TRUE +#define TRUE 1 +#endif /* TRUE */ +#ifndef FALSE +#define FALSE (!TRUE) +#endif /* FALSE */ + +/* global variables */ +FILE *output; /* output file */ +int sio_debug_level = 0; /* The debug level: + * 0 - Off + * 1 - Minimal + * 2 - Some more + * 3 - Maximal + * 4 - Maximal & then some + */ + +/* local variables */ +static const char *progname = "h5perf_serial"; + +/* + * Command-line options: The user can specify short or long-named + * parameters. The long-named ones can be partially spelled. When + * adding more, make sure that they don't clash with each other. + */ + +/* + * It seems that only the options that accept additional information + * such as dataset size (-e) require the colon next to it. + */ +static const char * s_opts = "a:A:B:c:Cd:D:e:F:ghi:Imno:p:P:r:stT:v:wx:X:"; +static struct h5_long_options l_opts[] = {{"align", require_arg, 'a'}, + {"api", require_arg, 'A'}, +#if 0 + /* a sighting of the elusive binary option */ + { "binary", no_arg, 'b' }, +#endif /* 0 */ + {"block-size", require_arg, 'B'}, + {"chunk", no_arg, 'c'}, + {"collective", no_arg, 'C'}, + {"debug", require_arg, 'D'}, + {"file-driver", require_arg, 'v'}, + {"geometry", no_arg, 'g'}, + {"help", no_arg, 'h'}, + {"interleaved", require_arg, 'I'}, + {"max-num-processes", require_arg, 'P'}, + {"min-num-processes", require_arg, 'p'}, + {"max-xfer-size", require_arg, 'X'}, + {"min-xfer-size", require_arg, 'x'}, + {"num-bytes", require_arg, 'e'}, + {"num-dsets", require_arg, 'd'}, + {"num-files", require_arg, 'F'}, + {"num-iterations", require_arg, 'i'}, + {"order", require_arg, 'r'}, + {"output", require_arg, 'o'}, + {"extendable", no_arg, 't'}, + {"threshold", require_arg, 'T'}, + {"write-only", require_arg, 'w'}, + {NULL, 0, '\0'}}; + +struct options { + long io_types; /* bitmask of which I/O types to test */ + const char *output_file; /* file to print report to */ + long num_dsets; /* number of datasets */ + long num_files; /* number of files */ + off_t num_bpp; /* number of bytes per proc per dset */ + int num_iters; /* number of iterations */ + hsize_t dset_size[MAX_DIMS]; /* Dataset size */ + size_t buf_size[MAX_DIMS]; /* Buffer size */ + size_t chk_size[MAX_DIMS]; /* Chunk size */ + int order[MAX_DIMS]; /* Dimension access order */ + int dset_rank; /* Rank */ + int buf_rank; /* Rank */ + int order_rank; /* Rank */ + int chk_rank; /* Rank */ + int print_times; /* print times as well as throughputs */ + int print_raw; /* print raw data throughput info */ + hsize_t h5_alignment; /* alignment in HDF5 file */ + hsize_t h5_threshold; /* threshold for alignment in HDF5 file */ + int h5_use_chunks; /* Make HDF5 dataset chunked */ + int h5_write_only; /* Perform the write tests only */ + int h5_extendable; /* Perform the write tests only */ + int verify; /* Verify data correctness */ + vfdtype vfd; /* File driver */ + size_t page_buffer_size; + size_t page_size; +}; + +typedef struct { + double min; + double max; + double sum; + int num; +} minmax; + +/* local functions */ +static hsize_t parse_size_directive(const char *size); +static struct options *parse_command_line(int argc, const char *argv[]); +static void run_test_loop(struct options *options); +static int run_test(iotype iot, parameters parms, struct options *opts); +static void output_all_info(minmax *mm, int count, int indent_level); +static void get_minmax(minmax *mm, double val); +static void accumulate_minmax_stuff(const minmax *mm, int count, minmax *total_mm); +static void output_results(const struct options *options, const char *name, minmax *table, int table_size, + off_t data_size); +static void output_report(const char *fmt, ...); +static void print_indent(register int indent); +static void usage(const char *prog); +static void report_parameters(struct options *opts); + +/* + * Function: main + * Purpose: Start things up. + * Return: EXIT_SUCCESS or EXIT_FAILURE + * Programmer: Bill Wendling, 30. October 2001 + * Modifications: + */ +int +main(int argc, const char *argv[]) +{ + int exit_value = EXIT_SUCCESS; + struct options *opts = NULL; + +#ifndef STANDALONE + /* Initialize h5tools lib */ + h5tools_init(); +#endif + + output = stdout; + + opts = parse_command_line(argc, argv); + + if (!opts) { + exit_value = EXIT_FAILURE; + goto finish; + } + + if (opts->output_file) { + if ((output = HDfopen(opts->output_file, "w")) == NULL) { + HDfprintf(stderr, "%s: cannot open output file\n", progname); + HDperror(opts->output_file); + goto finish; + } + } + + report_parameters(opts); + + run_test_loop(opts); + +finish: + HDfree(opts); + return exit_value; +} + +/* + * Function: run_test_loop + * Purpose: Run the I/O tests. Write the results to OUTPUT. + * + * - The slowest changing part of the test is the number of + * processors to use. For each loop iteration, we divide that + * number by 2 and rerun the test. + * + * - The second slowest is what type of IO API to perform. We have + * three choices: POSIXIO, and HDF5. + * + * - Then we change the size of the buffer. This information is + * inferred from the number of datasets to create and the number + * of integers to put into each dataset. The backend code figures + * this out. + * + * Return: Nothing + * Programmer: Bill Wendling, 30. October 2001 + * Modifications: + * Added multidimensional testing (Christian Chilan, April, 2008) + */ +static void +run_test_loop(struct options *opts) +{ + parameters parms; + int i; + size_t buf_bytes; + + /* load options into parameter structure */ + parms.num_files = opts->num_files; + parms.num_dsets = opts->num_dsets; + parms.num_iters = opts->num_iters; + parms.rank = opts->dset_rank; + parms.h5_align = opts->h5_alignment; + parms.h5_thresh = opts->h5_threshold; + parms.h5_use_chunks = opts->h5_use_chunks; + parms.h5_extendable = opts->h5_extendable; + parms.h5_write_only = opts->h5_write_only; + parms.verify = opts->verify; + parms.vfd = opts->vfd; + parms.page_buffer_size = opts->page_buffer_size; + parms.page_size = opts->page_size; + + /* load multidimensional options */ + parms.num_bytes = 1; + buf_bytes = 1; + for (i = 0; i < parms.rank; i++) { + parms.buf_size[i] = opts->buf_size[i]; + parms.dset_size[i] = opts->dset_size[i]; + parms.chk_size[i] = opts->chk_size[i]; + parms.order[i] = opts->order[i]; + parms.num_bytes *= opts->dset_size[i]; + buf_bytes *= opts->buf_size[i]; + } + + /* print size information */ + output_report("Transfer Buffer Size (bytes): %d\n", buf_bytes); + output_report("File Size(MB): %.2f\n", ((double)parms.num_bytes) / ONE_MB); + + print_indent(0); + if (opts->io_types & SIO_POSIX) + run_test(POSIXIO, parms, opts); + + print_indent(0); + if (opts->io_types & SIO_HDF5) + run_test(HDF5, parms, opts); +} + +/* + * Function: run_test + * Purpose: Inner loop call to actually run the I/O test. + * Return: Nothing + * Programmer: Bill Wendling, 18. December 2001 + * Modifications: + */ +static int +run_test(iotype iot, parameters parms, struct options *opts) +{ + results res; + register int i, ret_value = SUCCESS; + off_t raw_size; + minmax * write_sys_mm_table = NULL; + minmax * write_mm_table = NULL; + minmax * write_gross_mm_table = NULL; + minmax * write_raw_mm_table = NULL; + minmax * read_sys_mm_table = NULL; + minmax * read_mm_table = NULL; + minmax * read_gross_mm_table = NULL; + minmax * read_raw_mm_table = NULL; + minmax write_sys_mm = {0.0F, 0.0F, 0.0F, 0}; + minmax write_mm = {0.0F, 0.0F, 0.0F, 0}; + minmax write_gross_mm = {0.0F, 0.0F, 0.0F, 0}; + minmax write_raw_mm = {0.0F, 0.0F, 0.0F, 0}; + minmax read_sys_mm = {0.0F, 0.0F, 0.0F, 0}; + minmax read_mm = {0.0F, 0.0F, 0.0F, 0}; + minmax read_gross_mm = {0.0F, 0.0F, 0.0F, 0}; + minmax read_raw_mm = {0.0F, 0.0F, 0.0F, 0}; + + raw_size = (off_t)parms.num_bytes; + parms.io_type = iot; + print_indent(2); + output_report("IO API = "); + + switch (iot) { + case POSIXIO: + output_report("POSIX\n"); + break; + case HDF5: + output_report("HDF5\n"); + break; + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); + HDassert(0 && "Unknown IO tpe"); + break; + } + + /* allocate space for tables minmax and that it is sufficient */ + /* to initialize all elements to zeros by calloc. */ + write_sys_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); + write_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); + write_gross_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); + write_raw_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); + + if (!parms.h5_write_only) { + read_sys_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); + read_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); + read_gross_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); + read_raw_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); + } + + /* Do IO iteration times, collecting statistics each time */ + for (i = 0; i < parms.num_iters; ++i) { + double t; + + do_sio(parms, &res); + + /* gather all of the "sys write" times */ + t = io_time_get(res.timers, HDF5_MPI_WRITE); + get_minmax(&write_sys_mm, t); + + write_sys_mm_table[i] = write_sys_mm; + + /* gather all of the "write" times */ + t = io_time_get(res.timers, HDF5_FINE_WRITE_FIXED_DIMS); + get_minmax(&write_mm, t); + + write_mm_table[i] = write_mm; + + /* gather all of the "write" times from open to close */ + t = io_time_get(res.timers, HDF5_GROSS_WRITE_FIXED_DIMS); + get_minmax(&write_gross_mm, t); + + write_gross_mm_table[i] = write_gross_mm; + + /* gather all of the raw "write" times */ + t = io_time_get(res.timers, HDF5_RAW_WRITE_FIXED_DIMS); + get_minmax(&write_raw_mm, t); + + write_raw_mm_table[i] = write_raw_mm; + + if (!parms.h5_write_only) { + /* gather all of the "mpi read" times */ + t = io_time_get(res.timers, HDF5_MPI_READ); + get_minmax(&read_sys_mm, t); + + read_sys_mm_table[i] = read_sys_mm; + + /* gather all of the "read" times */ + t = io_time_get(res.timers, HDF5_FINE_READ_FIXED_DIMS); + get_minmax(&read_mm, t); + + read_mm_table[i] = read_mm; + + /* gather all of the "read" times from open to close */ + t = io_time_get(res.timers, HDF5_GROSS_READ_FIXED_DIMS); + get_minmax(&read_gross_mm, t); + + read_gross_mm_table[i] = read_gross_mm; + + /* gather all of the raw "read" times */ + t = io_time_get(res.timers, HDF5_RAW_READ_FIXED_DIMS); + get_minmax(&read_raw_mm, t); + + read_raw_mm_table[i] = read_gross_mm; + } + io_time_destroy(res.timers); + } + + /* + * Show various statistics + */ + /* Write statistics */ + /* Print the raw data throughput if desired */ + if (opts->print_raw) { + /* accumulate and output the max, min, and average "raw write" times */ + if (sio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Raw Data Write details:\n"); + output_all_info(write_raw_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Raw Data Write", write_raw_mm_table, parms.num_iters, raw_size); + } /* end if */ + + /* show sys write statics */ +#if 0 + if (sio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("MPI Write details:\n"); + output_all_info(write_sys_mm_table, parms.num_iters, 4); + } +#endif + /* We don't currently output the MPI write results */ + + /* accumulate and output the max, min, and average "write" times */ + if (sio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Write details:\n"); + output_all_info(write_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Write", write_mm_table, parms.num_iters, raw_size); + + /* accumulate and output the max, min, and average "gross write" times */ + if (sio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Write Open-Close details:\n"); + output_all_info(write_gross_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Write Open-Close", write_gross_mm_table, parms.num_iters, raw_size); + + if (!parms.h5_write_only) { + /* Read statistics */ + /* Print the raw data throughput if desired */ + if (opts->print_raw) { + /* accumulate and output the max, min, and average "raw read" times */ + if (sio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Raw Data Read details:\n"); + output_all_info(read_raw_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Raw Data Read", read_raw_mm_table, parms.num_iters, raw_size); + } /* end if */ + + /* show mpi read statics */ +#if 0 + if (sio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("MPI Read details:\n"); + output_all_info(read_sys_mm_table, parms.num_iters, 4); + } +#endif + /* We don't currently output the MPI read results */ + + /* accumulate and output the max, min, and average "read" times */ + if (sio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Read details:\n"); + output_all_info(read_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Read", read_mm_table, parms.num_iters, raw_size); + + /* accumulate and output the max, min, and average "gross read" times */ + if (sio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Read Open-Close details:\n"); + output_all_info(read_gross_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Read Open-Close", read_gross_mm_table, parms.num_iters, raw_size); + } + + /* clean up our mess */ + HDfree(write_sys_mm_table); + HDfree(write_mm_table); + HDfree(write_gross_mm_table); + HDfree(write_raw_mm_table); + + if (!parms.h5_write_only) { + HDfree(read_sys_mm_table); + HDfree(read_mm_table); + HDfree(read_gross_mm_table); + HDfree(read_raw_mm_table); + } + + return ret_value; +} + +/* + * Function: output_all_info + * Purpose: + * Return: Nothing + * Programmer: Bill Wendling, 29. January 2002 + * Modifications: + */ +static void +output_all_info(minmax *mm, int count, int indent_level) +{ + int i; + + for (i = 0; i < count; ++i) { + print_indent(indent_level); + output_report("Iteration %d:\n", i + 1); + print_indent(indent_level + 1); + output_report("Minimum Time: %.2fs\n", mm[i].min); + print_indent(indent_level + 1); + output_report("Maximum Time: %.2fs\n", mm[i].max); + } +} + +/* + * Function: get_minmax + * Purpose: Gather all the min, max and total of val. + * Return: Nothing + * Programmer: Bill Wendling, 21. December 2001 + * Modifications: + * Use MPI_Allreduce to do it. -akc, 2002/01/11 + */ + +static void +get_minmax(minmax *mm, double val) +{ + mm->max = val; + mm->min = val; + mm->sum = val; +} + +/* + * Function: accumulate_minmax_stuff + * Purpose: Accumulate the minimum, maximum, and average of the times + * across all processes. + * Return: TOTAL_MM - the total of all of these. + * Programmer: Bill Wendling, 21. December 2001 + * Modifications: + * Changed to use seconds instead of MB/s - QAK, 5/9/02 + */ +static void +accumulate_minmax_stuff(const minmax *mm, int count, minmax *total_mm) +{ + int i; + + total_mm->sum = 0.0F; + total_mm->max = -DBL_MAX; + total_mm->min = DBL_MAX; + total_mm->num = count; + + for (i = 0; i < count; ++i) { + double m = mm[i].max; + + total_mm->sum += m; + + if (m < total_mm->min) + total_mm->min = m; + + if (m > total_mm->max) + total_mm->max = m; + } +} + +/* + * Function: output_results + * Purpose: Print information about the time & bandwidth for a given + * minmax & # of iterations. + * Return: Nothing + * Programmer: Quincey Koziol, 9. May 2002 + * Modifications: + */ +static void +output_results(const struct options *opts, const char *name, minmax *table, int table_size, off_t data_size) +{ + minmax total_mm; + + accumulate_minmax_stuff(table, table_size, &total_mm); + + print_indent(3); + output_report("%s (%d iteration(s)):\n", name, table_size); + + /* Note: The maximum throughput uses the minimum amount of time & vice versa */ + + print_indent(4); + output_report("Maximum Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.min)); + if (opts->print_times) + output_report(" (%7.3f s)\n", total_mm.min); + else + output_report("\n"); + + print_indent(4); + output_report("Average Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.sum / total_mm.num)); + if (opts->print_times) + output_report(" (%7.3f s)\n", (total_mm.sum / total_mm.num)); + else + output_report("\n"); + + print_indent(4); + output_report("Minimum Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.max)); + if (opts->print_times) + output_report(" (%7.3f s)\n", total_mm.max); + else + output_report("\n"); +} + +/* + * Function: output_report + * Purpose: Print a line of the report. Only do so if I'm the 0 process. + * Return: Nothing + * Programmer: Bill Wendling, 19. December 2001 + * Modifications: + */ +static void +output_report(const char *fmt, ...) +{ + va_list ap; + + HDva_start(ap, fmt); + HDvfprintf(output, fmt, ap); + HDva_end(ap); +} + +/* + * Function: print_indent + * Purpose: Print spaces to indent a new line of text for pretty printing + * things. + * Return: Nothing + * Programmer: Bill Wendling, 29. October 2001 + * Modifications: + */ +static void +print_indent(register int indent) +{ + indent *= TAB_SPACE; + + for (; indent > 0; --indent) + HDfputc(' ', output); +} + +static void +recover_size_and_print(long long val, const char *end) +{ + if (val >= ONE_KB && (val % ONE_KB) == 0) { + if (val >= ONE_MB && (val % ONE_MB) == 0) { + if (val >= ONE_GB && (val % ONE_GB) == 0) + HDfprintf(output, + "%" H5_PRINTF_LL_WIDTH "d" + "GB%s", + val / ONE_GB, end); + else + HDfprintf(output, + "%" H5_PRINTF_LL_WIDTH "d" + "MB%s", + val / ONE_MB, end); + } + else { + HDfprintf(output, + "%" H5_PRINTF_LL_WIDTH "d" + "KB%s", + val / ONE_KB, end); + } + } + else { + HDfprintf(output, + "%" H5_PRINTF_LL_WIDTH "d" + "%s", + val, end); + } +} + +static void +print_io_api(long io_types) +{ + if (io_types & SIO_POSIX) + HDfprintf(output, "posix "); + if (io_types & SIO_HDF5) + HDfprintf(output, "hdf5 "); + HDfprintf(output, "\n"); +} + +static void +report_parameters(struct options *opts) +{ + int i, rank; + rank = opts->dset_rank; + + print_version("HDF5 Library"); /* print library version */ + HDfprintf(output, "==== Parameters ====\n"); + + HDfprintf(output, "IO API="); + print_io_api(opts->io_types); + + HDfprintf(output, "Number of iterations=%d\n", opts->num_iters); + + HDfprintf(output, "Dataset size="); + + for (i = 0; i < rank; i++) + recover_size_and_print((long long)opts->dset_size[i], " "); + HDfprintf(output, "\n"); + + HDfprintf(output, "Transfer buffer size="); + for (i = 0; i < rank; i++) + recover_size_and_print((long long)opts->buf_size[i], " "); + HDfprintf(output, "\n"); + + if (opts->page_size) { + HDfprintf(output, "Page Aggregation Enabled. Page size = %zu\n", opts->page_size); + if (opts->page_buffer_size) + HDfprintf(output, "Page Buffering Enabled. Page Buffer size = %zu\n", opts->page_buffer_size); + else + HDfprintf(output, "Page Buffering Disabled\n"); + } + else + HDfprintf(output, "Page Aggregation Disabled\n"); + + HDfprintf(output, "Dimension access order="); + for (i = 0; i < rank; i++) + recover_size_and_print((long long)opts->order[i], " "); + HDfprintf(output, "\n"); + + if (opts->io_types & SIO_HDF5) { + + HDfprintf(output, "HDF5 data storage method="); + + if (opts->h5_use_chunks) { + + HDfprintf(output, "Chunked\n"); + HDfprintf(output, "HDF5 chunk size="); + for (i = 0; i < rank; i++) + recover_size_and_print((long long)opts->chk_size[i], " "); + HDfprintf(output, "\n"); + + HDfprintf(output, "HDF5 dataset dimensions="); + if (opts->h5_extendable) { + HDfprintf(output, "Extendable\n"); + } + else { + HDfprintf(output, "Fixed\n"); + } + } + else { + HDfprintf(output, "Contiguous\n"); + } + + HDfprintf(output, "HDF5 file driver="); + if (opts->vfd == sec2) { + HDfprintf(output, "sec2\n"); + } + else if (opts->vfd == stdio) { + HDfprintf(output, "stdio\n"); + } + else if (opts->vfd == core) { + HDfprintf(output, "core\n"); + } + else if (opts->vfd == split) { + HDfprintf(output, "split\n"); + } + else if (opts->vfd == multi) { + HDfprintf(output, "multi\n"); + } + else if (opts->vfd == family) { + HDfprintf(output, "family\n"); + } + else if (opts->vfd == direct) { + HDfprintf(output, "direct\n"); + } + } + + { + char *prefix = HDgetenv("HDF5_PREFIX"); + + HDfprintf(output, "Env HDF5_PREFIX=%s\n", (prefix ? prefix : "not set")); + } + + HDfprintf(output, "==== End of Parameters ====\n"); + HDfprintf(output, "\n"); +} + +/* + * Function: parse_command_line + * Purpose: Parse the command line options and return a STRUCT OPTIONS + * structure which will need to be freed by the calling function. + * Return: Pointer to an OPTIONS structure + * Programmer: Bill Wendling, 31. October 2001 + * Modifications: + * Added multidimensional testing (Christian Chilan, April, 2008) + */ +static struct options * +parse_command_line(int argc, const char *argv[]) +{ + int opt; + struct options *cl_opts; + int i, default_rank, actual_rank, ranks[4]; + + cl_opts = (struct options *)HDmalloc(sizeof(struct options)); + + cl_opts->page_buffer_size = 0; + cl_opts->page_size = 0; + + cl_opts->output_file = NULL; + cl_opts->io_types = 0; /* will set default after parsing options */ + cl_opts->num_iters = 1; + + default_rank = 2; + + cl_opts->dset_rank = 0; + cl_opts->buf_rank = 0; + cl_opts->chk_rank = 0; + cl_opts->order_rank = 0; + + for (i = 0; i < MAX_DIMS; i++) { + cl_opts->buf_size[i] = (size_t)((i + 1) * 10); + cl_opts->dset_size[i] = (hsize_t)((i + 1) * 100); + cl_opts->chk_size[i] = (size_t)((i + 1) * 10); + cl_opts->order[i] = i + 1; + } + + cl_opts->vfd = sec2; + + cl_opts->print_times = FALSE; /* Printing times is off by default */ + cl_opts->print_raw = FALSE; /* Printing raw data throughput is off by default */ + cl_opts->h5_alignment = 1; /* No alignment for HDF5 objects by default */ + cl_opts->h5_threshold = 1; /* No threshold for aligning HDF5 objects by default */ + cl_opts->h5_use_chunks = FALSE; /* Don't chunk the HDF5 dataset by default */ + cl_opts->h5_write_only = FALSE; /* Do both read and write by default */ + cl_opts->h5_extendable = FALSE; /* Use extendable dataset */ + cl_opts->verify = FALSE; /* No Verify data correctness by default */ + + while ((opt = H5_get_option(argc, argv, s_opts, l_opts)) != EOF) { + switch ((char)opt) { + case 'a': + cl_opts->h5_alignment = parse_size_directive(H5_optarg); + break; + case 'G': + cl_opts->page_size = parse_size_directive(H5_optarg); + break; + case 'b': + cl_opts->page_buffer_size = parse_size_directive(H5_optarg); + break; + case 'A': { + const char *end = H5_optarg; + while (end && *end != '\0') { + char buf[10]; + + HDmemset(buf, '\0', sizeof(buf)); + + for (i = 0; *end != '\0' && *end != ','; ++end) + if (HDisalnum(*end) && i < 10) + buf[i++] = *end; + + if (!HDstrcasecmp(buf, "hdf5")) { + cl_opts->io_types |= SIO_HDF5; + } + else if (!HDstrcasecmp(buf, "posix")) { + cl_opts->io_types |= SIO_POSIX; + } + else { + HDfprintf(stderr, "sio_perf: invalid --api option %s\n", buf); + HDexit(EXIT_FAILURE); + } + + if (*end == '\0') + break; + + end++; + } + } + + break; +#if 0 + case 'b': + /* the future "binary" option */ + break; +#endif /* 0 */ + case 'c': + /* Turn on chunked HDF5 dataset creation */ + cl_opts->h5_use_chunks = 1; + { + const char *end = H5_optarg; + int j = 0; + + while (end && *end != '\0') { + char buf[10]; + + HDmemset(buf, '\0', sizeof(buf)); + + for (i = 0; *end != '\0' && *end != ','; ++end) + if (HDisalnum(*end) && i < 10) + buf[i++] = *end; + + cl_opts->chk_size[j] = parse_size_directive(buf); + + j++; + + if (*end == '\0') + break; + + end++; + } + cl_opts->chk_rank = j; + } + + break; + + case 'D': { + const char *end = H5_optarg; + + while (end && *end != '\0') { + char buf[10]; + + HDmemset(buf, '\0', sizeof(buf)); + + for (i = 0; *end != '\0' && *end != ','; ++end) + if (HDisalnum(*end) && i < 10) + buf[i++] = *end; + + if (HDstrlen(buf) > 1 || HDisdigit(buf[0])) { + size_t j; + + for (j = 0; j < 10 && buf[j] != '\0'; ++j) + if (!HDisdigit(buf[j])) { + HDfprintf(stderr, "sio_perf: invalid --debug option %s\n", buf); + HDexit(EXIT_FAILURE); + } + + sio_debug_level = atoi(buf); + + if (sio_debug_level > 4) + sio_debug_level = 4; + else if (sio_debug_level < 0) + sio_debug_level = 0; + } + else { + switch (*buf) { + case 'r': + /* Turn on raw data throughput info */ + cl_opts->print_raw = TRUE; + break; + case 't': + /* Turn on time printing */ + cl_opts->print_times = TRUE; + break; + case 'v': + /* Turn on verify data correctness*/ + cl_opts->verify = TRUE; + break; + default: + HDfprintf(stderr, "sio_perf: invalid --debug option %s\n", buf); + HDexit(EXIT_FAILURE); + } + } + + if (*end == '\0') + break; + + end++; + } + } + + break; + case 'e': { + const char *end = H5_optarg; + int j = 0; + + while (end && *end != '\0') { + char buf[10]; + + HDmemset(buf, '\0', sizeof(buf)); + + for (i = 0; *end != '\0' && *end != ','; ++end) + if (HDisalnum(*end) && i < 10) + buf[i++] = *end; + + cl_opts->dset_size[j] = parse_size_directive(buf); + + j++; + + if (*end == '\0') + break; + + end++; + } + cl_opts->dset_rank = j; + } + + break; + + case 'i': + cl_opts->num_iters = HDatoi(H5_optarg); + break; + case 'o': + cl_opts->output_file = H5_optarg; + break; + case 'T': + cl_opts->h5_threshold = parse_size_directive(H5_optarg); + break; + case 'v': + if (!HDstrcasecmp(H5_optarg, "sec2")) { + cl_opts->vfd = sec2; + } + else if (!HDstrcasecmp(H5_optarg, "stdio")) { + cl_opts->vfd = stdio; + } + else if (!HDstrcasecmp(H5_optarg, "core")) { + cl_opts->vfd = core; + } + else if (!HDstrcasecmp(H5_optarg, "split")) { + cl_opts->vfd = split; + } + else if (!HDstrcasecmp(H5_optarg, "multi")) { + cl_opts->vfd = multi; + } + else if (!HDstrcasecmp(H5_optarg, "family")) { + cl_opts->vfd = family; + } + else if (!HDstrcasecmp(H5_optarg, "direct")) { + cl_opts->vfd = direct; + } + else { + HDfprintf(stderr, "sio_perf: invalid --api option %s\n", H5_optarg); + HDexit(EXIT_FAILURE); + } + break; + case 'w': + cl_opts->h5_write_only = TRUE; + break; + case 't': + cl_opts->h5_extendable = TRUE; + break; + case 'x': { + const char *end = H5_optarg; + int j = 0; + + while (end && *end != '\0') { + char buf[10]; + + HDmemset(buf, '\0', sizeof(buf)); + + for (i = 0; *end != '\0' && *end != ','; ++end) + if (HDisalnum(*end) && i < 10) + buf[i++] = *end; + + cl_opts->buf_size[j] = parse_size_directive(buf); + + j++; + + if (*end == '\0') + break; + + end++; + } + cl_opts->buf_rank = j; + } + + break; + + case 'r': { + const char *end = H5_optarg; + int j = 0; + + while (end && *end != '\0') { + char buf[10]; + + HDmemset(buf, '\0', sizeof(buf)); + + for (i = 0; *end != '\0' && *end != ','; ++end) + if (HDisalnum(*end) && i < 10) + buf[i++] = *end; + + cl_opts->order[j] = (int)parse_size_directive(buf); + + j++; + + if (*end == '\0') + break; + + end++; + } + + cl_opts->order_rank = j; + } + + break; + + case 'h': + case '?': + default: + usage(progname); + HDfree(cl_opts); + return NULL; + } + } + + /* perform rank consistency analysis */ + actual_rank = 0; + + ranks[0] = cl_opts->dset_rank; + ranks[1] = cl_opts->buf_rank; + ranks[2] = cl_opts->order_rank; + ranks[3] = cl_opts->chk_rank; + + for (i = 0; i < 4; i++) { + if (ranks[i] > 0) { + if (!actual_rank) { + actual_rank = ranks[i]; + } + else { + if (actual_rank != ranks[i]) + exit(EXIT_FAILURE); + } + } + } + + if (!actual_rank) + actual_rank = default_rank; + + cl_opts->dset_rank = actual_rank; + cl_opts->buf_rank = actual_rank; + cl_opts->order_rank = actual_rank; + cl_opts->chk_rank = actual_rank; + + for (i = 0; i < actual_rank; i++) { + if (cl_opts->order[i] > actual_rank) { + exit(EXIT_FAILURE); + } + } + + /* set default if none specified yet */ + if (!cl_opts->io_types) + cl_opts->io_types = SIO_HDF5 | SIO_POSIX; /* run all API */ + + /* verify parameters sanity. Adjust if needed. */ + /* cap xfer_size with bytes per process */ + if (cl_opts->num_iters <= 0) + cl_opts->num_iters = 1; + + return cl_opts; +} + +/* + * Function: parse_size_directive + * Purpose: Parse the size directive passed on the commandline. The size + * directive is an integer followed by a size indicator: + * + * K, k - Kilobyte + * M, m - Megabyte + * G, g - Gigabyte + * + * Return: The size as a off_t because this is related to file size. + * If an unknown size indicator is used, then the program will + * exit with EXIT_FAILURE as the return value. + * Programmer: Bill Wendling, 18. December 2001 + * Modifications: + */ + +static hsize_t +parse_size_directive(const char *size) +{ + hsize_t s; + char * endptr; + + s = HDstrtoull(size, &endptr, 10); + + if (endptr && *endptr) { + while (*endptr != '\0' && (*endptr == ' ' || *endptr == '\t')) + ++endptr; + + switch (*endptr) { + case 'K': + case 'k': + s *= ONE_KB; + break; + + case 'M': + case 'm': + s *= ONE_MB; + break; + + case 'G': + case 'g': + s *= ONE_GB; + break; + + default: + HDfprintf(stderr, "Illegal size specifier '%c'\n", *endptr); + HDexit(EXIT_FAILURE); + } + } + + return s; +} + +/* + * Function: usage + * Purpose: Print a usage message and then exit. + * Return: Nothing + * Programmer: Bill Wendling, 31. October 2001 + * Modifications: + */ +static void +usage(const char *prog) +{ + print_version(prog); + HDprintf("usage: %s [OPTIONS]\n", prog); + HDprintf(" OPTIONS\n"); + HDprintf(" -h Print an usage message and exit\n"); + HDprintf(" -A AL Which APIs to test\n"); + HDprintf(" [default: all of them]\n"); + HDprintf(" -c SL Selects chunked storage and defines chunks dimensions\n"); + HDprintf(" and sizes\n"); + HDprintf(" [default: Off]\n"); + HDprintf(" -e SL Dimensions and sizes of dataset\n"); + HDprintf(" [default: 100,200]\n"); + HDprintf(" -i N Number of iterations to perform\n"); + HDprintf(" [default: 1]\n"); + HDprintf(" -r NL Dimension access order (see below for description)\n"); + HDprintf(" [default: 1,2]\n"); + HDprintf(" -t Selects extendable dimensions for HDF5 dataset\n"); + HDprintf(" [default: Off]\n"); + HDprintf(" -v VFD Selects file driver for HDF5 access\n"); + HDprintf(" [default: sec2]\n"); + HDprintf(" -w Perform write tests, not the read tests\n"); + HDprintf(" [default: Off]\n"); + HDprintf(" -x SL Dimensions and sizes of the transfer buffer\n"); + HDprintf(" [default: 10,20]\n"); + HDprintf("\n"); + HDprintf(" N - is an integer > 0.\n"); + HDprintf("\n"); + HDprintf(" S - is a size specifier, an integer > 0 followed by a size indicator:\n"); + HDprintf(" K - Kilobyte (%d)\n", ONE_KB); + HDprintf(" M - Megabyte (%d)\n", ONE_MB); + HDprintf(" G - Gigabyte (%d)\n", ONE_GB); + HDprintf("\n"); + HDprintf(" Example: '37M' is 37 megabytes or %d bytes\n", 37 * ONE_MB); + HDprintf("\n"); + HDprintf(" AL - is an API list. Valid values are:\n"); + HDprintf(" hdf5 - HDF5\n"); + HDprintf(" posix - POSIX\n"); + HDprintf("\n"); + HDprintf(" Example: -A posix,hdf5\n"); + HDprintf("\n"); + HDprintf(" NL - is list of integers (N) separated by commas.\n"); + HDprintf("\n"); + HDprintf(" Example: 1,2,3\n"); + HDprintf("\n"); + HDprintf(" SL - is list of size specifiers (S) separated by commas.\n"); + HDprintf("\n"); + HDprintf(" Example: 2K,2K,3K\n"); + HDprintf("\n"); + HDprintf(" The example defines an object (dataset, tranfer buffer) with three\n"); + HDprintf(" dimensions. Be aware that as the number of dimensions increases, the\n"); + HDprintf(" the total size of the object increases exponentially.\n"); + HDprintf("\n"); + HDprintf(" VFD - is an HDF5 file driver specifier. Valid values are:\n"); + HDprintf(" sec2, stdio, core, split, multi, family, direct\n"); + HDprintf("\n"); + HDprintf(" Dimension access order:\n"); + HDprintf(" Data access starts at the cardinal origin of the dataset using the\n"); + HDprintf(" transfer buffer. The next access occurs on a dataset region next to\n"); + HDprintf(" the previous one. For a multidimensional dataset, there are several\n"); + HDprintf(" directions as to where to proceed. This can be specified in the dimension\n"); + HDprintf(" access order. For example, -r 1,2 states that the tool should traverse\n"); + HDprintf(" dimension 1 first, and then dimension 2.\n"); + HDprintf("\n"); + HDprintf(" Environment variables:\n"); + HDprintf(" HDF5_NOCLEANUP Do not remove data files if set [default remove]\n"); + HDprintf(" HDF5_PREFIX Data file prefix\n"); + HDprintf("\n"); + HDfflush(stdout); +} /* end usage() */ diff --git a/tools/src/h5perf/sio_perf.h b/tools/src/h5perf/sio_perf.h new file mode 100644 index 0000000..d998377 --- /dev/null +++ b/tools/src/h5perf/sio_perf.h @@ -0,0 +1,104 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef SIO_PERF_H +#define SIO_PERF_H + +#ifndef STANDALONE +#include "io_timer.h" +#include "H5private.h" +#include "h5tools.h" +#include "h5tools_utils.h" +#else +#include "io_timer.h" +#include "sio_standalone.h" +#endif + +/* setup the dataset no fill option if this is v1.5 or more */ +#if H5_VERS_MAJOR > 1 || H5_VERS_MINOR > 4 +#define H5_HAVE_NOFILL 1 +#endif + +#define MAX_DIMS 32 + +typedef enum iotype_ { + POSIXIO, + HDF5 + /*NUM_TYPES*/ +} iotype; + +typedef enum vfdtype_ { + sec2, + stdio, + core, + split, + multi, + family, + direct + /*NUM_TYPES*/ +} vfdtype; + +typedef struct parameters_ { + iotype io_type; /* The type of IO test to perform */ + vfdtype vfd; + long num_files; /* Number of files to create */ + long num_dsets; /* Number of datasets to create */ + hsize_t num_bytes; /* Number of bytes in each dset */ + int num_iters; /* Number of times to loop doing the IO */ + int rank; /* Rank of dataset */ + hsize_t dset_size[MAX_DIMS]; /* Dataset size */ + size_t buf_size[MAX_DIMS]; /* Buffer size */ + size_t chk_size[MAX_DIMS]; /* Chunk size */ + int order[MAX_DIMS]; /* Buffer size */ + hsize_t h5_align; /* HDF5 object alignment */ + hsize_t h5_thresh; /* HDF5 object alignment threshold */ + int h5_use_chunks; /* Make HDF5 dataset chunked */ + int h5_extendable; /* Make HDF5 dataset chunked */ + int h5_write_only; /* Perform the write tests only */ + int verify; /* Verify data correctness */ + size_t page_size; + size_t page_buffer_size; +} parameters; + +typedef struct results_ { + herr_t ret_code; + io_time_t *timers; +} results; + +#ifndef SUCCESS +#define SUCCESS 0 +#endif /* !SUCCESS */ + +#ifndef FAIL +#define FAIL -1 +#endif /* !FAIL */ + +extern FILE * output; /* output file */ +extern io_time_t *timer_g; /* timer: global for stub functions */ +extern int sio_debug_level; /* The debug level: + * 0 - Off + * 1 - Minimal + * 2 - Some more + * 3 - Maximal + * 4 - Even More Debugging (timer stuff) + */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +extern void do_sio(parameters param, results *res); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SIO_PERF_H */ diff --git a/tools/src/h5repack/h5repack_copy.c b/tools/src/h5repack/h5repack_copy.c index 536de69..934b4d1 100644 --- a/tools/src/h5repack/h5repack_copy.c +++ b/tools/src/h5repack/h5repack_copy.c @@ -626,6 +626,7 @@ do_copy_objects(hid_t fidin, hid_t fidout, trav_table_t *travt, pack_opt_t *opti hid_t wtype_id = H5I_INVALID_HID; /* read/write type ID */ hid_t ocpl_id = H5I_INVALID_HID; /* property to pass copy options */ hid_t lcpl_id = H5I_INVALID_HID; /* link creation property list */ + hid_t dxpl_id = H5I_INVALID_HID; /* dataset transfer property list */ named_dt_t * named_dt_head = NULL; /* Pointer to the stack of named datatypes copied */ size_t msize; /* size of type */ hsize_t nelmts; /* number of elements in dataset */ @@ -995,12 +996,27 @@ do_copy_objects(hid_t fidin, hid_t fidout, trav_table_t *travt, pack_opt_t *opti if (need < H5TOOLS_MALLOCSIZE) buf = HDmalloc(need); + /* Set up collective write if using filters in parallel */ + { +#ifdef H5_HAVE_PARALLEL + hbool_t parallel = (H5FD_MPIO == H5Pget_driver(options->fout_fapl)); + + if (parallel && apply_s && apply_f) { + if ((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) + H5TOOLS_GOTO_ERROR((-1), "H5Pcreate failed"); + if (H5Pset_dxpl_mpio(dxpl_id, H5FD_MPIO_COLLECTIVE) < 0) + H5TOOLS_GOTO_ERROR((-1), "H5Pset_dxpl_mpio failed"); + } + else +#endif + dxpl_id = H5P_DEFAULT; + } + if (buf != NULL) { if (H5Dread(dset_in, wtype_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) H5TOOLS_GOTO_ERROR((-1), "H5Dread failed"); - if (H5Dwrite(dset_out, wtype_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < - 0) + if (H5Dwrite(dset_out, wtype_id, H5S_ALL, H5S_ALL, dxpl_id, buf) < 0) H5TOOLS_GOTO_ERROR((-1), "H5Dwrite failed"); /* Check if we have VL data in the dataset's @@ -1102,8 +1118,8 @@ do_copy_objects(hid_t fidin, hid_t fidout, trav_table_t *travt, pack_opt_t *opti if (H5Dread(dset_in, wtype_id, hslab_space, f_space_id, H5P_DEFAULT, hslab_buf) < 0) H5TOOLS_GOTO_ERROR((-1), "H5Dread failed"); - if (H5Dwrite(dset_out, wtype_id, hslab_space, f_space_id, - H5P_DEFAULT, hslab_buf) < 0) + if (H5Dwrite(dset_out, wtype_id, hslab_space, f_space_id, dxpl_id, + hslab_buf) < 0) H5TOOLS_GOTO_ERROR((-1), "H5Dwrite failed"); /* reclaim any VL memory, if necessary */ @@ -1382,6 +1398,7 @@ done: H5Pclose(dcpl_in); H5Pclose(gcpl_in); H5Pclose(gcpl_out); + H5Pclose(dxpl_id); H5Sclose(f_space_id); H5Dclose(dset_in); H5Dclose(dset_out); diff --git a/tools/src/h5stat/h5stat.c b/tools/src/h5stat/h5stat.c index b884b7e..ea4e314 100644 --- a/tools/src/h5stat/h5stat.c +++ b/tools/src/h5stat/h5stat.c @@ -172,102 +172,19 @@ struct handler_t { static const char *s_opts = "Aa:Ddm:EFfhGgl:sSTO:Vw:H:"; /* e.g. "filemetadata" has to precede "file"; "groupmetadata" has to precede "group" etc. */ static struct h5_long_options l_opts[] = {{"help", no_arg, 'h'}, - {"hel", no_arg, 'h'}, - {"he", no_arg, 'h'}, {"filemetadata", no_arg, 'F'}, - {"filemetadat", no_arg, 'F'}, - {"filemetada", no_arg, 'F'}, - {"filemetad", no_arg, 'F'}, - {"filemeta", no_arg, 'F'}, - {"filemet", no_arg, 'F'}, - {"fileme", no_arg, 'F'}, - {"filem", no_arg, 'F'}, - {"file", no_arg, 'f'}, - {"fil", no_arg, 'f'}, - {"fi", no_arg, 'f'}, {"groupmetadata", no_arg, 'G'}, - {"groupmetadat", no_arg, 'G'}, - {"groupmetada", no_arg, 'G'}, - {"groupmetad", no_arg, 'G'}, - {"groupmeta", no_arg, 'G'}, - {"groupmet", no_arg, 'G'}, - {"groupme", no_arg, 'G'}, - {"groupm", no_arg, 'G'}, - {"group", no_arg, 'g'}, - {"grou", no_arg, 'g'}, - {"gro", no_arg, 'g'}, - {"gr", no_arg, 'g'}, {"links", require_arg, 'l'}, - {"link", require_arg, 'l'}, - {"lin", require_arg, 'l'}, - {"li", require_arg, 'l'}, {"dsetmetadata", no_arg, 'D'}, - {"dsetmetadat", no_arg, 'D'}, - {"dsetmetada", no_arg, 'D'}, - {"dsetmetad", no_arg, 'D'}, - {"dsetmeta", no_arg, 'D'}, - {"dsetmet", no_arg, 'D'}, - {"dsetme", no_arg, 'D'}, - {"dsetm", no_arg, 'D'}, - {"dset", no_arg, 'd'}, - {"dse", no_arg, 'd'}, - {"ds", no_arg, 'd'}, {"dims", require_arg, 'm'}, - {"dim", require_arg, 'm'}, - {"di", require_arg, 'm'}, {"dtypemetadata", no_arg, 'T'}, - {"dtypemetadat", no_arg, 'T'}, - {"dtypemetada", no_arg, 'T'}, - {"dtypemetad", no_arg, 'T'}, - {"dtypemeta", no_arg, 'T'}, - {"dtypemet", no_arg, 'T'}, - {"dtypeme", no_arg, 'T'}, - {"dtypem", no_arg, 'T'}, - {"dtype", no_arg, 'T'}, - {"dtyp", no_arg, 'T'}, - {"dty", no_arg, 'T'}, - {"dt", no_arg, 'T'}, {"object", require_arg, 'O'}, - {"objec", require_arg, 'O'}, - {"obje", require_arg, 'O'}, - {"obj", require_arg, 'O'}, - {"ob", require_arg, 'O'}, {"version", no_arg, 'V'}, - {"versio", no_arg, 'V'}, - {"versi", no_arg, 'V'}, - {"vers", no_arg, 'V'}, - {"ver", no_arg, 'V'}, - {"ve", no_arg, 'V'}, {"attribute", no_arg, 'A'}, - {"attribut", no_arg, 'A'}, - {"attribu", no_arg, 'A'}, - {"attrib", no_arg, 'A'}, - {"attri", no_arg, 'A'}, - {"attr", no_arg, 'A'}, - {"att", no_arg, 'A'}, - {"at", no_arg, 'A'}, {"enable-error-stack", no_arg, 'E'}, {"numattrs", require_arg, 'a'}, - {"numattr", require_arg, 'a'}, - {"numatt", require_arg, 'a'}, - {"numat", require_arg, 'a'}, - {"numa", require_arg, 'a'}, - {"num", require_arg, 'a'}, - {"nu", require_arg, 'a'}, {"freespace", no_arg, 's'}, - {"freespac", no_arg, 's'}, - {"freespa", no_arg, 's'}, - {"freesp", no_arg, 's'}, - {"frees", no_arg, 's'}, - {"free", no_arg, 's'}, - {"fre", no_arg, 's'}, - {"fr", no_arg, 's'}, {"summary", no_arg, 'S'}, - {"summar", no_arg, 'S'}, - {"summa", no_arg, 'S'}, - {"summ", no_arg, 'S'}, - {"sum", no_arg, 'S'}, - {"su", no_arg, 'S'}, {"s3-cred", require_arg, 'w'}, {"hdfs-attrs", require_arg, 'H'}, {NULL, 0, '\0'}}; diff --git a/tools/src/misc/h5clear.c b/tools/src/misc/h5clear.c index 524ad03..face2f0 100644 --- a/tools/src/misc/h5clear.c +++ b/tools/src/misc/h5clear.c @@ -32,7 +32,7 @@ #define H5F_ACS_SKIP_EOF_CHECK_NAME "skip_eof_check" /* Default increment is 1 megabytes for the --increment option */ -#define DEFAULT_INCREMENT 1024 * 1024 +#define DEFAULT_INCREMENT (1024 * 1024) static char * fname_g = NULL; static hbool_t clear_status_flags = FALSE; @@ -45,39 +45,10 @@ static hsize_t increment = DEFAULT_INCREMENT; * Command-line options: only publicize long options */ static const char * s_opts = "hVsmzi*"; -static struct h5_long_options l_opts[] = {{"help", no_arg, 'h'}, - {"hel", no_arg, 'h'}, - {"he", no_arg, 'h'}, - {"version", no_arg, 'V'}, - {"version", no_arg, 'V'}, - {"versio", no_arg, 'V'}, - {"versi", no_arg, 'V'}, - {"vers", no_arg, 'V'}, - {"status", no_arg, 's'}, - {"statu", no_arg, 's'}, - {"stat", no_arg, 's'}, - {"sta", no_arg, 's'}, - {"st", no_arg, 's'}, - {"image", no_arg, 'm'}, - {"imag", no_arg, 'm'}, - {"ima", no_arg, 'm'}, - {"im", no_arg, 'm'}, - {"filesize", no_arg, 'z'}, - {"filesiz", no_arg, 'z'}, - {"filesi", no_arg, 'z'}, - {"files", no_arg, 'z'}, - {"file", no_arg, 'z'}, - {"fil", no_arg, 'z'}, - {"fi", no_arg, 'z'}, - {"increment", optional_arg, 'i'}, - {"incremen", optional_arg, 'i'}, - {"increme", optional_arg, 'i'}, - {"increm", optional_arg, 'i'}, - {"incre", optional_arg, 'i'}, - {"incr", optional_arg, 'i'}, - {"inc", optional_arg, 'i'}, - {"in", optional_arg, 'i'}, - {NULL, 0, '\0'}}; +static struct h5_long_options l_opts[] = { + {"help", no_arg, 'h'}, {"version", no_arg, 'V'}, {"status", no_arg, 's'}, + {"image", no_arg, 'm'}, {"filesize", no_arg, 'z'}, {"increment", optional_arg, 'i'}, + {NULL, 0, '\0'}}; /*------------------------------------------------------------------------- * Function: usage diff --git a/tools/test/h5diff/CMakeTests.cmake b/tools/test/h5diff/CMakeTests.cmake index 5ada730..4fcfa26 100644 --- a/tools/test/h5diff/CMakeTests.cmake +++ b/tools/test/h5diff/CMakeTests.cmake @@ -376,40 +376,44 @@ macro (ADD_H5_TEST resultfile resultcode) if (HDF5_TEST_SERIAL) - # If using memchecker add tests without using scripts - if (HDF5_ENABLE_USING_MEMCHECKER) - add_test (NAME H5DIFF-${resultfile} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:h5diff${tgt_file_ext}> ${ARGN}) - set_tests_properties (H5DIFF-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles") - if (${resultcode}) - set_tests_properties (H5DIFF-${resultfile} PROPERTIES WILL_FAIL "true") - endif () - if (last_test) - set_tests_properties (H5DIFF-${resultfile} PROPERTIES DEPENDS ${last_test}) - endif () - else () - add_test ( - NAME H5DIFF-${resultfile} - COMMAND "${CMAKE_COMMAND}" - -D "TEST_EMULATOR=${CMAKE_CROSSCOMPILING_EMULATOR}" - -D "TEST_PROGRAM=$<TARGET_FILE:h5diff${tgt_file_ext}>" - -D "TEST_ARGS:STRING=${ARGN}" - -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/testfiles" - -D "TEST_OUTPUT=${resultfile}.out" - -D "TEST_EXPECT=${resultcode}" - -D "TEST_REFERENCE=${resultfile}.txt" - -D "TEST_APPEND=EXIT CODE:" - -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" - ) - if (last_test) - set_tests_properties (H5DIFF-${resultfile} PROPERTIES DEPENDS ${last_test}) - endif () - endif () + ADD_SH5_TEST (${resultfile} ${resultcode} ${ARGN}) endif () if (H5_HAVE_PARALLEL AND HDF5_TEST_PARALLEL) ADD_PH5_TEST (${resultfile} ${resultcode} ${ARGN}) endif () endmacro () + macro (ADD_SH5_TEST resultfile resultcode) + # If using memchecker add tests without using scripts + if (HDF5_ENABLE_USING_MEMCHECKER) + add_test (NAME H5DIFF-${resultfile} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:h5diff${tgt_file_ext}> ${ARGN}) + set_tests_properties (H5DIFF-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles") + if (${resultcode}) + set_tests_properties (H5DIFF-${resultfile} PROPERTIES WILL_FAIL "true") + endif () + if (last_test) + set_tests_properties (H5DIFF-${resultfile} PROPERTIES DEPENDS ${last_test}) + endif () + else () + add_test ( + NAME H5DIFF-${resultfile} + COMMAND "${CMAKE_COMMAND}" + -D "TEST_EMULATOR=${CMAKE_CROSSCOMPILING_EMULATOR}" + -D "TEST_PROGRAM=$<TARGET_FILE:h5diff${tgt_file_ext}>" + -D "TEST_ARGS:STRING=${ARGN}" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/testfiles" + -D "TEST_OUTPUT=${resultfile}.out" + -D "TEST_EXPECT=${resultcode}" + -D "TEST_REFERENCE=${resultfile}.txt" + -D "TEST_APPEND=EXIT CODE:" + -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" + ) + if (last_test) + set_tests_properties (H5DIFF-${resultfile} PROPERTIES DEPENDS ${last_test}) + endif () + endif () + endmacro () + macro (ADD_PH5_TEST resultfile resultcode) # If using memchecker add tests without using scripts if (HDF5_ENABLE_USING_MEMCHECKER) @@ -1549,7 +1553,8 @@ ADD_H5_TEST (h5diff_801 1 -v ${FILE7} ${FILE8A} /g1/array /g1/array) # ############################################################################## # # dataset subsets # ############################################################################## -ADD_H5_TEST (h5diff_830 1 --enable-error-stack -v ${FILE7} ${FILE8} /g1/array3D[0,0,0;2,2,1;2,2,2;] /g1/array3D[0,0,0;2,2,1;2,2,2;]) +#serial only +ADD_SH5_TEST (h5diff_830 1 --enable-error-stack -v ${FILE7} ${FILE8} /g1/array3D[0,0,0;2,2,1;2,2,2;] /g1/array3D[0,0,0;2,2,1;2,2,2;]) # ############################################################################## # # VDS tests diff --git a/tools/test/h5dump/h5dumpgentest.c b/tools/test/h5dump/h5dumpgentest.c index 29922e8..e74054c 100644 --- a/tools/test/h5dump/h5dumpgentest.c +++ b/tools/test/h5dump/h5dumpgentest.c @@ -199,8 +199,8 @@ const H5L_class_t UD_link_class[1] = {{ #define DIM1 20 #define DIM2 10 -#define CDIM1 DIM1 / 2 -#define CDIM2 DIM2 / 2 +#define CDIM1 (DIM1 / 2) +#define CDIM2 (DIM2 / 2) #define RANK 2 /* Dataspace of 0 dimension size */ diff --git a/tools/test/h5jam/h5jamgentest.c b/tools/test/h5jam/h5jamgentest.c index 1da6b63..5632cc0 100644 --- a/tools/test/h5jam/h5jamgentest.c +++ b/tools/test/h5jam/h5jamgentest.c @@ -31,24 +31,7 @@ #define UBTXT3 "u511.txt" #define UBTXT4 "u512.txt" #define UBTXT5 "u513.txt" -/* not used yet -#define UBTXT6 "u1023.txt" -#define UBTXT7 "u1024.txt" -#define UBTXT8 "u1025.txt" -#define UBTXT9 "u2047.txt" -#define UBTXT10 "u2048.txt" -#define UBTXT11 "u2049.txt" -#define UBBIN1 "u0.dat" -#define UBBIN2 "u10.dat" -#define UBBIN3 "u511.dat" -#define UBBIN4 "u512.dat" -#define UBBIN5 "u513.dat" -*/ -/* not used yet -#define FILE1 "tnull.h5" -#define FILE2 "tnullwithub.h5" -*/ /* tall is same as dumper test */ #define FILE7 "tall.h5" #define FILE8 "twithub.h5" @@ -66,24 +49,13 @@ char pattern[11] = "abcdefghij"; #define BUF_SIZE 1024 -/* Element selection information */ - -typedef enum { RED, GREEN, BLUE, WHITE, BLACK } enumtype; - -/* Compound datatype */ -typedef struct s1_t { - unsigned int a; - unsigned int b; - float c; -} s1_t; - /* A UD link traversal function. Shouldn't actually be called. */ static hid_t UD_traverse(const char H5_ATTR_UNUSED *link_name, hid_t H5_ATTR_UNUSED cur_group, const void H5_ATTR_UNUSED *udata, size_t H5_ATTR_UNUSED udata_size, hid_t H5_ATTR_UNUSED lapl_id, hid_t H5_ATTR_UNUSED dxpl_id) { - return -1; + return H5I_INVALID_HID; } #define MY_LINKCLASS 187 @@ -115,261 +87,340 @@ g1.2.1 : slink g2 : dset2.1 dset2.2 udlink */ - -static void +static herr_t gent_ub(const char *filename, size_t ub_size, size_t ub_fill) { - hid_t fid, group, attr, dataset, space; - hid_t create_plist; + hid_t fid = H5I_INVALID_HID; + hid_t group = H5I_INVALID_HID; + hid_t attr = H5I_INVALID_HID; + hid_t dataset = H5I_INVALID_HID; + hid_t space = H5I_INVALID_HID; + hid_t create_plist = H5I_INVALID_HID; hsize_t dims[2]; int data[2][2], dset1[10][10], dset2[20]; char buf[BUF_SIZE]; int i, j; size_t u; float dset2_1[10], dset2_2[3][5]; - int fd; - char * bp; + int fd = -1; if (ub_size > 0) { - create_plist = H5Pcreate(H5P_FILE_CREATE); - H5Pset_userblock(create_plist, (hsize_t)ub_size); - fid = H5Fcreate(filename, H5F_ACC_TRUNC, create_plist, H5P_DEFAULT); + if ((create_plist = H5Pcreate(H5P_FILE_CREATE)) < 0) + goto error; + if (H5Pset_userblock(create_plist, (hsize_t)ub_size) < 0) + goto error; + if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, create_plist, H5P_DEFAULT)) < 0) + goto error; } else { - fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; } - /* create groups */ - group = H5Gcreate2(fid, "/g1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - H5Gclose(group); + /* Create groups */ + if ((group = H5Gcreate2(fid, "/g1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; + if (H5Gclose(group) < 0) + goto error; - group = H5Gcreate2(fid, "/g2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - H5Gclose(group); + if ((group = H5Gcreate2(fid, "/g2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; + if (H5Gclose(group) < 0) + goto error; - group = H5Gcreate2(fid, "/g1/g1.1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - H5Gclose(group); + if ((group = H5Gcreate2(fid, "/g1/g1.1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; + if (H5Gclose(group) < 0) + goto error; - group = H5Gcreate2(fid, "/g1/g1.2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - H5Gclose(group); + if ((group = H5Gcreate2(fid, "/g1/g1.2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; + if (H5Gclose(group) < 0) + goto error; - group = H5Gcreate2(fid, "/g1/g1.2/g1.2.1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - H5Gclose(group); + if ((group = H5Gcreate2(fid, "/g1/g1.2/g1.2.1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; + if (H5Gclose(group) < 0) + goto error; - /* root attributes */ - group = H5Gopen2(fid, "/", H5P_DEFAULT); + /* Root attributes */ + if ((group = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) + goto error; dims[0] = 10; - space = H5Screate_simple(1, dims, NULL); - attr = H5Acreate2(group, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT, H5P_DEFAULT); - HDsprintf(buf, "abcdefghi"); - H5Awrite(attr, H5T_NATIVE_SCHAR, buf); - H5Sclose(space); - H5Aclose(attr); - - dims[0] = 2; - dims[1] = 2; - space = H5Screate_simple(2, dims, NULL); - attr = H5Acreate2(group, "attr2", H5T_STD_I32BE, space, H5P_DEFAULT, H5P_DEFAULT); + if ((space = H5Screate_simple(1, dims, NULL)) < 0) + goto error; + if ((attr = H5Acreate2(group, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; + if (HDsprintf(buf, "abcdefghi") < 0) + goto error; + if (H5Awrite(attr, H5T_NATIVE_SCHAR, buf) < 0) + goto error; + if (H5Sclose(space) < 0) + goto error; + if (H5Aclose(attr) < 0) + goto error; + + dims[0] = 2; + dims[1] = 2; + if ((space = H5Screate_simple(2, dims, NULL)) < 0) + goto error; + if ((attr = H5Acreate2(group, "attr2", H5T_STD_I32BE, space, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; data[0][0] = 0; data[0][1] = 1; data[1][0] = 2; data[1][1] = 3; - H5Awrite(attr, H5T_NATIVE_INT, data); - H5Sclose(space); - H5Aclose(attr); + if (H5Awrite(attr, H5T_NATIVE_INT, data) < 0) + goto error; + if (H5Sclose(space) < 0) + goto error; + if (H5Aclose(attr) < 0) + goto error; - H5Gclose(group); + if (H5Gclose(group) < 0) + goto error; - group = H5Gopen2(fid, "/g1/g1.1", H5P_DEFAULT); + if ((group = H5Gopen2(fid, "/g1/g1.1", H5P_DEFAULT)) < 0) + goto error; - /* dset1.1.1 */ + /* Dataset 1.1.1 */ dims[0] = 10; dims[1] = 10; - space = H5Screate_simple(2, dims, NULL); - dataset = H5Dcreate2(group, "dset1.1.1", H5T_STD_I32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if ((space = H5Screate_simple(2, dims, NULL)) < 0) + goto error; + if ((dataset = + H5Dcreate2(group, "dset1.1.1", H5T_STD_I32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; for (i = 0; i < 10; i++) for (j = 0; j < 10; j++) dset1[i][j] = j * i; - H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset1); - H5Sclose(space); + if (H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset1) < 0) + goto error; + if (H5Sclose(space) < 0) + goto error; - /* attributes of dset1.1.1 */ + /* Attributes of dset1.1.1 */ dims[0] = 27; - space = H5Screate_simple(1, dims, NULL); - attr = H5Acreate2(dataset, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT, H5P_DEFAULT); - HDsprintf(buf, "1st attribute of dset1.1.1"); - H5Awrite(attr, H5T_NATIVE_SCHAR, buf); - H5Sclose(space); - H5Aclose(attr); + if ((space = H5Screate_simple(1, dims, NULL)) < 0) + goto error; + if ((attr = H5Acreate2(dataset, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; + if (HDsprintf(buf, "1st attribute of dset1.1.1") < 0) + goto error; + if (H5Awrite(attr, H5T_NATIVE_SCHAR, buf) < 0) + goto error; + if (H5Sclose(space) < 0) + goto error; + if (H5Aclose(attr) < 0) + goto error; dims[0] = 27; - space = H5Screate_simple(1, dims, NULL); - attr = H5Acreate2(dataset, "attr2", H5T_STD_I8BE, space, H5P_DEFAULT, H5P_DEFAULT); - HDsprintf(buf, "2nd attribute of dset1.1.1"); - H5Awrite(attr, H5T_NATIVE_SCHAR, buf); - H5Sclose(space); - H5Aclose(attr); - - H5Dclose(dataset); - - /* dset1.1.2 */ + if ((space = H5Screate_simple(1, dims, NULL)) < 0) + goto error; + if ((attr = H5Acreate2(dataset, "attr2", H5T_STD_I8BE, space, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; + if (HDsprintf(buf, "2nd attribute of dset1.1.1") < 0) + goto error; + if (H5Awrite(attr, H5T_NATIVE_SCHAR, buf) < 0) + goto error; + if (H5Sclose(space) < 0) + goto error; + if (H5Aclose(attr) < 0) + goto error; + + if (H5Dclose(dataset) < 0) + goto error; + + /* Dataset 1.1.2 */ dims[0] = 20; - space = H5Screate_simple(1, dims, NULL); - dataset = H5Dcreate2(group, "dset1.1.2", H5T_STD_I32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if ((space = H5Screate_simple(1, dims, NULL)) < 0) + goto error; + if ((dataset = + H5Dcreate2(group, "dset1.1.2", H5T_STD_I32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; for (i = 0; i < 20; i++) dset2[i] = i; - H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2); - H5Sclose(space); - H5Dclose(dataset); - - H5Gclose(group); - - /* external link */ - H5Lcreate_external("somefile", "somepath", fid, "/g1/g1.2/extlink", H5P_DEFAULT, H5P_DEFAULT); - - /* soft link */ - group = H5Gopen2(fid, "/g1/g1.2/g1.2.1", H5P_DEFAULT); - H5Lcreate_soft("somevalue", group, "slink", H5P_DEFAULT, H5P_DEFAULT); - H5Gclose(group); - - group = H5Gopen2(fid, "/g2", H5P_DEFAULT); - - /* dset2.1 */ + if (H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2) < 0) + goto error; + if (H5Sclose(space) < 0) + goto error; + if (H5Dclose(dataset) < 0) + goto error; + + if (H5Gclose(group) < 0) + goto error; + + /* External link */ + if (H5Lcreate_external("somefile", "somepath", fid, "/g1/g1.2/extlink", H5P_DEFAULT, H5P_DEFAULT) < 0) + goto error; + + /* Soft link */ + if ((group = H5Gopen2(fid, "/g1/g1.2/g1.2.1", H5P_DEFAULT)) < 0) + goto error; + if (H5Lcreate_soft("somevalue", group, "slink", H5P_DEFAULT, H5P_DEFAULT) < 0) + goto error; + if (H5Gclose(group) < 0) + goto error; + + if ((group = H5Gopen2(fid, "/g2", H5P_DEFAULT)) < 0) + goto error; + + /* Dataset 2.1 */ dims[0] = 10; - space = H5Screate_simple(1, dims, NULL); - dataset = H5Dcreate2(group, "dset2.1", H5T_IEEE_F32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if ((space = H5Screate_simple(1, dims, NULL)) < 0) + goto error; + if ((dataset = + H5Dcreate2(group, "dset2.1", H5T_IEEE_F32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; for (i = 0; i < 10; i++) dset2_1[i] = (float)((float)i * 0.1F + 1.0F); - H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_1); - H5Sclose(space); - H5Dclose(dataset); - - /* dset2.2 */ + if (H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_1) < 0) + goto error; + if (H5Sclose(space) < 0) + goto error; + if (H5Dclose(dataset) < 0) + goto error; + + /* Dataset 2.2 */ dims[0] = 3; dims[1] = 5; - space = H5Screate_simple(2, dims, NULL); - dataset = H5Dcreate2(group, "dset2.2", H5T_IEEE_F32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if ((space = H5Screate_simple(2, dims, NULL)) < 0) + goto error; + if ((dataset = + H5Dcreate2(group, "dset2.2", H5T_IEEE_F32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; for (i = 0; i < 3; i++) for (j = 0; j < 5; j++) dset2_2[i][j] = (float)(((float)i + 1.0F) * (float)j * 0.1F); - H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_2); - H5Sclose(space); - H5Dclose(dataset); - - H5Gclose(group); - - /* user-defined link */ - H5Lregister(UD_link_class); - H5Lcreate_ud(fid, "/g2/udlink", (H5L_type_t)MY_LINKCLASS, NULL, (size_t)0, H5P_DEFAULT, H5P_DEFAULT); - - H5Fclose(fid); + if (H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_2) < 0) + goto error; + if (H5Sclose(space) < 0) + goto error; + if (H5Dclose(dataset) < 0) + goto error; + + if (H5Gclose(group) < 0) + goto error; + + /* User-defined link */ + if (H5Lregister(UD_link_class) < 0) + goto error; + if (H5Lcreate_ud(fid, "/g2/udlink", (H5L_type_t)MY_LINKCLASS, NULL, (size_t)0, H5P_DEFAULT, H5P_DEFAULT) < + 0) + goto error; + + /* MUST close the file ID before the user block code or you risk tripping + * over file locking issues. + */ + if (H5Fclose(fid) < 0) + goto error; /* If a user block is being used, write to it here */ if (ub_size > 0) { - HDassert(ub_size <= BUF_SIZE); + char *bp; - fd = HDopen(filename, O_RDWR); - HDassert(fd >= 0); + if (ub_size > BUF_SIZE) + goto error; - /* fill buf with pattern */ + if ((fd = HDopen(filename, O_RDWR)) < 0) + goto error; + + /* Fill buf with pattern */ HDmemset(buf, '\0', ub_size); bp = buf; for (u = 0; u < ub_fill; u++) *bp++ = pattern[u % 10]; - (void)HDwrite(fd, buf, ub_size); + if (HDwrite(fd, buf, ub_size) < 0) + goto error; + + if (HDclose(fd) < 0) + goto error; + } + return SUCCEED; + +error: + if (fd >= 0) HDclose(fd); + + H5E_BEGIN_TRY + { + H5Fclose(fid); + H5Gclose(group); + H5Aclose(attr); + H5Dclose(dataset); + H5Sclose(space); + H5Pclose(create_plist); } + H5E_END_TRY; + + return FAIL; } -static void +/* Creates a simple (i.e., not HDF5) text file and fills it with a pattern */ +static herr_t create_textfile(const char *name, size_t size) { - char * buf; - int fd; + char * buf = NULL; + int fd = -1; size_t i; - char * bp; + char * bp = NULL; - fd = HDcreat(name, 0777); - HDassert(fd >= 0); - buf = (char *)HDcalloc(size, (size_t)1); - HDassert(buf); + if ((fd = HDcreat(name, 0777)) < 0) + goto error; + if (NULL == (buf = (char *)HDcalloc(size, 1))) + goto error; - /* fill buf with pattern */ + /* Fill buf with pattern */ bp = buf; for (i = 0; i < size; i++) *bp++ = pattern[i % 10]; - (void)HDwrite(fd, buf, size); + if (HDwrite(fd, buf, size) < 0) + goto error; HDfree(buf); - HDclose(fd); -} - -#ifdef notdef -/* not used yet */ -void -create_binfile(char *name, off_t size) -{ - char *buf; - int fd; - int i; - char *bp; - fd = creat(name, 0777); - HDassert(fd >= 0); + return SUCCEED; - buf = HDcalloc(size, 1); - HDassert(buf); - - /* fill buf with pattern */ - bp = buf; - for (i = 0; i < size; i++) - *bp++ = (char)i & 0xff; - - (void)HDwrite(fd, buf, size); +error: + HDfree(buf); + if (fd >= 0) + HDclose(fd); - HDclose(fd); + return FAIL; } -#endif /*------------------------------------------------------------------------- * Function: main * *------------------------------------------------------------------------- */ - int main(void) { - - /* - create_textfile(UBTXT1, (size_t)0); - */ - create_textfile(UBTXT2, (size_t)10); - create_textfile(UBTXT3, (size_t)511); - create_textfile(UBTXT4, (size_t)512); - create_textfile(UBTXT5, (size_t)513); - /* - create_textfile(UBTXT6, (size_t)1023); - create_textfile(UBTXT7, (size_t)1024); - create_textfile(UBTXT8, (size_t)1025); - create_textfile(UBTXT9, (size_t)2047); - create_textfile(UBTXT10, (size_t)2048); - create_textfile(UBTXT11, (size_t)2049); - - create_binfile(UBBIN1, (off_t)0); - create_binfile(UBBIN2, (off_t)10); - create_binfile(UBBIN3, (off_t)511); - create_binfile(UBBIN4, (off_t)512); - create_binfile(UBBIN5, (off_t)513); - - */ - gent_ub(FILE7, (size_t)0, (size_t)0); - gent_ub(FILE8, (size_t)512, HDstrlen(pattern)); - gent_ub(FILE9, (size_t)1024, (size_t)513); - - return 0; + if (create_textfile(UBTXT2, 10) < 0) + goto error; + if (create_textfile(UBTXT3, 511) < 0) + goto error; + if (create_textfile(UBTXT4, 512) < 0) + goto error; + if (create_textfile(UBTXT5, 513) < 0) + goto error; + + if (gent_ub(FILE7, 0, 0) < 0) + goto error; + if (gent_ub(FILE8, 512, HDstrlen(pattern)) < 0) + goto error; + if (gent_ub(FILE9, 1024, 513) < 0) + goto error; + + return EXIT_SUCCESS; + +error: + HDfprintf(stderr, "h5jam test generator FAILED\n"); + return EXIT_FAILURE; } diff --git a/tools/test/h5repack/h5repacktst.c b/tools/test/h5repack/h5repacktst.c index acad74e..b62fa53 100644 --- a/tools/test/h5repack/h5repacktst.c +++ b/tools/test/h5repack/h5repacktst.c @@ -111,8 +111,8 @@ const char *H5REPACK_FILENAMES[] = {"h5repack_big_out", NULL}; #define DIM1 40 #define DIM2 20 -#define CDIM1 DIM1 / 2 -#define CDIM2 DIM2 / 2 +#define CDIM1 (DIM1 / 2) +#define CDIM2 (DIM2 / 2) #define RANK 2 /* Size of userblock (for userblock test) */ diff --git a/tools/test/h5stat/CMakeTests.cmake b/tools/test/h5stat/CMakeTests.cmake index 79de6b9..d4238b5 100644 --- a/tools/test/h5stat/CMakeTests.cmake +++ b/tools/test/h5stat/CMakeTests.cmake @@ -207,7 +207,7 @@ # -d --di=15 ADD_H5_ERR_TEST (h5stat_err1_dims 1 -d --dims=-1 h5stat_threshold.h5) ADD_H5_TEST (h5stat_dims1 0 -gd -m 5 h5stat_threshold.h5) - ADD_H5_TEST (h5stat_dims2 0 -d --di=15 h5stat_threshold.h5) + ADD_H5_TEST (h5stat_dims2 0 -d --dims=15 h5stat_threshold.h5) # # Tests for -a option on h5stat_threshold.h5 # -a -2 (incorrect threshold value) diff --git a/tools/test/h5stat/h5stat_gentest.c b/tools/test/h5stat/h5stat_gentest.c index a9813e7..c775d6a 100644 --- a/tools/test/h5stat/h5stat_gentest.c +++ b/tools/test/h5stat/h5stat_gentest.c @@ -51,7 +51,7 @@ * Generate HDF5 file with latest format with * NUM_GRPS groups and NUM_ATTRS attributes for the dataset */ -static void +static herr_t gen_newgrat_file(const char *fname) { hid_t fcpl = H5I_INVALID_HID; /* File creation property */ @@ -117,6 +117,21 @@ gen_newgrat_file(const char *fname) } /* end for */ /* Close dataset, dataspace, datatype, file */ + if (H5Pclose(fapl) < 0) + goto error; + if (H5Pclose(fcpl) < 0) + goto error; + if (H5Dclose(did) < 0) + goto error; + if (H5Tclose(tid) < 0) + goto error; + if (H5Sclose(sid) < 0) + goto error; + if (H5Fclose(fid) < 0) + goto error; + + return SUCCEED; + error: H5E_BEGIN_TRY { @@ -130,6 +145,8 @@ error: H5Fclose(fid); } H5E_END_TRY; + + return FAIL; } /* gen_newgrat_file() */ /* @@ -139,7 +156,7 @@ error: * datasets. -a N (--numattrs=N): Set the threshold for the # of attributes when printing information for * small # of attributes. */ -static void +static herr_t gen_threshold_file(const char *fname) { hid_t fid = H5I_INVALID_HID; /* File ID */ @@ -302,6 +319,23 @@ gen_threshold_file(const char *fname) goto error; } + if (H5Gclose(gid) < 0) + goto error; + if (H5Sclose(sid0) < 0) + goto error; + if (H5Sclose(sid1) < 0) + goto error; + if (H5Sclose(sid2) < 0) + goto error; + if (H5Sclose(sid3) < 0) + goto error; + if (H5Sclose(sid4) < 0) + goto error; + if (H5Fclose(fid) < 0) + goto error; + + return SUCCEED; + error: H5E_BEGIN_TRY { @@ -317,6 +351,8 @@ error: } H5E_END_TRY; + return FAIL; + } /* gen_threshold_file() */ /* @@ -327,18 +363,21 @@ error: * one dataset: fixed dimension, chunked layout, w/ filters * */ -static void +static herr_t gen_idx_file(const char *fname) { - hid_t fapl = H5I_INVALID_HID; /* file access property id */ - hid_t fid = H5I_INVALID_HID; /* file id */ - hid_t sid = H5I_INVALID_HID; /* space id */ - hid_t dcpl = H5I_INVALID_HID; /* dataset creation property id */ - hid_t did = -1, did2 = H5I_INVALID_HID; /* dataset id */ - hsize_t dims[1] = {10}; /* dataset dimension */ - hsize_t c_dims[1] = {2}; /* chunk dimension */ - int i; /* local index variable */ - int buf[10]; /* data buffer */ + hid_t fapl = H5I_INVALID_HID; /* file access property id */ + hid_t fid = H5I_INVALID_HID; /* file id */ + hid_t sid = H5I_INVALID_HID; /* space id */ + hid_t dcpl = H5I_INVALID_HID; /* dataset creation property id */ + hid_t did = H5I_INVALID_HID; /* dataset id */ +#if defined(H5_HAVE_FILTER_DEFLATE) + hid_t did2 = H5I_INVALID_HID; /* dataset id (compressed) */ +#endif + hsize_t dims[1] = {10}; /* dataset dimension */ + hsize_t c_dims[1] = {2}; /* chunk dimension */ + int i; /* local index variable */ + int buf[10]; /* data buffer */ /* Get a copy of the file access property */ if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) @@ -390,6 +429,19 @@ gen_idx_file(const char *fname) #endif /* closing: dataspace, dataset, file */ + if (H5Pclose(fapl) < 0) + goto error; + if (H5Pclose(dcpl) < 0) + goto error; + if (H5Sclose(sid) < 0) + goto error; + if (H5Dclose(did) < 0) + goto error; + if (H5Fclose(fid) < 0) + goto error; + + return SUCCEED; + error: H5E_BEGIN_TRY { @@ -404,6 +456,8 @@ error: } H5E_END_TRY; + return FAIL; + } /* gen_idx_file() */ /* @@ -419,20 +473,21 @@ error: * H5O_refcount_decode in the jira issue. * */ -static void +static herr_t gen_err_refcount(const char *fname) { - hid_t fid = H5I_INVALID_HID; /* File identifier */ - hid_t sid = H5I_INVALID_HID; /* Dataspace message */ - hid_t did = H5I_INVALID_HID; /* Dataset identifier */ - hid_t gid = H5I_INVALID_HID; /* Group identifier */ - hid_t aid1 = -1, aid2 = H5I_INVALID_HID; /* Attribute identifier */ - hid_t tid = H5I_INVALID_HID; /* Datatype identifier */ - int i, n; /* Local index variables */ - int buf[10]; /* Data buffer */ - hsize_t dims[1]; /* Dimension size */ - int fd = -1; /* File descriptor */ - unsigned short val = 22; /* The refcount message ID */ + hid_t fid = H5I_INVALID_HID; /* File identifier */ + hid_t sid = H5I_INVALID_HID; /* Dataspace message */ + hid_t did = H5I_INVALID_HID; /* Dataset identifier */ + hid_t gid = H5I_INVALID_HID; /* Group identifier */ + hid_t aid1 = H5I_INVALID_HID; /* Attribute identifier */ + hid_t aid2 = H5I_INVALID_HID; /* Attribute identifier */ + hid_t tid = H5I_INVALID_HID; /* Datatype identifier */ + int i, n; /* Local index variables */ + int buf[10]; /* Data buffer */ + hsize_t dims[1]; /* Dimension size */ + int fd = -1; /* File descriptor */ + unsigned short val = 22; /* The refcount message ID */ /* Initialize data buffer */ n = 0; @@ -485,6 +540,10 @@ gen_err_refcount(const char *fname) goto error; if (H5Tclose(tid) < 0) goto error; + + /* Be sure to close this before opening the file again via open(), below, + * or you'll possibly trip over the file locking. + */ if (H5Fclose(fid) < 0) goto error; @@ -495,11 +554,16 @@ gen_err_refcount(const char *fname) with the committed datatype */ /* 24: the offset in the object header containing the version of the attribute message */ - if ((fd = HDopen(fname, O_RDWR, 0633)) >= 0) { - HDlseek(fd, 4520 + 24, SEEK_SET); - (void)HDwrite(fd, &val, 2); - HDclose(fd); - } + if ((fd = HDopen(fname, O_RDWR, 0633)) < 0) + goto error; + if (HDlseek(fd, 4520 + 24, SEEK_SET) < 0) + goto error; + if (HDwrite(fd, &val, 2) < 0) + goto error; + if (HDclose(fd) < 0) + goto error; + + return SUCCEED; error: H5E_BEGIN_TRY @@ -513,6 +577,11 @@ error: H5Fclose(fid); } H5E_END_TRY; + + if (fd >= 0) + HDclose(fd); + + return FAIL; } /* gen_err_refcount() */ /* @@ -542,14 +611,22 @@ error: int main(void) { - gen_newgrat_file(NEWGRAT_FILE); - gen_threshold_file(THRESHOLD_FILE); + if (gen_newgrat_file(NEWGRAT_FILE) < 0) + goto error; + if (gen_threshold_file(THRESHOLD_FILE) < 0) + goto error; /* Generate an HDF file to test for datasets with Fixed Array indexing */ - gen_idx_file(IDX_FILE); + if (gen_idx_file(IDX_FILE) < 0) + goto error; /* Generate a file with a refcount message ID */ - gen_err_refcount(ERR_REFCOUNT_FILE); + if (gen_err_refcount(ERR_REFCOUNT_FILE) < 0) + goto error; + + return EXIT_SUCCESS; - return 0; +error: + HDfprintf(stderr, "h5stat test generator FAILED\n"); + return EXIT_FAILURE; } diff --git a/tools/test/h5stat/testh5stat.sh.in b/tools/test/h5stat/testh5stat.sh.in index 470c381..647f06a 100644 --- a/tools/test/h5stat/testh5stat.sh.in +++ b/tools/test/h5stat/testh5stat.sh.in @@ -304,7 +304,7 @@ TOOLTEST h5stat_links5.ddl -g -l 40000 h5stat_newgrat.h5 # -d --di=15 TOOLTEST h5stat_err1_dims.ddl -d --dims=-1 h5stat_threshold.h5 TOOLTEST h5stat_dims1.ddl -gd -m 5 h5stat_threshold.h5 -TOOLTEST h5stat_dims2.ddl -d --di=15 h5stat_threshold.h5 +TOOLTEST h5stat_dims2.ddl -d --dims=15 h5stat_threshold.h5 # # Tests for -a option on h5stat_threshold.h5 # -a -2 (incorrect threshold value) diff --git a/tools/test/misc/CMakeTestsClear.cmake b/tools/test/misc/CMakeTestsClear.cmake index ec24a61..198a363 100644 --- a/tools/test/misc/CMakeTestsClear.cmake +++ b/tools/test/misc/CMakeTestsClear.cmake @@ -397,7 +397,7 @@ # # The following are tests to verify the expected exit code from h5clear: # "h5clear -m h5clear_mdc_image.h5" (valid option, existing file, succeed exit code) -# "h5clear --vers" (valid option, version #, succeed exit code) +# "h5clear --version" (valid option, version #, succeed exit code) # "h5clear -k" (invalid 1 option, no file, fail exit code) # "h5clear -k junk.h5" (invalid 1 option, nonexisting file, fail exit code) # "h5clear -l h5clear_sec2_v2.h5" (invalid 1 option, existing file, fail exit code) @@ -408,7 +408,7 @@ # "h5clear -m -l h5clear_sec2_v0.h5" (valid/invalid 2 options, existing file, fail exit code) # "h5clear -l -m h5clear_sec2_v0.h5" (invalid/valid 2 options, existing file, fail exit code) ADD_H5_RETTEST (h5clr_mdc_image "false" "-m" h5clear_mdc_image.h5) - ADD_H5_RETTEST (h5clr_vers "false" "--vers") + ADD_H5_RETTEST (h5clr_vers "false" "--version") ADD_H5_RETTEST (h5clr_k "true" "-k") ADD_H5_RETTEST (h5clr_k_junk "true" "-k" junk.h5) ADD_H5_RETTEST (h5clr_l_sec2 "true" "-l" h5clear_sec2_v2.h5) diff --git a/tools/test/misc/testh5clear.sh.in b/tools/test/misc/testh5clear.sh.in index c05e43d..a01fa4a 100644 --- a/tools/test/misc/testh5clear.sh.in +++ b/tools/test/misc/testh5clear.sh.in @@ -315,7 +315,7 @@ TOOLTEST_ERR orig_h5clear_sec2_v0.h5 -s -m "" h5clear_no_mdc_image.err # # The following are tests to verify the expected exit code from h5clear: # "h5clear -m h5clear_mdc_image.h5" (valid option, existing file, succeed exit code) -# "h5clear --vers" (valid option, version #, succeed exit code) +# "h5clear --version" (valid option, version #, succeed exit code) # "h5clear -k" (invalid 1 option, no file, fail exit code) # "h5clear -k junk.h5" (invalid 1 option, nonexisting file, fail exit code) # "h5clear -l h5clear_sec2_v2.h5" (invalid 1 option, existing file, fail exit code) @@ -326,7 +326,7 @@ TOOLTEST_ERR orig_h5clear_sec2_v0.h5 -s -m "" h5clear_no_mdc_image.err # "h5clear -m -l h5clear_sec2_v0.h5" (valid/invalid 2 options, existing file, fail exit code) # "h5clear -l -m h5clear_sec2_v0.h5" (invalid/valid 2 options, existing file, fail exit code) TOOLTEST h5clear_mdc_image.h5 -m "" $SUCCEED -TOOLTEST "" --vers "" $SUCCEED +TOOLTEST "" --version "" $SUCCEED TOOLTEST "" -k "" $FAIL TOOLTEST junk.h5 -k "" $FAIL TOOLTEST h5clear_sec2_v2.h5 -l "" $FAIL diff --git a/tools/test/perform/CMakeLists.txt b/tools/test/perform/CMakeLists.txt index 7399723..7bf79c5 100644 --- a/tools/test/perform/CMakeLists.txt +++ b/tools/test/perform/CMakeLists.txt @@ -4,39 +4,17 @@ project (HDF5_TOOLS_TEST_PERFORM C) # -------------------------------------------------------------------- # Add the executables # -------------------------------------------------------------------- -#-- Adding test for h5perf_serial -set (h5perf_serial_SOURCES - ${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR}/sio_perf.c - ${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR}/sio_engine.c -) -add_executable (h5perf_serial ${h5perf_serial_SOURCES}) -target_include_directories (h5perf_serial PRIVATE "${HDF5_TEST_SRC_DIR};${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") -if (NOT BUILD_SHARED_LIBS) - TARGET_C_PROPERTIES (h5perf_serial STATIC) - target_link_libraries (h5perf_serial PRIVATE ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET}) -else () - TARGET_C_PROPERTIES (h5perf_serial SHARED) - target_link_libraries (h5perf_serial PRIVATE ${HDF5_TOOLS_LIBSH_TARGET} ${HDF5_LIBSH_TARGET}) -endif () -set_target_properties (h5perf_serial PROPERTIES FOLDER perform) - -#----------------------------------------------------------------------------- -# Add Target to clang-format -#----------------------------------------------------------------------------- -if (HDF5_ENABLE_FORMATTERS) - clang_format (HDF5_TOOLS_TEST_PERFORM_h5perf_serial_FORMAT h5perf_serial) -endif () if (HDF5_BUILD_PERFORM_STANDALONE) #-- Adding test for h5perf_serial_alone - io_timer.c includes set (h5perf_serial_alone_SOURCES ${HDF5_TOOLS_DIR}/lib/io_timer.c - ${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR}/sio_perf.c - ${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR}/sio_engine.c + ${HDF5_TOOLS_SRC_H5PERF_SOURCE_DIR}/sio_perf.c + ${HDF5_TOOLS_SRC_H5PERF_SOURCE_DIR}/sio_engine.c ${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR}/sio_standalone.c ) add_executable (h5perf_serial_alone ${h5perf_serial_alone_SOURCES}) - target_include_directories (h5perf_serial_alone PRIVATE "${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};${HDF5_TOOLS_DIR}/lib;$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") + target_include_directories (h5perf_serial_alone PRIVATE "${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};${HDF5_TOOLS_DIR}/lib;${HDF5_TOOLS_SRC_H5PERF_SOURCE_DIR};${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") if (NOT BUILD_SHARED_LIBS) TARGET_C_PROPERTIES (h5perf_serial_alone STATIC) target_link_libraries (h5perf_serial_alone PRIVATE ${HDF5_LIB_TARGET} "$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_LIBRARIES}>") @@ -188,63 +166,16 @@ if (HDF5_ENABLE_FORMATTERS) endif () if (H5_HAVE_PARALLEL AND HDF5_TEST_PARALLEL) - if (UNIX) - #-- Adding test for perf - only on unix systems - set (perf_SOURCES - ${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR}/perf.c - ) - add_executable (perf ${perf_SOURCES}) - target_include_directories (perf PRIVATE "${HDF5_TEST_SRC_DIR};${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") - if (NOT BUILD_SHARED_LIBS) - TARGET_C_PROPERTIES (perf STATIC) - target_link_libraries (perf PRIVATE ${HDF5_TOOLS_LIB_TARGET} ${HDF5_TEST_LIB_TARGET} ${HDF5_LIB_TARGET}) - else () - TARGET_C_PROPERTIES (perf SHARED) - target_link_libraries (perf PRIVATE ${HDF5_TOOLS_LIBSH_TARGET} ${HDF5_TEST_LIBSH_TARGET} ${HDF5_LIBSH_TARGET}) - endif () - set_target_properties (perf PROPERTIES FOLDER perform) - - #----------------------------------------------------------------------------- - # Add Target to clang-format - #----------------------------------------------------------------------------- - if (HDF5_ENABLE_FORMATTERS) - clang_format (HDF5_TOOLS_TEST_PERFORM_perf_FORMAT perf) - endif () - endif () - - #-- Adding test for h5perf - set (h5perf_SOURCES - ${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR}/pio_perf.c - ${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR}/pio_engine.c - ) - add_executable (h5perf ${h5perf_SOURCES}) - target_include_directories (h5perf PRIVATE "${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") - if (NOT BUILD_SHARED_LIBS) - TARGET_C_PROPERTIES (h5perf STATIC) - target_link_libraries (h5perf PRIVATE ${HDF5_TOOLS_LIB_TARGET} ${HDF5_TEST_LIB_TARGET} ${HDF5_LIB_TARGET}) - else () - TARGET_C_PROPERTIES (h5perf SHARED) - target_link_libraries (h5perf PRIVATE ${HDF5_TOOLS_LIBSH_TARGET} ${HDF5_TEST_LIBSH_TARGET} ${HDF5_LIBSH_TARGET}) - endif () - set_target_properties (h5perf PROPERTIES FOLDER perform) - - #----------------------------------------------------------------------------- - # Add Target to clang-format - #----------------------------------------------------------------------------- - if (HDF5_ENABLE_FORMATTERS) - clang_format (HDF5_TOOLS_TEST_PERFORM_h5perf_FORMAT h5perf) - endif () - if (HDF5_BUILD_PERFORM_STANDALONE) #-- Adding test for h5perf set (h5perf_alone_SOURCES ${HDF5_TOOLS_DIR}/lib/io_timer.c - ${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR}/pio_perf.c - ${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR}/pio_engine.c + ${HDF5_TOOLS_SRC_H5PERF_SOURCE_DIR}/pio_perf.c + ${HDF5_TOOLS_SRC_H5PERF_SOURCE_DIR}/pio_engine.c ${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR}/pio_standalone.c ) add_executable (h5perf_alone ${h5perf_alone_SOURCES}) - target_include_directories (h5perf_alone PRIVATE "${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};${HDF5_TOOLS_DIR}/lib;$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") + target_include_directories (h5perf_alone PRIVATE "${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};${HDF5_TOOLS_DIR}/lib;${HDF5_TOOLS_SRC_H5PERF_SOURCE_DIR};${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") if (NOT BUILD_SHARED_LIBS) TARGET_C_PROPERTIES (h5perf_alone STATIC) target_link_libraries (h5perf_alone PRIVATE ${HDF5_LIB_TARGET} ${LINK_LIBS} "$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_LIBRARIES}>") diff --git a/tools/test/perform/Makefile.am b/tools/test/perform/Makefile.am index 244ef3a..10b13fe 100644 --- a/tools/test/perform/Makefile.am +++ b/tools/test/perform/Makefile.am @@ -21,17 +21,6 @@ include $(top_srcdir)/config/commence.am AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/test -I$(top_srcdir)/tools/lib -# bin_PROGRAMS will be installed. -if BUILD_PARALLEL_CONDITIONAL - bin_PROGRAMS=h5perf_serial h5perf -else - bin_PROGRAMS=h5perf_serial -endif - -# Add h5perf and h5perf_serial specific linker flags here -h5perf_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS) -h5perf_serial_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS) - # Some programs are not built or run by default, but can be built by hand or by # specifying --enable-build-all at configure time. # Also, some of these programs should only be built in parallel. @@ -47,18 +36,15 @@ endif # List them in the order they should be run. # Parallel test programs. if BUILD_PARALLEL_CONDITIONAL - TEST_PROG_PARA=h5perf perf + TEST_PROG_PARA= endif # Serial test programs. -TEST_PROG = iopipe chunk chunk_cache overhead zip_perf perf_meta h5perf_serial $(BUILD_ALL_PROGS) +TEST_PROG = iopipe chunk chunk_cache overhead zip_perf perf_meta $(BUILD_ALL_PROGS) # check_PROGRAMS will be built but not installed. Do not any executable # that is in bin_PROGRAMS already. Otherwise, it will be removed twice in # "make clean" and some systems, e.g., AIX, do not like it. -check_PROGRAMS= iopipe chunk chunk_cache overhead zip_perf perf_meta $(BUILD_ALL_PROGS) perf - -h5perf_SOURCES=pio_perf.c pio_engine.c -h5perf_serial_SOURCES=sio_perf.c sio_engine.c +check_PROGRAMS= $(TEST_PROG) $(BUILD_ALL_PROGS) # These are the files that `make clean' (and derivatives) will remove from # this directory. @@ -67,9 +53,6 @@ CLEANFILES=*.h5 *.raw *.dat x-gnuplot perftest.out # All of the programs depend on the main hdf5 library, and some of them # depend on test or tools library. LDADD=$(LIBHDF5) -h5perf_LDADD=$(LIBH5TOOLS) $(LIBH5TEST) $(LIBHDF5) -h5perf_serial_LDADD=$(LIBH5TOOLS) $(LIBH5TEST) $(LIBHDF5) -perf_LDADD=$(LIBH5TEST) $(LIBHDF5) iopipe_LDADD=$(LIBH5TEST) $(LIBHDF5) zip_perf_LDADD=$(LIBH5TOOLS) $(LIBH5TEST) $(LIBHDF5) perf_meta_LDADD=$(LIBH5TEST) $(LIBHDF5) diff --git a/tools/test/perform/chunk_cache.c b/tools/test/perform/chunk_cache.c index 25fa34c..b515961 100644 --- a/tools/test/perform/chunk_cache.c +++ b/tools/test/perform/chunk_cache.c @@ -26,9 +26,9 @@ #define RANK 2 #define DSET1_NAME "partial_chunks" -#define DSET1_DIM1 9 * 1000 +#define DSET1_DIM1 (9 * 1000) #define DSET1_DIM2 9 -#define CHUNK1_DIM1 2 * 1000 +#define CHUNK1_DIM1 (2 * 1000) #define CHUNK1_DIM2 2 #define DSET2_NAME "hash_value" @@ -38,7 +38,7 @@ #define CHUNK2_DIM2 100 #define RDCC_NSLOTS 5 -#define RDCC_NBYTES 1024 * 1024 * 10 +#define RDCC_NBYTES (1024 * 1024 * 10) #define RDCC_W0 0.75F #define FILTER_COUNTER 306 diff --git a/tools/test/perform/perf.c b/tools/test/perform/perf.c deleted file mode 100644 index 875f932..0000000 --- a/tools/test/perform/perf.c +++ /dev/null @@ -1,471 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * Copyright by the Board of Trustees of the University of Illinois. * - * All rights reserved. * - * * - * This file is part of HDF5. The full HDF5 copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the 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. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Author: Albert Cheng of NCSA, May 1, 2001. - * This is derived from code given to me by Robert Ross. - * - * NOTE: This code assumes that all command line arguments make it out to all - * the processes that make up the parallel job, which isn't always the case. - * So if it doesn't work on some platform, that might be why. - */ - -#include "hdf5.h" -#include "H5private.h" -#include "h5test.h" - -#ifdef H5_HAVE_PARALLEL - -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#ifdef H5_HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -#ifdef H5_HAVE_SYS_TIME_H -#include <sys/time.h> -#endif - -#ifdef H5_HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif - -#ifdef H5_HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <mpi.h> -#ifndef MPI_FILE_NULL /*MPIO may be defined in mpi.h already */ -#include <mpio.h> -#endif - -/* Macro definitions */ -/* Verify: - * if val is false (0), print mesg and if fatal is true (non-zero), die. - */ -#define H5FATAL 1 -#define VRFY(val, mesg, fatal) \ - do { \ - if (!val) { \ - printf("Proc %d: ", mynod); \ - printf("*** Assertion failed (%s) at line %4d in %s\n", mesg, (int)__LINE__, __FILE__); \ - if (fatal) { \ - fflush(stdout); \ - goto die_jar_jar_die; \ - } \ - } \ - } while (0) -#define RANK 1 -#define MAX_PATH 1024 - -hsize_t dims[RANK]; /* dataset dim sizes */ -hsize_t block[RANK], stride[RANK], count[RANK]; -hsize_t start[RANK]; -hid_t fid; /* HDF5 file ID */ -hid_t acc_tpl; /* File access templates */ -hid_t sid; /* Dataspace ID */ -hid_t file_dataspace; /* File dataspace ID */ -hid_t mem_dataspace; /* memory dataspace ID */ -hid_t dataset; /* Dataset ID */ -hsize_t opt_alignment = 1; -hsize_t opt_threshold = 1; -int opt_split_vfd = 0; -char * meta_ext, *raw_ext; /* holds the meta and raw file extension if */ - /* opt_split_vfd is set */ - -/* DEFAULT VALUES FOR OPTIONS */ -int64_t opt_block = 1048576 * 16; -int opt_iter = 1; -int opt_stripe = -1; -int opt_correct = 0; -int amode = O_RDWR | O_CREAT; -char opt_file[256] = "perftest.out"; -char opt_pvfstab[256] = "notset"; -int opt_pvfstab_set = 0; - -const char *FILENAME[] = {opt_file, NULL}; - -/* function prototypes */ -static int parse_args(int argc, char **argv); - -#ifndef H5_HAVE_UNISTD_H -/* globals needed for getopt */ -extern char *optarg; -#endif - -int -main(int argc, char **argv) -{ - char * buf, *tmp, *buf2 = NULL, *tmp2 = NULL, *check; - int i, j, mynod = 0, nprocs = 1, my_correct = 1, correct, myerrno; - double stim, etim; - double write_tim = 0; - double read_tim = 0; - double read_bw, write_bw; - double max_read_tim, max_write_tim; - double min_read_tim, min_write_tim; - double ave_read_tim, ave_write_tim; - int64_t iter_jump = 0; - char filename[MAX_PATH]; - herr_t ret; /* Generic return value */ - - /* startup MPI and determine the rank of this process */ - MPI_Init(&argc, &argv); - MPI_Comm_size(MPI_COMM_WORLD, &nprocs); - MPI_Comm_rank(MPI_COMM_WORLD, &mynod); - - /* parse the command line arguments */ - parse_args(argc, argv); - - if (mynod == 0) - printf("# Using hdf5-io calls.\n"); - -#ifdef H5_HAVE_UNISTD_H - /* Kind of a weird hack- if the location of the pvfstab file was - * specified on the command line, then spit out this location into - * the appropriate environment variable. - */ - if (opt_pvfstab_set) { - if ((setenv("PVFSTAB_FILE", opt_pvfstab, 1)) < 0) { - perror("setenv"); - goto die_jar_jar_die; - } - } -#endif - - /* this is how much of the file data is covered on each iteration of - * the test. used to help determine the seek offset on each - * iteration */ - iter_jump = nprocs * opt_block; - - /* setup a buffer of data to write */ - if (!(tmp = (char *)malloc((size_t)opt_block + 256))) { - perror("malloc"); - goto die_jar_jar_die; - } - buf = tmp + 128 - (((long)tmp) % 128); /* align buffer */ - - if (opt_correct) { - /* do the same buffer setup for verifiable data */ - if (!(tmp2 = (char *)malloc((size_t)opt_block + 256))) { - perror("malloc2"); - goto die_jar_jar_die; - } - buf2 = tmp + 128 - (((long)tmp) % 128); - } - - /* setup file access template with parallel IO access. */ - if (opt_split_vfd) { - hid_t mpio_pl; - - mpio_pl = H5Pcreate(H5P_FILE_ACCESS); - VRFY((acc_tpl >= 0), "", H5FATAL); - ret = H5Pset_fapl_mpio(mpio_pl, MPI_COMM_WORLD, MPI_INFO_NULL); - VRFY((ret >= 0), "", H5FATAL); - - /* set optional allocation alignment */ - if (opt_alignment * opt_threshold != 1) { - ret = H5Pset_alignment(acc_tpl, opt_threshold, opt_alignment); - VRFY((ret >= 0), "H5Pset_alignment succeeded", !H5FATAL); - } - - /* setup file access template */ - acc_tpl = H5Pcreate(H5P_FILE_ACCESS); - VRFY((acc_tpl >= 0), "", H5FATAL); - ret = H5Pset_fapl_split(acc_tpl, meta_ext, mpio_pl, raw_ext, mpio_pl); - VRFY((ret >= 0), "H5Pset_fapl_split succeeded", H5FATAL); - ret = H5Pclose(mpio_pl); - VRFY((ret >= 0), "H5Pclose mpio_pl succeeded", H5FATAL); - } - else { - /* setup file access template */ - acc_tpl = H5Pcreate(H5P_FILE_ACCESS); - VRFY((acc_tpl >= 0), "", H5FATAL); - ret = H5Pset_fapl_mpio(acc_tpl, MPI_COMM_WORLD, MPI_INFO_NULL); - VRFY((ret >= 0), "", H5FATAL); - - /* set optional allocation alignment */ - if (opt_alignment * opt_threshold != 1) { - ret = H5Pset_alignment(acc_tpl, opt_threshold, opt_alignment); - VRFY((ret >= 0), "H5Pset_alignment succeeded", !H5FATAL); - } - } - - h5_fixname_no_suffix(FILENAME[0], acc_tpl, filename, sizeof filename); - - /* create the parallel file */ - fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl); - VRFY((fid >= 0), "H5Fcreate succeeded", H5FATAL); - - /* define a contiquous dataset of opt_iter*nprocs*opt_block chars */ - dims[0] = (hsize_t)opt_iter * (hsize_t)nprocs * (hsize_t)opt_block; - sid = H5Screate_simple(RANK, dims, NULL); - VRFY((sid >= 0), "H5Screate_simple succeeded", H5FATAL); - dataset = H5Dcreate2(fid, "Dataset1", H5T_NATIVE_CHAR, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - VRFY((dataset >= 0), "H5Dcreate2 succeeded", H5FATAL); - - /* create the memory dataspace and the file dataspace */ - dims[0] = (hsize_t)opt_block; - mem_dataspace = H5Screate_simple(RANK, dims, NULL); - VRFY((mem_dataspace >= 0), "", H5FATAL); - file_dataspace = H5Dget_space(dataset); - VRFY((file_dataspace >= 0), "H5Dget_space succeeded", H5FATAL); - - /* now each process writes a block of opt_block chars in round robbin - * fashion until the whole dataset is covered. - */ - for (j = 0; j < opt_iter; j++) { - /* setup a file dataspace selection */ - start[0] = (hsize_t)((j * iter_jump) + (mynod * opt_block)); - stride[0] = block[0] = (hsize_t)opt_block; - count[0] = 1; - ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block); - VRFY((ret >= 0), "H5Sset_hyperslab succeeded", H5FATAL); - - if (opt_correct) /* fill in buffer for iteration */ { - for (i = mynod + j, check = buf; i < opt_block; i++, check++) - *check = (char)i; - } - - /* discover the starting time of the operation */ - MPI_Barrier(MPI_COMM_WORLD); - stim = MPI_Wtime(); - - /* write data */ - ret = H5Dwrite(dataset, H5T_NATIVE_CHAR, mem_dataspace, file_dataspace, H5P_DEFAULT, buf); - VRFY((ret >= 0), "H5Dwrite dataset1 succeeded", !H5FATAL); - - /* discover the ending time of the operation */ - etim = MPI_Wtime(); - - write_tim += (etim - stim); - - /* we are done with this "write" iteration */ - } - - /* close dataset and file */ - ret = H5Dclose(dataset); - VRFY((ret >= 0), "H5Dclose succeeded", H5FATAL); - ret = H5Fclose(fid); - VRFY((ret >= 0), "H5Fclose succeeded", H5FATAL); - - /* wait for everyone to synchronize at this point */ - MPI_Barrier(MPI_COMM_WORLD); - - /* reopen the file for reading */ - fid = H5Fopen(filename, H5F_ACC_RDONLY, acc_tpl); - VRFY((fid >= 0), "", H5FATAL); - - /* open the dataset */ - dataset = H5Dopen2(fid, "Dataset1", H5P_DEFAULT); - VRFY((dataset >= 0), "H5Dopen succeeded", H5FATAL); - - /* we can re-use the same mem_dataspace and file_dataspace - * the H5Dwrite used since the dimension size is the same. - */ - - /* we are going to repeat the read the same pattern the write used */ - for (j = 0; j < opt_iter; j++) { - /* setup a file dataspace selection */ - start[0] = (hsize_t)((j * iter_jump) + (mynod * opt_block)); - stride[0] = block[0] = (hsize_t)opt_block; - count[0] = 1; - ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block); - VRFY((ret >= 0), "H5Sset_hyperslab succeeded", H5FATAL); - /* seek to the appropriate spot give the current iteration and - * rank within the MPI processes */ - - /* discover the start time */ - MPI_Barrier(MPI_COMM_WORLD); - stim = MPI_Wtime(); - - /* read in the file data */ - if (!opt_correct) { - ret = H5Dread(dataset, H5T_NATIVE_CHAR, mem_dataspace, file_dataspace, H5P_DEFAULT, buf); - } - else { - ret = H5Dread(dataset, H5T_NATIVE_CHAR, mem_dataspace, file_dataspace, H5P_DEFAULT, buf2); - } - myerrno = errno; - - /* discover the end time */ - etim = MPI_Wtime(); - read_tim += (etim - stim); - VRFY((ret >= 0), "H5Dwrite dataset1 succeeded", !H5FATAL); - - if (ret < 0) - HDfprintf(stderr, "node %d, read error, loc = %" PRId64 ": %s\n", mynod, mynod * opt_block, - strerror(myerrno)); - - /* if the user wanted to check correctness, compare the write - * buffer to the read buffer */ - if (opt_correct && memcmp(buf, buf2, (size_t)opt_block)) { - HDfprintf(stderr, "node %d, correctness test failed\n", mynod); - my_correct = 0; - MPI_Allreduce(&my_correct, &correct, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD); - } - - /* we are done with this read iteration */ - } - - /* close dataset and file */ - ret = H5Dclose(dataset); - VRFY((ret >= 0), "H5Dclose succeeded", H5FATAL); - ret = H5Fclose(fid); - VRFY((ret >= 0), "H5Fclose succeeded", H5FATAL); - ret = H5Pclose(acc_tpl); - VRFY((ret >= 0), "H5Pclose succeeded", H5FATAL); - - /* compute the read and write times */ - MPI_Allreduce(&read_tim, &max_read_tim, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); - MPI_Allreduce(&read_tim, &min_read_tim, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); - MPI_Allreduce(&read_tim, &ave_read_tim, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - - /* calculate the average from the sum */ - ave_read_tim = ave_read_tim / nprocs; - - MPI_Allreduce(&write_tim, &max_write_tim, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); - MPI_Allreduce(&write_tim, &min_write_tim, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); - MPI_Allreduce(&write_tim, &ave_write_tim, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - - /* calculate the average from the sum */ - ave_write_tim = ave_write_tim / nprocs; - - /* print out the results on one node */ - if (mynod == 0) { - read_bw = (double)((int64_t)(opt_block * nprocs * opt_iter)) / (max_read_tim * 1000000.0); - write_bw = (double)((int64_t)(opt_block * nprocs * opt_iter)) / (max_write_tim * 1000000.0); - - printf("nr_procs = %d, nr_iter = %d, blk_sz = %ld\n", nprocs, opt_iter, (long)opt_block); - - printf("# total_size = %ld\n", (long)(opt_block * nprocs * opt_iter)); - - printf("# Write: min_time = %f, max_time = %f, mean_time = %f\n", min_write_tim, max_write_tim, - ave_write_tim); - printf("# Read: min_time = %f, max_time = %f, mean_time = %f\n", min_read_tim, max_read_tim, - ave_read_tim); - - printf("Write bandwidth = %f Mbytes/sec\n", write_bw); - printf("Read bandwidth = %f Mbytes/sec\n", read_bw); - - if (opt_correct) { - printf("Correctness test %s.\n", correct ? "passed" : "failed"); - } - } - -die_jar_jar_die: - -#ifdef H5_HAVE_UNISTD - /* Clear the environment variable if it was set earlier */ - if (opt_pvfstab_set) { - unsetenv("PVFSTAB_FILE"); - } -#endif - - free(tmp); - if (opt_correct) - free(tmp2); - - MPI_Finalize(); - - return (0); -} - -static int -parse_args(int argc, char **argv) -{ - int c; - - while ((c = getopt(argc, argv, "s:b:i:f:p:a:2:c")) != EOF) { - switch (c) { - case 's': /* stripe */ - opt_stripe = atoi(optarg); - break; - case 'b': /* block size */ - opt_block = atoi(optarg); - break; - case 'i': /* iterations */ - opt_iter = atoi(optarg); - break; - case 'f': /* filename */ - strncpy(opt_file, optarg, 255); - FILENAME[0] = opt_file; - break; - case 'p': /* pvfstab file */ - strncpy(opt_pvfstab, optarg, 255); - opt_pvfstab_set = 1; - break; - case 'a': /* aligned allocation. - * syntax: -a<alignment>/<threshold> - * e.g., -a4096/512 allocate at 4096 bytes - * boundary if request size >= 512. - */ - { - char *p; - - opt_alignment = (hsize_t)HDatoi(optarg); - if (NULL != (p = (char *)HDstrchr(optarg, '/'))) - opt_threshold = (hsize_t)HDatoi(p + 1); - } - HDfprintf(stdout, "alignment/threshold=%" PRIuHSIZE "/%" PRIuHSIZE "\n", opt_alignment, - opt_threshold); - break; - case '2': /* use 2-files, i.e., split file driver */ - opt_split_vfd = 1; - /* get meta and raw file extension. */ - /* syntax is <raw_ext>,<meta_ext> */ - meta_ext = raw_ext = optarg; - while (*raw_ext != '\0') { - if (*raw_ext == ',') { - *raw_ext = '\0'; - raw_ext++; - break; - } - raw_ext++; - } - printf("split-file-vfd used: %s,%s\n", meta_ext, raw_ext); - break; - case 'c': /* correctness */ - opt_correct = 1; - break; - case '?': /* unknown */ - default: - break; - } - } - - return (0); -} - -/* - * Local variables: - * c-indent-level: 3 - * c-basic-offset: 3 - * tab-width: 3 - * End: - */ - -#else /* H5_HAVE_PARALLEL */ -/* dummy program since H5_HAVE_PARALLEL is not configured in */ -int -main(int H5_ATTR_UNUSED argc, char H5_ATTR_UNUSED **argv) -{ - printf("No parallel performance because parallel is not configured in\n"); - return (0); -} -#endif /* H5_HAVE_PARALLEL */ diff --git a/tools/test/perform/pio_engine.c b/tools/test/perform/pio_engine.c deleted file mode 100644 index cac36d7..0000000 --- a/tools/test/perform/pio_engine.c +++ /dev/null @@ -1,2745 +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. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Author: Albert Cheng of NCSA, Oct 24, 2001. - */ - -#include "hdf5.h" - -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> - -#ifdef H5_HAVE_UNISTD_H -#include <sys/types.h> -#include <unistd.h> -#endif - -#ifdef H5_HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -#ifdef H5_HAVE_PARALLEL - -#include <mpi.h> - -#ifndef MPI_FILE_NULL /*MPIO may be defined in mpi.h already */ -#include <mpio.h> -#endif /* !MPI_FILE_NULL */ - -#include "pio_perf.h" - -/* Macro definitions */ - -#if H5_VERS_MAJOR == 1 && H5_VERS_MINOR == 6 -#define H5DCREATE(fd, name, type, space, dcpl) H5Dcreate(fd, name, type, space, dcpl) -#define H5DOPEN(fd, name) H5Dopen(fd, name) -#else -#define H5DCREATE(fd, name, type, space, dcpl) \ - H5Dcreate2(fd, name, type, space, H5P_DEFAULT, dcpl, H5P_DEFAULT) -#define H5DOPEN(fd, name) H5Dopen2(fd, name, H5P_DEFAULT) -#endif - -/* sizes of various items. these sizes won't change during program execution */ -/* The following three must have the same type */ -#define ELMT_H5_TYPE H5T_NATIVE_UCHAR - -#define GOTOERROR(errcode) \ - { \ - ret_code = errcode; \ - goto done; \ - } -#define ERRMSG(mesg) \ - { \ - HDfprintf(stderr, "Proc %d: ", pio_mpi_rank_g); \ - HDfprintf(stderr, "*** Assertion failed (%s) at line %4d in %s\n", mesg, (int)__LINE__, __FILE__); \ - } - -/* verify: if val is false (0), print mesg. */ -#define VRFY(val, mesg) \ - do { \ - if (!val) { \ - ERRMSG(mesg); \ - GOTOERROR(FAIL); \ - } \ - } while (0) - -/* POSIX I/O macros */ -#ifdef H5_HAVE_WIN32_API -/* Can't link against the library, so this test will use the older, non-Unicode - * _open() call on Windows. - */ -#define HDopen(S, F, ...) _open(S, F | _O_BINARY, __VA_ARGS__) -#endif /* H5_HAVE_WIN32_API */ -#define POSIXCREATE(fn) HDopen(fn, O_CREAT | O_TRUNC | O_RDWR, 0600) -#define POSIXOPEN(fn, F) HDopen(fn, F, 0600) -#define POSIXCLOSE(F) HDclose(F) -#define POSIXSEEK(F, L) HDlseek(F, L, SEEK_SET) -#define POSIXWRITE(F, B, S) HDwrite(F, B, S) -#define POSIXREAD(F, B, S) HDread(F, B, S) - -enum { PIO_CREATE = 1, PIO_WRITE = 2, PIO_READ = 4 }; - -/* Global variables */ -static int clean_file_g = -1; /*whether to cleanup temporary test */ -/*files. -1 is not defined; */ -/*0 is no cleanup; 1 is do cleanup */ - -/* - * In a parallel machine, the filesystem suitable for compiling is - * unlikely a parallel file system that is suitable for parallel I/O. - * There is no standard pathname for the parallel file system. /tmp - * is about the best guess. - */ -#ifndef HDF5_PARAPREFIX -#define HDF5_PARAPREFIX "" -#endif /* !HDF5_PARAPREFIX */ - -#ifndef MIN -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#endif /* !MIN */ - -/* the different types of file descriptors we can expect */ -typedef union _file_descr { - int posixfd; /* POSIX file handle*/ - MPI_File mpifd; /* MPI file */ - hid_t h5fd; /* HDF5 file */ -} file_descr; - -/* local functions */ -static char * pio_create_filename(iotype iot, const char *base_name, char *fullname, size_t size); -static herr_t do_write(results *res, file_descr *fd, parameters *parms, long ndsets, off_t nelmts, - size_t buf_size, void *buffer); -static herr_t do_read(results *res, file_descr *fd, parameters *parms, long ndsets, off_t nelmts, - size_t buf_size, void *buffer /*out*/); -static herr_t do_fopen(parameters *param, char *fname, file_descr *fd /*out*/, int flags); -static herr_t do_fclose(iotype iot, file_descr *fd); -static void do_cleanupfile(iotype iot, char *fname); -static off_t sqrto(off_t); - -/* - * Function: do_pio - * Purpose: PIO Engine where Parallel IO are executed. - * Return: results - * Programmer: Albert Cheng, Bill Wendling 2001/12/12 - * Modifications: - * Added 2D testing (Christian Chilan, 10. August 2005) - */ -results -do_pio(parameters param) -{ - /* return codes */ - herr_t ret_code = 0; /*return code */ - results res; - - file_descr fd; - iotype iot; - - char fname[FILENAME_MAX]; - long nf; - long ndsets; - off_t nbytes; /*number of bytes per dataset */ - off_t snbytes; /*general dataset size */ - /*for 1D, it is the actual dataset size */ - /*for 2D, it is the size of a side of the dataset square */ - char * buffer = NULL; /*data buffer pointer */ - size_t buf_size; /*general buffer size in bytes */ - /*for 1D, it is the actual buffer size */ - /*for 2D, it is the length of the buffer rectangle */ - size_t blk_size; /*data block size in bytes */ - size_t bsize; /*actual buffer size */ - - /* HDF5 variables */ - herr_t hrc; /*HDF5 return code */ - - /* Sanity check parameters */ - - /* IO type */ - iot = param.io_type; - - switch (iot) { - case MPIO: - fd.mpifd = MPI_FILE_NULL; - res.timers = io_time_new(MPI_CLOCK); - break; - case POSIXIO: - fd.posixfd = -1; - res.timers = io_time_new(MPI_CLOCK); - break; - case PHDF5: - fd.h5fd = -1; - res.timers = io_time_new(MPI_CLOCK); - break; - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", iot); - GOTOERROR(FAIL); - } - - ndsets = param.num_dsets; /* number of datasets per file */ - nbytes = param.num_bytes; /* number of bytes per dataset */ - buf_size = param.buf_size; - blk_size = param.blk_size; - - if (!param.dim2d) { - snbytes = nbytes; /* General dataset size */ - bsize = buf_size; /* Actual buffer size */ - } - else { - snbytes = sqrto(nbytes); /* General dataset size */ - bsize = buf_size * blk_size; /* Actual buffer size */ - } - - if (param.num_files < 0) { - HDfprintf(stderr, "number of files must be >= 0 (%ld)\n", param.num_files); - GOTOERROR(FAIL); - } - - if (ndsets < 0) { - HDfprintf(stderr, "number of datasets per file must be >= 0 (%ld)\n", ndsets); - GOTOERROR(FAIL); - } - - if (param.num_procs <= 0) { - HDfprintf(stderr, "maximum number of process to use must be > 0 (%d)\n", param.num_procs); - GOTOERROR(FAIL); - } - - /* Validate transfer buffer size & block size*/ - if (blk_size <= 0) { - HDfprintf(stderr, "Transfer block size (%zu) must be > 0\n", blk_size); - GOTOERROR(FAIL); - } - if (buf_size <= 0) { - HDfprintf(stderr, "Transfer buffer size (%zu) must be > 0\n", buf_size); - GOTOERROR(FAIL); - } - if ((buf_size % blk_size) != 0) { - HDfprintf(stderr, - "Transfer buffer size (%zu) must be a multiple of the " - "interleaved I/O block size (%zu)\n", - buf_size, blk_size); - GOTOERROR(FAIL); - } - if ((snbytes % pio_mpi_nprocs_g) != 0) { - HDfprintf(stderr, - "Dataset size (%" H5_PRINTF_LL_WIDTH "d) must be a multiple of the " - "number of processes (%d)\n", - (long long)snbytes, pio_mpi_nprocs_g); - GOTOERROR(FAIL); - } - - if (!param.dim2d) { - if (((size_t)(snbytes / pio_mpi_nprocs_g) % buf_size) != 0) { - HDfprintf(stderr, - "Dataset size/process (%" H5_PRINTF_LL_WIDTH "d) must be a multiple of the " - "trasfer buffer size (%zu)\n", - (long long)(snbytes / pio_mpi_nprocs_g), buf_size); - GOTOERROR(FAIL); - } - } - else { - if (((size_t)snbytes % buf_size) != 0) { - HDfprintf(stderr, - "Dataset side size (%" H5_PRINTF_LL_WIDTH "d) must be a multiple of the " - "trasfer buffer size (%zu)\n", - (long long)snbytes, buf_size); - GOTOERROR(FAIL); - } - } - - /* Allocate transfer buffer */ - if ((buffer = malloc(bsize)) == NULL) { - HDfprintf(stderr, "malloc for transfer buffer size (%zu) failed\n", bsize); - GOTOERROR(FAIL); - } - - if (pio_debug_level >= 4) { - int myrank; - - MPI_Comm_rank(pio_comm_g, &myrank); - - /* output all of the times for all iterations */ - if (myrank == 0) - HDfprintf(output, "Timer details:\n"); - } - - for (nf = 1; nf <= param.num_files; nf++) { - /* - * Write performance measurement - */ - /* Open file for write */ - char base_name[256]; - - HDsprintf(base_name, "#pio_tmp_%lu", nf); - pio_create_filename(iot, base_name, fname, sizeof(fname)); - if (pio_debug_level > 0) - HDfprintf(output, "rank %d: data filename=%s\n", pio_mpi_rank_g, fname); - - /* Need barrier to make sure everyone starts at the same time */ - MPI_Barrier(pio_comm_g); - - io_time_set(res.timers, HDF5_GROSS_WRITE_FIXED_DIMS, TSTART); - hrc = do_fopen(¶m, fname, &fd, PIO_CREATE | PIO_WRITE); - - VRFY((hrc == SUCCESS), "do_fopen failed"); - - io_time_set(res.timers, HDF5_FINE_WRITE_FIXED_DIMS, TSTART); - hrc = do_write(&res, &fd, ¶m, ndsets, nbytes, buf_size, buffer); - io_time_set(res.timers, HDF5_FINE_WRITE_FIXED_DIMS, TSTOP); - - VRFY((hrc == SUCCESS), "do_write failed"); - - /* Close file for write */ - hrc = do_fclose(iot, &fd); - - io_time_set(res.timers, HDF5_GROSS_WRITE_FIXED_DIMS, TSTOP); - VRFY((hrc == SUCCESS), "do_fclose failed"); - - if (!param.h5_write_only) { - /* - * Read performance measurement - */ - /* Need barrier to make sure everyone is done writing and has - * closed the file. Also to make sure everyone starts reading - * at the same time. - */ - MPI_Barrier(pio_comm_g); - - /* Open file for read */ - io_time_set(res.timers, HDF5_GROSS_READ_FIXED_DIMS, TSTART); - hrc = do_fopen(¶m, fname, &fd, PIO_READ); - - VRFY((hrc == SUCCESS), "do_fopen failed"); - - io_time_set(res.timers, HDF5_FINE_READ_FIXED_DIMS, TSTART); - hrc = do_read(&res, &fd, ¶m, ndsets, nbytes, buf_size, buffer); - io_time_set(res.timers, HDF5_FINE_READ_FIXED_DIMS, TSTOP); - VRFY((hrc == SUCCESS), "do_read failed"); - - /* Close file for read */ - hrc = do_fclose(iot, &fd); - - io_time_set(res.timers, HDF5_GROSS_READ_FIXED_DIMS, TSTOP); - VRFY((hrc == SUCCESS), "do_fclose failed"); - } - - /* Need barrier to make sure everyone is done with the file */ - /* before it may be removed by do_cleanupfile */ - MPI_Barrier(pio_comm_g); - do_cleanupfile(iot, fname); - } - -done: - /* clean up */ - /* release HDF5 objects */ - - /* close any opened files */ - /* no remove(fname) because that should have happened normally. */ - switch (iot) { - case POSIXIO: - if (fd.posixfd != -1) - hrc = do_fclose(iot, &fd); - break; - case MPIO: - if (fd.mpifd != MPI_FILE_NULL) - hrc = do_fclose(iot, &fd); - break; - case PHDF5: - if (fd.h5fd != -1) - hrc = do_fclose(iot, &fd); - break; - default: - break; - } - - /* release generic resources */ - if (buffer) - HDfree(buffer); - res.ret_code = ret_code; - return res; -} - -/* - * Function: pio_create_filename - * Purpose: Create a new filename to write to. Determine the correct - * suffix to append to the filename by the type of I/O we're - * doing. Also, place in the /tmp/{$USER,$LOGIN} directory if - * USER or LOGIN are specified in the environment. - * Return: Pointer to filename or NULL - * Programmer: Bill Wendling, 21. November 2001 - * Modifications: - */ -static char * -pio_create_filename(iotype iot, const char *base_name, char *fullname, size_t size) -{ - const char *prefix, *suffix = ""; - char * ptr, last = '\0'; - size_t i, j; - - if (!base_name || !fullname || size < 1) - return NULL; - - HDmemset(fullname, 0, size); - - switch (iot) { - case POSIXIO: - suffix = ".posix"; - break; - case MPIO: - suffix = ".mpio"; - break; - case PHDF5: - suffix = ".h5"; - break; - default: - break; - } - - /* First use the environment variable and then try the constant */ - prefix = HDgetenv("HDF5_PARAPREFIX"); - -#ifdef HDF5_PARAPREFIX - if (!prefix) - prefix = HDF5_PARAPREFIX; -#endif /* HDF5_PARAPREFIX */ - - /* Prepend the prefix value to the base name */ - if (prefix && *prefix) { - /* If the prefix specifies the HDF5_PARAPREFIX directory, then - * default to using the "/tmp/$USER" or "/tmp/$LOGIN" - * directory instead. */ - register char *user, *login, *subdir; - - user = HDgetenv("USER"); - login = HDgetenv("LOGIN"); - subdir = (user ? user : login); - - if (subdir) { - for (i = 0; i < size - 1 && prefix[i]; i++) - fullname[i] = prefix[i]; - - fullname[i++] = '/'; - - for (j = 0; i < size && subdir[j]; i++, j++) - fullname[i] = subdir[j]; - } - else { - /* We didn't append the prefix yet */ - HDstrncpy(fullname, prefix, size); - fullname[size - 1] = '\0'; - } - - if ((HDstrlen(fullname) + HDstrlen(base_name) + 1) < size) { - /* Append the base_name with a slash first. Multiple slashes are - * handled below. */ - h5_stat_t buf; - - if (HDstat(fullname, &buf) < 0) - /* The directory doesn't exist just yet */ - if (HDmkdir(fullname, (mode_t)0755) < 0 && errno != EEXIST) { - /* We couldn't make the "/tmp/${USER,LOGIN}" subdirectory. - * Default to PREFIX's original prefix value. */ - HDstrcpy(fullname, prefix); - } - - HDstrcat(fullname, "/"); - HDstrcat(fullname, base_name); - } - else { - /* Buffer is too small */ - return NULL; - } - } - else if (HDstrlen(base_name) >= size) { - /* Buffer is too small */ - return NULL; - } - else { - HDstrcpy(fullname, base_name); - } - - /* Append a suffix */ - if (suffix) { - if (HDstrlen(fullname) + HDstrlen(suffix) >= size) - return NULL; - - HDstrcat(fullname, suffix); - } - - /* Remove any double slashes in the filename */ - for (ptr = fullname, i = j = 0; ptr && i < size; i++, ptr++) { - if (*ptr != '/' || last != '/') - fullname[j++] = *ptr; - - last = *ptr; - } - - return fullname; -} - -/* - * Function: do_write - * Purpose: Write the required amount of data to the file. - * Return: SUCCESS or FAIL - * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 - * Modifications: - * Added 2D testing (Christian Chilan, 10. August 2005) - */ -static herr_t -do_write(results *res, file_descr *fd, parameters *parms, long ndsets, off_t nbytes, size_t buf_size, - void *buffer) -{ - int ret_code = SUCCESS; - int rc; /*routine return code */ - long ndset; - size_t blk_size; /* The block size to subdivide the xfer buffer into */ - off_t nbytes_xfer; /* Total number of bytes transferred so far */ - size_t nbytes_xfer_advance; /* Number of bytes transferred in a single I/O operation */ - size_t nbytes_toxfer; /* Number of bytes to transfer a particular time */ - char dname[64]; - off_t dset_offset = 0; /*dataset offset in a file */ - off_t bytes_begin[2]; /*first elmt this process transfer */ - off_t bytes_count; /*number of elmts this process transfer */ - off_t snbytes = 0; /*size of a side of the dataset square */ - unsigned char *buf_p; /* Current buffer pointer */ - - /* POSIX variables */ - off_t file_offset; /* File offset of the next transfer */ - off_t file_offset_advance; /* File offset advance after each I/O operation */ - off_t posix_file_offset; /* Base file offset of the next transfer */ - - /* MPI variables */ - MPI_Offset mpi_file_offset; /* Base file offset of the next transfer*/ - MPI_Offset mpi_offset; /* Offset in MPI file */ - MPI_Offset mpi_offset_advance; /* Offset advance after each I/O operation */ - MPI_Datatype mpi_file_type; /* MPI derived type for 1D file */ - MPI_Datatype mpi_blk_type; /* MPI derived type for 1D buffer */ - MPI_Datatype mpi_cont_type; /* MPI derived type for 2D contiguous file */ - MPI_Datatype mpi_partial_buffer_cont; /* MPI derived type for partial 2D contiguous buffer */ - MPI_Datatype mpi_inter_type; /* MPI derived type for 2D interleaved file */ - MPI_Datatype mpi_partial_buffer_inter; /* MPI derived type for partial 2D interleaved buffer */ - MPI_Datatype mpi_full_buffer; /* MPI derived type for 2D full buffer */ - MPI_Datatype mpi_full_chunk; /* MPI derived type for 2D full chunk */ - MPI_Datatype mpi_chunk_inter_type; /* MPI derived type for 2D chunk interleaved file */ - MPI_Datatype mpi_collective_type; /* Generic MPI derived type for 2D collective access */ - MPI_Status mpi_status; - int mrc; /* MPI return code */ - - /* HDF5 variables */ - herr_t hrc; /*HDF5 return code */ - hsize_t h5dims[2]; /*dataset dim sizes */ - hid_t h5dset_space_id = H5I_INVALID_HID; /*dataset space ID */ - hid_t h5mem_space_id = H5I_INVALID_HID; /*memory dataspace ID */ - hid_t h5ds_id = H5I_INVALID_HID; /*dataset handle */ - hsize_t h5block[2]; /*dataspace selection */ - hsize_t h5stride[2]; - hsize_t h5count[2]; - hsize_t h5start[2]; - hssize_t h5offset[2]; /* Selection offset within dataspace */ - hid_t h5dcpl = H5I_INVALID_HID; /* Dataset creation property list */ - hid_t h5dxpl = H5I_INVALID_HID; /* Dataset transfer property list */ - - /* Get the parameters from the parameter block */ - blk_size = parms->blk_size; - - /* There are two kinds of transfer patterns, contiguous and interleaved. - * Let 0,1,2,...,n be data accessed by process 0,1,2,...,n - * where n is rank of the last process. - * In contiguous pattern, data are accessed as - * 000...111...222...nnn... - * In interleaved pattern, data are accessed as - * 012...n012...n... - * These are all in the scope of one dataset. - */ - - /* 1D dataspace */ - if (!parms->dim2d) { - /* Contiguous Pattern: */ - if (!parms->interleaved) { - bytes_begin[0] = (off_t)(((double)nbytes * pio_mpi_rank_g) / pio_mpi_nprocs_g); - } /* end if */ - /* Interleaved Pattern: */ - else { - bytes_begin[0] = (off_t)(blk_size * (size_t)pio_mpi_rank_g); - } /* end else */ - - /* Prepare buffer for verifying data */ - if (parms->verify) - memset(buffer, pio_mpi_rank_g + 1, buf_size); - } /* end if */ - /* 2D dataspace */ - else { - /* nbytes is always the number of bytes per dataset (1D or 2D). If the - dataspace is 2D, snbytes is the size of a side of the dataset square. - */ - snbytes = sqrto(nbytes); - - /* Contiguous Pattern: */ - if (!parms->interleaved) { - bytes_begin[0] = (off_t)((double)snbytes * pio_mpi_rank_g / pio_mpi_nprocs_g); - bytes_begin[1] = 0; - } /* end if */ - /* Interleaved Pattern: */ - else { - bytes_begin[0] = 0; - - if (!parms->h5_use_chunks || parms->io_type == PHDF5) - bytes_begin[1] = (off_t)(blk_size * (size_t)pio_mpi_rank_g); - else - bytes_begin[1] = (off_t)(blk_size * blk_size * (size_t)pio_mpi_rank_g); - } /* end else */ - - /* Prepare buffer for verifying data */ - if (parms->verify) - HDmemset(buffer, pio_mpi_rank_g + 1, buf_size * blk_size); - } /* end else */ - - /* Calculate the total number of bytes (bytes_count) to be - * transferred by this process. It may be different for different - * transfer pattern due to rounding to integral values. - */ - /* - * Calculate the beginning bytes of this process and the next. - * bytes_count is the difference between these two beginnings. - * This way, it eliminates any rounding errors. - * (This is tricky, don't mess with the formula, rounding errors - * can easily get introduced) */ - bytes_count = (off_t)(((double)nbytes * (pio_mpi_rank_g + 1)) / pio_mpi_nprocs_g) - - (off_t)(((double)nbytes * pio_mpi_rank_g) / pio_mpi_nprocs_g); - - /* debug */ - if (pio_debug_level >= 4) { - HDprint_rank(output); - if (!parms->dim2d) { - HDfprintf(output, - "Debug(do_write): " - "buf_size=%zu, bytes_begin=%" H5_PRINTF_LL_WIDTH "d, bytes_count=%" H5_PRINTF_LL_WIDTH - "d\n", - buf_size, (long long)bytes_begin[0], (long long)bytes_count); - } - else { - HDfprintf(output, - "Debug(do_write): " - "linear buf_size=%zu, bytes_begin=(%" H5_PRINTF_LL_WIDTH "d,%" H5_PRINTF_LL_WIDTH - "d), bytes_count=%" H5_PRINTF_LL_WIDTH "d\n", - buf_size * blk_size, (long long)bytes_begin[0], (long long)bytes_begin[1], - (long long)bytes_count); - } - } - - /* I/O Access specific setup */ - switch (parms->io_type) { - case POSIXIO: - /* No extra setup */ - break; - - case MPIO: /* MPI-I/O setup */ - /* 1D dataspace */ - if (!parms->dim2d) { - /* Build block's derived type */ - mrc = MPI_Type_contiguous((int)blk_size, MPI_BYTE, &mpi_blk_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Build file's derived type */ - mrc = MPI_Type_vector((int)(buf_size / blk_size), (int)1, (int)pio_mpi_nprocs_g, mpi_blk_type, - &mpi_file_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit file type */ - mrc = MPI_Type_commit(&mpi_file_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Commit buffer type */ - mrc = MPI_Type_commit(&mpi_blk_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - } /* end if */ - /* 2D dataspace */ - else { - /* Build partial buffer derived type for contiguous access */ - - mrc = MPI_Type_contiguous((int)buf_size, MPI_BYTE, &mpi_partial_buffer_cont); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit partial buffer derived type */ - mrc = MPI_Type_commit(&mpi_partial_buffer_cont); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build contiguous file's derived type */ - mrc = MPI_Type_vector((int)blk_size, (int)1, (int)((size_t)snbytes / buf_size), - mpi_partial_buffer_cont, &mpi_cont_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit contiguous file type */ - mrc = MPI_Type_commit(&mpi_cont_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build partial buffer derived type for interleaved access */ - mrc = MPI_Type_contiguous((int)blk_size, MPI_BYTE, &mpi_partial_buffer_inter); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit partial buffer derived type */ - mrc = MPI_Type_commit(&mpi_partial_buffer_inter); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build interleaved file's derived type */ - mrc = MPI_Type_vector((int)buf_size, (int)1, (int)((size_t)snbytes / blk_size), - mpi_partial_buffer_inter, &mpi_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit interleaved file type */ - mrc = MPI_Type_commit(&mpi_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build full buffer derived type */ - mrc = MPI_Type_contiguous((int)(blk_size * buf_size), MPI_BYTE, &mpi_full_buffer); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit full buffer derived type */ - mrc = MPI_Type_commit(&mpi_full_buffer); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build full chunk derived type */ - mrc = MPI_Type_contiguous((int)(blk_size * blk_size), MPI_BYTE, &mpi_full_chunk); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit full chunk derived type */ - mrc = MPI_Type_commit(&mpi_full_chunk); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build chunk interleaved file's derived type */ - mrc = MPI_Type_vector((int)(buf_size / blk_size), (int)1, (int)((size_t)snbytes / blk_size), - mpi_full_chunk, &mpi_chunk_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit chunk interleaved file type */ - mrc = MPI_Type_commit(&mpi_chunk_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - } /* end else */ - break; - - case PHDF5: /* HDF5 setup */ - /* 1D dataspace */ - if (!parms->dim2d) { - if (nbytes > 0) { - /* define a contiguous dataset of nbytes native bytes */ - h5dims[0] = (hsize_t)nbytes; - h5dset_space_id = H5Screate_simple(1, h5dims, NULL); - VRFY((h5dset_space_id >= 0), "H5Screate_simple"); - - /* Set up the file dset space id to select the pattern to access */ - if (!parms->interleaved) { - /* Contiguous pattern */ - h5start[0] = (hsize_t)bytes_begin[0]; - h5stride[0] = h5block[0] = blk_size; - h5count[0] = buf_size / blk_size; - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5start[0] = (hsize_t)bytes_begin[0]; - h5stride[0] = blk_size * (size_t)pio_mpi_nprocs_g; - h5block[0] = blk_size; - h5count[0] = buf_size / blk_size; - } /* end else */ - hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, - h5block); - VRFY((hrc >= 0), "H5Sselect_hyperslab"); - } /* end if */ - else { - h5dset_space_id = H5Screate(H5S_SCALAR); - VRFY((h5dset_space_id >= 0), "H5Screate"); - } /* end else */ - - /* Create the memory dataspace that corresponds to the xfer buffer */ - if (buf_size > 0) { - h5dims[0] = buf_size; - h5mem_space_id = H5Screate_simple(1, h5dims, NULL); - VRFY((h5mem_space_id >= 0), "H5Screate_simple"); - } /* end if */ - else { - h5mem_space_id = H5Screate(H5S_SCALAR); - VRFY((h5mem_space_id >= 0), "H5Screate"); - } /* end else */ - } /* end if */ - /* 2D dataspace */ - else { - if (nbytes > 0) { - /* define a contiguous dataset of nbytes native bytes */ - h5dims[0] = (hsize_t)snbytes; - h5dims[1] = (hsize_t)snbytes; - h5dset_space_id = H5Screate_simple(2, h5dims, NULL); - VRFY((h5dset_space_id >= 0), "H5Screate_simple"); - - /* Set up the file dset space id to select the pattern to access */ - if (!parms->interleaved) { - /* Contiguous pattern */ - h5start[0] = (hsize_t)bytes_begin[0]; - h5start[1] = (hsize_t)bytes_begin[1]; - h5stride[0] = 1; - h5stride[1] = h5block[0] = h5block[1] = blk_size; - h5count[0] = 1; - h5count[1] = buf_size / blk_size; - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5start[0] = (hsize_t)bytes_begin[0]; - h5start[1] = (hsize_t)bytes_begin[1]; - h5stride[0] = blk_size; - h5stride[1] = blk_size * (size_t)pio_mpi_nprocs_g; - h5block[0] = h5block[1] = blk_size; - h5count[0] = buf_size / blk_size; - h5count[1] = 1; - } /* end else */ - hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, - h5block); - VRFY((hrc >= 0), "H5Sselect_hyperslab"); - } /* end if */ - else { - h5dset_space_id = H5Screate(H5S_SCALAR); - VRFY((h5dset_space_id >= 0), "H5Screate"); - } /* end else */ - - /* Create the memory dataspace that corresponds to the xfer buffer */ - if (buf_size > 0) { - if (!parms->interleaved) { - h5dims[0] = blk_size; - h5dims[1] = buf_size; - } - else { - h5dims[0] = buf_size; - h5dims[1] = blk_size; - } - h5mem_space_id = H5Screate_simple(2, h5dims, NULL); - VRFY((h5mem_space_id >= 0), "H5Screate_simple"); - } /* end if */ - else { - h5mem_space_id = H5Screate(H5S_SCALAR); - VRFY((h5mem_space_id >= 0), "H5Screate"); - } /* end else */ - } /* end else */ - - /* Create the dataset transfer property list */ - h5dxpl = H5Pcreate(H5P_DATASET_XFER); - if (h5dxpl < 0) { - HDfprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - - /* Change to collective I/O, if asked */ - if (parms->collective) { - hrc = H5Pset_dxpl_mpio(h5dxpl, H5FD_MPIO_COLLECTIVE); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Property List Set failed\n"); - GOTOERROR(FAIL); - } /* end if */ - } /* end if */ - break; - - default: - break; - } /* end switch */ - - for (ndset = 1; ndset <= ndsets; ++ndset) { - - /* Calculate dataset offset within a file */ - - /* create dataset */ - switch (parms->io_type) { - case POSIXIO: - case MPIO: - /* both posix and mpi io just need dataset offset in file*/ - dset_offset = (ndset - 1) * nbytes; - break; - - case PHDF5: - h5dcpl = H5Pcreate(H5P_DATASET_CREATE); - if (h5dcpl < 0) { - HDfprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - /* 1D dataspace */ - if (!parms->dim2d) { - /* Make the dataset chunked if asked */ - if (parms->h5_use_chunks) { - /* Set the chunk size to be the same as the buffer size */ - h5dims[0] = blk_size; - hrc = H5Pset_chunk(h5dcpl, 1, h5dims); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Property List Set failed\n"); - GOTOERROR(FAIL); - } /* end if */ - } /* end if */ - } /* end if */ - else { - /* 2D dataspace */ - if (parms->h5_use_chunks) { - /* Set the chunk size to be the same as the block size */ - h5dims[0] = blk_size; - h5dims[1] = blk_size; - hrc = H5Pset_chunk(h5dcpl, 2, h5dims); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Property List Set failed\n"); - GOTOERROR(FAIL); - } /* end if */ - } /* end if */ - } /* end else */ - - HDsprintf(dname, "Dataset_%ld", ndset); - h5ds_id = H5DCREATE(fd->h5fd, dname, ELMT_H5_TYPE, h5dset_space_id, h5dcpl); - - if (h5ds_id < 0) { - HDfprintf(stderr, "HDF5 Dataset Create failed\n"); - GOTOERROR(FAIL); - } - - hrc = H5Pclose(h5dcpl); - /* verifying the close of the dcpl */ - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Property List Close failed\n"); - GOTOERROR(FAIL); - } - break; - - default: - break; - } - - /* The task is to transfer bytes_count bytes, starting at - * bytes_begin position, using transfer buffer of buf_size bytes. - * If interleaved, select buf_size at a time, in round robin - * fashion, according to number of process. Otherwise, select - * all bytes_count in contiguous. - */ - nbytes_xfer = 0; - - /* 1D dataspace */ - if (!parms->dim2d) { - /* Set base file offset for all I/O patterns and POSIX access */ - posix_file_offset = dset_offset + bytes_begin[0]; - - /* Set base file offset for all I/O patterns and MPI access */ - mpi_file_offset = (MPI_Offset)(dset_offset + bytes_begin[0]); - } /* end if */ - else { - /* Set base file offset for all I/O patterns and POSIX access */ - posix_file_offset = dset_offset + bytes_begin[0] * snbytes + bytes_begin[1]; - - /* Set base file offset for all I/O patterns and MPI access */ - mpi_file_offset = (MPI_Offset)(dset_offset + bytes_begin[0] * snbytes + bytes_begin[1]); - } /* end else */ - - /* Start "raw data" write timer */ - io_time_set(res->timers, HDF5_RAW_WRITE_FIXED_DIMS, TSTART); - - while (nbytes_xfer < bytes_count) { - /* Write */ - /* Calculate offset of write within a dataset/file */ - switch (parms->io_type) { - case POSIXIO: - /* 1D dataspace */ - if (!parms->dim2d) { - /* Contiguous pattern */ - if (!parms->interleaved) { - /* Compute file offset */ - file_offset = posix_file_offset + (off_t)nbytes_xfer; - - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; - VRFY((rc == 0), "POSIXSEEK"); - - /* check if all bytes are written */ - rc = ((ssize_t)buf_size == POSIXWRITE(fd->posixfd, buffer, buf_size)); - VRFY((rc != 0), "POSIXWRITE"); - - /* Advance global offset in dataset */ - nbytes_xfer += (ssize_t)buf_size; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Set the base of user's buffer */ - buf_p = (unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size; - - /* Loop over the buffers to write */ - while (nbytes_toxfer > 0) { - /* Skip offset over blocks of other processes */ - file_offset = posix_file_offset + (off_t)(nbytes_xfer * pio_mpi_nprocs_g); - - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; - VRFY((rc == 0), "POSIXSEEK"); - - /* check if all bytes are written */ - rc = ((ssize_t)blk_size == POSIXWRITE(fd->posixfd, buf_p, blk_size)); - VRFY((rc != 0), "POSIXWRITE"); - - /* Advance location in buffer */ - buf_p += blk_size; - - /* Advance global offset in dataset */ - nbytes_xfer += (ssize_t)blk_size; - - /* Decrement number of bytes left this time */ - nbytes_toxfer -= blk_size; - } /* end while */ - } /* end else */ - } /* end if */ - /* 2D dataspace */ - else { - /* Contiguous storage */ - if (!parms->h5_use_chunks) { - /* Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute file offset */ - file_offset = posix_file_offset + - (off_t)((((size_t)nbytes_xfer / blk_size) / (size_t)snbytes) * - (blk_size * (size_t)snbytes) + - (((size_t)nbytes_xfer / blk_size) % (size_t)snbytes)); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = buf_size; - - /* Global offset advance after each I/O operation */ - file_offset_advance = (off_t)snbytes; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Compute file offset */ - file_offset = - posix_file_offset + - (off_t)(((((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) / - (size_t)snbytes) * - (buf_size * (size_t)snbytes) + - (((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) % - (size_t)snbytes); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size; - - /* Global offset advance after each I/O operation */ - file_offset_advance = (off_t)snbytes; - } /* end else */ - } /* end if */ - /* Chunked storage */ - else { - /*Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute file offset */ - file_offset = posix_file_offset + (off_t)nbytes_xfer; - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * buf_size; - - /* Global offset advance after each I/O operation */ - file_offset_advance = 0; - } /* end if */ - /*Interleaved access pattern */ - else { - /* Compute file offset */ - /* Before simplification */ - /* file_offset=posix_file_offset+(off_t)((nbytes_xfer/(buf_size/blk_size) - *pio_mpi_nprocs_g)/(snbytes/blk_size*(blk_size*blk_size))*(buf_size/blk_size - *snbytes/blk_size*(blk_size*blk_size))+((nbytes_xfer/(buf_size/blk_size)) - *pio_mpi_nprocs_g)%(snbytes/blk_size*(blk_size*blk_size))); */ - - file_offset = posix_file_offset + - (off_t)((((size_t)nbytes_xfer / (buf_size / blk_size) * - (size_t)pio_mpi_nprocs_g) / - ((size_t)snbytes * blk_size)) * - (buf_size * (size_t)snbytes) + - (((size_t)nbytes_xfer / (buf_size / blk_size)) * - (size_t)pio_mpi_nprocs_g) % - ((size_t)snbytes * blk_size)); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * blk_size; - - /* Global offset advance after each I/O operation */ - /* file_offset_advance = (off_t)(snbytes/blk_size*(blk_size*blk_size)); */ - file_offset_advance = (off_t)snbytes * (off_t)blk_size; - } /* end else */ - } /* end else */ - - /* Common code for file access */ - - /* Set the base of user's buffer */ - buf_p = (unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size * blk_size; - - /* Loop over portions of the buffer to write */ - while (nbytes_toxfer > 0) { - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; - VRFY((rc == 0), "POSIXSEEK"); - - /* check if all bytes are written */ - rc = ((ssize_t)nbytes_xfer_advance == - POSIXWRITE(fd->posixfd, buf_p, nbytes_xfer_advance)); - VRFY((rc != 0), "POSIXWRITE"); - - /* Advance location in buffer */ - buf_p += nbytes_xfer_advance; - - /* Advance global offset in dataset */ - nbytes_xfer += (ssize_t)nbytes_xfer_advance; - - /* Decrement number of bytes left this time */ - nbytes_toxfer -= nbytes_xfer_advance; - - /* Partially advance file offset */ - file_offset += file_offset_advance; - } /* end while */ - - } /* end else */ - - break; - - case MPIO: - /* 1D dataspace */ - if (!parms->dim2d) { - /* Independent file access */ - if (!parms->collective) { - /* Contiguous pattern */ - if (!parms->interleaved) { - /* Compute offset in file */ - mpi_offset = mpi_file_offset + nbytes_xfer; - - /* Perform independent write */ - mrc = - MPI_File_write_at(fd->mpifd, mpi_offset, buffer, - (int)(buf_size / blk_size), mpi_blk_type, &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); - - /* Advance global offset in dataset */ - nbytes_xfer += (ssize_t)buf_size; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Set the base of user's buffer */ - buf_p = (unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size; - - /* Loop over the buffers to write */ - while (nbytes_toxfer > 0) { - /* Skip offset over blocks of other processes */ - mpi_offset = mpi_file_offset + (nbytes_xfer * pio_mpi_nprocs_g); - - /* Perform independent write */ - mrc = MPI_File_write_at(fd->mpifd, mpi_offset, buf_p, (int)1, - mpi_blk_type, &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); - - /* Advance location in buffer */ - buf_p += blk_size; - - /* Advance global offset in dataset */ - nbytes_xfer += (ssize_t)blk_size; - - /* Decrement number of bytes left this time */ - nbytes_toxfer -= blk_size; - } /* end while */ - } /* end else */ - } /* end if */ - /* Collective file access */ - else { - /* Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute offset in file */ - mpi_offset = mpi_file_offset + nbytes_xfer; - - /* Perform independent write */ - mrc = MPI_File_write_at_all(fd->mpifd, mpi_offset, buffer, - (int)(buf_size / blk_size), mpi_blk_type, - &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); - - /* Advance global offset in dataset */ - nbytes_xfer += (ssize_t)buf_size; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Compute offset in file */ - mpi_offset = mpi_file_offset + (nbytes_xfer * pio_mpi_nprocs_g); - - /* Set the file view */ - mrc = MPI_File_set_view(fd->mpifd, mpi_offset, mpi_blk_type, mpi_file_type, - (char *)"native", h5_io_info_g); - VRFY((mrc == MPI_SUCCESS), "MPIO_VIEW"); - - /* Perform write */ - mrc = MPI_File_write_at_all(fd->mpifd, 0, buffer, (int)(buf_size / blk_size), - mpi_blk_type, &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); - - /* Advance global offset in dataset */ - nbytes_xfer += (ssize_t)buf_size; - } /* end else */ - } /* end else */ - } /* end if */ - /* 2D dataspace */ - else { - /* Contiguous storage */ - if (!parms->h5_use_chunks) { - /* Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute offset in file */ - mpi_offset = - mpi_file_offset + - (MPI_Offset)((((size_t)nbytes_xfer / blk_size) / (size_t)snbytes) * - (blk_size * (size_t)snbytes)) + - (MPI_Offset)(((size_t)nbytes_xfer / blk_size) % (size_t)snbytes); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = buf_size; - - /* Global offset advance after each I/O operation */ - mpi_offset_advance = snbytes; - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_cont_type; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Compute offset in file */ - mpi_offset = - mpi_file_offset + - (MPI_Offset)( - ((((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) / - (size_t)snbytes) * - (buf_size * (size_t)snbytes)) + - (MPI_Offset)( - (((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) % - (size_t)snbytes); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size; - - /* Global offset advance after each I/O operation */ - mpi_offset_advance = snbytes; - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_inter_type; - } /* end else */ - } /* end if */ - /* Chunked storage */ - else { - /*Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute offset in file */ - mpi_offset = mpi_file_offset + nbytes_xfer; - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * buf_size; - - /* Global offset advance after each I/O operation */ - mpi_offset_advance = 0; - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_full_buffer; - } /* end if */ - /*Interleaved access pattern */ - else { - /* Compute offset in file */ - /* Before simplification */ - /* mpi_offset=mpi_file_offset+(nbytes_xfer/(buf_size/blk_size) - *pio_mpi_nprocs_g)/(snbytes/blk_size*(blk_size*blk_size))* - (buf_size/blk_size*snbytes/blk_size*(blk_size*blk_size))+ - ((nbytes_xfer/(buf_size/blk_size))*pio_mpi_nprocs_g)%(snbytes - /blk_size*(blk_size*blk_size)); */ - mpi_offset = mpi_file_offset + - (MPI_Offset)((((size_t)nbytes_xfer / (buf_size / blk_size) * - (size_t)pio_mpi_nprocs_g) / - ((size_t)snbytes * blk_size)) * - (buf_size * (size_t)snbytes)) + - (MPI_Offset)((((size_t)nbytes_xfer / (buf_size / blk_size)) * - (size_t)pio_mpi_nprocs_g) % - ((size_t)snbytes * blk_size)); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * blk_size; - - /* Global offset advance after each I/O operation */ - /* mpi_offset_advance = (MPI_Offset)(snbytes/blk_size*(blk_size*blk_size)); */ - mpi_offset_advance = (MPI_Offset)((size_t)snbytes * blk_size); - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_chunk_inter_type; - } /* end else */ - } /* end else */ - - /* Common code for independent file access */ - if (!parms->collective) { - /* Set the base of user's buffer */ - buf_p = (unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size * blk_size; - - /* Loop over portions of the buffer to write */ - while (nbytes_toxfer > 0) { - /* Perform independent write */ - mrc = MPI_File_write_at(fd->mpifd, mpi_offset, buf_p, - (int)nbytes_xfer_advance, MPI_BYTE, &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); - - /* Advance location in buffer */ - buf_p += nbytes_xfer_advance; - - /* Advance global offset in dataset */ - nbytes_xfer += (ssize_t)nbytes_xfer_advance; - - /* Decrement number of bytes left this time */ - nbytes_toxfer -= nbytes_xfer_advance; - - /* Partially advance global offset in dataset */ - mpi_offset += mpi_offset_advance; - } /* end while */ - } /* end if */ - - /* Common code for collective file access */ - else { - /* Set the file view */ - mrc = MPI_File_set_view(fd->mpifd, mpi_offset, MPI_BYTE, mpi_collective_type, - (char *)"native", h5_io_info_g); - VRFY((mrc == MPI_SUCCESS), "MPIO_VIEW"); - - /* Perform write */ - MPI_File_write_at_all(fd->mpifd, 0, buffer, (int)(buf_size * blk_size), MPI_BYTE, - &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); - - /* Advance global offset in dataset */ - nbytes_xfer += (off_t)buf_size * (off_t)blk_size; - } /* end else */ - - } /* end else */ - - break; - - case PHDF5: - /* 1D dataspace */ - if (!parms->dim2d) { - /* Set up the file dset space id to move the selection to process */ - if (!parms->interleaved) { - /* Contiguous pattern */ - h5offset[0] = nbytes_xfer; - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5offset[0] = (nbytes_xfer * pio_mpi_nprocs_g); - } /* end else */ - hrc = H5Soffset_simple(h5dset_space_id, h5offset); - VRFY((hrc >= 0), "H5Soffset_simple"); - - /* Write the buffer out */ - hrc = - H5Dwrite(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); - VRFY((hrc >= 0), "H5Dwrite"); - - /* Increment number of bytes transferred */ - nbytes_xfer += (ssize_t)buf_size; - } /* end if */ - /* 2D dataspace */ - else { - /* Set up the file dset space id to move the selection to process */ - if (!parms->interleaved) { - /* Contiguous pattern */ - h5offset[0] = - (hssize_t)(((size_t)nbytes_xfer / ((size_t)snbytes * blk_size)) * blk_size); - h5offset[1] = - (hssize_t)(((size_t)nbytes_xfer % ((size_t)snbytes * blk_size)) / blk_size); - - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5offset[0] = (hssize_t)((((size_t)nbytes_xfer * (size_t)pio_mpi_nprocs_g) / - ((size_t)snbytes * buf_size)) * - buf_size); - h5offset[1] = (hssize_t)((((size_t)nbytes_xfer * (size_t)pio_mpi_nprocs_g) % - ((size_t)snbytes * buf_size)) / - buf_size); - - } /* end else */ - hrc = H5Soffset_simple(h5dset_space_id, h5offset); - VRFY((hrc >= 0), "H5Soffset_simple"); - - /* Write the buffer out */ - hrc = - H5Dwrite(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); - VRFY((hrc >= 0), "H5Dwrite"); - - /* Increment number of bytes transferred */ - nbytes_xfer += (off_t)buf_size * (off_t)blk_size; - - } /* end else */ - - break; - - default: - break; - } /* switch (parms->io_type) */ - } /* end while */ - - /* Stop "raw data" write timer */ - io_time_set(res->timers, HDF5_RAW_WRITE_FIXED_DIMS, TSTOP); - - /* Calculate write time */ - - /* Close dataset. Only HDF5 needs to do an explicit close. */ - if (parms->io_type == PHDF5) { - hrc = H5Dclose(h5ds_id); - - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Close failed\n"); - GOTOERROR(FAIL); - } - - h5ds_id = H5I_INVALID_HID; - } /* end if */ - } /* end for */ - -done: - /* release MPI-I/O objects */ - if (parms->io_type == MPIO) { - /* 1D dataspace */ - if (!parms->dim2d) { - /* Free file type */ - mrc = MPI_Type_free(&mpi_file_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free buffer type */ - mrc = MPI_Type_free(&mpi_blk_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - } /* end if */ - /* 2D dataspace */ - else { - /* Free partial buffer type for contiguous access */ - mrc = MPI_Type_free(&mpi_partial_buffer_cont); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free contiguous file type */ - mrc = MPI_Type_free(&mpi_cont_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free partial buffer type for interleaved access */ - mrc = MPI_Type_free(&mpi_partial_buffer_inter); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free interleaved file type */ - mrc = MPI_Type_free(&mpi_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free full buffer type */ - mrc = MPI_Type_free(&mpi_full_buffer); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free full chunk type */ - mrc = MPI_Type_free(&mpi_full_chunk); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free chunk interleaved file type */ - mrc = MPI_Type_free(&mpi_chunk_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - } /* end else */ - } /* end if */ - - /* release HDF5 objects */ - if (h5dset_space_id != -1) { - hrc = H5Sclose(h5dset_space_id); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Space Close failed\n"); - ret_code = FAIL; - } - else { - h5dset_space_id = H5I_INVALID_HID; - } - } - - if (h5mem_space_id != -1) { - hrc = H5Sclose(h5mem_space_id); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Memory Space Close failed\n"); - ret_code = FAIL; - } - else { - h5mem_space_id = H5I_INVALID_HID; - } - } - - if (h5dxpl != -1) { - hrc = H5Pclose(h5dxpl); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Transfer Property List Close failed\n"); - ret_code = FAIL; - } - else { - h5dxpl = H5I_INVALID_HID; - } - } - - return ret_code; -} - -static off_t -sqrto(off_t x) -{ - double root_x = sqrt((double)x); - return (off_t)root_x; -} - -/* - * Function: do_read - * Purpose: read the required amount of data from the file. - * Return: SUCCESS or FAIL - * Programmer: Albert Cheng 2001/12/13 - * Modifications: - * Added 2D testing (Christian Chilan, 10. August 2005) - */ -static herr_t -do_read(results *res, file_descr *fd, parameters *parms, long ndsets, off_t nbytes, size_t buf_size, - void *buffer /*out*/) -{ - int ret_code = SUCCESS; - int rc; /*routine return code */ - long ndset; - size_t blk_size; /* The block size to subdivide the xfer buffer into */ - size_t bsize; /* Size of the actual buffer */ - off_t nbytes_xfer; /* Total number of bytes transferred so far */ - size_t nbytes_xfer_advance; /* Number of bytes transferred in a single I/O operation */ - size_t nbytes_toxfer; /* Number of bytes to transfer a particular time */ - char dname[64]; - off_t dset_offset = 0; /*dataset offset in a file */ - off_t bytes_begin[2]; /*first elmt this process transfer */ - off_t bytes_count; /*number of elmts this process transfer */ - off_t snbytes = 0; /*size of a side of the dataset square */ - unsigned char *buf_p; /* Current buffer pointer */ - - /* POSIX variables */ - off_t file_offset; /* File offset of the next transfer */ - off_t file_offset_advance; /* File offset advance after each I/O operation */ - off_t posix_file_offset; /* Base file offset of the next transfer */ - - /* MPI variables */ - MPI_Offset mpi_file_offset; /* Base file offset of the next transfer*/ - MPI_Offset mpi_offset; /* Offset in MPI file */ - MPI_Offset mpi_offset_advance; /* Offset advance after each I/O operation */ - MPI_Datatype mpi_file_type; /* MPI derived type for 1D file */ - MPI_Datatype mpi_blk_type; /* MPI derived type for 1D buffer */ - MPI_Datatype mpi_cont_type; /* MPI derived type for 2D contiguous file */ - MPI_Datatype mpi_partial_buffer_cont; /* MPI derived type for partial 2D contiguous buffer */ - MPI_Datatype mpi_inter_type; /* MPI derived type for 2D interleaved file */ - MPI_Datatype mpi_partial_buffer_inter; /* MPI derived type for partial 2D interleaved buffer */ - MPI_Datatype mpi_full_buffer; /* MPI derived type for 2D full buffer */ - MPI_Datatype mpi_full_chunk; /* MPI derived type for 2D full chunk */ - MPI_Datatype mpi_chunk_inter_type; /* MPI derived type for 2D chunk interleaved file */ - MPI_Datatype mpi_collective_type; /* Generic MPI derived type for 2D collective access */ - MPI_Status mpi_status; - int mrc; /* MPI return code */ - - /* HDF5 variables */ - herr_t hrc; /*HDF5 return code */ - hsize_t h5dims[2]; /*dataset dim sizes */ - hid_t h5dset_space_id = H5I_INVALID_HID; /*dataset space ID */ - hid_t h5mem_space_id = H5I_INVALID_HID; /*memory dataspace ID */ - hid_t h5ds_id = H5I_INVALID_HID; /*dataset handle */ - hsize_t h5block[2]; /*dataspace selection */ - hsize_t h5stride[2]; - hsize_t h5count[2]; - hsize_t h5start[2]; - hssize_t h5offset[2]; /* Selection offset within dataspace */ - hid_t h5dxpl = H5I_INVALID_HID; /* Dataset transfer property list */ - - /* Get the parameters from the parameter block */ - blk_size = parms->blk_size; - - /* There are two kinds of transfer patterns, contiguous and interleaved. - * Let 0,1,2,...,n be data accessed by process 0,1,2,...,n - * where n is rank of the last process. - * In contiguous pattern, data are accessed as - * 000...111...222...nnn... - * In interleaved pattern, data are accessed as - * 012...n012...n... - * These are all in the scope of one dataset. - */ - - /* 1D dataspace */ - if (!parms->dim2d) { - bsize = buf_size; - /* Contiguous Pattern: */ - if (!parms->interleaved) { - bytes_begin[0] = (off_t)(((double)nbytes * pio_mpi_rank_g) / pio_mpi_nprocs_g); - } /* end if */ - /* Interleaved Pattern: */ - else { - bytes_begin[0] = (off_t)blk_size * (off_t)pio_mpi_rank_g; - } /* end else */ - } /* end if */ - /* 2D dataspace */ - else { - /* nbytes is always the number of bytes per dataset (1D or 2D). If the - dataspace is 2D, snbytes is the size of a side of the 'dataset square'. - */ - snbytes = sqrto(nbytes); - - bsize = buf_size * blk_size; - - /* Contiguous Pattern: */ - if (!parms->interleaved) { - bytes_begin[0] = (off_t)((double)snbytes * pio_mpi_rank_g / pio_mpi_nprocs_g); - bytes_begin[1] = 0; - } /* end if */ - /* Interleaved Pattern: */ - else { - bytes_begin[0] = 0; - - if (!parms->h5_use_chunks || parms->io_type == PHDF5) - bytes_begin[1] = (off_t)blk_size * (off_t)pio_mpi_rank_g; - else - bytes_begin[1] = (off_t)blk_size * (off_t)blk_size * (off_t)pio_mpi_rank_g; - } /* end else */ - } /* end else */ - - /* Calculate the total number of bytes (bytes_count) to be - * transferred by this process. It may be different for different - * transfer pattern due to rounding to integral values. - */ - /* - * Calculate the beginning bytes of this process and the next. - * bytes_count is the difference between these two beginnings. - * This way, it eliminates any rounding errors. - * (This is tricky, don't mess with the formula, rounding errors - * can easily get introduced) */ - bytes_count = (off_t)(((double)nbytes * (pio_mpi_rank_g + 1)) / pio_mpi_nprocs_g) - - (off_t)(((double)nbytes * pio_mpi_rank_g) / pio_mpi_nprocs_g); - - /* debug */ - if (pio_debug_level >= 4) { - HDprint_rank(output); - if (!parms->dim2d) { - HDfprintf(output, - "Debug(do_write): " - "buf_size=%zu, bytes_begin=%" H5_PRINTF_LL_WIDTH "d, bytes_count=%" H5_PRINTF_LL_WIDTH - "d\n", - buf_size, (long long)bytes_begin[0], (long long)bytes_count); - } - else { - HDfprintf(output, - "Debug(do_write): " - "linear buf_size=%zu, bytes_begin=(%" H5_PRINTF_LL_WIDTH "d,%" H5_PRINTF_LL_WIDTH - "d), bytes_count=%" H5_PRINTF_LL_WIDTH "d\n", - buf_size * blk_size, (long long)bytes_begin[0], (long long)bytes_begin[1], - (long long)bytes_count); - } - } - - /* I/O Access specific setup */ - switch (parms->io_type) { - case POSIXIO: - /* No extra setup */ - break; - - case MPIO: /* MPI-I/O setup */ - /* 1D dataspace */ - if (!parms->dim2d) { - /* Build block's derived type */ - mrc = MPI_Type_contiguous((int)blk_size, MPI_BYTE, &mpi_blk_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Build file's derived type */ - mrc = MPI_Type_vector((int)(buf_size / blk_size), (int)1, (int)pio_mpi_nprocs_g, mpi_blk_type, - &mpi_file_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit file type */ - mrc = MPI_Type_commit(&mpi_file_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Commit buffer type */ - mrc = MPI_Type_commit(&mpi_blk_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - } /* end if */ - /* 2D dataspace */ - else { - /* Build partial buffer derived type for contiguous access */ - mrc = MPI_Type_contiguous((int)buf_size, MPI_BYTE, &mpi_partial_buffer_cont); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit partial buffer derived type */ - mrc = MPI_Type_commit(&mpi_partial_buffer_cont); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build contiguous file's derived type */ - mrc = MPI_Type_vector((int)blk_size, (int)1, (int)((size_t)snbytes / buf_size), - mpi_partial_buffer_cont, &mpi_cont_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit contiguous file type */ - mrc = MPI_Type_commit(&mpi_cont_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build partial buffer derived type for interleaved access */ - mrc = MPI_Type_contiguous((int)blk_size, MPI_BYTE, &mpi_partial_buffer_inter); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit partial buffer derived type */ - mrc = MPI_Type_commit(&mpi_partial_buffer_inter); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build interleaved file's derived type */ - mrc = MPI_Type_vector((int)buf_size, (int)1, (int)((size_t)snbytes / blk_size), - mpi_partial_buffer_inter, &mpi_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit interleaved file type */ - mrc = MPI_Type_commit(&mpi_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build full buffer derived type */ - mrc = MPI_Type_contiguous((int)(blk_size * buf_size), MPI_BYTE, &mpi_full_buffer); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit full buffer derived type */ - mrc = MPI_Type_commit(&mpi_full_buffer); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build full chunk derived type */ - mrc = MPI_Type_contiguous((int)(blk_size * blk_size), MPI_BYTE, &mpi_full_chunk); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit full chunk derived type */ - mrc = MPI_Type_commit(&mpi_full_chunk); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build chunk interleaved file's derived type */ - mrc = MPI_Type_vector((int)(buf_size / blk_size), (int)1, (int)((size_t)snbytes / blk_size), - mpi_full_chunk, &mpi_chunk_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit chunk interleaved file type */ - mrc = MPI_Type_commit(&mpi_chunk_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - } /* end else */ - break; - - case PHDF5: /* HDF5 setup */ - /* 1D dataspace */ - if (!parms->dim2d) { - if (nbytes > 0) { - /* define a contiguous dataset of nbytes native bytes */ - h5dims[0] = (hsize_t)nbytes; - h5dset_space_id = H5Screate_simple(1, h5dims, NULL); - VRFY((h5dset_space_id >= 0), "H5Screate_simple"); - - /* Set up the file dset space id to select the pattern to access */ - if (!parms->interleaved) { - /* Contiguous pattern */ - h5start[0] = (hsize_t)bytes_begin[0]; - h5stride[0] = h5block[0] = blk_size; - h5count[0] = buf_size / blk_size; - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5start[0] = (hsize_t)bytes_begin[0]; - h5stride[0] = blk_size * (size_t)pio_mpi_nprocs_g; - h5block[0] = blk_size; - h5count[0] = buf_size / blk_size; - } /* end else */ - hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, - h5block); - VRFY((hrc >= 0), "H5Sselect_hyperslab"); - } /* end if */ - else { - h5dset_space_id = H5Screate(H5S_SCALAR); - VRFY((h5dset_space_id >= 0), "H5Screate"); - } /* end else */ - - /* Create the memory dataspace that corresponds to the xfer buffer */ - if (buf_size > 0) { - h5dims[0] = buf_size; - h5mem_space_id = H5Screate_simple(1, h5dims, NULL); - VRFY((h5mem_space_id >= 0), "H5Screate_simple"); - } /* end if */ - else { - h5mem_space_id = H5Screate(H5S_SCALAR); - VRFY((h5mem_space_id >= 0), "H5Screate"); - } /* end else */ - } /* end if */ - /* 2D dataspace */ - else { - if (nbytes > 0) { - /* define a contiguous dataset of nbytes native bytes */ - h5dims[0] = (hsize_t)snbytes; - h5dims[1] = (hsize_t)snbytes; - h5dset_space_id = H5Screate_simple(2, h5dims, NULL); - VRFY((h5dset_space_id >= 0), "H5Screate_simple"); - - /* Set up the file dset space id to select the pattern to access */ - if (!parms->interleaved) { - /* Contiguous pattern */ - h5start[0] = (hsize_t)bytes_begin[0]; - h5start[1] = (hsize_t)bytes_begin[1]; - h5stride[0] = 1; - h5stride[1] = h5block[0] = h5block[1] = blk_size; - h5count[0] = 1; - h5count[1] = buf_size / blk_size; - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5start[0] = (hsize_t)bytes_begin[0]; - h5start[1] = (hsize_t)bytes_begin[1]; - h5stride[0] = blk_size; - h5stride[1] = blk_size * (size_t)pio_mpi_nprocs_g; - h5block[0] = h5block[1] = blk_size; - h5count[0] = buf_size / blk_size; - h5count[1] = 1; - } /* end else */ - hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, - h5block); - VRFY((hrc >= 0), "H5Sselect_hyperslab"); - } /* end if */ - else { - h5dset_space_id = H5Screate(H5S_SCALAR); - VRFY((h5dset_space_id >= 0), "H5Screate"); - } /* end else */ - - /* Create the memory dataspace that corresponds to the xfer buffer */ - if (buf_size > 0) { - if (!parms->interleaved) { - h5dims[0] = blk_size; - h5dims[1] = buf_size; - } - else { - h5dims[0] = buf_size; - h5dims[1] = blk_size; - } - h5mem_space_id = H5Screate_simple(2, h5dims, NULL); - VRFY((h5mem_space_id >= 0), "H5Screate_simple"); - } /* end if */ - else { - h5mem_space_id = H5Screate(H5S_SCALAR); - VRFY((h5mem_space_id >= 0), "H5Screate"); - } /* end else */ - } /* end else */ - - /* Create the dataset transfer property list */ - h5dxpl = H5Pcreate(H5P_DATASET_XFER); - if (h5dxpl < 0) { - HDfprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - - /* Change to collective I/O, if asked */ - if (parms->collective) { - hrc = H5Pset_dxpl_mpio(h5dxpl, H5FD_MPIO_COLLECTIVE); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Property List Set failed\n"); - GOTOERROR(FAIL); - } /* end if */ - } /* end if */ - break; - - default: - break; - } /* end switch */ - - for (ndset = 1; ndset <= ndsets; ++ndset) { - - /* Calculate dataset offset within a file */ - - /* create dataset */ - switch (parms->io_type) { - case POSIXIO: - case MPIO: - /* both posix and mpi io just need dataset offset in file*/ - dset_offset = (ndset - 1) * nbytes; - break; - - case PHDF5: - HDsprintf(dname, "Dataset_%ld", ndset); - h5ds_id = H5DOPEN(fd->h5fd, dname); - if (h5ds_id < 0) { - HDfprintf(stderr, "HDF5 Dataset open failed\n"); - GOTOERROR(FAIL); - } - break; - - default: - break; - } - - /* The task is to transfer bytes_count bytes, starting at - * bytes_begin position, using transfer buffer of buf_size bytes. - * If interleaved, select buf_size at a time, in round robin - * fashion, according to number of process. Otherwise, select - * all bytes_count in contiguous. - */ - nbytes_xfer = 0; - - /* 1D dataspace */ - if (!parms->dim2d) { - /* Set base file offset for all I/O patterns and POSIX access */ - posix_file_offset = dset_offset + bytes_begin[0]; - - /* Set base file offset for all I/O patterns and MPI access */ - mpi_file_offset = (MPI_Offset)(dset_offset + bytes_begin[0]); - } /* end if */ - else { - /* Set base file offset for all I/O patterns and POSIX access */ - posix_file_offset = dset_offset + bytes_begin[0] * snbytes + bytes_begin[1]; - - /* Set base file offset for all I/O patterns and MPI access */ - mpi_file_offset = (MPI_Offset)(dset_offset + bytes_begin[0] * snbytes + bytes_begin[1]); - } /* end else */ - - /* Start "raw data" read timer */ - io_time_set(res->timers, HDF5_RAW_READ_FIXED_DIMS, TSTART); - - while (nbytes_xfer < bytes_count) { - /* Read */ - /* Calculate offset of read within a dataset/file */ - switch (parms->io_type) { - case POSIXIO: - /* 1D dataspace */ - if (!parms->dim2d) { - /* Contiguous pattern */ - if (!parms->interleaved) { - /* Compute file offset */ - file_offset = posix_file_offset + (off_t)nbytes_xfer; - - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; - VRFY((rc == 0), "POSIXSEEK"); - - /* check if all bytes are read */ - rc = ((ssize_t)buf_size == POSIXREAD(fd->posixfd, buffer, buf_size)); - VRFY((rc != 0), "POSIXREAD"); - - /* Advance global offset in dataset */ - nbytes_xfer += (off_t)buf_size; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Set the base of user's buffer */ - buf_p = (unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size; - - /* Loop over the buffers to read */ - while (nbytes_toxfer > 0) { - /* Skip offset over blocks of other processes */ - file_offset = posix_file_offset + (off_t)(nbytes_xfer * pio_mpi_nprocs_g); - - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; - VRFY((rc == 0), "POSIXSEEK"); - - /* check if all bytes are read */ - rc = ((ssize_t)blk_size == POSIXREAD(fd->posixfd, buf_p, blk_size)); - VRFY((rc != 0), "POSIXREAD"); - - /* Advance location in buffer */ - buf_p += blk_size; - - /* Advance global offset in dataset */ - nbytes_xfer += (off_t)blk_size; - - /* Decrement number of bytes left this time */ - nbytes_toxfer -= blk_size; - } /* end while */ - } /* end else */ - } /* end if */ - /* 2D dataspace */ - else { - /* Contiguous storage */ - if (!parms->h5_use_chunks) { - /* Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute file offset */ - file_offset = posix_file_offset + - (off_t)((((size_t)nbytes_xfer / blk_size) / (size_t)snbytes) * - (blk_size * (size_t)snbytes) + - (((size_t)nbytes_xfer / blk_size) % (size_t)snbytes)); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = buf_size; - - /* Global offset advance after each I/O operation */ - file_offset_advance = (off_t)snbytes; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Compute file offset */ - file_offset = - posix_file_offset + - (off_t)(((((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) / - (size_t)snbytes) * - (buf_size * (size_t)snbytes) + - (((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) % - (size_t)snbytes); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size; - - /* Global offset advance after each I/O operation */ - file_offset_advance = (off_t)snbytes; - } /* end else */ - } /* end if */ - /* Chunked storage */ - else { - /*Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute file offset */ - file_offset = posix_file_offset + (off_t)nbytes_xfer; - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * buf_size; - - /* Global offset advance after each I/O operation */ - file_offset_advance = 0; - } /* end if */ - /*Interleaved access pattern */ - else { - /* Compute file offset */ - /* Before simplification */ - /* file_offset=posix_file_offset+(off_t)((nbytes_xfer/(buf_size/blk_size) - *pio_mpi_nprocs_g)/(snbytes/blk_size*(blk_size*blk_size))*(buf_size/blk_size - *snbytes/blk_size*(blk_size*blk_size))+((nbytes_xfer/(buf_size/blk_size)) - *pio_mpi_nprocs_g)%(snbytes/blk_size*(blk_size*blk_size))); */ - - file_offset = posix_file_offset + - (off_t)((((size_t)nbytes_xfer / (buf_size / blk_size) * - (size_t)pio_mpi_nprocs_g) / - ((size_t)snbytes * blk_size)) * - (buf_size * (size_t)snbytes) + - (((size_t)nbytes_xfer / (buf_size / blk_size)) * - (size_t)pio_mpi_nprocs_g) % - ((size_t)snbytes * blk_size)); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * blk_size; - - /* Global offset advance after each I/O operation */ - /* file_offset_advance = (off_t)(snbytes/blk_size*(blk_size*blk_size)); */ - file_offset_advance = (off_t)((size_t)snbytes * blk_size); - } /* end else */ - } /* end else */ - - /* Common code for file access */ - - /* Set the base of user's buffer */ - buf_p = (unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size * blk_size; - - /* Loop over portions of the buffer to read */ - while (nbytes_toxfer > 0) { - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; - VRFY((rc == 0), "POSIXSEEK"); - - /* check if all bytes are read */ - rc = ((ssize_t)nbytes_xfer_advance == - POSIXREAD(fd->posixfd, buf_p, nbytes_xfer_advance)); - VRFY((rc != 0), "POSIXREAD"); - - /* Advance location in buffer */ - buf_p += nbytes_xfer_advance; - - /* Advance global offset in dataset */ - nbytes_xfer += (off_t)nbytes_xfer_advance; - - /* Decrement number of bytes left this time */ - nbytes_toxfer -= nbytes_xfer_advance; - - /* Partially advance file offset */ - file_offset += file_offset_advance; - } /* end while */ - - } /* end else */ - break; - - case MPIO: - /* 1D dataspace */ - if (!parms->dim2d) { - /* Independent file access */ - if (!parms->collective) { - /* Contiguous pattern */ - if (!parms->interleaved) { - /* Compute offset in file */ - mpi_offset = mpi_file_offset + nbytes_xfer; - - /* Perform independent read */ - mrc = MPI_File_read_at(fd->mpifd, mpi_offset, buffer, - (int)(buf_size / blk_size), mpi_blk_type, &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); - - /* Advance global offset in dataset */ - nbytes_xfer += (off_t)buf_size; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Set the base of user's buffer */ - buf_p = (unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size; - - /* Loop over the buffers to read */ - while (nbytes_toxfer > 0) { - /* Skip offset over blocks of other processes */ - mpi_offset = mpi_file_offset + (nbytes_xfer * pio_mpi_nprocs_g); - - /* Perform independent read */ - mrc = MPI_File_read_at(fd->mpifd, mpi_offset, buf_p, (int)1, mpi_blk_type, - &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); - - /* Advance location in buffer */ - buf_p += blk_size; - - /* Advance global offset in dataset */ - nbytes_xfer += (off_t)blk_size; - - /* Decrement number of bytes left this time */ - nbytes_toxfer -= blk_size; - } /* end while */ - } /* end else */ - } /* end if */ - /* Collective file access */ - else { - /* Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute offset in file */ - mpi_offset = mpi_file_offset + nbytes_xfer; - - /* Perform collective read */ - mrc = MPI_File_read_at_all(fd->mpifd, mpi_offset, buffer, - (int)(buf_size / blk_size), mpi_blk_type, - &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); - - /* Advance global offset in dataset */ - nbytes_xfer += (off_t)buf_size; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Compute offset in file */ - mpi_offset = mpi_file_offset + (nbytes_xfer * pio_mpi_nprocs_g); - - /* Set the file view */ - mrc = MPI_File_set_view(fd->mpifd, mpi_offset, mpi_blk_type, mpi_file_type, - (char *)"native", h5_io_info_g); - VRFY((mrc == MPI_SUCCESS), "MPIO_VIEW"); - - /* Perform collective read */ - mrc = MPI_File_read_at_all(fd->mpifd, 0, buffer, (int)(buf_size / blk_size), - mpi_blk_type, &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); - - /* Advance global offset in dataset */ - nbytes_xfer += (off_t)buf_size; - } /* end else */ - } /* end else */ - } /* end if */ - /* 2D dataspace */ - else { - /* Contiguous storage */ - if (!parms->h5_use_chunks) { - /* Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute offset in file */ - mpi_offset = - mpi_file_offset + - (MPI_Offset)((((size_t)nbytes_xfer / blk_size) / (size_t)snbytes) * - (blk_size * (size_t)snbytes)) + - (MPI_Offset)(((size_t)nbytes_xfer / blk_size) % (size_t)snbytes); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = buf_size; - - /* Global offset advance after each I/O operation */ - mpi_offset_advance = snbytes; - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_cont_type; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Compute offset in file */ - mpi_offset = - mpi_file_offset + - (MPI_Offset)( - ((((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) / - (size_t)snbytes) * - (buf_size * (size_t)snbytes)) + - (MPI_Offset)( - (((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) % - (size_t)snbytes); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size; - - /* Global offset advance after each I/O operation */ - mpi_offset_advance = snbytes; - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_inter_type; - } /* end else */ - } /* end if */ - /* Chunked storage */ - else { - /*Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute offset in file */ - mpi_offset = mpi_file_offset + nbytes_xfer; - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * buf_size; - - /* Global offset advance after each I/O operation */ - mpi_offset_advance = 0; - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_full_buffer; - } /* end if */ - /*Interleaved access pattern */ - else { - /* Compute offset in file */ - /* Before simplification */ - /* mpi_offset=mpi_file_offset+(nbytes_xfer/(buf_size/blk_size) - *pio_mpi_nprocs_g)/(snbytes/blk_size*(blk_size*blk_size))* - (buf_size/blk_size*snbytes/blk_size*(blk_size*blk_size))+ - ((nbytes_xfer/(buf_size/blk_size))*pio_mpi_nprocs_g)%(snbytes - /blk_size*(blk_size*blk_size)); */ - mpi_offset = mpi_file_offset + - (MPI_Offset)((((size_t)nbytes_xfer / (buf_size / blk_size) * - (size_t)pio_mpi_nprocs_g) / - ((size_t)snbytes * blk_size)) * - (buf_size * (size_t)snbytes)) + - (MPI_Offset)((((size_t)nbytes_xfer / (buf_size / blk_size)) * - (size_t)pio_mpi_nprocs_g) % - ((size_t)snbytes * blk_size)); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * blk_size; - - /* Global offset advance after each I/O operation */ - /* mpi_offset_advance = (MPI_Offset)(snbytes/blk_size*(blk_size*blk_size)); */ - mpi_offset_advance = (MPI_Offset)((size_t)snbytes * blk_size); - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_chunk_inter_type; - } /* end else */ - } /* end else */ - - /* Common code for independent file access */ - if (!parms->collective) { - /* Set the base of user's buffer */ - buf_p = (unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size * blk_size; - - /* Loop over portions of the buffer to read */ - while (nbytes_toxfer > 0) { - /* Perform independent read */ - mrc = MPI_File_read_at(fd->mpifd, mpi_offset, buf_p, (int)nbytes_xfer_advance, - MPI_BYTE, &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); - - /* Advance location in buffer */ - buf_p += nbytes_xfer_advance; - - /* Advance global offset in dataset */ - nbytes_xfer += (off_t)nbytes_xfer_advance; - - /* Decrement number of bytes left this time */ - nbytes_toxfer -= nbytes_xfer_advance; - - /* Partially advance global offset in dataset */ - mpi_offset += mpi_offset_advance; - } /* end while */ - } /* end if */ - - /* Common code for collective file access */ - else { - /* Set the file view */ - mrc = MPI_File_set_view(fd->mpifd, mpi_offset, MPI_BYTE, mpi_collective_type, - (char *)"native", h5_io_info_g); - VRFY((mrc == MPI_SUCCESS), "MPIO_VIEW"); - - /* Perform read */ - MPI_File_read_at_all(fd->mpifd, 0, buffer, (int)(buf_size * blk_size), MPI_BYTE, - &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); - - /* Advance global offset in dataset */ - nbytes_xfer += (off_t)buf_size * (off_t)blk_size; - } /* end else */ - - } /* end else */ - break; - - case PHDF5: - /* 1D dataspace */ - if (!parms->dim2d) { - /* Set up the file dset space id to move the selection to process */ - if (!parms->interleaved) { - /* Contiguous pattern */ - h5offset[0] = nbytes_xfer; - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5offset[0] = (nbytes_xfer * pio_mpi_nprocs_g); - } /* end else */ - hrc = H5Soffset_simple(h5dset_space_id, h5offset); - VRFY((hrc >= 0), "H5Soffset_simple"); - - /* Read the buffer in */ - hrc = H5Dread(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); - VRFY((hrc >= 0), "H5Dread"); - - /* Increment number of bytes transferred */ - nbytes_xfer += (off_t)buf_size; - } /* end if */ - /* 2D dataspace */ - else { - /* Set up the file dset space id to move the selection to process */ - if (!parms->interleaved) { - /* Contiguous pattern */ - h5offset[0] = - (hssize_t)(((size_t)nbytes_xfer / ((size_t)snbytes * blk_size)) * blk_size); - h5offset[1] = - (hssize_t)(((size_t)nbytes_xfer % ((size_t)snbytes * blk_size)) / blk_size); - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5offset[0] = (hssize_t)((((size_t)nbytes_xfer * (size_t)pio_mpi_nprocs_g) / - ((size_t)snbytes * buf_size)) * - buf_size); - h5offset[1] = (hssize_t)((((size_t)nbytes_xfer * (size_t)pio_mpi_nprocs_g) % - ((size_t)snbytes * buf_size)) / - buf_size); - - } /* end else */ - hrc = H5Soffset_simple(h5dset_space_id, h5offset); - VRFY((hrc >= 0), "H5Soffset_simple"); - - /* Write the buffer out */ - hrc = H5Dread(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); - VRFY((hrc >= 0), "H5Dread"); - - /* Increment number of bytes transferred */ - nbytes_xfer += (off_t)buf_size * (off_t)blk_size; - - } /* end else */ - break; - - default: - break; - } /* switch (parms->io_type) */ - - /* Verify raw data, if asked */ - if (parms->verify) { - /* Verify data read */ - unsigned char *ucharptr = (unsigned char *)buffer; - size_t i; - int nerror = 0; - - for (i = 0; i < bsize; ++i) { - if (*ucharptr++ != pio_mpi_rank_g + 1) { - if (++nerror < 20) { - /* report at most 20 errors */ - HDprint_rank(output); - HDfprintf(output, - "read data error, expected (%d), " - "got (%d)\n", - pio_mpi_rank_g + 1, (int)*(ucharptr - 1)); - } /* end if */ - } /* end if */ - } /* end for */ - if (nerror >= 20) { - HDprint_rank(output); - HDfprintf(output, "..."); - HDfprintf(output, "total read data errors=%d\n", nerror); - } /* end if */ - } /* if (parms->verify) */ - - } /* end while */ - - /* Stop "raw data" read timer */ - io_time_set(res->timers, HDF5_RAW_READ_FIXED_DIMS, TSTOP); - - /* Calculate read time */ - - /* Close dataset. Only HDF5 needs to do an explicit close. */ - if (parms->io_type == PHDF5) { - hrc = H5Dclose(h5ds_id); - - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Close failed\n"); - GOTOERROR(FAIL); - } - - h5ds_id = H5I_INVALID_HID; - } /* end if */ - } /* end for */ - -done: - /* release MPI-I/O objects */ - if (parms->io_type == MPIO) { - /* 1D dataspace */ - if (!parms->dim2d) { - /* Free file type */ - mrc = MPI_Type_free(&mpi_file_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free buffer type */ - mrc = MPI_Type_free(&mpi_blk_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - } /* end if */ - /* 2D dataspace */ - else { - /* Free partial buffer type for contiguous access */ - mrc = MPI_Type_free(&mpi_partial_buffer_cont); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free contiguous file type */ - mrc = MPI_Type_free(&mpi_cont_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free partial buffer type for interleaved access */ - mrc = MPI_Type_free(&mpi_partial_buffer_inter); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free interleaved file type */ - mrc = MPI_Type_free(&mpi_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free full buffer type */ - mrc = MPI_Type_free(&mpi_full_buffer); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free full chunk type */ - mrc = MPI_Type_free(&mpi_full_chunk); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free chunk interleaved file type */ - mrc = MPI_Type_free(&mpi_chunk_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - } /* end else */ - } /* end if */ - - /* release HDF5 objects */ - if (h5dset_space_id != -1) { - hrc = H5Sclose(h5dset_space_id); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Space Close failed\n"); - ret_code = FAIL; - } - else { - h5dset_space_id = H5I_INVALID_HID; - } - } - - if (h5mem_space_id != -1) { - hrc = H5Sclose(h5mem_space_id); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Memory Space Close failed\n"); - ret_code = FAIL; - } - else { - h5mem_space_id = H5I_INVALID_HID; - } - } - - if (h5dxpl != -1) { - hrc = H5Pclose(h5dxpl); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Transfer Property List Close failed\n"); - ret_code = FAIL; - } - else { - h5dxpl = H5I_INVALID_HID; - } - } - - return ret_code; -} - -/* - * Function: do_fopen - * Purpose: Open the specified file. - * Return: SUCCESS or FAIL - * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 - * Modifications: - */ -static herr_t -do_fopen(parameters *param, char *fname, file_descr *fd /*out*/, int flags) -{ - int ret_code = SUCCESS, mrc; - hid_t acc_tpl = H5I_INVALID_HID; /* file access templates */ - - switch (param->io_type) { - case POSIXIO: - if (flags & (PIO_CREATE | PIO_WRITE)) - fd->posixfd = POSIXCREATE(fname); - else - fd->posixfd = POSIXOPEN(fname, O_RDONLY); - - if (fd->posixfd < 0) { - HDfprintf(stderr, "POSIX File Open failed(%s)\n", fname); - GOTOERROR(FAIL); - } - - /* The perils of POSIX I/O in a parallel environment. The problem is: - * - * - Process n opens a file with truncation and then starts - * writing to the file. - * - Process m also opens the file with truncation, but after - * process n has already started to write to the file. Thus, - * all of the stuff process n wrote is now lost. - */ - MPI_Barrier(pio_comm_g); - - break; - - case MPIO: - if (flags & (PIO_CREATE | PIO_WRITE)) { - MPI_File_delete(fname, h5_io_info_g); - mrc = MPI_File_open(pio_comm_g, fname, MPI_MODE_CREATE | MPI_MODE_RDWR, h5_io_info_g, - &fd->mpifd); - - if (mrc != MPI_SUCCESS) { - HDfprintf(stderr, "MPI File Open failed(%s)\n", fname); - GOTOERROR(FAIL); - } - - /*since MPI_File_open with MPI_MODE_CREATE does not truncate */ - /*filesize , set size to 0 explicitedly. */ - mrc = MPI_File_set_size(fd->mpifd, (MPI_Offset)0); - if (mrc != MPI_SUCCESS) { - HDfprintf(stderr, "MPI_File_set_size failed\n"); - GOTOERROR(FAIL); - } - } - else { - mrc = MPI_File_open(pio_comm_g, fname, MPI_MODE_RDONLY, h5_io_info_g, &fd->mpifd); - if (mrc != MPI_SUCCESS) { - HDfprintf(stderr, "MPI File Open failed(%s)\n", fname); - GOTOERROR(FAIL); - } - } - - break; - - case PHDF5: - if ((acc_tpl = H5Pcreate(H5P_FILE_ACCESS)) < 0) { - HDfprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - - /* Set the file driver to the MPI-IO driver */ - if (H5Pset_fapl_mpio(acc_tpl, pio_comm_g, h5_io_info_g) < 0) { - HDfprintf(stderr, "HDF5 Property List Set failed\n"); - GOTOERROR(FAIL); - } - - /* Set the alignment of objects in HDF5 file */ - if (H5Pset_alignment(acc_tpl, param->h5_thresh, param->h5_align) < 0) { - HDfprintf(stderr, "HDF5 Property List Set failed\n"); - GOTOERROR(FAIL); - } - - /* create the parallel file */ - if (flags & (PIO_CREATE | PIO_WRITE)) - fd->h5fd = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl); - else - fd->h5fd = H5Fopen(fname, H5F_ACC_RDONLY, acc_tpl); - if (fd->h5fd < 0) { - HDfprintf(stderr, "HDF5 File Create failed(%s)\n", fname); - GOTOERROR(FAIL); - } - - /* verifying the close of the acc_tpl */ - if (H5Pclose(acc_tpl) < 0) { - HDfprintf(stderr, "HDF5 Property List Close failed\n"); - GOTOERROR(FAIL); - } - - break; - - default: - break; - } - -done: - return ret_code; -} - -/* - * Function: do_fclose - * Purpose: Close the specified file descriptor. - * Return: SUCCESS or FAIL - * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 - * Modifications: - */ -static herr_t -do_fclose(iotype iot, file_descr *fd /*out*/) -{ - herr_t ret_code = SUCCESS, hrc; - int mrc = 0, rc = 0; - - switch (iot) { - case POSIXIO: - rc = POSIXCLOSE(fd->posixfd); - - if (rc != 0) { - HDfprintf(stderr, "POSIX File Close failed\n"); - GOTOERROR(FAIL); - } - - fd->posixfd = -1; - break; - - case MPIO: - mrc = MPI_File_close(&fd->mpifd); - - if (mrc != MPI_SUCCESS) { - HDfprintf(stderr, "MPI File close failed\n"); - GOTOERROR(FAIL); - } - - fd->mpifd = MPI_FILE_NULL; - break; - - case PHDF5: - hrc = H5Fclose(fd->h5fd); - - if (hrc < 0) { - HDfprintf(stderr, "HDF5 File Close failed\n"); - GOTOERROR(FAIL); - } - - fd->h5fd = -1; - break; - - default: - break; - } - -done: - return ret_code; -} - -/* - * Function: do_fclose - * Purpose: Cleanup temporary file unless HDF5_NOCLEANUP is set. - * Only Proc 0 of the PIO communicator will do the cleanup. - * Other processes just return. - * Return: void - * Programmer: Albert Cheng 2001/12/12 - * Modifications: - */ -static void -do_cleanupfile(iotype iot, char *fname) -{ - if (pio_mpi_rank_g != 0) - return; - - if (clean_file_g == -1) - clean_file_g = (getenv("HDF5_NOCLEANUP") == NULL) ? 1 : 0; - - if (clean_file_g) { - switch (iot) { - case POSIXIO: - HDremove(fname); - break; - case MPIO: - case PHDF5: - MPI_File_delete(fname, h5_io_info_g); - break; - default: - break; - } - } -} - -#ifdef TIME_MPI -/* instrument the MPI_File_wrirte_xxx and read_xxx calls to measure - * pure time spent in MPI_File code. - */ -int -MPI_File_read_at(MPI_File fh, MPI_Offset offset, void *buf, int count, MPI_Datatype datatype, - MPI_Status *status) -{ - int err; - io_time_set(timer_g, HDF5_MPI_READ, TSTART); - err = PMPI_File_read_at(fh, offset, buf, count, datatype, status); - io_time_set(timer_g, HDF5_MPI_READ, TSTOP); - return err; -} - -int -MPI_File_read_at_all(MPI_File fh, MPI_Offset offset, void *buf, int count, MPI_Datatype datatype, - MPI_Status *status) -{ - int err; - io_time_set(timer_g, HDF5_MPI_READ, TSTART); - err = PMPI_File_read_at_all(fh, offset, buf, count, datatype, status); - io_time_set(timer_g, HDF5_MPI_READ, TSTOP); - return err; -} - -int -MPI_File_write_at(MPI_File fh, MPI_Offset offset, void *buf, int count, MPI_Datatype datatype, - MPI_Status *status) -{ - int err; - io_time_set(timer_g, HDF5_MPI_WRITE, TSTART); - err = PMPI_File_write_at(fh, offset, buf, count, datatype, status); - io_time_set(timer_g, HDF5_MPI_WRITE, TSTOP); - return err; -} - -int -MPI_File_write_at_all(MPI_File fh, MPI_Offset offset, void *buf, int count, MPI_Datatype datatype, - MPI_Status *status) -{ - int err; - io_time_set(timer_g, HDF5_MPI_WRITE, TSTART); - err = PMPI_File_write_at_all(fh, offset, buf, count, datatype, status); - io_time_set(timer_g, HDF5_MPI_WRITE, TSTOP); - return err; -} - -#endif /* TIME_MPI */ -#endif /* H5_HAVE_PARALLEL */ diff --git a/tools/test/perform/pio_perf.c b/tools/test/perform/pio_perf.c deleted file mode 100644 index d38c574..0000000 --- a/tools/test/perform/pio_perf.c +++ /dev/null @@ -1,1699 +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. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Parallel HDF5 Performance Testing Code - * -------------------------------------- - * - * Portable code to test performance on the different platforms we support. - * This is what the report should look like: - * - * nprocs = Max#Procs - * IO API = POSIXIO - * # Files = 1, # of dsets = 1000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * # Files = 1, # of dsets = 3000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * - * . . . - * - * IO API = MPIO - * # Files = 1, # of dsets = 1000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * # Files = 1, # of dsets = 3000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * - * . . . - * - * IO API = PHDF5 - * # Files = 1, # of dsets = 1000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * # Files = 1, # of dsets = 3000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * - * . . . - * - * nprocs = Max#Procs / 2 - * - * . . . - * - */ - -/* system header files */ -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> - -#include "hdf5.h" - -#ifdef H5_HAVE_PARALLEL - -/* library header files */ -#include <mpi.h> - -/* our header files */ -#include "pio_perf.h" - -/* useful macros */ -#define TAB_SPACE 4 - -#define ONE_KB 1024 -#define ONE_MB (ONE_KB * ONE_KB) -#define ONE_GB (ONE_MB * ONE_KB) - -#define PIO_POSIX 0x1 -#define PIO_MPI 0x2 -#define PIO_HDF5 0x4 - -#ifdef STANDALONE -#define DBL_EPSILON 2.2204460492503131e-16 -#define H5_DBL_ABS_EQUAL(X, Y) (fabs((X) - (Y)) < DBL_EPSILON) -#endif - -/* report 0.0 in case t is zero too */ -#define MB_PER_SEC(bytes, t) (H5_DBL_ABS_EQUAL((t), 0.0) ? 0.0 : ((((double)bytes) / ONE_MB) / (t))) - -#ifndef TRUE -#define TRUE 1 -#endif /* TRUE */ -#ifndef FALSE -#define FALSE (!TRUE) -#endif /* FALSE */ - -/* global variables */ -FILE * output; /* output file */ -int comm_world_rank_g; /* my rank in MPI_COMM_RANK */ -int comm_world_nprocs_g; /* num. of processes of MPI_COMM_WORLD */ -MPI_Comm pio_comm_g; /* Communicator to run the PIO */ -int pio_mpi_rank_g; /* MPI rank of pio_comm_g */ -int pio_mpi_nprocs_g; /* Number of processes of pio_comm_g */ -int pio_debug_level = 0; /* The debug level: - * 0 - Off - * 1 - Minimal - * 2 - Some more - * 3 - Maximal - * 4 - Maximal & then some - */ - -/* local variables */ -static const char *progname = "h5perf"; - -/* - * Command-line options: The user can specify short or long-named - * parameters. The long-named ones can be partially spelled. When - * adding more, make sure that they don't clash with each other. - */ -#if 1 -static const char *s_opts = "a:A:B:cCd:D:e:F:ghi:Imno:p:P:stT:wx:X:"; -#else -static const char *s_opts = "a:A:bB:cCd:D:e:F:ghi:Imno:p:P:stT:wx:X:"; -#endif /* 1 */ -static struct h5_long_options l_opts[] = {{"align", require_arg, 'a'}, - {"alig", require_arg, 'a'}, - {"ali", require_arg, 'a'}, - {"al", require_arg, 'a'}, - {"api", require_arg, 'A'}, - {"ap", require_arg, 'A'}, -#if 0 - /* a sighting of the elusive binary option */ - { "binary", no_arg, 'b' }, - { "binar", no_arg, 'b' }, - { "bina", no_arg, 'b' }, - { "bin", no_arg, 'b' }, - { "bi", no_arg, 'b' }, -#endif /* 0 */ - {"block-size", require_arg, 'B'}, - {"block-siz", require_arg, 'B'}, - {"block-si", require_arg, 'B'}, - {"block-s", require_arg, 'B'}, - {"block-", require_arg, 'B'}, - {"block", require_arg, 'B'}, - {"bloc", require_arg, 'B'}, - {"blo", require_arg, 'B'}, - {"bl", require_arg, 'B'}, - {"chunk", no_arg, 'c'}, - {"chun", no_arg, 'c'}, - {"chu", no_arg, 'c'}, - {"ch", no_arg, 'c'}, - {"collective", no_arg, 'C'}, - {"collectiv", no_arg, 'C'}, - {"collecti", no_arg, 'C'}, - {"collect", no_arg, 'C'}, - {"collec", no_arg, 'C'}, - {"colle", no_arg, 'C'}, - {"coll", no_arg, 'C'}, - {"col", no_arg, 'C'}, - {"co", no_arg, 'C'}, - {"debug", require_arg, 'D'}, - {"debu", require_arg, 'D'}, - {"deb", require_arg, 'D'}, - {"de", require_arg, 'D'}, - {"geometry", no_arg, 'g'}, - {"geometr", no_arg, 'g'}, - {"geomet", no_arg, 'g'}, - {"geome", no_arg, 'g'}, - {"geom", no_arg, 'g'}, - {"geo", no_arg, 'g'}, - {"ge", no_arg, 'g'}, - {"help", no_arg, 'h'}, - {"hel", no_arg, 'h'}, - {"he", no_arg, 'h'}, - {"interleaved", require_arg, 'I'}, - {"interleave", require_arg, 'I'}, - {"interleav", require_arg, 'I'}, - {"interlea", require_arg, 'I'}, - {"interle", require_arg, 'I'}, - {"interl", require_arg, 'I'}, - {"inter", require_arg, 'I'}, - {"inte", require_arg, 'I'}, - {"int", require_arg, 'I'}, - {"in", require_arg, 'I'}, - {"max-num-processes", require_arg, 'P'}, - {"max-num-processe", require_arg, 'P'}, - {"max-num-process", require_arg, 'P'}, - {"max-num-proces", require_arg, 'P'}, - {"max-num-proce", require_arg, 'P'}, - {"max-num-proc", require_arg, 'P'}, - {"max-num-pro", require_arg, 'P'}, - {"max-num-pr", require_arg, 'P'}, - {"max-num-p", require_arg, 'P'}, - {"min-num-processes", require_arg, 'p'}, - {"min-num-processe", require_arg, 'p'}, - {"min-num-process", require_arg, 'p'}, - {"min-num-proces", require_arg, 'p'}, - {"min-num-proce", require_arg, 'p'}, - {"min-num-proc", require_arg, 'p'}, - {"min-num-pro", require_arg, 'p'}, - {"min-num-pr", require_arg, 'p'}, - {"min-num-p", require_arg, 'p'}, - {"max-xfer-size", require_arg, 'X'}, - {"max-xfer-siz", require_arg, 'X'}, - {"max-xfer-si", require_arg, 'X'}, - {"max-xfer-s", require_arg, 'X'}, - {"max-xfer", require_arg, 'X'}, - {"max-xfe", require_arg, 'X'}, - {"max-xf", require_arg, 'X'}, - {"max-x", require_arg, 'X'}, - {"min-xfer-size", require_arg, 'x'}, - {"min-xfer-siz", require_arg, 'x'}, - {"min-xfer-si", require_arg, 'x'}, - {"min-xfer-s", require_arg, 'x'}, - {"min-xfer", require_arg, 'x'}, - {"min-xfe", require_arg, 'x'}, - {"min-xf", require_arg, 'x'}, - {"min-x", require_arg, 'x'}, - {"num-bytes", require_arg, 'e'}, - {"num-byte", require_arg, 'e'}, - {"num-byt", require_arg, 'e'}, - {"num-by", require_arg, 'e'}, - {"num-b", require_arg, 'e'}, - {"num-dsets", require_arg, 'd'}, - {"num-dset", require_arg, 'd'}, - {"num-dse", require_arg, 'd'}, - {"num-ds", require_arg, 'd'}, - {"num-d", require_arg, 'd'}, - {"num-files", require_arg, 'F'}, - {"num-file", require_arg, 'F'}, - {"num-fil", require_arg, 'F'}, - {"num-fi", require_arg, 'F'}, - {"num-f", require_arg, 'F'}, - {"num-iterations", require_arg, 'i'}, - {"num-iteration", require_arg, 'i'}, - {"num-iteratio", require_arg, 'i'}, - {"num-iterati", require_arg, 'i'}, - {"num-iterat", require_arg, 'i'}, - {"num-itera", require_arg, 'i'}, - {"num-iter", require_arg, 'i'}, - {"num-ite", require_arg, 'i'}, - {"num-it", require_arg, 'i'}, - {"num-i", require_arg, 'i'}, - {"output", require_arg, 'o'}, - {"outpu", require_arg, 'o'}, - {"outp", require_arg, 'o'}, - {"out", require_arg, 'o'}, - {"ou", require_arg, 'o'}, - {"threshold", require_arg, 'T'}, - {"threshol", require_arg, 'T'}, - {"thresho", require_arg, 'T'}, - {"thresh", require_arg, 'T'}, - {"thres", require_arg, 'T'}, - {"thre", require_arg, 'T'}, - {"thr", require_arg, 'T'}, - {"th", require_arg, 'T'}, - {"write-only", require_arg, 'w'}, - {"write-onl", require_arg, 'w'}, - {"write-on", require_arg, 'w'}, - {"write-o", require_arg, 'w'}, - {"write", require_arg, 'w'}, - {"writ", require_arg, 'w'}, - {"wri", require_arg, 'w'}, - {"wr", require_arg, 'w'}, - {NULL, 0, '\0'}}; - -struct options { - long io_types; /* bitmask of which I/O types to test */ - const char *output_file; /* file to print report to */ - long num_dsets; /* number of datasets */ - long num_files; /* number of files */ - off_t num_bpp; /* number of bytes per proc per dset */ - int num_iters; /* number of iterations */ - int max_num_procs; /* maximum number of processes to use */ - int min_num_procs; /* minimum number of processes to use */ - size_t max_xfer_size; /* maximum transfer buffer size */ - size_t min_xfer_size; /* minimum transfer buffer size */ - size_t blk_size; /* Block size */ - unsigned interleaved; /* Interleaved vs. contiguous blocks */ - unsigned collective; /* Collective vs. independent I/O */ - unsigned dim2d; /* 1D vs. 2D geometry */ - int print_times; /* print times as well as throughputs */ - int print_raw; /* print raw data throughput info */ - off_t h5_alignment; /* alignment in HDF5 file */ - off_t h5_threshold; /* threshold for alignment in HDF5 file */ - int h5_use_chunks; /* Make HDF5 dataset chunked */ - int h5_write_only; /* Perform the write tests only */ - int verify; /* Verify data correctness */ -}; - -typedef struct _minmax { - double min; - double max; - double sum; - int num; -} minmax; - -/* local functions */ -static off_t parse_size_directive(const char *size); -static struct options *parse_command_line(int argc, char *argv[]); -static void run_test_loop(struct options *options); -static int run_test(iotype iot, parameters parms, struct options *opts); -static void output_all_info(minmax *mm, int count, int indent_level); -static void get_minmax(minmax *mm, double val); -static minmax accumulate_minmax_stuff(minmax *mm, int count); -static int create_comm_world(int num_procs, int *doing_pio); -static int destroy_comm_world(void); -static void output_results(const struct options *options, const char *name, minmax *table, int table_size, - off_t data_size); -static void output_times(const struct options *options, const char *name, minmax *table, int table_size); -static void output_report(const char *fmt, ...); -static void print_indent(register int indent); -static void usage(const char *prog); -static void report_parameters(struct options *opts); -static off_t squareo(off_t); - -/* - * Function: main - * Purpose: Start things up. Initialize MPI and then call the test looping - * function. - * Return: EXIT_SUCCESS or EXIT_FAILURE - * Programmer: Bill Wendling, 30. October 2001 - * Modifications: - */ -int -main(int argc, char *argv[]) -{ - int ret; - int exit_value = EXIT_SUCCESS; - struct options *opts = NULL; - -#ifndef STANDALONE - /* Initialize h5tools lib */ - h5tools_init(); -#endif - - output = stdout; - - /* initialize MPI and get the maximum num of processors we started with */ - MPI_Init(&argc, &argv); - ret = MPI_Comm_size(MPI_COMM_WORLD, &comm_world_nprocs_g); - - if (ret != MPI_SUCCESS) { - HDfprintf(stderr, "%s: MPI_Comm_size call failed\n", progname); - - if (ret == MPI_ERR_COMM) - HDfprintf(stderr, "invalid MPI communicator\n"); - else - HDfprintf(stderr, "invalid argument\n"); - - exit_value = EXIT_FAILURE; - goto finish; - } - - ret = MPI_Comm_rank(MPI_COMM_WORLD, &comm_world_rank_g); - - if (ret != MPI_SUCCESS) { - HDfprintf(stderr, "%s: MPI_Comm_rank call failed\n", progname); - - if (ret == MPI_ERR_COMM) - HDfprintf(stderr, "invalid MPI communicator\n"); - else - HDfprintf(stderr, "invalid argument\n"); - - exit_value = EXIT_FAILURE; - goto finish; - } - - pio_comm_g = MPI_COMM_WORLD; - - h5_set_info_object(); - opts = parse_command_line(argc, argv); - - if (!opts) { - exit_value = EXIT_FAILURE; - goto finish; - } - - if (opts->output_file) { - if ((output = HDfopen(opts->output_file, "w")) == NULL) { - HDfprintf(stderr, "%s: cannot open output file\n", progname); - perror(opts->output_file); - goto finish; - } - } - - if ((pio_debug_level == 0 && comm_world_rank_g == 0) || pio_debug_level > 0) - report_parameters(opts); - - run_test_loop(opts); - -finish: - MPI_Finalize(); - free(opts); - return exit_value; -} - -off_t -squareo(off_t x) -{ - return x * x; -} - -/* - * Function: run_test_loop - * Purpose: Run the I/O tests. Write the results to OUTPUT. - * - * - The slowest changing part of the test is the number of - * processors to use. For each loop iteration, we divide that - * number by 2 and rerun the test. - * - * - The second slowest is what type of IO API to perform. We have - * three choices: POSIXIO, MPI-IO, and PHDF5. - * - * - Then we change the size of the buffer. This information is - * inferred from the number of datasets to create and the number - * of integers to put into each dataset. The backend code figures - * this out. - * - * Return: Nothing - * Programmer: Bill Wendling, 30. October 2001 - * Modifications: - * Added 2D testing (Christian Chilan, 10. August 2005) - */ -static void -run_test_loop(struct options *opts) -{ - parameters parms; - int num_procs; - int doing_pio; /* if this process is doing PIO */ - - parms.num_files = opts->num_files; - parms.num_dsets = opts->num_dsets; - parms.num_iters = opts->num_iters; - parms.blk_size = opts->blk_size; - parms.interleaved = opts->interleaved; - parms.collective = opts->collective; - parms.dim2d = opts->dim2d; - parms.h5_align = (hsize_t)opts->h5_alignment; - parms.h5_thresh = (hsize_t)opts->h5_threshold; - parms.h5_use_chunks = opts->h5_use_chunks; - parms.h5_write_only = opts->h5_write_only; - parms.verify = opts->verify; - - /* start with max_num_procs and decrement it by half for each loop. */ - /* if performance needs restart, fewer processes may be needed. */ - for (num_procs = opts->max_num_procs; num_procs >= opts->min_num_procs; num_procs >>= 1) { - register size_t buf_size; - - parms.num_procs = num_procs; - - if (create_comm_world(parms.num_procs, &doing_pio) != SUCCESS) { - /* do something harsh */ - } - - /* only processes doing PIO will run the tests */ - if (doing_pio) { - output_report("Number of processors = %ld\n", parms.num_procs); - - /* multiply the xfer buffer size by 2 for each loop iteration */ - for (buf_size = opts->min_xfer_size; buf_size <= opts->max_xfer_size; buf_size <<= 1) { - parms.buf_size = buf_size; - - if (parms.dim2d) { - parms.num_bytes = squareo(opts->num_bpp * parms.num_procs); - if (parms.interleaved) - output_report("Transfer Buffer Size: %ldx%ld bytes, File size: %.2f MB\n", buf_size, - opts->blk_size, - ((double)parms.num_dsets * (double)parms.num_bytes) / ONE_MB); - else - output_report("Transfer Buffer Size: %ldx%ld bytes, File size: %.2f MB\n", - opts->blk_size, buf_size, - ((double)parms.num_dsets * (double)parms.num_bytes) / ONE_MB); - - print_indent(1); - output_report(" # of files: %ld, # of datasets: %ld, dataset size: %.2fx%.2f KB\n", - parms.num_files, parms.num_dsets, - (double)(opts->num_bpp * parms.num_procs) / ONE_KB, - (double)(opts->num_bpp * parms.num_procs) / ONE_KB); - } - else { - parms.num_bytes = (off_t)opts->num_bpp * parms.num_procs; - output_report("Transfer Buffer Size: %ld bytes, File size: %.2f MB\n", buf_size, - ((double)parms.num_dsets * (double)parms.num_bytes) / ONE_MB); - - print_indent(1); - output_report(" # of files: %ld, # of datasets: %ld, dataset size: %.2f MB\n", - parms.num_files, parms.num_dsets, - (double)(opts->num_bpp * parms.num_procs) / ONE_MB); - } - - if (opts->io_types & PIO_POSIX) - run_test(POSIXIO, parms, opts); - - if (opts->io_types & PIO_MPI) - run_test(MPIO, parms, opts); - - if (opts->io_types & PIO_HDF5) - run_test(PHDF5, parms, opts); - - /* Run the tests once if buf_size==0, but then break out */ - if (buf_size == 0) - break; - } - - if (destroy_comm_world() != SUCCESS) { - /* do something harsh */ - } - } - } -} - -/* - * Function: run_test - * Purpose: Inner loop call to actually run the I/O test. - * Return: Nothing - * Programmer: Bill Wendling, 18. December 2001 - * Modifications: - */ -static int -run_test(iotype iot, parameters parms, struct options *opts) -{ - results res; - register int i, ret_value = SUCCESS; - int comm_size; - off_t raw_size; - minmax * write_mpi_mm_table = NULL; - minmax * write_mm_table = NULL; - minmax * write_gross_mm_table = NULL; - minmax * write_raw_mm_table = NULL; - minmax * read_mpi_mm_table = NULL; - minmax * read_mm_table = NULL; - minmax * read_gross_mm_table = NULL; - minmax * read_raw_mm_table = NULL; - minmax * read_open_mm_table = NULL; - minmax * read_close_mm_table = NULL; - minmax * write_open_mm_table = NULL; - minmax * write_close_mm_table = NULL; - minmax write_mpi_mm = {0.0, 0.0, 0.0, 0}; - minmax write_mm = {0.0, 0.0, 0.0, 0}; - minmax write_gross_mm = {0.0, 0.0, 0.0, 0}; - minmax write_raw_mm = {0.0, 0.0, 0.0, 0}; - minmax read_mpi_mm = {0.0, 0.0, 0.0, 0}; - minmax read_mm = {0.0, 0.0, 0.0, 0}; - minmax read_gross_mm = {0.0, 0.0, 0.0, 0}; - minmax read_raw_mm = {0.0, 0.0, 0.0, 0}; - minmax read_open_mm = {0.0, 0.0, 0.0, 0}; - minmax read_close_mm = {0.0, 0.0, 0.0, 0}; - minmax write_open_mm = {0.0, 0.0, 0.0, 0}; - minmax write_close_mm = {0.0, 0.0, 0.0, 0}; - - raw_size = parms.num_files * (off_t)parms.num_dsets * (off_t)parms.num_bytes; - parms.io_type = iot; - print_indent(2); - output_report("IO API = "); - - switch (iot) { - case POSIXIO: - output_report("POSIX\n"); - break; - case MPIO: - output_report("MPIO\n"); - break; - case PHDF5: - output_report("PHDF5 (w/MPI-IO driver)\n"); - break; - default: - break; - } - - MPI_Comm_size(pio_comm_g, &comm_size); - - /* allocate space for tables minmax and that it is sufficient */ - /* to initialize all elements to zeros by calloc. */ - write_mpi_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - write_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - write_gross_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - write_raw_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - write_open_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - write_close_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - if (!parms.h5_write_only) { - read_mpi_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - read_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - read_gross_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - read_raw_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - read_open_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - read_close_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - } - - /* Do IO iteration times, collecting statistics each time */ - for (i = 0; i < parms.num_iters; ++i) { - double t; - - MPI_Barrier(pio_comm_g); - res = do_pio(parms); - - /* gather all of the "mpi write" times */ - t = io_time_get(res.timers, HDF5_MPI_WRITE); - get_minmax(&write_mpi_mm, t); - - write_mpi_mm_table[i] = write_mpi_mm; - - /* gather all of the "write" times */ - t = io_time_get(res.timers, HDF5_FINE_WRITE_FIXED_DIMS); - get_minmax(&write_mm, t); - - write_mm_table[i] = write_mm; - - /* gather all of the "write" times from open to close */ - t = io_time_get(res.timers, HDF5_GROSS_WRITE_FIXED_DIMS); - get_minmax(&write_gross_mm, t); - - write_gross_mm_table[i] = write_gross_mm; - - /* gather all of the raw "write" times */ - t = io_time_get(res.timers, HDF5_RAW_WRITE_FIXED_DIMS); - get_minmax(&write_raw_mm, t); - - write_raw_mm_table[i] = write_raw_mm; - - /* gather all of the file open times (time from open to first write) */ - t = io_time_get(res.timers, HDF5_FILE_WRITE_OPEN); - get_minmax(&write_open_mm, t); - - write_open_mm_table[i] = write_open_mm; - - /* gather all of the file close times (time from last write to close) */ - t = io_time_get(res.timers, HDF5_FILE_WRITE_CLOSE); - get_minmax(&write_close_mm, t); - - write_close_mm_table[i] = write_close_mm; - - if (!parms.h5_write_only) { - /* gather all of the "mpi read" times */ - t = io_time_get(res.timers, HDF5_MPI_READ); - get_minmax(&read_mpi_mm, t); - - read_mpi_mm_table[i] = read_mpi_mm; - - /* gather all of the "read" times */ - t = io_time_get(res.timers, HDF5_FINE_READ_FIXED_DIMS); - get_minmax(&read_mm, t); - - read_mm_table[i] = read_mm; - - /* gather all of the "read" times from open to close */ - t = io_time_get(res.timers, HDF5_GROSS_READ_FIXED_DIMS); - get_minmax(&read_gross_mm, t); - - read_gross_mm_table[i] = read_gross_mm; - - /* gather all of the raw "read" times */ - t = io_time_get(res.timers, HDF5_RAW_READ_FIXED_DIMS); - get_minmax(&read_raw_mm, t); - - read_raw_mm_table[i] = read_raw_mm; - - /* gather all of the file open times (time from open to first read) */ - t = io_time_get(res.timers, HDF5_FILE_READ_OPEN); - get_minmax(&read_open_mm, t); - - read_open_mm_table[i] = read_open_mm; - - /* gather all of the file close times (time from last read to close) */ - t = io_time_get(res.timers, HDF5_FILE_READ_CLOSE); - get_minmax(&read_close_mm, t); - - read_close_mm_table[i] = read_close_mm; - } - - io_time_destroy(res.timers); - } - - /* - * Show various statistics - */ - /* Write statistics */ - /* Print the raw data throughput if desired */ - if (opts->print_raw) { - /* accumulate and output the max, min, and average "raw write" times */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Raw Data Write details:\n"); - output_all_info(write_raw_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Raw Data Write", write_raw_mm_table, parms.num_iters, raw_size); - } /* end if */ - - /* show mpi write statics */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("MPI Write details:\n"); - output_all_info(write_mpi_mm_table, parms.num_iters, 4); - } - - /* We don't currently output the MPI write results */ - - /* accumulate and output the max, min, and average "write" times */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Write details:\n"); - output_all_info(write_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Write", write_mm_table, parms.num_iters, raw_size); - - /* accumulate and output the max, min, and average "gross write" times */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Write Open-Close details:\n"); - output_all_info(write_gross_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Write Open-Close", write_gross_mm_table, parms.num_iters, raw_size); - - if (opts->print_times) { - output_times(opts, "Write File Open", write_open_mm_table, parms.num_iters); - output_times(opts, "Write File Close", write_close_mm_table, parms.num_iters); - } - - /* Print out time from open to first write */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Write file open details:\n"); - output_all_info(write_open_mm_table, parms.num_iters, 4); - } - - /* Print out time from last write to close */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Write file close details:\n"); - output_all_info(write_close_mm_table, parms.num_iters, 4); - } - - if (!parms.h5_write_only) { - /* Read statistics */ - /* Print the raw data throughput if desired */ - if (opts->print_raw) { - /* accumulate and output the max, min, and average "raw read" times */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Raw Data Read details:\n"); - output_all_info(read_raw_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Raw Data Read", read_raw_mm_table, parms.num_iters, raw_size); - } /* end if */ - - /* show mpi read statics */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("MPI Read details:\n"); - output_all_info(read_mpi_mm_table, parms.num_iters, 4); - } - - /* We don't currently output the MPI read results */ - - /* accumulate and output the max, min, and average "read" times */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Read details:\n"); - output_all_info(read_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Read", read_mm_table, parms.num_iters, raw_size); - - /* accumulate and output the max, min, and average "gross read" times */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Read Open-Close details:\n"); - output_all_info(read_gross_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Read Open-Close", read_gross_mm_table, parms.num_iters, raw_size); - - if (opts->print_times) { - output_times(opts, "Read File Open", read_open_mm_table, parms.num_iters); - output_times(opts, "Read File Close", read_close_mm_table, parms.num_iters); - } - - /* Print out time from open to first read */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Read file open details:\n"); - output_all_info(read_open_mm_table, parms.num_iters, 4); - } - - /* Print out time from last read to close */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Read file close details:\n"); - output_all_info(read_close_mm_table, parms.num_iters, 4); - } - } - - /* clean up our mess */ - free(write_mpi_mm_table); - free(write_mm_table); - free(write_gross_mm_table); - free(write_raw_mm_table); - free(write_open_mm_table); - free(write_close_mm_table); - - if (!parms.h5_write_only) { - free(read_mpi_mm_table); - free(read_mm_table); - free(read_gross_mm_table); - free(read_raw_mm_table); - free(read_open_mm_table); - free(read_close_mm_table); - } - - return ret_value; -} - -/* - * Function: output_all_info - * Purpose: - * Return: Nothing - * Programmer: Bill Wendling, 29. January 2002 - * Modifications: - */ -static void -output_all_info(minmax *mm, int count, int indent_level) -{ - int i; - - for (i = 0; i < count; ++i) { - print_indent(indent_level); - output_report("Iteration %d:\n", i + 1); - print_indent(indent_level + 1); - output_report("Minimum Time: %.2fs\n", mm[i].min); - print_indent(indent_level + 1); - output_report("Maximum Time: %.2fs\n", mm[i].max); - } -} - -/* - * Function: get_minmax - * Purpose: Gather all the min, max and total of val. - * Return: Nothing - * Programmer: Bill Wendling, 21. December 2001 - * Modifications: - * Use MPI_Allreduce to do it. -akc, 2002/01/11 - */ -static void -get_minmax(minmax *mm, double val) -{ - int myrank; - - MPI_Comm_rank(pio_comm_g, &myrank); - MPI_Comm_size(pio_comm_g, &mm->num); - - MPI_Allreduce(&val, &mm->max, 1, MPI_DOUBLE, MPI_MAX, pio_comm_g); - MPI_Allreduce(&val, &mm->min, 1, MPI_DOUBLE, MPI_MIN, pio_comm_g); - MPI_Allreduce(&val, &mm->sum, 1, MPI_DOUBLE, MPI_SUM, pio_comm_g); -} - -/* - * Function: accumulate_minmax_stuff - * Purpose: Accumulate the minimum, maximum, and average of the times - * across all processes. - * Return: TOTAL_MM - the total of all of these. - * Programmer: Bill Wendling, 21. December 2001 - * Modifications: - * Changed to use seconds instead of MB/s - QAK, 5/9/02 - */ -static minmax -accumulate_minmax_stuff(minmax *mm, int count) -{ - int i; - minmax total_mm; - - total_mm.sum = 0.0f; - total_mm.max = -DBL_MAX; - total_mm.min = DBL_MAX; - total_mm.num = count; - - for (i = 0; i < count; ++i) { - double m = mm[i].max; - - total_mm.sum += m; - - if (m < total_mm.min) - total_mm.min = m; - - if (m > total_mm.max) - total_mm.max = m; - } - - return total_mm; -} - -/* - * Function: create_comm_world - * Purpose: Create an MPI Comm world and store it in pio_comm_g, which - * is a global variable. - * Return: SUCCESS on success. - * FAIL otherwise. - * Programmer: Bill Wendling, 19. December 2001 - * Modifications: - */ -static int -create_comm_world(int num_procs, int *doing_pio) -{ - /* MPI variables */ - int mrc; /* return values */ - int color; /* for communicator creation */ - int myrank, nprocs; - - pio_comm_g = MPI_COMM_NULL; - - /* - * Create a sub communicator for this PIO run. Easier to use the first N - * processes. - */ - MPI_Comm_size(MPI_COMM_WORLD, &nprocs); - - if (num_procs > nprocs) { - HDfprintf(stderr, "number of process(%d) must be <= number of processes in MPI_COMM_WORLD(%d)\n", - num_procs, nprocs); - goto error_done; - } - - MPI_Comm_rank(MPI_COMM_WORLD, &myrank); - color = (myrank < num_procs); - mrc = MPI_Comm_split(MPI_COMM_WORLD, color, myrank, &pio_comm_g); - - if (mrc != MPI_SUCCESS) { - HDfprintf(stderr, "MPI_Comm_split failed\n"); - goto error_done; - } - - if (!color) { - /* not involved in this run */ - mrc = destroy_comm_world(); - goto done; - } - - /* determine the MPI rank in the PIO communicator */ - MPI_Comm_size(pio_comm_g, &pio_mpi_nprocs_g); - MPI_Comm_rank(pio_comm_g, &pio_mpi_rank_g); - -done: - *doing_pio = color; - return SUCCESS; - -error_done: - destroy_comm_world(); - return FAIL; -} - -/* - * Function: destroy_comm_world - * Purpose: Destroy the created MPI Comm world which is stored in the - * pio_comm_g global variable. - * Return: SUCCESS on success. - * FAIL otherwise. - * Programmer: Bill Wendling, 19. December 2001 - * Modifications: - */ -static int -destroy_comm_world(void) -{ - int mrc = SUCCESS; /* return code */ - - /* release MPI resources */ - if (pio_comm_g != MPI_COMM_NULL) - mrc = (MPI_Comm_free(&pio_comm_g) == MPI_SUCCESS ? SUCCESS : FAIL); - - return mrc; -} - -/* - * Function: output_results - * Purpose: Print information about the time & bandwidth for a given - * minmax & # of iterations. - * Return: Nothing - * Programmer: Quincey Koziol, 9. May 2002 - * Modifications: - */ -static void -output_results(const struct options *opts, const char *name, minmax *table, int table_size, off_t data_size) -{ - minmax total_mm; - - total_mm = accumulate_minmax_stuff(table, table_size); - - print_indent(3); - output_report("%s (%d iteration(s)):\n", name, table_size); - - /* Note: The maximum throughput uses the minimum amount of time & vice versa */ - - print_indent(4); - output_report("Maximum Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.min)); - if (opts->print_times) - output_report(" (%7.3f s)\n", total_mm.min); - else - output_report("\n"); - - print_indent(4); - output_report("Average Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.sum / total_mm.num)); - if (opts->print_times) - output_report(" (%7.3f s)\n", (total_mm.sum / total_mm.num)); - else - output_report("\n"); - - print_indent(4); - output_report("Minimum Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.max)); - if (opts->print_times) - output_report(" (%7.3f s)\n", total_mm.max); - else - output_report("\n"); -} - -static void -output_times(const struct options *opts, const char *name, minmax *table, int table_size) -{ - minmax total_mm; - - total_mm = accumulate_minmax_stuff(table, table_size); - - print_indent(3); - output_report("%s (%d iteration(s)):\n", name, table_size); - - /* Note: The maximum throughput uses the minimum amount of time & vice versa */ - - print_indent(4); - output_report("Minimum Accumulated Time using %d file(s): %7.5f s\n", opts->num_files, (total_mm.min)); - - print_indent(4); - output_report("Average Accumulated Time using %d file(s): %7.5f s\n", opts->num_files, - (total_mm.sum / total_mm.num)); - - print_indent(4); - output_report("Maximum Accumulated Time using %d file(s): %7.5f s\n", opts->num_files, (total_mm.max)); -} - -/* - * Function: output_report - * Purpose: Print a line of the report. Only do so if I'm the 0 process. - * Return: Nothing - * Programmer: Bill Wendling, 19. December 2001 - * Modifications: - */ -static void -output_report(const char *fmt, ...) -{ - int myrank; - - MPI_Comm_rank(pio_comm_g, &myrank); - - if (myrank == 0) { - va_list ap; - - HDva_start(ap, fmt); - HDvfprintf(output, fmt, ap); - HDva_end(ap); - } -} - -/* - * Function: print_indent - * Purpose: Print spaces to indent a new line of text for pretty printing - * things. - * Return: Nothing - * Programmer: Bill Wendling, 29. October 2001 - * Modifications: - */ -static void -print_indent(register int indent) -{ - int myrank; - - MPI_Comm_rank(pio_comm_g, &myrank); - - if (myrank == 0) { - indent *= TAB_SPACE; - - for (; indent > 0; --indent) - HDfputc(' ', output); - } -} - -static void -recover_size_and_print(long long val, const char *end) -{ - if (val >= ONE_KB && (val % ONE_KB) == 0) { - if (val >= ONE_MB && (val % ONE_MB) == 0) { - if (val >= ONE_GB && (val % ONE_GB) == 0) - HDfprintf(output, - "%" H5_PRINTF_LL_WIDTH "d" - "GB%s", - val / ONE_GB, end); - else - HDfprintf(output, - "%" H5_PRINTF_LL_WIDTH "d" - "MB%s", - val / ONE_MB, end); - } - else { - HDfprintf(output, - "%" H5_PRINTF_LL_WIDTH "d" - "KB%s", - val / ONE_KB, end); - } - } - else { - HDfprintf(output, - "%" H5_PRINTF_LL_WIDTH "d" - "%s", - val, end); - } -} - -static void -print_io_api(long io_types) -{ - if (io_types & PIO_POSIX) - HDfprintf(output, "posix "); - if (io_types & PIO_MPI) - HDfprintf(output, "mpiio "); - if (io_types & PIO_HDF5) - HDfprintf(output, "phdf5 "); - HDfprintf(output, "\n"); -} - -static void -report_parameters(struct options *opts) -{ - int rank = comm_world_rank_g; - - print_version("HDF5 Library"); /* print library version */ - HDfprintf(output, "rank %d: ==== Parameters ====\n", rank); - - HDfprintf(output, "rank %d: IO API=", rank); - print_io_api(opts->io_types); - - HDfprintf(output, "rank %d: Number of files=%ld\n", rank, opts->num_files); - HDfprintf(output, "rank %d: Number of datasets=%ld\n", rank, opts->num_dsets); - HDfprintf(output, "rank %d: Number of iterations=%d\n", rank, opts->num_iters); - HDfprintf(output, "rank %d: Number of processes=%d:%d\n", rank, opts->min_num_procs, opts->max_num_procs); - - if (opts->dim2d) { - HDfprintf(output, "rank %d: Number of bytes per process per dataset=", rank); - recover_size_and_print((long long)(opts->num_bpp * opts->num_bpp * opts->min_num_procs), ":"); - recover_size_and_print((long long)(opts->num_bpp * opts->num_bpp * opts->max_num_procs), "\n"); - - HDfprintf(output, "rank %d: Size of dataset(s)=", rank); - recover_size_and_print((long long)(opts->num_bpp * opts->min_num_procs), "x"); - recover_size_and_print((long long)(opts->num_bpp * opts->min_num_procs), ":"); - recover_size_and_print((long long)(opts->num_bpp * opts->max_num_procs), "x"); - recover_size_and_print((long long)(opts->num_bpp * opts->max_num_procs), "\n"); - - HDfprintf(output, "rank %d: File size=", rank); - recover_size_and_print((long long)(squareo(opts->num_bpp * opts->min_num_procs) * opts->num_dsets), - ":"); - recover_size_and_print((long long)(squareo(opts->num_bpp * opts->max_num_procs) * opts->num_dsets), - "\n"); - - HDfprintf(output, "rank %d: Transfer buffer size=", rank); - if (opts->interleaved) { - recover_size_and_print((long long)opts->min_xfer_size, "x"); - recover_size_and_print((long long)opts->blk_size, ":"); - recover_size_and_print((long long)opts->max_xfer_size, "x"); - recover_size_and_print((long long)opts->blk_size, "\n"); - } - else { - recover_size_and_print((long long)opts->blk_size, "x"); - recover_size_and_print((long long)opts->min_xfer_size, ":"); - recover_size_and_print((long long)opts->blk_size, "x"); - recover_size_and_print((long long)opts->max_xfer_size, "\n"); - } - HDfprintf(output, "rank %d: Block size=", rank); - recover_size_and_print((long long)opts->blk_size, "x"); - recover_size_and_print((long long)opts->blk_size, "\n"); - } - else { - HDfprintf(output, "rank %d: Number of bytes per process per dataset=", rank); - recover_size_and_print((long long)opts->num_bpp, "\n"); - - HDfprintf(output, "rank %d: Size of dataset(s)=", rank); - recover_size_and_print((long long)(opts->num_bpp * opts->min_num_procs), ":"); - recover_size_and_print((long long)(opts->num_bpp * opts->max_num_procs), "\n"); - - HDfprintf(output, "rank %d: File size=", rank); - recover_size_and_print((long long)(opts->num_bpp * opts->min_num_procs * opts->num_dsets), ":"); - recover_size_and_print((long long)(opts->num_bpp * opts->max_num_procs * opts->num_dsets), "\n"); - - HDfprintf(output, "rank %d: Transfer buffer size=", rank); - recover_size_and_print((long long)opts->min_xfer_size, ":"); - recover_size_and_print((long long)opts->max_xfer_size, "\n"); - HDfprintf(output, "rank %d: Block size=", rank); - recover_size_and_print((long long)opts->blk_size, "\n"); - } - - HDfprintf(output, "rank %d: Block Pattern in Dataset=", rank); - if (opts->interleaved) - HDfprintf(output, "Interleaved\n"); - else - HDfprintf(output, "Contiguous\n"); - - HDfprintf(output, "rank %d: I/O Method for MPI and HDF5=", rank); - if (opts->collective) - HDfprintf(output, "Collective\n"); - else - HDfprintf(output, "Independent\n"); - - HDfprintf(output, "rank %d: Geometry=", rank); - if (opts->dim2d) - HDfprintf(output, "2D\n"); - else - HDfprintf(output, "1D\n"); - - HDfprintf(output, "rank %d: VFL used for HDF5 I/O=%s\n", rank, "MPI-IO driver"); - - HDfprintf(output, "rank %d: Data storage method in HDF5=", rank); - if (opts->h5_use_chunks) - HDfprintf(output, "Chunked\n"); - else - HDfprintf(output, "Contiguous\n"); - - { - char *prefix = HDgetenv("HDF5_PARAPREFIX"); - - HDfprintf(output, "rank %d: Env HDF5_PARAPREFIX=%s\n", rank, (prefix ? prefix : "not set")); - } - - HDfprintf(output, "rank %d: ", rank); - h5_dump_info_object(h5_io_info_g); - - HDfprintf(output, "rank %d: ==== End of Parameters ====\n", rank); - HDfprintf(output, "\n"); -} - -/* - * Function: parse_command_line - * Purpose: Parse the command line options and return a STRUCT OPTIONS - * structure which will need to be freed by the calling function. - * Return: Pointer to an OPTIONS structure - * Programmer: Bill Wendling, 31. October 2001 - * Modifications: - * Added 2D testing (Christian Chilan, 10. August 2005) - */ -static struct options * -parse_command_line(int argc, char *argv[]) -{ - register int opt; - struct options *cl_opts; - - cl_opts = (struct options *)malloc(sizeof(struct options)); - - cl_opts->output_file = NULL; - cl_opts->io_types = 0; /* will set default after parsing options */ - cl_opts->num_dsets = 1; - cl_opts->num_files = 1; - cl_opts->num_bpp = 0; - cl_opts->num_iters = 1; - cl_opts->max_num_procs = comm_world_nprocs_g; - cl_opts->min_num_procs = 1; - cl_opts->max_xfer_size = 0; - cl_opts->min_xfer_size = 0; - cl_opts->blk_size = 0; - cl_opts->interleaved = 0; /* Default to contiguous blocks in dataset */ - cl_opts->collective = 0; /* Default to independent I/O access */ - cl_opts->dim2d = 0; /* Default to 1D */ - cl_opts->print_times = FALSE; /* Printing times is off by default */ - cl_opts->print_raw = FALSE; /* Printing raw data throughput is off by default */ - cl_opts->h5_alignment = 1; /* No alignment for HDF5 objects by default */ - cl_opts->h5_threshold = 1; /* No threshold for aligning HDF5 objects by default */ - cl_opts->h5_use_chunks = FALSE; /* Don't chunk the HDF5 dataset by default */ - cl_opts->h5_write_only = FALSE; /* Do both read and write by default */ - cl_opts->verify = FALSE; /* No Verify data correctness by default */ - - while ((opt = H5_get_option(argc, (const char **)argv, s_opts, l_opts)) != EOF) { - switch ((char)opt) { - case 'a': - cl_opts->h5_alignment = parse_size_directive(H5_optarg); - break; - case 'A': { - const char *end = H5_optarg; - - while (end && *end != '\0') { - char buf[10]; - int i; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (isalnum(*end) && i < 10) - buf[i++] = *end; - - if (!HDstrcasecmp(buf, "phdf5")) { - cl_opts->io_types |= PIO_HDF5; - } - else if (!HDstrcasecmp(buf, "mpiio")) { - cl_opts->io_types |= PIO_MPI; - } - else if (!HDstrcasecmp(buf, "posix")) { - cl_opts->io_types |= PIO_POSIX; - } - else { - HDfprintf(stderr, "pio_perf: invalid --api option %s\n", buf); - HDexit(EXIT_FAILURE); - } - - if (*end == '\0') - break; - - end++; - } - } - - break; -#if 0 - case 'b': - /* the future "binary" option */ - break; -#endif /* 0 */ - case 'B': - cl_opts->blk_size = (size_t)parse_size_directive(H5_optarg); - break; - case 'c': - /* Turn on chunked HDF5 dataset creation */ - cl_opts->h5_use_chunks = TRUE; - break; - case 'C': - cl_opts->collective = 1; - break; - case 'd': - cl_opts->num_dsets = atoi(H5_optarg); - break; - case 'D': { - const char *end = H5_optarg; - - while (end && *end != '\0') { - char buf[10]; - int i; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (HDisalnum(*end) && i < 10) - buf[i++] = *end; - - if (HDstrlen(buf) > 1 || HDisdigit(buf[0])) { - size_t j; - - for (j = 0; j < 10 && buf[j] != '\0'; ++j) - if (!isdigit(buf[j])) { - HDfprintf(stderr, "pio_perf: invalid --debug option %s\n", buf); - HDexit(EXIT_FAILURE); - } - - pio_debug_level = atoi(buf); - - if (pio_debug_level > 4) - pio_debug_level = 4; - else if (pio_debug_level < 0) - pio_debug_level = 0; - } - else { - switch (*buf) { - case 'r': - /* Turn on raw data throughput info */ - cl_opts->print_raw = TRUE; - break; - case 't': - /* Turn on time printing */ - cl_opts->print_times = TRUE; - break; - case 'v': - /* Turn on verify data correctness*/ - cl_opts->verify = TRUE; - break; - default: - HDfprintf(stderr, "pio_perf: invalid --debug option %s\n", buf); - HDexit(EXIT_FAILURE); - } - } - - if (*end == '\0') - break; - - end++; - } - } - - break; - case 'e': - cl_opts->num_bpp = parse_size_directive(H5_optarg); - break; - case 'F': - cl_opts->num_files = HDatoi(H5_optarg); - break; - case 'g': - cl_opts->dim2d = 1; - break; - case 'i': - cl_opts->num_iters = HDatoi(H5_optarg); - break; - case 'I': - cl_opts->interleaved = 1; - break; - case 'o': - cl_opts->output_file = H5_optarg; - break; - case 'p': - cl_opts->min_num_procs = HDatoi(H5_optarg); - break; - case 'P': - cl_opts->max_num_procs = HDatoi(H5_optarg); - break; - case 'T': - cl_opts->h5_threshold = parse_size_directive(H5_optarg); - break; - case 'w': - cl_opts->h5_write_only = TRUE; - break; - case 'x': - cl_opts->min_xfer_size = (size_t)parse_size_directive(H5_optarg); - break; - case 'X': - cl_opts->max_xfer_size = (size_t)parse_size_directive(H5_optarg); - break; - case 'h': - case '?': - default: - usage(progname); - HDfree(cl_opts); - return NULL; - } - } - - if (cl_opts->num_bpp == 0) { - if (cl_opts->dim2d == 0) - cl_opts->num_bpp = 256 * ONE_KB; - else - cl_opts->num_bpp = 8 * ONE_KB; - } - - if (cl_opts->max_xfer_size == 0) - cl_opts->max_xfer_size = (size_t)cl_opts->num_bpp; - - if (cl_opts->min_xfer_size == 0) - cl_opts->min_xfer_size = (size_t)(cl_opts->num_bpp) / 2; - - if (cl_opts->blk_size == 0) - cl_opts->blk_size = (size_t)(cl_opts->num_bpp) / 2; - - /* set default if none specified yet */ - if (!cl_opts->io_types) - cl_opts->io_types = PIO_HDF5 | PIO_MPI | PIO_POSIX; /* run all API */ - - /* verify parameters sanity. Adjust if needed. */ - /* cap xfer_size with bytes per process */ - if (!cl_opts->dim2d) { - if (cl_opts->min_xfer_size > (size_t)cl_opts->num_bpp) - cl_opts->min_xfer_size = (size_t)cl_opts->num_bpp; - if (cl_opts->max_xfer_size > (size_t)cl_opts->num_bpp) - cl_opts->max_xfer_size = (size_t)cl_opts->num_bpp; - } - if (cl_opts->min_xfer_size > cl_opts->max_xfer_size) - cl_opts->min_xfer_size = cl_opts->max_xfer_size; - if (cl_opts->blk_size > (size_t)cl_opts->num_bpp) - cl_opts->blk_size = (size_t)cl_opts->num_bpp; - /* check range of number of processes */ - if (cl_opts->min_num_procs <= 0) - cl_opts->min_num_procs = 1; - if (cl_opts->max_num_procs <= 0) - cl_opts->max_num_procs = 1; - if (cl_opts->min_num_procs > cl_opts->max_num_procs) - cl_opts->min_num_procs = cl_opts->max_num_procs; - /* check iteration */ - if (cl_opts->num_iters <= 0) - cl_opts->num_iters = 1; - - return cl_opts; -} - -/* - * Function: parse_size_directive - * Purpose: Parse the size directive passed on the commandline. The size - * directive is an integer followed by a size indicator: - * - * K, k - Kilobyte - * M, m - Megabyte - * G, g - Gigabyte - * - * Return: The size as a off_t because this is related to file size. - * If an unknown size indicator is used, then the program will - * exit with EXIT_FAILURE as the return value. - * Programmer: Bill Wendling, 18. December 2001 - * Modifications: - */ -static off_t -parse_size_directive(const char *size) -{ - off_t s; - char *endptr; - - s = HDstrtol(size, &endptr, 10); - - if (endptr && *endptr) { - while (*endptr != '\0' && (*endptr == ' ' || *endptr == '\t')) - ++endptr; - - switch (*endptr) { - case 'K': - case 'k': - s *= ONE_KB; - break; - case 'M': - case 'm': - s *= ONE_MB; - break; - case 'G': - case 'g': - s *= ONE_GB; - break; - default: - HDfprintf(stderr, "Illegal size specifier '%c'\n", *endptr); - HDexit(EXIT_FAILURE); - } - } - - return s; -} - -/* - * Function: usage - * Purpose: Print a usage message and then exit. - * Return: Nothing - * Programmer: Bill Wendling, 31. October 2001 - * Modifications: - * Added 2D testing (Christian Chilan, 10. August 2005) - */ -static void -usage(const char *prog) -{ - int myrank; - - MPI_Comm_rank(pio_comm_g, &myrank); - - if (myrank == 0) { - print_version(prog); - HDprintf("usage: %s [OPTIONS]\n", prog); - HDprintf(" OPTIONS\n"); - HDprintf(" -h, --help Print a usage message and exit\n"); - HDprintf(" -a S, --align=S Alignment of objects in HDF5 file [default: 1]\n"); - HDprintf(" -A AL, --api=AL Which APIs to test [default: all of them]\n"); -#if 0 - HDprintf(" -b, --binary The elusive binary option\n"); -#endif /* 0 */ - HDprintf(" -B S, --block-size=S Block size within transfer buffer\n"); - HDprintf(" (see below for description)\n"); - HDprintf(" [default: half the number of bytes per process\n"); - HDprintf(" per dataset]\n"); - HDprintf(" -c, --chunk Create HDF5 datasets using chunked storage\n"); - HDprintf(" [default: contiguous storage]\n"); - HDprintf(" -C, --collective Use collective I/O for MPI and HDF5 APIs\n"); - HDprintf(" [default: independent I/O)\n"); - HDprintf(" -d N, --num-dsets=N Number of datasets per file [default: 1]\n"); - HDprintf(" -D DL, --debug=DL Indicate the debugging level\n"); - HDprintf(" [default: no debugging]\n"); - HDprintf(" -e S, --num-bytes=S Number of bytes per process per dataset\n"); - HDprintf(" (see below for description)\n"); - HDprintf(" [default: 256K for 1D, 8K for 2D]\n"); - HDprintf(" -F N, --num-files=N Number of files [default: 1]\n"); - HDprintf(" -g, --geometry Use 2D geometry [default: 1D geometry]\n"); - HDprintf(" -i N, --num-iterations=N Number of iterations to perform [default: 1]\n"); - HDprintf(" -I, --interleaved Interleaved access pattern\n"); - HDprintf(" (see below for example)\n"); - HDprintf(" [default: Contiguous access pattern]\n"); - HDprintf(" -o F, --output=F Output raw data into file F [default: none]\n"); - HDprintf(" -p N, --min-num-processes=N Minimum number of processes to use [default: 1]\n"); - HDprintf(" -P N, --max-num-processes=N Maximum number of processes to use\n"); - HDprintf(" [default: all MPI_COMM_WORLD processes ]\n"); - HDprintf(" -T S, --threshold=S Threshold for alignment of objects in HDF5 file\n"); - HDprintf(" [default: 1]\n"); - HDprintf(" -w, --write-only Perform write tests not the read tests\n"); - HDprintf(" -x S, --min-xfer-size=S Minimum transfer buffer size\n"); - HDprintf(" (see below for description)\n"); - HDprintf(" [default: half the number of bytes per process\n"); - HDprintf(" per dataset]\n"); - HDprintf(" -X S, --max-xfer-size=S Maximum transfer buffer size\n"); - HDprintf(" [default: the number of bytes per process per\n"); - HDprintf(" dataset]\n"); - HDprintf("\n"); - HDprintf(" F - is a filename.\n"); - HDprintf(" N - is an integer >=0.\n"); - HDprintf(" S - is a size specifier, an integer >=0 followed by a size indicator:\n"); - HDprintf(" K - Kilobyte (%d)\n", ONE_KB); - HDprintf(" M - Megabyte (%d)\n", ONE_MB); - HDprintf(" G - Gigabyte (%d)\n", ONE_GB); - HDprintf("\n"); - HDprintf(" Example: '37M' is 37 megabytes or %d bytes\n", 37 * ONE_MB); - HDprintf("\n"); - HDprintf(" AL - is an API list. Valid values are:\n"); - HDprintf(" phdf5 - Parallel HDF5\n"); - HDprintf(" mpiio - MPI-I/O\n"); - HDprintf(" posix - POSIX\n"); - HDprintf("\n"); - HDprintf(" Example: --api=mpiio,phdf5\n"); - HDprintf("\n"); - HDprintf(" Dataset size:\n"); - HDprintf(" Depending on the selected geometry, each test dataset is either a linear\n"); - HDprintf(" array of size bytes-per-process * num-processes, or a square array of size\n"); - HDprintf(" (bytes-per-process * num-processes) x (bytes-per-process * num-processes).\n"); - HDprintf("\n"); - HDprintf(" Block size vs. Transfer buffer size:\n"); - HDprintf(" buffer-size controls the size of the memory buffer, which is broken into\n"); - HDprintf(" blocks and written to the file. Depending on the selected geometry, each\n"); - HDprintf(" block can be a linear array of size block-size or a square array of size\n"); - HDprintf(" block-size x block-size. The arrangement in which blocks are written is\n"); - HDprintf(" determined by the access pattern.\n"); - HDprintf("\n"); - HDprintf(" In 1D geometry, the transfer buffer is a linear array of size buffer-size.\n"); - HDprintf(" In 2D geometry, it is a rectangular array of size block-size x buffer-size\n"); - HDprintf(" or buffer-size x block-size if interleaved pattern is selected.\n"); - HDprintf("\n"); - HDprintf(" Interleaved and Contiguous patterns in 1D geometry:\n"); - HDprintf(" When contiguous access pattern is chosen, the dataset is evenly divided\n"); - HDprintf(" into num-processes regions and each process writes data to its own region.\n"); - HDprintf(" When interleaved blocks are written to a dataset, space for the first\n"); - HDprintf(" block of the first process is allocated in the dataset, then space is\n"); - HDprintf(" allocated for the first block of the second process, etc. until space is\n"); - HDprintf(" allocated for the first block of each process, then space is allocated for\n"); - HDprintf(" the second block of the first process, the second block of the second\n"); - HDprintf(" process, etc.\n"); - HDprintf("\n"); - HDprintf(" For example, with a 3 process run, 512KB bytes-per-process, 256KB transfer\n"); - HDprintf(" buffer size, and 64KB block size, each process must issue 2 transfer\n"); - HDprintf(" requests to complete access to the dataset.\n"); - HDprintf(" Contiguous blocks of the first transfer request are written like so:\n"); - HDprintf(" 1111----2222----3333----\n"); - HDprintf(" Interleaved blocks of the first transfer request are written like so:\n"); - HDprintf(" 123123123123------------\n"); - HDprintf(" The actual number of I/O operations involved in a transfer request\n"); - HDprintf(" depends on the access pattern and communication mode.\n"); - HDprintf(" When using independent I/O with interleaved pattern, each process\n"); - HDprintf(" performs 4 small non-contiguous I/O operations per transfer request.\n"); - HDprintf(" If collective I/O is turned on, the combined content of the buffers of\n"); - HDprintf(" the 3 processes will be written using one collective I/O operation\n"); - HDprintf(" per transfer request.\n"); - HDprintf("\n"); - HDprintf(" For information about access patterns in 2D geometry, please refer to the\n"); - HDprintf(" HDF5 Reference Manual.\n"); - HDprintf("\n"); - HDprintf(" DL - is a list of debugging flags. Valid values are:\n"); - HDprintf(" 1 - Minimal\n"); - HDprintf(" 2 - Not quite everything\n"); - HDprintf(" 3 - Everything\n"); - HDprintf(" 4 - The kitchen sink\n"); - HDprintf(" r - Raw data I/O throughput information\n"); - HDprintf(" t - Times as well as throughputs\n"); - HDprintf(" v - Verify data correctness\n"); - HDprintf("\n"); - HDprintf(" Example: --debug=2,r,t\n"); - HDprintf("\n"); - HDprintf(" Environment variables:\n"); - HDprintf(" HDF5_NOCLEANUP Do not remove data files if set [default remove]\n"); - HDprintf(" HDF5_MPI_INFO MPI INFO object key=value separated by ;\n"); - HDprintf(" HDF5_PARAPREFIX Paralllel data files prefix\n"); - fflush(stdout); - } /* end if */ -} /* end usage() */ - -#else /* H5_HAVE_PARALLEL */ - -/* - * Function: main - * Purpose: Dummy main() function for if HDF5 was configured without - * parallel stuff. - * Return: EXIT_SUCCESS - * Programmer: Bill Wendling, 14. November 2001 - */ -int -main(void) -{ - HDprintf("No parallel IO performance because parallel is not configured\n"); - return EXIT_SUCCESS; -} /* end main */ - -#endif /* !H5_HAVE_PARALLEL */ diff --git a/tools/test/perform/pio_perf.h b/tools/test/perform/pio_perf.h deleted file mode 100644 index 24621da..0000000 --- a/tools/test/perform/pio_perf.h +++ /dev/null @@ -1,100 +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. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef PIO_PERF_H -#define PIO_PERF_H - -#ifndef STANDALONE -#include "io_timer.h" -#include "h5test.h" -#include "h5tools.h" -#include "h5tools_utils.h" -#else -#include "io_timer.h" -#include "pio_standalone.h" -#endif - -/* setup the dataset no fill option if this is v1.5 or more */ -#if H5_VERS_MAJOR > 1 || H5_VERS_MINOR > 4 -#define H5_HAVE_NOFILL 1 -#endif - -typedef enum iotype_ { - POSIXIO, - MPIO, - PHDF5 - /*NUM_TYPES*/ -} iotype; - -typedef struct parameters_ { - iotype io_type; /* The type of IO test to perform */ - int num_procs; /* Maximum number of processes to use */ - long num_files; /* Number of files to create */ - long num_dsets; /* Number of datasets to create */ - off_t num_bytes; /* Number of bytes in each dset */ - int num_iters; /* Number of times to loop doing the IO */ - size_t buf_size; /* Buffer size */ - size_t blk_size; /* Block size */ - unsigned interleaved; /* Interleaved vs. contiguous blocks */ - unsigned collective; /* Collective vs. independent I/O */ - unsigned dim2d; /* 1D vs. 2D */ - hsize_t h5_align; /* HDF5 object alignment */ - hsize_t h5_thresh; /* HDF5 object alignment threshold */ - int h5_use_chunks; /* Make HDF5 dataset chunked */ - int h5_write_only; /* Perform the write tests only */ - int verify; /* Verify data correctness */ -} parameters; - -typedef struct results_ { - herr_t ret_code; - io_time_t *timers; -} results; - -#ifndef SUCCESS -#define SUCCESS 0 -#endif /* !SUCCESS */ - -#ifndef FAIL -#define FAIL -1 -#endif /* !FAIL */ - -extern FILE * output; /* output file */ -extern io_time_t *timer_g; /* timer: global for stub functions */ -extern int comm_world_rank_g; /* my rank in MPI_COMM_RANK */ -extern int comm_world_nprocs_g; /* num. of processes of MPI_COMM_WORLD */ -extern MPI_Comm pio_comm_g; /* Communicator to run the PIO */ -extern int pio_mpi_rank_g; /* MPI rank of pio_comm_g */ -extern int pio_mpi_nprocs_g; /* number of processes of pio_comm_g */ -extern int pio_debug_level; /* The debug level: - * 0 - Off - * 1 - Minimal - * 2 - Some more - * 3 - Maximal - * 4 - Even More Debugging (timer stuff) - */ - -#define HDprint_rank(f) /* print rank in MPI_COMM_WORLD */ HDfprintf(f, "%d: ", comm_world_rank_g); -#define HDprint_size(f) /* print size of MPI_COMM_WORLD */ HDfprintf(f, "%d", comm_world_nprocs_g); -#define HDprint_rank_size(f) /* print rank/size of MPI_COMM_WORLD */ \ - HDfprintf(f, "%d/%d: ", comm_world_rank_g, comm_world_nprocs_g); - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -extern results do_pio(parameters param); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* PIO_PERF_H */ diff --git a/tools/test/perform/pio_standalone.c b/tools/test/perform/pio_standalone.c index db8633e..032bfba 100644 --- a/tools/test/perform/pio_standalone.c +++ b/tools/test/perform/pio_standalone.c @@ -17,20 +17,11 @@ #include "pio_perf.h" -#ifdef STANDALONE -MPI_Info h5_io_info_g = MPI_INFO_NULL; /* MPI INFO object for IO */ -#endif - /** From h5tools_utils.c **/ /* global variables */ int nCols = 80; -/* ``get_option'' variables */ -int H5_opterr = 1; /*get_option prints errors if this is on */ -int H5_optind = 1; /*token pointer */ -const char *H5_optarg; /*flag argument (or value) */ - int get_option(int argc, const char **argv, const char *opts, const struct h5_long_options *l_opts) { @@ -161,134 +152,3 @@ print_version(const char *progname) printf("%s: Version %u.%u.%u%s%s\n", progname, H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE, H5_VERS_SUBRELEASE[0] ? "-" : "", H5_VERS_SUBRELEASE); } - -#ifdef STANDALONE -/* - * Function: h5_set_info_object - * Purpose: Process environment variables setting to set up MPI Info - * object. - * Return: 0 if all is fine; otherwise non-zero. - * Programmer: Albert Cheng, 2002/05/21. - * Modifications: - * Bill Wendling, 2002/05/31 - * Modified so that the HDF5_MPI_INFO environment variable can - * be a semicolon separated list of "key=value" pairings. Most - * of the code is to remove any whitespaces which might be - * surrounding the "key=value" pairs. - */ -int -h5_set_info_object(void) -{ - char *envp; /* environment pointer */ - int ret_value = 0; - - /* handle any MPI INFO hints via $HDF5_MPI_INFO */ - if ((envp = HDgetenv("HDF5_MPI_INFO")) != NULL) { - char *next, *valp; - - valp = envp = next = HDstrdup(envp); - - if (!valp) - return 0; - - /* create an INFO object if not created yet */ - if (h5_io_info_g == MPI_INFO_NULL) - MPI_Info_create(&h5_io_info_g); - - do { - size_t len; - char * key_val, *endp, *namep; - - if (*valp == ';') - valp++; - - /* copy key/value pair into temporary buffer */ - len = strcspn(valp, ";"); - next = &valp[len]; - key_val = (char *)HDcalloc(1, len + 1); - - /* increment the next pointer past the terminating semicolon */ - if (*next == ';') - ++next; - - namep = HDstrncpy(key_val, valp, len); - - /* pass up any beginning whitespaces */ - while (*namep && (*namep == ' ' || *namep == '\t')) - namep++; - - if (!*namep) - continue; /* was all white space, so move to next k/v pair */ - - /* eat up any ending white spaces */ - endp = &namep[HDstrlen(namep) - 1]; - - while (endp && (*endp == ' ' || *endp == '\t')) - *endp-- = '\0'; - - /* find the '=' */ - valp = HDstrchr(namep, '='); - - if (valp != NULL) { /* it's a valid key/value pairing */ - char *tmp_val = valp + 1; - - /* change '=' to \0, move valp down one */ - *valp-- = '\0'; - - /* eat up ending whitespace on the "key" part */ - while (*valp == ' ' || *valp == '\t') - *valp-- = '\0'; - - valp = tmp_val; - - /* eat up beginning whitespace on the "value" part */ - while (*valp == ' ' || *valp == '\t') - *valp++ = '\0'; - - /* actually set the darned thing */ - if (MPI_SUCCESS != MPI_Info_set(h5_io_info_g, namep, valp)) { - HDprintf("MPI_Info_set failed\n"); - ret_value = -1; - } - } - - valp = next; - HDfree(key_val); - } while (next && *next); - - HDfree(envp); - } - - return ret_value; -} - -/* - * Function: h5_dump_info_object - * Purpose: Display content of an MPI Info object - * Return: void - * Programmer: Albert Cheng 2002/05/21 - * Modifications: - */ -void -h5_dump_info_object(MPI_Info info) -{ - char key[MPI_MAX_INFO_KEY + 1]; - char value[MPI_MAX_INFO_VAL + 1]; - int flag; - int i, nkeys; - - HDprintf("Dumping MPI Info Object (up to %d bytes per item):\n", MPI_MAX_INFO_VAL); - if (info == MPI_INFO_NULL) { - HDprintf("object is MPI_INFO_NULL\n"); - } - else { - MPI_Info_get_nkeys(info, &nkeys); - HDprintf("object has %d items\n", nkeys); - for (i = 0; i < nkeys; i++) { - MPI_Info_get_nthkey(info, i, key); - MPI_Info_get(info, key, MPI_MAX_INFO_VAL, value, &flag); - HDprintf("%s=%s\n", key, value); - } - } -} -#endif /* STANDALONE */ diff --git a/tools/test/perform/pio_standalone.h b/tools/test/perform/pio_standalone.h index 4b5c7b2..f1fb946 100644 --- a/tools/test/perform/pio_standalone.h +++ b/tools/test/perform/pio_standalone.h @@ -441,22 +441,11 @@ extern char * strdup(const char *s); #define TRUE true #endif -/** From h5test.h **/ - -#ifdef H5_HAVE_PARALLEL -extern MPI_Info h5_io_info_g; /* MPI INFO object for IO */ -#endif - -#ifdef H5_HAVE_PARALLEL -int h5_set_info_object(void); -void h5_dump_info_object(MPI_Info info); -#endif - /** From h5tools_utils.h **/ -extern int H5_opterr; /* getoption prints errors if this is on */ -extern int H5_optind; /* token pointer */ -extern const char *H5_optarg; /* flag argument (or value) */ +H5_DLLVAR int H5_opterr; /* getoption prints errors if this is on */ +H5_DLLVAR int H5_optind; /* token pointer */ +H5_DLLVAR const char *H5_optarg; /* flag argument (or value) */ enum h5_arg_level { no_arg = 0, /* doesn't take an argument */ diff --git a/tools/test/perform/sio_engine.c b/tools/test/perform/sio_engine.c deleted file mode 100644 index 1af2318..0000000 --- a/tools/test/perform/sio_engine.c +++ /dev/null @@ -1,1328 +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. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Author: Christian Chilan, April 2008 - */ - -#include "hdf5.h" - -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> - -#ifdef H5_HAVE_UNISTD_H -#include <sys/types.h> -#include <unistd.h> -#endif - -#ifdef H5_HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -#include "sio_perf.h" - -/* Macro definitions */ - -/* sizes of various items. these sizes won't change during program execution */ -#define ELMT_H5_TYPE H5T_NATIVE_UCHAR - -#define GOTOERROR(errcode) \ - { \ - ret_code = errcode; \ - goto done; \ - } -#define ERRMSG(mesg) \ - { \ - HDfprintf(stderr, "*** Assertion failed (%s) at line %4d in %s\n", mesg, (int)__LINE__, __FILE__); \ - } - -/* verify: if val is false (0), print mesg. */ -#define VRFY(val, mesg) \ - do { \ - if (!val) { \ - ERRMSG(mesg); \ - GOTOERROR(FAIL); \ - } \ - } while (0) - -/* POSIX I/O macros */ -#ifdef H5_HAVE_WIN32_API -/* Can't link against the library, so this test will use the older, non-Unicode - * _open() call on Windows. - */ -#define HDopen(S, F, ...) _open(S, F | _O_BINARY, __VA_ARGS__) -#endif /* H5_HAVE_WIN32_API */ -#define POSIXCREATE(fn) HDopen(fn, O_CREAT | O_TRUNC | O_RDWR, 0600) -#define POSIXOPEN(fn, F) HDopen(fn, F, 0600) -#define POSIXCLOSE(F) HDclose(F) -#define POSIXSEEK(F, L) HDlseek(F, L, SEEK_SET) -#define POSIXWRITE(F, B, S) HDwrite(F, B, S) -#define POSIXREAD(F, B, S) HDread(F, B, S) - -enum { SIO_CREATE = 1, SIO_WRITE = 2, SIO_READ = 4 }; - -/* Global variables */ -static int clean_file_g = -1; /*whether to cleanup temporary test */ -/*files. -1 is not defined; */ -/*0 is no cleanup; 1 is do cleanup */ - -/* the different types of file descriptors we can expect */ -typedef union { - int posixfd; /* POSIX file handle*/ - hid_t h5fd; /* HDF5 file */ -} file_descr; - -/* local functions */ -static char * sio_create_filename(iotype iot, const char *base_name, char *fullname, size_t size, - parameters *param); -static herr_t do_write(results *res, file_descr *fd, parameters *parms, void *buffer); -static herr_t do_read(results *res, file_descr *fd, parameters *parms, void *buffer); -static herr_t dset_write(int local_dim, file_descr *fd, parameters *parms, void *buffer); -static herr_t posix_buffer_write(int local_dim, file_descr *fd, parameters *parms, void *buffer); -static herr_t dset_read(int localrank, file_descr *fd, parameters *parms, void *buffer, const char *buffer2); -static herr_t posix_buffer_read(int local_dim, file_descr *fd, parameters *parms, void *buffer); -static herr_t do_fopen(parameters *param, char *fname, file_descr *fd /*out*/, int flags); -hid_t set_vfd(parameters *param); -static herr_t do_fclose(iotype iot, file_descr *fd); -static void do_cleanupfile(iotype iot, char *fname); - -/* global variables */ -static HDoff_t offset[MAX_DIMS]; /* dataset size in bytes */ -static size_t buf_offset[MAX_DIMS]; /* dataset size in bytes */ -static int order[MAX_DIMS]; /* dimension access order */ -static size_t linear_buf_size; /* linear buffer size */ -static int cont_dim; /* lowest dimension for contiguous POSIX - access */ -static size_t cont_size; /* size of contiguous POSIX access */ -static hid_t fapl; /* file access list */ -static unsigned char *buf_p; /* buffer pointer */ -static const char * multi_letters = "msbrglo"; /* string for multi driver */ - -/* HDF5 global variables */ -static hsize_t h5count[MAX_DIMS]; /*selection count */ -static hssize_t h5offset[MAX_DIMS]; /* Selection offset within dataspace */ -static hid_t h5dset_space_id = H5I_INVALID_HID; /*dataset space ID */ -static hid_t h5mem_space_id = H5I_INVALID_HID; /*memory dataspace ID */ -static hid_t h5ds_id = H5I_INVALID_HID; /*dataset handle */ -static hid_t h5dcpl = H5I_INVALID_HID; /* Dataset creation property list */ -static hid_t h5dxpl = H5I_INVALID_HID; /* Dataset transfer property list */ - -/* - * Function: do_sio - * Purpose: SIO Engine where IO are executed. - * Return: results - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ -void -do_sio(parameters param, results *res) -{ - char * buffer = NULL; /*data buffer pointer */ - size_t buf_size[MAX_DIMS]; /* general buffer size in bytes */ - file_descr fd; /* file handles */ - iotype iot; /* API type */ - char base_name[256]; /* test file base name */ - /* return codes */ - herr_t ret_code = 0; /*return code */ - - char fname[FILENAME_MAX]; /* test file name */ - int i; - /* HDF5 variables */ - herr_t hrc; /*HDF5 return code */ - - /* Sanity check parameters */ - - /* IO type */ - iot = param.io_type; - - switch (iot) { - case POSIXIO: - fd.posixfd = -1; - res->timers = io_time_new(SYS_CLOCK); - break; - case HDF5: - fd.h5fd = -1; - res->timers = io_time_new(SYS_CLOCK); - break; - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); - GOTOERROR(FAIL); - } - - linear_buf_size = 1; - - for (i = 0; i < param.rank; i++) { - buf_size[i] = param.buf_size[i]; - order[i] = param.order[i]; - linear_buf_size *= buf_size[i]; - buf_offset[i] = 0; - offset[i] = 0; - - /* Validate transfer buffer size */ - if (param.buf_size[i] <= 0) { - HDfprintf(stderr, "Transfer buffer size[%d] (%zu) must be > 0\n", i, buf_size[i]); - GOTOERROR(FAIL); - } - - if ((param.dset_size[i] % param.buf_size[i]) != 0) { - HDfprintf(stderr, - "Dataset size[%d] (%" H5_PRINTF_LL_WIDTH "d) must be a multiple of the " - "trasfer buffer size[%d] (%zu)\n", - param.rank, (long long)param.dset_size[i], param.rank, param.buf_size[i]); - GOTOERROR(FAIL); - } - } - - /* Allocate transfer buffer */ - if ((buffer = (char *)malloc(linear_buf_size)) == NULL) { - HDfprintf(stderr, "malloc for transfer buffer size (%zu) failed\n", linear_buf_size); - GOTOERROR(FAIL); - } - - if (sio_debug_level >= 4) - - /* output all of the times for all iterations */ - HDfprintf(output, "Timer details:\n"); - - /* - * Write performance measurement - */ - /* Open file for write */ - - HDstrcpy(base_name, "#sio_tmp"); - sio_create_filename(iot, base_name, fname, sizeof(fname), ¶m); - - if (sio_debug_level > 0) - HDfprintf(output, "data filename=%s\n", fname); - - io_time_set(res->timers, HDF5_GROSS_WRITE_FIXED_DIMS, TSTART); - hrc = do_fopen(¶m, fname, &fd, SIO_CREATE | SIO_WRITE); - VRFY((hrc == SUCCESS), "do_fopen failed"); - - io_time_set(res->timers, HDF5_FINE_WRITE_FIXED_DIMS, TSTART); - hrc = do_write(res, &fd, ¶m, buffer); - io_time_set(res->timers, HDF5_FINE_WRITE_FIXED_DIMS, TSTOP); - VRFY((hrc == SUCCESS), "do_write failed"); - - /* Close file for write */ - hrc = do_fclose(iot, &fd); - io_time_set(res->timers, HDF5_GROSS_WRITE_FIXED_DIMS, TSTOP); - VRFY((hrc == SUCCESS), "do_fclose failed"); - - if (!param.h5_write_only) { - /* - * Read performance measurement - */ - - /* Open file for read */ - io_time_set(res->timers, HDF5_GROSS_READ_FIXED_DIMS, TSTART); - hrc = do_fopen(¶m, fname, &fd, SIO_READ); - VRFY((hrc == SUCCESS), "do_fopen failed"); - - io_time_set(res->timers, HDF5_FINE_READ_FIXED_DIMS, TSTART); - hrc = do_read(res, &fd, ¶m, buffer); - io_time_set(res->timers, HDF5_FINE_READ_FIXED_DIMS, TSTOP); - VRFY((hrc == SUCCESS), "do_read failed"); - - /* Close file for read */ - hrc = do_fclose(iot, &fd); - - io_time_set(res->timers, HDF5_GROSS_READ_FIXED_DIMS, TSTOP); - VRFY((hrc == SUCCESS), "do_fclose failed"); - } - - do_cleanupfile(iot, fname); - -done: - /* clean up */ - /* release HDF5 objects */ - - /* close any opened files */ - /* no remove(fname) because that should have happened normally. */ - switch (iot) { - case POSIXIO: - if (fd.posixfd != -1) - hrc = do_fclose(iot, &fd); - break; - case HDF5: - if (fd.h5fd != -1) - hrc = do_fclose(iot, &fd); - break; - default: - /* unknown request */ - HDassert(0 && "Unknown IO type"); - break; - } - - /* release generic resources */ - if (buffer) - free(buffer); - - res->ret_code = ret_code; -} - -/* - * Function: sio_create_filename - * Purpose: Create a new filename to write to. Determine the correct - * suffix to append to the filename by the type of I/O we're - * doing. Also, place in the /tmp/{$USER,$LOGIN} directory if - * USER or LOGIN are specified in the environment. - * Return: Pointer to filename or NULL - * Programmer: Bill Wendling, 21. November 2001 - * Modifications: Support for file drivers. Christian Chilan, April, 2008 - */ -static char * -sio_create_filename(iotype iot, const char *base_name, char *fullname, size_t size, parameters *param) -{ - const char *prefix, *suffix = ""; - char * ptr, last = '\0'; - size_t i, j; - vfdtype vfd; - vfd = param->vfd; - - if (!base_name || !fullname || size < 1) - return NULL; - - memset(fullname, 0, size); - - switch (iot) { - case POSIXIO: - suffix = ".posix"; - break; - case HDF5: - suffix = ".h5"; - if (vfd == family) - suffix = "%05d.h5"; - else if (vfd == multi) - suffix = NULL; - break; - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); - HDassert(0 && "Unknown IO type"); - break; - } - - /* First use the environment variable and then try the constant */ - prefix = HDgetenv("HDF5_PREFIX"); - -#ifdef HDF5_PREFIX - if (!prefix) - prefix = HDF5_PREFIX; -#endif /* HDF5_PREFIX */ - - /* Prepend the prefix value to the base name */ - if (prefix && *prefix) { - /* If the prefix specifies the HDF5_PREFIX directory, then - * default to using the "/tmp/$USER" or "/tmp/$LOGIN" - * directory instead. */ - register char *user, *login, *subdir; - - user = HDgetenv("USER"); - login = HDgetenv("LOGIN"); - subdir = (user ? user : login); - - if (subdir) { - for (i = 0; i < size - 1 && prefix[i]; i++) - fullname[i] = prefix[i]; - - fullname[i++] = '/'; - - for (j = 0; i < size && subdir[j]; i++, j++) - fullname[i] = subdir[j]; - } - else { - /* We didn't append the prefix yet */ - HDstrncpy(fullname, prefix, size); - fullname[size - 1] = '\0'; - } - - if ((HDstrlen(fullname) + HDstrlen(base_name) + 1) < size) { - /* Append the base_name with a slash first. Multiple slashes are - * handled below. */ - h5_stat_t buf; - - if (HDstat(fullname, &buf) < 0) - /* The directory doesn't exist just yet */ - if (HDmkdir(fullname, 0755) < 0 && errno != EEXIST) { - /* We couldn't make the "/tmp/${USER,LOGIN}" subdirectory. - * Default to PREFIX's original prefix value. */ - HDstrcpy(fullname, prefix); - } - - HDstrcat(fullname, "/"); - HDstrcat(fullname, base_name); - } - else { - /* Buffer is too small */ - return NULL; - } - } - else if (strlen(base_name) >= size) { - /* Buffer is too small */ - return NULL; - } - else { - HDstrcpy(fullname, base_name); - } - - /* Append a suffix */ - if (suffix) { - if (HDstrlen(fullname) + HDstrlen(suffix) >= size) - return NULL; - - HDstrcat(fullname, suffix); - } - - /* Remove any double slashes in the filename */ - for (ptr = fullname, i = j = 0; ptr && (i < size); i++, ptr++) { - if (*ptr != '/' || last != '/') - fullname[j++] = *ptr; - - last = *ptr; - } - - return fullname; -} - -/* - * Function: do_write - * Purpose: Write the required amount of data to the file. - * Return: SUCCESS or FAIL - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ -static herr_t -do_write(results *res, file_descr *fd, parameters *parms, void *buffer) -{ - int ret_code = SUCCESS; - char dname[64]; - int i; - size_t u; - /* HDF5 variables */ - herr_t hrc; /*HDF5 return code */ - hsize_t h5dims[MAX_DIMS]; /*dataset dim sizes */ - hsize_t h5chunk[MAX_DIMS]; /*dataset dim sizes */ - hsize_t h5block[MAX_DIMS]; /*dataspace selection */ - hsize_t h5stride[MAX_DIMS]; /*selection stride */ - hsize_t h5start[MAX_DIMS]; /*selection start */ - hsize_t h5maxdims[MAX_DIMS]; - int rank; /*rank of dataset */ - - /* Prepare buffer for verifying data */ - /* if (parms->verify) - memset(buffer,1,linear_buf_size); */ - - buf_p = (unsigned char *)buffer; - - for (u = 0; u < linear_buf_size; u++) - buf_p[u] = u % 128; - - rank = parms->rank; - - for (i = 0; i < rank; i++) - h5offset[i] = offset[i] = 0; - - /* I/O Access specific setup */ - switch (parms->io_type) { - case POSIXIO: - - /* determine lowest dimension for contiguous POSIX access */ - cont_dim = rank; - - for (i = rank - 1; i >= 0; i--) { - if (parms->buf_size[i] == parms->dset_size[i]) - cont_dim = i; - else - break; - } - - /* determine size of the contiguous POSIX access */ - cont_size = (!cont_dim) ? 1 : parms->buf_size[cont_dim - 1]; - for (i = cont_dim; i < rank; i++) - cont_size *= parms->buf_size[i]; - - break; - - case HDF5: /* HDF5 setup */ - - for (i = 0; i < rank; i++) { - h5dims[i] = parms->dset_size[i]; - h5start[i] = 0; - h5stride[i] = 1; - h5block[i] = 1; - h5count[i] = parms->buf_size[i]; - h5chunk[i] = parms->chk_size[i]; - h5maxdims[i] = H5S_UNLIMITED; - } - - if (parms->h5_use_chunks && parms->h5_extendable) { - h5dset_space_id = H5Screate_simple(rank, h5count, h5maxdims); - VRFY((h5dset_space_id >= 0), "H5Screate_simple"); - } - else { - h5dset_space_id = H5Screate_simple(rank, h5dims, NULL); - VRFY((h5dset_space_id >= 0), "H5Screate_simple"); - } - - hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, h5block); - VRFY((hrc >= 0), "H5Sselect_hyperslab"); - - /* Create the memory dataspace that corresponds to the xfer buffer */ - h5mem_space_id = H5Screate_simple(rank, h5count, NULL); - VRFY((h5mem_space_id >= 0), "H5Screate_simple"); - - /* Create the dataset transfer property list */ - h5dxpl = H5Pcreate(H5P_DATASET_XFER); - if (h5dxpl < 0) { - HDfprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - - break; - - default: - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); - GOTOERROR(FAIL); - break; - } /* end switch */ - - /* create dataset */ - switch (parms->io_type) { - case POSIXIO: - break; - - case HDF5: - h5dcpl = H5Pcreate(H5P_DATASET_CREATE); - - if (h5dcpl < 0) { - HDfprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - - if (parms->h5_use_chunks) { - /* Set the chunk size to be the same as the buffer size */ - hrc = H5Pset_chunk(h5dcpl, rank, h5chunk); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Property List Set failed\n"); - GOTOERROR(FAIL); - } /* end if */ - } /* end if */ - - HDsprintf(dname, "Dataset_%ld", (unsigned long)parms->num_bytes); - h5ds_id = - H5Dcreate2(fd->h5fd, dname, ELMT_H5_TYPE, h5dset_space_id, H5P_DEFAULT, h5dcpl, H5P_DEFAULT); - - if (h5ds_id < 0) { - HDfprintf(stderr, "HDF5 Dataset Create failed\n"); - GOTOERROR(FAIL); - } - - hrc = H5Pclose(h5dcpl); - /* verifying the close of the dcpl */ - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Property List Close failed\n"); - GOTOERROR(FAIL); - } - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); - GOTOERROR(FAIL); - break; - } - - /* Start "raw data" write timer */ - io_time_set(res->timers, HDF5_RAW_WRITE_FIXED_DIMS, TSTART); - - /* Perform write */ - hrc = dset_write(rank - 1, fd, parms, buffer); - - if (hrc < 0) { - HDfprintf(stderr, "Error in dataset write\n"); - GOTOERROR(FAIL); - } - - /* Stop "raw data" write timer */ - io_time_set(res->timers, HDF5_RAW_WRITE_FIXED_DIMS, TSTOP); - - /* Calculate write time */ - - /* Close dataset. Only HDF5 needs to do an explicit close. */ - if (parms->io_type == HDF5) { - hrc = H5Dclose(h5ds_id); - - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Close failed\n"); - GOTOERROR(FAIL); - } - - h5ds_id = H5I_INVALID_HID; - } /* end if */ - -done: - - /* release HDF5 objects */ - if (h5dset_space_id != -1) { - hrc = H5Sclose(h5dset_space_id); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Space Close failed\n"); - ret_code = FAIL; - } - else { - h5dset_space_id = H5I_INVALID_HID; - } - } - - if (h5mem_space_id != -1) { - hrc = H5Sclose(h5mem_space_id); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Memory Space Close failed\n"); - ret_code = FAIL; - } - else { - h5mem_space_id = H5I_INVALID_HID; - } - } - - if (h5dxpl != -1) { - hrc = H5Pclose(h5dxpl); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Transfer Property List Close failed\n"); - ret_code = FAIL; - } - else { - h5dxpl = H5I_INVALID_HID; - } - } - - return ret_code; -} - -/* - * Function: dset_write - * Purpose: Write buffer into the dataset. - * Return: SUCCESS or FAIL - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ -static herr_t -dset_write(int local_dim, file_descr *fd, parameters *parms, void *buffer) -{ - int cur_dim = order[local_dim] - 1; - int ret_code = SUCCESS; - int k; - hsize_t dims[MAX_DIMS], maxdims[MAX_DIMS]; - hsize_t i; - int j; - herr_t hrc; - - /* iterates according to the dimensions in order array */ - for (i = 0; i < parms->dset_size[cur_dim]; i += parms->buf_size[cur_dim]) { - - h5offset[cur_dim] = (hssize_t)i; - offset[cur_dim] = (HDoff_t)i; - - if (local_dim > 0) { - - dset_write(local_dim - 1, fd, parms, buffer); - } - else { - - switch (parms->io_type) { - - case POSIXIO: - /* initialize POSIX offset in the buffer */ - for (j = 0; j < parms->rank; j++) - buf_offset[j] = 0; - buf_p = (unsigned char *)buffer; - /* write POSIX buffer */ - posix_buffer_write(0, fd, parms, buffer); - break; - - case HDF5: - /* if dimensions are extendable, extend them as needed during access */ - if (parms->h5_use_chunks && parms->h5_extendable) { - - hrc = H5Sget_simple_extent_dims(h5dset_space_id, dims, maxdims); - VRFY((hrc >= 0), "H5Sget_simple_extent_dims"); - - for (k = 0; k < parms->rank; k++) { - - HDassert(h5offset[k] >= 0); - if (dims[k] <= (hsize_t)h5offset[k]) { - dims[k] = dims[k] + h5count[k]; - hrc = H5Sset_extent_simple(h5dset_space_id, parms->rank, dims, maxdims); - VRFY((hrc >= 0), "H5Sset_extent_simple"); - hrc = H5Dset_extent(h5ds_id, dims); - VRFY((hrc >= 0), "H5Dextend"); - } - } - } - /* applies offset */ - hrc = H5Soffset_simple(h5dset_space_id, h5offset); - VRFY((hrc >= 0), "H5Soffset_simple"); - - /* Write the buffer out */ - hrc = H5Sget_simple_extent_dims(h5dset_space_id, dims, maxdims); - hrc = H5Dwrite(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); - VRFY((hrc >= 0), "H5Dwrite"); - - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); - HDassert(0 && "Unknown IO type"); - break; - } /* switch (parms->io_type) */ - } - } -done: - return ret_code; -} - -/* - * Function: posix_buffer_write - * Purpose: Write buffer into the POSIX file considering contiguity. - * Return: SUCCESS or FAIL - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ - -static herr_t -posix_buffer_write(int local_dim, file_descr *fd, parameters *parms, void *buffer) -{ - int ret_code = SUCCESS; - - /* if dimension is not contiguous, call recursively */ - if (local_dim < parms->rank - 1 && local_dim != cont_dim) { - size_t u; - - for (u = 0; u < parms->buf_size[local_dim]; u++) { - buf_offset[local_dim] = u; - posix_buffer_write(local_dim + 1, fd, parms, buffer); - - /* if next dimension is cont_dim, it will fill out the buffer - traversing the entire dimension local_dim without the need - of performing iteration */ - if (local_dim + 1 == cont_dim) - break; - } - /* otherwise, perform contiguous POSIX access */ - } - else { - HDoff_t d_offset; - HDoff_t linear_dset_offset = 0; - int i, j, rc; - - buf_offset[local_dim] = 0; - - /* determine offset in the buffer */ - for (i = 0; i < parms->rank; i++) { - d_offset = 1; - - for (j = i + 1; j < parms->rank; j++) - d_offset *= (HDoff_t)parms->dset_size[j]; - - linear_dset_offset += (offset[i] + (HDoff_t)buf_offset[i]) * d_offset; - } - - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, linear_dset_offset) < 0 ? -1 : 0; - VRFY((rc == 0), "POSIXSEEK"); - /* check if all bytes are written */ - rc = ((ssize_t)cont_size == POSIXWRITE(fd->posixfd, buf_p, cont_size)); - VRFY((rc != 0), "POSIXWRITE"); - - /* Advance location in buffer */ - buf_p += cont_size; - } - -done: - return ret_code; -} - -/* - * Function: do_read - * Purpose: Read the required amount of data to the file. - * Return: SUCCESS or FAIL - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ -static herr_t -do_read(results *res, file_descr *fd, parameters *parms, void *buffer) -{ - char * buffer2 = NULL; /* Buffer for data verification */ - int ret_code = SUCCESS; - char dname[64]; - int i; - size_t u; - /* HDF5 variables */ - herr_t hrc; /*HDF5 return code */ - hsize_t h5dims[MAX_DIMS]; /*dataset dim sizes */ - hsize_t h5block[MAX_DIMS]; /*dataspace selection */ - hsize_t h5stride[MAX_DIMS]; /*selection stride */ - hsize_t h5start[MAX_DIMS]; /*selection start */ - int rank; - - /* Allocate data verification buffer */ - if (NULL == (buffer2 = (char *)malloc(linear_buf_size))) { - HDfprintf(stderr, "malloc for data verification buffer size (%zu) failed\n", linear_buf_size); - GOTOERROR(FAIL); - } /* end if */ - - /* Prepare buffer for verifying data */ - for (u = 0; u < linear_buf_size; u++) - buffer2[u] = (char)(u % 128); - - rank = parms->rank; - for (i = 0; i < rank; i++) - h5offset[i] = offset[i] = 0; - - /* I/O Access specific setup */ - switch (parms->io_type) { - case POSIXIO: - cont_dim = rank; - - for (i = rank - 1; i >= 0; i--) { - if (parms->buf_size[i] == parms->dset_size[i]) - cont_dim = i; - else - break; - } - cont_size = (!cont_dim) ? 1 : parms->buf_size[cont_dim - 1]; - for (i = cont_dim; i < rank; i++) - cont_size *= parms->buf_size[i]; - - break; - - case HDF5: /* HDF5 setup */ - for (i = 0; i < rank; i++) { - h5dims[i] = parms->dset_size[i]; - h5start[i] = 0; - h5stride[i] = 1; - h5block[i] = 1; - h5count[i] = parms->buf_size[i]; - } - - h5dset_space_id = H5Screate_simple(rank, h5dims, NULL); - VRFY((h5dset_space_id >= 0), "H5Screate_simple"); - - hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, h5block); - VRFY((hrc >= 0), "H5Sselect_hyperslab"); - - /* Create the memory dataspace that corresponds to the xfer buffer */ - h5mem_space_id = H5Screate_simple(rank, h5count, NULL); - VRFY((h5mem_space_id >= 0), "H5Screate_simple"); - - /* Create the dataset transfer property list */ - h5dxpl = H5Pcreate(H5P_DATASET_XFER); - if (h5dxpl < 0) { - HDfprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); - GOTOERROR(FAIL); - break; - } /* end switch */ - - /* create dataset */ - switch (parms->io_type) { - case POSIXIO: - break; - - case HDF5: - HDsprintf(dname, "Dataset_%ld", (long)parms->num_bytes); - h5ds_id = H5Dopen2(fd->h5fd, dname, H5P_DEFAULT); - if (h5ds_id < 0) { - HDfprintf(stderr, "HDF5 Dataset open failed\n"); - GOTOERROR(FAIL); - } - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); - GOTOERROR(FAIL); - break; - } /* end switch */ - - /* Start "raw data" read timer */ - io_time_set(res->timers, HDF5_RAW_READ_FIXED_DIMS, TSTART); - hrc = dset_read(rank - 1, fd, parms, buffer, buffer2); - - if (hrc < 0) { - HDfprintf(stderr, "Error in dataset read\n"); - GOTOERROR(FAIL); - } - - /* Stop "raw data" read timer */ - io_time_set(res->timers, HDF5_RAW_READ_FIXED_DIMS, TSTOP); - - /* Calculate read time */ - - /* Close dataset. Only HDF5 needs to do an explicit close. */ - if (parms->io_type == HDF5) { - hrc = H5Dclose(h5ds_id); - - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Close failed\n"); - GOTOERROR(FAIL); - } - - h5ds_id = H5I_INVALID_HID; - } /* end if */ - -done: - - /* release HDF5 objects */ - if (h5dset_space_id != -1) { - hrc = H5Sclose(h5dset_space_id); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Space Close failed\n"); - ret_code = FAIL; - } - else { - h5dset_space_id = H5I_INVALID_HID; - } - } - - if (h5mem_space_id != -1) { - hrc = H5Sclose(h5mem_space_id); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Memory Space Close failed\n"); - ret_code = FAIL; - } - else { - h5mem_space_id = H5I_INVALID_HID; - } - } - - if (h5dxpl != -1) { - hrc = H5Pclose(h5dxpl); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Transfer Property List Close failed\n"); - ret_code = FAIL; - } - else { - h5dxpl = H5I_INVALID_HID; - } - } - - /* release generic resources */ - if (buffer2) - free(buffer2); - - return ret_code; -} - -/* - * Function: dset_read - * Purpose: Read buffer into the dataset. - * Return: SUCCESS or FAIL - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ - -static herr_t -dset_read(int local_dim, file_descr *fd, parameters *parms, void *buffer, const char *buffer2) -{ - int cur_dim = order[local_dim] - 1; - hsize_t i; - int j; - herr_t hrc; - int ret_code = SUCCESS; - - /* iterate on the current dimension */ - for (i = 0; i < parms->dset_size[cur_dim]; i += parms->buf_size[cur_dim]) { - - h5offset[cur_dim] = (hssize_t)i; - offset[cur_dim] = (HDoff_t)i; - - /* if traverse in order array is incomplete, recurse */ - if (local_dim > 0) { - - ret_code = dset_read(local_dim - 1, fd, parms, buffer, buffer2); - - /* otherwise, write buffer into dataset */ - } - else { - - switch (parms->io_type) { - - case POSIXIO: - for (j = 0; j < parms->rank; j++) { - buf_offset[j] = 0; - } - buf_p = (unsigned char *)buffer; - posix_buffer_read(0, fd, parms, buffer); - break; - - case HDF5: - hrc = H5Soffset_simple(h5dset_space_id, h5offset); - VRFY((hrc >= 0), "H5Soffset_simple"); - /* Read the buffer out */ - hrc = H5Dread(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); - VRFY((hrc >= 0), "H5Dread"); - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); - HDassert(0 && "Unknown IO type"); - break; - } /* switch (parms->io_type) */ - } - } -done: - return ret_code; -} - -/* - * Function: posix_buffer_read - * Purpose: Read buffer into the POSIX file considering contiguity. - * Return: SUCCESS or FAIL - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ - -static herr_t -posix_buffer_read(int local_dim, file_descr *fd, parameters *parms, void *buffer) -{ - int ret_code = SUCCESS; - - /* if local dimension is not contiguous, recurse */ - if (local_dim < parms->rank - 1 && local_dim != cont_dim) { - size_t u; - - for (u = 0; u < parms->buf_size[local_dim]; u++) { - buf_offset[local_dim] = u; - ret_code = posix_buffer_read(local_dim + 1, fd, parms, buffer); - if (local_dim + 1 == cont_dim) - break; - } - /* otherwise, perform contiguous POSIX access */ - } - else { - HDoff_t d_offset; - HDoff_t linear_dset_offset = 0; - int i, j, rc; - - buf_offset[local_dim] = 0; - /* determine offset in buffer */ - for (i = 0; i < parms->rank; i++) { - d_offset = 1; - - for (j = i + 1; j < parms->rank; j++) - d_offset *= (HDoff_t)parms->dset_size[j]; - - linear_dset_offset += (offset[i] + (HDoff_t)buf_offset[i]) * d_offset; - } - - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, linear_dset_offset) < 0 ? -1 : 0; - VRFY((rc == 0), "POSIXSEEK"); - /* check if all bytes are read */ - rc = ((ssize_t)cont_size == POSIXREAD(fd->posixfd, buf_p, cont_size)); - VRFY((rc != 0), "POSIXREAD"); - - /* Advance location in buffer */ - buf_p += cont_size; - } -done: - return ret_code; -} - -/* - * Function: do_fopen - * Purpose: Open the specified file. - * Return: SUCCESS or FAIL - * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 - * Modifications: Support for file drivers, Christian Chilan, April, 2008 - */ -static herr_t -do_fopen(parameters *param, char *fname, file_descr *fd /*out*/, int flags) -{ - int ret_code = SUCCESS; - hid_t fcpl; - - switch (param->io_type) { - case POSIXIO: - if (flags & (SIO_CREATE | SIO_WRITE)) - fd->posixfd = POSIXCREATE(fname); - else - fd->posixfd = POSIXOPEN(fname, O_RDONLY); - - if (fd->posixfd < 0) { - HDfprintf(stderr, "POSIX File Open failed(%s)\n", fname); - GOTOERROR(FAIL); - } - - break; - - case HDF5: - - fapl = set_vfd(param); - - if (fapl < 0) { - HDfprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - - fcpl = H5Pcreate(H5P_FILE_CREATE); - if (param->page_size) { - H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, 0, (hsize_t)1); - H5Pset_file_space_page_size(fcpl, param->page_size); - if (param->page_buffer_size) - H5Pset_page_buffer_size(fapl, param->page_buffer_size, 0, 0); - } - - /* create the parallel file */ - if (flags & (SIO_CREATE | SIO_WRITE)) { - fd->h5fd = H5Fcreate(fname, H5F_ACC_TRUNC, fcpl, fapl); - } - else { - fd->h5fd = H5Fopen(fname, H5F_ACC_RDONLY, fapl); - } - - if (fd->h5fd < 0) { - HDfprintf(stderr, "HDF5 File Create failed(%s)\n", fname); - GOTOERROR(FAIL); - } - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)param->io_type); - GOTOERROR(FAIL); - break; - } - -done: - return ret_code; -} - -/* - * Function: set_vfd - * Purpose: Sets file driver. - * Return: SUCCESS or FAIL - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ - -hid_t -set_vfd(parameters *param) -{ - hid_t my_fapl = H5I_INVALID_HID; - vfdtype vfd; - - vfd = param->vfd; - - if ((my_fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) - return -1; - - if (vfd == sec2) { - /* Unix read() and write() system calls */ - if (H5Pset_fapl_sec2(my_fapl) < 0) - return -1; - } - else if (vfd == stdio) { - /* Standard C fread() and fwrite() system calls */ - if (H5Pset_fapl_stdio(my_fapl) < 0) - return -1; - } - else if (vfd == core) { - /* In-core temporary file with 1MB increment */ - if (H5Pset_fapl_core(my_fapl, (size_t)1024 * 1024, TRUE) < 0) - return -1; - } - else if (vfd == split) { - /* Split meta data and raw data each using default driver */ - if (H5Pset_fapl_split(my_fapl, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT) < 0) - return -1; - } - else if (vfd == multi) { - /* Multi-file driver, general case of the split driver */ - H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; - hid_t memb_fapl[H5FD_MEM_NTYPES]; - const char *memb_name[H5FD_MEM_NTYPES]; - char sv[H5FD_MEM_NTYPES][1024]; - haddr_t memb_addr[H5FD_MEM_NTYPES]; - H5FD_mem_t mt; - - HDmemset(memb_map, 0, sizeof memb_map); - HDmemset(memb_fapl, 0, sizeof memb_fapl); - HDmemset(memb_name, 0, sizeof memb_name); - HDmemset(memb_addr, 0, sizeof memb_addr); - - HDassert(HDstrlen(multi_letters) == H5FD_MEM_NTYPES); - for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt++) { - memb_fapl[mt] = H5P_DEFAULT; - HDsprintf(sv[mt], "%%s-%c.h5", multi_letters[mt]); - memb_name[mt] = sv[mt]; - memb_addr[mt] = (haddr_t)MAX(mt - 1, 0) * (HADDR_MAX / 10); - } - - if (H5Pset_fapl_multi(my_fapl, memb_map, memb_fapl, memb_name, memb_addr, FALSE) < 0) { - return -1; - } - } - else if (vfd == family) { - hsize_t fam_size = 1 * 1024 * 1024; /*100 MB*/ - - /* Family of files, each 1MB and using the default driver */ - /* if ((val=HDstrtok(NULL, " \t\n\r"))) - fam_size = (hsize_t)(HDstrtod(val, NULL) * 1024*1024); */ - if (H5Pset_fapl_family(my_fapl, fam_size, H5P_DEFAULT) < 0) - return -1; - } - else if (vfd == direct) { -#ifdef H5_HAVE_DIRECT - /* Linux direct read() and write() system calls. Set memory boundary, file block size, - * and copy buffer size to the default values. */ - if (H5Pset_fapl_direct(my_fapl, 1024, 4096, 8 * 4096) < 0) - return -1; -#endif - } - else { - /* Unknown driver */ - return -1; - } - - return my_fapl; -} - -/* - * Function: do_fclose - * Purpose: Close the specified file descriptor. - * Return: SUCCESS or FAIL - * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 - * Modifications: - */ -static herr_t -do_fclose(iotype iot, file_descr *fd /*out*/) -{ - herr_t ret_code = SUCCESS, hrc; - int rc = 0; - - switch (iot) { - case POSIXIO: - rc = POSIXCLOSE(fd->posixfd); - - if (rc != 0) { - HDfprintf(stderr, "POSIX File Close failed\n"); - GOTOERROR(FAIL); - } - - fd->posixfd = -1; - break; - - case HDF5: - hrc = H5Fclose(fd->h5fd); - - if (hrc < 0) { - HDfprintf(stderr, "HDF5 File Close failed\n"); - GOTOERROR(FAIL); - } - - fd->h5fd = -1; - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); - GOTOERROR(FAIL); - break; - } - -done: - return ret_code; -} - -/* - * Function: do_cleanupfile - * Purpose: Cleanup temporary file unless HDF5_NOCLEANUP is set. - * Return: void - * Programmer: Albert Cheng 2001/12/12 - * Modifications: Support for file drivers. Christian Chilan, April, 2008 - */ -static void -do_cleanupfile(iotype iot, char *filename) -{ - char temp[2048]; - int j; - hid_t driver; - - if (clean_file_g == -1) - clean_file_g = (HDgetenv("HDF5_NOCLEANUP") == NULL) ? 1 : 0; - - if (clean_file_g) { - - switch (iot) { - case POSIXIO: - HDremove(filename); - break; - - case HDF5: - driver = H5Pget_driver(fapl); - - if (driver == H5FD_FAMILY) { - for (j = 0; /*void*/; j++) { - HDsnprintf(temp, sizeof temp, filename, j); - - if (HDaccess(temp, F_OK) < 0) - break; - - HDremove(temp); - } - } - else if (driver == H5FD_CORE) { - hbool_t backing; /* Whether the core file has backing store */ - - H5Pget_fapl_core(fapl, NULL, &backing); - - /* If the file was stored to disk with bacing store, remove it */ - if (backing) - HDremove(filename); - } - else if (driver == H5FD_MULTI) { - H5FD_mem_t mt; - assert(HDstrlen(multi_letters) == H5FD_MEM_NTYPES); - - for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt++) { - HDsnprintf(temp, sizeof temp, "%s-%c.h5", filename, multi_letters[mt]); - HDremove(temp); /*don't care if it fails*/ - } - } - else { - HDremove(filename); - } - H5Pclose(fapl); - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); - HDassert(0 && "Unknown IO type"); - break; - } - } -} diff --git a/tools/test/perform/sio_perf.c b/tools/test/perform/sio_perf.c deleted file mode 100644 index 51a7825..0000000 --- a/tools/test/perform/sio_perf.c +++ /dev/null @@ -1,1437 +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. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Serial HDF5 Performance Testing Code - * -------------------------------------- - * - * Portable code to test performance on the different platforms we support. - * This is what the report should look like: - * - * nprocs = Max#Procs - * IO API = POSIXIO - * # Files = 1, # of dsets = 1000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * # Files = 1, # of dsets = 3000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * - * . . . - * - * - * IO API = HDF5 - * # Files = 1, # of dsets = 1000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * # Files = 1, # of dsets = 3000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * - * . . . - * - * - * . . . - * - */ - -/* system header files */ -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> - -#include "hdf5.h" - -/* our header files */ -#include "sio_perf.h" - -/* useful macros */ -#define TAB_SPACE 4 - -#define ONE_KB 1024 -#define ONE_MB (ONE_KB * ONE_KB) -#define ONE_GB (ONE_MB * ONE_KB) - -#define SIO_POSIX 0x1 -#define SIO_HDF5 0x4 - -/* report 0.0 in case t is zero too */ -#define MB_PER_SEC(bytes, t) (H5_DBL_ABS_EQUAL(t, 0.0) ? 0.0 : ((((double)bytes) / (double)ONE_MB) / (t))) - -#ifndef TRUE -#define TRUE 1 -#endif /* TRUE */ -#ifndef FALSE -#define FALSE (!TRUE) -#endif /* FALSE */ - -/* global variables */ -FILE *output; /* output file */ -int sio_debug_level = 0; /* The debug level: - * 0 - Off - * 1 - Minimal - * 2 - Some more - * 3 - Maximal - * 4 - Maximal & then some - */ - -/* local variables */ -static const char *progname = "h5perf_serial"; - -/* - * Command-line options: The user can specify short or long-named - * parameters. The long-named ones can be partially spelled. When - * adding more, make sure that they don't clash with each other. - */ - -/* - * It seems that only the options that accept additional information - * such as dataset size (-e) require the colon next to it. - */ -static const char * s_opts = "a:A:B:c:Cd:D:e:F:ghi:Imno:p:P:r:stT:v:wx:X:"; -static struct h5_long_options l_opts[] = {{"align", require_arg, 'a'}, - {"alig", require_arg, 'a'}, - {"ali", require_arg, 'a'}, - {"al", require_arg, 'a'}, - {"api", require_arg, 'A'}, - {"ap", require_arg, 'A'}, -#if 0 - /* a sighting of the elusive binary option */ - { "binary", no_arg, 'b' }, - { "binar", no_arg, 'b' }, - { "bina", no_arg, 'b' }, - { "bin", no_arg, 'b' }, - { "bi", no_arg, 'b' }, -#endif /* 0 */ - {"block-size", require_arg, 'B'}, - {"block-siz", require_arg, 'B'}, - {"block-si", require_arg, 'B'}, - {"block-s", require_arg, 'B'}, - {"block-", require_arg, 'B'}, - {"block", require_arg, 'B'}, - {"bloc", require_arg, 'B'}, - {"blo", require_arg, 'B'}, - {"bl", require_arg, 'B'}, - {"chunk", no_arg, 'c'}, - {"chun", no_arg, 'c'}, - {"chu", no_arg, 'c'}, - {"ch", no_arg, 'c'}, - {"collective", no_arg, 'C'}, - {"collectiv", no_arg, 'C'}, - {"collecti", no_arg, 'C'}, - {"collect", no_arg, 'C'}, - {"collec", no_arg, 'C'}, - {"colle", no_arg, 'C'}, - {"coll", no_arg, 'C'}, - {"col", no_arg, 'C'}, - {"co", no_arg, 'C'}, - {"debug", require_arg, 'D'}, - {"debu", require_arg, 'D'}, - {"deb", require_arg, 'D'}, - {"de", require_arg, 'D'}, - {"file-driver", require_arg, 'v'}, - {"file-drive", require_arg, 'v'}, - {"file-driv", require_arg, 'v'}, - {"file-dri", require_arg, 'v'}, - {"file-dr", require_arg, 'v'}, - {"file-d", require_arg, 'v'}, - {"file-", require_arg, 'v'}, - {"file", require_arg, 'v'}, - {"fil", require_arg, 'v'}, - {"fi", require_arg, 'v'}, - {"geometry", no_arg, 'g'}, - {"geometr", no_arg, 'g'}, - {"geomet", no_arg, 'g'}, - {"geome", no_arg, 'g'}, - {"geom", no_arg, 'g'}, - {"geo", no_arg, 'g'}, - {"ge", no_arg, 'g'}, - {"help", no_arg, 'h'}, - {"hel", no_arg, 'h'}, - {"he", no_arg, 'h'}, - {"interleaved", require_arg, 'I'}, - {"interleave", require_arg, 'I'}, - {"interleav", require_arg, 'I'}, - {"interlea", require_arg, 'I'}, - {"interle", require_arg, 'I'}, - {"interl", require_arg, 'I'}, - {"inter", require_arg, 'I'}, - {"inte", require_arg, 'I'}, - {"int", require_arg, 'I'}, - {"in", require_arg, 'I'}, - {"max-num-processes", require_arg, 'P'}, - {"max-num-processe", require_arg, 'P'}, - {"max-num-process", require_arg, 'P'}, - {"max-num-proces", require_arg, 'P'}, - {"max-num-proce", require_arg, 'P'}, - {"max-num-proc", require_arg, 'P'}, - {"max-num-pro", require_arg, 'P'}, - {"max-num-pr", require_arg, 'P'}, - {"max-num-p", require_arg, 'P'}, - {"min-num-processes", require_arg, 'p'}, - {"min-num-processe", require_arg, 'p'}, - {"min-num-process", require_arg, 'p'}, - {"min-num-proces", require_arg, 'p'}, - {"min-num-proce", require_arg, 'p'}, - {"min-num-proc", require_arg, 'p'}, - {"min-num-pro", require_arg, 'p'}, - {"min-num-pr", require_arg, 'p'}, - {"min-num-p", require_arg, 'p'}, - {"max-xfer-size", require_arg, 'X'}, - {"max-xfer-siz", require_arg, 'X'}, - {"max-xfer-si", require_arg, 'X'}, - {"max-xfer-s", require_arg, 'X'}, - {"max-xfer", require_arg, 'X'}, - {"max-xfe", require_arg, 'X'}, - {"max-xf", require_arg, 'X'}, - {"max-x", require_arg, 'X'}, - {"min-xfer-size", require_arg, 'x'}, - {"min-xfer-siz", require_arg, 'x'}, - {"min-xfer-si", require_arg, 'x'}, - {"min-xfer-s", require_arg, 'x'}, - {"min-xfer", require_arg, 'x'}, - {"min-xfe", require_arg, 'x'}, - {"min-xf", require_arg, 'x'}, - {"min-x", require_arg, 'x'}, - {"num-bytes", require_arg, 'e'}, - {"num-byte", require_arg, 'e'}, - {"num-byt", require_arg, 'e'}, - {"num-by", require_arg, 'e'}, - {"num-b", require_arg, 'e'}, - {"num-dsets", require_arg, 'd'}, - {"num-dset", require_arg, 'd'}, - {"num-dse", require_arg, 'd'}, - {"num-ds", require_arg, 'd'}, - {"num-d", require_arg, 'd'}, - {"num-files", require_arg, 'F'}, - {"num-file", require_arg, 'F'}, - {"num-fil", require_arg, 'F'}, - {"num-fi", require_arg, 'F'}, - {"num-f", require_arg, 'F'}, - {"num-iterations", require_arg, 'i'}, - {"num-iteration", require_arg, 'i'}, - {"num-iteratio", require_arg, 'i'}, - {"num-iterati", require_arg, 'i'}, - {"num-iterat", require_arg, 'i'}, - {"num-itera", require_arg, 'i'}, - {"num-iter", require_arg, 'i'}, - {"num-ite", require_arg, 'i'}, - {"num-it", require_arg, 'i'}, - {"num-i", require_arg, 'i'}, - {"order", require_arg, 'r'}, - {"orde", require_arg, 'r'}, - {"ord", require_arg, 'r'}, - {"or", require_arg, 'r'}, - {"output", require_arg, 'o'}, - {"outpu", require_arg, 'o'}, - {"outp", require_arg, 'o'}, - {"out", require_arg, 'o'}, - {"ou", require_arg, 'o'}, - {"extendable", no_arg, 't'}, - {"extendabl", no_arg, 't'}, - {"extendab", no_arg, 't'}, - {"extenda", no_arg, 't'}, - {"extend", no_arg, 't'}, - {"exten", no_arg, 't'}, - {"exte", no_arg, 't'}, - {"ext", no_arg, 't'}, - {"ex", no_arg, 't'}, - {"threshold", require_arg, 'T'}, - {"threshol", require_arg, 'T'}, - {"thresho", require_arg, 'T'}, - {"thresh", require_arg, 'T'}, - {"thres", require_arg, 'T'}, - {"thre", require_arg, 'T'}, - {"thr", require_arg, 'T'}, - {"th", require_arg, 'T'}, - {"write-only", require_arg, 'w'}, - {"write-onl", require_arg, 'w'}, - {"write-on", require_arg, 'w'}, - {"write-o", require_arg, 'w'}, - {"write", require_arg, 'w'}, - {"writ", require_arg, 'w'}, - {"wri", require_arg, 'w'}, - {"wr", require_arg, 'w'}, - {NULL, 0, '\0'}}; - -struct options { - long io_types; /* bitmask of which I/O types to test */ - const char *output_file; /* file to print report to */ - long num_dsets; /* number of datasets */ - long num_files; /* number of files */ - off_t num_bpp; /* number of bytes per proc per dset */ - int num_iters; /* number of iterations */ - hsize_t dset_size[MAX_DIMS]; /* Dataset size */ - size_t buf_size[MAX_DIMS]; /* Buffer size */ - size_t chk_size[MAX_DIMS]; /* Chunk size */ - int order[MAX_DIMS]; /* Dimension access order */ - int dset_rank; /* Rank */ - int buf_rank; /* Rank */ - int order_rank; /* Rank */ - int chk_rank; /* Rank */ - int print_times; /* print times as well as throughputs */ - int print_raw; /* print raw data throughput info */ - hsize_t h5_alignment; /* alignment in HDF5 file */ - hsize_t h5_threshold; /* threshold for alignment in HDF5 file */ - int h5_use_chunks; /* Make HDF5 dataset chunked */ - int h5_write_only; /* Perform the write tests only */ - int h5_extendable; /* Perform the write tests only */ - int verify; /* Verify data correctness */ - vfdtype vfd; /* File driver */ - size_t page_buffer_size; - size_t page_size; -}; - -typedef struct { - double min; - double max; - double sum; - int num; -} minmax; - -/* local functions */ -static hsize_t parse_size_directive(const char *size); -static struct options *parse_command_line(int argc, const char *argv[]); -static void run_test_loop(struct options *options); -static int run_test(iotype iot, parameters parms, struct options *opts); -static void output_all_info(minmax *mm, int count, int indent_level); -static void get_minmax(minmax *mm, double val); -static void accumulate_minmax_stuff(const minmax *mm, int count, minmax *total_mm); -static void output_results(const struct options *options, const char *name, minmax *table, int table_size, - off_t data_size); -static void output_report(const char *fmt, ...); -static void print_indent(register int indent); -static void usage(const char *prog); -static void report_parameters(struct options *opts); - -/* - * Function: main - * Purpose: Start things up. - * Return: EXIT_SUCCESS or EXIT_FAILURE - * Programmer: Bill Wendling, 30. October 2001 - * Modifications: - */ -int -main(int argc, const char *argv[]) -{ - int exit_value = EXIT_SUCCESS; - struct options *opts = NULL; - -#ifndef STANDALONE - /* Initialize h5tools lib */ - h5tools_init(); -#endif - - output = stdout; - - opts = parse_command_line(argc, argv); - - if (!opts) { - exit_value = EXIT_FAILURE; - goto finish; - } - - if (opts->output_file) { - if ((output = HDfopen(opts->output_file, "w")) == NULL) { - HDfprintf(stderr, "%s: cannot open output file\n", progname); - HDperror(opts->output_file); - goto finish; - } - } - - report_parameters(opts); - - run_test_loop(opts); - -finish: - HDfree(opts); - return exit_value; -} - -/* - * Function: run_test_loop - * Purpose: Run the I/O tests. Write the results to OUTPUT. - * - * - The slowest changing part of the test is the number of - * processors to use. For each loop iteration, we divide that - * number by 2 and rerun the test. - * - * - The second slowest is what type of IO API to perform. We have - * three choices: POSIXIO, and HDF5. - * - * - Then we change the size of the buffer. This information is - * inferred from the number of datasets to create and the number - * of integers to put into each dataset. The backend code figures - * this out. - * - * Return: Nothing - * Programmer: Bill Wendling, 30. October 2001 - * Modifications: - * Added multidimensional testing (Christian Chilan, April, 2008) - */ -static void -run_test_loop(struct options *opts) -{ - parameters parms; - int i; - size_t buf_bytes; - - /* load options into parameter structure */ - parms.num_files = opts->num_files; - parms.num_dsets = opts->num_dsets; - parms.num_iters = opts->num_iters; - parms.rank = opts->dset_rank; - parms.h5_align = opts->h5_alignment; - parms.h5_thresh = opts->h5_threshold; - parms.h5_use_chunks = opts->h5_use_chunks; - parms.h5_extendable = opts->h5_extendable; - parms.h5_write_only = opts->h5_write_only; - parms.verify = opts->verify; - parms.vfd = opts->vfd; - parms.page_buffer_size = opts->page_buffer_size; - parms.page_size = opts->page_size; - - /* load multidimensional options */ - parms.num_bytes = 1; - buf_bytes = 1; - for (i = 0; i < parms.rank; i++) { - parms.buf_size[i] = opts->buf_size[i]; - parms.dset_size[i] = opts->dset_size[i]; - parms.chk_size[i] = opts->chk_size[i]; - parms.order[i] = opts->order[i]; - parms.num_bytes *= opts->dset_size[i]; - buf_bytes *= opts->buf_size[i]; - } - - /* print size information */ - output_report("Transfer Buffer Size (bytes): %d\n", buf_bytes); - output_report("File Size(MB): %.2f\n", ((double)parms.num_bytes) / ONE_MB); - - print_indent(0); - if (opts->io_types & SIO_POSIX) - run_test(POSIXIO, parms, opts); - - print_indent(0); - if (opts->io_types & SIO_HDF5) - run_test(HDF5, parms, opts); -} - -/* - * Function: run_test - * Purpose: Inner loop call to actually run the I/O test. - * Return: Nothing - * Programmer: Bill Wendling, 18. December 2001 - * Modifications: - */ -static int -run_test(iotype iot, parameters parms, struct options *opts) -{ - results res; - register int i, ret_value = SUCCESS; - off_t raw_size; - minmax * write_sys_mm_table = NULL; - minmax * write_mm_table = NULL; - minmax * write_gross_mm_table = NULL; - minmax * write_raw_mm_table = NULL; - minmax * read_sys_mm_table = NULL; - minmax * read_mm_table = NULL; - minmax * read_gross_mm_table = NULL; - minmax * read_raw_mm_table = NULL; - minmax write_sys_mm = {0.0F, 0.0F, 0.0F, 0}; - minmax write_mm = {0.0F, 0.0F, 0.0F, 0}; - minmax write_gross_mm = {0.0F, 0.0F, 0.0F, 0}; - minmax write_raw_mm = {0.0F, 0.0F, 0.0F, 0}; - minmax read_sys_mm = {0.0F, 0.0F, 0.0F, 0}; - minmax read_mm = {0.0F, 0.0F, 0.0F, 0}; - minmax read_gross_mm = {0.0F, 0.0F, 0.0F, 0}; - minmax read_raw_mm = {0.0F, 0.0F, 0.0F, 0}; - - raw_size = (off_t)parms.num_bytes; - parms.io_type = iot; - print_indent(2); - output_report("IO API = "); - - switch (iot) { - case POSIXIO: - output_report("POSIX\n"); - break; - case HDF5: - output_report("HDF5\n"); - break; - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); - HDassert(0 && "Unknown IO tpe"); - break; - } - - /* allocate space for tables minmax and that it is sufficient */ - /* to initialize all elements to zeros by calloc. */ - write_sys_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); - write_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); - write_gross_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); - write_raw_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); - - if (!parms.h5_write_only) { - read_sys_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); - read_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); - read_gross_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); - read_raw_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); - } - - /* Do IO iteration times, collecting statistics each time */ - for (i = 0; i < parms.num_iters; ++i) { - double t; - - do_sio(parms, &res); - - /* gather all of the "sys write" times */ - t = io_time_get(res.timers, HDF5_MPI_WRITE); - get_minmax(&write_sys_mm, t); - - write_sys_mm_table[i] = write_sys_mm; - - /* gather all of the "write" times */ - t = io_time_get(res.timers, HDF5_FINE_WRITE_FIXED_DIMS); - get_minmax(&write_mm, t); - - write_mm_table[i] = write_mm; - - /* gather all of the "write" times from open to close */ - t = io_time_get(res.timers, HDF5_GROSS_WRITE_FIXED_DIMS); - get_minmax(&write_gross_mm, t); - - write_gross_mm_table[i] = write_gross_mm; - - /* gather all of the raw "write" times */ - t = io_time_get(res.timers, HDF5_RAW_WRITE_FIXED_DIMS); - get_minmax(&write_raw_mm, t); - - write_raw_mm_table[i] = write_raw_mm; - - if (!parms.h5_write_only) { - /* gather all of the "mpi read" times */ - t = io_time_get(res.timers, HDF5_MPI_READ); - get_minmax(&read_sys_mm, t); - - read_sys_mm_table[i] = read_sys_mm; - - /* gather all of the "read" times */ - t = io_time_get(res.timers, HDF5_FINE_READ_FIXED_DIMS); - get_minmax(&read_mm, t); - - read_mm_table[i] = read_mm; - - /* gather all of the "read" times from open to close */ - t = io_time_get(res.timers, HDF5_GROSS_READ_FIXED_DIMS); - get_minmax(&read_gross_mm, t); - - read_gross_mm_table[i] = read_gross_mm; - - /* gather all of the raw "read" times */ - t = io_time_get(res.timers, HDF5_RAW_READ_FIXED_DIMS); - get_minmax(&read_raw_mm, t); - - read_raw_mm_table[i] = read_gross_mm; - } - io_time_destroy(res.timers); - } - - /* - * Show various statistics - */ - /* Write statistics */ - /* Print the raw data throughput if desired */ - if (opts->print_raw) { - /* accumulate and output the max, min, and average "raw write" times */ - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Raw Data Write details:\n"); - output_all_info(write_raw_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Raw Data Write", write_raw_mm_table, parms.num_iters, raw_size); - } /* end if */ - - /* show sys write statics */ -#if 0 - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("MPI Write details:\n"); - output_all_info(write_sys_mm_table, parms.num_iters, 4); - } -#endif - /* We don't currently output the MPI write results */ - - /* accumulate and output the max, min, and average "write" times */ - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Write details:\n"); - output_all_info(write_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Write", write_mm_table, parms.num_iters, raw_size); - - /* accumulate and output the max, min, and average "gross write" times */ - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Write Open-Close details:\n"); - output_all_info(write_gross_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Write Open-Close", write_gross_mm_table, parms.num_iters, raw_size); - - if (!parms.h5_write_only) { - /* Read statistics */ - /* Print the raw data throughput if desired */ - if (opts->print_raw) { - /* accumulate and output the max, min, and average "raw read" times */ - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Raw Data Read details:\n"); - output_all_info(read_raw_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Raw Data Read", read_raw_mm_table, parms.num_iters, raw_size); - } /* end if */ - - /* show mpi read statics */ -#if 0 - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("MPI Read details:\n"); - output_all_info(read_sys_mm_table, parms.num_iters, 4); - } -#endif - /* We don't currently output the MPI read results */ - - /* accumulate and output the max, min, and average "read" times */ - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Read details:\n"); - output_all_info(read_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Read", read_mm_table, parms.num_iters, raw_size); - - /* accumulate and output the max, min, and average "gross read" times */ - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Read Open-Close details:\n"); - output_all_info(read_gross_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Read Open-Close", read_gross_mm_table, parms.num_iters, raw_size); - } - - /* clean up our mess */ - HDfree(write_sys_mm_table); - HDfree(write_mm_table); - HDfree(write_gross_mm_table); - HDfree(write_raw_mm_table); - - if (!parms.h5_write_only) { - HDfree(read_sys_mm_table); - HDfree(read_mm_table); - HDfree(read_gross_mm_table); - HDfree(read_raw_mm_table); - } - - return ret_value; -} - -/* - * Function: output_all_info - * Purpose: - * Return: Nothing - * Programmer: Bill Wendling, 29. January 2002 - * Modifications: - */ -static void -output_all_info(minmax *mm, int count, int indent_level) -{ - int i; - - for (i = 0; i < count; ++i) { - print_indent(indent_level); - output_report("Iteration %d:\n", i + 1); - print_indent(indent_level + 1); - output_report("Minimum Time: %.2fs\n", mm[i].min); - print_indent(indent_level + 1); - output_report("Maximum Time: %.2fs\n", mm[i].max); - } -} - -/* - * Function: get_minmax - * Purpose: Gather all the min, max and total of val. - * Return: Nothing - * Programmer: Bill Wendling, 21. December 2001 - * Modifications: - * Use MPI_Allreduce to do it. -akc, 2002/01/11 - */ - -static void -get_minmax(minmax *mm, double val) -{ - mm->max = val; - mm->min = val; - mm->sum = val; -} - -/* - * Function: accumulate_minmax_stuff - * Purpose: Accumulate the minimum, maximum, and average of the times - * across all processes. - * Return: TOTAL_MM - the total of all of these. - * Programmer: Bill Wendling, 21. December 2001 - * Modifications: - * Changed to use seconds instead of MB/s - QAK, 5/9/02 - */ -static void -accumulate_minmax_stuff(const minmax *mm, int count, minmax *total_mm) -{ - int i; - - total_mm->sum = 0.0F; - total_mm->max = -DBL_MAX; - total_mm->min = DBL_MAX; - total_mm->num = count; - - for (i = 0; i < count; ++i) { - double m = mm[i].max; - - total_mm->sum += m; - - if (m < total_mm->min) - total_mm->min = m; - - if (m > total_mm->max) - total_mm->max = m; - } -} - -/* - * Function: output_results - * Purpose: Print information about the time & bandwidth for a given - * minmax & # of iterations. - * Return: Nothing - * Programmer: Quincey Koziol, 9. May 2002 - * Modifications: - */ -static void -output_results(const struct options *opts, const char *name, minmax *table, int table_size, off_t data_size) -{ - minmax total_mm; - - accumulate_minmax_stuff(table, table_size, &total_mm); - - print_indent(3); - output_report("%s (%d iteration(s)):\n", name, table_size); - - /* Note: The maximum throughput uses the minimum amount of time & vice versa */ - - print_indent(4); - output_report("Maximum Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.min)); - if (opts->print_times) - output_report(" (%7.3f s)\n", total_mm.min); - else - output_report("\n"); - - print_indent(4); - output_report("Average Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.sum / total_mm.num)); - if (opts->print_times) - output_report(" (%7.3f s)\n", (total_mm.sum / total_mm.num)); - else - output_report("\n"); - - print_indent(4); - output_report("Minimum Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.max)); - if (opts->print_times) - output_report(" (%7.3f s)\n", total_mm.max); - else - output_report("\n"); -} - -/* - * Function: output_report - * Purpose: Print a line of the report. Only do so if I'm the 0 process. - * Return: Nothing - * Programmer: Bill Wendling, 19. December 2001 - * Modifications: - */ -static void -output_report(const char *fmt, ...) -{ - va_list ap; - - HDva_start(ap, fmt); - HDvfprintf(output, fmt, ap); - HDva_end(ap); -} - -/* - * Function: print_indent - * Purpose: Print spaces to indent a new line of text for pretty printing - * things. - * Return: Nothing - * Programmer: Bill Wendling, 29. October 2001 - * Modifications: - */ -static void -print_indent(register int indent) -{ - indent *= TAB_SPACE; - - for (; indent > 0; --indent) - HDfputc(' ', output); -} - -static void -recover_size_and_print(long long val, const char *end) -{ - if (val >= ONE_KB && (val % ONE_KB) == 0) { - if (val >= ONE_MB && (val % ONE_MB) == 0) { - if (val >= ONE_GB && (val % ONE_GB) == 0) - HDfprintf(output, - "%" H5_PRINTF_LL_WIDTH "d" - "GB%s", - val / ONE_GB, end); - else - HDfprintf(output, - "%" H5_PRINTF_LL_WIDTH "d" - "MB%s", - val / ONE_MB, end); - } - else { - HDfprintf(output, - "%" H5_PRINTF_LL_WIDTH "d" - "KB%s", - val / ONE_KB, end); - } - } - else { - HDfprintf(output, - "%" H5_PRINTF_LL_WIDTH "d" - "%s", - val, end); - } -} - -static void -print_io_api(long io_types) -{ - if (io_types & SIO_POSIX) - HDfprintf(output, "posix "); - if (io_types & SIO_HDF5) - HDfprintf(output, "hdf5 "); - HDfprintf(output, "\n"); -} - -static void -report_parameters(struct options *opts) -{ - int i, rank; - rank = opts->dset_rank; - - print_version("HDF5 Library"); /* print library version */ - HDfprintf(output, "==== Parameters ====\n"); - - HDfprintf(output, "IO API="); - print_io_api(opts->io_types); - - HDfprintf(output, "Number of iterations=%d\n", opts->num_iters); - - HDfprintf(output, "Dataset size="); - - for (i = 0; i < rank; i++) - recover_size_and_print((long long)opts->dset_size[i], " "); - HDfprintf(output, "\n"); - - HDfprintf(output, "Transfer buffer size="); - for (i = 0; i < rank; i++) - recover_size_and_print((long long)opts->buf_size[i], " "); - HDfprintf(output, "\n"); - - if (opts->page_size) { - HDfprintf(output, "Page Aggregation Enabled. Page size = %zu\n", opts->page_size); - if (opts->page_buffer_size) - HDfprintf(output, "Page Buffering Enabled. Page Buffer size = %zu\n", opts->page_buffer_size); - else - HDfprintf(output, "Page Buffering Disabled\n"); - } - else - HDfprintf(output, "Page Aggregation Disabled\n"); - - HDfprintf(output, "Dimension access order="); - for (i = 0; i < rank; i++) - recover_size_and_print((long long)opts->order[i], " "); - HDfprintf(output, "\n"); - - if (opts->io_types & SIO_HDF5) { - - HDfprintf(output, "HDF5 data storage method="); - - if (opts->h5_use_chunks) { - - HDfprintf(output, "Chunked\n"); - HDfprintf(output, "HDF5 chunk size="); - for (i = 0; i < rank; i++) - recover_size_and_print((long long)opts->chk_size[i], " "); - HDfprintf(output, "\n"); - - HDfprintf(output, "HDF5 dataset dimensions="); - if (opts->h5_extendable) { - HDfprintf(output, "Extendable\n"); - } - else { - HDfprintf(output, "Fixed\n"); - } - } - else { - HDfprintf(output, "Contiguous\n"); - } - - HDfprintf(output, "HDF5 file driver="); - if (opts->vfd == sec2) { - HDfprintf(output, "sec2\n"); - } - else if (opts->vfd == stdio) { - HDfprintf(output, "stdio\n"); - } - else if (opts->vfd == core) { - HDfprintf(output, "core\n"); - } - else if (opts->vfd == split) { - HDfprintf(output, "split\n"); - } - else if (opts->vfd == multi) { - HDfprintf(output, "multi\n"); - } - else if (opts->vfd == family) { - HDfprintf(output, "family\n"); - } - else if (opts->vfd == direct) { - HDfprintf(output, "direct\n"); - } - } - - { - char *prefix = HDgetenv("HDF5_PREFIX"); - - HDfprintf(output, "Env HDF5_PREFIX=%s\n", (prefix ? prefix : "not set")); - } - - HDfprintf(output, "==== End of Parameters ====\n"); - HDfprintf(output, "\n"); -} - -/* - * Function: parse_command_line - * Purpose: Parse the command line options and return a STRUCT OPTIONS - * structure which will need to be freed by the calling function. - * Return: Pointer to an OPTIONS structure - * Programmer: Bill Wendling, 31. October 2001 - * Modifications: - * Added multidimensional testing (Christian Chilan, April, 2008) - */ -static struct options * -parse_command_line(int argc, const char *argv[]) -{ - int opt; - struct options *cl_opts; - int i, default_rank, actual_rank, ranks[4]; - - cl_opts = (struct options *)HDmalloc(sizeof(struct options)); - - cl_opts->page_buffer_size = 0; - cl_opts->page_size = 0; - - cl_opts->output_file = NULL; - cl_opts->io_types = 0; /* will set default after parsing options */ - cl_opts->num_iters = 1; - - default_rank = 2; - - cl_opts->dset_rank = 0; - cl_opts->buf_rank = 0; - cl_opts->chk_rank = 0; - cl_opts->order_rank = 0; - - for (i = 0; i < MAX_DIMS; i++) { - cl_opts->buf_size[i] = (size_t)((i + 1) * 10); - cl_opts->dset_size[i] = (hsize_t)((i + 1) * 100); - cl_opts->chk_size[i] = (size_t)((i + 1) * 10); - cl_opts->order[i] = i + 1; - } - - cl_opts->vfd = sec2; - - cl_opts->print_times = FALSE; /* Printing times is off by default */ - cl_opts->print_raw = FALSE; /* Printing raw data throughput is off by default */ - cl_opts->h5_alignment = 1; /* No alignment for HDF5 objects by default */ - cl_opts->h5_threshold = 1; /* No threshold for aligning HDF5 objects by default */ - cl_opts->h5_use_chunks = FALSE; /* Don't chunk the HDF5 dataset by default */ - cl_opts->h5_write_only = FALSE; /* Do both read and write by default */ - cl_opts->h5_extendable = FALSE; /* Use extendable dataset */ - cl_opts->verify = FALSE; /* No Verify data correctness by default */ - - while ((opt = H5_get_option(argc, argv, s_opts, l_opts)) != EOF) { - switch ((char)opt) { - case 'a': - cl_opts->h5_alignment = parse_size_directive(H5_optarg); - break; - case 'G': - cl_opts->page_size = parse_size_directive(H5_optarg); - break; - case 'b': - cl_opts->page_buffer_size = parse_size_directive(H5_optarg); - break; - case 'A': { - const char *end = H5_optarg; - while (end && *end != '\0') { - char buf[10]; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (HDisalnum(*end) && i < 10) - buf[i++] = *end; - - if (!HDstrcasecmp(buf, "hdf5")) { - cl_opts->io_types |= SIO_HDF5; - } - else if (!HDstrcasecmp(buf, "posix")) { - cl_opts->io_types |= SIO_POSIX; - } - else { - HDfprintf(stderr, "sio_perf: invalid --api option %s\n", buf); - HDexit(EXIT_FAILURE); - } - - if (*end == '\0') - break; - - end++; - } - } - - break; -#if 0 - case 'b': - /* the future "binary" option */ - break; -#endif /* 0 */ - case 'c': - /* Turn on chunked HDF5 dataset creation */ - cl_opts->h5_use_chunks = 1; - { - const char *end = H5_optarg; - int j = 0; - - while (end && *end != '\0') { - char buf[10]; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (HDisalnum(*end) && i < 10) - buf[i++] = *end; - - cl_opts->chk_size[j] = parse_size_directive(buf); - - j++; - - if (*end == '\0') - break; - - end++; - } - cl_opts->chk_rank = j; - } - - break; - - case 'D': { - const char *end = H5_optarg; - - while (end && *end != '\0') { - char buf[10]; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (HDisalnum(*end) && i < 10) - buf[i++] = *end; - - if (HDstrlen(buf) > 1 || HDisdigit(buf[0])) { - size_t j; - - for (j = 0; j < 10 && buf[j] != '\0'; ++j) - if (!HDisdigit(buf[j])) { - HDfprintf(stderr, "sio_perf: invalid --debug option %s\n", buf); - HDexit(EXIT_FAILURE); - } - - sio_debug_level = atoi(buf); - - if (sio_debug_level > 4) - sio_debug_level = 4; - else if (sio_debug_level < 0) - sio_debug_level = 0; - } - else { - switch (*buf) { - case 'r': - /* Turn on raw data throughput info */ - cl_opts->print_raw = TRUE; - break; - case 't': - /* Turn on time printing */ - cl_opts->print_times = TRUE; - break; - case 'v': - /* Turn on verify data correctness*/ - cl_opts->verify = TRUE; - break; - default: - HDfprintf(stderr, "sio_perf: invalid --debug option %s\n", buf); - HDexit(EXIT_FAILURE); - } - } - - if (*end == '\0') - break; - - end++; - } - } - - break; - case 'e': { - const char *end = H5_optarg; - int j = 0; - - while (end && *end != '\0') { - char buf[10]; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (HDisalnum(*end) && i < 10) - buf[i++] = *end; - - cl_opts->dset_size[j] = parse_size_directive(buf); - - j++; - - if (*end == '\0') - break; - - end++; - } - cl_opts->dset_rank = j; - } - - break; - - case 'i': - cl_opts->num_iters = HDatoi(H5_optarg); - break; - case 'o': - cl_opts->output_file = H5_optarg; - break; - case 'T': - cl_opts->h5_threshold = parse_size_directive(H5_optarg); - break; - case 'v': - if (!HDstrcasecmp(H5_optarg, "sec2")) { - cl_opts->vfd = sec2; - } - else if (!HDstrcasecmp(H5_optarg, "stdio")) { - cl_opts->vfd = stdio; - } - else if (!HDstrcasecmp(H5_optarg, "core")) { - cl_opts->vfd = core; - } - else if (!HDstrcasecmp(H5_optarg, "split")) { - cl_opts->vfd = split; - } - else if (!HDstrcasecmp(H5_optarg, "multi")) { - cl_opts->vfd = multi; - } - else if (!HDstrcasecmp(H5_optarg, "family")) { - cl_opts->vfd = family; - } - else if (!HDstrcasecmp(H5_optarg, "direct")) { - cl_opts->vfd = direct; - } - else { - HDfprintf(stderr, "sio_perf: invalid --api option %s\n", H5_optarg); - HDexit(EXIT_FAILURE); - } - break; - case 'w': - cl_opts->h5_write_only = TRUE; - break; - case 't': - cl_opts->h5_extendable = TRUE; - break; - case 'x': { - const char *end = H5_optarg; - int j = 0; - - while (end && *end != '\0') { - char buf[10]; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (HDisalnum(*end) && i < 10) - buf[i++] = *end; - - cl_opts->buf_size[j] = parse_size_directive(buf); - - j++; - - if (*end == '\0') - break; - - end++; - } - cl_opts->buf_rank = j; - } - - break; - - case 'r': { - const char *end = H5_optarg; - int j = 0; - - while (end && *end != '\0') { - char buf[10]; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (HDisalnum(*end) && i < 10) - buf[i++] = *end; - - cl_opts->order[j] = (int)parse_size_directive(buf); - - j++; - - if (*end == '\0') - break; - - end++; - } - - cl_opts->order_rank = j; - } - - break; - - case 'h': - case '?': - default: - usage(progname); - HDfree(cl_opts); - return NULL; - } - } - - /* perform rank consistency analysis */ - actual_rank = 0; - - ranks[0] = cl_opts->dset_rank; - ranks[1] = cl_opts->buf_rank; - ranks[2] = cl_opts->order_rank; - ranks[3] = cl_opts->chk_rank; - - for (i = 0; i < 4; i++) { - if (ranks[i] > 0) { - if (!actual_rank) { - actual_rank = ranks[i]; - } - else { - if (actual_rank != ranks[i]) - exit(EXIT_FAILURE); - } - } - } - - if (!actual_rank) - actual_rank = default_rank; - - cl_opts->dset_rank = actual_rank; - cl_opts->buf_rank = actual_rank; - cl_opts->order_rank = actual_rank; - cl_opts->chk_rank = actual_rank; - - for (i = 0; i < actual_rank; i++) { - if (cl_opts->order[i] > actual_rank) { - exit(EXIT_FAILURE); - } - } - - /* set default if none specified yet */ - if (!cl_opts->io_types) - cl_opts->io_types = SIO_HDF5 | SIO_POSIX; /* run all API */ - - /* verify parameters sanity. Adjust if needed. */ - /* cap xfer_size with bytes per process */ - if (cl_opts->num_iters <= 0) - cl_opts->num_iters = 1; - - return cl_opts; -} - -/* - * Function: parse_size_directive - * Purpose: Parse the size directive passed on the commandline. The size - * directive is an integer followed by a size indicator: - * - * K, k - Kilobyte - * M, m - Megabyte - * G, g - Gigabyte - * - * Return: The size as a off_t because this is related to file size. - * If an unknown size indicator is used, then the program will - * exit with EXIT_FAILURE as the return value. - * Programmer: Bill Wendling, 18. December 2001 - * Modifications: - */ - -static hsize_t -parse_size_directive(const char *size) -{ - hsize_t s; - char * endptr; - - s = HDstrtoull(size, &endptr, 10); - - if (endptr && *endptr) { - while (*endptr != '\0' && (*endptr == ' ' || *endptr == '\t')) - ++endptr; - - switch (*endptr) { - case 'K': - case 'k': - s *= ONE_KB; - break; - - case 'M': - case 'm': - s *= ONE_MB; - break; - - case 'G': - case 'g': - s *= ONE_GB; - break; - - default: - HDfprintf(stderr, "Illegal size specifier '%c'\n", *endptr); - HDexit(EXIT_FAILURE); - } - } - - return s; -} - -/* - * Function: usage - * Purpose: Print a usage message and then exit. - * Return: Nothing - * Programmer: Bill Wendling, 31. October 2001 - * Modifications: - */ -static void -usage(const char *prog) -{ - print_version(prog); - HDprintf("usage: %s [OPTIONS]\n", prog); - HDprintf(" OPTIONS\n"); - HDprintf(" -h Print an usage message and exit\n"); - HDprintf(" -A AL Which APIs to test\n"); - HDprintf(" [default: all of them]\n"); - HDprintf(" -c SL Selects chunked storage and defines chunks dimensions\n"); - HDprintf(" and sizes\n"); - HDprintf(" [default: Off]\n"); - HDprintf(" -e SL Dimensions and sizes of dataset\n"); - HDprintf(" [default: 100,200]\n"); - HDprintf(" -i N Number of iterations to perform\n"); - HDprintf(" [default: 1]\n"); - HDprintf(" -r NL Dimension access order (see below for description)\n"); - HDprintf(" [default: 1,2]\n"); - HDprintf(" -t Selects extendable dimensions for HDF5 dataset\n"); - HDprintf(" [default: Off]\n"); - HDprintf(" -v VFD Selects file driver for HDF5 access\n"); - HDprintf(" [default: sec2]\n"); - HDprintf(" -w Perform write tests, not the read tests\n"); - HDprintf(" [default: Off]\n"); - HDprintf(" -x SL Dimensions and sizes of the transfer buffer\n"); - HDprintf(" [default: 10,20]\n"); - HDprintf("\n"); - HDprintf(" N - is an integer > 0.\n"); - HDprintf("\n"); - HDprintf(" S - is a size specifier, an integer > 0 followed by a size indicator:\n"); - HDprintf(" K - Kilobyte (%d)\n", ONE_KB); - HDprintf(" M - Megabyte (%d)\n", ONE_MB); - HDprintf(" G - Gigabyte (%d)\n", ONE_GB); - HDprintf("\n"); - HDprintf(" Example: '37M' is 37 megabytes or %d bytes\n", 37 * ONE_MB); - HDprintf("\n"); - HDprintf(" AL - is an API list. Valid values are:\n"); - HDprintf(" hdf5 - HDF5\n"); - HDprintf(" posix - POSIX\n"); - HDprintf("\n"); - HDprintf(" Example: -A posix,hdf5\n"); - HDprintf("\n"); - HDprintf(" NL - is list of integers (N) separated by commas.\n"); - HDprintf("\n"); - HDprintf(" Example: 1,2,3\n"); - HDprintf("\n"); - HDprintf(" SL - is list of size specifiers (S) separated by commas.\n"); - HDprintf("\n"); - HDprintf(" Example: 2K,2K,3K\n"); - HDprintf("\n"); - HDprintf(" The example defines an object (dataset, tranfer buffer) with three\n"); - HDprintf(" dimensions. Be aware that as the number of dimensions increases, the\n"); - HDprintf(" the total size of the object increases exponentially.\n"); - HDprintf("\n"); - HDprintf(" VFD - is an HDF5 file driver specifier. Valid values are:\n"); - HDprintf(" sec2, stdio, core, split, multi, family, direct\n"); - HDprintf("\n"); - HDprintf(" Dimension access order:\n"); - HDprintf(" Data access starts at the cardinal origin of the dataset using the\n"); - HDprintf(" transfer buffer. The next access occurs on a dataset region next to\n"); - HDprintf(" the previous one. For a multidimensional dataset, there are several\n"); - HDprintf(" directions as to where to proceed. This can be specified in the dimension\n"); - HDprintf(" access order. For example, -r 1,2 states that the tool should traverse\n"); - HDprintf(" dimension 1 first, and then dimension 2.\n"); - HDprintf("\n"); - HDprintf(" Environment variables:\n"); - HDprintf(" HDF5_NOCLEANUP Do not remove data files if set [default remove]\n"); - HDprintf(" HDF5_PREFIX Data file prefix\n"); - HDprintf("\n"); - HDfflush(stdout); -} /* end usage() */ diff --git a/tools/test/perform/sio_perf.h b/tools/test/perform/sio_perf.h deleted file mode 100644 index 6242782..0000000 --- a/tools/test/perform/sio_perf.h +++ /dev/null @@ -1,104 +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. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef SIO_PERF_H -#define SIO_PERF_H - -#ifndef STANDALONE -#include "io_timer.h" -#include "h5test.h" -#include "h5tools.h" -#include "h5tools_utils.h" -#else -#include "io_timer.h" -#include "sio_standalone.h" -#endif - -/* setup the dataset no fill option if this is v1.5 or more */ -#if H5_VERS_MAJOR > 1 || H5_VERS_MINOR > 4 -#define H5_HAVE_NOFILL 1 -#endif - -#define MAX_DIMS 32 - -typedef enum iotype_ { - POSIXIO, - HDF5 - /*NUM_TYPES*/ -} iotype; - -typedef enum vfdtype_ { - sec2, - stdio, - core, - split, - multi, - family, - direct - /*NUM_TYPES*/ -} vfdtype; - -typedef struct parameters_ { - iotype io_type; /* The type of IO test to perform */ - vfdtype vfd; - long num_files; /* Number of files to create */ - long num_dsets; /* Number of datasets to create */ - hsize_t num_bytes; /* Number of bytes in each dset */ - int num_iters; /* Number of times to loop doing the IO */ - int rank; /* Rank of dataset */ - hsize_t dset_size[MAX_DIMS]; /* Dataset size */ - size_t buf_size[MAX_DIMS]; /* Buffer size */ - size_t chk_size[MAX_DIMS]; /* Chunk size */ - int order[MAX_DIMS]; /* Buffer size */ - hsize_t h5_align; /* HDF5 object alignment */ - hsize_t h5_thresh; /* HDF5 object alignment threshold */ - int h5_use_chunks; /* Make HDF5 dataset chunked */ - int h5_extendable; /* Make HDF5 dataset chunked */ - int h5_write_only; /* Perform the write tests only */ - int verify; /* Verify data correctness */ - size_t page_size; - size_t page_buffer_size; -} parameters; - -typedef struct results_ { - herr_t ret_code; - io_time_t *timers; -} results; - -#ifndef SUCCESS -#define SUCCESS 0 -#endif /* !SUCCESS */ - -#ifndef FAIL -#define FAIL -1 -#endif /* !FAIL */ - -extern FILE * output; /* output file */ -extern io_time_t *timer_g; /* timer: global for stub functions */ -extern int sio_debug_level; /* The debug level: - * 0 - Off - * 1 - Minimal - * 2 - Some more - * 3 - Maximal - * 4 - Even More Debugging (timer stuff) - */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -extern void do_sio(parameters param, results *res); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* SIO_PERF_H */ diff --git a/tools/test/perform/sio_standalone.c b/tools/test/perform/sio_standalone.c index 2e793fb..7c22b53 100644 --- a/tools/test/perform/sio_standalone.c +++ b/tools/test/perform/sio_standalone.c @@ -22,11 +22,6 @@ /* global variables */ int nCols = 80; -/* ``get_option'' variables */ -int H5_opterr = 1; /*get_option prints errors if this is on */ -int H5_optind = 1; /*token pointer */ -const char *H5_optarg; /*flag argument (or value) */ - int get_option(int argc, const char **argv, const char *opts, const struct h5_long_options *l_opts) { diff --git a/tools/test/perform/sio_standalone.h b/tools/test/perform/sio_standalone.h index 098b98a..99cca75 100644 --- a/tools/test/perform/sio_standalone.h +++ b/tools/test/perform/sio_standalone.h @@ -456,22 +456,11 @@ extern char * strdup(const char *s); #define TRUE true #endif -/** From h5test.h **/ - -#ifdef H5_HAVE_PARALLEL -extern MPI_Info h5_io_info_g; /* MPI INFO object for IO */ -#endif - -#ifdef H5_HAVE_PARALLEL -int h5_set_info_object(void); -void h5_dump_info_object(MPI_Info info); -#endif - /** From h5tools_utils.h **/ -extern int H5_opterr; /* getoption prints errors if this is on */ -extern int H5_optind; /* token pointer */ -extern const char *H5_optarg; /* flag argument (or value) */ +H5_DLLVAR int H5_opterr; /* getoption prints errors if this is on */ +H5_DLLVAR int H5_optind; /* token pointer */ +H5_DLLVAR const char *H5_optarg; /* flag argument (or value) */ enum h5_arg_level { no_arg = 0, /* doesn't take an argument */ diff --git a/tools/test/perform/zip_perf.c b/tools/test/perform/zip_perf.c index 6231587..d8cd3a1 100644 --- a/tools/test/perform/zip_perf.c +++ b/tools/test/perform/zip_perf.c @@ -35,7 +35,7 @@ #define MICROSECOND 1000000.0 /* report 0.0 in case t is zero too */ -#define MB_PER_SEC(bytes, t) ((fabs(t) < 0.0000000001) ? 0.0 : ((((double)bytes) / (double)ONE_MB) / (t))) +#define MB_PER_SEC(bytes, t) ((fabs(t) < 0.0000000001) ? 0.0 : ((((double)(bytes)) / (double)ONE_MB) / (t))) #ifndef TRUE #define TRUE 1 @@ -67,62 +67,11 @@ static void compress_buffer(Bytef *dest, uLongf *destLen, const Bytef *source, u static const char * s_opts = "hB:b:c:p:rs:0123456789"; static struct h5_long_options l_opts[] = {{"help", no_arg, 'h'}, {"compressability", require_arg, 'c'}, - {"compressabilit", require_arg, 'c'}, - {"compressabili", require_arg, 'c'}, - {"compressabil", require_arg, 'c'}, - {"compressabi", require_arg, 'c'}, - {"compressab", require_arg, 'c'}, - {"compressa", require_arg, 'c'}, - {"compress", require_arg, 'c'}, - {"compres", require_arg, 'c'}, - {"compre", require_arg, 'c'}, - {"compr", require_arg, 'c'}, - {"comp", require_arg, 'c'}, - {"com", require_arg, 'c'}, - {"co", require_arg, 'c'}, {"file-size", require_arg, 's'}, - {"file-siz", require_arg, 's'}, - {"file-si", require_arg, 's'}, - {"file-s", require_arg, 's'}, - {"file", require_arg, 's'}, - {"fil", require_arg, 's'}, - {"fi", require_arg, 's'}, {"max-buffer-size", require_arg, 'B'}, - {"max-buffer-siz", require_arg, 'B'}, - {"max-buffer-si", require_arg, 'B'}, - {"max-buffer-s", require_arg, 'B'}, - {"max-buffer", require_arg, 'B'}, - {"max-buffe", require_arg, 'B'}, - {"max-buff", require_arg, 'B'}, - {"max-buf", require_arg, 'B'}, - {"max-bu", require_arg, 'B'}, - {"max-b", require_arg, 'B'}, - {"max", require_arg, 'B'}, {"min-buffer-size", require_arg, 'b'}, - {"min-buffer-siz", require_arg, 'b'}, - {"min-buffer-si", require_arg, 'b'}, - {"min-buffer-s", require_arg, 'b'}, - {"min-buffer", require_arg, 'b'}, - {"min-buffe", require_arg, 'b'}, - {"min-buff", require_arg, 'b'}, - {"min-buf", require_arg, 'b'}, - {"min-bu", require_arg, 'b'}, - {"min-b", require_arg, 'b'}, - {"min", require_arg, 'b'}, {"prefix", require_arg, 'p'}, - {"prefi", require_arg, 'p'}, - {"pref", require_arg, 'p'}, - {"pre", require_arg, 'p'}, - {"pr", require_arg, 'p'}, {"random-test", no_arg, 'r'}, - {"random-tes", no_arg, 'r'}, - {"random-te", no_arg, 'r'}, - {"random-t", no_arg, 'r'}, - {"random", no_arg, 'r'}, - {"rando", no_arg, 'r'}, - {"rand", no_arg, 'r'}, - {"ran", no_arg, 'r'}, - {"ra", no_arg, 'r'}, {NULL, 0, '\0'}}; /* -- cgit v0.12 From 572201b560b87fb0011dea1d3257fe0351483e8c Mon Sep 17 00:00:00 2001 From: Dana Robinson <43805+derobins@users.noreply.github.com> Date: Mon, 11 Oct 2021 15:20:31 -0700 Subject: VFD SWMR: Added VFD SWMR utils directory as a submodule (#1086) * Added VFD SWMR utils directory as a submodule * Fixed MANIFEST --- .gitmodules | 3 +++ MANIFEST | 1 + utils/vfd_swmr | 1 + 3 files changed, 5 insertions(+) create mode 100644 .gitmodules create mode 160000 utils/vfd_swmr diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..441564c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "utils/vfd_swmr"] + path = utils/vfd_swmr + url = https://github.com/HDFGroup/vfd_swmr_util.git diff --git a/MANIFEST b/MANIFEST index ca1a58c..75a7aca 100644 --- a/MANIFEST +++ b/MANIFEST @@ -20,6 +20,7 @@ ./.gitattributes _DO_NOT_DISTRIBUTE_ ./.gitignore _DO_NOT_DISTRIBUTE_ +./.gitmodules _DO_NOT_DISTRIBUTE_ ./.autom4te.cfg _DO_NOT_DISTRIBUTE_ ./.h5chkright.ini _DO_NOT_DISTRIBUTE_ ./ACKNOWLEDGMENTS diff --git a/utils/vfd_swmr b/utils/vfd_swmr new file mode 160000 index 0000000..b0b2f45 --- /dev/null +++ b/utils/vfd_swmr @@ -0,0 +1 @@ +Subproject commit b0b2f45944e6526eeb67f04ed4f8b825053d2e75 -- cgit v0.12 From 89cde3e0009bf2e97319ba3f36c100c97b6208e1 Mon Sep 17 00:00:00 2001 From: myang6 <myang6@hdfgroup.org> 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 <myang6@hdfgroup.org> 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 <myang6@hdfgroup.org> 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 <myang6@hdfgroup.org> 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 <myang6@hdfgroup.org> 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 <myang6@hdfgroup.org> 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 <myang6@hdfgroup.org> 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 <myang6@hdfgroup.org> 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 <myang6@hdfgroup.org> 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 <myang6@hdfgroup.org> 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 <myang6@hdfgroup.org> 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 <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) + * 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) #endif -/* clang-format on */ #endif /* H5Fpkg_H */ diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index 5119b38..3f24352 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -54,17 +54,38 @@ #define nanosecs_per_second 1000000000 /* nanoseconds per second */ #define nanosecs_per_tenth_sec 100000000 /* nanoseconds per 0.1 second */ +/* Declare an array of string to identify the VFD SMWR Log tags. + * Note this array is used to generate the entry tag by the log reporting macro + * H5F_POST_VFD_SWMR_LOG_ENTRY. + * + * The following is the first version. Developers can add/modify the tags as necessary. + * + * If the entry code is 0, H5Fvfd_swmr_log_tags[0] is used to report the entry tag. + * H5F_POST_VFD_SWMR_LOG_ENTRY(f, 0, log_msg) will put the log_msg attached to + * the entry tag "EOT_PROCESSING_TIME". + * The entry code number is listed in the comment for convenience. + * Currently for the production mode, only the "EOT_PROCESSING_TIME" is present. + */ + /* clang-format off */ -/* 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_PROCESSING_TIME", /* 0 */ + "FILE_OPEN", /* 1 */ + "FILE_CLOSE", /* 2 */ + "EOT_TRIGGER_TIME", /* 3 */ "EOT_META_FILE_INDEX" /* 4 */ }; /* clang-format on */ +/* This string defines the format of the VFD SWMR log file. + * The current maximum length of entry tag string is set to 26. + * One can enlarge or reduce this number as necessary. + * For example, to enlarge the maximum length of entry tag string to 30, + * Just change 26 to 30 in the following line, like + * const char *log_fmt_str="%-30s: %.3lf s: %s\n"; + */ +const char *log_fmt_str="%-26s: %.3lf s: %s\n"; + /********************/ /* Local Prototypes */ /********************/ @@ -329,14 +350,16 @@ 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 */ - H5F_POST_VFD_SWMR_LOG_ENTRY(f, 1, "VFD SWMR File close or flush ends") +#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"); #endif done: + /* Kent: close the VFD SWMR log file if it is turned on */ if (shared->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 <max_code) { \ - H5F_POST_VFD_SWMR_LOG_ENTRY_INTERNAL(fp,entry_type_code,log_info); \ - } \ + 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 +/* 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) - * as necessary. + * as necessary. */ #ifndef NDEBUG #define H5F_POST_VFD_SWMR_LOG_ENTRY(f, c, m) H5F_POST_VFD_SWMR_LOG_ENTRY_INTERNAL(f, c, m) diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index 3f24352..12c8905 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -54,7 +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. +/* 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. * @@ -63,7 +63,7 @@ * 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 * the entry tag "EOT_PROCESSING_TIME". - * The entry code number is listed in the comment for convenience. + * The entry code number is listed in the comment for convenience. * Currently for the production mode, only the "EOT_PROCESSING_TIME" is present. */ @@ -77,14 +77,14 @@ static const char *H5Fvfd_swmr_log_tags[] = { }; /* clang-format on */ -/* This string defines the format of the VFD SWMR log file. - * The current maximum length of entry tag string is set to 26. - * One can enlarge or reduce this number as necessary. +/* This string defines the format of the VFD SWMR log file. + * The current maximum length of entry tag string is set to 26. + * One can enlarge or reduce this number as necessary. * For example, to enlarge the maximum length of entry tag string to 30, - * Just change 26 to 30 in the following line, like - * const char *log_fmt_str="%-30s: %.3lf s: %s\n"; + * Just change 26 to 30 in the following line, like + * const char *log_fmt_str="%-30s: %.3lf s: %s\n"; */ -const char *log_fmt_str="%-26s: %.3lf s: %s\n"; +const char *log_fmt_str = "%-26s: %.3lf s: %s\n"; /********************/ /* Local Prototypes */ @@ -1958,8 +1958,8 @@ done: * * Parameters: * H5F_t *f IN: HDF5 file pointer - * int entry_type_code IN: The entry type code to identify the - * log entry tag. + * 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 @@ -1967,29 +1967,28 @@ done: *------------------------------------------------------------------------- */ -void +void H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log_info) { double temp_time; struct timespec current_time; - char *gettime_error; + char * gettime_error; - /* Obtain the current time. - If failed, write an error message to the log file. + /* 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], + 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 <myang6@hdfgroup.org> 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 <myang6@hdfgroup.org> 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 <myang6@hdfgroup.org> 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 <myang6@hdfgroup.org> 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 <myang6@hdfgroup.org> 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 <myang6@hdfgroup.org> 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 <myang6@hdfgroup.org> 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 <songyulu@hdfgroup.org> 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 <myang6@hdfgroup.org> 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 <myang6@hdfgroup.org> 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 From 97a37aa84913808792418e6814126bdee856288e Mon Sep 17 00:00:00 2001 From: vchoi <vchoi@jelly.ad.hdfgroup.org> Date: Wed, 17 Nov 2021 11:25:20 -0600 Subject: 1) Core changes for adding NFS/updater support as described in the RFC. src/H5Pfapl.c src/H5Fvfd_swmr.c src/H5Fpublic.h src/H5Fpkg.h src/H5Fprivate.h 2) For VFD SWMR testing, add private property for checksum generation of metadata files: src/H5Fint.c src/H5Fvfd_swmr.c src/H5Pfapl.c src/H5Fpkg.h src/H5Fprivate.h 3) Fix the following in H5F_vfd_swmr_init() and H5F_vfd_swmr_close_or_flush(): (a) Allocate metadata file index right after metadata file header. (b) Set tick number to 0 when creating header and index for file open case. (c) Remove tick number increment at file close. src/H5Fvfd_swmr.c src/H5Ftest.c 4) To be consistent with the RFC, change the name for field "chksum" to "checksum" in struct H5FD_vfd_swmr_idx_entry_t: src/H5FDprivate.h src/H5FDtest.c src/H5FDvfd_swmr.c src/H5Ftest.c src/H5PB.c 4) Add tests for NFS/updater test/vfd_swmr.c 5) Modify common routine init_vfd_swmr_config() to accept updater_file_path test/vfd_swmr_common.c test/vfd_swmr_common.h 6) Changes to the tests due to the common routine init_vfd_swmr_config(): test/vfd_swmr_addrem_writer.c test/vfd_swmr_attrdset_writer.c test/vfd_swmr_bigset_writer.c test/vfd_swmr_dsetchks_writer.c test/vfd_swmr_dsetops_writer.c test/vfd_swmr_generator.c test/vfd_swmr_gfail_writer.c test/vfd_swmr_gperf_writer.c test/vfd_swmr_group_writer.c test/vfd_swmr_reader.c test/vfd_swmr_remove_reader.c test/vfd_swmr_remove_writer.c test/vfd_swmr_sparse_reader.c test/vfd_swmr_sparse_writer.c test/vfd_swmr_vlstr_reader.c test/vfd_swmr_vlstr_writer.c test/vfd_swmr_writer.c test/page_buffer.c --- src/H5FDprivate.h | 2 +- src/H5FDtest.c | 2 +- src/H5FDvfd_swmr.c | 4 +- src/H5Fint.c | 8 + src/H5Fpkg.h | 27 +- src/H5Fprivate.h | 249 ++++++- src/H5Fpublic.h | 43 +- src/H5Ftest.c | 26 +- src/H5Fvfd_swmr.c | 604 ++++++++++++++--- src/H5PB.c | 2 +- src/H5Pfapl.c | 62 +- test/page_buffer.c | 2 + test/vfd_swmr.c | 1378 +++++++++++++++++++++++++++++++++------ test/vfd_swmr_addrem_writer.c | 5 +- test/vfd_swmr_attrdset_writer.c | 5 +- test/vfd_swmr_bigset_writer.c | 6 +- test/vfd_swmr_common.c | 13 +- test/vfd_swmr_common.h | 8 +- test/vfd_swmr_dsetchks_writer.c | 5 +- test/vfd_swmr_dsetops_writer.c | 5 +- test/vfd_swmr_generator.c | 5 +- test/vfd_swmr_gfail_writer.c | 5 +- test/vfd_swmr_gperf_writer.c | 5 +- test/vfd_swmr_group_writer.c | 5 +- test/vfd_swmr_reader.c | 5 +- test/vfd_swmr_remove_reader.c | 5 +- test/vfd_swmr_remove_writer.c | 5 +- test/vfd_swmr_sparse_reader.c | 5 +- test/vfd_swmr_sparse_writer.c | 5 +- test/vfd_swmr_vlstr_reader.c | 5 +- test/vfd_swmr_vlstr_writer.c | 5 +- test/vfd_swmr_writer.c | 5 +- test/vfd_swmr_zoo_writer.c | 5 +- 33 files changed, 2147 insertions(+), 374 deletions(-) diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index 0a8850f..7c0dd77 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -168,7 +168,7 @@ typedef struct H5FD_vfd_swmr_idx_entry_t { uint64_t hdf5_page_offset; uint64_t md_file_page_offset; uint32_t length; - uint32_t chksum; + uint32_t checksum; void * entry_ptr; uint64_t tick_of_last_change; hbool_t clean; diff --git a/src/H5FDtest.c b/src/H5FDtest.c index a55d34c..521886f 100644 --- a/src/H5FDtest.c +++ b/src/H5FDtest.c @@ -162,7 +162,7 @@ H5FD__vfd_swmr_reader_md_test(H5FD_t *file, unsigned num_entries, H5FD_vfd_swmr_ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect md_file_page_offset read from metadata file") - if (vfd_index[i].chksum != index[i].chksum) + if (vfd_index[i].checksum != index[i].checksum) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect chksum read from metadata file") } } diff --git a/src/H5FDvfd_swmr.c b/src/H5FDvfd_swmr.c index 568f5d9..73d8df4 100644 --- a/src/H5FDvfd_swmr.c +++ b/src/H5FDvfd_swmr.c @@ -857,7 +857,7 @@ H5FD__vfd_swmr_read(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id * signature. */ if (file->pb_configured && entry->length == init_size && - H5_checksum_metadata(buf, entry->length, 0) != entry->chksum) { + H5_checksum_metadata(buf, entry->length, 0) != entry->checksum) { H5FD_vfd_swmr_md_header tmp_header; if (H5FD__vfd_swmr_header_deserialize(file, &tmp_header) != TRUE) @@ -1331,7 +1331,7 @@ H5FD__vfd_swmr_index_deserialize(const H5FD_vfd_swmr_t *file, H5FD_vfd_swmr_md_i UINT32DECODE(p, md_index->entries[i].hdf5_page_offset); UINT32DECODE(p, md_index->entries[i].md_file_page_offset); UINT32DECODE(p, md_index->entries[i].length); - UINT32DECODE(p, md_index->entries[i].chksum); + UINT32DECODE(p, md_index->entries[i].checksum); } } else diff --git a/src/H5Fint.c b/src/H5Fint.c index c3fc346..8518785 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -1853,6 +1853,7 @@ 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 */ + H5F_generate_md_ck_cb_t cb_info = {NULL}; H5F_t * ret_value = NULL; /* Actual return value */ FUNC_ENTER_NOAPI(NULL) @@ -1876,6 +1877,10 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "file access is writer but VFD SWMR config is reader") if ((flags & H5F_ACC_RDWR) == 0 && vfd_swmr_config_ptr->writer) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "file access is reader but VFD SWMR config is writer") + + /* Retrieve the private property for VFD SWMR testing */ + if (H5P_get(a_plist, H5F_ACS_GENERATE_MD_CK_CB_NAME, &cb_info) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get generate_md_ck_cb info") } /* @@ -2111,6 +2116,9 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) /* Initialization for VFD SWMR writer and reader */ if (1 == shared->nrefs) { + /* Private property for VFD SWMR testing: generate checksum for metadata file */ + if(cb_info.func) + shared->generate_md_ck_cb = cb_info.func; if (H5F_vfd_swmr_init(file, file_create) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "file open fail with initialization for VFD SWMR") } diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 706e41d..31630ef 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -455,13 +455,36 @@ struct H5F_shared_t { uint32_t old_mdf_idx_len; uint32_t old_mdf_idx_entries_used; - /* Metadata file for VFD SWMR writer */ + /* Metadata file and updater file for VFD SWMR writer */ int vfd_swmr_md_fd; /* POSIX: file descriptor for the - * metadata file + * metadata file or -1 if the metadata file + * is not currently open. + * The vfd_swmr_config.generate_updater_files + * is FALSE. */ + /* NFS: + * The vfd_swmr_config.generate_updater_files + * is TRUE and: + * --if vfd_swmr_config.writer is FALSE, + * this field is the file descriptor of the local + * copy of the metadata file, or -1 if the local + * copy is not currently open. + * --if vfd_swmr_config.writer is TRUE, this field + * is not used and is set to -1. + */ + H5F_generate_md_ck_t generate_md_ck_cb; + /* For testing only: + * Invoke the user-defined callback if exists to + * generate checksum for the metadata file + */ + haddr_t vfd_swmr_md_eoa; /* POSIX: eoa for the metadata * file */ + uint64_t updater_seq_num;/* Sequence number of the next updater file to be + * genereated. This field must be initialized to zero, + * and incremented after each updater file is generated. + */ /* Free space manager for the metadata file */ H5FS_t * fs_man_md; /* Free-space manager */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index cef77dc..05ace44 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -647,11 +647,18 @@ uint64_decode(uint8_t **pp) { \ /* int32_t version = */ 0, /* int32_t tick_len = */ 0, \ /* int32_t max_lag = */ 0, /* hbool_t vfd_swmr_writer = */ FALSE, \ + /* hbool_t maintain_metadata_file = */ FALSE, \ + /* hbool_t generate_updater_files = */ FALSE, \ /* hbool_t flush_raw_data = */ FALSE, /* int32_t md_pages_reserved = */ 0, \ - /* int32_t pb_expansion_threshold = */ 0, /* char md_file_path[] = */ "", \ + /* int32_t pb_expansion_threshold = */ 0, \ + /* char md_file_path[] = */ "", \ + /* char updater_file_path[] = */ "", \ /* char log_file_path[] = */ "" \ } +/* For VFD SWMR testing only: private property to generate checksum for metadata file via callback */ +#define H5F_ACS_GENERATE_MD_CK_CB_NAME "generate md ck callback" + /* ======================== File Mount properties ====================*/ #define H5F_MNT_SYM_LOCAL_NAME "local" /* Whether absolute symlinks local to file. */ @@ -784,6 +791,72 @@ uint64_decode(uint8_t **pp) #define H5SM_TABLE_MAGIC "SMTB" /* Shared Message Table */ #define H5SM_LIST_MAGIC "SMLI" /* Shared Message List */ +/* + * VFD SWMR + */ + +/* Updater file header */ +#define H5F_UD_VERSION 0 /* Version of the updater file format */ +#define H5F_UD_HEADER_OFF 0 /* Updater file header offset */ +#define H5F_UD_HEADER_MAGIC "VUDH" /* Updater file header magic */ +#define H5F_SIZEOF_CHKSUM 4 /* Size of checksum */ + +/* Flags in the updater file header */ +#define CREATE_METADATA_FILE_ONLY_FLAG 0x0001 +#define FINAL_UPDATE_FLAG 0x0002 + +/* Size of updater file header */ +#define H5F_UD_HEADER_SIZE \ + (H5_SIZEOF_MAGIC /* Signature */ \ + + 2 /* Version number */ \ + + 2 /* Flags */ \ + + 4 /* Page size */ \ + + 8 /* Sequence number */ \ + + 8 /* Tick number */ \ + + 8 /* Chnage list offset */ \ + + 8 /* Change list length */ \ + + H5F_SIZEOF_CHKSUM /* Updater file header checksum */ \ + ) + +#define H5F_UD_CL_MAGIC "VUCL" /* Updater file change list magic */ + +/* Size of an updater file change list entry */ +#define H5F_UD_CL_ENTRY_SIZE \ + (4 /* Updater file page offset */ \ + + 4 /* Metadata file page offset */ \ + + 4 /* HDF5 file page offset */ \ + + 4 /* Length */ \ + + H5F_SIZEOF_CHKSUM /* Updater file change list entry checksum */ \ + ) + +/* Size of updater file change list */ +#define H5F_UD_CL_SIZE(N) /* N is number of change list entries */ \ + (H5_SIZEOF_MAGIC /* Signature */ \ + + 8 /* Tick num */ \ + + 4 /* Metadata file header updater file page offset */ \ + + 4 /* Metadata file header length */ \ + + 4 /* Metadata file header checksum */ \ + + 4 /* Metadata file index updater file page offset */ \ + + 8 /* Metadata file index metadata file offset */ \ + + 4 /* Metadata file index length */ \ + + 4 /* Metadata file index checksum */ \ + + 4 /* Number of change list entries */ \ + + (N * H5F_UD_CL_ENTRY_SIZE) /* Change list entries */ \ + + H5F_SIZEOF_CHKSUM /* Updater file change list checksum */ \ + ) + +/* + * For VFD SWMR testing only: + */ + +/* Callback routine to generate checksum for metadata file specified by md_path */ +typedef herr_t (*H5F_generate_md_ck_t)(char *md_path, uint64_t updater_seq_num); + +/* Structure for "generate checksum callback" private property */ +typedef struct H5F_generate_md_ck_cb_t { + H5F_generate_md_ck_t func; +} H5F_generate_md_ck_cb_t; + /****************************/ /* Library Private Typedefs */ /****************************/ @@ -854,6 +927,180 @@ typedef enum H5F_prefix_open_t { H5F_PREFIX_EFILE = 2 /* External file prefix */ } H5F_prefix_open_t; +/* + * VFD SWMR + */ + +/*---------------------------------------------------------------------------- + * + * struct H5F_vfd_swmr_updater_cl_entry_t + * + * An array of instances of H5F_vfd_swmr_updater_cl_entry_t of length equal to + * the number of metadata pages and multi-page metadata entries modified in + * the past tick is used ot aseemble the assoicated data in preparation for + * writing an updater file. + * + * Each entry in this array pertains to a given modified metdata page or + * multi-page metadata entry, and contains the following fields: + * + * entry_image_ptr: void pointer to a buffer containing the image of the + * target metadata page or multi-page metadata entry as modified in + * this tick, or NULL if undefined. + * + * entry_image_ud_file_page_offset: Page offset of the entry in the + * updater file, or 0 if undefined. + * + * entry_image_md_file_page_offset: Page offset of the entry in the + * metadata file, or 0 if undefined. + * + * entry_image_h5_file_page_offset: Page offset of the entry in the + * HDF5 file. In this case, a page offset of zero is valid, + * so we havd no easy marker for an invalid value. Instead, + * presume that this field is invalid if the entry_image_md_file_page_offset + * is invalid. + * + * entry_image_len: The size of the metadata page or multi-page metadata + * entry in bytes. + * entry_image_checksum: Checksum of the entry image. + * + *---------------------------------------------------------------------------- + */ +typedef struct H5F_vfd_swmr_updater_cl_entry_t { + void *entry_image_ptr; + uint32_t entry_image_ud_file_page_offset; + uint32_t entry_image_md_file_page_offset; + uint32_t entry_image_h5_file_page_offset; + size_t entry_image_len; + uint32_t entry_image_checksum; +} H5F_vfd_swmr_updater_cl_entry_t; + +/*---------------------------------------------------------------------------- + * + * struct H5F_vfd_swmr_updater_t + * + * Instances of this structure are used to assemble the data required to + * write a metadata file updater file. + * + * Updater file header related fields: + * + * version: Version of the updater file format to be used. At present this + * must be zero. + * + * flags: This field contains any flags to be set in the updater file header. + * Currently defined flags are: + * + * 0x0001 CREATE_METADATA_FILE_ONLY_FLAG + * If set, the auxiliary process should create the metadata file, + * but leave it empty. This flag may only be set if sequence_num + * is zero. + * + * 0x0002 FINAL_UPDATE_FLAG + * If set, the VFD SWMR writer is closing the target file, and this + * updater contains the final set of updates to the metadata file. + * On receipt, the auxiliary process should apply the enclosed + * changes to the metadata file, unlink it, and exit. + * + * sequence_num: This field contains the sequence number of this updater file. + * The sequence number of the first updater file must be zero, and + * this sequence number must be increased by one for each new updater + * file. Note that under some circumstances, the sequence number + * will not match the tick_num. + * + * tick_num: Number of the tick for which this updater file is to be generated. + * This value should match that of the index used to fill our this + * structure. + * + * header_image_ptr: void pointer to the buffer in which the + * updater file header is constructed. + * This field is NULL if the buffer is undefined. + * + * header_image_len: This field contains the length of the updater file + * header in bytes. + * + * change_list_image_ptr: void pointer to a buffer containing the on disk image + * of the updater file change list, or NULL if that buffer does not exist. + * + * change_list_offset: This field contains the offset in bytes of the change + * list in the updater file. This will typically be the offset of + * the first byte in the updater file after the header. + * + * change_list_len: This field contains the size in bytes of the on disk image + * of the change list in the updater file. + * + * Updater File Change List Related Fields: + * + * The updater file change list is a section of the updater file that details the + * locations and lengths of all metadata file entries that must be modified for + * this tick. + * + * md_file_header_image_ptr: void pointer to a buffer containing the on disk image + * of the metadata file header as updated for tick_num. + * + * md_file_header_ud_file_page_offset: This field contains the updater file + * page offset of the metadata file header image. Note that we do + * not store the metadata file page offset of the metadata file header, + * as it is always written to offset 0 in the metadata file. + * + * md_file_header_len: This field contains the size of the metadata file header + * image in bytes. + * + * md_file_index_image: void pointer to a buffer containing the on disk image + * of the metadata file index as updated for tick_num. + * + * md_file_index_md_file_offset: This field contains the offset of the + * metadata file index in the metadata file in bytes. + * + * This value will either be the size of the metadata file header + * (if the metadata file header and index are adjacent), or a page + * aligned value. + * + * md_file_index_ud_file_page_offset: This field contains the page offset of the + * metadata file index in the updater file. + * + * md_file_index_len: This field contains the size of the metadata file index in + * bytes. + * + * num_change_list_entries: This field contains the number of entries in the + * array of H5F_vfd_swmr_updater_cl_ entry_t whose base address + * is stored in the change_list field below. This value is also the + * number of metadata pages and multi-page metadata entries that have + * been modified in the past tick + * + * If this field is zero, there is no change list, and the change_list + * field below is NULL. + * + * change_list: This field contains the base address of a dynamically allocated + * array of H5F_vfd_swmr_updater_cl_entry_t of length num_change_list_entries, + * or NULL if undefined. + * + *---------------------------------------------------------------------------- + */ +typedef struct H5F_vfd_swmr_updater_t { + /* Updater file header related fields */ + uint16_t version; + uint16_t flags; + uint32_t page_size; + uint64_t sequence_number; + uint64_t tick_num; + void *header_image_ptr; + size_t header_image_len; + void *change_list_image_ptr; + uint64_t change_list_offset; + size_t change_list_len; + /* Updater file change list related fields */ + void *md_file_header_image_ptr; + uint32_t md_file_header_image_chksum; + uint32_t md_file_header_ud_file_page_offset; + size_t md_file_header_len; + void *md_file_index_image_ptr; + uint32_t md_file_index_image_chksum; + uint64_t md_file_index_md_file_offset; + uint32_t md_file_index_ud_file_page_offset; + size_t md_file_index_len; + uint32_t num_change_list_entries; + H5F_vfd_swmr_updater_cl_entry_t *change_list; +} H5F_vfd_swmr_updater_t; + /*****************************/ /* Library-private Variables */ /*****************************/ diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h index d241816..5e0473a 100644 --- a/src/H5Fpublic.h +++ b/src/H5Fpublic.h @@ -275,6 +275,31 @@ typedef herr_t (*H5F_flush_cb_t)(hid_t object_id, void *udata); * A boolean flag indicating whether the file opened with this FAPL entry * will be opened R/W. (i.e. as a VFD SWMR writer) * + * maintain_metadata_file + * A boolean flag indicating whether the writer should create and + * maintain the metadata file. Note that this field is only revelant + * if the above writer flag is TRUE. + * If this flag is TRUE, the writer must create and maintain the + * metadata file in the location specified in the md_file_path. + * Observe that at least one of maintain_metadata_file and + * generate_updater_files fields must be TRUE if writer is TRUE. + * + * generate_updater_files + * A boolean flag indicating whether the writer should generate a + * sequence of updater files describing how the metadata file + * should be updated at the end of each tick. + * If the flag is TRUE, all modifications to the metadata file + * (including its creation) are described in an ordered sequence of + * updater files. These files are read in order by auxiliary processes, + * and used to generate local copies of the metadata file as required. + * This mechanism exists to allow VFD SWMR to operate on storage + * systems that do not support POSIX semantics. + * This field is only used by the VFD SWMR writer. VFD SWMR readers + * ignore this field, as they always look to the specified metadata + * file, regardless of whether it is generated and maintained + * directly by the VFD SWMR writer, or by an auxiliary process that + * polls for new updater files, and applies them as they appear. + * * flush_raw_data: * A boolean flag indicating whether raw data should be flushed * as part of the end of tick processing. If set to TRUE, raw @@ -307,11 +332,16 @@ typedef herr_t (*H5F_flush_cb_t)(hid_t object_id, void *udata); * of tick is triggered. * * md_file_path: - * POSIX: this field contains the path of the metadata file. - * NFS: it contains the path and base name of the metadata file - * updater files. - * Object store: it contains the base URL for the objects used - * to store metadata file updater objects. + * If both the writer and maintain_metadata_file fields are TRUE, this + * field contains the path of the metadata file. + * If writer is FALSE, this field contains the path of the (possibly + * local copy of the) metadata file. + * + * updater_file_path: + * If generate_updater_files is TRUE, the contents of this field depends + * on whether the writer field is TRUE. If it is, the field contains + * the path and base name of the metadatea file updater files. + * If writer is FALSE, the field is ignored. * * log_file_path: * This field contains the path to the log file. If defined, this path should @@ -324,10 +354,13 @@ typedef struct H5F_vfd_swmr_config_t { uint32_t tick_len; uint32_t max_lag; hbool_t writer; + hbool_t maintain_metadata_file; + hbool_t generate_updater_files; hbool_t flush_raw_data; uint32_t md_pages_reserved; uint32_t pb_expansion_threshold; char md_file_path[H5F__MAX_VFD_SWMR_FILE_NAME_LEN + 1]; + char updater_file_path[H5F__MAX_VFD_SWMR_FILE_NAME_LEN + 1]; char log_file_path[H5F__MAX_VFD_SWMR_FILE_NAME_LEN + 1]; } H5F_vfd_swmr_config_t; diff --git a/src/H5Ftest.c b/src/H5Ftest.c index b76c579..e9cecc1 100644 --- a/src/H5Ftest.c +++ b/src/H5Ftest.c @@ -344,24 +344,10 @@ H5F__vfd_swmr_writer_create_open_flush_test(hid_t file_id, hbool_t file_create) /* Verify the minimum size for the metadata file */ if (HDstat(f->shared->vfd_swmr_config.md_file_path, &stat_buf) < 0) HGOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to stat the metadata file") - if (stat_buf.st_size < - (HDoff_t)((hsize_t)f->shared->vfd_swmr_config.md_pages_reserved * f->shared->fs_page_size)) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect metadata file size") if (file_create) { /* Creating file */ - uint32_t hdr_magic; - - /* Seek to the beginning of the file */ - if (HDlseek(md_fd, (HDoff_t)H5FD_MD_HEADER_OFF, SEEK_SET) < 0) - HGOTO_ERROR(H5E_FILE, H5E_SEEKERROR, FAIL, "error seeking metadata file") - - /* Try to read the magic for header */ - if (HDread(md_fd, &hdr_magic, H5_SIZEOF_MAGIC) < 0) - HGOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "error reading metadata file") - - /* Verify that there is no header magic in the metadata file */ - if (HDmemcmp(&hdr_magic, H5FD_MD_HEADER_MAGIC, (size_t)H5_SIZEOF_MAGIC) == 0) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "error finding header magic in the metadata file") + if(stat_buf.st_size != 0) + HGOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "metadata file should be empty for file create") } else { /* Opening or flushing the file */ @@ -494,7 +480,7 @@ H5F__vfd_swmr_decode_md_idx(int md_fd, H5FD_vfd_swmr_md_header *md_hdr, H5FD_vfd UINT32DECODE(p, md_idx->entries[i].hdf5_page_offset); UINT32DECODE(p, md_idx->entries[i].md_file_page_offset); UINT32DECODE(p, md_idx->entries[i].length); - UINT32DECODE(p, md_idx->entries[i].chksum); + UINT32DECODE(p, md_idx->entries[i].checksum); } /* end for */ } /* end if */ @@ -546,7 +532,7 @@ H5F__vfd_swmr_verify_md_hdr_and_idx(H5F_t *f, H5FD_vfd_swmr_md_header *md_hdr, H HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect index_length read from metadata file") /* Verify index_offset read from header in the metadata file is the size of md header */ - if (md_hdr->index_offset != f->shared->fs_page_size) + if (md_hdr->index_offset != H5FD_MD_HEADER_SIZE) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect index_offset read from metadata file") /* Verify num_entries read from index in the metadata file is num_entries */ @@ -573,8 +559,8 @@ H5F__vfd_swmr_verify_md_hdr_and_idx(H5F_t *f, H5FD_vfd_swmr_md_header *md_hdr, H HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect md_file_page_offset read from metadata file") - if (md_idx->entries[i].chksum != index[i].chksum) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect chksum read from metadata file") + if (md_idx->entries[i].checksum != index[i].checksum) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect checksum read from metadata file") } } diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index 8da238c..fe07e74 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -25,6 +25,7 @@ /****************/ #include "H5Fmodule.h" /* This source code file is part of the H5F module */ +#define H5FD_FRIEND /*suppress error about including H5FDpkg */ /***********/ /* Headers */ @@ -36,7 +37,7 @@ #include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* File access */ -#include "H5FDprivate.h" /* File drivers */ +#include "H5FDpkg.h" /* File drivers */ #include "H5Gprivate.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ #include "H5Lprivate.h" /* Links */ @@ -97,13 +98,19 @@ const unsigned int log_err_mesg_length = 14; /********************/ static herr_t H5F__vfd_swmr_update_end_of_tick_and_tick_num(H5F_shared_t *, hbool_t); -static herr_t H5F__vfd_swmr_construct_write_md_hdr(H5F_shared_t *, uint32_t); +static herr_t H5F__vfd_swmr_construct_write_md_hdr(H5F_shared_t *, uint32_t, uint8_t *); static herr_t H5F__vfd_swmr_construct_write_md_idx(H5F_shared_t *, uint32_t, - struct H5FD_vfd_swmr_idx_entry_t[]); + struct H5FD_vfd_swmr_idx_entry_t[], uint8_t *); static herr_t H5F__idx_entry_cmp(const void *_entry1, const void *_entry2); static herr_t H5F__vfd_swmr_create_index(H5F_shared_t *); static herr_t H5F__vfd_swmr_writer__wait_a_tick(H5F_t *); +static herr_t H5F__vfd_swmr_construct_ud_hdr(H5F_vfd_swmr_updater_t *updater); +static herr_t H5F__vfd_swmr_construct_ud_cl(H5F_vfd_swmr_updater_t *updater); +static herr_t H5F__generate_updater_file(H5F_t *f, uint32_t num_entries, uint16_t flags, + uint8_t *md_file_hdr_image_ptr, size_t md_file_hdr_image_len, + uint8_t *md_file_index_image_ptr, uint64_t md_file_index_offset, size_t md_file_index_image_len); + /*********************/ /* Package Variables */ /*********************/ @@ -171,9 +178,11 @@ herr_t H5F_vfd_swmr_init(H5F_t *f, hbool_t file_create) { hsize_t md_size; /* Size of the metadata file */ - haddr_t hdr_addr, idx_addr; /* Addresses returned from H5MV_alloc() */ - herr_t ret_value = SUCCEED; /* Return value */ + haddr_t hdr_addr; /* Address returned from H5MV_alloc() */ H5F_shared_t *shared = f->shared; + uint8_t md_idx_image[H5FD_MD_INDEX_SIZE(0)]; /* Buffer for metadata file index */ + uint8_t md_hdr_image[H5FD_MD_HEADER_SIZE]; /* Buffer for metadata file header */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -184,43 +193,26 @@ H5F_vfd_swmr_init(H5F_t *f, hbool_t file_create) if (H5F_SHARED_INTENT(shared) & H5F_ACC_RDWR) { HDassert(shared->vfd_swmr_config.writer); + HDassert(shared->vfd_swmr_config.maintain_metadata_file || + shared->vfd_swmr_config.generate_updater_files); SIMPLEQ_INIT(&shared->lower_defrees); shared->vfd_swmr_writer = TRUE; - shared->tick_num = 1; - - if (H5PB_vfd_swmr__set_tick(shared) < 0) - HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "Can't update page buffer current tick") + shared->tick_num = 0; /* Create the metadata file */ - if (((shared->vfd_swmr_md_fd = HDopen(shared->vfd_swmr_config.md_file_path, O_CREAT | O_RDWR, + if (((shared->vfd_swmr_md_fd = HDopen(shared->vfd_swmr_config.md_file_path, O_CREAT | O_RDWR | O_TRUNC, 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; - HDassert(shared->fs_page_size >= H5FD_MD_HEADER_SIZE); - - /* Allocate an entire page from the shadow file for the header. */ - if ((hdr_addr = H5MV_alloc(f, shared->fs_page_size)) == HADDR_UNDEF) { + if ((hdr_addr = H5MV_alloc(f, md_size)) == HADDR_UNDEF) { HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "error allocating shadow-file header"); } HDassert(H5F_addr_eq(hdr_addr, H5FD_MD_HEADER_OFF)); - idx_addr = H5MV_alloc(f, md_size - shared->fs_page_size); - if (idx_addr == HADDR_UNDEF) { - HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "error allocating shadow-file index"); - } - - HDassert(H5F_addr_eq(idx_addr, shared->fs_page_size)); - - shared->writer_index_offset = idx_addr; - - /* Set the metadata file size to md_pages_reserved */ - if (-1 == HDftruncate(shared->vfd_swmr_md_fd, (HDoff_t)md_size)) - HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "truncate fail for the metadata file"); - - /* Set eof for metadata file to md_pages_reserved */ + shared->writer_index_offset = H5FD_MD_HEADER_SIZE; shared->vfd_swmr_md_eoa = (haddr_t)md_size; /* When opening an existing HDF5 file, create header and empty @@ -228,12 +220,34 @@ H5F_vfd_swmr_init(H5F_t *f, hbool_t file_create) */ if (!file_create) { - if (H5F__vfd_swmr_construct_write_md_idx(shared, 0, NULL) < 0) + if (H5F__vfd_swmr_construct_write_md_idx(shared, 0, NULL, md_idx_image) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to create index in md"); - if (H5F__vfd_swmr_construct_write_md_hdr(shared, 0) < 0) + if (H5F__vfd_swmr_construct_write_md_hdr(shared, 0, md_hdr_image) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to create header in md"); + } + + /* For VFD SWMR testing: invoke callback if set to generate metadata file checksum */ + if(shared->generate_md_ck_cb) { + if(shared->generate_md_ck_cb(shared->vfd_swmr_config.md_file_path, shared->updater_seq_num) < 0) + HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "error from generate_md_ck_cb()") + } + + /* Generate updater files if configuration indicates so */ + if(shared->vfd_swmr_config.generate_updater_files) { + shared->updater_seq_num = 0; + if(H5F__generate_updater_file(f, 0, file_create ? CREATE_METADATA_FILE_ONLY_FLAG : 0, + md_hdr_image, H5FD_MD_HEADER_SIZE, + md_idx_image, shared->writer_index_offset, H5FD_MD_INDEX_SIZE(0)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "can't generate updater file") + } + + shared->tick_num = 1; + + if (H5PB_vfd_swmr__set_tick(shared) < 0) + HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "Can't update page buffer current tick") + } else { /* VFD SWMR reader */ @@ -254,7 +268,6 @@ H5F_vfd_swmr_init(H5F_t *f, hbool_t file_create) &(shared->mdf_idx_entries_used), shared->mdf_idx) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTLOAD, FAIL, "unable to load/decode metadata file"); - HDassert(shared->tick_num != 0); vfd_swmr_reader_did_increase_tick_to(shared->tick_num); #if 0 /* JRM */ @@ -310,6 +323,8 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing) { H5F_shared_t * shared = f->shared; shadow_defree_t *curr; + uint8_t md_idx_image[H5FD_MD_INDEX_SIZE(0)]; /* Buffer for metadata file index */ + uint8_t md_hdr_image[H5FD_MD_HEADER_SIZE]; /* Buffer for metadata file header */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(FAIL) @@ -318,22 +333,26 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing) HDassert(shared->vfd_swmr_md_fd >= 0); /* Write empty index to the md file */ - if (H5F__vfd_swmr_construct_write_md_idx(shared, 0, NULL) < 0) + if (H5F__vfd_swmr_construct_write_md_idx(shared, 0, NULL, md_idx_image) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to create index in md"); /* Write header to the md file */ - if (H5F__vfd_swmr_construct_write_md_hdr(shared, 0) < 0) + if (H5F__vfd_swmr_construct_write_md_hdr(shared, 0, md_hdr_image) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to create header in md"); if (closing) { /* For file close */ - ++shared->tick_num; - /* Close the md file */ if (HDclose(shared->vfd_swmr_md_fd) < 0) HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close the metadata file"); shared->vfd_swmr_md_fd = -1; + /* For VFD SWMR testing: invoke callback if set to generate metadata file checksum */ + if(shared->generate_md_ck_cb) { + if(shared->generate_md_ck_cb(shared->vfd_swmr_config.md_file_path, shared->updater_seq_num) < 0) + HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "error from generate_md_ck_cb()") + } + /* Unlink the md file */ if (HDunlink(shared->vfd_swmr_config.md_file_path) < 0) HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTREMOVE, FAIL, "unable to unlink the metadata file"); @@ -350,6 +369,13 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing) } HDassert(TAILQ_EMPTY(&shared->shadow_defrees)); + + if(shared->vfd_swmr_config.generate_updater_files) { + if(H5F__generate_updater_file(f, 0, FINAL_UPDATE_FLAG, + md_hdr_image, H5FD_MD_HEADER_SIZE, + md_idx_image, shared->writer_index_offset, H5FD_MD_INDEX_SIZE(0)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "can't generate updater file") + } } else { /* For file flush */ /* Update end_of_tick */ @@ -438,6 +464,8 @@ H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t num_entries, H5FD_vfd_swmr_ shadow_defree_t *shadow_defree; haddr_t md_addr; /* Address in the metadata file */ uint32_t i; /* Local index variable */ + uint8_t *md_idx_image = NULL; + uint8_t md_hdr_image[H5FD_MD_HEADER_SIZE]; /* Buffer for metadata file header */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -460,13 +488,15 @@ H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t num_entries, H5FD_vfd_swmr_ * --Compute checksum, update the index entry, write entry to * the metadata file * - * --Set entry_ptr to NULL + * --Set entry_ptr to NULL when not generating updater files */ for (i = 0; i < num_entries; i++) { if (index[i].entry_ptr == NULL) continue; + HDassert(index[i].tick_of_last_change == f->shared->tick_num); + /* Prepend previous image of the entry to the delayed list */ if (index[i].md_file_page_offset) { if (shadow_image_defer_free(shared, &index[i]) == -1) { @@ -482,16 +512,16 @@ H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t num_entries, H5FD_vfd_swmr_ /* Compute checksum and update the index entry */ index[i].md_file_page_offset = md_addr / shared->fs_page_size; - index[i].chksum = H5_checksum_metadata(index[i].entry_ptr, index[i].length, 0); + index[i].checksum = H5_checksum_metadata(index[i].entry_ptr, index[i].length, 0); #if 0 /* JRM */ HDfprintf(stderr, - "writing index[%d] fo/mdfo/l/chksum/fc/lc = %lld/%lld/%ld/%lx/%lx/%lx\n", + "writing index[%d] fo/mdfo/l/checksum/fc/lc = %lld/%lld/%ld/%lx/%lx/%lx\n", i, index[i].hdf5_page_offset, index[i].md_file_page_offset, index[i].length, - index[i].chksum, + index[i].checksum, (((char*)(index[i].entry_ptr))[0]), (((char*)(index[i].entry_ptr))[4095])); @@ -500,26 +530,34 @@ H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t num_entries, H5FD_vfd_swmr_ HDassert(shared->fs_page_size == 4096); #endif /* JRM */ - /* Seek and write the entry to the metadata file */ - if (HDlseek(shared->vfd_swmr_md_fd, (HDoff_t)md_addr, SEEK_SET) < 0) + if(shared->vfd_swmr_config.maintain_metadata_file) { - HGOTO_ERROR(H5E_FILE, H5E_SEEKERROR, FAIL, "unable to seek in the metadata file") + /* Seek and write the entry to the metadata file */ + if (HDlseek(shared->vfd_swmr_md_fd, (HDoff_t)md_addr, SEEK_SET) < 0) - if (HDwrite(shared->vfd_swmr_md_fd, index[i].entry_ptr, index[i].length) != (ssize_t)index[i].length) + HGOTO_ERROR(H5E_FILE, H5E_SEEKERROR, FAIL, "unable to seek in the metadata file") - HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, - "error in writing the page/multi-page entry to metadata file") + if (HDwrite(shared->vfd_swmr_md_fd, index[i].entry_ptr, index[i].length) != (ssize_t)index[i].length) + + HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, + "error in writing the page/multi-page entry to metadata file") + } + + if(!shared->vfd_swmr_config.generate_updater_files) + index[i].entry_ptr = NULL; - index[i].entry_ptr = NULL; } + if ((md_idx_image = HDmalloc(H5FD_MD_INDEX_SIZE(num_entries))) == NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for md index") + /* Construct and write index to the metadata file */ - if (H5F__vfd_swmr_construct_write_md_idx(shared, num_entries, index) < 0) + if (H5F__vfd_swmr_construct_write_md_idx(shared, num_entries, index, md_idx_image) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to construct & write index to md") /* Construct and write header to the md file */ - if (H5F__vfd_swmr_construct_write_md_hdr(shared, num_entries) < 0) + if (H5F__vfd_swmr_construct_write_md_hdr(shared, num_entries, md_hdr_image) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to construct & write header to md") @@ -534,26 +572,47 @@ H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t num_entries, H5FD_vfd_swmr_ * --remove the associated entries from the list */ - if (shared->tick_num <= shared->vfd_swmr_config.max_lag) - goto done; // It is too early for any reclamations to be due. + /* if (shared->tick_num <= shared->vfd_swmr_config.max_lag), + it is too early for any reclamations to be due. + */ + if (shared->tick_num > shared->vfd_swmr_config.max_lag) { - TAILQ_FOREACH_REVERSE_SAFE(shadow_defree, &shared->shadow_defrees, shadow_defree_queue, link, prev) - { + TAILQ_FOREACH_REVERSE_SAFE(shadow_defree, &shared->shadow_defrees, shadow_defree_queue, link, prev) + { - if (shadow_defree->tick_num + shared->vfd_swmr_config.max_lag > shared->tick_num) { - break; // No more entries are due for reclamation. - } + if (shadow_defree->tick_num + shared->vfd_swmr_config.max_lag > shared->tick_num) { + break; // No more entries are due for reclamation. + } + + if (H5MV_free(f, shadow_defree->offset, shadow_defree->length) < 0) { + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush clean entry"); + } + + TAILQ_REMOVE(&shared->shadow_defrees, shadow_defree, link); - if (H5MV_free(f, shadow_defree->offset, shadow_defree->length) < 0) { - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush clean entry"); + H5FL_FREE(shadow_defree_t, shadow_defree); } + } - TAILQ_REMOVE(&shared->shadow_defrees, shadow_defree, link); - H5FL_FREE(shadow_defree_t, shadow_defree); + /* For VFD SWMR testing: invoke callback if set to generate metadata file checksum */ + if(shared->generate_md_ck_cb) { + if(shared->generate_md_ck_cb(shared->vfd_swmr_config.md_file_path, shared->updater_seq_num) < 0) + HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "error from generate_md_ck_cb()") } + /* Generate updater files with num_entries */ + if(shared->vfd_swmr_config.generate_updater_files) + if(H5F__generate_updater_file(f, num_entries, 0, + md_hdr_image, H5FD_MD_HEADER_SIZE, + md_idx_image, shared->writer_index_offset, H5FD_MD_INDEX_SIZE(num_entries)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "can't generate updater file") + done: + + if (md_idx_image) + HDfree(md_idx_image); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_update_vfd_swmr_metadata_file() */ @@ -1571,9 +1630,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5F__vfd_swmr_construct_write_md_hdr(H5F_shared_t *shared, uint32_t num_entries) +H5F__vfd_swmr_construct_write_md_hdr(H5F_shared_t *shared, uint32_t num_entries, uint8_t *image) { - uint8_t image[H5FD_MD_HEADER_SIZE]; /* Buffer for header */ uint8_t *p = NULL; /* Pointer to buffer */ uint32_t metadata_chksum; /* Computed metadata checksum value */ /* Size of header and index */ @@ -1607,15 +1665,17 @@ H5F__vfd_swmr_construct_write_md_hdr(H5F_shared_t *shared, uint32_t num_entries) /* Sanity checks on header */ HDassert(p - image == (ptrdiff_t)hdr_size); - /* Set to beginning of the file */ - if (HDlseek(shared->vfd_swmr_md_fd, H5FD_MD_HEADER_OFF, SEEK_SET) < 0) + if(shared->vfd_swmr_config.maintain_metadata_file) { + /* Set to beginning of the file */ + if (HDlseek(shared->vfd_swmr_md_fd, H5FD_MD_HEADER_OFF, SEEK_SET) < 0) - HGOTO_ERROR(H5E_VFL, H5E_SEEKERROR, FAIL, "unable to seek in metadata file") + HGOTO_ERROR(H5E_VFL, H5E_SEEKERROR, FAIL, "unable to seek in metadata file") - nwritten = HDwrite(shared->vfd_swmr_md_fd, image, hdr_size); - /* Write header to the metadata file */ - if (nwritten != (ssize_t)hdr_size) { - HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "error in writing header to metadata file") + nwritten = HDwrite(shared->vfd_swmr_md_fd, image, hdr_size); + /* Write header to the metadata file */ + if (nwritten != (ssize_t)hdr_size) { + HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "error in writing header to metadata file") + } } done: @@ -1648,9 +1708,8 @@ done: */ static herr_t H5F__vfd_swmr_construct_write_md_idx(H5F_shared_t *shared, uint32_t num_entries, - struct H5FD_vfd_swmr_idx_entry_t index[]) + struct H5FD_vfd_swmr_idx_entry_t index[], uint8_t *image) { - uint8_t *image = NULL; /* Pointer to buffer */ uint8_t *p = NULL; /* Pointer to buffer */ uint32_t metadata_chksum; /* Computed metadata checksum value */ /* Size of index */ @@ -1663,11 +1722,6 @@ H5F__vfd_swmr_construct_write_md_idx(H5F_shared_t *shared, uint32_t num_entries, HDassert(num_entries == 0 || index != NULL); - /* Allocate space for the buffer to hold the index */ - if ((image = HDmalloc(idx_size)) == NULL) - - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for md index") - /* * Encode metadata file index */ @@ -1688,7 +1742,7 @@ H5F__vfd_swmr_construct_write_md_idx(H5F_shared_t *shared, uint32_t num_entries, UINT32ENCODE(p, index[i].hdf5_page_offset); UINT32ENCODE(p, index[i].md_file_page_offset); UINT32ENCODE(p, index[i].length); - UINT32ENCODE(p, index[i].chksum); + UINT32ENCODE(p, index[i].checksum); } /* Calculate checksum for index */ @@ -1703,22 +1757,20 @@ H5F__vfd_swmr_construct_write_md_idx(H5F_shared_t *shared, uint32_t num_entries, /* Verify the md file descriptor exists */ HDassert(shared->vfd_swmr_md_fd >= 0); - if (HDlseek(shared->vfd_swmr_md_fd, (HDoff_t)shared->writer_index_offset, SEEK_SET) < 0) - HGOTO_ERROR(H5E_VFL, H5E_SEEKERROR, FAIL, "unable to seek in metadata file") + if(shared->vfd_swmr_config.maintain_metadata_file) { - nwritten = HDwrite(shared->vfd_swmr_md_fd, image, idx_size); - /* Write index to the metadata file */ - if (nwritten != (ssize_t)idx_size) { - HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "error in writing index to metadata file") + if (HDlseek(shared->vfd_swmr_md_fd, (HDoff_t)shared->writer_index_offset, SEEK_SET) < 0) + HGOTO_ERROR(H5E_VFL, H5E_SEEKERROR, FAIL, "unable to seek in metadata file") + + nwritten = HDwrite(shared->vfd_swmr_md_fd, image, idx_size); + /* Write index to the metadata file */ + if (nwritten != (ssize_t)idx_size) { + HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "error in writing index to metadata file") + } } done: - if (image) { - - HDfree(image); - } - FUNC_LEAVE_NOAPI(ret_value) } /* H5F__vfd_swmr_construct_write_idx() */ @@ -2010,3 +2062,381 @@ H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log_info) } return; } + +/*------------------------------------------------------------------------- + * + * Function: H5F__vfd_swmr_construct_ud_hdr + * + * Purpose: Encode updater header in the buffer updater->header_image_ptr + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Vailin Choi -- 10/2021 + * + * Changes: None. + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F__vfd_swmr_construct_ud_hdr(H5F_vfd_swmr_updater_t *updater) +{ + uint8_t *p = NULL; /* Pointer to buffer */ + uint8_t *image = (uint8_t *)updater->header_image_ptr; + uint32_t metadata_chksum; /* Computed metadata checksum value */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC_NOERR + + /* + * Encode metadata file header + */ + p = image; + + /* Encode magic for header */ + HDmemcpy(p, H5F_UD_HEADER_MAGIC, (size_t)H5_SIZEOF_MAGIC); + p += H5_SIZEOF_MAGIC; + + /* Encode version number, flags, page size, sequence number, tick number, change list offset, change list length */ + UINT16ENCODE(p, H5F_UD_VERSION); + UINT16ENCODE(p, updater->flags); + UINT32ENCODE(p, updater->page_size); + UINT64ENCODE(p, updater->sequence_number); + UINT64ENCODE(p, updater->tick_num); + + UINT64ENCODE(p, updater->change_list_offset); + UINT64ENCODE(p, updater->change_list_len); + + /* Calculate checksum for header */ + metadata_chksum = H5_checksum_metadata(image, (size_t)(p - image), 0); + + /* Encode checksum for header */ + UINT32ENCODE(p, metadata_chksum); + + /* Sanity checks on header */ + HDassert(p - image == (ptrdiff_t)updater->header_image_len); + + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5F__vfd_swmr_construct_ud_hdr() */ + +/*------------------------------------------------------------------------- + * + * Function: H5F__vfd_swmr_construct_ud_cl + * + * Purpose: Encode updater change list in the buffer + * updater->change_list_image_ptr + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Vailin Choi -- 10/2021 + * + * Changes: None. + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F__vfd_swmr_construct_ud_cl(H5F_vfd_swmr_updater_t *updater) +{ + uint8_t *p = NULL; /* Pointer to buffer */ + uint8_t *image = (uint8_t *)updater->change_list_image_ptr; + uint32_t metadata_chksum; /* Computed metadata checksum value */ + unsigned i; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC_NOERR + + /* + * Encode ud cl + */ + p = image; + + /* Encode magic for ud cl */ + HDmemcpy(p, H5F_UD_CL_MAGIC, H5_SIZEOF_MAGIC); + p += H5_SIZEOF_MAGIC; + + /* Encode tick number */ + UINT64ENCODE(p, updater->tick_num); + + /* Encode Metadata File Header Updater File Page Offset*/ + UINT32ENCODE(p, updater->md_file_header_ud_file_page_offset); + + /* Encode Metadata File Header Length */ + UINT32ENCODE(p, updater->md_file_header_len); + + /* Calculate checksum on the image of the metadata file header */ + updater->md_file_header_image_chksum = H5_checksum_metadata( + updater->md_file_header_image_ptr, (size_t)updater->md_file_header_len, 0); + + /* Encode Metadata File Header Checksum */ + UINT32ENCODE(p, updater->md_file_header_image_chksum); + + /* Encode Metadata File Index Updater File Page Offset*/ + UINT32ENCODE(p, updater->md_file_index_ud_file_page_offset); + + /* Encode Metadata File Index Metadata File Offset */ + UINT64ENCODE(p, updater->md_file_index_md_file_offset); + + /* Encode Metadata File Index Length */ + UINT32ENCODE(p, updater->md_file_index_len); + + /* Calculate checksum on the image of the metadata file index */ + updater->md_file_index_image_chksum = H5_checksum_metadata( + updater->md_file_index_image_ptr, (size_t)updater->md_file_index_len, 0); + + /* Encode Metadata File Index Checksum */ + UINT32ENCODE(p, updater->md_file_index_image_chksum); + + UINT32ENCODE(p, updater->num_change_list_entries); + + /* Encode the ud cl entries */ + for (i = 0; i < updater->num_change_list_entries; i++) { + UINT32ENCODE(p, updater->change_list[i].entry_image_ud_file_page_offset); + UINT32ENCODE(p, updater->change_list[i].entry_image_md_file_page_offset); + UINT32ENCODE(p, updater->change_list[i].entry_image_h5_file_page_offset); + UINT32ENCODE(p, updater->change_list[i].entry_image_len); + UINT32ENCODE(p, updater->change_list[i].entry_image_checksum); + } + + /* Calculate checksum for ud cl */ + metadata_chksum = H5_checksum_metadata(image, (size_t)(p - image), 0); + + /* Encode checksum for index */ + UINT32ENCODE(p, metadata_chksum); + + /* Sanity checks on index */ + HDassert(p - image == (ptrdiff_t)updater->change_list_len); + + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5F__vfd_swmr_construct_ud_cl() */ + +/*------------------------------------------------------------------------- + * + * Function: H5F_generate_updater_file() + * + * Purpose: Generate updater file: + * --assemble and initialize data in the updater struct + * --determine num_change_list entries + * --allocate buffers + * --construct on disk image (serialize) of the updater header and change list + * --create updater file using a temporay file name: + * --<shared->vfd_swmr_config.updater_file_path>.ud_tmp + * --allocate space and write the following to the updater file + * --updater file header + * --updater file change list + * --metadata entries + * --metadata file index + * --metadata file header + * --close the updater file + * --rename the updater file with the correct name: + * <shared->vfd_swmr_config.updater_file_path>.<shared->updater_seq_num> + * + * --increment shared->updater_seq_num + * --free buffers + * + * Return: SUCCEED/FAIL + * + * Programmer: Vailin Choi 8/24/2021 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F__generate_updater_file(H5F_t *f, uint32_t num_entries, uint16_t flags, + uint8_t *md_file_hdr_image_ptr, size_t md_file_hdr_image_len, + uint8_t *md_file_index_image_ptr, uint64_t md_file_index_offset, + size_t md_file_index_image_len) +{ + H5F_shared_t *shared = f->shared; /* shared file pointer */ + H5F_vfd_swmr_updater_t updater; /* Updater struct */ + uint32_t next_page_offset; + H5FD_t *ud_file = NULL; /* Low-level file struct */ + char namebuf[H5F__MAX_VFD_SWMR_FILE_NAME_LEN]; + char newname[H5F__MAX_VFD_SWMR_FILE_NAME_LEN]; + unsigned i; + hsize_t alloc_size; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Updater file header fields */ + updater.version = H5F_UD_VERSION; + updater.flags = flags; + updater.page_size = (uint32_t)shared->fs_page_size; + updater.sequence_number = shared->updater_seq_num; + updater.tick_num = shared->tick_num; + updater.header_image_ptr = NULL; + updater.header_image_len = H5F_UD_HEADER_SIZE; + updater.change_list_image_ptr = NULL; + updater.change_list_offset = 0; + updater.change_list_len = 0; + + /* Updater file change list fields */ + + /* md_file_header related fields */ + updater.md_file_header_ud_file_page_offset = 0; + updater.md_file_header_image_ptr = md_file_hdr_image_ptr; /* parameter */ + updater.md_file_header_len = md_file_hdr_image_len; /* parameter */ + + /* md_file_index related fields */ + updater.md_file_index_ud_file_page_offset = 0; + updater.md_file_index_image_ptr = md_file_index_image_ptr; /* parameter */ + updater.md_file_index_md_file_offset = md_file_index_offset; /* parameter */ + updater.md_file_index_len = md_file_index_image_len; /* parameter */ + + updater.num_change_list_entries = 0; + updater.change_list = NULL; + + /* Scan index to determine updater.num_change_list_entries */ + for (i = 0; i < num_entries; i++) { + if (shared->mdf_idx[i].entry_ptr != NULL && + shared->mdf_idx[i].tick_of_last_change == shared->tick_num) + updater.num_change_list_entries += 1; + } + + if (flags == CREATE_METADATA_FILE_ONLY_FLAG) + HDassert(updater.sequence_number == 0); + /* For file creation, just generate a header with this flag set */ + else { + /* Update 2 updater file header fields: change_list_len, change_list_offset */ + updater.change_list_len = H5F_UD_CL_SIZE(updater.num_change_list_entries); + updater.change_list_offset = updater.header_image_len; + } + + + /* Create the updater file with a temporary file name */ + HDsprintf(namebuf, "%s.ud_tmp", shared->vfd_swmr_config.updater_file_path); + + if((ud_file = H5FD_open(namebuf, H5F_ACC_TRUNC|H5F_ACC_RDWR|H5F_ACC_CREAT, H5P_FILE_ACCESS_DEFAULT, HADDR_UNDEF)) == NULL) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "fail to open updater file"); + + if ((updater.header_image_ptr = HDmalloc(updater.header_image_len)) == NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for ud header") + + /* Serialize updater file hdr in updater.header_image_ptr */ + if (H5F__vfd_swmr_construct_ud_hdr(&updater) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to create updater file header "); + + /* Allocate space in updater file for updater file header */ + if(H5FD__alloc_real(ud_file, H5FD_MEM_DEFAULT, updater.header_image_len, NULL, NULL) == HADDR_UNDEF) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to allocate file memory") + + /* Write updater file header */ + if(H5FD_write(ud_file, H5FD_MEM_DEFAULT, H5F_UD_HEADER_OFF, updater.header_image_len, updater.header_image_ptr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "ud file write failed") + + + if (flags != CREATE_METADATA_FILE_ONLY_FLAG) { + + next_page_offset = ((uint32_t)(updater.header_image_len + updater.change_list_len) / updater.page_size) + 1; + + if(updater.num_change_list_entries) { + + /* Allocate space for change list entries */ + if((updater.change_list = HDmalloc(sizeof(H5F_vfd_swmr_updater_cl_entry_t) * + updater.num_change_list_entries)) == NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for ud cl") + + + /* Initialize change list entries */ + for (i = 0; i < num_entries; i++) { + + if (shared->mdf_idx[i].entry_ptr != NULL && + shared->mdf_idx[i].tick_of_last_change == shared->tick_num) { + + updater.change_list[i].entry_image_ptr = shared->mdf_idx[i].entry_ptr; + updater.change_list[i].entry_image_ud_file_page_offset = 0; + updater.change_list[i].entry_image_md_file_page_offset = (uint32_t)shared->mdf_idx[i].md_file_page_offset; + updater.change_list[i].entry_image_h5_file_page_offset = (uint32_t)shared->mdf_idx[i].hdf5_page_offset; + updater.change_list[i].entry_image_len = shared->mdf_idx[i].length; + updater.change_list[i].entry_image_checksum = shared->mdf_idx[i].checksum; + + shared->mdf_idx[i].entry_ptr = NULL; + } + } + + /* Set up page aligned space for all metadata pages */ + for(i = 0; i < updater.num_change_list_entries; i++) { + updater.change_list[i].entry_image_ud_file_page_offset = next_page_offset; + next_page_offset += (((uint32_t)updater.change_list[i].entry_image_len / updater.page_size) + 1); + } + } + + /* Set up page aligned space for the metadata file index */ + updater.md_file_index_ud_file_page_offset = next_page_offset; + + /* Set up page aligned space for the metadata file header */ + next_page_offset += (((uint32_t)updater.md_file_index_len / updater.page_size) + 1); + updater.md_file_header_ud_file_page_offset = next_page_offset; + + if ((updater.change_list_image_ptr = HDmalloc(updater.change_list_len)) == NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for ud cl ") + + /* Serialize updater file change list in updater.change_list_image_ptr */ + if (H5F__vfd_swmr_construct_ud_cl(&updater) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to create updater file cl"); + + /* Allocate space in updater file for updater file change list */ + if(H5FD__alloc_real(ud_file, H5FD_MEM_DEFAULT, updater.header_image_len+updater.change_list_len, NULL, NULL) == HADDR_UNDEF) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to allocate file memory") + + /* Write updater file change list */ + if(H5FD_write(ud_file, H5FD_MEM_DEFAULT, updater.header_image_len, + updater.change_list_len, updater.change_list_image_ptr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "ud file write failed") + + + /* Allocate and write metadata pages */ + for (i = 0; i < updater.num_change_list_entries; i++) { + alloc_size = updater.change_list[i].entry_image_ud_file_page_offset * updater.page_size + + updater.change_list[i].entry_image_len; + + if(H5FD__alloc_real(ud_file, H5FD_MEM_DEFAULT, alloc_size, NULL, NULL) == HADDR_UNDEF) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to allocate file memory") + + if(H5FD_write(ud_file, H5FD_MEM_DEFAULT, + updater.change_list[i].entry_image_ud_file_page_offset * updater.page_size, + updater.change_list[i].entry_image_len, + updater.change_list[i].entry_image_ptr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "ud file write failed") + } + + /* Allocate and write metadata file index */ + alloc_size = updater.md_file_index_ud_file_page_offset * updater.page_size + updater.md_file_index_len; + if(H5FD__alloc_real(ud_file, H5FD_MEM_DEFAULT, alloc_size, NULL, NULL) == HADDR_UNDEF) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to allocate file memory") + + if(H5FD_write(ud_file, H5FD_MEM_DEFAULT, updater.md_file_index_ud_file_page_offset * updater.page_size, + updater.md_file_index_len, updater.md_file_index_image_ptr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "ud file write failed") + + /* Allocate and write metadata file header */ + alloc_size = updater.md_file_header_ud_file_page_offset * updater.page_size + updater.md_file_header_len; + if(H5FD__alloc_real(ud_file, H5FD_MEM_DEFAULT, alloc_size, NULL, NULL) == HADDR_UNDEF) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to allocate file memory") + + if(H5FD_write(ud_file, H5FD_MEM_DEFAULT, updater.md_file_header_ud_file_page_offset * updater.page_size, + updater.md_file_header_len, updater.md_file_header_image_ptr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "ud file write failed") + } + + /* Close the updater file and rename the file */ + if(H5FD_close(ud_file) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close updater file") + HDsprintf(newname, "%s.%lu", shared->vfd_swmr_config.updater_file_path, shared->updater_seq_num); + HDrename(namebuf, newname); + + ++shared->updater_seq_num; + +done: + if(updater.header_image_ptr) + HDfree(updater.header_image_ptr); + if(updater.change_list_image_ptr) + HDfree(updater.change_list_image_ptr); + if(updater.change_list) + HDfree(updater.change_list); + + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5F__generate_updater_file() */ diff --git a/src/H5PB.c b/src/H5PB.c index 57ef7fb..ef93bd7 100644 --- a/src/H5PB.c +++ b/src/H5PB.c @@ -2121,7 +2121,7 @@ H5PB_vfd_swmr__update_index(H5F_t *f, uint32_t *idx_ent_added_ptr, uint32_t *idx /* partial initialization of new entry -- rest done later */ ie_ptr->hdf5_page_offset = target_page; ie_ptr->md_file_page_offset = 0; /* undefined at this point */ - ie_ptr->chksum = 0; /* undefined at this point */ + ie_ptr->checksum = 0; /* undefined at this point */ /* ie_ptr->entry_ptr initialized below */ /* ie_ptr->tick_of_last_change initialized below */ /* ie_ptr->clean initialized below */ diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index 3b39f12..f833d65 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -318,6 +318,16 @@ #define H5F_ACS_VFD_SWMR_CONFIG_ENC H5P__facc_vfd_swmr_config_enc #define H5F_ACS_VFD_SWMR_CONFIG_DEC H5P__facc_vfd_swmr_config_dec +/* Private property for VFD SWMR testing: + * Callback function to generate checksum for metadata file + */ +#define H5F_ACS_GENERATE_MD_CK_CB_SIZE sizeof(H5F_generate_md_ck_cb_t) + +#define H5F_ACS_GENERATE_MD_CK_CB_DEF \ + { \ + NULL \ + } + /******************/ /* Local Typedefs */ /******************/ @@ -515,6 +525,9 @@ static const hbool_t H5F_def_ignore_disabled_file_locks_g = H5F_ACS_IGNORE_DISABLED_FILE_LOCKS_DEF; /* Default ignore disabled file locks flag */ static const H5F_vfd_swmr_config_t H5F_def_vfd_swmr_config_g = H5F_ACS_VFD_SWMR_CONFIG_DEF; /* Default vfd swmr configuration */ +/* For VFD SWMR testing only: Default to generate checksum for metadata file */ +static const H5F_generate_md_ck_t H5F_def_generate_md_ck_cb_g = + H5F_ACS_GENERATE_MD_CK_CB_DEF; /*------------------------------------------------------------------------- * Function: H5P__facc_reg_prop @@ -633,6 +646,14 @@ H5P__facc_reg_prop(H5P_genclass_t *pclass) NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + /* Register the private property of whether to generate checksum for metadata file. + * It's used for VFD SWMR testing only. */ + /* (Note: this property should not have an encode/decode callback -QAK) */ + if (H5P__register_real(pclass, H5F_ACS_GENERATE_MD_CK_CB_NAME, H5F_ACS_GENERATE_MD_CK_CB_SIZE, + &H5F_def_generate_md_ck_cb_g, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + /* Register the data type of multi driver info */ if (H5P__register_real(pclass, H5F_ACS_MULTI_TYPE_NAME, H5F_ACS_MULTI_TYPE_SIZE, &H5F_def_mem_type_g, NULL, NULL, NULL, H5F_ACS_MULTI_TYPE_ENC, H5F_ACS_MULTI_TYPE_DEC, NULL, NULL, NULL, @@ -4097,11 +4118,15 @@ H5P__facc_vfd_swmr_config_enc(const void *value, void **_pp, size_t *size) INT32ENCODE(*pp, (int32_t)config->tick_len); INT32ENCODE(*pp, (int32_t)config->max_lag); H5_ENCODE_UNSIGNED(*pp, config->writer); + H5_ENCODE_UNSIGNED(*pp, config->maintain_metadata_file); + H5_ENCODE_UNSIGNED(*pp, config->generate_updater_files); H5_ENCODE_UNSIGNED(*pp, config->flush_raw_data); INT32ENCODE(*pp, (int32_t)config->md_pages_reserved); INT32ENCODE(*pp, (int32_t)config->pb_expansion_threshold); HDmemcpy(*pp, (const uint8_t *)(config->md_file_path), (size_t)(H5F__MAX_VFD_SWMR_FILE_NAME_LEN + 1)); *pp += H5F__MAX_VFD_SWMR_FILE_NAME_LEN + 1; + HDmemcpy(*pp, (const uint8_t *)(config->updater_file_path), (size_t)(H5F__MAX_VFD_SWMR_FILE_NAME_LEN + 1)); + *pp += H5F__MAX_VFD_SWMR_FILE_NAME_LEN + 1; HDmemcpy(*pp, (const uint8_t *)(config->log_file_path), (size_t)(H5F__MAX_VFD_SWMR_FILE_NAME_LEN + 1)); *pp += H5F__MAX_VFD_SWMR_FILE_NAME_LEN + 1; @@ -4109,7 +4134,7 @@ H5P__facc_vfd_swmr_config_enc(const void *value, void **_pp, size_t *size) } /* end if */ /* Compute encoded size */ - *size += ((5 * sizeof(int32_t)) + (2 * sizeof(unsigned)) + (2 * (H5F__MAX_VFD_SWMR_FILE_NAME_LEN + 1))); + *size += ((5 * sizeof(int32_t)) + (4 * sizeof(unsigned)) + (3 * (H5F__MAX_VFD_SWMR_FILE_NAME_LEN + 1))); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5P__facc_vfd_swmr_config_enc() */ @@ -4150,6 +4175,8 @@ H5P__facc_vfd_swmr_config_dec(const void **_pp, void *_value) UINT32DECODE(*pp, config->max_lag); H5_DECODE_UNSIGNED(*pp, config->writer); + H5_DECODE_UNSIGNED(*pp, config->maintain_metadata_file); + H5_DECODE_UNSIGNED(*pp, config->generate_updater_files); H5_DECODE_UNSIGNED(*pp, config->flush_raw_data); /* int */ @@ -4159,6 +4186,9 @@ H5P__facc_vfd_swmr_config_dec(const void **_pp, void *_value) HDstrcpy(config->md_file_path, (const char *)(*pp)); *pp += H5F__MAX_VFD_SWMR_FILE_NAME_LEN + 1; + HDstrcpy(config->updater_file_path, (const char *)(*pp)); + *pp += H5F__MAX_VFD_SWMR_FILE_NAME_LEN + 1; + HDstrcpy(config->log_file_path, (const char *)(*pp)); *pp += H5F__MAX_VFD_SWMR_FILE_NAME_LEN + 1; @@ -5703,12 +5733,30 @@ H5Pset_vfd_swmr_config(hid_t plist_id, H5F_vfd_swmr_config_t *config_ptr) if (config_ptr->pb_expansion_threshold > H5F__MAX_PB_EXPANSION_THRESHOLD) HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "pb_expansion_threshold out of range") - /* Must provide the path for the metadata file */ - name_len = HDstrlen(config_ptr->md_file_path); - if (name_len == 0) - HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "md_file_path is empty") - else if (name_len > H5F__MAX_VFD_SWMR_FILE_NAME_LEN) - HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "md_file_path is too long") + /* If writer is TRUE, at least one of maintain_metadata_file and generate_updater_files must be TRUE */ + if(config_ptr->writer) { + if(!config_ptr->maintain_metadata_file && !config_ptr->generate_updater_files) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "either maintain_metadata_file or generate_updater_files must be TRUE") + } + + if((config_ptr->writer && config_ptr->maintain_metadata_file) || !config_ptr->writer) { + /* Must provide the path and base name of the metadata file */ + name_len = HDstrlen(config_ptr->md_file_path); + if (name_len == 0) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "md_file_path is empty") + else if (name_len > H5F__MAX_VFD_SWMR_FILE_NAME_LEN) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "md_file_path is too long") + } + + if(config_ptr->writer && config_ptr->generate_updater_files) { + /* Must provide the path and base name of the metadata updater files */ + name_len = HDstrlen(config_ptr->updater_file_path); + if (name_len == 0) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "updater_file_path is empty") + else if (name_len > H5F__MAX_VFD_SWMR_FILE_NAME_LEN) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "updater_file_path is too long") + } + name_len = HDstrlen(config_ptr->log_file_path); if (name_len > H5F__MAX_VFD_SWMR_FILE_NAME_LEN) diff --git a/test/page_buffer.c b/test/page_buffer.c index 61e9696..53c9b74 100644 --- a/test/page_buffer.c +++ b/test/page_buffer.c @@ -101,6 +101,8 @@ swmr_fapl_augment(hid_t fapl, const char *filename, uint32_t max_lag) .tick_len = 4, .max_lag = max_lag, .writer = true, + .maintain_metadata_file = true, + .generate_updater_files = false, .md_pages_reserved = 128}; char * bname = NULL; char * dname = NULL; diff --git a/test/vfd_swmr.c b/test/vfd_swmr.c index 3ed73c1..e93a399 100644 --- a/test/vfd_swmr.c +++ b/test/vfd_swmr.c @@ -41,6 +41,7 @@ #define FS_PAGE_SIZE 512 #define FILENAME "vfd_swmr_file.h5" #define MD_FILENAME "vfd_swmr_metadata_file" +#define UD_FILENAME "vfd_swmr_updater_file" #define FILENAME2 "vfd_swmr_file2.h5" #define MD_FILENAME2 "vfd_swmr_metadata_file2" @@ -48,61 +49,50 @@ #define FILENAME3 "vfd_swmr_file3.h5" #define MD_FILENAME3 "vfd_swmr_metadata_file3" +#define FILENAME4 "vfd_swmr_file4.h5" +#define MD_FILE "vfd_swmr_md_file" +#define UD_FILE "vfd_swmr_ud_file" + #define FNAME "non_vfd_swmr_file.h5" -/* test routines for VFD SWMR */ -static unsigned test_fapl(void); -static unsigned test_file_end_tick(void); -static unsigned test_file_fapl(void); -static unsigned test_writer_md(void); +/* Defines used by verify_updater_flags() and verify_ud_chk() helper routine */ -/* helper routines */ -static hid_t init_vfd_swmr_config_fapl(H5F_vfd_swmr_config_t *config, uint32_t tick_len, uint32_t max_lag, - hbool_t is_writer, uint32_t md_pages_reserved, - const char *md_file_path, size_t pbuf_size); +/* Offset of "flags" in updater file header */ +#define UD_HD_FLAGS_OFFSET 6 -/*------------------------------------------------------------------------- - * Function: init_vfd_swmr_config_fapl - * - * Purpose: Helper routine to initialize the fields for VFD SWMR configuration - * - * Return: void - * - *------------------------------------------------------------------------- - */ -static hid_t -init_vfd_swmr_config_fapl(H5F_vfd_swmr_config_t *config, uint32_t tick_len, uint32_t max_lag, - hbool_t is_writer, uint32_t md_pages_reserved, const char *md_file_path, - size_t pbuf_size) -{ - hid_t fapl; +/* Offset of "sequence number" in updater file header */ +#define UD_HD_SEQ_NUM_OFFSET 12 - HDmemset(config, 0, sizeof(*config)); +/* Offset of "change list length" in updater file header */ +#define UD_HD_CHANGE_LIST_LEN_OFFSET 36 - config->version = H5F__CURR_VFD_SWMR_CONFIG_VERSION; - config->tick_len = tick_len; - config->max_lag = max_lag; - config->writer = is_writer; - config->md_pages_reserved = md_pages_reserved; - HDstrcpy(config->md_file_path, md_file_path); +/* Offset of "number of change list entries" in updater file change list header */ +#define UD_CL_NUM_CHANGE_LIST_ENTRIES_OFFSET H5F_UD_HEADER_SIZE + 44 - /* Create a copy of the file access property list */ - if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) - return H5I_INVALID_HID; +/* Size of "sequence number", "tick number" and "change list length" fields in the updater file header */ +#define UD_SIZE_8 8 - if (H5Pset_vfd_swmr_config(fapl, config) < 0) { - (void)H5Pclose(fapl); - return H5I_INVALID_HID; - } +/* Size of checksum and "number of change list entries" field in the updater change list header */ +#define UD_SIZE_4 4 - /* Enable page buffering */ - if (pbuf_size != 0 && H5Pset_page_buffer_size(fapl, pbuf_size, 0, 0) < 0) { - (void)H5Pclose(fapl); - return H5I_INVALID_HID; - } +/* Size of "flags" field in the updater file header */ +#define UD_SIZE_2 2 + +/* test routines for VFD SWMR */ +static unsigned test_fapl(void); +static unsigned test_file_end_tick(void); +static unsigned test_file_fapl(void); +static unsigned test_writer_md(void); + +static unsigned test_updater_flags(void); +static unsigned test_updater_flags_same_file_opens(void); +static herr_t verify_updater_flags(char *ud_name, uint16_t expected_flags); + +static void clean_chk_ud_files(char *md_file_path, char *updater_file_path); +static herr_t verify_ud_chk(char *md_file_path, char *ud_file_path); +static herr_t md_ck_cb(char *md_file_path, uint64_t tick_num); +static unsigned test_updater_generate_md_checksums(hbool_t file_create); - return fapl; -} /* init_vfd_swmr_config_fapl() */ /*------------------------------------------------------------------------- * Function: test_fapl() @@ -114,6 +104,12 @@ init_vfd_swmr_config_fapl(H5F_vfd_swmr_config_t *config, uint32_t tick_len, uint * --max_lag: should be >= 3 * --md_pages_reserved: should be >= 2 * --md_file_path: should contain the metadata file path (POSIX) + * --at least one of maintain_metadata_file and generate_updater_files + * must be true + * --if both the writer and maintain_metadata_file fields are true, + * then md_file_path field shouldn't be empty + * --if both the writer and generate_updater_files fields are true, + * then updater_file_path field shouldn't be empty * B) Verify that info set in the fapl is retrieved correctly. * * Return: 0 if test is sucessful @@ -195,9 +191,40 @@ test_fapl(void) if (ret >= 0) TEST_ERROR; + my_config->writer = TRUE; + /* Should fail: at least one of maintain_metadata_file and generate_updater_files must be true */ + H5E_BEGIN_TRY + { + ret = H5Pset_vfd_swmr_config(fapl, my_config); + } + H5E_END_TRY; + if (ret >= 0) + TEST_ERROR; + + my_config->writer = TRUE; + my_config->maintain_metadata_file = TRUE; + /* Should fail: empty md_file_path */ + H5E_BEGIN_TRY + { + ret = H5Pset_vfd_swmr_config(fapl, my_config); + } + H5E_END_TRY; + if (ret >= 0) + TEST_ERROR; + + my_config->generate_updater_files = TRUE; + /* Should fail: empty updater_file_path */ + H5E_BEGIN_TRY + { + ret = H5Pset_vfd_swmr_config(fapl, my_config); + } + H5E_END_TRY; + if (ret >= 0) + TEST_ERROR; + /* Set md_file_path */ HDstrcpy(my_config->md_file_path, MD_FILENAME); - my_config->writer = TRUE; + my_config->generate_updater_files = FALSE; /* Should succeed in setting the configuration info */ if (H5Pset_vfd_swmr_config(fapl, my_config) < 0) @@ -215,6 +242,33 @@ test_fapl(void) TEST_ERROR; if (my_config->md_pages_reserved != 2) TEST_ERROR; + if (my_config->generate_updater_files) + TEST_ERROR; + if (HDstrcmp(my_config->md_file_path, MD_FILENAME) != 0) + TEST_ERROR; + + my_config->generate_updater_files = TRUE; + /* Set updater_file_path */ + HDstrcpy(my_config->updater_file_path, UD_FILENAME); + + /* Should succeed in setting the configuration info */ + if (H5Pset_vfd_swmr_config(fapl, my_config) < 0) + TEST_ERROR; + + /* Clear the configuration structure */ + HDmemset(my_config, 0, sizeof(H5F_vfd_swmr_config_t)); + + /* Retrieve the configuration info just set */ + if (H5Pget_vfd_swmr_config(fapl, my_config) < 0) + TEST_ERROR; + + /* Verify the configuration info */ + if (!my_config->generate_updater_files) + TEST_ERROR; + if (HDstrcmp(my_config->updater_file_path, UD_FILENAME) != 0) + TEST_ERROR; + if (!my_config->maintain_metadata_file) + TEST_ERROR; if (HDstrcmp(my_config->md_file_path, MD_FILENAME) != 0) TEST_ERROR; @@ -290,8 +344,17 @@ test_file_fapl(void) if ((file_config = (H5F_vfd_swmr_config_t *)HDmalloc(sizeof(H5F_vfd_swmr_config_t))) == NULL) FAIL_STACK_ERROR; - /* Configured as VFD SWMR reader + no page buffering */ - fapl1 = init_vfd_swmr_config_fapl(config1, 4, 6, FALSE, 2, MD_FILENAME, 0); + + /* + * Configured as VFD SWMR reader + no page buffering + */ + + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config1, 4, 7, FALSE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl1 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 0, config1); if (fapl1 == H5I_INVALID_HID) TEST_ERROR @@ -307,8 +370,17 @@ test_file_fapl(void) if (H5Pclose(fapl1) < 0) FAIL_STACK_ERROR - /* Configured as VFD SWMR writer + no page buffering */ - fapl1 = init_vfd_swmr_config_fapl(config1, 4, 6, TRUE, 2, MD_FILENAME, 0); + /* + * Configured as VFD SWMR writer + no page buffering + */ + + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config1, 4, 7, TRUE, TRUE, TRUE, TRUE, 2, MD_FILENAME, UD_FILENAME); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl1 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 0, config1); + if (fapl1 == H5I_INVALID_HID) TEST_ERROR @@ -321,13 +393,10 @@ test_file_fapl(void) if (fid >= 0) TEST_ERROR; - /* Create a copy of the file creation property list */ - if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) + if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, 4096)) < 0) { + HDprintf("vfd_swmr_create_fcpl() failed"); FAIL_STACK_ERROR - - /* Set file space strategy */ - if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, FALSE, 1) < 0) - FAIL_STACK_ERROR; + } /* Should fail to create: no page buffering */ H5E_BEGIN_TRY @@ -341,8 +410,17 @@ test_file_fapl(void) if (H5Pclose(fapl1) < 0) FAIL_STACK_ERROR - /* Configured as VFD SWMR writer + page buffering */ - fapl1 = init_vfd_swmr_config_fapl(config1, 4, 6, TRUE, 2, MD_FILENAME, 4096); + /* + * Configured as VFD SWMR writer + page buffering + */ + + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config1, 4, 7, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl1 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config1); + if (fapl1 == H5I_INVALID_HID) TEST_ERROR @@ -404,8 +482,17 @@ test_file_fapl(void) if (H5Pclose(fapl1) < 0) FAIL_STACK_ERROR; - /* Set up different VFD SWMR configuration + page_buffering */ - fapl2 = init_vfd_swmr_config_fapl(config2, 4, 10, TRUE, 2, MD_FILENAME, 4096); + /* + * Set up different VFD SWMR configuration + page_buffering + */ + + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config2, 4, 10, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl2 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config2); + if (fapl2 == H5I_INVALID_HID) TEST_ERROR @@ -435,10 +522,20 @@ test_file_fapl(void) /* The file previously opened as VDF SWMR writer is still open */ /* with VFD SWMR configuration in config2 */ - /* Set up as VFD SWMR writer in config1 but different from config2 */ - fapl1 = init_vfd_swmr_config_fapl(config1, 3, 8, TRUE, 3, MD_FILENAME, 4096); + + /* + * Set up as VFD SWMR writer in config1 but different from config2 + */ + + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config1, 3, 8, TRUE, TRUE, FALSE, TRUE, 3, MD_FILENAME, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl1 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config1); + if (fapl1 == H5I_INVALID_HID) - TEST_ERROR; + TEST_ERROR /* Re-open the same file with config1 */ /* Should fail to open since config1 is different from config2 setting */ @@ -454,10 +551,17 @@ test_file_fapl(void) if (H5Pclose(fapl1) < 0) FAIL_STACK_ERROR; - /* Set up as VFD SWMR reader in config1 which is same as config2 */ - fapl1 = init_vfd_swmr_config_fapl(config1, 4, 10, TRUE, 2, MD_FILENAME, 4096); + /* + * Set up as VFD SWMR reader in config1 which is same as config2 + */ + + init_vfd_swmr_config(config1, 4, 10, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl1 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config1); + if (fapl1 == H5I_INVALID_HID) - TEST_ERROR; + TEST_ERROR /* Re-open the same file as VFD SWMR writer */ /* Should succeed since config1 is same as the setting in config2 */ @@ -530,6 +634,7 @@ error: return 1; } /* test_file_fapl() */ + /*------------------------------------------------------------------------- * Function: test_file_end_tick() * @@ -589,28 +694,52 @@ test_file_end_tick(void) if ((config3 = HDmalloc(sizeof(*config3))) == NULL) FAIL_STACK_ERROR; - /* Configured file 1 as VFD SWMR writer + page buffering */ - fapl1 = init_vfd_swmr_config_fapl(config1, 10, 15, TRUE, 2, MD_FILENAME, 4096); + /* + * Configured file 1 as VFD SWMR writer + page buffering + */ + + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config1, 10, 15, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl1 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config1); + if (fapl1 == H5I_INVALID_HID) - FAIL_STACK_ERROR; + TEST_ERROR + + /* + * Configured file 2 as VFD SWMR writer + page buffering + */ + + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config2, 5, 6, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME2, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl2 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config2); - /* Configured file 2 as VFD SWMR writer + page buffering */ - fapl2 = init_vfd_swmr_config_fapl(config2, 5, 6, TRUE, 2, MD_FILENAME2, 4096); if (fapl2 == H5I_INVALID_HID) - FAIL_STACK_ERROR; + TEST_ERROR - /* Configured file 3 as VFD SWMR writer + page buffering */ - fapl3 = init_vfd_swmr_config_fapl(config3, 3, 6, TRUE, 2, MD_FILENAME3, 4096); - if (fapl3 == H5I_INVALID_HID) - FAIL_STACK_ERROR; + /* + * Configured file 3 as VFD SWMR writer + page buffering + */ - /* Create a copy of the file creation property list */ - if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) - FAIL_STACK_ERROR + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config3, 3, 6, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME3, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl3 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config3); + + if (fapl3 == H5I_INVALID_HID) + TEST_ERROR - /* Set file space strategy */ - if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, FALSE, 1) < 0) + if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, 4096)) < 0) { + HDprintf("vfd_swmr_create_fcpl() failed"); FAIL_STACK_ERROR; + } /* Create file 1 with VFD SWMR writer */ if ((fid1 = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl1)) < 0) @@ -776,18 +905,23 @@ test_writer_create_open_flush(void) if ((my_config = HDmalloc(sizeof(H5F_vfd_swmr_config_t))) == NULL) FAIL_STACK_ERROR; - /* Set up the VFD SWMR configuration + page buffering */ - fapl = init_vfd_swmr_config_fapl(my_config, 1, 3, TRUE, 2, MD_FILENAME, 4096); - if (fapl == H5I_INVALID_HID) - FAIL_STACK_ERROR; + /* + * Set up the VFD SWMR configuration + page buffering + */ - /* Create a copy of the file creation property list */ - if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) - FAIL_STACK_ERROR + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(my_config, 1, 3, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, my_config); + if (fapl == H5I_INVALID_HID) + TEST_ERROR - /* Set file space strategy */ - if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, FALSE, 1) < 0) + if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, 4096)) < 0) { + HDprintf("vfd_swmr_create_fcpl() failed"); FAIL_STACK_ERROR; + } /* Create an HDF5 file with VFD SWMR configured */ if ((fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl)) < 0) @@ -797,7 +931,6 @@ test_writer_create_open_flush(void) if (H5F__vfd_swmr_writer_create_open_flush_test(fid, TRUE) < 0) FAIL_STACK_ERROR; -#ifdef LATER /* Will activate the test when flush is implemented */ /* Flush the HDF5 file */ if (H5Fflush(fid, H5F_SCOPE_GLOBAL) < 0) FAIL_STACK_ERROR @@ -805,7 +938,6 @@ test_writer_create_open_flush(void) /* Verify info in metadata file when flushing the HDF5 file */ if (H5F__vfd_swmr_writer_create_open_flush_test(fid, FALSE) < 0) FAIL_STACK_ERROR -#endif /* Close the file */ if (H5Fclose(fid) < 0) @@ -891,6 +1023,7 @@ test_writer_md(void) hsize_t chunk_dims[2] = {2, 5}; /* Dataset chunked dimension sizes */ H5FD_vfd_swmr_idx_entry_t *index = NULL; /* Pointer to the index entries */ H5F_vfd_swmr_config_t * my_config = NULL; /* Configuration for VFD SWMR */ + H5F_t * f = NULL; /* Internal file object pointer */ TESTING("Verify the metadata file for VFD SWMR writer"); @@ -898,25 +1031,28 @@ test_writer_md(void) if ((my_config = HDmalloc(sizeof(H5F_vfd_swmr_config_t))) == NULL) FAIL_STACK_ERROR; - /* Set up the VFD SWMR configuration + page buffering */ - fapl = init_vfd_swmr_config_fapl(my_config, 1, 3, TRUE, 256, MD_FILENAME, FS_PAGE_SIZE); - if (fapl == H5I_INVALID_HID) - FAIL_STACK_ERROR + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(my_config, 1, 3, TRUE, TRUE, FALSE, TRUE, 256, MD_FILENAME, NULL); - /* Create a copy of the file creation property list */ - if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) - FAIL_STACK_ERROR + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, FS_PAGE_SIZE, my_config); + if (fapl == H5I_INVALID_HID) + TEST_ERROR - /* Set file space strategy */ - if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, FALSE, 1) < 0) - FAIL_STACK_ERROR; - if (H5Pset_file_space_page_size(fcpl, FS_PAGE_SIZE) < 0) + if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, FS_PAGE_SIZE)) < 0) { + HDprintf("vfd_swmr_create_fcpl() failed"); FAIL_STACK_ERROR; + } /* Create an HDF5 file with VFD SWMR configured */ if ((fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl)) < 0) FAIL_STACK_ERROR; + /* Get a pointer to the internal file object */ + if (NULL == (f = (H5F_t *)H5VL_object(fid))) + FAIL_STACK_ERROR; + /* Allocate num_entries for the data buffer */ if ((buf = HDcalloc(num_entries, FS_PAGE_SIZE)) == NULL) FAIL_STACK_ERROR; @@ -932,6 +1068,7 @@ test_writer_md(void) index[i].md_file_page_offset = 1 + (num_entries - i) * 5; index[i].length = (uint32_t)FS_PAGE_SIZE; index[i].entry_ptr = &buf[i * FS_PAGE_SIZE]; + index[i].tick_of_last_change = f->shared->tick_num; } /* Update with index and verify info in the metadata file */ @@ -970,8 +1107,10 @@ test_writer_md(void) } /* (B) Update every other entry in the index */ - for (i = 0; i < num_entries; i += 2) + for (i = 0; i < num_entries; i += 2) { index[i].entry_ptr = &buf[i * FS_PAGE_SIZE]; + index[i].tick_of_last_change = f->shared->tick_num; + } /* Update with index and verify info in the metadata file */ /* Also verify that 5 entries will be on the delayed list */ @@ -1007,8 +1146,10 @@ test_writer_md(void) } /* (C) Update every 3 entry in the index */ - for (i = 0; i < num_entries; i += 3) + for (i = 0; i < num_entries; i += 3) { index[i].entry_ptr = &buf[i * FS_PAGE_SIZE]; + index[i].tick_of_last_change = f->shared->tick_num; + } /* Update with index and verify info in the metadata file */ /* Also verify that 4 entries will be on the delayed list */ @@ -1042,7 +1183,9 @@ test_writer_md(void) /* (D) Update two entries in the index */ index[1].entry_ptr = &buf[1 * FS_PAGE_SIZE]; + index[1].tick_of_last_change = f->shared->tick_num; index[5].entry_ptr = &buf[5 * FS_PAGE_SIZE]; + index[5].tick_of_last_change = f->shared->tick_num; /* Update with index and verify info in the metadata file */ /* Also verify that 2 entries will be on the delayed list */ @@ -1202,21 +1345,23 @@ test_reader_md_concur(void) if ((config_writer = HDmalloc(sizeof(*config_writer))) == NULL) FAIL_STACK_ERROR; - /* Set up the VFD SWMR configuration + page buffering */ - fapl_writer = init_vfd_swmr_config_fapl(config_writer, 1, 3, TRUE, 256, MD_FILENAME, FS_PAGE_SIZE); - if (fapl_writer == H5I_INVALID_HID) - FAIL_STACK_ERROR; + /* + * Set up the VFD SWMR configuration + page buffering + */ - /* Create a copy of the file creation property list */ - if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) - FAIL_STACK_ERROR + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config_writer, 1, 3, TRUE, TRUE, FALSE, TRUE, 256, MD_FILENAME, NULL); - /* Set file space strategy */ - if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, FALSE, 1) < 0) - FAIL_STACK_ERROR; + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl_writer = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, FS_PAGE_SIZE, config_writer); + if (fapl_writer == H5I_INVALID_HID) + TEST_ERROR - if (H5Pset_file_space_page_size(fcpl, FS_PAGE_SIZE) < 0) + if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, FS_PAGE_SIZE)) < 0) { + HDprintf("vfd_swmr_create_fcpl() failed"); FAIL_STACK_ERROR; + } /* Create an HDF5 file with VFD SWMR configured */ if ((fid_writer = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl_writer)) < 0) @@ -1276,10 +1421,19 @@ test_reader_md_concur(void) if ((config_reader = HDmalloc(sizeof(*config_reader))) == NULL) HDexit(EXIT_FAILURE); - /* Set up the VFD SWMR configuration as reader + page buffering */ - fapl_reader = init_vfd_swmr_config_fapl(config_reader, 1, 3, FALSE, 256, MD_FILENAME, FS_PAGE_SIZE); + /* + * Set up the VFD SWMR configuration as reader + page buffering + */ + + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config_reader, 1, 3, FALSE, TRUE, FALSE, TRUE, 256, MD_FILENAME, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl_reader = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, FS_PAGE_SIZE, config_reader); + if (fapl_reader == H5I_INVALID_HID) - HDexit(EXIT_FAILURE); + TEST_ERROR /* Open the test file as reader */ if ((fid_reader = H5Fopen(FILENAME, H5F_ACC_RDONLY, fapl_reader)) < 0) @@ -1479,6 +1633,9 @@ test_reader_md_concur(void) if ((fid_writer = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl_writer)) < 0) FAIL_STACK_ERROR; + /* Get the file pointer */ + file_writer = H5VL_object(fid_writer); + /* Send notification 1 to reader to start verfication */ notify = 1; if (HDwrite(parent_pfd[1], ¬ify, sizeof(int)) < 0) @@ -1544,11 +1701,9 @@ test_reader_md_concur(void) index[i].md_file_page_offset = 1 + (num_entries - i) * 5; index[i].length = (uint32_t)FS_PAGE_SIZE; index[i].entry_ptr = &buf[i * FS_PAGE_SIZE]; + index[i].tick_of_last_change = file_writer->shared->tick_num; } - /* Get the file pointer */ - file_writer = H5VL_object(fid_writer); - /* Update the metadata file with the index */ if (H5F_update_vfd_swmr_metadata_file(file_writer, num_entries, index) < 0) TEST_ERROR; @@ -1605,8 +1760,10 @@ test_reader_md_concur(void) /* Update 3 entries in the index */ num_entries = 3; - for (i = 0; i < num_entries; i++) + for (i = 0; i < num_entries; i++) { index[i].entry_ptr = &buf[i * FS_PAGE_SIZE]; + index[i].tick_of_last_change = file_writer->shared->tick_num; + } /* Update the metadata file with the index */ if (H5F_update_vfd_swmr_metadata_file(file_writer, num_entries, index) < 0) @@ -1658,8 +1815,10 @@ test_reader_md_concur(void) /* Update 5 entries in the index */ num_entries = 5; - for (i = 0; i < num_entries; i++) + for (i = 0; i < num_entries; i++) { index[i].entry_ptr = &buf[i * FS_PAGE_SIZE]; + index[i].tick_of_last_change = file_writer->shared->tick_num; + } /* Update the metadata file with the index */ if (H5F_update_vfd_swmr_metadata_file(file_writer, num_entries, index) < 0) @@ -1816,16 +1975,10 @@ test_multiple_file_opens_concur(void) TESTING("EOT queue entries when opening files concurrently with VFD SWMR"); - /* Create a copy of the file creation property list */ - if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) - FAIL_STACK_ERROR - - /* Set file space strategy */ - if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, FALSE, 1) < 0) - FAIL_STACK_ERROR; - - if (H5Pset_file_space_page_size(fcpl, FS_PAGE_SIZE) < 0) + if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, FS_PAGE_SIZE)) < 0) { + HDprintf("vfd_swmr_create_fcpl() failed"); FAIL_STACK_ERROR; + } /* Create file A */ if ((fid1 = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, H5P_DEFAULT)) < 0) @@ -1886,7 +2039,14 @@ test_multiple_file_opens_concur(void) HDexit(EXIT_FAILURE); /* Set the VFD SWMR configuration in fapl_writer + page buffering */ - fapl_writer = init_vfd_swmr_config_fapl(config_writer, 1, 3, TRUE, 256, MD_FILENAME2, FS_PAGE_SIZE); + + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config_writer, 1, 3, TRUE, TRUE, FALSE, TRUE, 256, MD_FILENAME2, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl_writer = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, FS_PAGE_SIZE, config_writer); + if (fapl_writer == H5I_INVALID_HID) HDexit(EXIT_FAILURE); @@ -1948,8 +2108,13 @@ test_multiple_file_opens_concur(void) if ((config1 = HDmalloc(sizeof(*config1))) == NULL) FAIL_STACK_ERROR - /* Set the VFD SWMR configuration in fapl1 + page buffering */ - fapl1 = init_vfd_swmr_config_fapl(config1, 7, 10, TRUE, 256, MD_FILENAME, FS_PAGE_SIZE); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config1, 7, 10, TRUE, TRUE, FALSE, TRUE, 256, MD_FILENAME, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl1 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, FS_PAGE_SIZE, config1); + if (fapl1 == H5I_INVALID_HID) FAIL_STACK_ERROR @@ -1986,8 +2151,13 @@ test_multiple_file_opens_concur(void) if ((config2 = HDmalloc(sizeof(*config2))) == NULL) FAIL_STACK_ERROR - /* Set the VFD SWMR configuration in fapl2 + page buffering */ - fapl2 = init_vfd_swmr_config_fapl(config2, 1, 3, FALSE, 256, MD_FILENAME2, FS_PAGE_SIZE); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config2, 1, 3, FALSE, TRUE, FALSE, TRUE, 256, MD_FILENAME2, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl2 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, FS_PAGE_SIZE, config2); + if (fapl2 == H5I_INVALID_HID) FAIL_STACK_ERROR @@ -2120,21 +2290,24 @@ test_disable_enable_eot_concur(void) if ((config_writer = HDmalloc(sizeof(*config_writer))) == NULL) FAIL_STACK_ERROR; - /* Set up the VFD SWMR configuration + page buffering */ - fapl_writer = init_vfd_swmr_config_fapl(config_writer, 1, 3, TRUE, 256, MD_FILENAME, FS_PAGE_SIZE); - if (fapl_writer == H5I_INVALID_HID) - FAIL_STACK_ERROR; + /* + * Set up the VFD SWMR configuration + page buffering + */ - /* Create a copy of the file creation property list */ - if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) - FAIL_STACK_ERROR + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config_writer, 1, 3, TRUE, TRUE, FALSE, TRUE, 256, MD_FILENAME, NULL); - /* Set file space strategy */ - if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, FALSE, 1) < 0) - FAIL_STACK_ERROR; + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl_writer = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, FS_PAGE_SIZE, config_writer); - if (H5Pset_file_space_page_size(fcpl, FS_PAGE_SIZE) < 0) - FAIL_STACK_ERROR; + if (fapl_writer == H5I_INVALID_HID) + FAIL_STACK_ERROR + + if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, FS_PAGE_SIZE)) < 0) { + HDprintf("vfd_swmr_create_fcpl() failed"); + FAIL_STACK_ERROR + } /* Create an HDF5 file with VFD SWMR configured */ if ((fid_writer = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl_writer)) < 0) @@ -2197,10 +2370,19 @@ test_disable_enable_eot_concur(void) if ((config_reader = HDmalloc(sizeof(*config_reader))) == NULL) HDexit(EXIT_FAILURE); - /* Set up the VFD SWMR configuration as reader + page buffering */ - fapl_reader = init_vfd_swmr_config_fapl(config_reader, 1, 3, FALSE, 256, MD_FILENAME, FS_PAGE_SIZE); + /* + * Set up the VFD SWMR configuration as reader + page buffering + */ + + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config_reader, 1, 3, FALSE, TRUE, FALSE, TRUE, 256, MD_FILENAME, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl_reader = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, FS_PAGE_SIZE, config_reader); + if (fapl_reader == H5I_INVALID_HID) - FAIL_STACK_ERROR; + FAIL_STACK_ERROR /* Open the test file as reader */ if ((fid_reader = H5Fopen(FILENAME, H5F_ACC_RDONLY, fapl_reader)) < 0) @@ -2400,21 +2582,24 @@ test_file_end_tick_concur(void) if ((config_writer = HDmalloc(sizeof(*config_writer))) == NULL) FAIL_STACK_ERROR; - /* Set up the VFD SWMR configuration + page buffering */ - fapl_writer = init_vfd_swmr_config_fapl(config_writer, 1, 3, TRUE, 256, MD_FILENAME, FS_PAGE_SIZE); - if (fapl_writer == H5I_INVALID_HID) - FAIL_STACK_ERROR; + /* + * Set up the VFD SWMR configuration + page buffering + */ - /* Create a copy of the file creation property list */ - if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) - FAIL_STACK_ERROR + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config_writer, 1, 3, TRUE, TRUE, FALSE, TRUE, 256, MD_FILENAME, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl_writer = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, FS_PAGE_SIZE, config_writer); - /* Set file space strategy */ - if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, FALSE, 1) < 0) + if (fapl_writer == H5I_INVALID_HID) FAIL_STACK_ERROR; - if (H5Pset_file_space_page_size(fcpl, FS_PAGE_SIZE) < 0) + if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, FS_PAGE_SIZE)) < 0) { + HDprintf("vfd_swmr_create_fcpl() failed"); FAIL_STACK_ERROR; + } /* Create an HDF5 file with VFD SWMR configured */ if ((fid_writer = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl_writer)) < 0) @@ -2477,10 +2662,15 @@ test_file_end_tick_concur(void) if ((config_reader = HDmalloc(sizeof(*config_reader))) == NULL) HDexit(EXIT_FAILURE); - /* Set up the VFD SWMR configuration as reader + page buffering */ - fapl_reader = init_vfd_swmr_config_fapl(config_reader, 1, 3, FALSE, 256, MD_FILENAME, FS_PAGE_SIZE); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config_reader, 1, 3, FALSE, TRUE, FALSE, TRUE, 256, MD_FILENAME, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl_reader = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, FS_PAGE_SIZE, config_reader); + if (fapl_reader == H5I_INVALID_HID) - FAIL_STACK_ERROR; + FAIL_STACK_ERROR /* Open the test file as reader */ if ((fid_reader1 = H5Fopen(FILENAME, H5F_ACC_RDONLY, fapl_reader)) < 0) @@ -2667,23 +2857,33 @@ test_multiple_file_opens(void) if ((config2 = HDmalloc(sizeof(*config2))) == NULL) FAIL_STACK_ERROR; - /* Configured as VFD SWMR writer + page buffering */ - fapl1 = init_vfd_swmr_config_fapl(config1, 4, 6, TRUE, 2, MD_FILENAME, 4096); + /* + * Configured as VFD SWMR writer + page buffering + */ + + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config1, 4, 6, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl1 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config1); if (fapl1 == H5I_INVALID_HID) FAIL_STACK_ERROR; - /* Configured as VFD SWMR writer + page buffering */ - fapl2 = init_vfd_swmr_config_fapl(config2, 4, 6, TRUE, 2, MD_FILENAME2, 4096); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config2, 4, 6, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME2, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl2 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config2); + if (fapl2 == H5I_INVALID_HID) FAIL_STACK_ERROR; - /* Create a copy of the file creation property list */ - if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) - FAIL_STACK_ERROR - - /* Set file space strategy */ - if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, FALSE, 1) < 0) + if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, 4096)) < 0) { + HDprintf("vfd_swmr_create_fcpl() failed"); FAIL_STACK_ERROR; + } /* Create a file without VFD SWMR */ if ((fid = H5Fcreate(FNAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) @@ -2854,13 +3054,10 @@ test_same_file_opens(void) if ((config2 = HDmalloc(sizeof(*config2))) == NULL) FAIL_STACK_ERROR; - /* Create a copy of the file creation property list */ - if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) + if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, 4096)) < 0) { + HDprintf("vfd_swmr_create_fcpl() failed"); FAIL_STACK_ERROR - - /* Set file space strategy */ - if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, FALSE, 1) < 0) - FAIL_STACK_ERROR; + } /* * Tests for first column @@ -2874,8 +3071,17 @@ test_same_file_opens(void) if (H5Fclose(fid) < 0) FAIL_STACK_ERROR; - /* Set the VFD SWMR configuration in fapl1 + page buffering */ - fapl1 = init_vfd_swmr_config_fapl(config1, 4, 10, TRUE, 2, MD_FILENAME, 4096); + /* + * Set the VFD SWMR configuration in fapl1 + page buffering + */ + + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config1, 4, 10, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl1 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config1); + if (fapl1 == H5I_INVALID_HID) FAIL_STACK_ERROR; @@ -2893,8 +3099,17 @@ test_same_file_opens(void) if (H5Fclose(fid2) < 0) FAIL_STACK_ERROR; - /* Set the VFD SWMR configuration in fapl2 + page buffering */ - fapl2 = init_vfd_swmr_config_fapl(config2, 3, 8, FALSE, 3, MD_FILENAME, 4096); + /* + * Set the VFD SWMR configuration in fapl2 + page buffering + */ + + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config2, 3, 8, FALSE, TRUE, FALSE, TRUE, 3, MD_FILENAME, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl2 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config2); + if (fapl2 == H5I_INVALID_HID) FAIL_STACK_ERROR; @@ -2939,8 +3154,18 @@ test_same_file_opens(void) * Tests for second column */ - /* Set up as VFD SWMR reader + page buffering */ - fapl1 = init_vfd_swmr_config_fapl(config1, 4, 10, FALSE, 2, MD_FILENAME, 4096); + + /* + * Set up as VFD SWMR reader + page buffering + */ + + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config1, 4, 10, FALSE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl1 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config1); + if (fapl1 == H5I_INVALID_HID) FAIL_STACK_ERROR; @@ -2967,8 +3192,17 @@ test_same_file_opens(void) if ((fid = H5Fopen(FILENAME, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR; - /* Set up as VFD SWMR writer + page buffering */ - fapl1 = init_vfd_swmr_config_fapl(config1, 4, 10, TRUE, 2, MD_FILENAME, 4096); + /* + * Set up as VFD SWMR writer + page buffering + */ + + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config1, 4, 10, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl1 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config1); + if (fapl1 == H5I_INVALID_HID) FAIL_STACK_ERROR; @@ -3014,8 +3248,17 @@ test_same_file_opens(void) if ((fid = H5Fopen(FILENAME, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR; - /* Set up as VFD SWMR writer + page buffering */ - fapl1 = init_vfd_swmr_config_fapl(config1, 4, 10, TRUE, 2, MD_FILENAME, 4096); + /* + * Set up as VFD SWMR writer + page buffering + */ + + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config1, 4, 10, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl1 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config1); + if (fapl1 == H5I_INVALID_HID) FAIL_STACK_ERROR; @@ -3216,28 +3459,52 @@ test_enable_disable_eot(void) if ((config3 = HDmalloc(sizeof(*config3))) == NULL) FAIL_STACK_ERROR; - /* Configured first file as VFD SWMR writer + page buffering */ - fapl1 = init_vfd_swmr_config_fapl(config1, 4, 6, TRUE, 2, MD_FILENAME, 4096); + /* + * Configured first file as VFD SWMR writer + page buffering + */ + + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config1, 4, 6, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl1 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config1); + if (fapl1 == H5I_INVALID_HID) FAIL_STACK_ERROR; - /* Configured second file as VFD SWMR writer + page buffering */ - fapl2 = init_vfd_swmr_config_fapl(config2, 4, 6, TRUE, 2, MD_FILENAME2, 4096); + /* + * Configured second file as VFD SWMR writer + page buffering + */ + + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config2, 4, 6, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME2, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl2 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config2); + if (fapl2 == H5I_INVALID_HID) FAIL_STACK_ERROR; - /* Configured third file as VFD SWMR writer + page buffering */ - fapl3 = init_vfd_swmr_config_fapl(config3, 4, 6, TRUE, 2, MD_FILENAME3, 4096); + /* + * Configured third file as VFD SWMR writer + page buffering + */ + + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config3, 4, 6, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME3, NULL); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl3 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config3); + if (fapl3 == H5I_INVALID_HID) FAIL_STACK_ERROR; - /* Create a copy of the file creation property list */ - if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) + if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, 4096)) < 0) { + HDprintf("vfd_swmr_create_fcpl() failed"); FAIL_STACK_ERROR - - /* Set file space strategy */ - if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, FALSE, 1) < 0) - FAIL_STACK_ERROR; + } /* Create a file without VFD SWMR */ if ((fid = H5Fcreate(FNAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) @@ -3425,6 +3692,703 @@ error: } /* test_enable_disable_eot() */ /*------------------------------------------------------------------------- + * Function: verify_updater_flags() + * + * Purpose: This is the helper routine used to verify whether + * "flags" in the updater file is as expected. + * + * Return: 0 if test is sucessful + * 1 if test fails + * + * Programmer: Vailin Choi; October 2021 + * + *------------------------------------------------------------------------- + */ +static herr_t +verify_updater_flags(char *ud_name, uint16_t expected_flags) +{ + FILE* ud_fp; /* Updater file pointer */ + uint16_t flags; + size_t ret; /* Return value */ + + + /* Open the updater file */ + if((ud_fp = HDfopen(ud_name, "r")) == NULL) + FAIL_STACK_ERROR; + + /* Seek to the position of "flags" in the updater file's header */ + if(HDfseek(ud_fp, (HDoff_t)UD_HD_FLAGS_OFFSET, SEEK_SET) < 0) + FAIL_STACK_ERROR; + + /* Read "flags" from the updater file */ + if((ret = HDfread(&flags, UD_SIZE_2, 1, ud_fp)) != (size_t)1) + FAIL_STACK_ERROR; + + if (flags != expected_flags) + TEST_ERROR; + + if (HDfclose(ud_fp) < 0) + FAIL_STACK_ERROR; + + return 0; + +error: + return 1; + +} /* verify_updater_flags() */ + +/*------------------------------------------------------------------------- + * Function: test_updater_flags + * + * Purpose: Verify "flags" in the updater file is as expected for + * file creation. + * + * Return: 0 if test is sucessful + * 1 if test fails + * + * Programmer: Vailin Choi; October 2021 + * + *------------------------------------------------------------------------- + */ +static unsigned +test_updater_flags(void) +{ + hid_t fid = -1; /* File ID */ + hid_t fcpl = -1; /* File creation property list ID */ + hid_t fapl = -1; /* File access property list ID */ + hid_t file_fapl = -1; /* File access property list ID associated with the file */ + H5F_vfd_swmr_config_t *config = NULL; /* Configuration for VFD SWMR */ + H5F_vfd_swmr_config_t *file_config = NULL; /* Configuration for VFD SWMR */ + uint64_t seq_num = 0; /* Sequence number for updater file */ + uint64_t i = 0; /* Local index variable */ + char namebuf[H5F__MAX_VFD_SWMR_FILE_NAME_LEN]; /* Updater file path */ + h5_stat_t sb; /* Info returned by stat system call */ + + TESTING("VFD SWMR updater file flags"); + + /* Should succeed without VFD SWMR configured */ + if ((fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR; + + /* Close the file */ + if (H5Fclose(fid) < 0) + FAIL_STACK_ERROR; + + /* Allocate memory for the configuration structure */ + if ((config = (H5F_vfd_swmr_config_t *)HDmalloc(sizeof(H5F_vfd_swmr_config_t))) == NULL) + FAIL_STACK_ERROR; + if ((file_config = (H5F_vfd_swmr_config_t *)HDmalloc(sizeof(H5F_vfd_swmr_config_t))) == NULL) + FAIL_STACK_ERROR; + + /* + * Configured as VFD SWMR writer + page buffering + generate updater files + */ + + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config, 4, 7, TRUE, TRUE, TRUE, TRUE, 2, MD_FILENAME, UD_FILENAME); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config); + + if (fapl == H5I_INVALID_HID) + TEST_ERROR + + if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, 4096)) < 0) { + HDprintf("vfd_swmr_create_fcpl() failed"); + FAIL_STACK_ERROR + } + + if ((fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl)) < 0) + TEST_ERROR; + + /* Get the file's file access property list */ + if ((file_fapl = H5Fget_access_plist(fid)) < 0) + FAIL_STACK_ERROR; + + /* Retrieve the VFD SWMR configuration from file_fapl */ + if (H5Pget_vfd_swmr_config(file_fapl, file_config) < 0) + TEST_ERROR; + + /* Verify the retrieved info is the same as config1 */ + if (HDmemcmp(config, file_config, sizeof(H5F_vfd_swmr_config_t)) != 0) + TEST_ERROR; + + /* Verify the first updater file: "flags" field and file size */ + HDsprintf(namebuf, "%s.%lu", UD_FILENAME, seq_num); + + /* Verify "flags" of the first updater file */ + if(verify_updater_flags(namebuf, CREATE_METADATA_FILE_ONLY_FLAG) < 0) + TEST_ERROR; + + /* Check updater file size */ + if (HDstat(namebuf, &sb) == 0 && sb.st_size != H5F_UD_HEADER_SIZE) + TEST_ERROR; + + /* Closing */ + if (H5Fclose(fid) < 0) + FAIL_STACK_ERROR; + + /* Look for the last updater file */ + for (seq_num = 0; ; seq_num++) { + HDsprintf(namebuf, "%s.%lu", UD_FILENAME, seq_num); + if (HDaccess(namebuf, F_OK) != 0) + break; + } + HDsprintf(namebuf, "%s.%lu", UD_FILENAME, seq_num-1); + + /* Verify "flags" of the last updater file */ + if(verify_updater_flags(namebuf, FINAL_UPDATE_FLAG) < 0) + TEST_ERROR; + + if (H5Pclose(file_fapl) < 0) + FAIL_STACK_ERROR; + if (H5Pclose(fapl) < 0) + FAIL_STACK_ERROR; + if (H5Pclose(fcpl) < 0) + FAIL_STACK_ERROR; + + /* Remove updater files */ + for (i = 0; i < seq_num; i++) { + HDsprintf(namebuf, "%s.%lu", UD_FILENAME, i); + HDremove(namebuf); + } + + /* Free buffers */ + if (config) + HDfree(config); + if (file_config) + HDfree(file_config); + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY + { + H5Pclose(fapl); + H5Pclose(file_fapl); + H5Pclose(fcpl); + H5Fclose(fid); + } + H5E_END_TRY; + if (config) + HDfree(config); + if (file_config) + HDfree(file_config); + + return 1; +} /* test_updater_flags() */ + +/*------------------------------------------------------------------------- + * Function: test_updater_flags_same_file_opens() + * + * Purpose: Verify "flags" in the updater file is as expected for + * multiple opens of the same file. + * + * Return: 0 if test is sucessful + * 1 if test fails + * + * Programmer: Vailin Choi; October 2021 + * + *------------------------------------------------------------------------- + */ +static unsigned +test_updater_flags_same_file_opens(void) +{ + hid_t fid = -1; /* File ID */ + hid_t fid2 = -1; /* File ID */ + hid_t fcpl = -1; /* File creation property list ID */ + hid_t fapl1 = -1; /* File access property list ID */ + H5F_vfd_swmr_config_t *config1 = NULL; /* Configuration for VFD SWMR */ + uint64_t seq_num = 0; /* Sequence number for updater file */ + uint64_t i = 0; /* Local index variable */ + char namebuf[H5F__MAX_VFD_SWMR_FILE_NAME_LEN]; /* Updater file path */ + + TESTING("VFD SWMR updater file flags for multiple opens of the same file"); + + /* Should succeed without VFD SWMR configured */ + if ((fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR; + + /* Close the file */ + if (H5Fclose(fid) < 0) + FAIL_STACK_ERROR; + + /* Allocate memory for the configuration structure */ + if ((config1 = HDmalloc(sizeof(*config1))) == NULL) + FAIL_STACK_ERROR; + + if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, 4096)) < 0) { + HDprintf("vfd_swmr_create_fcpl() failed"); + FAIL_STACK_ERROR + } + + /* Create the test file */ + if ((fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, H5P_DEFAULT)) < 0) + TEST_ERROR; + + /* Close the file */ + if (H5Fclose(fid) < 0) + FAIL_STACK_ERROR; + + /* + * Set the VFD SWMR configuration in fapl1 + page buffering + */ + + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config1, 4, 10, TRUE, TRUE, TRUE, TRUE, 2, MD_FILENAME, UD_FILENAME); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl1 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config1); + + if (fapl1 == H5I_INVALID_HID) + FAIL_STACK_ERROR; + + /* Open the file as VFD SWMR writer */ + /* Keep the file open */ + if ((fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl1)) < 0) + TEST_ERROR; + + /* Open the same file again as VFD SWMR writer */ + /* Should succeed: 1st open--VFD SWMR writer, 2nd open--VFD SWMR writer */ + if ((fid2 = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl1)) < 0) + TEST_ERROR; + + /* Close the second file open */ + if (H5Fclose(fid2) < 0) + FAIL_STACK_ERROR; + + + /* Verify the first updater file for first file open */ + HDsprintf(namebuf, "%s.%lu", UD_FILENAME, seq_num); + + /* Verify "flags" of the first updater file is 0*/ + if(verify_updater_flags(namebuf, 0) < 0) + TEST_ERROR; + + /* Look for the last updater file */ + for (seq_num = 0; ; seq_num++) { + HDsprintf(namebuf, "%s.%lu", UD_FILENAME, seq_num); + if (HDaccess(namebuf, F_OK) != 0) + break; + } + HDsprintf(namebuf, "%s.%lu", UD_FILENAME, seq_num-1); + + /* Verify "flags" of the last updater file is 0 */ + if(verify_updater_flags(namebuf, 0) < 0) + TEST_ERROR; + + /* Close the 1st open file */ + if (H5Fclose(fid) < 0) + FAIL_STACK_ERROR; + + /* Look for the last updater file */ + for (seq_num = 0; ; seq_num++) { + HDsprintf(namebuf, "%s.%lu", UD_FILENAME, seq_num); + if (HDaccess(namebuf, F_OK) != 0) + break; + } + HDsprintf(namebuf, "%s.%lu", UD_FILENAME, seq_num-1); + + /* Verify "flags" of the last updater file after closing file */ + if(verify_updater_flags(namebuf, FINAL_UPDATE_FLAG) < 0) + TEST_ERROR; + + /* Clean up updater files */ + for (i = 0; i < seq_num; i++) { + HDsprintf(namebuf, "%s.%lu", UD_FILENAME, i); + HDremove(namebuf); + } + + if (H5Pclose(fcpl) < 0) + FAIL_STACK_ERROR; + + /* Free buffers */ + if (config1) + HDfree(config1); + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY + { + H5Pclose(fapl1); + H5Pclose(fcpl); + H5Fclose(fid); + H5Fclose(fid2); + } + H5E_END_TRY; + if (config1) + HDfree(config1); + return 1; +} /* test_updater_flags_same_file_opens() */ + + +/*------------------------------------------------------------------------- + * Function: clean_chk_ud_files() + * + * Purpose: This is the helper routine used to clean up + * the checksum file and the updater files. + * + * Return: void + * + * Programmer: Vailin Choi; October 2021 + * + *------------------------------------------------------------------------- + */ +static void +clean_chk_ud_files(char *md_file_path, char *updater_file_path) +{ + char chk_name[1024 + 4]; + char ud_name[1024 + 4]; + uint64_t i; + + /* Name of the checksum file: <md_file_path>.chk */ + HDsprintf(chk_name, "%s.chk", md_file_path); + + /* Remove the checksum file if exists. + If not, the callback will just continue appending + checksums to the existing file */ + if(HDaccess(chk_name, F_OK) == 0) { + HDremove(chk_name); + } + + /* Remove all the updater files if exist: <updater_file_path>.<i> */ + for(i = 0; ; i++) { + sprintf(ud_name, "%s.%lu", updater_file_path, i); + if(HDaccess(ud_name, F_OK) != 0) + break; + HDremove(ud_name); + } + +} /* clean_chk_ud_files() */ + + +/*------------------------------------------------------------------------- + * Function: verify_ud_chk() + * + * Purpose: This is the helper routine used by + * test_updater_generate_md_checksums() to verify + * contents of the checksum file and the updater files. + * --verify the sequence number in each updater's file header + * corresponds to the ith sequence number of the updater + * file name. + * --verify the tick number in each updater's file header + * corresponds to the tick number stored in the checksum file + * --verify the change_list_len in each updater's file header + * is consistent with num_change_list_entries in each updater's + * change list header + * + * Return: 0 if test is sucessful + * 1 if test fails + * + * Programmer: Vailin Choi; October 2021 + * + *------------------------------------------------------------------------- + */ +static herr_t +verify_ud_chk(char *md_file_path, char *ud_file_path) +{ + char chk_name[1024 + 4]; /* Checksum file name */ + char ud_name[1024 + 4]; /* Updater file name */ + FILE* chk_fp; /* Checksum file pointer */ + FILE* ud_fp; /* Updater file pointer */ + uint64_t ud_seq_num; /* Sequence number in the updater file */ + uint64_t chk_ud_seq_num; /* Updater sequence number in the checksum file */ + uint64_t i; /* Local index variable */ + long size = 0; /* Size of the file */ + size_t change_list_len; /* change_list_len in the updater file header */ + uint32_t num_change_list_entries; /* num_change_list_entries in the updater change list header */ + + /* Open the checksum file */ + HDsprintf(chk_name, "%s.chk", md_file_path); + if((chk_fp = HDfopen(chk_name, "r")) == NULL) + FAIL_STACK_ERROR; + + for(i = 0; ; i++) { + /* Generate updater file name: <ud_file_path>.<i> */ + HDsprintf(ud_name, "%s.%lu", ud_file_path, i); + + /* Open the updater file */ + if ((ud_fp = HDfopen(ud_name, "r")) == NULL) + break; + else { + /* Seek to the position of the sequence number in the updater file's header */ + if(HDfseek(ud_fp, (off_t)UD_HD_SEQ_NUM_OFFSET, SEEK_SET) < 0) + FAIL_STACK_ERROR; + + /* Read the sequence number from the updater file */ + if(HDfread(&ud_seq_num, UD_SIZE_8, 1, ud_fp) != 1) + FAIL_STACK_ERROR; + + /* Compare the sequence number with i */ + if(ud_seq_num != i) + TEST_ERROR; + + /* Read change_list_len from updater file's header */ + if(HDfseek(ud_fp, (off_t)UD_HD_CHANGE_LIST_LEN_OFFSET, SEEK_SET) < 0) + FAIL_STACK_ERROR; + + if(HDfread(&change_list_len, UD_SIZE_8, 1, ud_fp) != 1) + FAIL_STACK_ERROR; + + if(i != 0) { + + /* Read num_change_list_entries from updater file's change list */ + if(HDfseek(ud_fp, (off_t)UD_CL_NUM_CHANGE_LIST_ENTRIES_OFFSET, SEEK_SET) < 0) + FAIL_STACK_ERROR; + + if(HDfread(&num_change_list_entries, UD_SIZE_4, 1, ud_fp) != 1) + FAIL_STACK_ERROR; + + if(num_change_list_entries == 0) { + if(change_list_len != H5F_UD_CL_SIZE(0)) + TEST_ERROR; + } else { + if (change_list_len != H5F_UD_CL_SIZE(num_change_list_entries)) + TEST_ERROR + } + } + + /* Close the updater file */ + if(HDfclose(ud_fp) < 0) + FAIL_STACK_ERROR; + + /* Read the updater sequence number from checksum file */ + if(HDfread(&chk_ud_seq_num, UD_SIZE_8, 1, chk_fp) != 1) + FAIL_STACK_ERROR; + + /* Compare sequence number in updater file with sequence number in checksum file */ + if (ud_seq_num != chk_ud_seq_num) + TEST_ERROR; + + /* Advance checksum file to the next sequence number */ + if(HDfseek(chk_fp, (off_t)UD_SIZE_4, SEEK_CUR) < 0) + FAIL_STACK_ERROR; + } + } + + /* Get the size of the chksum file */ + if ((size = HDftell(chk_fp)) < 0) + FAIL_STACK_ERROR; + + /* Size of sequence number and checksum in the checksum file */ + if((unsigned)size != (i * (UD_SIZE_8 + UD_SIZE_4))) + TEST_ERROR; + + return 0; + +error: + return (-1); + +} /* verify_ud_chk() */ + +/*------------------------------------------------------------------------- + * Function: md_ck_cb() + * + * Purpose: This is the callback function used by + * test_updater_generate_md_checksums() when the + * H5F_ACS_GENERATE_MD_CK_CB_NAME property is set in fapl. + * --Opens and read the metadata file into a buffer. + * --Generate checksum for the metadata file + * --Write the tick number and the checksum to the checksum file + * + * Return: 0 if test is sucessful + * 1 if test fails + * + * Programmer: Vailin Choi; October 2021 + * + *------------------------------------------------------------------------- + */ +static herr_t +md_ck_cb(char *md_file_path, uint64_t updater_seq_num) +{ + FILE* md_fp = NULL; /* Metadata file pointer */ + FILE* chk_fp = NULL; /* Checksum file pointer */ + long size = 0; /* File size returned from HDftell() */ + void *buf = NULL; /* Buffer for holding the metadata file content */ + uint32_t chksum = 0; /* The checksum generated for the metadata file */ + char chk_name[1024 + 4]; /* Buffer for the checksum file name */ + size_t ret; /* Return value */ + + /* Open the metadata file */ + if((md_fp = HDfopen(md_file_path, "r")) == NULL) + FAIL_STACK_ERROR; + + /* Set file pointer at end of file.*/ + if(HDfseek(md_fp, 0, SEEK_END) < 0) + FAIL_STACK_ERROR; + + /* Get the current position of the file pointer.*/ + if ((size = HDftell(md_fp)) < 0) + FAIL_STACK_ERROR; + + if(size != 0) { + + HDrewind(md_fp); + + if((buf = HDmalloc((size_t)size)) == NULL) + FAIL_STACK_ERROR; + + /* Read the metadata file to buf */ + if ((ret = HDfread(buf, 1, (size_t)size, md_fp)) != (size_t)size) + FAIL_STACK_ERROR; + + /* Calculate checksum of the metadata file */ + chksum = H5_checksum_metadata(buf, (size_t)size, 0); + } + + /* Close the metadata file */ + if(md_fp && HDfclose(md_fp) < 0) + FAIL_STACK_ERROR; + + /* + * Checksum file + */ + + /* Generate checksum file name: <md_file_path>.chk */ + HDsprintf(chk_name, "%s.chk", md_file_path); + + /* Open checksum file for append */ + if((chk_fp = HDfopen(chk_name, "a")) == NULL) + FAIL_STACK_ERROR; + + /* Write the updater sequence number to the checksum file */ + if((ret = HDfwrite(&updater_seq_num, sizeof(uint64_t), 1, chk_fp)) != 1) + FAIL_STACK_ERROR; + + /* Write the checksum to the checksum file */ + if((ret = HDfwrite(&chksum, sizeof(uint32_t), 1, chk_fp)) != 1) + FAIL_STACK_ERROR; + + /* Close the checksum file */ + if(chk_fp && HDfclose(chk_fp) != 0) + FAIL_STACK_ERROR; + + if(buf) + HDfree(buf); + + return 0; + +error: + if(buf) + HDfree(buf); + if(md_fp) + HDfclose(md_fp); + if(chk_fp) + HDfclose(chk_fp); + + return -1; +} /* md_ck_cb() */ + +/*------------------------------------------------------------------------- + * Function: test_updater_generate_md_checksums() + * + * Purpose: It enables the generation of checksums for the metadata file + * created by the writer end of tick function. + * It also verifies the contents of the checksum file and the + * updater files. + * + * The test is invoked when the file is created via H5Fcreate() + * and via H5Fopen(). + * + * Return: 0 if test is sucessful + * 1 if test fails + * + * Programmer: Vailin Choi; October 2021 + * + * Note: It is important to clean up the checksum file and the updater files. + * + *------------------------------------------------------------------------- + */ +static unsigned +test_updater_generate_md_checksums(hbool_t file_create) +{ + hid_t fid = -1; /* File ID */ + hid_t fcpl = -1; /* File creation property list ID */ + hid_t fapl = -1; /* File access property list ID */ + H5F_vfd_swmr_config_t config; /* Configuration for VFD SWMR */ + H5F_generate_md_ck_cb_t cb_info; /* Callback */ + + if(file_create) { + TESTING("VFD SWMR updater generate checksums for metadata file with H5Fcreate"); + } else { + TESTING("VFD SWMR updater generate checksums for metadata file with H5Fopen"); + } + + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(&config, 4, 7, TRUE, TRUE, TRUE, TRUE, 2, MD_FILE, UD_FILE); + + /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ + fapl = vfd_swmr_create_fapl(TRUE, TRUE, FALSE, 4096, &config); + + if (fapl == H5I_INVALID_HID) + TEST_ERROR + + if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, 4096)) < 0) { + HDprintf("vfd_swmr_create_fcpl() failed"); + FAIL_STACK_ERROR + } + + /* Set up callback to generate checksums for updater's metadata files */ + cb_info.func = md_ck_cb; + + /* Activate private property to generate checksums for updater's metadata file */ + H5Pset(fapl, H5F_ACS_GENERATE_MD_CK_CB_NAME, &cb_info); + + /* Use file creation or file open for testing */ + if(file_create) { + if((fid = H5Fcreate(FILENAME4, H5F_ACC_TRUNC, fcpl, fapl)) < 0) + TEST_ERROR; + } else { + fid = H5Fcreate(FILENAME4, H5F_ACC_TRUNC, fcpl, H5P_DEFAULT); + H5Fclose(fid); + + fid = H5Fopen(FILENAME4, H5F_ACC_RDWR, fapl); + } + + /* Close the file */ + if (H5Fclose(fid) < 0) + FAIL_STACK_ERROR; + + if (H5Pclose(fapl) < 0) + FAIL_STACK_ERROR; + if (H5Pclose(fcpl) < 0) + FAIL_STACK_ERROR; + + /* Verify contents of checksum file and updater files */ + if(verify_ud_chk(config.md_file_path, config.updater_file_path) < 0) + TEST_ERROR; + + /* It's important to clean up the chechsum and updater files. */ + clean_chk_ud_files(config.md_file_path, config.updater_file_path); + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Pclose(fapl); + H5Pclose(fcpl); + H5Fclose(fid); + } + H5E_END_TRY; + + /* It's important to clean up the chechsum and updater files. */ + clean_chk_ud_files(config.md_file_path, config.updater_file_path); + + return 1; + +} /* test_updater_generate_md_checksums() */ + + +/*------------------------------------------------------------------------- * Function: main() * * Purpose: Main function for VFD SWMR tests. @@ -3481,9 +4445,15 @@ main(void) PUTS_ERROR("Can't get VFD-dependent fapl") } + /* Add nfs/updater testing in this routine */ nerrors += test_fapl(); if (use_file_locking) { + nerrors += test_updater_flags(); + nerrors += test_updater_flags_same_file_opens(); + nerrors += test_updater_generate_md_checksums(TRUE); + nerrors += test_updater_generate_md_checksums(FALSE); + nerrors += test_shadow_index_lookup(); nerrors += test_file_fapl(); diff --git a/test/vfd_swmr_addrem_writer.c b/test/vfd_swmr_addrem_writer.c index f115d2e..a2982fd 100644 --- a/test/vfd_swmr_addrem_writer.c +++ b/test/vfd_swmr_addrem_writer.c @@ -94,8 +94,9 @@ open_skeleton(const char *filename, unsigned verbose) if ((config = HDcalloc(1, sizeof(*config))) == NULL) goto error; - /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ - init_vfd_swmr_config(config, 4, 5, TRUE, TRUE, 128, "./rw-shadow"); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config, 4, 5, TRUE, TRUE, FALSE, TRUE, 128, "rw-shadow", NULL); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ if ((fapl = vfd_swmr_create_fapl(TRUE, TRUE, FALSE, 4096, config)) < 0) diff --git a/test/vfd_swmr_attrdset_writer.c b/test/vfd_swmr_attrdset_writer.c index f445321..a722f44 100644 --- a/test/vfd_swmr_attrdset_writer.c +++ b/test/vfd_swmr_attrdset_writer.c @@ -1979,8 +1979,9 @@ main(int argc, char **argv) TEST_ERROR; } - /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ - init_vfd_swmr_config(&config, 4, 7, writer, true, 128, "./attrdset-shadow"); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(&config, 4, 7, writer, TRUE, FALSE, TRUE, 128, "./attrdset-shadow", NULL); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ if ((fapl = vfd_swmr_create_fapl(true, s.use_vfd_swmr, true, 4096, &config)) < 0) { diff --git a/test/vfd_swmr_bigset_writer.c b/test/vfd_swmr_bigset_writer.c index 77c7b26..928f7c7 100644 --- a/test/vfd_swmr_bigset_writer.c +++ b/test/vfd_swmr_bigset_writer.c @@ -2470,9 +2470,9 @@ main(int argc, char **argv) continue; } - /* 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, s.writer, s.flush_raw_data, 128, - "./bigset-shadow-%zu", i); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(&config, s.tick_len, s.max_lag, s.writer, TRUE, FALSE, s.flush_raw_data, 128, "./bigset-shadow-%zu", NULL, i); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ if ((fapl = vfd_swmr_create_fapl(true, s.use_vfd_swmr, true, s.page_buf_size, &config)) < 0) { diff --git a/test/vfd_swmr_common.c b/test/vfd_swmr_common.c index cfe93aa..90abeed 100644 --- a/test/vfd_swmr_common.c +++ b/test/vfd_swmr_common.c @@ -345,10 +345,10 @@ await_signal(hid_t fid) /* Revised support routines that can be used for all VFD SWMR integration tests */ -/* Initialize fields in config with the input parameters */ void init_vfd_swmr_config(H5F_vfd_swmr_config_t *config, uint32_t tick_len, uint32_t max_lag, hbool_t writer, - hbool_t flush_raw_data, uint32_t md_pages_reserved, const char *md_file_fmtstr, ...) + hbool_t maintain_metadata_file, hbool_t generate_updater_files, hbool_t flush_raw_data, + uint32_t md_pages_reserved, const char *md_file_fmtstr, const char *updater_file_path, ...) { va_list ap; @@ -360,13 +360,20 @@ init_vfd_swmr_config(H5F_vfd_swmr_config_t *config, uint32_t tick_len, uint32_t config->tick_len = tick_len; config->max_lag = max_lag; config->writer = writer; + config->maintain_metadata_file = maintain_metadata_file; + config->generate_updater_files = generate_updater_files; config->flush_raw_data = flush_raw_data; config->md_pages_reserved = md_pages_reserved; - HDva_start(ap, md_file_fmtstr); + HDva_start(ap, updater_file_path); + evsnprintf(config->md_file_path, sizeof(config->md_file_path), md_file_fmtstr, ap); + HDva_end(ap); + if(config->generate_updater_files && updater_file_path != NULL) + HDstrcpy(config->updater_file_path, updater_file_path); + } /* init_vfd_swmr_config() */ /* Initialize the log file path in config, this function should be called after init_vfd_swmr_config. */ diff --git a/test/vfd_swmr_common.h b/test/vfd_swmr_common.h index f5981a5..42569be 100644 --- a/test/vfd_swmr_common.h +++ b/test/vfd_swmr_common.h @@ -73,9 +73,11 @@ H5TEST_DLL void await_signal(hid_t); H5TEST_DLL hid_t vfd_swmr_create_fapl(bool use_latest_format, bool use_vfd_swmr, bool only_meta_pages, size_t page_buf_size, H5F_vfd_swmr_config_t *config); -H5TEST_DLL void init_vfd_swmr_config(H5F_vfd_swmr_config_t *config, uint32_t tick_len, uint32_t max_lag, - 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(H5F_vfd_swmr_config_t *config, uint32_t tick_len, uint32_t max_lag, hbool_t writer, + hbool_t maintain_metadata_file, hbool_t generate_updater_files, hbool_t flush_raw_data, + uint32_t md_pages_reserved, const char *md_file_fmtstr, + const char *updater_file_path, ...) H5_ATTR_FORMAT(printf, 9, 11); H5TEST_DLL void init_vfd_swmr_log(H5F_vfd_swmr_config_t *config, const char *log_file_fmtstr, ...) H5_ATTR_FORMAT(printf, 2, 3); diff --git a/test/vfd_swmr_dsetchks_writer.c b/test/vfd_swmr_dsetchks_writer.c index d264ca9..3cf43f9 100644 --- a/test/vfd_swmr_dsetchks_writer.c +++ b/test/vfd_swmr_dsetchks_writer.c @@ -2302,8 +2302,9 @@ main(int argc, char **argv) TEST_ERROR; } - /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ - init_vfd_swmr_config(&config, 4, 7, writer, s.flush_raw_data, 128, "./dsetchks-shadow"); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(&config, 4, 7, writer, TRUE, FALSE, s.flush_raw_data, 128, "./dsetchks-shadow", NULL); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ if ((fapl = vfd_swmr_create_fapl(true, s.use_vfd_swmr, true, 4096, &config)) < 0) { diff --git a/test/vfd_swmr_dsetops_writer.c b/test/vfd_swmr_dsetops_writer.c index 3704c44..d999d64 100644 --- a/test/vfd_swmr_dsetops_writer.c +++ b/test/vfd_swmr_dsetops_writer.c @@ -1888,8 +1888,9 @@ main(int argc, char **argv) TEST_ERROR; } - /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ - init_vfd_swmr_config(&config, 4, 7, writer, s.flush_raw_data, 128, "./dsetops-shadow"); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(&config, 4, 7, writer, TRUE, FALSE, s.flush_raw_data, 128, "./dsetops-shadow", NULL); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ if ((fapl = vfd_swmr_create_fapl(true, s.use_vfd_swmr, true, 4096, &config)) < 0) { diff --git a/test/vfd_swmr_generator.c b/test/vfd_swmr_generator.c index 16b1d4b..1c549ca 100644 --- a/test/vfd_swmr_generator.c +++ b/test/vfd_swmr_generator.c @@ -125,8 +125,9 @@ gen_skeleton(const char *filename, hbool_t verbose, hbool_t vfd_swmr_write, int if ((config = HDcalloc(1, sizeof(*config))) == NULL) return -1; - /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ - init_vfd_swmr_config(config, 4, 10, vfd_swmr_write, TRUE, 128, "generator-shadow"); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config, 4, 10, vfd_swmr_write, TRUE, FALSE, TRUE, 128, "generator-shadow", NULL); } /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ diff --git a/test/vfd_swmr_gfail_writer.c b/test/vfd_swmr_gfail_writer.c index 430ed89..2be58e2 100644 --- a/test/vfd_swmr_gfail_writer.c +++ b/test/vfd_swmr_gfail_writer.c @@ -544,8 +544,9 @@ main(int argc, char **argv) TEST_ERROR; } - /* 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, TRUE, 128, "./group-shadow"); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(&config, s.tick_len, s.max_lag, writer, TRUE, FALSE, TRUE, 128, "./group-shadow", NULL); /* 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 diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c index 3342b40..18f3199 100644 --- a/test/vfd_swmr_gperf_writer.c +++ b/test/vfd_swmr_gperf_writer.c @@ -2786,8 +2786,9 @@ main(int argc, char **argv) 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"); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(&config, s.tick_len, s.max_lag, writer, TRUE, FALSE, FALSE, 128, "./group-shadow", NULL); /* If the log flag is on, create the log file log-test under the current directory. */ if (s.glog == true) diff --git a/test/vfd_swmr_group_writer.c b/test/vfd_swmr_group_writer.c index 5881300..af46f3d 100644 --- a/test/vfd_swmr_group_writer.c +++ b/test/vfd_swmr_group_writer.c @@ -5011,8 +5011,9 @@ main(int argc, char **argv) TEST_ERROR; } - /* 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, TRUE, 128, "./group-shadow"); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(&config, s.tick_len, s.max_lag, writer, TRUE, FALSE, TRUE, 128, "./group-shadow", NULL); /* 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 diff --git a/test/vfd_swmr_reader.c b/test/vfd_swmr_reader.c index 6265cae..2b960c13 100644 --- a/test/vfd_swmr_reader.c +++ b/test/vfd_swmr_reader.c @@ -319,8 +319,9 @@ read_records(const char *filename, hbool_t verbose, FILE *verbose_file, unsigned goto error; } - /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ - init_vfd_swmr_config(config, 4, 5, FALSE, TRUE, 128, "./rw-shadow"); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config, 4, 5, FALSE, TRUE, FALSE, TRUE, 128, "rw-shadow", NULL); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ if ((fapl = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config)) < 0) { diff --git a/test/vfd_swmr_remove_reader.c b/test/vfd_swmr_remove_reader.c index 4389b05..18dbb62 100644 --- a/test/vfd_swmr_remove_reader.c +++ b/test/vfd_swmr_remove_reader.c @@ -303,8 +303,9 @@ read_records(const char *filename, unsigned verbose, unsigned long nseconds, uns if ((config = HDcalloc(1, sizeof(*config))) == NULL) goto error; - /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ - init_vfd_swmr_config(config, 4, 5, FALSE, TRUE, 128, "./rw-shadow"); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config, 4, 5, FALSE, TRUE, FALSE, TRUE, 128, "rw-shadow", NULL); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ if ((fapl = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config)) < 0) { diff --git a/test/vfd_swmr_remove_writer.c b/test/vfd_swmr_remove_writer.c index 8df8fa8..41c2300 100644 --- a/test/vfd_swmr_remove_writer.c +++ b/test/vfd_swmr_remove_writer.c @@ -86,8 +86,9 @@ open_skeleton(const char *filename, unsigned verbose, unsigned old H5_ATTR_UNUSE if ((config = (H5F_vfd_swmr_config_t *)HDcalloc(1, sizeof(H5F_vfd_swmr_config_t))) == NULL) goto error; - /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ - init_vfd_swmr_config(config, 4, 5, TRUE, TRUE, 128, "./rw-shadow"); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config, 4, 5, TRUE, TRUE, FALSE, TRUE, 128, "rw-shadow", NULL); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ if ((fapl = vfd_swmr_create_fapl(TRUE, TRUE, FALSE, 4096, config)) < 0) diff --git a/test/vfd_swmr_sparse_reader.c b/test/vfd_swmr_sparse_reader.c index 943c375..a737f70 100644 --- a/test/vfd_swmr_sparse_reader.c +++ b/test/vfd_swmr_sparse_reader.c @@ -207,8 +207,9 @@ read_records(const char *filename, unsigned verbose, unsigned long nrecords, uns if ((config = HDcalloc(1, sizeof(H5F_vfd_swmr_config_t))) == NULL) goto error; - /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ - init_vfd_swmr_config(config, 4, 5, FALSE, TRUE, 128, "./rw-shadow"); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config, 4, 5, FALSE, TRUE, FALSE, TRUE, 128, "rw-shadow", NULL); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ if ((fapl = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config)) < 0) { diff --git a/test/vfd_swmr_sparse_writer.c b/test/vfd_swmr_sparse_writer.c index 56d19f3..f473249 100644 --- a/test/vfd_swmr_sparse_writer.c +++ b/test/vfd_swmr_sparse_writer.c @@ -86,8 +86,9 @@ open_skeleton(const char *filename, unsigned verbose) if ((config = (H5F_vfd_swmr_config_t *)HDcalloc(1, sizeof(H5F_vfd_swmr_config_t))) == NULL) goto error; - /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ - init_vfd_swmr_config(config, 4, 5, TRUE, TRUE, 128, "./rw-shadow"); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config, 4, 5, TRUE, TRUE, FALSE, TRUE, 128, "rw-shadow", NULL); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ if ((fapl = vfd_swmr_create_fapl(TRUE, TRUE, FALSE, 4096, config)) < 0) diff --git a/test/vfd_swmr_vlstr_reader.c b/test/vfd_swmr_vlstr_reader.c index fa9d7b4..2554207 100644 --- a/test/vfd_swmr_vlstr_reader.c +++ b/test/vfd_swmr_vlstr_reader.c @@ -115,8 +115,9 @@ main(int argc, char **argv) if (argc > 0) errx(EXIT_FAILURE, "unexpected command-line arguments"); - /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ - init_vfd_swmr_config(&config, 4, 7, false, TRUE, 128, "./vlstr-shadow"); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(&config, 4, 7, false, TRUE, FALSE, TRUE, 128, "./vlstr-shadow", NULL); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ fapl = vfd_swmr_create_fapl(true, use_vfd_swmr, sel == TEST_OOB, 4096, &config); diff --git a/test/vfd_swmr_vlstr_writer.c b/test/vfd_swmr_vlstr_writer.c index 4f7376e..e3905e8 100644 --- a/test/vfd_swmr_vlstr_writer.c +++ b/test/vfd_swmr_vlstr_writer.c @@ -184,8 +184,9 @@ main(int argc, char **argv) if (argc > 0) errx(EXIT_FAILURE, "unexpected command-line arguments"); - /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ - init_vfd_swmr_config(&config, 4, 7, true, TRUE, 128, "./vlstr-shadow"); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(&config, 4, 7, true, TRUE, FALSE, TRUE, 128, "./vlstr-shadow", NULL); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ fapl = vfd_swmr_create_fapl(true, use_vfd_swmr, sel == TEST_OOB, 4096, &config); diff --git a/test/vfd_swmr_writer.c b/test/vfd_swmr_writer.c index 4693554..0fb5fe8 100644 --- a/test/vfd_swmr_writer.c +++ b/test/vfd_swmr_writer.c @@ -88,8 +88,9 @@ open_skeleton(const char *filename, hbool_t verbose, FILE *verbose_file, unsigne if ((config = (H5F_vfd_swmr_config_t *)HDcalloc(1, sizeof(H5F_vfd_swmr_config_t))) == NULL) return -1; - /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ - init_vfd_swmr_config(config, 4, 5, TRUE, TRUE, 128, "./rw-shadow"); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(config, 4, 5, TRUE, TRUE, FALSE, TRUE, 128, "rw-shadow", NULL); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ if ((fapl = vfd_swmr_create_fapl(TRUE, TRUE, FALSE, 4096, config)) < 0) diff --git a/test/vfd_swmr_zoo_writer.c b/test/vfd_swmr_zoo_writer.c index 13794d9..d40f2d9 100644 --- a/test/vfd_swmr_zoo_writer.c +++ b/test/vfd_swmr_zoo_writer.c @@ -473,8 +473,9 @@ main(int argc, char **argv) parse_command_line_options(argc, argv); - /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ - init_vfd_swmr_config(&vfd_swmr_config, TICK_LEN, 7, writer, TRUE, 128, "./zoo-shadow"); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(&vfd_swmr_config, TICK_LEN, 7, writer, TRUE, FALSE, TRUE, 128, "./zoo-shadow", NULL); /* ? turn off use latest format argument via 1st argument? since later on it reset to early format */ /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ -- cgit v0.12 From 68ddc3029a1e55cb1f995c0b69233c7c06ff94da Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 17 Nov 2021 17:30:05 +0000 Subject: Committing clang-format changes --- src/H5Fint.c | 42 ++-- src/H5Fpkg.h | 56 +++--- src/H5Fprivate.h | 200 +++++++++---------- src/H5Fpublic.h | 10 +- src/H5Ftest.c | 2 +- src/H5Fvfd_swmr.c | 278 +++++++++++++------------- src/H5Pfapl.c | 26 +-- test/page_buffer.c | 10 +- test/vfd_swmr.c | 433 ++++++++++++++++++++-------------------- test/vfd_swmr_addrem_writer.c | 4 +- test/vfd_swmr_bigset_writer.c | 3 +- test/vfd_swmr_common.c | 17 +- test/vfd_swmr_common.h | 10 +- test/vfd_swmr_dsetchks_writer.c | 3 +- test/vfd_swmr_gfail_writer.c | 3 +- test/vfd_swmr_gperf_writer.c | 7 +- test/vfd_swmr_group_writer.c | 3 +- test/vfd_swmr_reader.c | 4 +- test/vfd_swmr_remove_reader.c | 4 +- test/vfd_swmr_remove_writer.c | 4 +- test/vfd_swmr_sparse_reader.c | 4 +- test/vfd_swmr_sparse_writer.c | 4 +- test/vfd_swmr_writer.c | 4 +- 23 files changed, 566 insertions(+), 565 deletions(-) diff --git a/src/H5Fint.c b/src/H5Fint.c index 8518785..3dae17e 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -1835,26 +1835,26 @@ done: H5F_t * H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) { - H5F_t * file = NULL; /*the success return value */ - H5F_shared_t * shared = NULL; /*shared part of `file' */ - H5FD_t * lf = NULL; /*file driver part of `shared' */ - unsigned tent_flags; /*tentative flags */ - H5FD_class_t * drvr; /*file driver class info */ - H5P_genplist_t * a_plist; /*file access property list */ - H5F_close_degree_t fc_degree; /*file close degree */ - size_t page_buf_size; - unsigned page_buf_min_meta_perc = 0; - unsigned page_buf_min_raw_perc = 0; - hbool_t set_flag = FALSE; /* Set the status_flags in the superblock */ - hbool_t clear = FALSE; /* Clear the status_flags */ - hbool_t evict_on_close; /* Evict on close value from plist */ - hbool_t use_file_locking = TRUE; /* Using file locks? */ - hbool_t ci_load = FALSE; /* Whether MDC ci load requested */ - 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 */ - H5F_generate_md_ck_cb_t cb_info = {NULL}; - H5F_t * ret_value = NULL; /* Actual return value */ + H5F_t * file = NULL; /*the success return value */ + H5F_shared_t * shared = NULL; /*shared part of `file' */ + H5FD_t * lf = NULL; /*file driver part of `shared' */ + unsigned tent_flags; /*tentative flags */ + H5FD_class_t * drvr; /*file driver class info */ + H5P_genplist_t * a_plist; /*file access property list */ + H5F_close_degree_t fc_degree; /*file close degree */ + size_t page_buf_size; + unsigned page_buf_min_meta_perc = 0; + unsigned page_buf_min_raw_perc = 0; + hbool_t set_flag = FALSE; /* Set the status_flags in the superblock */ + hbool_t clear = FALSE; /* Clear the status_flags */ + hbool_t evict_on_close; /* Evict on close value from plist */ + hbool_t use_file_locking = TRUE; /* Using file locks? */ + hbool_t ci_load = FALSE; /* Whether MDC ci load requested */ + 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 */ + H5F_generate_md_ck_cb_t cb_info = {NULL}; + H5F_t * ret_value = NULL; /* Actual return value */ FUNC_ENTER_NOAPI(NULL) @@ -2117,7 +2117,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) /* Initialization for VFD SWMR writer and reader */ if (1 == shared->nrefs) { /* Private property for VFD SWMR testing: generate checksum for metadata file */ - if(cb_info.func) + if (cb_info.func) shared->generate_md_ck_cb = cb_info.func; if (H5F_vfd_swmr_init(file, file_create) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "file open fail with initialization for VFD SWMR") diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 31630ef..ca26941 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -456,35 +456,35 @@ struct H5F_shared_t { uint32_t old_mdf_idx_entries_used; /* Metadata file and updater file for VFD SWMR writer */ - int vfd_swmr_md_fd; /* POSIX: file descriptor for the - * metadata file or -1 if the metadata file - * is not currently open. - * The vfd_swmr_config.generate_updater_files - * is FALSE. - */ - /* NFS: - * The vfd_swmr_config.generate_updater_files - * is TRUE and: - * --if vfd_swmr_config.writer is FALSE, - * this field is the file descriptor of the local - * copy of the metadata file, or -1 if the local - * copy is not currently open. - * --if vfd_swmr_config.writer is TRUE, this field - * is not used and is set to -1. - */ + int vfd_swmr_md_fd; /* POSIX: file descriptor for the + * metadata file or -1 if the metadata file + * is not currently open. + * The vfd_swmr_config.generate_updater_files + * is FALSE. + */ + /* NFS: + * The vfd_swmr_config.generate_updater_files + * is TRUE and: + * --if vfd_swmr_config.writer is FALSE, + * this field is the file descriptor of the local + * copy of the metadata file, or -1 if the local + * copy is not currently open. + * --if vfd_swmr_config.writer is TRUE, this field + * is not used and is set to -1. + */ H5F_generate_md_ck_t generate_md_ck_cb; - /* For testing only: - * Invoke the user-defined callback if exists to - * generate checksum for the metadata file - */ - - haddr_t vfd_swmr_md_eoa; /* POSIX: eoa for the metadata - * file - */ - uint64_t updater_seq_num;/* Sequence number of the next updater file to be - * genereated. This field must be initialized to zero, - * and incremented after each updater file is generated. - */ + /* For testing only: + * Invoke the user-defined callback if exists to + * generate checksum for the metadata file + */ + + haddr_t vfd_swmr_md_eoa; /* POSIX: eoa for the metadata + * file + */ + uint64_t updater_seq_num; /* Sequence number of the next updater file to be + * genereated. This field must be initialized to zero, + * and incremented after each updater file is generated. + */ /* Free space manager for the metadata file */ H5FS_t * fs_man_md; /* Free-space manager */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 05ace44..796242b 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -650,10 +650,8 @@ uint64_decode(uint8_t **pp) /* hbool_t maintain_metadata_file = */ FALSE, \ /* hbool_t generate_updater_files = */ FALSE, \ /* hbool_t flush_raw_data = */ FALSE, /* int32_t md_pages_reserved = */ 0, \ - /* int32_t pb_expansion_threshold = */ 0, \ - /* char md_file_path[] = */ "", \ - /* char updater_file_path[] = */ "", \ - /* char log_file_path[] = */ "" \ + /* int32_t pb_expansion_threshold = */ 0, /* char md_file_path[] = */ "", \ + /* char updater_file_path[] = */ "", /* char log_file_path[] = */ "" \ } /* For VFD SWMR testing only: private property to generate checksum for metadata file via callback */ @@ -796,57 +794,57 @@ uint64_decode(uint8_t **pp) */ /* Updater file header */ -#define H5F_UD_VERSION 0 /* Version of the updater file format */ -#define H5F_UD_HEADER_OFF 0 /* Updater file header offset */ -#define H5F_UD_HEADER_MAGIC "VUDH" /* Updater file header magic */ -#define H5F_SIZEOF_CHKSUM 4 /* Size of checksum */ +#define H5F_UD_VERSION 0 /* Version of the updater file format */ +#define H5F_UD_HEADER_OFF 0 /* Updater file header offset */ +#define H5F_UD_HEADER_MAGIC "VUDH" /* Updater file header magic */ +#define H5F_SIZEOF_CHKSUM 4 /* Size of checksum */ /* Flags in the updater file header */ -#define CREATE_METADATA_FILE_ONLY_FLAG 0x0001 -#define FINAL_UPDATE_FLAG 0x0002 +#define CREATE_METADATA_FILE_ONLY_FLAG 0x0001 +#define FINAL_UPDATE_FLAG 0x0002 /* Size of updater file header */ -#define H5F_UD_HEADER_SIZE \ - (H5_SIZEOF_MAGIC /* Signature */ \ - + 2 /* Version number */ \ - + 2 /* Flags */ \ - + 4 /* Page size */ \ - + 8 /* Sequence number */ \ - + 8 /* Tick number */ \ - + 8 /* Chnage list offset */ \ - + 8 /* Change list length */ \ - + H5F_SIZEOF_CHKSUM /* Updater file header checksum */ \ +#define H5F_UD_HEADER_SIZE \ + (H5_SIZEOF_MAGIC /* Signature */ \ + + 2 /* Version number */ \ + + 2 /* Flags */ \ + + 4 /* Page size */ \ + + 8 /* Sequence number */ \ + + 8 /* Tick number */ \ + + 8 /* Chnage list offset */ \ + + 8 /* Change list length */ \ + + H5F_SIZEOF_CHKSUM /* Updater file header checksum */ \ ) -#define H5F_UD_CL_MAGIC "VUCL" /* Updater file change list magic */ +#define H5F_UD_CL_MAGIC "VUCL" /* Updater file change list magic */ /* Size of an updater file change list entry */ -#define H5F_UD_CL_ENTRY_SIZE \ - (4 /* Updater file page offset */ \ - + 4 /* Metadata file page offset */ \ - + 4 /* HDF5 file page offset */ \ - + 4 /* Length */ \ - + H5F_SIZEOF_CHKSUM /* Updater file change list entry checksum */ \ +#define H5F_UD_CL_ENTRY_SIZE \ + (4 /* Updater file page offset */ \ + + 4 /* Metadata file page offset */ \ + + 4 /* HDF5 file page offset */ \ + + 4 /* Length */ \ + + H5F_SIZEOF_CHKSUM /* Updater file change list entry checksum */ \ ) /* Size of updater file change list */ -#define H5F_UD_CL_SIZE(N) /* N is number of change list entries */ \ - (H5_SIZEOF_MAGIC /* Signature */ \ - + 8 /* Tick num */ \ - + 4 /* Metadata file header updater file page offset */ \ - + 4 /* Metadata file header length */ \ - + 4 /* Metadata file header checksum */ \ - + 4 /* Metadata file index updater file page offset */ \ - + 8 /* Metadata file index metadata file offset */ \ - + 4 /* Metadata file index length */ \ - + 4 /* Metadata file index checksum */ \ - + 4 /* Number of change list entries */ \ - + (N * H5F_UD_CL_ENTRY_SIZE) /* Change list entries */ \ - + H5F_SIZEOF_CHKSUM /* Updater file change list checksum */ \ +#define H5F_UD_CL_SIZE(N) /* N is number of change list entries */ \ + (H5_SIZEOF_MAGIC /* Signature */ \ + + 8 /* Tick num */ \ + + 4 /* Metadata file header updater file page offset */ \ + + 4 /* Metadata file header length */ \ + + 4 /* Metadata file header checksum */ \ + + 4 /* Metadata file index updater file page offset */ \ + + 8 /* Metadata file index metadata file offset */ \ + + 4 /* Metadata file index length */ \ + + 4 /* Metadata file index checksum */ \ + + 4 /* Number of change list entries */ \ + + (N * H5F_UD_CL_ENTRY_SIZE) /* Change list entries */ \ + + H5F_SIZEOF_CHKSUM /* Updater file change list checksum */ \ ) -/* - * For VFD SWMR testing only: +/* + * For VFD SWMR testing only: */ /* Callback routine to generate checksum for metadata file specified by md_path */ @@ -854,7 +852,7 @@ typedef herr_t (*H5F_generate_md_ck_t)(char *md_path, uint64_t updater_seq_num); /* Structure for "generate checksum callback" private property */ typedef struct H5F_generate_md_ck_cb_t { - H5F_generate_md_ck_t func; + H5F_generate_md_ck_t func; } H5F_generate_md_ck_cb_t; /****************************/ @@ -936,7 +934,7 @@ typedef enum H5F_prefix_open_t { * struct H5F_vfd_swmr_updater_cl_entry_t * * An array of instances of H5F_vfd_swmr_updater_cl_entry_t of length equal to - * the number of metadata pages and multi-page metadata entries modified in + * the number of metadata pages and multi-page metadata entries modified in * the past tick is used ot aseemble the assoicated data in preparation for * writing an updater file. * @@ -950,13 +948,13 @@ typedef enum H5F_prefix_open_t { * entry_image_ud_file_page_offset: Page offset of the entry in the * updater file, or 0 if undefined. * - * entry_image_md_file_page_offset: Page offset of the entry in the + * entry_image_md_file_page_offset: Page offset of the entry in the * metadata file, or 0 if undefined. * * entry_image_h5_file_page_offset: Page offset of the entry in the * HDF5 file. In this case, a page offset of zero is valid, * so we havd no easy marker for an invalid value. Instead, - * presume that this field is invalid if the entry_image_md_file_page_offset + * presume that this field is invalid if the entry_image_md_file_page_offset * is invalid. * * entry_image_len: The size of the metadata page or multi-page metadata @@ -966,12 +964,12 @@ typedef enum H5F_prefix_open_t { *---------------------------------------------------------------------------- */ typedef struct H5F_vfd_swmr_updater_cl_entry_t { - void *entry_image_ptr; - uint32_t entry_image_ud_file_page_offset; - uint32_t entry_image_md_file_page_offset; - uint32_t entry_image_h5_file_page_offset; - size_t entry_image_len; - uint32_t entry_image_checksum; + void * entry_image_ptr; + uint32_t entry_image_ud_file_page_offset; + uint32_t entry_image_md_file_page_offset; + uint32_t entry_image_h5_file_page_offset; + size_t entry_image_len; + uint32_t entry_image_checksum; } H5F_vfd_swmr_updater_cl_entry_t; /*---------------------------------------------------------------------------- @@ -983,35 +981,35 @@ typedef struct H5F_vfd_swmr_updater_cl_entry_t { * * Updater file header related fields: * - * version: Version of the updater file format to be used. At present this + * version: Version of the updater file format to be used. At present this * must be zero. * * flags: This field contains any flags to be set in the updater file header. * Currently defined flags are: * * 0x0001 CREATE_METADATA_FILE_ONLY_FLAG - * If set, the auxiliary process should create the metadata file, + * If set, the auxiliary process should create the metadata file, * but leave it empty. This flag may only be set if sequence_num * is zero. * * 0x0002 FINAL_UPDATE_FLAG - * If set, the VFD SWMR writer is closing the target file, and this - * updater contains the final set of updates to the metadata file. - * On receipt, the auxiliary process should apply the enclosed + * If set, the VFD SWMR writer is closing the target file, and this + * updater contains the final set of updates to the metadata file. + * On receipt, the auxiliary process should apply the enclosed * changes to the metadata file, unlink it, and exit. * * sequence_num: This field contains the sequence number of this updater file. - * The sequence number of the first updater file must be zero, and + * The sequence number of the first updater file must be zero, and * this sequence number must be increased by one for each new updater - * file. Note that under some circumstances, the sequence number + * file. Note that under some circumstances, the sequence number * will not match the tick_num. * * tick_num: Number of the tick for which this updater file is to be generated. - * This value should match that of the index used to fill our this - * structure. + * This value should match that of the index used to fill our this + * structure. * - * header_image_ptr: void pointer to the buffer in which the - * updater file header is constructed. + * header_image_ptr: void pointer to the buffer in which the + * updater file header is constructed. * This field is NULL if the buffer is undefined. * * header_image_len: This field contains the length of the updater file @@ -1020,8 +1018,8 @@ typedef struct H5F_vfd_swmr_updater_cl_entry_t { * change_list_image_ptr: void pointer to a buffer containing the on disk image * of the updater file change list, or NULL if that buffer does not exist. * - * change_list_offset: This field contains the offset in bytes of the change - * list in the updater file. This will typically be the offset of + * change_list_offset: This field contains the offset in bytes of the change + * list in the updater file. This will typically be the offset of * the first byte in the updater file after the header. * * change_list_len: This field contains the size in bytes of the on disk image @@ -1029,21 +1027,21 @@ typedef struct H5F_vfd_swmr_updater_cl_entry_t { * * Updater File Change List Related Fields: * - * The updater file change list is a section of the updater file that details the - * locations and lengths of all metadata file entries that must be modified for - * this tick. + * The updater file change list is a section of the updater file that details the + * locations and lengths of all metadata file entries that must be modified for + * this tick. * * md_file_header_image_ptr: void pointer to a buffer containing the on disk image * of the metadata file header as updated for tick_num. * - * md_file_header_ud_file_page_offset: This field contains the updater file - * page offset of the metadata file header image. Note that we do + * md_file_header_ud_file_page_offset: This field contains the updater file + * page offset of the metadata file header image. Note that we do * not store the metadata file page offset of the metadata file header, * as it is always written to offset 0 in the metadata file. * - * md_file_header_len: This field contains the size of the metadata file header + * md_file_header_len: This field contains the size of the metadata file header * image in bytes. - * + * * md_file_index_image: void pointer to a buffer containing the on disk image * of the metadata file index as updated for tick_num. * @@ -1051,53 +1049,53 @@ typedef struct H5F_vfd_swmr_updater_cl_entry_t { * metadata file index in the metadata file in bytes. * * This value will either be the size of the metadata file header - * (if the metadata file header and index are adjacent), or a page + * (if the metadata file header and index are adjacent), or a page * aligned value. * - * md_file_index_ud_file_page_offset: This field contains the page offset of the + * md_file_index_ud_file_page_offset: This field contains the page offset of the * metadata file index in the updater file. * - * md_file_index_len: This field contains the size of the metadata file index in + * md_file_index_len: This field contains the size of the metadata file index in * bytes. * - * num_change_list_entries: This field contains the number of entries in the + * num_change_list_entries: This field contains the number of entries in the * array of H5F_vfd_swmr_updater_cl_ entry_t whose base address - * is stored in the change_list field below. This value is also the - * number of metadata pages and multi-page metadata entries that have + * is stored in the change_list field below. This value is also the + * number of metadata pages and multi-page metadata entries that have * been modified in the past tick - * + * * If this field is zero, there is no change list, and the change_list * field below is NULL. * - * change_list: This field contains the base address of a dynamically allocated - * array of H5F_vfd_swmr_updater_cl_entry_t of length num_change_list_entries, + * change_list: This field contains the base address of a dynamically allocated + * array of H5F_vfd_swmr_updater_cl_entry_t of length num_change_list_entries, * or NULL if undefined. * *---------------------------------------------------------------------------- */ typedef struct H5F_vfd_swmr_updater_t { /* Updater file header related fields */ - uint16_t version; - uint16_t flags; - uint32_t page_size; - uint64_t sequence_number; - uint64_t tick_num; - void *header_image_ptr; - size_t header_image_len; - void *change_list_image_ptr; - uint64_t change_list_offset; - size_t change_list_len; + uint16_t version; + uint16_t flags; + uint32_t page_size; + uint64_t sequence_number; + uint64_t tick_num; + void * header_image_ptr; + size_t header_image_len; + void * change_list_image_ptr; + uint64_t change_list_offset; + size_t change_list_len; /* Updater file change list related fields */ - void *md_file_header_image_ptr; - uint32_t md_file_header_image_chksum; - uint32_t md_file_header_ud_file_page_offset; - size_t md_file_header_len; - void *md_file_index_image_ptr; - uint32_t md_file_index_image_chksum; - uint64_t md_file_index_md_file_offset; - uint32_t md_file_index_ud_file_page_offset; - size_t md_file_index_len; - uint32_t num_change_list_entries; + void * md_file_header_image_ptr; + uint32_t md_file_header_image_chksum; + uint32_t md_file_header_ud_file_page_offset; + size_t md_file_header_len; + void * md_file_index_image_ptr; + uint32_t md_file_index_image_chksum; + uint64_t md_file_index_md_file_offset; + uint32_t md_file_index_ud_file_page_offset; + size_t md_file_index_len; + uint32_t num_change_list_entries; H5F_vfd_swmr_updater_cl_entry_t *change_list; } H5F_vfd_swmr_updater_t; diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h index 5e0473a..7120085 100644 --- a/src/H5Fpublic.h +++ b/src/H5Fpublic.h @@ -277,20 +277,20 @@ typedef herr_t (*H5F_flush_cb_t)(hid_t object_id, void *udata); * * maintain_metadata_file * A boolean flag indicating whether the writer should create and - * maintain the metadata file. Note that this field is only revelant + * maintain the metadata file. Note that this field is only revelant * if the above writer flag is TRUE. * If this flag is TRUE, the writer must create and maintain the * metadata file in the location specified in the md_file_path. - * Observe that at least one of maintain_metadata_file and + * Observe that at least one of maintain_metadata_file and * generate_updater_files fields must be TRUE if writer is TRUE. * * generate_updater_files * A boolean flag indicating whether the writer should generate a * sequence of updater files describing how the metadata file * should be updated at the end of each tick. - * If the flag is TRUE, all modifications to the metadata file - * (including its creation) are described in an ordered sequence of - * updater files. These files are read in order by auxiliary processes, + * If the flag is TRUE, all modifications to the metadata file + * (including its creation) are described in an ordered sequence of + * updater files. These files are read in order by auxiliary processes, * and used to generate local copies of the metadata file as required. * This mechanism exists to allow VFD SWMR to operate on storage * systems that do not support POSIX semantics. diff --git a/src/H5Ftest.c b/src/H5Ftest.c index e9cecc1..f4a89fd 100644 --- a/src/H5Ftest.c +++ b/src/H5Ftest.c @@ -346,7 +346,7 @@ H5F__vfd_swmr_writer_create_open_flush_test(hid_t file_id, hbool_t file_create) HGOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to stat the metadata file") if (file_create) { /* Creating file */ - if(stat_buf.st_size != 0) + if (stat_buf.st_size != 0) HGOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "metadata file should be empty for file create") } else { /* Opening or flushing the file */ diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index fe07e74..2ac5e6c 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -25,7 +25,7 @@ /****************/ #include "H5Fmodule.h" /* This source code file is part of the H5F module */ -#define H5FD_FRIEND /*suppress error about including H5FDpkg */ +#define H5FD_FRIEND /*suppress error about including H5FDpkg */ /***********/ /* Headers */ @@ -108,8 +108,9 @@ static herr_t H5F__vfd_swmr_writer__wait_a_tick(H5F_t *); static herr_t H5F__vfd_swmr_construct_ud_hdr(H5F_vfd_swmr_updater_t *updater); static herr_t H5F__vfd_swmr_construct_ud_cl(H5F_vfd_swmr_updater_t *updater); static herr_t H5F__generate_updater_file(H5F_t *f, uint32_t num_entries, uint16_t flags, - uint8_t *md_file_hdr_image_ptr, size_t md_file_hdr_image_len, - uint8_t *md_file_index_image_ptr, uint64_t md_file_index_offset, size_t md_file_index_image_len); + uint8_t *md_file_hdr_image_ptr, size_t md_file_hdr_image_len, + uint8_t *md_file_index_image_ptr, uint64_t md_file_index_offset, + size_t md_file_index_image_len); /*********************/ /* Package Variables */ @@ -177,12 +178,12 @@ H5FL_DEFINE(eot_queue_entry_t); herr_t H5F_vfd_swmr_init(H5F_t *f, hbool_t file_create) { - hsize_t md_size; /* Size of the metadata file */ - haddr_t hdr_addr; /* Address returned from H5MV_alloc() */ - H5F_shared_t *shared = f->shared; - uint8_t md_idx_image[H5FD_MD_INDEX_SIZE(0)]; /* Buffer for metadata file index */ - uint8_t md_hdr_image[H5FD_MD_HEADER_SIZE]; /* Buffer for metadata file header */ - herr_t ret_value = SUCCEED; /* Return value */ + hsize_t md_size; /* Size of the metadata file */ + haddr_t hdr_addr; /* Address returned from H5MV_alloc() */ + H5F_shared_t *shared = f->shared; + uint8_t md_idx_image[H5FD_MD_INDEX_SIZE(0)]; /* Buffer for metadata file index */ + uint8_t md_hdr_image[H5FD_MD_HEADER_SIZE]; /* Buffer for metadata file header */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -201,8 +202,8 @@ H5F_vfd_swmr_init(H5F_t *f, hbool_t file_create) shared->tick_num = 0; /* Create the metadata file */ - if (((shared->vfd_swmr_md_fd = HDopen(shared->vfd_swmr_config.md_file_path, O_CREAT | O_RDWR | O_TRUNC, - H5_POSIX_CREATE_MODE_RW))) < 0) + if (((shared->vfd_swmr_md_fd = HDopen(shared->vfd_swmr_config.md_file_path, + O_CREAT | O_RDWR | O_TRUNC, 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; @@ -213,7 +214,7 @@ H5F_vfd_swmr_init(H5F_t *f, hbool_t file_create) HDassert(H5F_addr_eq(hdr_addr, H5FD_MD_HEADER_OFF)); shared->writer_index_offset = H5FD_MD_HEADER_SIZE; - shared->vfd_swmr_md_eoa = (haddr_t)md_size; + shared->vfd_swmr_md_eoa = (haddr_t)md_size; /* When opening an existing HDF5 file, create header and empty * index in the metadata file @@ -225,29 +226,27 @@ H5F_vfd_swmr_init(H5F_t *f, hbool_t file_create) if (H5F__vfd_swmr_construct_write_md_hdr(shared, 0, md_hdr_image) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to create header in md"); - } /* For VFD SWMR testing: invoke callback if set to generate metadata file checksum */ - if(shared->generate_md_ck_cb) { - if(shared->generate_md_ck_cb(shared->vfd_swmr_config.md_file_path, shared->updater_seq_num) < 0) + if (shared->generate_md_ck_cb) { + if (shared->generate_md_ck_cb(shared->vfd_swmr_config.md_file_path, shared->updater_seq_num) < 0) HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "error from generate_md_ck_cb()") } /* Generate updater files if configuration indicates so */ - if(shared->vfd_swmr_config.generate_updater_files) { + if (shared->vfd_swmr_config.generate_updater_files) { shared->updater_seq_num = 0; - if(H5F__generate_updater_file(f, 0, file_create ? CREATE_METADATA_FILE_ONLY_FLAG : 0, - md_hdr_image, H5FD_MD_HEADER_SIZE, - md_idx_image, shared->writer_index_offset, H5FD_MD_INDEX_SIZE(0)) < 0) + if (H5F__generate_updater_file(f, 0, file_create ? CREATE_METADATA_FILE_ONLY_FLAG : 0, + md_hdr_image, H5FD_MD_HEADER_SIZE, md_idx_image, + shared->writer_index_offset, H5FD_MD_INDEX_SIZE(0)) < 0) HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "can't generate updater file") } - shared->tick_num = 1; + shared->tick_num = 1; if (H5PB_vfd_swmr__set_tick(shared) < 0) HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "Can't update page buffer current tick") - } else { /* VFD SWMR reader */ @@ -323,8 +322,8 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing) { H5F_shared_t * shared = f->shared; shadow_defree_t *curr; - uint8_t md_idx_image[H5FD_MD_INDEX_SIZE(0)]; /* Buffer for metadata file index */ - uint8_t md_hdr_image[H5FD_MD_HEADER_SIZE]; /* Buffer for metadata file header */ + uint8_t md_idx_image[H5FD_MD_INDEX_SIZE(0)]; /* Buffer for metadata file index */ + uint8_t md_hdr_image[H5FD_MD_HEADER_SIZE]; /* Buffer for metadata file header */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(FAIL) @@ -348,8 +347,8 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing) shared->vfd_swmr_md_fd = -1; /* For VFD SWMR testing: invoke callback if set to generate metadata file checksum */ - if(shared->generate_md_ck_cb) { - if(shared->generate_md_ck_cb(shared->vfd_swmr_config.md_file_path, shared->updater_seq_num) < 0) + if (shared->generate_md_ck_cb) { + if (shared->generate_md_ck_cb(shared->vfd_swmr_config.md_file_path, shared->updater_seq_num) < 0) HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "error from generate_md_ck_cb()") } @@ -370,10 +369,10 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing) HDassert(TAILQ_EMPTY(&shared->shadow_defrees)); - if(shared->vfd_swmr_config.generate_updater_files) { - if(H5F__generate_updater_file(f, 0, FINAL_UPDATE_FLAG, - md_hdr_image, H5FD_MD_HEADER_SIZE, - md_idx_image, shared->writer_index_offset, H5FD_MD_INDEX_SIZE(0)) < 0) + if (shared->vfd_swmr_config.generate_updater_files) { + if (H5F__generate_updater_file(f, 0, FINAL_UPDATE_FLAG, md_hdr_image, H5FD_MD_HEADER_SIZE, + md_idx_image, shared->writer_index_offset, + H5FD_MD_INDEX_SIZE(0)) < 0) HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "can't generate updater file") } } @@ -462,11 +461,11 @@ H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t num_entries, H5FD_vfd_swmr_ H5F_shared_t * shared = f->shared; shadow_defree_t *prev; shadow_defree_t *shadow_defree; - haddr_t md_addr; /* Address in the metadata file */ - uint32_t i; /* Local index variable */ - uint8_t *md_idx_image = NULL; - uint8_t md_hdr_image[H5FD_MD_HEADER_SIZE]; /* Buffer for metadata file header */ - herr_t ret_value = SUCCEED; /* Return value */ + haddr_t md_addr; /* Address in the metadata file */ + uint32_t i; /* Local index variable */ + uint8_t * md_idx_image = NULL; + uint8_t md_hdr_image[H5FD_MD_HEADER_SIZE]; /* Buffer for metadata file header */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -512,7 +511,7 @@ H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t num_entries, H5FD_vfd_swmr_ /* Compute checksum and update the index entry */ index[i].md_file_page_offset = md_addr / shared->fs_page_size; - index[i].checksum = H5_checksum_metadata(index[i].entry_ptr, index[i].length, 0); + index[i].checksum = H5_checksum_metadata(index[i].entry_ptr, index[i].length, 0); #if 0 /* JRM */ HDfprintf(stderr, @@ -530,22 +529,22 @@ H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t num_entries, H5FD_vfd_swmr_ HDassert(shared->fs_page_size == 4096); #endif /* JRM */ - if(shared->vfd_swmr_config.maintain_metadata_file) { + if (shared->vfd_swmr_config.maintain_metadata_file) { /* Seek and write the entry to the metadata file */ if (HDlseek(shared->vfd_swmr_md_fd, (HDoff_t)md_addr, SEEK_SET) < 0) HGOTO_ERROR(H5E_FILE, H5E_SEEKERROR, FAIL, "unable to seek in the metadata file") - if (HDwrite(shared->vfd_swmr_md_fd, index[i].entry_ptr, index[i].length) != (ssize_t)index[i].length) + if (HDwrite(shared->vfd_swmr_md_fd, index[i].entry_ptr, index[i].length) != + (ssize_t)index[i].length) HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "error in writing the page/multi-page entry to metadata file") } - if(!shared->vfd_swmr_config.generate_updater_files) + if (!shared->vfd_swmr_config.generate_updater_files) index[i].entry_ptr = NULL; - } if ((md_idx_image = HDmalloc(H5FD_MD_INDEX_SIZE(num_entries))) == NULL) @@ -572,7 +571,7 @@ H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t num_entries, H5FD_vfd_swmr_ * --remove the associated entries from the list */ - /* if (shared->tick_num <= shared->vfd_swmr_config.max_lag), + /* if (shared->tick_num <= shared->vfd_swmr_config.max_lag), it is too early for any reclamations to be due. */ if (shared->tick_num > shared->vfd_swmr_config.max_lag) { @@ -594,23 +593,21 @@ H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t num_entries, H5FD_vfd_swmr_ } } - /* For VFD SWMR testing: invoke callback if set to generate metadata file checksum */ - if(shared->generate_md_ck_cb) { - if(shared->generate_md_ck_cb(shared->vfd_swmr_config.md_file_path, shared->updater_seq_num) < 0) + if (shared->generate_md_ck_cb) { + if (shared->generate_md_ck_cb(shared->vfd_swmr_config.md_file_path, shared->updater_seq_num) < 0) HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "error from generate_md_ck_cb()") } /* Generate updater files with num_entries */ - if(shared->vfd_swmr_config.generate_updater_files) - if(H5F__generate_updater_file(f, num_entries, 0, - md_hdr_image, H5FD_MD_HEADER_SIZE, - md_idx_image, shared->writer_index_offset, H5FD_MD_INDEX_SIZE(num_entries)) < 0) + if (shared->vfd_swmr_config.generate_updater_files) + if (H5F__generate_updater_file(f, num_entries, 0, md_hdr_image, H5FD_MD_HEADER_SIZE, md_idx_image, + shared->writer_index_offset, H5FD_MD_INDEX_SIZE(num_entries)) < 0) HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "can't generate updater file") done: - if (md_idx_image) + if (md_idx_image) HDfree(md_idx_image); FUNC_LEAVE_NOAPI(ret_value) @@ -1632,8 +1629,8 @@ done: static herr_t H5F__vfd_swmr_construct_write_md_hdr(H5F_shared_t *shared, uint32_t num_entries, uint8_t *image) { - uint8_t *p = NULL; /* Pointer to buffer */ - uint32_t metadata_chksum; /* Computed metadata checksum value */ + uint8_t *p = NULL; /* Pointer to buffer */ + uint32_t metadata_chksum; /* Computed metadata checksum value */ /* Size of header and index */ const size_t hdr_size = H5FD_MD_HEADER_SIZE; ssize_t nwritten; @@ -1665,7 +1662,7 @@ H5F__vfd_swmr_construct_write_md_hdr(H5F_shared_t *shared, uint32_t num_entries, /* Sanity checks on header */ HDassert(p - image == (ptrdiff_t)hdr_size); - if(shared->vfd_swmr_config.maintain_metadata_file) { + if (shared->vfd_swmr_config.maintain_metadata_file) { /* Set to beginning of the file */ if (HDlseek(shared->vfd_swmr_md_fd, H5FD_MD_HEADER_OFF, SEEK_SET) < 0) @@ -1710,7 +1707,7 @@ static herr_t H5F__vfd_swmr_construct_write_md_idx(H5F_shared_t *shared, uint32_t num_entries, struct H5FD_vfd_swmr_idx_entry_t index[], uint8_t *image) { - uint8_t *p = NULL; /* Pointer to buffer */ + uint8_t *p = NULL; /* Pointer to buffer */ uint32_t metadata_chksum; /* Computed metadata checksum value */ /* Size of index */ const size_t idx_size = H5FD_MD_INDEX_SIZE(num_entries); @@ -1757,7 +1754,7 @@ H5F__vfd_swmr_construct_write_md_idx(H5F_shared_t *shared, uint32_t num_entries, /* Verify the md file descriptor exists */ HDassert(shared->vfd_swmr_md_fd >= 0); - if(shared->vfd_swmr_config.maintain_metadata_file) { + if (shared->vfd_swmr_config.maintain_metadata_file) { if (HDlseek(shared->vfd_swmr_md_fd, (HDoff_t)shared->writer_index_offset, SEEK_SET) < 0) HGOTO_ERROR(H5E_VFL, H5E_SEEKERROR, FAIL, "unable to seek in metadata file") @@ -2081,10 +2078,10 @@ H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log_info) static herr_t H5F__vfd_swmr_construct_ud_hdr(H5F_vfd_swmr_updater_t *updater) { - uint8_t *p = NULL; /* Pointer to buffer */ - uint8_t *image = (uint8_t *)updater->header_image_ptr; - uint32_t metadata_chksum; /* Computed metadata checksum value */ - herr_t ret_value = SUCCEED; /* Return value */ + uint8_t *p = NULL; /* Pointer to buffer */ + uint8_t *image = (uint8_t *)updater->header_image_ptr; + uint32_t metadata_chksum; /* Computed metadata checksum value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC_NOERR @@ -2097,7 +2094,8 @@ H5F__vfd_swmr_construct_ud_hdr(H5F_vfd_swmr_updater_t *updater) HDmemcpy(p, H5F_UD_HEADER_MAGIC, (size_t)H5_SIZEOF_MAGIC); p += H5_SIZEOF_MAGIC; - /* Encode version number, flags, page size, sequence number, tick number, change list offset, change list length */ + /* Encode version number, flags, page size, sequence number, tick number, change list offset, change list + * length */ UINT16ENCODE(p, H5F_UD_VERSION); UINT16ENCODE(p, updater->flags); UINT32ENCODE(p, updater->page_size); @@ -2139,11 +2137,11 @@ H5F__vfd_swmr_construct_ud_hdr(H5F_vfd_swmr_updater_t *updater) static herr_t H5F__vfd_swmr_construct_ud_cl(H5F_vfd_swmr_updater_t *updater) { - uint8_t *p = NULL; /* Pointer to buffer */ + uint8_t *p = NULL; /* Pointer to buffer */ uint8_t *image = (uint8_t *)updater->change_list_image_ptr; - uint32_t metadata_chksum; /* Computed metadata checksum value */ - unsigned i; /* Local index variable */ - herr_t ret_value = SUCCEED; /* Return value */ + uint32_t metadata_chksum; /* Computed metadata checksum value */ + unsigned i; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC_NOERR @@ -2166,8 +2164,8 @@ H5F__vfd_swmr_construct_ud_cl(H5F_vfd_swmr_updater_t *updater) UINT32ENCODE(p, updater->md_file_header_len); /* Calculate checksum on the image of the metadata file header */ - updater->md_file_header_image_chksum = H5_checksum_metadata( - updater->md_file_header_image_ptr, (size_t)updater->md_file_header_len, 0); + updater->md_file_header_image_chksum = + H5_checksum_metadata(updater->md_file_header_image_ptr, (size_t)updater->md_file_header_len, 0); /* Encode Metadata File Header Checksum */ UINT32ENCODE(p, updater->md_file_header_image_chksum); @@ -2182,8 +2180,8 @@ H5F__vfd_swmr_construct_ud_cl(H5F_vfd_swmr_updater_t *updater) UINT32ENCODE(p, updater->md_file_index_len); /* Calculate checksum on the image of the metadata file index */ - updater->md_file_index_image_chksum = H5_checksum_metadata( - updater->md_file_index_image_ptr, (size_t)updater->md_file_index_len, 0); + updater->md_file_index_image_chksum = + H5_checksum_metadata(updater->md_file_index_image_ptr, (size_t)updater->md_file_index_len, 0); /* Encode Metadata File Index Checksum */ UINT32ENCODE(p, updater->md_file_index_image_chksum); @@ -2221,7 +2219,7 @@ H5F__vfd_swmr_construct_ud_cl(H5F_vfd_swmr_updater_t *updater) * --determine num_change_list entries * --allocate buffers * --construct on disk image (serialize) of the updater header and change list - * --create updater file using a temporay file name: + * --create updater file using a temporay file name: * --<shared->vfd_swmr_config.updater_file_path>.ud_tmp * --allocate space and write the following to the updater file * --updater file header @@ -2243,50 +2241,49 @@ H5F__vfd_swmr_construct_ud_cl(H5F_vfd_swmr_updater_t *updater) *------------------------------------------------------------------------- */ static herr_t -H5F__generate_updater_file(H5F_t *f, uint32_t num_entries, uint16_t flags, - uint8_t *md_file_hdr_image_ptr, size_t md_file_hdr_image_len, - uint8_t *md_file_index_image_ptr, uint64_t md_file_index_offset, - size_t md_file_index_image_len) +H5F__generate_updater_file(H5F_t *f, uint32_t num_entries, uint16_t flags, uint8_t *md_file_hdr_image_ptr, + size_t md_file_hdr_image_len, uint8_t *md_file_index_image_ptr, + uint64_t md_file_index_offset, size_t md_file_index_image_len) { - H5F_shared_t *shared = f->shared; /* shared file pointer */ - H5F_vfd_swmr_updater_t updater; /* Updater struct */ - uint32_t next_page_offset; - H5FD_t *ud_file = NULL; /* Low-level file struct */ - char namebuf[H5F__MAX_VFD_SWMR_FILE_NAME_LEN]; - char newname[H5F__MAX_VFD_SWMR_FILE_NAME_LEN]; - unsigned i; - hsize_t alloc_size; - herr_t ret_value = SUCCEED; /* Return value */ + H5F_shared_t * shared = f->shared; /* shared file pointer */ + H5F_vfd_swmr_updater_t updater; /* Updater struct */ + uint32_t next_page_offset; + H5FD_t * ud_file = NULL; /* Low-level file struct */ + char namebuf[H5F__MAX_VFD_SWMR_FILE_NAME_LEN]; + char newname[H5F__MAX_VFD_SWMR_FILE_NAME_LEN]; + unsigned i; + hsize_t alloc_size; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Updater file header fields */ - updater.version = H5F_UD_VERSION; - updater.flags = flags; - updater.page_size = (uint32_t)shared->fs_page_size; - updater.sequence_number = shared->updater_seq_num; - updater.tick_num = shared->tick_num; - updater.header_image_ptr = NULL; - updater.header_image_len = H5F_UD_HEADER_SIZE; + updater.version = H5F_UD_VERSION; + updater.flags = flags; + updater.page_size = (uint32_t)shared->fs_page_size; + updater.sequence_number = shared->updater_seq_num; + updater.tick_num = shared->tick_num; + updater.header_image_ptr = NULL; + updater.header_image_len = H5F_UD_HEADER_SIZE; updater.change_list_image_ptr = NULL; - updater.change_list_offset = 0; - updater.change_list_len = 0; + updater.change_list_offset = 0; + updater.change_list_len = 0; /* Updater file change list fields */ /* md_file_header related fields */ updater.md_file_header_ud_file_page_offset = 0; - updater.md_file_header_image_ptr = md_file_hdr_image_ptr; /* parameter */ - updater.md_file_header_len = md_file_hdr_image_len; /* parameter */ - + updater.md_file_header_image_ptr = md_file_hdr_image_ptr; /* parameter */ + updater.md_file_header_len = md_file_hdr_image_len; /* parameter */ + /* md_file_index related fields */ updater.md_file_index_ud_file_page_offset = 0; - updater.md_file_index_image_ptr = md_file_index_image_ptr; /* parameter */ - updater.md_file_index_md_file_offset = md_file_index_offset; /* parameter */ - updater.md_file_index_len = md_file_index_image_len; /* parameter */ + updater.md_file_index_image_ptr = md_file_index_image_ptr; /* parameter */ + updater.md_file_index_md_file_offset = md_file_index_offset; /* parameter */ + updater.md_file_index_len = md_file_index_image_len; /* parameter */ updater.num_change_list_entries = 0; - updater.change_list = NULL; + updater.change_list = NULL; /* Scan index to determine updater.num_change_list_entries */ for (i = 0; i < num_entries; i++) { @@ -2297,18 +2294,18 @@ H5F__generate_updater_file(H5F_t *f, uint32_t num_entries, uint16_t flags, if (flags == CREATE_METADATA_FILE_ONLY_FLAG) HDassert(updater.sequence_number == 0); - /* For file creation, just generate a header with this flag set */ + /* For file creation, just generate a header with this flag set */ else { /* Update 2 updater file header fields: change_list_len, change_list_offset */ - updater.change_list_len = H5F_UD_CL_SIZE(updater.num_change_list_entries); + updater.change_list_len = H5F_UD_CL_SIZE(updater.num_change_list_entries); updater.change_list_offset = updater.header_image_len; } - /* Create the updater file with a temporary file name */ HDsprintf(namebuf, "%s.ud_tmp", shared->vfd_swmr_config.updater_file_path); - if((ud_file = H5FD_open(namebuf, H5F_ACC_TRUNC|H5F_ACC_RDWR|H5F_ACC_CREAT, H5P_FILE_ACCESS_DEFAULT, HADDR_UNDEF)) == NULL) + if ((ud_file = H5FD_open(namebuf, H5F_ACC_TRUNC | H5F_ACC_RDWR | H5F_ACC_CREAT, H5P_FILE_ACCESS_DEFAULT, + HADDR_UNDEF)) == NULL) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "fail to open updater file"); if ((updater.header_image_ptr = HDmalloc(updater.header_image_len)) == NULL) @@ -2319,37 +2316,39 @@ H5F__generate_updater_file(H5F_t *f, uint32_t num_entries, uint16_t flags, HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to create updater file header "); /* Allocate space in updater file for updater file header */ - if(H5FD__alloc_real(ud_file, H5FD_MEM_DEFAULT, updater.header_image_len, NULL, NULL) == HADDR_UNDEF) + if (H5FD__alloc_real(ud_file, H5FD_MEM_DEFAULT, updater.header_image_len, NULL, NULL) == HADDR_UNDEF) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to allocate file memory") /* Write updater file header */ - if(H5FD_write(ud_file, H5FD_MEM_DEFAULT, H5F_UD_HEADER_OFF, updater.header_image_len, updater.header_image_ptr) < 0) + if (H5FD_write(ud_file, H5FD_MEM_DEFAULT, H5F_UD_HEADER_OFF, updater.header_image_len, + updater.header_image_ptr) < 0) HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "ud file write failed") - if (flags != CREATE_METADATA_FILE_ONLY_FLAG) { - next_page_offset = ((uint32_t)(updater.header_image_len + updater.change_list_len) / updater.page_size) + 1; + next_page_offset = + ((uint32_t)(updater.header_image_len + updater.change_list_len) / updater.page_size) + 1; - if(updater.num_change_list_entries) { + if (updater.num_change_list_entries) { /* Allocate space for change list entries */ - if((updater.change_list = HDmalloc(sizeof(H5F_vfd_swmr_updater_cl_entry_t) * - updater.num_change_list_entries)) == NULL) + if ((updater.change_list = HDmalloc(sizeof(H5F_vfd_swmr_updater_cl_entry_t) * + updater.num_change_list_entries)) == NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for ud cl") - /* Initialize change list entries */ for (i = 0; i < num_entries; i++) { if (shared->mdf_idx[i].entry_ptr != NULL && shared->mdf_idx[i].tick_of_last_change == shared->tick_num) { - updater.change_list[i].entry_image_ptr = shared->mdf_idx[i].entry_ptr; + updater.change_list[i].entry_image_ptr = shared->mdf_idx[i].entry_ptr; updater.change_list[i].entry_image_ud_file_page_offset = 0; - updater.change_list[i].entry_image_md_file_page_offset = (uint32_t)shared->mdf_idx[i].md_file_page_offset; - updater.change_list[i].entry_image_h5_file_page_offset = (uint32_t)shared->mdf_idx[i].hdf5_page_offset; - updater.change_list[i].entry_image_len = shared->mdf_idx[i].length; + updater.change_list[i].entry_image_md_file_page_offset = + (uint32_t)shared->mdf_idx[i].md_file_page_offset; + updater.change_list[i].entry_image_h5_file_page_offset = + (uint32_t)shared->mdf_idx[i].hdf5_page_offset; + updater.change_list[i].entry_image_len = shared->mdf_idx[i].length; updater.change_list[i].entry_image_checksum = shared->mdf_idx[i].checksum; shared->mdf_idx[i].entry_ptr = NULL; @@ -2357,9 +2356,10 @@ H5F__generate_updater_file(H5F_t *f, uint32_t num_entries, uint16_t flags, } /* Set up page aligned space for all metadata pages */ - for(i = 0; i < updater.num_change_list_entries; i++) { + for (i = 0; i < updater.num_change_list_entries; i++) { updater.change_list[i].entry_image_ud_file_page_offset = next_page_offset; - next_page_offset += (((uint32_t)updater.change_list[i].entry_image_len / updater.page_size) + 1); + next_page_offset += + (((uint32_t)updater.change_list[i].entry_image_len / updater.page_size) + 1); } } @@ -2378,51 +2378,55 @@ H5F__generate_updater_file(H5F_t *f, uint32_t num_entries, uint16_t flags, HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "fail to create updater file cl"); /* Allocate space in updater file for updater file change list */ - if(H5FD__alloc_real(ud_file, H5FD_MEM_DEFAULT, updater.header_image_len+updater.change_list_len, NULL, NULL) == HADDR_UNDEF) + if (H5FD__alloc_real(ud_file, H5FD_MEM_DEFAULT, updater.header_image_len + updater.change_list_len, + NULL, NULL) == HADDR_UNDEF) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to allocate file memory") /* Write updater file change list */ - if(H5FD_write(ud_file, H5FD_MEM_DEFAULT, updater.header_image_len, - updater.change_list_len, updater.change_list_image_ptr) < 0) + if (H5FD_write(ud_file, H5FD_MEM_DEFAULT, updater.header_image_len, updater.change_list_len, + updater.change_list_image_ptr) < 0) HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "ud file write failed") - /* Allocate and write metadata pages */ for (i = 0; i < updater.num_change_list_entries; i++) { - alloc_size = updater.change_list[i].entry_image_ud_file_page_offset * updater.page_size + + alloc_size = updater.change_list[i].entry_image_ud_file_page_offset * updater.page_size + updater.change_list[i].entry_image_len; - if(H5FD__alloc_real(ud_file, H5FD_MEM_DEFAULT, alloc_size, NULL, NULL) == HADDR_UNDEF) + if (H5FD__alloc_real(ud_file, H5FD_MEM_DEFAULT, alloc_size, NULL, NULL) == HADDR_UNDEF) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to allocate file memory") - if(H5FD_write(ud_file, H5FD_MEM_DEFAULT, - updater.change_list[i].entry_image_ud_file_page_offset * updater.page_size, - updater.change_list[i].entry_image_len, - updater.change_list[i].entry_image_ptr) < 0) + if (H5FD_write(ud_file, H5FD_MEM_DEFAULT, + updater.change_list[i].entry_image_ud_file_page_offset * updater.page_size, + updater.change_list[i].entry_image_len, + updater.change_list[i].entry_image_ptr) < 0) HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "ud file write failed") } /* Allocate and write metadata file index */ - alloc_size = updater.md_file_index_ud_file_page_offset * updater.page_size + updater.md_file_index_len; - if(H5FD__alloc_real(ud_file, H5FD_MEM_DEFAULT, alloc_size, NULL, NULL) == HADDR_UNDEF) + alloc_size = + updater.md_file_index_ud_file_page_offset * updater.page_size + updater.md_file_index_len; + if (H5FD__alloc_real(ud_file, H5FD_MEM_DEFAULT, alloc_size, NULL, NULL) == HADDR_UNDEF) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to allocate file memory") - if(H5FD_write(ud_file, H5FD_MEM_DEFAULT, updater.md_file_index_ud_file_page_offset * updater.page_size, - updater.md_file_index_len, updater.md_file_index_image_ptr) < 0) + if (H5FD_write(ud_file, H5FD_MEM_DEFAULT, + updater.md_file_index_ud_file_page_offset * updater.page_size, + updater.md_file_index_len, updater.md_file_index_image_ptr) < 0) HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "ud file write failed") /* Allocate and write metadata file header */ - alloc_size = updater.md_file_header_ud_file_page_offset * updater.page_size + updater.md_file_header_len; - if(H5FD__alloc_real(ud_file, H5FD_MEM_DEFAULT, alloc_size, NULL, NULL) == HADDR_UNDEF) + alloc_size = + updater.md_file_header_ud_file_page_offset * updater.page_size + updater.md_file_header_len; + if (H5FD__alloc_real(ud_file, H5FD_MEM_DEFAULT, alloc_size, NULL, NULL) == HADDR_UNDEF) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to allocate file memory") - if(H5FD_write(ud_file, H5FD_MEM_DEFAULT, updater.md_file_header_ud_file_page_offset * updater.page_size, - updater.md_file_header_len, updater.md_file_header_image_ptr) < 0) + if (H5FD_write(ud_file, H5FD_MEM_DEFAULT, + updater.md_file_header_ud_file_page_offset * updater.page_size, + updater.md_file_header_len, updater.md_file_header_image_ptr) < 0) HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "ud file write failed") } /* Close the updater file and rename the file */ - if(H5FD_close(ud_file) < 0) + if (H5FD_close(ud_file) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close updater file") HDsprintf(newname, "%s.%lu", shared->vfd_swmr_config.updater_file_path, shared->updater_seq_num); HDrename(namebuf, newname); @@ -2430,13 +2434,13 @@ H5F__generate_updater_file(H5F_t *f, uint32_t num_entries, uint16_t flags, ++shared->updater_seq_num; done: - if(updater.header_image_ptr) + if (updater.header_image_ptr) HDfree(updater.header_image_ptr); - if(updater.change_list_image_ptr) + if (updater.change_list_image_ptr) HDfree(updater.change_list_image_ptr); - if(updater.change_list) + if (updater.change_list) HDfree(updater.change_list); FUNC_LEAVE_NOAPI(ret_value) -} /* H5F__generate_updater_file() */ +} /* H5F__generate_updater_file() */ diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index f833d65..0c2686a 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -319,13 +319,13 @@ #define H5F_ACS_VFD_SWMR_CONFIG_DEC H5P__facc_vfd_swmr_config_dec /* Private property for VFD SWMR testing: - * Callback function to generate checksum for metadata file + * Callback function to generate checksum for metadata file */ #define H5F_ACS_GENERATE_MD_CK_CB_SIZE sizeof(H5F_generate_md_ck_cb_t) -#define H5F_ACS_GENERATE_MD_CK_CB_DEF \ - { \ - NULL \ +#define H5F_ACS_GENERATE_MD_CK_CB_DEF \ + { \ + NULL \ } /******************/ @@ -526,8 +526,7 @@ static const hbool_t H5F_def_ignore_disabled_file_locks_g = static const H5F_vfd_swmr_config_t H5F_def_vfd_swmr_config_g = H5F_ACS_VFD_SWMR_CONFIG_DEF; /* Default vfd swmr configuration */ /* For VFD SWMR testing only: Default to generate checksum for metadata file */ -static const H5F_generate_md_ck_t H5F_def_generate_md_ck_cb_g = - H5F_ACS_GENERATE_MD_CK_CB_DEF; +static const H5F_generate_md_ck_t H5F_def_generate_md_ck_cb_g = H5F_ACS_GENERATE_MD_CK_CB_DEF; /*------------------------------------------------------------------------- * Function: H5P__facc_reg_prop @@ -4125,7 +4124,8 @@ H5P__facc_vfd_swmr_config_enc(const void *value, void **_pp, size_t *size) INT32ENCODE(*pp, (int32_t)config->pb_expansion_threshold); HDmemcpy(*pp, (const uint8_t *)(config->md_file_path), (size_t)(H5F__MAX_VFD_SWMR_FILE_NAME_LEN + 1)); *pp += H5F__MAX_VFD_SWMR_FILE_NAME_LEN + 1; - HDmemcpy(*pp, (const uint8_t *)(config->updater_file_path), (size_t)(H5F__MAX_VFD_SWMR_FILE_NAME_LEN + 1)); + HDmemcpy(*pp, (const uint8_t *)(config->updater_file_path), + (size_t)(H5F__MAX_VFD_SWMR_FILE_NAME_LEN + 1)); *pp += H5F__MAX_VFD_SWMR_FILE_NAME_LEN + 1; HDmemcpy(*pp, (const uint8_t *)(config->log_file_path), (size_t)(H5F__MAX_VFD_SWMR_FILE_NAME_LEN + 1)); @@ -5734,12 +5734,13 @@ H5Pset_vfd_swmr_config(hid_t plist_id, H5F_vfd_swmr_config_t *config_ptr) HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "pb_expansion_threshold out of range") /* If writer is TRUE, at least one of maintain_metadata_file and generate_updater_files must be TRUE */ - if(config_ptr->writer) { - if(!config_ptr->maintain_metadata_file && !config_ptr->generate_updater_files) - HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "either maintain_metadata_file or generate_updater_files must be TRUE") + if (config_ptr->writer) { + if (!config_ptr->maintain_metadata_file && !config_ptr->generate_updater_files) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, + "either maintain_metadata_file or generate_updater_files must be TRUE") } - if((config_ptr->writer && config_ptr->maintain_metadata_file) || !config_ptr->writer) { + if ((config_ptr->writer && config_ptr->maintain_metadata_file) || !config_ptr->writer) { /* Must provide the path and base name of the metadata file */ name_len = HDstrlen(config_ptr->md_file_path); if (name_len == 0) @@ -5748,7 +5749,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") } - if(config_ptr->writer && config_ptr->generate_updater_files) { + if (config_ptr->writer && config_ptr->generate_updater_files) { /* Must provide the path and base name of the metadata updater files */ name_len = HDstrlen(config_ptr->updater_file_path); if (name_len == 0) @@ -5757,7 +5758,6 @@ H5Pset_vfd_swmr_config(hid_t plist_id, H5F_vfd_swmr_config_t *config_ptr) HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "updater_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") diff --git a/test/page_buffer.c b/test/page_buffer.c index 53c9b74..c7bb965 100644 --- a/test/page_buffer.c +++ b/test/page_buffer.c @@ -97,13 +97,13 @@ error: static int swmr_fapl_augment(hid_t fapl, const char *filename, uint32_t max_lag) { - H5F_vfd_swmr_config_t config = {.version = H5F__CURR_VFD_SWMR_CONFIG_VERSION, - .tick_len = 4, - .max_lag = max_lag, - .writer = true, + H5F_vfd_swmr_config_t config = {.version = H5F__CURR_VFD_SWMR_CONFIG_VERSION, + .tick_len = 4, + .max_lag = max_lag, + .writer = true, .maintain_metadata_file = true, .generate_updater_files = false, - .md_pages_reserved = 128}; + .md_pages_reserved = 128}; char * bname = NULL; char * dname = NULL; diff --git a/test/vfd_swmr.c b/test/vfd_swmr.c index e93a399..e763191 100644 --- a/test/vfd_swmr.c +++ b/test/vfd_swmr.c @@ -49,34 +49,34 @@ #define FILENAME3 "vfd_swmr_file3.h5" #define MD_FILENAME3 "vfd_swmr_metadata_file3" -#define FILENAME4 "vfd_swmr_file4.h5" -#define MD_FILE "vfd_swmr_md_file" -#define UD_FILE "vfd_swmr_ud_file" +#define FILENAME4 "vfd_swmr_file4.h5" +#define MD_FILE "vfd_swmr_md_file" +#define UD_FILE "vfd_swmr_ud_file" #define FNAME "non_vfd_swmr_file.h5" /* Defines used by verify_updater_flags() and verify_ud_chk() helper routine */ /* Offset of "flags" in updater file header */ -#define UD_HD_FLAGS_OFFSET 6 +#define UD_HD_FLAGS_OFFSET 6 /* Offset of "sequence number" in updater file header */ -#define UD_HD_SEQ_NUM_OFFSET 12 +#define UD_HD_SEQ_NUM_OFFSET 12 /* Offset of "change list length" in updater file header */ -#define UD_HD_CHANGE_LIST_LEN_OFFSET 36 +#define UD_HD_CHANGE_LIST_LEN_OFFSET 36 /* Offset of "number of change list entries" in updater file change list header */ -#define UD_CL_NUM_CHANGE_LIST_ENTRIES_OFFSET H5F_UD_HEADER_SIZE + 44 +#define UD_CL_NUM_CHANGE_LIST_ENTRIES_OFFSET H5F_UD_HEADER_SIZE + 44 /* Size of "sequence number", "tick number" and "change list length" fields in the updater file header */ -#define UD_SIZE_8 8 +#define UD_SIZE_8 8 /* Size of checksum and "number of change list entries" field in the updater change list header */ -#define UD_SIZE_4 4 +#define UD_SIZE_4 4 /* Size of "flags" field in the updater file header */ -#define UD_SIZE_2 2 +#define UD_SIZE_2 2 /* test routines for VFD SWMR */ static unsigned test_fapl(void); @@ -86,14 +86,13 @@ static unsigned test_writer_md(void); static unsigned test_updater_flags(void); static unsigned test_updater_flags_same_file_opens(void); -static herr_t verify_updater_flags(char *ud_name, uint16_t expected_flags); +static herr_t verify_updater_flags(char *ud_name, uint16_t expected_flags); -static void clean_chk_ud_files(char *md_file_path, char *updater_file_path); -static herr_t verify_ud_chk(char *md_file_path, char *ud_file_path); -static herr_t md_ck_cb(char *md_file_path, uint64_t tick_num); +static void clean_chk_ud_files(char *md_file_path, char *updater_file_path); +static herr_t verify_ud_chk(char *md_file_path, char *ud_file_path); +static herr_t md_ck_cb(char *md_file_path, uint64_t tick_num); static unsigned test_updater_generate_md_checksums(hbool_t file_create); - /*------------------------------------------------------------------------- * Function: test_fapl() * @@ -108,7 +107,7 @@ static unsigned test_updater_generate_md_checksums(hbool_t file_create); * must be true * --if both the writer and maintain_metadata_file fields are true, * then md_file_path field shouldn't be empty - * --if both the writer and generate_updater_files fields are true, + * --if both the writer and generate_updater_files fields are true, * then updater_file_path field shouldn't be empty * B) Verify that info set in the fapl is retrieved correctly. * @@ -201,7 +200,7 @@ test_fapl(void) if (ret >= 0) TEST_ERROR; - my_config->writer = TRUE; + my_config->writer = TRUE; my_config->maintain_metadata_file = TRUE; /* Should fail: empty md_file_path */ H5E_BEGIN_TRY @@ -344,12 +343,11 @@ test_file_fapl(void) if ((file_config = (H5F_vfd_swmr_config_t *)HDmalloc(sizeof(H5F_vfd_swmr_config_t))) == NULL) FAIL_STACK_ERROR; - - /* - * Configured as VFD SWMR reader + no page buffering + /* + * Configured as VFD SWMR reader + no page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config1, 4, 7, FALSE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); @@ -370,11 +368,11 @@ test_file_fapl(void) if (H5Pclose(fapl1) < 0) FAIL_STACK_ERROR - /* - * Configured as VFD SWMR writer + no page buffering + /* + * Configured as VFD SWMR writer + no page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config1, 4, 7, TRUE, TRUE, TRUE, TRUE, 2, MD_FILENAME, UD_FILENAME); @@ -410,11 +408,11 @@ test_file_fapl(void) if (H5Pclose(fapl1) < 0) FAIL_STACK_ERROR - /* - * Configured as VFD SWMR writer + page buffering + /* + * Configured as VFD SWMR writer + page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config1, 4, 7, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); @@ -482,11 +480,11 @@ test_file_fapl(void) if (H5Pclose(fapl1) < 0) FAIL_STACK_ERROR; - /* - * Set up different VFD SWMR configuration + page_buffering + /* + * Set up different VFD SWMR configuration + page_buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config2, 4, 10, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); @@ -522,12 +520,11 @@ test_file_fapl(void) /* The file previously opened as VDF SWMR writer is still open */ /* with VFD SWMR configuration in config2 */ - - /* - * Set up as VFD SWMR writer in config1 but different from config2 + /* + * Set up as VFD SWMR writer in config1 but different from config2 */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config1, 3, 8, TRUE, TRUE, FALSE, TRUE, 3, MD_FILENAME, NULL); @@ -551,8 +548,8 @@ test_file_fapl(void) if (H5Pclose(fapl1) < 0) FAIL_STACK_ERROR; - /* - * Set up as VFD SWMR reader in config1 which is same as config2 + /* + * Set up as VFD SWMR reader in config1 which is same as config2 */ init_vfd_swmr_config(config1, 4, 10, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); @@ -634,7 +631,6 @@ error: return 1; } /* test_file_fapl() */ - /*------------------------------------------------------------------------- * Function: test_file_end_tick() * @@ -694,11 +690,11 @@ test_file_end_tick(void) if ((config3 = HDmalloc(sizeof(*config3))) == NULL) FAIL_STACK_ERROR; - /* - * Configured file 1 as VFD SWMR writer + page buffering + /* + * Configured file 1 as VFD SWMR writer + page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config1, 10, 15, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); @@ -708,11 +704,11 @@ test_file_end_tick(void) if (fapl1 == H5I_INVALID_HID) TEST_ERROR - /* - * Configured file 2 as VFD SWMR writer + page buffering + /* + * Configured file 2 as VFD SWMR writer + page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config2, 5, 6, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME2, NULL); @@ -722,11 +718,11 @@ test_file_end_tick(void) if (fapl2 == H5I_INVALID_HID) TEST_ERROR - /* - * Configured file 3 as VFD SWMR writer + page buffering + /* + * Configured file 3 as VFD SWMR writer + page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config3, 3, 6, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME3, NULL); @@ -905,11 +901,11 @@ test_writer_create_open_flush(void) if ((my_config = HDmalloc(sizeof(H5F_vfd_swmr_config_t))) == NULL) FAIL_STACK_ERROR; - /* - * Set up the VFD SWMR configuration + page buffering + /* + * Set up the VFD SWMR configuration + page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(my_config, 1, 3, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); @@ -1023,7 +1019,7 @@ test_writer_md(void) hsize_t chunk_dims[2] = {2, 5}; /* Dataset chunked dimension sizes */ H5FD_vfd_swmr_idx_entry_t *index = NULL; /* Pointer to the index entries */ H5F_vfd_swmr_config_t * my_config = NULL; /* Configuration for VFD SWMR */ - H5F_t * f = NULL; /* Internal file object pointer */ + H5F_t * f = NULL; /* Internal file object pointer */ TESTING("Verify the metadata file for VFD SWMR writer"); @@ -1031,7 +1027,7 @@ test_writer_md(void) if ((my_config = HDmalloc(sizeof(H5F_vfd_swmr_config_t))) == NULL) FAIL_STACK_ERROR; - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(my_config, 1, 3, TRUE, TRUE, FALSE, TRUE, 256, MD_FILENAME, NULL); @@ -1108,7 +1104,7 @@ test_writer_md(void) /* (B) Update every other entry in the index */ for (i = 0; i < num_entries; i += 2) { - index[i].entry_ptr = &buf[i * FS_PAGE_SIZE]; + index[i].entry_ptr = &buf[i * FS_PAGE_SIZE]; index[i].tick_of_last_change = f->shared->tick_num; } @@ -1147,7 +1143,7 @@ test_writer_md(void) /* (C) Update every 3 entry in the index */ for (i = 0; i < num_entries; i += 3) { - index[i].entry_ptr = &buf[i * FS_PAGE_SIZE]; + index[i].entry_ptr = &buf[i * FS_PAGE_SIZE]; index[i].tick_of_last_change = f->shared->tick_num; } @@ -1182,9 +1178,9 @@ test_writer_md(void) } /* (D) Update two entries in the index */ - index[1].entry_ptr = &buf[1 * FS_PAGE_SIZE]; + index[1].entry_ptr = &buf[1 * FS_PAGE_SIZE]; index[1].tick_of_last_change = f->shared->tick_num; - index[5].entry_ptr = &buf[5 * FS_PAGE_SIZE]; + index[5].entry_ptr = &buf[5 * FS_PAGE_SIZE]; index[5].tick_of_last_change = f->shared->tick_num; /* Update with index and verify info in the metadata file */ @@ -1345,11 +1341,11 @@ test_reader_md_concur(void) if ((config_writer = HDmalloc(sizeof(*config_writer))) == NULL) FAIL_STACK_ERROR; - /* - * Set up the VFD SWMR configuration + page buffering + /* + * Set up the VFD SWMR configuration + page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config_writer, 1, 3, TRUE, TRUE, FALSE, TRUE, 256, MD_FILENAME, NULL); @@ -1421,11 +1417,11 @@ test_reader_md_concur(void) if ((config_reader = HDmalloc(sizeof(*config_reader))) == NULL) HDexit(EXIT_FAILURE); - /* - * Set up the VFD SWMR configuration as reader + page buffering + /* + * Set up the VFD SWMR configuration as reader + page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config_reader, 1, 3, FALSE, TRUE, FALSE, TRUE, 256, MD_FILENAME, NULL); @@ -1761,7 +1757,7 @@ test_reader_md_concur(void) /* Update 3 entries in the index */ num_entries = 3; for (i = 0; i < num_entries; i++) { - index[i].entry_ptr = &buf[i * FS_PAGE_SIZE]; + index[i].entry_ptr = &buf[i * FS_PAGE_SIZE]; index[i].tick_of_last_change = file_writer->shared->tick_num; } @@ -1816,7 +1812,7 @@ test_reader_md_concur(void) /* Update 5 entries in the index */ num_entries = 5; for (i = 0; i < num_entries; i++) { - index[i].entry_ptr = &buf[i * FS_PAGE_SIZE]; + index[i].entry_ptr = &buf[i * FS_PAGE_SIZE]; index[i].tick_of_last_change = file_writer->shared->tick_num; } @@ -2040,7 +2036,7 @@ test_multiple_file_opens_concur(void) /* Set the VFD SWMR configuration in fapl_writer + page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config_writer, 1, 3, TRUE, TRUE, FALSE, TRUE, 256, MD_FILENAME2, NULL); @@ -2108,7 +2104,7 @@ test_multiple_file_opens_concur(void) if ((config1 = HDmalloc(sizeof(*config1))) == NULL) FAIL_STACK_ERROR - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config1, 7, 10, TRUE, TRUE, FALSE, TRUE, 256, MD_FILENAME, NULL); @@ -2151,7 +2147,7 @@ test_multiple_file_opens_concur(void) if ((config2 = HDmalloc(sizeof(*config2))) == NULL) FAIL_STACK_ERROR - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config2, 1, 3, FALSE, TRUE, FALSE, TRUE, 256, MD_FILENAME2, NULL); @@ -2290,11 +2286,11 @@ test_disable_enable_eot_concur(void) if ((config_writer = HDmalloc(sizeof(*config_writer))) == NULL) FAIL_STACK_ERROR; - /* - * Set up the VFD SWMR configuration + page buffering + /* + * Set up the VFD SWMR configuration + page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config_writer, 1, 3, TRUE, TRUE, FALSE, TRUE, 256, MD_FILENAME, NULL); @@ -2370,11 +2366,11 @@ test_disable_enable_eot_concur(void) if ((config_reader = HDmalloc(sizeof(*config_reader))) == NULL) HDexit(EXIT_FAILURE); - /* - * Set up the VFD SWMR configuration as reader + page buffering + /* + * Set up the VFD SWMR configuration as reader + page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config_reader, 1, 3, FALSE, TRUE, FALSE, TRUE, 256, MD_FILENAME, NULL); @@ -2582,11 +2578,11 @@ test_file_end_tick_concur(void) if ((config_writer = HDmalloc(sizeof(*config_writer))) == NULL) FAIL_STACK_ERROR; - /* - * Set up the VFD SWMR configuration + page buffering + /* + * Set up the VFD SWMR configuration + page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config_writer, 1, 3, TRUE, TRUE, FALSE, TRUE, 256, MD_FILENAME, NULL); @@ -2662,7 +2658,7 @@ test_file_end_tick_concur(void) if ((config_reader = HDmalloc(sizeof(*config_reader))) == NULL) HDexit(EXIT_FAILURE); - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config_reader, 1, 3, FALSE, TRUE, FALSE, TRUE, 256, MD_FILENAME, NULL); @@ -2857,11 +2853,11 @@ test_multiple_file_opens(void) if ((config2 = HDmalloc(sizeof(*config2))) == NULL) FAIL_STACK_ERROR; - /* - * Configured as VFD SWMR writer + page buffering + /* + * Configured as VFD SWMR writer + page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config1, 4, 6, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); @@ -2870,7 +2866,7 @@ test_multiple_file_opens(void) if (fapl1 == H5I_INVALID_HID) FAIL_STACK_ERROR; - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config2, 4, 6, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME2, NULL); @@ -3071,11 +3067,11 @@ test_same_file_opens(void) if (H5Fclose(fid) < 0) FAIL_STACK_ERROR; - /* - * Set the VFD SWMR configuration in fapl1 + page buffering + /* + * Set the VFD SWMR configuration in fapl1 + page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config1, 4, 10, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); @@ -3099,11 +3095,11 @@ test_same_file_opens(void) if (H5Fclose(fid2) < 0) FAIL_STACK_ERROR; - /* - * Set the VFD SWMR configuration in fapl2 + page buffering + /* + * Set the VFD SWMR configuration in fapl2 + page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config2, 3, 8, FALSE, TRUE, FALSE, TRUE, 3, MD_FILENAME, NULL); @@ -3154,12 +3150,11 @@ test_same_file_opens(void) * Tests for second column */ - - /* - * Set up as VFD SWMR reader + page buffering + /* + * Set up as VFD SWMR reader + page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config1, 4, 10, FALSE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); @@ -3192,11 +3187,11 @@ test_same_file_opens(void) if ((fid = H5Fopen(FILENAME, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR; - /* - * Set up as VFD SWMR writer + page buffering + /* + * Set up as VFD SWMR writer + page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config1, 4, 10, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); @@ -3248,11 +3243,11 @@ test_same_file_opens(void) if ((fid = H5Fopen(FILENAME, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR; - /* - * Set up as VFD SWMR writer + page buffering + /* + * Set up as VFD SWMR writer + page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config1, 4, 10, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); @@ -3459,11 +3454,11 @@ test_enable_disable_eot(void) if ((config3 = HDmalloc(sizeof(*config3))) == NULL) FAIL_STACK_ERROR; - /* - * Configured first file as VFD SWMR writer + page buffering + /* + * Configured first file as VFD SWMR writer + page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config1, 4, 6, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME, NULL); @@ -3473,11 +3468,11 @@ test_enable_disable_eot(void) if (fapl1 == H5I_INVALID_HID) FAIL_STACK_ERROR; - /* - * Configured second file as VFD SWMR writer + page buffering + /* + * Configured second file as VFD SWMR writer + page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config2, 4, 6, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME2, NULL); @@ -3487,11 +3482,11 @@ test_enable_disable_eot(void) if (fapl2 == H5I_INVALID_HID) FAIL_STACK_ERROR; - /* - * Configured third file as VFD SWMR writer + page buffering + /* + * Configured third file as VFD SWMR writer + page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config3, 4, 6, TRUE, TRUE, FALSE, TRUE, 2, MD_FILENAME3, NULL); @@ -3707,21 +3702,20 @@ error: static herr_t verify_updater_flags(char *ud_name, uint16_t expected_flags) { - FILE* ud_fp; /* Updater file pointer */ + FILE * ud_fp; /* Updater file pointer */ uint16_t flags; - size_t ret; /* Return value */ + size_t ret; /* Return value */ - /* Open the updater file */ - if((ud_fp = HDfopen(ud_name, "r")) == NULL) + if ((ud_fp = HDfopen(ud_name, "r")) == NULL) FAIL_STACK_ERROR; /* Seek to the position of "flags" in the updater file's header */ - if(HDfseek(ud_fp, (HDoff_t)UD_HD_FLAGS_OFFSET, SEEK_SET) < 0) + if (HDfseek(ud_fp, (HDoff_t)UD_HD_FLAGS_OFFSET, SEEK_SET) < 0) FAIL_STACK_ERROR; /* Read "flags" from the updater file */ - if((ret = HDfread(&flags, UD_SIZE_2, 1, ud_fp)) != (size_t)1) + if ((ret = HDfread(&flags, UD_SIZE_2, 1, ud_fp)) != (size_t)1) FAIL_STACK_ERROR; if (flags != expected_flags) @@ -3740,7 +3734,7 @@ error: /*------------------------------------------------------------------------- * Function: test_updater_flags * - * Purpose: Verify "flags" in the updater file is as expected for + * Purpose: Verify "flags" in the updater file is as expected for * file creation. * * Return: 0 if test is sucessful @@ -3759,10 +3753,10 @@ test_updater_flags(void) hid_t file_fapl = -1; /* File access property list ID associated with the file */ H5F_vfd_swmr_config_t *config = NULL; /* Configuration for VFD SWMR */ H5F_vfd_swmr_config_t *file_config = NULL; /* Configuration for VFD SWMR */ - uint64_t seq_num = 0; /* Sequence number for updater file */ - uint64_t i = 0; /* Local index variable */ - char namebuf[H5F__MAX_VFD_SWMR_FILE_NAME_LEN]; /* Updater file path */ - h5_stat_t sb; /* Info returned by stat system call */ + uint64_t seq_num = 0; /* Sequence number for updater file */ + uint64_t i = 0; /* Local index variable */ + char namebuf[H5F__MAX_VFD_SWMR_FILE_NAME_LEN]; /* Updater file path */ + h5_stat_t sb; /* Info returned by stat system call */ TESTING("VFD SWMR updater file flags"); @@ -3780,11 +3774,11 @@ test_updater_flags(void) if ((file_config = (H5F_vfd_swmr_config_t *)HDmalloc(sizeof(H5F_vfd_swmr_config_t))) == NULL) FAIL_STACK_ERROR; - /* + /* * Configured as VFD SWMR writer + page buffering + generate updater files */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config, 4, 7, TRUE, TRUE, TRUE, TRUE, 2, MD_FILENAME, UD_FILENAME); @@ -3818,7 +3812,7 @@ test_updater_flags(void) HDsprintf(namebuf, "%s.%lu", UD_FILENAME, seq_num); /* Verify "flags" of the first updater file */ - if(verify_updater_flags(namebuf, CREATE_METADATA_FILE_ONLY_FLAG) < 0) + if (verify_updater_flags(namebuf, CREATE_METADATA_FILE_ONLY_FLAG) < 0) TEST_ERROR; /* Check updater file size */ @@ -3830,15 +3824,15 @@ test_updater_flags(void) FAIL_STACK_ERROR; /* Look for the last updater file */ - for (seq_num = 0; ; seq_num++) { + for (seq_num = 0;; seq_num++) { HDsprintf(namebuf, "%s.%lu", UD_FILENAME, seq_num); if (HDaccess(namebuf, F_OK) != 0) break; } - HDsprintf(namebuf, "%s.%lu", UD_FILENAME, seq_num-1); + HDsprintf(namebuf, "%s.%lu", UD_FILENAME, seq_num - 1); /* Verify "flags" of the last updater file */ - if(verify_updater_flags(namebuf, FINAL_UPDATE_FLAG) < 0) + if (verify_updater_flags(namebuf, FINAL_UPDATE_FLAG) < 0) TEST_ERROR; if (H5Pclose(file_fapl) < 0) @@ -3883,7 +3877,7 @@ error: /*------------------------------------------------------------------------- * Function: test_updater_flags_same_file_opens() * - * Purpose: Verify "flags" in the updater file is as expected for + * Purpose: Verify "flags" in the updater file is as expected for * multiple opens of the same file. * * Return: 0 if test is sucessful @@ -3896,14 +3890,14 @@ error: static unsigned test_updater_flags_same_file_opens(void) { - hid_t fid = -1; /* File ID */ - hid_t fid2 = -1; /* File ID */ - hid_t fcpl = -1; /* File creation property list ID */ - hid_t fapl1 = -1; /* File access property list ID */ - H5F_vfd_swmr_config_t *config1 = NULL; /* Configuration for VFD SWMR */ - uint64_t seq_num = 0; /* Sequence number for updater file */ - uint64_t i = 0; /* Local index variable */ - char namebuf[H5F__MAX_VFD_SWMR_FILE_NAME_LEN]; /* Updater file path */ + hid_t fid = -1; /* File ID */ + hid_t fid2 = -1; /* File ID */ + hid_t fcpl = -1; /* File creation property list ID */ + hid_t fapl1 = -1; /* File access property list ID */ + H5F_vfd_swmr_config_t *config1 = NULL; /* Configuration for VFD SWMR */ + uint64_t seq_num = 0; /* Sequence number for updater file */ + uint64_t i = 0; /* Local index variable */ + char namebuf[H5F__MAX_VFD_SWMR_FILE_NAME_LEN]; /* Updater file path */ TESTING("VFD SWMR updater file flags for multiple opens of the same file"); @@ -3932,11 +3926,11 @@ test_updater_flags_same_file_opens(void) if (H5Fclose(fid) < 0) FAIL_STACK_ERROR; - /* - * Set the VFD SWMR configuration in fapl1 + page buffering + /* + * Set the VFD SWMR configuration in fapl1 + page buffering */ - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config1, 4, 10, TRUE, TRUE, TRUE, TRUE, 2, MD_FILENAME, UD_FILENAME); @@ -3960,24 +3954,23 @@ test_updater_flags_same_file_opens(void) if (H5Fclose(fid2) < 0) FAIL_STACK_ERROR; - /* Verify the first updater file for first file open */ HDsprintf(namebuf, "%s.%lu", UD_FILENAME, seq_num); /* Verify "flags" of the first updater file is 0*/ - if(verify_updater_flags(namebuf, 0) < 0) + if (verify_updater_flags(namebuf, 0) < 0) TEST_ERROR; /* Look for the last updater file */ - for (seq_num = 0; ; seq_num++) { + for (seq_num = 0;; seq_num++) { HDsprintf(namebuf, "%s.%lu", UD_FILENAME, seq_num); if (HDaccess(namebuf, F_OK) != 0) break; } - HDsprintf(namebuf, "%s.%lu", UD_FILENAME, seq_num-1); + HDsprintf(namebuf, "%s.%lu", UD_FILENAME, seq_num - 1); /* Verify "flags" of the last updater file is 0 */ - if(verify_updater_flags(namebuf, 0) < 0) + if (verify_updater_flags(namebuf, 0) < 0) TEST_ERROR; /* Close the 1st open file */ @@ -3985,15 +3978,15 @@ test_updater_flags_same_file_opens(void) FAIL_STACK_ERROR; /* Look for the last updater file */ - for (seq_num = 0; ; seq_num++) { + for (seq_num = 0;; seq_num++) { HDsprintf(namebuf, "%s.%lu", UD_FILENAME, seq_num); if (HDaccess(namebuf, F_OK) != 0) break; } - HDsprintf(namebuf, "%s.%lu", UD_FILENAME, seq_num-1); + HDsprintf(namebuf, "%s.%lu", UD_FILENAME, seq_num - 1); /* Verify "flags" of the last updater file after closing file */ - if(verify_updater_flags(namebuf, FINAL_UPDATE_FLAG) < 0) + if (verify_updater_flags(namebuf, FINAL_UPDATE_FLAG) < 0) TEST_ERROR; /* Clean up updater files */ @@ -4026,7 +4019,6 @@ error: return 1; } /* test_updater_flags_same_file_opens() */ - /*------------------------------------------------------------------------- * Function: clean_chk_ud_files() * @@ -4042,41 +4034,40 @@ error: static void clean_chk_ud_files(char *md_file_path, char *updater_file_path) { - char chk_name[1024 + 4]; - char ud_name[1024 + 4]; + char chk_name[1024 + 4]; + char ud_name[1024 + 4]; uint64_t i; /* Name of the checksum file: <md_file_path>.chk */ HDsprintf(chk_name, "%s.chk", md_file_path); - /* Remove the checksum file if exists. + /* Remove the checksum file if exists. If not, the callback will just continue appending checksums to the existing file */ - if(HDaccess(chk_name, F_OK) == 0) { + if (HDaccess(chk_name, F_OK) == 0) { HDremove(chk_name); } /* Remove all the updater files if exist: <updater_file_path>.<i> */ - for(i = 0; ; i++) { + for (i = 0;; i++) { sprintf(ud_name, "%s.%lu", updater_file_path, i); - if(HDaccess(ud_name, F_OK) != 0) + if (HDaccess(ud_name, F_OK) != 0) break; HDremove(ud_name); } } /* clean_chk_ud_files() */ - /*------------------------------------------------------------------------- * Function: verify_ud_chk() * - * Purpose: This is the helper routine used by - * test_updater_generate_md_checksums() to verify + * Purpose: This is the helper routine used by + * test_updater_generate_md_checksums() to verify * contents of the checksum file and the updater files. * --verify the sequence number in each updater's file header - * corresponds to the ith sequence number of the updater + * corresponds to the ith sequence number of the updater * file name. - * --verify the tick number in each updater's file header + * --verify the tick number in each updater's file header * corresponds to the tick number stored in the checksum file * --verify the change_list_len in each updater's file header * is consistent with num_change_list_entries in each updater's @@ -4092,23 +4083,23 @@ clean_chk_ud_files(char *md_file_path, char *updater_file_path) static herr_t verify_ud_chk(char *md_file_path, char *ud_file_path) { - char chk_name[1024 + 4]; /* Checksum file name */ - char ud_name[1024 + 4]; /* Updater file name */ - FILE* chk_fp; /* Checksum file pointer */ - FILE* ud_fp; /* Updater file pointer */ - uint64_t ud_seq_num; /* Sequence number in the updater file */ - uint64_t chk_ud_seq_num; /* Updater sequence number in the checksum file */ - uint64_t i; /* Local index variable */ - long size = 0; /* Size of the file */ - size_t change_list_len; /* change_list_len in the updater file header */ - uint32_t num_change_list_entries; /* num_change_list_entries in the updater change list header */ + char chk_name[1024 + 4]; /* Checksum file name */ + char ud_name[1024 + 4]; /* Updater file name */ + FILE * chk_fp; /* Checksum file pointer */ + FILE * ud_fp; /* Updater file pointer */ + uint64_t ud_seq_num; /* Sequence number in the updater file */ + uint64_t chk_ud_seq_num; /* Updater sequence number in the checksum file */ + uint64_t i; /* Local index variable */ + long size = 0; /* Size of the file */ + size_t change_list_len; /* change_list_len in the updater file header */ + uint32_t num_change_list_entries; /* num_change_list_entries in the updater change list header */ /* Open the checksum file */ HDsprintf(chk_name, "%s.chk", md_file_path); - if((chk_fp = HDfopen(chk_name, "r")) == NULL) + if ((chk_fp = HDfopen(chk_name, "r")) == NULL) FAIL_STACK_ERROR; - for(i = 0; ; i++) { + for (i = 0;; i++) { /* Generate updater file name: <ud_file_path>.<i> */ HDsprintf(ud_name, "%s.%lu", ud_file_path, i); @@ -4117,48 +4108,49 @@ verify_ud_chk(char *md_file_path, char *ud_file_path) break; else { /* Seek to the position of the sequence number in the updater file's header */ - if(HDfseek(ud_fp, (off_t)UD_HD_SEQ_NUM_OFFSET, SEEK_SET) < 0) + if (HDfseek(ud_fp, (off_t)UD_HD_SEQ_NUM_OFFSET, SEEK_SET) < 0) FAIL_STACK_ERROR; /* Read the sequence number from the updater file */ - if(HDfread(&ud_seq_num, UD_SIZE_8, 1, ud_fp) != 1) + if (HDfread(&ud_seq_num, UD_SIZE_8, 1, ud_fp) != 1) FAIL_STACK_ERROR; /* Compare the sequence number with i */ - if(ud_seq_num != i) + if (ud_seq_num != i) TEST_ERROR; /* Read change_list_len from updater file's header */ - if(HDfseek(ud_fp, (off_t)UD_HD_CHANGE_LIST_LEN_OFFSET, SEEK_SET) < 0) + if (HDfseek(ud_fp, (off_t)UD_HD_CHANGE_LIST_LEN_OFFSET, SEEK_SET) < 0) FAIL_STACK_ERROR; - if(HDfread(&change_list_len, UD_SIZE_8, 1, ud_fp) != 1) + if (HDfread(&change_list_len, UD_SIZE_8, 1, ud_fp) != 1) FAIL_STACK_ERROR; - if(i != 0) { - + if (i != 0) { + /* Read num_change_list_entries from updater file's change list */ - if(HDfseek(ud_fp, (off_t)UD_CL_NUM_CHANGE_LIST_ENTRIES_OFFSET, SEEK_SET) < 0) + if (HDfseek(ud_fp, (off_t)UD_CL_NUM_CHANGE_LIST_ENTRIES_OFFSET, SEEK_SET) < 0) FAIL_STACK_ERROR; - if(HDfread(&num_change_list_entries, UD_SIZE_4, 1, ud_fp) != 1) + if (HDfread(&num_change_list_entries, UD_SIZE_4, 1, ud_fp) != 1) FAIL_STACK_ERROR; - if(num_change_list_entries == 0) { - if(change_list_len != H5F_UD_CL_SIZE(0)) + if (num_change_list_entries == 0) { + if (change_list_len != H5F_UD_CL_SIZE(0)) TEST_ERROR; - } else { + } + else { if (change_list_len != H5F_UD_CL_SIZE(num_change_list_entries)) TEST_ERROR } } /* Close the updater file */ - if(HDfclose(ud_fp) < 0) + if (HDfclose(ud_fp) < 0) FAIL_STACK_ERROR; /* Read the updater sequence number from checksum file */ - if(HDfread(&chk_ud_seq_num, UD_SIZE_8, 1, chk_fp) != 1) + if (HDfread(&chk_ud_seq_num, UD_SIZE_8, 1, chk_fp) != 1) FAIL_STACK_ERROR; /* Compare sequence number in updater file with sequence number in checksum file */ @@ -4166,7 +4158,7 @@ verify_ud_chk(char *md_file_path, char *ud_file_path) TEST_ERROR; /* Advance checksum file to the next sequence number */ - if(HDfseek(chk_fp, (off_t)UD_SIZE_4, SEEK_CUR) < 0) + if (HDfseek(chk_fp, (off_t)UD_SIZE_4, SEEK_CUR) < 0) FAIL_STACK_ERROR; } } @@ -4176,7 +4168,7 @@ verify_ud_chk(char *md_file_path, char *ud_file_path) FAIL_STACK_ERROR; /* Size of sequence number and checksum in the checksum file */ - if((unsigned)size != (i * (UD_SIZE_8 + UD_SIZE_4))) + if ((unsigned)size != (i * (UD_SIZE_8 + UD_SIZE_4))) TEST_ERROR; return 0; @@ -4184,16 +4176,16 @@ verify_ud_chk(char *md_file_path, char *ud_file_path) error: return (-1); -} /* verify_ud_chk() */ +} /* verify_ud_chk() */ /*------------------------------------------------------------------------- * Function: md_ck_cb() * - * Purpose: This is the callback function used by - * test_updater_generate_md_checksums() when the + * Purpose: This is the callback function used by + * test_updater_generate_md_checksums() when the * H5F_ACS_GENERATE_MD_CK_CB_NAME property is set in fapl. * --Opens and read the metadata file into a buffer. - * --Generate checksum for the metadata file + * --Generate checksum for the metadata file * --Write the tick number and the checksum to the checksum file * * Return: 0 if test is sucessful @@ -4203,34 +4195,34 @@ error: * *------------------------------------------------------------------------- */ -static herr_t +static herr_t md_ck_cb(char *md_file_path, uint64_t updater_seq_num) { - FILE* md_fp = NULL; /* Metadata file pointer */ - FILE* chk_fp = NULL; /* Checksum file pointer */ - long size = 0; /* File size returned from HDftell() */ - void *buf = NULL; /* Buffer for holding the metadata file content */ - uint32_t chksum = 0; /* The checksum generated for the metadata file */ - char chk_name[1024 + 4]; /* Buffer for the checksum file name */ - size_t ret; /* Return value */ + FILE * md_fp = NULL; /* Metadata file pointer */ + FILE * chk_fp = NULL; /* Checksum file pointer */ + long size = 0; /* File size returned from HDftell() */ + void * buf = NULL; /* Buffer for holding the metadata file content */ + uint32_t chksum = 0; /* The checksum generated for the metadata file */ + char chk_name[1024 + 4]; /* Buffer for the checksum file name */ + size_t ret; /* Return value */ /* Open the metadata file */ - if((md_fp = HDfopen(md_file_path, "r")) == NULL) + if ((md_fp = HDfopen(md_file_path, "r")) == NULL) FAIL_STACK_ERROR; /* Set file pointer at end of file.*/ - if(HDfseek(md_fp, 0, SEEK_END) < 0) + if (HDfseek(md_fp, 0, SEEK_END) < 0) FAIL_STACK_ERROR; /* Get the current position of the file pointer.*/ if ((size = HDftell(md_fp)) < 0) FAIL_STACK_ERROR; - if(size != 0) { + if (size != 0) { HDrewind(md_fp); - if((buf = HDmalloc((size_t)size)) == NULL) + if ((buf = HDmalloc((size_t)size)) == NULL) FAIL_STACK_ERROR; /* Read the metadata file to buf */ @@ -4242,7 +4234,7 @@ md_ck_cb(char *md_file_path, uint64_t updater_seq_num) } /* Close the metadata file */ - if(md_fp && HDfclose(md_fp) < 0) + if (md_fp && HDfclose(md_fp) < 0) FAIL_STACK_ERROR; /* @@ -4253,36 +4245,36 @@ md_ck_cb(char *md_file_path, uint64_t updater_seq_num) HDsprintf(chk_name, "%s.chk", md_file_path); /* Open checksum file for append */ - if((chk_fp = HDfopen(chk_name, "a")) == NULL) + if ((chk_fp = HDfopen(chk_name, "a")) == NULL) FAIL_STACK_ERROR; /* Write the updater sequence number to the checksum file */ - if((ret = HDfwrite(&updater_seq_num, sizeof(uint64_t), 1, chk_fp)) != 1) + if ((ret = HDfwrite(&updater_seq_num, sizeof(uint64_t), 1, chk_fp)) != 1) FAIL_STACK_ERROR; /* Write the checksum to the checksum file */ - if((ret = HDfwrite(&chksum, sizeof(uint32_t), 1, chk_fp)) != 1) + if ((ret = HDfwrite(&chksum, sizeof(uint32_t), 1, chk_fp)) != 1) FAIL_STACK_ERROR; /* Close the checksum file */ - if(chk_fp && HDfclose(chk_fp) != 0) + if (chk_fp && HDfclose(chk_fp) != 0) FAIL_STACK_ERROR; - if(buf) + if (buf) HDfree(buf); return 0; error: - if(buf) + if (buf) HDfree(buf); - if(md_fp) + if (md_fp) HDfclose(md_fp); - if(chk_fp) + if (chk_fp) HDfclose(chk_fp); return -1; -} /* md_ck_cb() */ +} /* md_ck_cb() */ /*------------------------------------------------------------------------- * Function: test_updater_generate_md_checksums() @@ -4307,15 +4299,16 @@ error: static unsigned test_updater_generate_md_checksums(hbool_t file_create) { - hid_t fid = -1; /* File ID */ - hid_t fcpl = -1; /* File creation property list ID */ - hid_t fapl = -1; /* File access property list ID */ - H5F_vfd_swmr_config_t config; /* Configuration for VFD SWMR */ - H5F_generate_md_ck_cb_t cb_info; /* Callback */ + hid_t fid = -1; /* File ID */ + hid_t fcpl = -1; /* File creation property list ID */ + hid_t fapl = -1; /* File access property list ID */ + H5F_vfd_swmr_config_t config; /* Configuration for VFD SWMR */ + H5F_generate_md_ck_cb_t cb_info; /* Callback */ - if(file_create) { + if (file_create) { TESTING("VFD SWMR updater generate checksums for metadata file with H5Fcreate"); - } else { + } + else { TESTING("VFD SWMR updater generate checksums for metadata file with H5Fopen"); } @@ -4341,10 +4334,11 @@ test_updater_generate_md_checksums(hbool_t file_create) H5Pset(fapl, H5F_ACS_GENERATE_MD_CK_CB_NAME, &cb_info); /* Use file creation or file open for testing */ - if(file_create) { - if((fid = H5Fcreate(FILENAME4, H5F_ACC_TRUNC, fcpl, fapl)) < 0) + if (file_create) { + if ((fid = H5Fcreate(FILENAME4, H5F_ACC_TRUNC, fcpl, fapl)) < 0) TEST_ERROR; - } else { + } + else { fid = H5Fcreate(FILENAME4, H5F_ACC_TRUNC, fcpl, H5P_DEFAULT); H5Fclose(fid); @@ -4361,7 +4355,7 @@ test_updater_generate_md_checksums(hbool_t file_create) FAIL_STACK_ERROR; /* Verify contents of checksum file and updater files */ - if(verify_ud_chk(config.md_file_path, config.updater_file_path) < 0) + if (verify_ud_chk(config.md_file_path, config.updater_file_path) < 0) TEST_ERROR; /* It's important to clean up the chechsum and updater files. */ @@ -4387,7 +4381,6 @@ error: } /* test_updater_generate_md_checksums() */ - /*------------------------------------------------------------------------- * Function: main() * diff --git a/test/vfd_swmr_addrem_writer.c b/test/vfd_swmr_addrem_writer.c index a2982fd..ddf3f9c 100644 --- a/test/vfd_swmr_addrem_writer.c +++ b/test/vfd_swmr_addrem_writer.c @@ -94,8 +94,8 @@ open_skeleton(const char *filename, unsigned verbose) if ((config = HDcalloc(1, sizeof(*config))) == NULL) goto error; - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, - * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config, 4, 5, TRUE, TRUE, FALSE, TRUE, 128, "rw-shadow", NULL); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ diff --git a/test/vfd_swmr_bigset_writer.c b/test/vfd_swmr_bigset_writer.c index 928f7c7..14cbedf 100644 --- a/test/vfd_swmr_bigset_writer.c +++ b/test/vfd_swmr_bigset_writer.c @@ -2472,7 +2472,8 @@ main(int argc, char **argv) /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ - init_vfd_swmr_config(&config, s.tick_len, s.max_lag, s.writer, TRUE, FALSE, s.flush_raw_data, 128, "./bigset-shadow-%zu", NULL, i); + init_vfd_swmr_config(&config, s.tick_len, s.max_lag, s.writer, TRUE, FALSE, s.flush_raw_data, 128, + "./bigset-shadow-%zu", NULL, i); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ if ((fapl = vfd_swmr_create_fapl(true, s.use_vfd_swmr, true, s.page_buf_size, &config)) < 0) { diff --git a/test/vfd_swmr_common.c b/test/vfd_swmr_common.c index 90abeed..7e4ac59 100644 --- a/test/vfd_swmr_common.c +++ b/test/vfd_swmr_common.c @@ -347,8 +347,9 @@ await_signal(hid_t fid) */ void init_vfd_swmr_config(H5F_vfd_swmr_config_t *config, uint32_t tick_len, uint32_t max_lag, hbool_t writer, - hbool_t maintain_metadata_file, hbool_t generate_updater_files, hbool_t flush_raw_data, - uint32_t md_pages_reserved, const char *md_file_fmtstr, const char *updater_file_path, ...) + hbool_t maintain_metadata_file, hbool_t generate_updater_files, hbool_t flush_raw_data, + uint32_t md_pages_reserved, const char *md_file_fmtstr, const char *updater_file_path, + ...) { va_list ap; @@ -357,13 +358,13 @@ init_vfd_swmr_config(H5F_vfd_swmr_config_t *config, uint32_t tick_len, uint32_t config->version = H5F__CURR_VFD_SWMR_CONFIG_VERSION; config->pb_expansion_threshold = 0; - config->tick_len = tick_len; - config->max_lag = max_lag; - config->writer = writer; + config->tick_len = tick_len; + config->max_lag = max_lag; + config->writer = writer; config->maintain_metadata_file = maintain_metadata_file; config->generate_updater_files = generate_updater_files; - config->flush_raw_data = flush_raw_data; - config->md_pages_reserved = md_pages_reserved; + config->flush_raw_data = flush_raw_data; + config->md_pages_reserved = md_pages_reserved; HDva_start(ap, updater_file_path); @@ -371,7 +372,7 @@ init_vfd_swmr_config(H5F_vfd_swmr_config_t *config, uint32_t tick_len, uint32_t HDva_end(ap); - if(config->generate_updater_files && updater_file_path != NULL) + if (config->generate_updater_files && updater_file_path != NULL) HDstrcpy(config->updater_file_path, updater_file_path); } /* init_vfd_swmr_config() */ diff --git a/test/vfd_swmr_common.h b/test/vfd_swmr_common.h index 42569be..b842fe7 100644 --- a/test/vfd_swmr_common.h +++ b/test/vfd_swmr_common.h @@ -73,11 +73,11 @@ H5TEST_DLL void await_signal(hid_t); H5TEST_DLL hid_t vfd_swmr_create_fapl(bool use_latest_format, bool use_vfd_swmr, bool only_meta_pages, size_t page_buf_size, H5F_vfd_swmr_config_t *config); -H5TEST_DLL void -init_vfd_swmr_config(H5F_vfd_swmr_config_t *config, uint32_t tick_len, uint32_t max_lag, hbool_t writer, - hbool_t maintain_metadata_file, hbool_t generate_updater_files, hbool_t flush_raw_data, - uint32_t md_pages_reserved, const char *md_file_fmtstr, - const char *updater_file_path, ...) H5_ATTR_FORMAT(printf, 9, 11); +H5TEST_DLL void init_vfd_swmr_config(H5F_vfd_swmr_config_t *config, uint32_t tick_len, uint32_t max_lag, + hbool_t writer, hbool_t maintain_metadata_file, + hbool_t generate_updater_files, hbool_t flush_raw_data, + uint32_t md_pages_reserved, const char *md_file_fmtstr, + const char *updater_file_path, ...) H5_ATTR_FORMAT(printf, 9, 11); H5TEST_DLL void init_vfd_swmr_log(H5F_vfd_swmr_config_t *config, const char *log_file_fmtstr, ...) H5_ATTR_FORMAT(printf, 2, 3); diff --git a/test/vfd_swmr_dsetchks_writer.c b/test/vfd_swmr_dsetchks_writer.c index 3cf43f9..c09c825 100644 --- a/test/vfd_swmr_dsetchks_writer.c +++ b/test/vfd_swmr_dsetchks_writer.c @@ -2304,7 +2304,8 @@ main(int argc, char **argv) /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ - init_vfd_swmr_config(&config, 4, 7, writer, TRUE, FALSE, s.flush_raw_data, 128, "./dsetchks-shadow", NULL); + init_vfd_swmr_config(&config, 4, 7, writer, TRUE, FALSE, s.flush_raw_data, 128, "./dsetchks-shadow", + NULL); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ if ((fapl = vfd_swmr_create_fapl(true, s.use_vfd_swmr, true, 4096, &config)) < 0) { diff --git a/test/vfd_swmr_gfail_writer.c b/test/vfd_swmr_gfail_writer.c index 2be58e2..aef39a0 100644 --- a/test/vfd_swmr_gfail_writer.c +++ b/test/vfd_swmr_gfail_writer.c @@ -546,7 +546,8 @@ main(int argc, char **argv) /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ - init_vfd_swmr_config(&config, s.tick_len, s.max_lag, writer, TRUE, FALSE, TRUE, 128, "./group-shadow", NULL); + init_vfd_swmr_config(&config, s.tick_len, s.max_lag, writer, TRUE, FALSE, TRUE, 128, "./group-shadow", + NULL); /* 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 diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c index 18f3199..1ca4483 100644 --- a/test/vfd_swmr_gperf_writer.c +++ b/test/vfd_swmr_gperf_writer.c @@ -2786,9 +2786,10 @@ main(int argc, char **argv) return EXIT_SUCCESS; } - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, - * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ - init_vfd_swmr_config(&config, s.tick_len, s.max_lag, writer, TRUE, FALSE, FALSE, 128, "./group-shadow", NULL); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(&config, s.tick_len, s.max_lag, writer, TRUE, FALSE, FALSE, 128, "./group-shadow", + NULL); /* If the log flag is on, create the log file log-test under the current directory. */ if (s.glog == true) diff --git a/test/vfd_swmr_group_writer.c b/test/vfd_swmr_group_writer.c index af46f3d..eb7bb0e 100644 --- a/test/vfd_swmr_group_writer.c +++ b/test/vfd_swmr_group_writer.c @@ -5013,7 +5013,8 @@ main(int argc, char **argv) /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ - init_vfd_swmr_config(&config, s.tick_len, s.max_lag, writer, TRUE, FALSE, TRUE, 128, "./group-shadow", NULL); + init_vfd_swmr_config(&config, s.tick_len, s.max_lag, writer, TRUE, FALSE, TRUE, 128, "./group-shadow", + NULL); /* 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 diff --git a/test/vfd_swmr_reader.c b/test/vfd_swmr_reader.c index 2b960c13..d6a87dd 100644 --- a/test/vfd_swmr_reader.c +++ b/test/vfd_swmr_reader.c @@ -319,8 +319,8 @@ read_records(const char *filename, hbool_t verbose, FILE *verbose_file, unsigned goto error; } - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, - * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config, 4, 5, FALSE, TRUE, FALSE, TRUE, 128, "rw-shadow", NULL); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ diff --git a/test/vfd_swmr_remove_reader.c b/test/vfd_swmr_remove_reader.c index 18dbb62..bc00756 100644 --- a/test/vfd_swmr_remove_reader.c +++ b/test/vfd_swmr_remove_reader.c @@ -303,8 +303,8 @@ read_records(const char *filename, unsigned verbose, unsigned long nseconds, uns if ((config = HDcalloc(1, sizeof(*config))) == NULL) goto error; - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, - * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config, 4, 5, FALSE, TRUE, FALSE, TRUE, 128, "rw-shadow", NULL); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ diff --git a/test/vfd_swmr_remove_writer.c b/test/vfd_swmr_remove_writer.c index 41c2300..6b0c13f 100644 --- a/test/vfd_swmr_remove_writer.c +++ b/test/vfd_swmr_remove_writer.c @@ -86,8 +86,8 @@ open_skeleton(const char *filename, unsigned verbose, unsigned old H5_ATTR_UNUSE if ((config = (H5F_vfd_swmr_config_t *)HDcalloc(1, sizeof(H5F_vfd_swmr_config_t))) == NULL) goto error; - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, - * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config, 4, 5, TRUE, TRUE, FALSE, TRUE, 128, "rw-shadow", NULL); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ diff --git a/test/vfd_swmr_sparse_reader.c b/test/vfd_swmr_sparse_reader.c index a737f70..6a7ba2f 100644 --- a/test/vfd_swmr_sparse_reader.c +++ b/test/vfd_swmr_sparse_reader.c @@ -207,8 +207,8 @@ read_records(const char *filename, unsigned verbose, unsigned long nrecords, uns if ((config = HDcalloc(1, sizeof(H5F_vfd_swmr_config_t))) == NULL) goto error; - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, - * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config, 4, 5, FALSE, TRUE, FALSE, TRUE, 128, "rw-shadow", NULL); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ diff --git a/test/vfd_swmr_sparse_writer.c b/test/vfd_swmr_sparse_writer.c index f473249..f78bf8b 100644 --- a/test/vfd_swmr_sparse_writer.c +++ b/test/vfd_swmr_sparse_writer.c @@ -86,8 +86,8 @@ open_skeleton(const char *filename, unsigned verbose) if ((config = (H5F_vfd_swmr_config_t *)HDcalloc(1, sizeof(H5F_vfd_swmr_config_t))) == NULL) goto error; - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, - * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config, 4, 5, TRUE, TRUE, FALSE, TRUE, 128, "rw-shadow", NULL); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ diff --git a/test/vfd_swmr_writer.c b/test/vfd_swmr_writer.c index 0fb5fe8..a630532 100644 --- a/test/vfd_swmr_writer.c +++ b/test/vfd_swmr_writer.c @@ -88,8 +88,8 @@ open_skeleton(const char *filename, hbool_t verbose, FILE *verbose_file, unsigne if ((config = (H5F_vfd_swmr_config_t *)HDcalloc(1, sizeof(H5F_vfd_swmr_config_t))) == NULL) return -1; - /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, - * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ init_vfd_swmr_config(config, 4, 5, TRUE, TRUE, FALSE, TRUE, 128, "rw-shadow", NULL); /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ -- cgit v0.12 From 9ee9d67dc9fd6e4a59f6f9e1b1112e41f639a2fc Mon Sep 17 00:00:00 2001 From: Dana Robinson <43805+derobins@users.noreply.github.com> Date: Mon, 29 Nov 2021 15:08:09 -0800 Subject: Updated submodule to reflect recent changes (#1235) --- utils/vfd_swmr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/vfd_swmr b/utils/vfd_swmr index b0b2f45..5f4b020 160000 --- a/utils/vfd_swmr +++ b/utils/vfd_swmr @@ -1 +1 @@ -Subproject commit b0b2f45944e6526eeb67f04ed4f8b825053d2e75 +Subproject commit 5f4b020713f3194222311b2e87b29f0de0722ed2 -- cgit v0.12 From 210464603ed5f01144b3f18d0c368ef335cdae14 Mon Sep 17 00:00:00 2001 From: myang6 <myang6@hdfgroup.org> Date: Wed, 1 Dec 2021 12:13:22 -0600 Subject: Add the test for independence of reader and writer. --- MANIFEST | 1 + test/Makefile.am | 5 + test/testvfdswmr.sh.in | 26 +- test/vfd_swmr_indep_rw_writer.c | 784 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 813 insertions(+), 3 deletions(-) create mode 100644 test/vfd_swmr_indep_rw_writer.c diff --git a/MANIFEST b/MANIFEST index 75a7aca..65141b3 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1435,6 +1435,7 @@ ./test/vfd_swmr_group_writer.c ./test/vfd_swmr_gperf_writer.c ./test/vfd_swmr_gfail_writer.c +./test/vfd_swmr_indep_rw_writer.c ./test/vfd_swmr_reader.c ./test/vfd_swmr_remove_reader.c ./test/vfd_swmr_remove_writer.c diff --git a/test/Makefile.am b/test/Makefile.am index 87b2925..f7ed4c6 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_indep_wr_p0$(EXEEXT) vfd_swmr_indep_wr_p1$(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_indep_wr_p0 vfd_swmr_indep_wr_p1 \ 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,9 @@ 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_indep_wr_p0_SOURCES=vfd_swmr_indep_rw_writer.c +vfd_swmr_indep_wr_p1_SOURCES=vfd_swmr_indep_rw_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/testvfdswmr.sh.in b/test/testvfdswmr.sh.in index 535aafa..d52527b 100644 --- a/test/testvfdswmr.sh.in +++ b/test/testvfdswmr.sh.in @@ -143,13 +143,14 @@ fi all_tests="generator expand shrink expand_shrink sparse vlstr_null vlstr_oob zoo" all_tests="${all_tests} groups groups_attrs groups_ops few_big many_small attrdset" -tests=${all_tests} -# For exhaustive run, add: os_groups_attrs, os_groups_ops, os_groups_seg, dsetops, dsetchks +# For exhaustive run, add: os_groups_attrs, os_groups_ops, os_groups_seg, dsetops, dsetchks,independ_wr if [[ "$HDF5TestExpress" -eq 0 ]] ; then # exhaustive run - all_tests="${all_tests} os_groups_attrs os_groups_ops os_groups_seg dsetops dsetchks" + all_tests="${all_tests} os_groups_attrs os_groups_ops os_groups_seg dsetops dsetchks independ_wr" fi +tests=${all_tests} + if [ $# -gt 0 ]; then tests= fi @@ -1367,6 +1368,25 @@ for flush in "" "-U"; do done done +if [ ${do_independ_wr:-no} = yes ]; then + echo launch vfd_swmr_indep_wr_p0 ..... process 0 ...... + echo launch vfd_swmr_indep_wr_p1 ..... process 1 ...... + catch_out_err_and_rc vfd_swmr_indep_wr_p0 \ + ../vfd_swmr_indep_wr_p0 & + pid_writer=$! + + catch_out_err_and_rc vfd_swmr_group_reader \ + ../vfd_swmr_indep_wr_p1 & + pid_reader=$! + + wait $pid_reader + wait $pid_writer + # Clean up output files + rm -f vfd_swmr_indep_wr_p0.{out,rc} + rm -f vfd_swmr_indep_wr_p1.{out,rc} +fi + + ############################################################################### ## Report and exit ############################################################################### diff --git a/test/vfd_swmr_indep_rw_writer.c b/test/vfd_swmr_indep_rw_writer.c new file mode 100644 index 0000000..1d1a530 --- /dev/null +++ b/test/vfd_swmr_indep_rw_writer.c @@ -0,0 +1,784 @@ +/* + * Copyright by The HDF Group. + * Copyright by the Board of Trustees of the University of Illinois. + * All rights reserved. + * + * This file is part of HDF5. The full HDF5 copyright notice, including + * terms governing use, modification, and redistribution, is contained in + * the COPYING file, which can be found at the root of the source code + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. + * If you do not have access to either file, you may request a copy from + * help@hdfgroup.org. + */ + +/* This program checks independence of writer and reader for VFD SWMR. + * A writer can also be a reader of another writer. A reader can also be a + * writer. The program adapts from the "many small" and the "few big" tests. + * One can test the program as follows: + * Run ./vfd_swmr_indep_wr_p0 at one terminal + * Run ./vfd_swmr_indep_wr_p1 at another terminal + * You should see something like: + * Successfully write the dataset /dataset-0 for file vfd_swmr_indep_wr_p0.h5. + * Successfully open the dataset /dataset-1 for file vfd_swmr_indep_wr_p1.h5. + * Successfully verify a dataset. + * and + * Successfully open the dataset /dataset-0 for file vfd_swmr_indep_wr_p0.h5. + * Successfully verify a dataset. + * Successfully write the dataset /dataset-1 for file vfd_swmr_indep_wr_p1.h5. + */ + +#define H5C_FRIEND /*suppress error about including H5Cpkg */ +#define H5F_FRIEND /*suppress error about including H5Fpkg */ + +#include "hdf5.h" +#include "H5Cpkg.h" +#include "H5Fpkg.h" +#include "H5HGprivate.h" +#include "H5VLprivate.h" + +#include "testhdf5.h" +#include "vfd_swmr_common.h" + +#ifndef H5_HAVE_WIN32_API + +#define DATA_ROWS 256 +#define DATA_COLS 512 +#define DATA_RANK 2 +#define NUM_ATTEMPTS 100 + +typedef struct _mat { + unsigned rows, cols; + uint32_t elt[1]; +} mat_t; + +typedef struct { + hid_t file[2]; + const char *filename[2]; + char progname[PATH_MAX]; + hid_t r_dsetid; + hid_t dtype,fapl,fcpl; + unsigned int rows,cols; + int rank; + hsize_t dims[DATA_RANK]; + uint32_t max_lag; + uint32_t tick_len; + uint32_t ps; + uint32_t pbs; + uint32_t check_interval; + bool use_vfd_swmr; + bool first_proc; +} state_t; + +static inline state_t +state_initializer(void) +{ + return (state_t){ + .file = {H5I_INVALID_HID, H5I_INVALID_HID} + , .filename = {"", ""} + , .r_dsetid = H5I_INVALID_HID + , .dtype = H5T_NATIVE_UINT32 + , .fapl = H5I_INVALID_HID + , .fcpl = H5I_INVALID_HID + , .rows = DATA_ROWS + , .cols = DATA_COLS + , .rank = DATA_RANK + , .dims = { DATA_ROWS, DATA_COLS} + , .max_lag = 7 + , .tick_len = 4 + , .ps = 4096 + , .pbs = 4096 + , .check_interval = 1 + , .use_vfd_swmr = true + , .first_proc = true}; +} + +static uint32_t +matget(const mat_t *mat, unsigned i, unsigned j) +{ + return mat->elt[i * mat->cols + j]; +} + +static bool +matset(mat_t *mat, unsigned i, unsigned j, uint32_t v) +{ + if (i >= mat->rows || j >= mat->cols) { + HDfprintf(stderr, "index out of boundary\n"); + TEST_ERROR; + } + + mat->elt[i * mat->cols + j] = v; + + return true; + +error: + return false; +} + +static mat_t * +newmat(state_t s) +{ + mat_t *mat; + + mat = HDmalloc(sizeof(*mat) + (s.rows * s.cols - 1) * sizeof(mat->elt[0])); + if (mat == NULL) { + HDfprintf(stderr, "HDmalloc failed\n"); + TEST_ERROR; + } + + mat->rows = s.rows; + mat->cols = s.cols; + + return mat; + +error: + return NULL; +} + +/* Write or verify the dataset test pattern in the matrix `mat`. + * If `do_set` is true, write the pattern; otherwise, verify. + * + * The basic test pattern consists of increasing + * integers written in nested corners of the dataset + * starting at element (0, 0): + * + * 0 + * + * 0 1 + * 3 2 + * + * 0 1 4 + * 3 2 5 + * 8 7 6 + * + * 0 1 4 9 + * 3 2 5 10 + * 8 7 6 11 + * 15 14 13 12 + * + * In an actual pattern, the dataset number, `which`, is added to each integer. + * + */ +static bool +set_or_verify_matrix(mat_t *mat, unsigned int which, bool do_set) +{ + unsigned row, col; + bool ret = true; + + for (row = 0; row < mat->rows; row++) { + for (col = 0; col < mat->cols; col++) { + uint32_t v; + hsize_t i = row, j = col, u; + if (j <= i) + u = (i + 1) * (i + 1) - 1 - j; + else + u = j * j + i; + + v = (uint32_t)(u + which); + + if (do_set) { + if (!matset(mat, row, col, v)) { + HDfprintf(stderr, "data initialization failed\n"); + ret = false; + break; + } + } + else if (matget(mat, row, col) != v) { + /* If the data doesn't match, return false + */ + dbgf(1,"vrfy_matrix failed at row %u,col %u\n",row,col); + dbgf(1,"real value is %u\n",matget(mat,row,col)); + dbgf(1,"expected value is %u\n",v); + ret = false; + break; + } + + } + } + + return ret; +} + +static bool +init_matrix(mat_t *mat, unsigned int which) +{ + return set_or_verify_matrix(mat, which, true); +} + +static bool +verify_matrix(mat_t *mat, unsigned int which) +{ + return set_or_verify_matrix(mat, which, false); +} + + +static void +usage(const char *progname) +{ + fprintf(stderr, "usage: %s [-S] [-c cols] [-r rows] [-t tick_len] [-m max_lag] \n" + " [-B page_buffer_size] [-s page_size] [-u reader wait interval] [-q silent output] \n" + "\n" + "-S: do not use VFD SWMR\n" + "-c cols: `cols` columns for the dataset\n" + " The default value is 512.\n" + "-r rows: `rows` rows for the dataset\n" + " The default value is 256.\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. The default value is 4K(4096).\n" + "-u 0.1s: interval in tenth of seconds to check if a dataset is ready for the reader.\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; + char *tfile = NULL; + char *end; + const char *personality; + + *s = state_initializer(); + + if (H5_basename(argv[0], &tfile) < 0) { + HDprintf("H5_basename failed\n"); + TEST_ERROR; + } + + esnprintf(s->progname, sizeof(s->progname), "%s", tfile); + + if (tfile) { + HDfree(tfile); + tfile = NULL; + } + + while ((ch = getopt(argc, argv, "Sqc:r:t:m:B:s:u:")) != -1) { + switch (ch) { + case 'S': + s->use_vfd_swmr = false; + break; + case 'c': + case 'r': + case 't': + case 'm': + case 'B': + case 's': + case 'u': + errno = 0; + tmp = HDstrtoul(optarg, &end, 0); + if (end == optarg || *end != '\0') { + HDfprintf(stderr, "couldn't parse -%c argument %s\n", ch, optarg); + TEST_ERROR; + } + else if (errno != 0) { + HDfprintf(stderr, "couldn't parse -%c argument %s\n", ch, optarg); + TEST_ERROR; + } + else if (tmp > UINT_MAX) { + HDfprintf(stderr, "-%c argument %lu too large", ch, tmp); + TEST_ERROR; + } + if ((ch == 'c' || ch == 'r') && tmp == 0) { + HDfprintf(stderr, "-%c argument %lu must be >= 1", ch, tmp); + TEST_ERROR; + } + + if (ch == 'c') + s->cols = (unsigned)tmp; + else if (ch == 'r') + s->rows = (unsigned)tmp; + else if (ch == 't') + s->tick_len = (unsigned)tmp; + else if (ch == 'm') + s->max_lag = (unsigned)tmp; + else if (ch == 'B') + s->pbs = (unsigned)tmp; + else if (ch == 's') + s->ps = (unsigned)tmp; + else if (ch == 'u') + s->check_interval = (unsigned)tmp; + break; + case 'q': + verbosity = 0; + break; + case '?': + default: + usage(s->progname); + break; + } + } + argc -= optind; + argv += optind; + + if (argc > 0) { + HDprintf("unexpected command-line arguments\n"); + TEST_ERROR; + } + + s->filename[0] = "vfd_swmr_indep_wr_p0.h5"; + s->filename[1] = "vfd_swmr_indep_wr_p1.h5"; + s->dims[0] = s->rows; + s->dims[1] = s->cols; + + personality = HDstrstr(s->progname, "vfd_swmr_indep_wr"); + + if (personality != NULL && + HDstrcmp(personality, "vfd_swmr_indep_wr_p0") == 0) + s->first_proc = true; + else if (personality != NULL && + HDstrcmp(personality, "vfd_swmr_indep_wr_p1") == 0) + s->first_proc = false; + else { + HDprintf("unknown personality, expected vfd_swmr_indep_wr_{p0,p1}\n"); + TEST_ERROR; + } + + return true; + +error: + if (tfile) + HDfree(tfile); + return false; + +} + +static bool indep_init_vfd_swmr_config_plist(state_t *s,bool writer,const char* mdf_path){ + + H5F_vfd_swmr_config_t config; + + /* 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, TRUE, 128, mdf_path); + + /* Pass the use_vfd_swmr, only_meta_page, page buffer size, config to vfd_swmr_create_fapl().*/ + if ((s->fapl = vfd_swmr_create_fapl(true, 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 ((s->fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, s->ps)) < 0) { + HDprintf("vfd_swmr_create_fcpl() failed"); + TEST_ERROR; + } + + return true; + +error: + return false; + +} + +static bool write_dataset(const state_t *s, mat_t *mat) { + + char dname[sizeof("/dataset-?")]; + hid_t dset_id = H5I_INVALID_HID; + hid_t filespace = H5I_INVALID_HID; + unsigned int which = 0; + + if(s->first_proc) + esnprintf(dname, sizeof(dname), "/dataset-%d", 0); + else { + esnprintf(dname, sizeof(dname), "/dataset-%d", 1); + which = 1; + } + + filespace = H5Screate_simple(s->rank, s->dims,NULL); + if (filespace < 0) { + HDfprintf(stderr, "H5Screate_simple failed\n"); + TEST_ERROR; + } + + if((dset_id = H5Dcreate2(s->file[which], dname, s->dtype, filespace, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) <0 ) { + HDfprintf(stderr, "H5Dcreate2 failed\n"); + TEST_ERROR; + } + + if (H5Sclose(filespace) < 0) { + HDfprintf(stderr, "H5Sclose failed\n"); + TEST_ERROR; + } + + if (!init_matrix(mat, which)) { + HDfprintf(stderr, "data initialization failed\n"); + TEST_ERROR; + } + + if (H5Dwrite(dset_id, H5T_NATIVE_UINT32, H5S_ALL, H5S_ALL, H5P_DEFAULT, mat->elt) < 0) { + HDfprintf(stderr, "H5Dwrite failed\n"); + TEST_ERROR; + } + + if (H5Dclose(dset_id) < 0) { + HDfprintf(stderr, "H5Dclose failed\n"); + TEST_ERROR; + } + + if(s->first_proc) + dbgf(1,"Process 0: Successfully write the dataset %s for file %s.\n",dname,s->filename[which]); + else + dbgf(1,"Process 1: Successfully write the dataset %s for file %s.\n",dname,s->filename[which]); + + return true; + +error: + H5E_BEGIN_TRY + { + H5Sclose(filespace); + H5Dclose(dset_id); + } + H5E_END_TRY; + + return false; +} + +static bool open_dset(state_t *s) { + + char dname[sizeof("/dataset-?")]; + hid_t dset_id; + unsigned int i; + unsigned int fopen_idx = 0; + + /* The first process reads the dataset from the second process + * The second process reads the dataset from the first process + */ + if(s->first_proc) { + esnprintf(dname, sizeof(dname), "/dataset-%d", 1); + fopen_idx = 1; + } + else { + esnprintf(dname, sizeof(dname), "/dataset-%d", 0); + fopen_idx = 0; + } + + + /* Same as the big dset test, tries to open the dataset repeatedly until successful. After trying + * NUM_ATTEMPTS times without success, report it as a failure + */ + for (i = 0; i < NUM_ATTEMPTS; i++) { + H5E_BEGIN_TRY + { + dset_id = H5Dopen2(s->file[fopen_idx], dname, H5P_DEFAULT); + } + H5E_END_TRY; + + if (dset_id >= 0) + break; + else + decisleep(s->check_interval); + } + + s->r_dsetid = dset_id; + if (i == NUM_ATTEMPTS) { + HDfprintf(stderr, "dataset opening reachs the maximal number of attempts\n"); + TEST_ERROR; + } + + if(s->first_proc) + dbgf(1,"Process 0: Successfully open the dataset %s for file %s.\n",dname,s->filename[fopen_idx]); + else + dbgf(1,"Process 1: Successfully open the dataset %s for file %s.\n",dname,s->filename[fopen_idx]); + return true; + +error: + return false; +} + +static bool vrfy_dset(const state_t *s, mat_t *mat) { + + unsigned int i; + unsigned int which = 0; + herr_t status; + + /* A failure to read the data may indicate the data isn't ready yet. Instead of displaying the error + * stack, simply return false and let the caller repeat this step. + */ + + for (i = 0; i < NUM_ATTEMPTS; i++) { + H5E_BEGIN_TRY + { + status = H5Dread(s->r_dsetid, H5T_NATIVE_UINT32, H5S_ALL, H5S_ALL, H5P_DEFAULT, mat->elt); + } + H5E_END_TRY; + if(status <0) { + decisleep(1); + /* Refresh the dataset and try it again */ + if (H5Drefresh(s->r_dsetid) < 0) { + HDfprintf(stderr, "H5Drefresh failed\n"); + TEST_ERROR; + } + } + else + break; + } + if (i == NUM_ATTEMPTS) { + HDfprintf(stderr, "dataset verification reached the maximal number of attempts\n"); + TEST_ERROR; + } + if(s->first_proc) + which = 1; + + if (verify_matrix(mat,which) == false) { + HDfprintf(stderr, "dataset verification failed\n"); + TEST_ERROR; + } + + if(s->first_proc) + dbgf(1,"Process 0: Successfully verify a dataset.\n"); + else + dbgf(1,"Process 1: Successfully verify a dataset.\n"); + + return true; + +error: + return false; +} + +static bool read_vrfy_dataset(state_t *s, mat_t *mat) { + + if(false == open_dset(s)) { + HDfprintf(stderr, "Reader: open_dataset() failed\n"); + TEST_ERROR; + } + if(false == vrfy_dset(s,mat)) { + HDfprintf(stderr, "Reader: vrfy_dataset() failed\n"); + TEST_ERROR; + } + + if(H5Dclose(s->r_dsetid)<0) { + HDfprintf(stderr, "Reader: H5Dclose() failed\n"); + TEST_ERROR; + } + return true; + +error: + + H5E_BEGIN_TRY { + H5Dclose(s->r_dsetid); + } + H5E_END_TRY; + return false; + +} + + +static bool close_pl(const state_t *s) { + + if (H5Pclose(s->fapl) < 0) { + printf("H5Pclose failed\n"); + TEST_ERROR; + } + + if (H5Pclose(s->fcpl) < 0) { + printf("H5Pclose failed\n"); + TEST_ERROR; + } + + return true; + +error: + H5E_BEGIN_TRY + { + H5Pclose(s->fapl); + H5Pclose(s->fcpl); + } + H5E_END_TRY; + + return false; + +} + +int +main(int argc, char **argv) +{ + bool writer = true; + state_t s; + bool ret = false; + unsigned i; + mat_t * mat = NULL; + + + if (!state_init(&s, argc, argv)) { + HDfprintf(stderr,"state_init failed\n"); + TEST_ERROR; + } + + if ((mat = newmat(s)) == NULL) { + HDfprintf(stderr, "could not allocate memory for dataset \n"); + TEST_ERROR; + } + + if(s.first_proc) { + + writer = true; + if(false == indep_init_vfd_swmr_config_plist(&s,writer,"./file1-shadow")) { + HDfprintf(stderr,"Writer: Cannot initialize file property lists for file %s\n",s.filename[0]); + TEST_ERROR; + } + s.file[0] = H5Fcreate(s.filename[0], H5F_ACC_TRUNC, s.fcpl, s.fapl); + if (s.file[0] < 0) { + HDfprintf(stderr, "H5Fcreate failed for the file %s\n",s.filename[0]); + TEST_ERROR; + } + + ret = write_dataset(&s,mat); + if (ret == false) { + HDfprintf(stderr, "write_dataset failed for the file %s\n", s.filename[0]); + TEST_ERROR; + } + + /* writer makes repeated HDF5 API calls + * to trigger EOT at approximately the correct time */ + for (i = 0; i < s.max_lag + 1; i++) { + decisleep(s.tick_len); + H5E_BEGIN_TRY + { + H5Aexists(s.file[0], "nonexistent"); + } + H5E_END_TRY; + } + + if (false == close_pl(&s)) { + HDfprintf(stderr, "Fail to close file property lists for writing the file %s.\n",s.filename[0]); + TEST_ERROR; + } + + writer = false; + if(false == indep_init_vfd_swmr_config_plist(&s,writer,"./file2-shadow")) { + HDfprintf(stderr, "Reader: Cannot initialize file property lists for file %s\n",s.filename[1]); + TEST_ERROR; + } + s.file[1] = H5Fopen(s.filename[1], H5F_ACC_RDONLY, s.fapl); + if (s.file[1] < 0) { + HDfprintf(stderr, "H5Fopen failed for the file %s\n",s.filename[1]); + TEST_ERROR; + } + + ret = read_vrfy_dataset(&s,mat); + if (ret == false) { + HDfprintf(stderr, "read and verify dataset failed for file %s\n",s.filename[1]); + TEST_ERROR; + } + + if (false == close_pl(&s)) { + HDfprintf(stderr, "Fail to close file property lists for reading the file %s.\n",s.filename[1]); + TEST_ERROR; + } + + if (H5Fclose(s.file[0]) < 0) { + HDfprintf(stderr,"fail to close HDF5 file %s \n",s.filename[0]); + TEST_ERROR; + } + + if (H5Fclose(s.file[1]) < 0) { + HDfprintf(stderr, "fail to close HDF5 file %s \n",s.filename[1]); + TEST_ERROR; + } + } + else { + + writer = false; + if(false == indep_init_vfd_swmr_config_plist(&s,writer,"./file1-shadow")) { + HDfprintf(stderr,"Reader: Cannot initialize file property lists for file %s\n",s.filename[0]); + TEST_ERROR; + } + + s.file[0] = H5Fopen(s.filename[0], H5F_ACC_RDONLY, s.fapl); + if (s.file[0] < 0) { + HDfprintf(stderr, "H5Fopen failed for the file %s\n",s.filename[0]); + TEST_ERROR; + } + ret = read_vrfy_dataset(&s,mat); + if (ret == false) { + HDfprintf(stderr, "read and verify dataset failed for file %s\n",s.filename[0]); + TEST_ERROR; + } + + if (false == close_pl(&s)) { + HDfprintf(stderr,"Fail to close file property lists for reading the file %s.\n",s.filename[0]); + TEST_ERROR; + } + + writer = true; + if(false == indep_init_vfd_swmr_config_plist(&s,writer,"./file2-shadow")) { + HDfprintf(stderr, "writer: Cannot initialize file property lists for file %s\n",s.filename[1]); + TEST_ERROR; + } + + s.file[1] = H5Fcreate(s.filename[1], H5F_ACC_TRUNC, s.fcpl, s.fapl); + if (s.file[1] < 0) { + HDfprintf(stderr, "H5Fcreate failed for the file %s\n",s.filename[1]); + TEST_ERROR; + } + ret = write_dataset(&s,mat); + if (ret == false) { + HDfprintf(stderr, "write_dataset failed for the file %s\n", s.filename[1]); + TEST_ERROR; + } + + /* writer makes repeated HDF5 API calls + * to trigger EOT at approximately the correct time */ + for (i = 0; i < s.max_lag + 1; i++) { + decisleep(s.tick_len); + H5E_BEGIN_TRY + { + H5Aexists(s.file[1], "nonexistent"); + } + H5E_END_TRY; + } + + if (false == close_pl(&s)) { + HDfprintf(stderr, "Fail to close file property lists for writing the file %s.\n",s.filename[1]); + TEST_ERROR; + } + + if (H5Fclose(s.file[0]) < 0) { + HDfprintf(stderr,"fail to close HDF5 file %s \n",s.filename[0]); + TEST_ERROR; + } + + if (H5Fclose(s.file[1]) < 0) { + HDfprintf(stderr, "fail to close HDF5 file %s \n",s.filename[1]); + TEST_ERROR; + } + } + + if (mat) + HDfree(mat); + + + return EXIT_SUCCESS; + +error: + H5E_BEGIN_TRY + { + H5Pclose(s.fapl); + H5Pclose(s.fcpl); + H5Fclose(s.file[0]); + H5Fclose(s.file[1]); + } + H5E_END_TRY; + + if (mat) + HDfree(mat); + + 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 67c0a04d74f2024a6482fc2d3fab8be8a78bfada Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 1 Dec 2021 18:17:15 +0000 Subject: Committing clang-format changes --- test/vfd_swmr_indep_rw_writer.c | 450 ++++++++++++++++++++-------------------- 1 file changed, 225 insertions(+), 225 deletions(-) diff --git a/test/vfd_swmr_indep_rw_writer.c b/test/vfd_swmr_indep_rw_writer.c index 1d1a530..3aa8a2e 100644 --- a/test/vfd_swmr_indep_rw_writer.c +++ b/test/vfd_swmr_indep_rw_writer.c @@ -11,8 +11,8 @@ * help@hdfgroup.org. */ -/* This program checks independence of writer and reader for VFD SWMR. - * A writer can also be a reader of another writer. A reader can also be a +/* This program checks independence of writer and reader for VFD SWMR. + * A writer can also be a reader of another writer. A reader can also be a * writer. The program adapts from the "many small" and the "few big" tests. * One can test the program as follows: * Run ./vfd_swmr_indep_wr_p0 at one terminal @@ -21,14 +21,14 @@ * Successfully write the dataset /dataset-0 for file vfd_swmr_indep_wr_p0.h5. * Successfully open the dataset /dataset-1 for file vfd_swmr_indep_wr_p1.h5. * Successfully verify a dataset. - * and + * and * Successfully open the dataset /dataset-0 for file vfd_swmr_indep_wr_p0.h5. * Successfully verify a dataset. * Successfully write the dataset /dataset-1 for file vfd_swmr_indep_wr_p1.h5. */ -#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 "H5Cpkg.h" @@ -41,9 +41,9 @@ #ifndef H5_HAVE_WIN32_API -#define DATA_ROWS 256 -#define DATA_COLS 512 -#define DATA_RANK 2 +#define DATA_ROWS 256 +#define DATA_COLS 512 +#define DATA_RANK 2 #define NUM_ATTEMPTS 100 typedef struct _mat { @@ -52,44 +52,43 @@ typedef struct _mat { } mat_t; typedef struct { - hid_t file[2]; - const char *filename[2]; - char progname[PATH_MAX]; - hid_t r_dsetid; - hid_t dtype,fapl,fcpl; - unsigned int rows,cols; - int rank; - hsize_t dims[DATA_RANK]; - uint32_t max_lag; - uint32_t tick_len; - uint32_t ps; - uint32_t pbs; - uint32_t check_interval; - bool use_vfd_swmr; - bool first_proc; + hid_t file[2]; + const char * filename[2]; + char progname[PATH_MAX]; + hid_t r_dsetid; + hid_t dtype, fapl, fcpl; + unsigned int rows, cols; + int rank; + hsize_t dims[DATA_RANK]; + uint32_t max_lag; + uint32_t tick_len; + uint32_t ps; + uint32_t pbs; + uint32_t check_interval; + bool use_vfd_swmr; + bool first_proc; } state_t; static inline state_t state_initializer(void) { - return (state_t){ - .file = {H5I_INVALID_HID, H5I_INVALID_HID} - , .filename = {"", ""} - , .r_dsetid = H5I_INVALID_HID - , .dtype = H5T_NATIVE_UINT32 - , .fapl = H5I_INVALID_HID - , .fcpl = H5I_INVALID_HID - , .rows = DATA_ROWS - , .cols = DATA_COLS - , .rank = DATA_RANK - , .dims = { DATA_ROWS, DATA_COLS} - , .max_lag = 7 - , .tick_len = 4 - , .ps = 4096 - , .pbs = 4096 - , .check_interval = 1 - , .use_vfd_swmr = true - , .first_proc = true}; + return (state_t){.file = {H5I_INVALID_HID, H5I_INVALID_HID}, + .filename = {"", ""}, + .r_dsetid = H5I_INVALID_HID, + .dtype = H5T_NATIVE_UINT32, + .fapl = H5I_INVALID_HID, + .fcpl = H5I_INVALID_HID, + .rows = DATA_ROWS, + .cols = DATA_COLS, + .rank = DATA_RANK, + .dims = {DATA_ROWS, DATA_COLS}, + .max_lag = 7, + .tick_len = 4, + .ps = 4096, + .pbs = 4096, + .check_interval = 1, + .use_vfd_swmr = true, + .first_proc = true}; } static uint32_t @@ -119,14 +118,14 @@ newmat(state_t s) { mat_t *mat; - mat = HDmalloc(sizeof(*mat) + (s.rows * s.cols - 1) * sizeof(mat->elt[0])); + mat = HDmalloc(sizeof(*mat) + (s.rows * s.cols - 1) * sizeof(mat->elt[0])); if (mat == NULL) { HDfprintf(stderr, "HDmalloc failed\n"); TEST_ERROR; } - mat->rows = s.rows; - mat->cols = s.cols; + mat->rows = s.rows; + mat->cols = s.cols; return mat; @@ -183,15 +182,14 @@ set_or_verify_matrix(mat_t *mat, unsigned int which, bool do_set) } } else if (matget(mat, row, col) != v) { - /* If the data doesn't match, return false + /* If the data doesn't match, return false */ - dbgf(1,"vrfy_matrix failed at row %u,col %u\n",row,col); - dbgf(1,"real value is %u\n",matget(mat,row,col)); - dbgf(1,"expected value is %u\n",v); + dbgf(1, "vrfy_matrix failed at row %u,col %u\n", row, col); + dbgf(1, "real value is %u\n", matget(mat, row, col)); + dbgf(1, "expected value is %u\n", v); ret = false; break; } - } } @@ -210,40 +208,39 @@ verify_matrix(mat_t *mat, unsigned int which) return set_or_verify_matrix(mat, which, false); } - static void usage(const char *progname) { - fprintf(stderr, "usage: %s [-S] [-c cols] [-r rows] [-t tick_len] [-m max_lag] \n" - " [-B page_buffer_size] [-s page_size] [-u reader wait interval] [-q silent output] \n" - "\n" - "-S: do not use VFD SWMR\n" - "-c cols: `cols` columns for the dataset\n" - " The default value is 512.\n" - "-r rows: `rows` rows for the dataset\n" - " The default value is 256.\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. The default value is 4K(4096).\n" - "-u 0.1s: interval in tenth of seconds to check if a dataset is ready for the reader.\n" - "-q: silence printouts, few messages\n" - "\n", - progname); - exit(EXIT_FAILURE); + fprintf(stderr, + "usage: %s [-S] [-c cols] [-r rows] [-t tick_len] [-m max_lag] \n" + " [-B page_buffer_size] [-s page_size] [-u reader wait interval] [-q silent output] \n" + "\n" + "-S: do not use VFD SWMR\n" + "-c cols: `cols` columns for the dataset\n" + " The default value is 512.\n" + "-r rows: `rows` rows for the dataset\n" + " The default value is 256.\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. The default value is 4K(4096).\n" + "-u 0.1s: interval in tenth of seconds to check if a dataset is ready for the reader.\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; - char *tfile = NULL; - char *end; - const char *personality; + int ch; + char * tfile = NULL; + char * end; + const char * personality; *s = state_initializer(); @@ -261,57 +258,57 @@ state_init(state_t *s, int argc, char **argv) while ((ch = getopt(argc, argv, "Sqc:r:t:m:B:s:u:")) != -1) { switch (ch) { - case 'S': - s->use_vfd_swmr = false; - break; - case 'c': - case 'r': - case 't': - case 'm': - case 'B': - case 's': - case 'u': - errno = 0; - tmp = HDstrtoul(optarg, &end, 0); - if (end == optarg || *end != '\0') { - HDfprintf(stderr, "couldn't parse -%c argument %s\n", ch, optarg); - TEST_ERROR; - } - else if (errno != 0) { - HDfprintf(stderr, "couldn't parse -%c argument %s\n", ch, optarg); - TEST_ERROR; - } - else if (tmp > UINT_MAX) { - HDfprintf(stderr, "-%c argument %lu too large", ch, tmp); - TEST_ERROR; - } - if ((ch == 'c' || ch == 'r') && tmp == 0) { - HDfprintf(stderr, "-%c argument %lu must be >= 1", ch, tmp); - TEST_ERROR; - } + case 'S': + s->use_vfd_swmr = false; + break; + case 'c': + case 'r': + case 't': + case 'm': + case 'B': + case 's': + case 'u': + errno = 0; + tmp = HDstrtoul(optarg, &end, 0); + if (end == optarg || *end != '\0') { + HDfprintf(stderr, "couldn't parse -%c argument %s\n", ch, optarg); + TEST_ERROR; + } + else if (errno != 0) { + HDfprintf(stderr, "couldn't parse -%c argument %s\n", ch, optarg); + TEST_ERROR; + } + else if (tmp > UINT_MAX) { + HDfprintf(stderr, "-%c argument %lu too large", ch, tmp); + TEST_ERROR; + } + if ((ch == 'c' || ch == 'r') && tmp == 0) { + HDfprintf(stderr, "-%c argument %lu must be >= 1", ch, tmp); + TEST_ERROR; + } - if (ch == 'c') - s->cols = (unsigned)tmp; - else if (ch == 'r') - s->rows = (unsigned)tmp; - else if (ch == 't') - s->tick_len = (unsigned)tmp; - else if (ch == 'm') - s->max_lag = (unsigned)tmp; - else if (ch == 'B') - s->pbs = (unsigned)tmp; - else if (ch == 's') - s->ps = (unsigned)tmp; - else if (ch == 'u') - s->check_interval = (unsigned)tmp; - break; - case 'q': - verbosity = 0; - break; - case '?': - default: - usage(s->progname); - break; + if (ch == 'c') + s->cols = (unsigned)tmp; + else if (ch == 'r') + s->rows = (unsigned)tmp; + else if (ch == 't') + s->tick_len = (unsigned)tmp; + else if (ch == 'm') + s->max_lag = (unsigned)tmp; + else if (ch == 'B') + s->pbs = (unsigned)tmp; + else if (ch == 's') + s->ps = (unsigned)tmp; + else if (ch == 'u') + s->check_interval = (unsigned)tmp; + break; + case 'q': + verbosity = 0; + break; + case '?': + default: + usage(s->progname); + break; } } argc -= optind; @@ -324,16 +321,14 @@ state_init(state_t *s, int argc, char **argv) s->filename[0] = "vfd_swmr_indep_wr_p0.h5"; s->filename[1] = "vfd_swmr_indep_wr_p1.h5"; - s->dims[0] = s->rows; - s->dims[1] = s->cols; + s->dims[0] = s->rows; + s->dims[1] = s->cols; personality = HDstrstr(s->progname, "vfd_swmr_indep_wr"); - if (personality != NULL && - HDstrcmp(personality, "vfd_swmr_indep_wr_p0") == 0) + if (personality != NULL && HDstrcmp(personality, "vfd_swmr_indep_wr_p0") == 0) s->first_proc = true; - else if (personality != NULL && - HDstrcmp(personality, "vfd_swmr_indep_wr_p1") == 0) + else if (personality != NULL && HDstrcmp(personality, "vfd_swmr_indep_wr_p1") == 0) s->first_proc = false; else { HDprintf("unknown personality, expected vfd_swmr_indep_wr_{p0,p1}\n"); @@ -346,11 +341,12 @@ error: if (tfile) HDfree(tfile); return false; - } -static bool indep_init_vfd_swmr_config_plist(state_t *s,bool writer,const char* mdf_path){ - +static bool +indep_init_vfd_swmr_config_plist(state_t *s, bool writer, const char *mdf_path) +{ + H5F_vfd_swmr_config_t config; /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ @@ -372,31 +368,32 @@ static bool indep_init_vfd_swmr_config_plist(state_t *s,bool writer,const char* error: return false; - } -static bool write_dataset(const state_t *s, mat_t *mat) { +static bool +write_dataset(const state_t *s, mat_t *mat) +{ - char dname[sizeof("/dataset-?")]; - hid_t dset_id = H5I_INVALID_HID; - hid_t filespace = H5I_INVALID_HID; - unsigned int which = 0; + char dname[sizeof("/dataset-?")]; + hid_t dset_id = H5I_INVALID_HID; + hid_t filespace = H5I_INVALID_HID; + unsigned int which = 0; - if(s->first_proc) + if (s->first_proc) esnprintf(dname, sizeof(dname), "/dataset-%d", 0); else { esnprintf(dname, sizeof(dname), "/dataset-%d", 1); which = 1; } - filespace = H5Screate_simple(s->rank, s->dims,NULL); + filespace = H5Screate_simple(s->rank, s->dims, NULL); if (filespace < 0) { HDfprintf(stderr, "H5Screate_simple failed\n"); TEST_ERROR; } - if((dset_id = H5Dcreate2(s->file[which], dname, s->dtype, filespace, - H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) <0 ) { + if ((dset_id = H5Dcreate2(s->file[which], dname, s->dtype, filespace, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { HDfprintf(stderr, "H5Dcreate2 failed\n"); TEST_ERROR; } @@ -420,11 +417,11 @@ static bool write_dataset(const state_t *s, mat_t *mat) { HDfprintf(stderr, "H5Dclose failed\n"); TEST_ERROR; } - - if(s->first_proc) - dbgf(1,"Process 0: Successfully write the dataset %s for file %s.\n",dname,s->filename[which]); - else - dbgf(1,"Process 1: Successfully write the dataset %s for file %s.\n",dname,s->filename[which]); + + if (s->first_proc) + dbgf(1, "Process 0: Successfully write the dataset %s for file %s.\n", dname, s->filename[which]); + else + dbgf(1, "Process 1: Successfully write the dataset %s for file %s.\n", dname, s->filename[which]); return true; @@ -439,26 +436,27 @@ error: return false; } -static bool open_dset(state_t *s) { +static bool +open_dset(state_t *s) +{ - char dname[sizeof("/dataset-?")]; - hid_t dset_id; + char dname[sizeof("/dataset-?")]; + hid_t dset_id; unsigned int i; unsigned int fopen_idx = 0; /* The first process reads the dataset from the second process * The second process reads the dataset from the first process */ - if(s->first_proc) { + if (s->first_proc) { esnprintf(dname, sizeof(dname), "/dataset-%d", 1); fopen_idx = 1; } - else { + else { esnprintf(dname, sizeof(dname), "/dataset-%d", 0); fopen_idx = 0; } - /* Same as the big dset test, tries to open the dataset repeatedly until successful. After trying * NUM_ATTEMPTS times without success, report it as a failure */ @@ -480,34 +478,36 @@ static bool open_dset(state_t *s) { HDfprintf(stderr, "dataset opening reachs the maximal number of attempts\n"); TEST_ERROR; } - - if(s->first_proc) - dbgf(1,"Process 0: Successfully open the dataset %s for file %s.\n",dname,s->filename[fopen_idx]); + + if (s->first_proc) + dbgf(1, "Process 0: Successfully open the dataset %s for file %s.\n", dname, s->filename[fopen_idx]); else - dbgf(1,"Process 1: Successfully open the dataset %s for file %s.\n",dname,s->filename[fopen_idx]); + dbgf(1, "Process 1: Successfully open the dataset %s for file %s.\n", dname, s->filename[fopen_idx]); return true; error: return false; } -static bool vrfy_dset(const state_t *s, mat_t *mat) { +static bool +vrfy_dset(const state_t *s, mat_t *mat) +{ unsigned int i; unsigned int which = 0; - herr_t status; - + herr_t status; + /* A failure to read the data may indicate the data isn't ready yet. Instead of displaying the error * stack, simply return false and let the caller repeat this step. */ - + for (i = 0; i < NUM_ATTEMPTS; i++) { - H5E_BEGIN_TRY - { + H5E_BEGIN_TRY + { status = H5Dread(s->r_dsetid, H5T_NATIVE_UINT32, H5S_ALL, H5S_ALL, H5P_DEFAULT, mat->elt); - } + } H5E_END_TRY; - if(status <0) { + if (status < 0) { decisleep(1); /* Refresh the dataset and try it again */ if (H5Drefresh(s->r_dsetid) < 0) { @@ -515,25 +515,25 @@ static bool vrfy_dset(const state_t *s, mat_t *mat) { TEST_ERROR; } } - else + else break; } if (i == NUM_ATTEMPTS) { HDfprintf(stderr, "dataset verification reached the maximal number of attempts\n"); TEST_ERROR; } - if(s->first_proc) + if (s->first_proc) which = 1; - - if (verify_matrix(mat,which) == false) { + + if (verify_matrix(mat, which) == false) { HDfprintf(stderr, "dataset verification failed\n"); TEST_ERROR; } - if(s->first_proc) - dbgf(1,"Process 0: Successfully verify a dataset.\n"); - else - dbgf(1,"Process 1: Successfully verify a dataset.\n"); + if (s->first_proc) + dbgf(1, "Process 0: Successfully verify a dataset.\n"); + else + dbgf(1, "Process 1: Successfully verify a dataset.\n"); return true; @@ -541,18 +541,20 @@ error: return false; } -static bool read_vrfy_dataset(state_t *s, mat_t *mat) { +static bool +read_vrfy_dataset(state_t *s, mat_t *mat) +{ - if(false == open_dset(s)) { + if (false == open_dset(s)) { HDfprintf(stderr, "Reader: open_dataset() failed\n"); TEST_ERROR; } - if(false == vrfy_dset(s,mat)) { + if (false == vrfy_dset(s, mat)) { HDfprintf(stderr, "Reader: vrfy_dataset() failed\n"); TEST_ERROR; } - if(H5Dclose(s->r_dsetid)<0) { + if (H5Dclose(s->r_dsetid) < 0) { HDfprintf(stderr, "Reader: H5Dclose() failed\n"); TEST_ERROR; } @@ -560,22 +562,23 @@ static bool read_vrfy_dataset(state_t *s, mat_t *mat) { error: - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Dclose(s->r_dsetid); } H5E_END_TRY; return false; - } - -static bool close_pl(const state_t *s) { +static bool +close_pl(const state_t *s) +{ if (H5Pclose(s->fapl) < 0) { printf("H5Pclose failed\n"); TEST_ERROR; } - + if (H5Pclose(s->fcpl) < 0) { printf("H5Pclose failed\n"); TEST_ERROR; @@ -584,7 +587,7 @@ static bool close_pl(const state_t *s) { return true; error: - H5E_BEGIN_TRY + H5E_BEGIN_TRY { H5Pclose(s->fapl); H5Pclose(s->fcpl); @@ -592,21 +595,19 @@ error: H5E_END_TRY; return false; - } int main(int argc, char **argv) { - bool writer = true; - state_t s; - bool ret = false; - unsigned i; - mat_t * mat = NULL; - + bool writer = true; + state_t s; + bool ret = false; + unsigned i; + mat_t * mat = NULL; if (!state_init(&s, argc, argv)) { - HDfprintf(stderr,"state_init failed\n"); + HDfprintf(stderr, "state_init failed\n"); TEST_ERROR; } @@ -615,20 +616,20 @@ main(int argc, char **argv) TEST_ERROR; } - if(s.first_proc) { + if (s.first_proc) { writer = true; - if(false == indep_init_vfd_swmr_config_plist(&s,writer,"./file1-shadow")) { - HDfprintf(stderr,"Writer: Cannot initialize file property lists for file %s\n",s.filename[0]); + if (false == indep_init_vfd_swmr_config_plist(&s, writer, "./file1-shadow")) { + HDfprintf(stderr, "Writer: Cannot initialize file property lists for file %s\n", s.filename[0]); TEST_ERROR; } s.file[0] = H5Fcreate(s.filename[0], H5F_ACC_TRUNC, s.fcpl, s.fapl); if (s.file[0] < 0) { - HDfprintf(stderr, "H5Fcreate failed for the file %s\n",s.filename[0]); + HDfprintf(stderr, "H5Fcreate failed for the file %s\n", s.filename[0]); TEST_ERROR; } - ret = write_dataset(&s,mat); + ret = write_dataset(&s, mat); if (ret == false) { HDfprintf(stderr, "write_dataset failed for the file %s\n", s.filename[0]); TEST_ERROR; @@ -646,78 +647,78 @@ main(int argc, char **argv) } if (false == close_pl(&s)) { - HDfprintf(stderr, "Fail to close file property lists for writing the file %s.\n",s.filename[0]); + HDfprintf(stderr, "Fail to close file property lists for writing the file %s.\n", s.filename[0]); TEST_ERROR; } writer = false; - if(false == indep_init_vfd_swmr_config_plist(&s,writer,"./file2-shadow")) { - HDfprintf(stderr, "Reader: Cannot initialize file property lists for file %s\n",s.filename[1]); + if (false == indep_init_vfd_swmr_config_plist(&s, writer, "./file2-shadow")) { + HDfprintf(stderr, "Reader: Cannot initialize file property lists for file %s\n", s.filename[1]); TEST_ERROR; } s.file[1] = H5Fopen(s.filename[1], H5F_ACC_RDONLY, s.fapl); if (s.file[1] < 0) { - HDfprintf(stderr, "H5Fopen failed for the file %s\n",s.filename[1]); + HDfprintf(stderr, "H5Fopen failed for the file %s\n", s.filename[1]); TEST_ERROR; } - ret = read_vrfy_dataset(&s,mat); + ret = read_vrfy_dataset(&s, mat); if (ret == false) { - HDfprintf(stderr, "read and verify dataset failed for file %s\n",s.filename[1]); + HDfprintf(stderr, "read and verify dataset failed for file %s\n", s.filename[1]); TEST_ERROR; } - + if (false == close_pl(&s)) { - HDfprintf(stderr, "Fail to close file property lists for reading the file %s.\n",s.filename[1]); + HDfprintf(stderr, "Fail to close file property lists for reading the file %s.\n", s.filename[1]); TEST_ERROR; } if (H5Fclose(s.file[0]) < 0) { - HDfprintf(stderr,"fail to close HDF5 file %s \n",s.filename[0]); + HDfprintf(stderr, "fail to close HDF5 file %s \n", s.filename[0]); TEST_ERROR; } - + if (H5Fclose(s.file[1]) < 0) { - HDfprintf(stderr, "fail to close HDF5 file %s \n",s.filename[1]); + HDfprintf(stderr, "fail to close HDF5 file %s \n", s.filename[1]); TEST_ERROR; } } else { - + writer = false; - if(false == indep_init_vfd_swmr_config_plist(&s,writer,"./file1-shadow")) { - HDfprintf(stderr,"Reader: Cannot initialize file property lists for file %s\n",s.filename[0]); + if (false == indep_init_vfd_swmr_config_plist(&s, writer, "./file1-shadow")) { + HDfprintf(stderr, "Reader: Cannot initialize file property lists for file %s\n", s.filename[0]); TEST_ERROR; } s.file[0] = H5Fopen(s.filename[0], H5F_ACC_RDONLY, s.fapl); if (s.file[0] < 0) { - HDfprintf(stderr, "H5Fopen failed for the file %s\n",s.filename[0]); + HDfprintf(stderr, "H5Fopen failed for the file %s\n", s.filename[0]); TEST_ERROR; } - ret = read_vrfy_dataset(&s,mat); + ret = read_vrfy_dataset(&s, mat); if (ret == false) { - HDfprintf(stderr, "read and verify dataset failed for file %s\n",s.filename[0]); + HDfprintf(stderr, "read and verify dataset failed for file %s\n", s.filename[0]); TEST_ERROR; } if (false == close_pl(&s)) { - HDfprintf(stderr,"Fail to close file property lists for reading the file %s.\n",s.filename[0]); + HDfprintf(stderr, "Fail to close file property lists for reading the file %s.\n", s.filename[0]); TEST_ERROR; } writer = true; - if(false == indep_init_vfd_swmr_config_plist(&s,writer,"./file2-shadow")) { - HDfprintf(stderr, "writer: Cannot initialize file property lists for file %s\n",s.filename[1]); + if (false == indep_init_vfd_swmr_config_plist(&s, writer, "./file2-shadow")) { + HDfprintf(stderr, "writer: Cannot initialize file property lists for file %s\n", s.filename[1]); TEST_ERROR; } s.file[1] = H5Fcreate(s.filename[1], H5F_ACC_TRUNC, s.fcpl, s.fapl); if (s.file[1] < 0) { - HDfprintf(stderr, "H5Fcreate failed for the file %s\n",s.filename[1]); + HDfprintf(stderr, "H5Fcreate failed for the file %s\n", s.filename[1]); TEST_ERROR; } - ret = write_dataset(&s,mat); + ret = write_dataset(&s, mat); if (ret == false) { HDfprintf(stderr, "write_dataset failed for the file %s\n", s.filename[1]); TEST_ERROR; @@ -733,19 +734,19 @@ main(int argc, char **argv) } H5E_END_TRY; } - + if (false == close_pl(&s)) { - HDfprintf(stderr, "Fail to close file property lists for writing the file %s.\n",s.filename[1]); + HDfprintf(stderr, "Fail to close file property lists for writing the file %s.\n", s.filename[1]); TEST_ERROR; } if (H5Fclose(s.file[0]) < 0) { - HDfprintf(stderr,"fail to close HDF5 file %s \n",s.filename[0]); + HDfprintf(stderr, "fail to close HDF5 file %s \n", s.filename[0]); TEST_ERROR; } - + if (H5Fclose(s.file[1]) < 0) { - HDfprintf(stderr, "fail to close HDF5 file %s \n",s.filename[1]); + HDfprintf(stderr, "fail to close HDF5 file %s \n", s.filename[1]); TEST_ERROR; } } @@ -753,7 +754,6 @@ main(int argc, char **argv) if (mat) HDfree(mat); - return EXIT_SUCCESS; error: -- cgit v0.12 From 904c2efddec9a99a68e799b28a9f2e9381c86f0b Mon Sep 17 00:00:00 2001 From: myang6 <myang6@hdfgroup.org> Date: Wed, 1 Dec 2021 16:52:28 -0600 Subject: Add some comments. --- test/vfd_swmr_indep_rw_writer.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/vfd_swmr_indep_rw_writer.c b/test/vfd_swmr_indep_rw_writer.c index 3aa8a2e..9f7fda7 100644 --- a/test/vfd_swmr_indep_rw_writer.c +++ b/test/vfd_swmr_indep_rw_writer.c @@ -616,6 +616,7 @@ main(int argc, char **argv) TEST_ERROR; } + /* The first process writes a dataset in the first file and then reads a dataset from the second file.*/ if (s.first_proc) { writer = true; @@ -685,6 +686,9 @@ main(int argc, char **argv) } else { + /* The second process reads the dataset of the first file generated by the first process, + * then writes a dataset in the second file for the first process to read. + */ writer = false; if (false == indep_init_vfd_swmr_config_plist(&s, writer, "./file1-shadow")) { HDfprintf(stderr, "Reader: Cannot initialize file property lists for file %s\n", s.filename[0]); -- cgit v0.12 From 4734ef55293797acd07a4852abc0df038f80884c Mon Sep 17 00:00:00 2001 From: myang6 <myang6@hdfgroup.org> Date: Mon, 6 Dec 2021 17:38:14 -0600 Subject: Add comments. --- test/vfd_swmr_indep_rw_writer.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/test/vfd_swmr_indep_rw_writer.c b/test/vfd_swmr_indep_rw_writer.c index 9f7fda7..378e72f 100644 --- a/test/vfd_swmr_indep_rw_writer.c +++ b/test/vfd_swmr_indep_rw_writer.c @@ -46,11 +46,14 @@ #define DATA_RANK 2 #define NUM_ATTEMPTS 100 + +/* Structure for filling the dataset values. Adapted from vfd_swmr_bigset_writer.c. */ typedef struct _mat { unsigned rows, cols; uint32_t elt[1]; } mat_t; +/* Structure to hold the information of various parameters used in the program. */ typedef struct { hid_t file[2]; const char * filename[2]; @@ -69,6 +72,7 @@ typedef struct { bool first_proc; } state_t; +/* Assign the initialized values to struct state_t declared above */ static inline state_t state_initializer(void) { @@ -91,12 +95,15 @@ state_initializer(void) .first_proc = true}; } +/* Obtain the data value at index [i][j] for the 2D matrix. + All the routines related to the matrix are adapted from the vfd_swmr_bigset_writer.c. */ static uint32_t matget(const mat_t *mat, unsigned i, unsigned j) { return mat->elt[i * mat->cols + j]; } +/* Set the data value at index [i][j] for the 2D matrix. */ static bool matset(mat_t *mat, unsigned i, unsigned j, uint32_t v) { @@ -113,6 +120,7 @@ error: return false; } +/* Allocate memory for the 2-D matrix. */ static mat_t * newmat(state_t s) { @@ -196,18 +204,21 @@ set_or_verify_matrix(mat_t *mat, unsigned int which, bool do_set) return ret; } +/* Initialize the matrix values. The parameter 'which' determines the data value. */ static bool init_matrix(mat_t *mat, unsigned int which) { return set_or_verify_matrix(mat, which, true); } +/* Verify the matrix values at each point. The parameter 'which" determines the data value. */ static bool verify_matrix(mat_t *mat, unsigned int which) { return set_or_verify_matrix(mat, which, false); } +/* Usage of this program when running with the -h option */ static void usage(const char *progname) { @@ -233,6 +244,7 @@ usage(const char *progname) exit(EXIT_FAILURE); } +/* Initialize the state_t with different options specified by the user. */ static bool state_init(state_t *s, int argc, char **argv) { @@ -343,6 +355,9 @@ error: return false; } +/* Initialize the configuration and the file creation and access property lists + * for the VFD SMWR independence of the reader/writer test. + */ static bool indep_init_vfd_swmr_config_plist(state_t *s, bool writer, const char *mdf_path) { @@ -370,6 +385,7 @@ error: return false; } +/* Write the matrix mat to a dataset. The dataset name depends on the process it runs. */ static bool write_dataset(const state_t *s, mat_t *mat) { @@ -436,6 +452,8 @@ error: return false; } +/* Open the dataset according to the dataset name related to the process. + The dataset ID is saved in the state_t s */ static bool open_dset(state_t *s) { @@ -489,6 +507,9 @@ error: return false; } +/* Verify a dataset, this routine must be called after the open_dset(). + * It will use the dataset ID assigned by open_dset(). + */ static bool vrfy_dset(const state_t *s, mat_t *mat) { @@ -541,6 +562,7 @@ error: return false; } +/* The wrapper routine of open_dset() and vrfy_dset() for readers to verify a dataset. */ static bool read_vrfy_dataset(state_t *s, mat_t *mat) { @@ -570,6 +592,7 @@ error: return false; } +/* Close the file access and creation property lists. */ static bool close_pl(const state_t *s) { -- cgit v0.12 From 829c3a83c36251c4134ac81d8cc6012b7af8227b Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 6 Dec 2021 23:40:28 +0000 Subject: Committing clang-format changes --- test/vfd_swmr_indep_rw_writer.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/test/vfd_swmr_indep_rw_writer.c b/test/vfd_swmr_indep_rw_writer.c index 378e72f..2ab756b 100644 --- a/test/vfd_swmr_indep_rw_writer.c +++ b/test/vfd_swmr_indep_rw_writer.c @@ -46,7 +46,6 @@ #define DATA_RANK 2 #define NUM_ATTEMPTS 100 - /* Structure for filling the dataset values. Adapted from vfd_swmr_bigset_writer.c. */ typedef struct _mat { unsigned rows, cols; @@ -95,7 +94,7 @@ state_initializer(void) .first_proc = true}; } -/* Obtain the data value at index [i][j] for the 2D matrix. +/* Obtain the data value at index [i][j] for the 2D matrix. All the routines related to the matrix are adapted from the vfd_swmr_bigset_writer.c. */ static uint32_t matget(const mat_t *mat, unsigned i, unsigned j) @@ -355,8 +354,8 @@ error: return false; } -/* Initialize the configuration and the file creation and access property lists - * for the VFD SMWR independence of the reader/writer test. +/* Initialize the configuration and the file creation and access property lists + * for the VFD SMWR independence of the reader/writer test. */ static bool indep_init_vfd_swmr_config_plist(state_t *s, bool writer, const char *mdf_path) @@ -507,9 +506,9 @@ error: return false; } -/* Verify a dataset, this routine must be called after the open_dset(). +/* Verify a dataset, this routine must be called after the open_dset(). * It will use the dataset ID assigned by open_dset(). - */ + */ static bool vrfy_dset(const state_t *s, mat_t *mat) { -- cgit v0.12 From 7253d772b8205a03232411bd58bcd5c331e6f19a Mon Sep 17 00:00:00 2001 From: vchoi <vchoi@jelly.ad.hdfgroup.org> Date: Mon, 6 Dec 2021 18:52:04 -0600 Subject: Changes to address feedback from PR review. --- src/H5Fint.c | 10 +- src/H5Fprivate.h | 6 +- test/vfd_swmr.c | 308 +++++++++++++++++++++++++------------------------ test/vfd_swmr_common.c | 2 + 4 files changed, 167 insertions(+), 159 deletions(-) diff --git a/src/H5Fint.c b/src/H5Fint.c index 3dae17e..f0d03e4 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -1850,11 +1850,13 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) hbool_t evict_on_close; /* Evict on close value from plist */ hbool_t use_file_locking = TRUE; /* Using file locks? */ hbool_t ci_load = FALSE; /* Whether MDC ci load requested */ - hbool_t ci_write = FALSE; /* Whether MDC CI write requested */ + 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 */ - H5F_generate_md_ck_cb_t cb_info = {NULL}; - H5F_t * ret_value = NULL; /* Actual return value */ + H5F_generate_md_ck_cb_t cb_info = {NULL}; /* For VFD SWMR NFS testing: + initialize the callback to generate + checksums for metadata files */ + H5F_t * ret_value = NULL; /* Actual return value */ FUNC_ENTER_NOAPI(NULL) @@ -3772,7 +3774,7 @@ herr_t H5F__start_swmr_write(H5F_t *f) { hbool_t ci_load = FALSE; /* whether MDC ci load requested */ - hbool_t ci_write = FALSE; /* whether MDC CI write requested */ + hbool_t ci_write = FALSE; /* whether MDC ci write requested */ size_t grp_dset_count = 0; /* # of open objects: groups & datasets */ size_t nt_attr_count = 0; /* # of opened named datatypes + opened attributes */ hid_t * obj_ids = NULL; /* List of ids */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 796242b..9a4f363 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -811,7 +811,7 @@ uint64_decode(uint8_t **pp) + 4 /* Page size */ \ + 8 /* Sequence number */ \ + 8 /* Tick number */ \ - + 8 /* Chnage list offset */ \ + + 8 /* Change list offset */ \ + 8 /* Change list length */ \ + H5F_SIZEOF_CHKSUM /* Updater file header checksum */ \ ) @@ -935,7 +935,7 @@ typedef enum H5F_prefix_open_t { * * An array of instances of H5F_vfd_swmr_updater_cl_entry_t of length equal to * the number of metadata pages and multi-page metadata entries modified in - * the past tick is used ot aseemble the assoicated data in preparation for + * the past tick is used to assemble the associated data in preparation for * writing an updater file. * * Each entry in this array pertains to a given modified metdata page or @@ -1062,7 +1062,7 @@ typedef struct H5F_vfd_swmr_updater_cl_entry_t { * array of H5F_vfd_swmr_updater_cl_ entry_t whose base address * is stored in the change_list field below. This value is also the * number of metadata pages and multi-page metadata entries that have - * been modified in the past tick + * been modified in the past tick. * * If this field is zero, there is no change list, and the change_list * field below is NULL. diff --git a/test/vfd_swmr.c b/test/vfd_swmr.c index e763191..d87f512 100644 --- a/test/vfd_swmr.c +++ b/test/vfd_swmr.c @@ -55,6 +55,8 @@ #define FNAME "non_vfd_swmr_file.h5" +#define FILE_NAME_LEN 1024 + /* Defines used by verify_updater_flags() and verify_ud_chk() helper routine */ /* Offset of "flags" in updater file header */ @@ -354,7 +356,7 @@ test_file_fapl(void) /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ fapl1 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 0, config1); if (fapl1 == H5I_INVALID_HID) - TEST_ERROR + TEST_ERROR; /* Should fail to create: file access is writer but VFD SWMR config is reader */ H5E_BEGIN_TRY @@ -366,7 +368,7 @@ test_file_fapl(void) TEST_ERROR; if (H5Pclose(fapl1) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* * Configured as VFD SWMR writer + no page buffering @@ -380,7 +382,7 @@ test_file_fapl(void) fapl1 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 0, config1); if (fapl1 == H5I_INVALID_HID) - TEST_ERROR + TEST_ERROR; /* Should fail to create: page buffering and paged aggregation not enabled */ H5E_BEGIN_TRY @@ -393,7 +395,7 @@ test_file_fapl(void) if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, 4096)) < 0) { HDprintf("vfd_swmr_create_fcpl() failed"); - FAIL_STACK_ERROR + FAIL_STACK_ERROR; } /* Should fail to create: no page buffering */ @@ -406,7 +408,7 @@ test_file_fapl(void) TEST_ERROR; if (H5Pclose(fapl1) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* * Configured as VFD SWMR writer + page buffering @@ -420,7 +422,7 @@ test_file_fapl(void) fapl1 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config1); if (fapl1 == H5I_INVALID_HID) - TEST_ERROR + TEST_ERROR; /* Should succeed to create the file: paged aggregation and page buffering enabled */ if ((fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl1)) < 0) @@ -492,7 +494,7 @@ test_file_fapl(void) fapl2 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config2); if (fapl2 == H5I_INVALID_HID) - TEST_ERROR + TEST_ERROR; /* Should succeed to open the file as VFD SWMR writer */ if ((fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl2)) < 0) @@ -532,7 +534,7 @@ test_file_fapl(void) fapl1 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config1); if (fapl1 == H5I_INVALID_HID) - TEST_ERROR + TEST_ERROR; /* Re-open the same file with config1 */ /* Should fail to open since config1 is different from config2 setting */ @@ -558,12 +560,12 @@ test_file_fapl(void) fapl1 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config1); if (fapl1 == H5I_INVALID_HID) - TEST_ERROR + TEST_ERROR; /* Re-open the same file as VFD SWMR writer */ /* Should succeed since config1 is same as the setting in config2 */ if ((fid2 = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl1)) < 0) - TEST_ERROR + TEST_ERROR; /* Close fapl1 */ if (H5Pclose(fapl1) < 0) @@ -702,7 +704,7 @@ test_file_end_tick(void) fapl1 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config1); if (fapl1 == H5I_INVALID_HID) - TEST_ERROR + TEST_ERROR; /* * Configured file 2 as VFD SWMR writer + page buffering @@ -716,7 +718,7 @@ test_file_end_tick(void) fapl2 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config2); if (fapl2 == H5I_INVALID_HID) - TEST_ERROR + TEST_ERROR; /* * Configured file 3 as VFD SWMR writer + page buffering @@ -730,7 +732,7 @@ test_file_end_tick(void) fapl3 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config3); if (fapl3 == H5I_INVALID_HID) - TEST_ERROR + TEST_ERROR; if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, 4096)) < 0) { HDprintf("vfd_swmr_create_fcpl() failed"); @@ -912,7 +914,7 @@ test_writer_create_open_flush(void) /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ fapl = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, my_config); if (fapl == H5I_INVALID_HID) - TEST_ERROR + TEST_ERROR; if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, 4096)) < 0) { HDprintf("vfd_swmr_create_fcpl() failed"); @@ -929,11 +931,11 @@ test_writer_create_open_flush(void) /* Flush the HDF5 file */ if (H5Fflush(fid, H5F_SCOPE_GLOBAL) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Verify info in metadata file when flushing the HDF5 file */ if (H5F__vfd_swmr_writer_create_open_flush_test(fid, FALSE) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Close the file */ if (H5Fclose(fid) < 0) @@ -1034,7 +1036,7 @@ test_writer_md(void) /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ fapl = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, FS_PAGE_SIZE, my_config); if (fapl == H5I_INVALID_HID) - TEST_ERROR + TEST_ERROR; if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, FS_PAGE_SIZE)) < 0) { HDprintf("vfd_swmr_create_fcpl() failed"); @@ -1070,19 +1072,19 @@ test_writer_md(void) /* Update with index and verify info in the metadata file */ /* Also verify that 0 entries will be on the delayed list */ if (H5F__vfd_swmr_writer_md_test(fid, num_entries, index, 0) < 0) - TEST_ERROR + TEST_ERROR; /* Create dataset creation property list */ if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Set to use chunked dataset */ if (H5Pset_chunk(dcpl, 2, chunk_dims) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Create dataspace */ if ((sid = H5Screate_simple(2, dims, max_dims)) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Perform activities to ensure that max_lag ticks elapse */ for (i = 0; i < my_config->max_lag + 1; i++) { @@ -1091,15 +1093,15 @@ test_writer_md(void) /* Create a chunked dataset */ HDsprintf(dname, "dset %d", i); if ((did = H5Dcreate2(fid, dname, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Get dataset object header address */ if (H5Oget_info3(did, &oinfo, H5O_INFO_BASIC) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Close the dataset */ if (H5Dclose(did) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; } /* (B) Update every other entry in the index */ @@ -1111,7 +1113,7 @@ test_writer_md(void) /* Update with index and verify info in the metadata file */ /* Also verify that 5 entries will be on the delayed list */ if (H5F__vfd_swmr_writer_md_test(fid, num_entries, index, 5) < 0) - TEST_ERROR + TEST_ERROR; /* Allocate memory for the read/write buffer */ if ((rwbuf = HDmalloc(sizeof(*rwbuf) * (50 * 20))) == NULL) @@ -1126,19 +1128,19 @@ test_writer_md(void) /* Open the dataset */ HDsprintf(dname, "dset %d", i); if ((did = H5Dopen2(fid, dname, H5P_DEFAULT)) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Write to the dataset */ if (H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rwbuf) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Get dataset object info */ if (H5Oget_info3(did, &oinfo, H5O_INFO_BASIC) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Close the dataset */ if (H5Dclose(did) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; } /* (C) Update every 3 entry in the index */ @@ -1150,7 +1152,7 @@ test_writer_md(void) /* Update with index and verify info in the metadata file */ /* Also verify that 4 entries will be on the delayed list */ if (H5F__vfd_swmr_writer_md_test(fid, num_entries, index, 4) < 0) - TEST_ERROR + TEST_ERROR; /* Clear the read/write buffer */ HDmemset(rwbuf, 0, sizeof(sizeof(int) * (50 * 20))); @@ -1162,19 +1164,19 @@ test_writer_md(void) /* Open the dataset */ HDsprintf(dname, "dset %d", i); if ((did = H5Dopen2(fid, dname, H5P_DEFAULT)) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Read from the dataset */ if (H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rwbuf) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Get dataset object info */ if (H5Oget_info3(did, &oinfo, H5O_INFO_BASIC) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Close the dataset */ if (H5Dclose(did) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; } /* (D) Update two entries in the index */ @@ -1186,7 +1188,7 @@ test_writer_md(void) /* Update with index and verify info in the metadata file */ /* Also verify that 2 entries will be on the delayed list */ if (H5F__vfd_swmr_writer_md_test(fid, num_entries, index, 2) < 0) - TEST_ERROR + TEST_ERROR; /* Closing */ if (H5Fclose(fid) < 0) @@ -1352,7 +1354,7 @@ test_reader_md_concur(void) /* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */ fapl_writer = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, FS_PAGE_SIZE, config_writer); if (fapl_writer == H5I_INVALID_HID) - TEST_ERROR + TEST_ERROR; if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, FS_PAGE_SIZE)) < 0) { HDprintf("vfd_swmr_create_fcpl() failed"); @@ -1369,14 +1371,14 @@ test_reader_md_concur(void) /* Create 2 pipes */ if (HDpipe(parent_pfd) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; if (HDpipe(child_pfd) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Fork child process */ if ((childpid = HDfork()) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* * Child process as reader @@ -1429,7 +1431,7 @@ test_reader_md_concur(void) fapl_reader = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, FS_PAGE_SIZE, config_reader); if (fapl_reader == H5I_INVALID_HID) - TEST_ERROR + TEST_ERROR; /* Open the test file as reader */ if ((fid_reader = H5Fopen(FILENAME, H5F_ACC_RDONLY, fapl_reader)) < 0) @@ -1614,11 +1616,11 @@ test_reader_md_concur(void) /* Close unused read end for writer pipe */ if (HDclose(parent_pfd[0]) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Close unused write end for reader pipe */ if (HDclose(child_pfd[1]) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* * Case A: writer @@ -1652,15 +1654,15 @@ test_reader_md_concur(void) /* Create dataset creation property list */ if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Set to use chunked dataset */ if (H5Pset_chunk(dcpl, 2, chunk_dims) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Create dataspace */ if ((sid = H5Screate_simple(2, dims, max_dims)) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Perform activities to ensure that ticks elapse */ for (i = 0; i < config_writer->max_lag + 1; i++) { @@ -1669,15 +1671,15 @@ test_reader_md_concur(void) /* Create a chunked dataset */ HDsprintf(dname, "dset %d", i); if ((did = H5Dcreate2(fid_writer, dname, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Get dataset object header address */ if (H5Oget_info3(did, &oinfo, H5O_INFO_BASIC) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Close the dataset */ if (H5Dclose(did) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; } num_entries = 12; @@ -1743,15 +1745,15 @@ test_reader_md_concur(void) /* Open the dataset */ HDsprintf(dname, "dset %d", i); if ((did = H5Dopen2(fid_writer, dname, H5P_DEFAULT)) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Write to the dataset */ if (H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rwbuf) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Close the dataset */ if (H5Dclose(did) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; } /* Update 3 entries in the index */ @@ -1798,15 +1800,15 @@ test_reader_md_concur(void) /* Open the dataset */ HDsprintf(dname, "dset %d", i); if ((did = H5Dopen2(fid_writer, dname, H5P_DEFAULT)) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Read from the dataset */ if (H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rwbuf) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Close the dataset */ if (H5Dclose(did) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; } /* Update 5 entries in the index */ @@ -1852,15 +1854,15 @@ test_reader_md_concur(void) /* Open the dataset */ HDsprintf(dname, "dset %d", i); if ((did = H5Dopen2(fid_writer, dname, H5P_DEFAULT)) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Write to the dataset */ if (H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rwbuf) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Close the dataset */ if (H5Dclose(did) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; } /* Update the metadata file with 0 entries and NULL index */ @@ -1884,20 +1886,20 @@ test_reader_md_concur(void) /* Wait for child process to complete */ if ((tmppid = HDwaitpid(childpid, &child_status, child_wait_option)) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Check exit status of child process */ if (WIFEXITED(child_status)) { if ((child_exit_val = WEXITSTATUS(child_status)) != 0) - TEST_ERROR + TEST_ERROR; } else { /* child process terminated abnormally */ - TEST_ERROR + TEST_ERROR; } /* Closing */ if (H5Fclose(fid_writer) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; if (H5Pclose(fapl_writer) < 0) FAIL_STACK_ERROR; if (H5Pclose(fcpl) < 0) @@ -1994,14 +1996,14 @@ test_multiple_file_opens_concur(void) /* Create 2 pipes */ if (HDpipe(parent_pfd) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; if (HDpipe(child_pfd) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Fork child process */ if ((childpid = HDfork()) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* * Child process @@ -2090,11 +2092,11 @@ test_multiple_file_opens_concur(void) /* Close unused read end for writer pipe */ if (HDclose(parent_pfd[0]) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Close unused write end for reader pipe */ if (HDclose(child_pfd[1]) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* * Set up and open file A as VFD SWMR writer @@ -2102,7 +2104,7 @@ test_multiple_file_opens_concur(void) /* Allocate memory for VFD SWMR configuration */ if ((config1 = HDmalloc(sizeof(*config1))) == NULL) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ @@ -2112,7 +2114,7 @@ test_multiple_file_opens_concur(void) fapl1 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, FS_PAGE_SIZE, config1); if (fapl1 == H5I_INVALID_HID) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Open file A as VFD SWMR writer */ if ((fid1 = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl1)) < 0) @@ -2120,7 +2122,7 @@ test_multiple_file_opens_concur(void) /* Get a pointer to the internal file object */ if (NULL == (f1 = H5VL_object(fid1))) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Head of EOT queue should be a writer */ if ((curr = TAILQ_FIRST(&eot_queue_g)) == NULL || !curr->vfd_swmr_writer) @@ -2145,7 +2147,7 @@ test_multiple_file_opens_concur(void) /* Allocate memory for VFD SWMR configuration */ if ((config2 = HDmalloc(sizeof(*config2))) == NULL) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ @@ -2155,7 +2157,7 @@ test_multiple_file_opens_concur(void) fapl2 = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, FS_PAGE_SIZE, config2); if (fapl2 == H5I_INVALID_HID) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Open file B as VFD SWMR reader */ if ((fid2 = H5Fopen(FILENAME2, H5F_ACC_RDONLY, fapl2)) < 0) @@ -2163,7 +2165,7 @@ test_multiple_file_opens_concur(void) /* Get a pointer to the internal file object */ if (NULL == (f2 = H5VL_object(fid2))) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Head of EOT queue should NOT be a writer */ if ((curr = TAILQ_FIRST(&eot_queue_g)) != NULL && curr->vfd_swmr_writer) @@ -2196,22 +2198,22 @@ test_multiple_file_opens_concur(void) /* Wait for child process to complete */ if ((tmppid = HDwaitpid(childpid, &child_status, child_wait_option)) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Check exit status of child process */ if (WIFEXITED(child_status)) { if ((child_exit_val = WEXITSTATUS(child_status)) != 0) - TEST_ERROR + TEST_ERROR; } else { /* child process terminated abnormally */ - TEST_ERROR + TEST_ERROR; } /* Closing */ if (H5Fclose(fid1) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; if (H5Fclose(fid2) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; if (H5Pclose(fapl1) < 0) FAIL_STACK_ERROR; if (H5Pclose(fapl2) < 0) @@ -2298,11 +2300,11 @@ test_disable_enable_eot_concur(void) fapl_writer = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, FS_PAGE_SIZE, config_writer); if (fapl_writer == H5I_INVALID_HID) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, FS_PAGE_SIZE)) < 0) { HDprintf("vfd_swmr_create_fcpl() failed"); - FAIL_STACK_ERROR + FAIL_STACK_ERROR; } /* Create an HDF5 file with VFD SWMR configured */ @@ -2315,14 +2317,14 @@ test_disable_enable_eot_concur(void) /* Create 2 pipes */ if (HDpipe(parent_pfd) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; if (HDpipe(child_pfd) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Fork child process */ if ((childpid = HDfork()) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* * Child process as reader @@ -2378,7 +2380,7 @@ test_disable_enable_eot_concur(void) fapl_reader = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, FS_PAGE_SIZE, config_reader); if (fapl_reader == H5I_INVALID_HID) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Open the test file as reader */ if ((fid_reader = H5Fopen(FILENAME, H5F_ACC_RDONLY, fapl_reader)) < 0) @@ -2469,11 +2471,11 @@ test_disable_enable_eot_concur(void) /* Close unused read end for writer pipe */ if (HDclose(parent_pfd[0]) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Close unused write end for reader pipe */ if (HDclose(child_pfd[1]) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* * Open the file as VFD SWMR writer @@ -2500,20 +2502,20 @@ test_disable_enable_eot_concur(void) /* Wait for child process to complete */ if ((tmppid = HDwaitpid(childpid, &child_status, child_wait_option)) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Check exit status of child process */ if (WIFEXITED(child_status)) { if ((child_exit_val = WEXITSTATUS(child_status)) != 0) - TEST_ERROR + TEST_ERROR; } else { /* child process terminated abnormally */ - TEST_ERROR + TEST_ERROR; } /* Closing */ if (H5Fclose(fid_writer) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; if (H5Pclose(fapl_writer) < 0) FAIL_STACK_ERROR; if (H5Pclose(fcpl) < 0) @@ -2607,14 +2609,14 @@ test_file_end_tick_concur(void) /* Create 2 pipes */ if (HDpipe(parent_pfd) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; if (HDpipe(child_pfd) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Fork child process */ if ((childpid = HDfork()) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* * Child process as reader @@ -2666,7 +2668,7 @@ test_file_end_tick_concur(void) fapl_reader = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, FS_PAGE_SIZE, config_reader); if (fapl_reader == H5I_INVALID_HID) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Open the test file as reader */ if ((fid_reader1 = H5Fopen(FILENAME, H5F_ACC_RDONLY, fapl_reader)) < 0) @@ -2743,11 +2745,11 @@ test_file_end_tick_concur(void) /* Close unused read end for writer pipe */ if (HDclose(parent_pfd[0]) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Close unused write end for reader pipe */ if (HDclose(child_pfd[1]) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* * Open the file as VFD SWMR writer @@ -2774,20 +2776,20 @@ test_file_end_tick_concur(void) /* Wait for child process to complete */ if ((tmppid = HDwaitpid(childpid, &child_status, child_wait_option)) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Check exit status of child process */ if (WIFEXITED(child_status)) { if ((child_exit_val = WEXITSTATUS(child_status)) != 0) - TEST_ERROR + TEST_ERROR; } else { /* child process terminated abnormally */ - TEST_ERROR + TEST_ERROR; } /* Closing */ if (H5Fclose(fid_writer) < 0) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; if (H5Pclose(fapl_writer) < 0) FAIL_STACK_ERROR; if (H5Pclose(fcpl) < 0) @@ -2887,7 +2889,7 @@ test_multiple_file_opens(void) /* Get a pointer to the internal file object */ if (NULL == (f = H5VL_object(fid))) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Verify the global vfd_swmr_writer_g is not set */ if ((curr = TAILQ_FIRST(&eot_queue_g)) != NULL && curr->vfd_swmr_writer) @@ -2902,7 +2904,7 @@ test_multiple_file_opens(void) /* Get a pointer to the internal file object */ if (NULL == (f1 = H5VL_object(fid1))) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Head of EOT queue should be a writer */ if ((curr = TAILQ_FIRST(&eot_queue_g)) == NULL || !curr->vfd_swmr_writer) @@ -2917,7 +2919,7 @@ test_multiple_file_opens(void) /* Get a pointer to the internal file object */ if (NULL == (f2 = H5VL_object(fid2))) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Head of EOT queue should be a writer */ if ((curr = TAILQ_FIRST(&eot_queue_g)) == NULL || !curr->vfd_swmr_writer) @@ -2930,7 +2932,7 @@ test_multiple_file_opens(void) TAILQ_FOREACH(curr, &eot_queue_g, link) { if (curr->vfd_swmr_file == f) - TEST_ERROR + TEST_ERROR; } /* Close the first file with VFD SWMR */ @@ -3052,7 +3054,7 @@ test_same_file_opens(void) if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, 4096)) < 0) { HDprintf("vfd_swmr_create_fcpl() failed"); - FAIL_STACK_ERROR + FAIL_STACK_ERROR; } /* @@ -3498,7 +3500,7 @@ test_enable_disable_eot(void) if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, 4096)) < 0) { HDprintf("vfd_swmr_create_fcpl() failed"); - FAIL_STACK_ERROR + FAIL_STACK_ERROR; } /* Create a file without VFD SWMR */ @@ -3512,10 +3514,10 @@ test_enable_disable_eot(void) } H5E_END_TRY; if (ret >= 0) - TEST_ERROR + TEST_ERROR; if (H5Fclose(fid) < 0) - TEST_ERROR + TEST_ERROR; /* Create file 1 with VFD SWMR writer */ if ((fid1 = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl1)) < 0) @@ -3537,7 +3539,7 @@ test_enable_disable_eot(void) /* Disable EOT for file 1 */ if (H5Fvfd_swmr_disable_end_of_tick(fid1) < 0) - TEST_ERROR + TEST_ERROR; /* Disable file 1 again should fail because the file has just been disabled */ H5E_BEGIN_TRY @@ -3546,18 +3548,18 @@ test_enable_disable_eot(void) } H5E_END_TRY; if (ret >= 0) - TEST_ERROR + TEST_ERROR; /* Should have 2 files on the EOT queue */ count = 0; TAILQ_FOREACH(curr, &eot_queue_g, link) count++; if (count != 2) - TEST_ERROR + TEST_ERROR; /* Get a pointer to the internal file object */ if (NULL == (f1 = H5VL_object(fid1))) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* Should not find file 1 on the EOT queue */ TAILQ_FOREACH(curr, &eot_queue_g, link) @@ -3566,7 +3568,7 @@ test_enable_disable_eot(void) break; } if (curr != NULL && curr->vfd_swmr_file == f1) - TEST_ERROR + TEST_ERROR; /* Enable EOT for file 2 should fail because the file has not been disabled */ H5E_BEGIN_TRY @@ -3575,11 +3577,11 @@ test_enable_disable_eot(void) } H5E_END_TRY; if (ret >= 0) - TEST_ERROR + TEST_ERROR; /* Get a pointer to the internal file object */ if (NULL == (f2 = H5VL_object(fid2))) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* File 2 should be on the EOT queue */ TAILQ_FOREACH(curr, &eot_queue_g, link) @@ -3588,19 +3590,19 @@ test_enable_disable_eot(void) break; } if (curr == NULL || curr->vfd_swmr_file != f2) - TEST_ERROR + TEST_ERROR; /* Close file 3 */ if (H5Fclose(fid3) < 0) - TEST_ERROR + TEST_ERROR; /* Open file 3 again without VFD SWMR writer */ if ((fid3 = H5Fopen(FILENAME3, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) - TEST_ERROR + TEST_ERROR; /* Get a pointer to the internal file object for file 3 */ if (NULL == (f3 = H5VL_object(fid3))) - FAIL_STACK_ERROR + FAIL_STACK_ERROR; /* File 3 should not exist on the EOT queue */ TAILQ_FOREACH(curr, &eot_queue_g, link) @@ -3609,7 +3611,7 @@ test_enable_disable_eot(void) break; } if (curr != NULL && curr->vfd_swmr_file == f3) - TEST_ERROR + TEST_ERROR; /* Should have 2 files on the EOT queue */ count = 0; @@ -3625,7 +3627,7 @@ test_enable_disable_eot(void) } H5E_END_TRY; if (ret >= 0) - TEST_ERROR + TEST_ERROR; /* Should fail to disable file 3 */ H5E_BEGIN_TRY @@ -3634,7 +3636,7 @@ test_enable_disable_eot(void) } H5E_END_TRY; if (ret >= 0) - TEST_ERROR + TEST_ERROR; /* Closing */ if (H5Fclose(fid1) < 0) @@ -3702,9 +3704,8 @@ error: static herr_t verify_updater_flags(char *ud_name, uint16_t expected_flags) { - FILE * ud_fp; /* Updater file pointer */ - uint16_t flags; - size_t ret; /* Return value */ + FILE * ud_fp = NULL; /* Updater file pointer */ + uint16_t flags = 0; /* The "flags" field in the updater file */ /* Open the updater file */ if ((ud_fp = HDfopen(ud_name, "r")) == NULL) @@ -3715,7 +3716,7 @@ verify_updater_flags(char *ud_name, uint16_t expected_flags) FAIL_STACK_ERROR; /* Read "flags" from the updater file */ - if ((ret = HDfread(&flags, UD_SIZE_2, 1, ud_fp)) != (size_t)1) + if(HDfread(&flags, UD_SIZE_2, 1, ud_fp) != (size_t)1) FAIL_STACK_ERROR; if (flags != expected_flags) @@ -3786,11 +3787,11 @@ test_updater_flags(void) fapl = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config); if (fapl == H5I_INVALID_HID) - TEST_ERROR + TEST_ERROR; if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, 4096)) < 0) { HDprintf("vfd_swmr_create_fcpl() failed"); - FAIL_STACK_ERROR + FAIL_STACK_ERROR; } if ((fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl)) < 0) @@ -3915,7 +3916,7 @@ test_updater_flags_same_file_opens(void) if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, 4096)) < 0) { HDprintf("vfd_swmr_create_fcpl() failed"); - FAIL_STACK_ERROR + FAIL_STACK_ERROR; } /* Create the test file */ @@ -4034,8 +4035,8 @@ error: static void clean_chk_ud_files(char *md_file_path, char *updater_file_path) { - char chk_name[1024 + 4]; - char ud_name[1024 + 4]; + char chk_name[FILE_NAME_LEN]; /* Checksum file name */ + char ud_name[FILE_NAME_LEN]; /* Updater file name */ uint64_t i; /* Name of the checksum file: <md_file_path>.chk */ @@ -4050,7 +4051,7 @@ clean_chk_ud_files(char *md_file_path, char *updater_file_path) /* Remove all the updater files if exist: <updater_file_path>.<i> */ for (i = 0;; i++) { - sprintf(ud_name, "%s.%lu", updater_file_path, i); + HDsprintf(ud_name, "%s.%lu", updater_file_path, i); if (HDaccess(ud_name, F_OK) != 0) break; HDremove(ud_name); @@ -4083,16 +4084,16 @@ clean_chk_ud_files(char *md_file_path, char *updater_file_path) static herr_t verify_ud_chk(char *md_file_path, char *ud_file_path) { - char chk_name[1024 + 4]; /* Checksum file name */ - char ud_name[1024 + 4]; /* Updater file name */ - FILE * chk_fp; /* Checksum file pointer */ - FILE * ud_fp; /* Updater file pointer */ - uint64_t ud_seq_num; /* Sequence number in the updater file */ - uint64_t chk_ud_seq_num; /* Updater sequence number in the checksum file */ + char chk_name[FILE_NAME_LEN]; /* Checksum file name */ + char ud_name[FILE_NAME_LEN]; /* Updater file name */ + FILE * chk_fp = NULL; /* Checksum file pointer */ + FILE * ud_fp = NULL; /* Updater file pointer */ + uint64_t ud_seq_num = 0; /* Sequence number in the updater file */ + uint64_t chk_ud_seq_num = 0; /* Updater sequence number in the checksum file */ uint64_t i; /* Local index variable */ long size = 0; /* Size of the file */ - size_t change_list_len; /* change_list_len in the updater file header */ - uint32_t num_change_list_entries; /* num_change_list_entries in the updater change list header */ + size_t change_list_len = 0; /* change_list_len in the updater file header */ + uint32_t num_change_list_entries = 0; /* num_change_list_entries in the updater change list header */ /* Open the checksum file */ HDsprintf(chk_name, "%s.chk", md_file_path); @@ -4141,7 +4142,7 @@ verify_ud_chk(char *md_file_path, char *ud_file_path) } else { if (change_list_len != H5F_UD_CL_SIZE(num_change_list_entries)) - TEST_ERROR + TEST_ERROR; } } @@ -4184,7 +4185,7 @@ error: * Purpose: This is the callback function used by * test_updater_generate_md_checksums() when the * H5F_ACS_GENERATE_MD_CK_CB_NAME property is set in fapl. - * --Opens and read the metadata file into a buffer. + * --Open and read the metadata file into a buffer. * --Generate checksum for the metadata file * --Write the tick number and the checksum to the checksum file * @@ -4203,7 +4204,7 @@ md_ck_cb(char *md_file_path, uint64_t updater_seq_num) long size = 0; /* File size returned from HDftell() */ void * buf = NULL; /* Buffer for holding the metadata file content */ uint32_t chksum = 0; /* The checksum generated for the metadata file */ - char chk_name[1024 + 4]; /* Buffer for the checksum file name */ + char chk_name[FILE_NAME_LEN]; /* Buffer for the checksum file name */ size_t ret; /* Return value */ /* Open the metadata file */ @@ -4320,29 +4321,32 @@ test_updater_generate_md_checksums(hbool_t file_create) fapl = vfd_swmr_create_fapl(TRUE, TRUE, FALSE, 4096, &config); if (fapl == H5I_INVALID_HID) - TEST_ERROR + TEST_ERROR; if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, 4096)) < 0) { HDprintf("vfd_swmr_create_fcpl() failed"); - FAIL_STACK_ERROR + FAIL_STACK_ERROR; } /* Set up callback to generate checksums for updater's metadata files */ cb_info.func = md_ck_cb; /* Activate private property to generate checksums for updater's metadata file */ - H5Pset(fapl, H5F_ACS_GENERATE_MD_CK_CB_NAME, &cb_info); + if(H5Pset(fapl, H5F_ACS_GENERATE_MD_CK_CB_NAME, &cb_info) < 0) + FAIL_STACK_ERROR; /* Use file creation or file open for testing */ if (file_create) { - if ((fid = H5Fcreate(FILENAME4, H5F_ACC_TRUNC, fcpl, fapl)) < 0) - TEST_ERROR; - } - else { - fid = H5Fcreate(FILENAME4, H5F_ACC_TRUNC, fcpl, H5P_DEFAULT); - H5Fclose(fid); + if((fid = H5Fcreate(FILENAME4, H5F_ACC_TRUNC, fcpl, fapl)) < 0) + FAIL_STACK_ERROR; + } else { + if((fid = H5Fcreate(FILENAME4, H5F_ACC_TRUNC, fcpl, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR; + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR; - fid = H5Fopen(FILENAME4, H5F_ACC_RDWR, fapl); + if((fid = H5Fopen(FILENAME4, H5F_ACC_RDWR, fapl)) < 0) + FAIL_STACK_ERROR; } /* Close the file */ diff --git a/test/vfd_swmr_common.c b/test/vfd_swmr_common.c index 7e4ac59..f314304 100644 --- a/test/vfd_swmr_common.c +++ b/test/vfd_swmr_common.c @@ -344,6 +344,8 @@ await_signal(hid_t fid) #endif /* H5_HAVE_WIN32_API */ /* Revised support routines that can be used for all VFD SWMR integration tests + * NOTE: For tests that call this common routine, md_file_path needs to be set + * regardless of whether maintain_metadata_file is true or false. */ void init_vfd_swmr_config(H5F_vfd_swmr_config_t *config, uint32_t tick_len, uint32_t max_lag, hbool_t writer, -- cgit v0.12 From cf7f42cbd5169eae0045210ff4328818a17d3310 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 7 Dec 2021 00:54:55 +0000 Subject: Committing clang-format changes --- src/H5Fint.c | 2 +- test/vfd_swmr.c | 53 +++++++++++++++++++++++++------------------------- test/vfd_swmr_common.c | 2 +- 3 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/H5Fint.c b/src/H5Fint.c index f0d03e4..b80fd15 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -1856,7 +1856,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) H5F_generate_md_ck_cb_t cb_info = {NULL}; /* For VFD SWMR NFS testing: initialize the callback to generate checksums for metadata files */ - H5F_t * ret_value = NULL; /* Actual return value */ + H5F_t *ret_value = NULL; /* Actual return value */ FUNC_ENTER_NOAPI(NULL) diff --git a/test/vfd_swmr.c b/test/vfd_swmr.c index d87f512..cfead39 100644 --- a/test/vfd_swmr.c +++ b/test/vfd_swmr.c @@ -55,7 +55,7 @@ #define FNAME "non_vfd_swmr_file.h5" -#define FILE_NAME_LEN 1024 +#define FILE_NAME_LEN 1024 /* Defines used by verify_updater_flags() and verify_ud_chk() helper routine */ @@ -3716,7 +3716,7 @@ verify_updater_flags(char *ud_name, uint16_t expected_flags) FAIL_STACK_ERROR; /* Read "flags" from the updater file */ - if(HDfread(&flags, UD_SIZE_2, 1, ud_fp) != (size_t)1) + if (HDfread(&flags, UD_SIZE_2, 1, ud_fp) != (size_t)1) FAIL_STACK_ERROR; if (flags != expected_flags) @@ -4035,8 +4035,8 @@ error: static void clean_chk_ud_files(char *md_file_path, char *updater_file_path) { - char chk_name[FILE_NAME_LEN]; /* Checksum file name */ - char ud_name[FILE_NAME_LEN]; /* Updater file name */ + char chk_name[FILE_NAME_LEN]; /* Checksum file name */ + char ud_name[FILE_NAME_LEN]; /* Updater file name */ uint64_t i; /* Name of the checksum file: <md_file_path>.chk */ @@ -4084,15 +4084,15 @@ clean_chk_ud_files(char *md_file_path, char *updater_file_path) static herr_t verify_ud_chk(char *md_file_path, char *ud_file_path) { - char chk_name[FILE_NAME_LEN]; /* Checksum file name */ - char ud_name[FILE_NAME_LEN]; /* Updater file name */ - FILE * chk_fp = NULL; /* Checksum file pointer */ - FILE * ud_fp = NULL; /* Updater file pointer */ - uint64_t ud_seq_num = 0; /* Sequence number in the updater file */ - uint64_t chk_ud_seq_num = 0; /* Updater sequence number in the checksum file */ - uint64_t i; /* Local index variable */ - long size = 0; /* Size of the file */ - size_t change_list_len = 0; /* change_list_len in the updater file header */ + char chk_name[FILE_NAME_LEN]; /* Checksum file name */ + char ud_name[FILE_NAME_LEN]; /* Updater file name */ + FILE * chk_fp = NULL; /* Checksum file pointer */ + FILE * ud_fp = NULL; /* Updater file pointer */ + uint64_t ud_seq_num = 0; /* Sequence number in the updater file */ + uint64_t chk_ud_seq_num = 0; /* Updater sequence number in the checksum file */ + uint64_t i; /* Local index variable */ + long size = 0; /* Size of the file */ + size_t change_list_len = 0; /* change_list_len in the updater file header */ uint32_t num_change_list_entries = 0; /* num_change_list_entries in the updater change list header */ /* Open the checksum file */ @@ -4199,13 +4199,13 @@ error: static herr_t md_ck_cb(char *md_file_path, uint64_t updater_seq_num) { - FILE * md_fp = NULL; /* Metadata file pointer */ - FILE * chk_fp = NULL; /* Checksum file pointer */ - long size = 0; /* File size returned from HDftell() */ - void * buf = NULL; /* Buffer for holding the metadata file content */ - uint32_t chksum = 0; /* The checksum generated for the metadata file */ - char chk_name[FILE_NAME_LEN]; /* Buffer for the checksum file name */ - size_t ret; /* Return value */ + FILE * md_fp = NULL; /* Metadata file pointer */ + FILE * chk_fp = NULL; /* Checksum file pointer */ + long size = 0; /* File size returned from HDftell() */ + void * buf = NULL; /* Buffer for holding the metadata file content */ + uint32_t chksum = 0; /* The checksum generated for the metadata file */ + char chk_name[FILE_NAME_LEN]; /* Buffer for the checksum file name */ + size_t ret; /* Return value */ /* Open the metadata file */ if ((md_fp = HDfopen(md_file_path, "r")) == NULL) @@ -4332,20 +4332,21 @@ test_updater_generate_md_checksums(hbool_t file_create) cb_info.func = md_ck_cb; /* Activate private property to generate checksums for updater's metadata file */ - if(H5Pset(fapl, H5F_ACS_GENERATE_MD_CK_CB_NAME, &cb_info) < 0) + if (H5Pset(fapl, H5F_ACS_GENERATE_MD_CK_CB_NAME, &cb_info) < 0) FAIL_STACK_ERROR; /* Use file creation or file open for testing */ if (file_create) { - if((fid = H5Fcreate(FILENAME4, H5F_ACC_TRUNC, fcpl, fapl)) < 0) + if ((fid = H5Fcreate(FILENAME4, H5F_ACC_TRUNC, fcpl, fapl)) < 0) FAIL_STACK_ERROR; - } else { - if((fid = H5Fcreate(FILENAME4, H5F_ACC_TRUNC, fcpl, H5P_DEFAULT)) < 0) + } + else { + if ((fid = H5Fcreate(FILENAME4, H5F_ACC_TRUNC, fcpl, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR; - if(H5Fclose(fid) < 0) + if (H5Fclose(fid) < 0) FAIL_STACK_ERROR; - if((fid = H5Fopen(FILENAME4, H5F_ACC_RDWR, fapl)) < 0) + if ((fid = H5Fopen(FILENAME4, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR; } diff --git a/test/vfd_swmr_common.c b/test/vfd_swmr_common.c index f314304..9b711dd 100644 --- a/test/vfd_swmr_common.c +++ b/test/vfd_swmr_common.c @@ -344,7 +344,7 @@ await_signal(hid_t fid) #endif /* H5_HAVE_WIN32_API */ /* Revised support routines that can be used for all VFD SWMR integration tests - * NOTE: For tests that call this common routine, md_file_path needs to be set + * NOTE: For tests that call this common routine, md_file_path needs to be set * regardless of whether maintain_metadata_file is true or false. */ void -- cgit v0.12 From 03047ba4c082b482f9fc0c52be56921c1581e4be Mon Sep 17 00:00:00 2001 From: vchoi <vchoi@jelly.ad.hdfgroup.org> Date: Mon, 6 Dec 2021 18:58:29 -0600 Subject: Clang format changes. --- src/H5Fint.c | 2 +- test/vfd_swmr.c | 53 +++++++++++++++++++++++++------------------------- test/vfd_swmr_common.c | 2 +- 3 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/H5Fint.c b/src/H5Fint.c index f0d03e4..b80fd15 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -1856,7 +1856,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) H5F_generate_md_ck_cb_t cb_info = {NULL}; /* For VFD SWMR NFS testing: initialize the callback to generate checksums for metadata files */ - H5F_t * ret_value = NULL; /* Actual return value */ + H5F_t *ret_value = NULL; /* Actual return value */ FUNC_ENTER_NOAPI(NULL) diff --git a/test/vfd_swmr.c b/test/vfd_swmr.c index d87f512..cfead39 100644 --- a/test/vfd_swmr.c +++ b/test/vfd_swmr.c @@ -55,7 +55,7 @@ #define FNAME "non_vfd_swmr_file.h5" -#define FILE_NAME_LEN 1024 +#define FILE_NAME_LEN 1024 /* Defines used by verify_updater_flags() and verify_ud_chk() helper routine */ @@ -3716,7 +3716,7 @@ verify_updater_flags(char *ud_name, uint16_t expected_flags) FAIL_STACK_ERROR; /* Read "flags" from the updater file */ - if(HDfread(&flags, UD_SIZE_2, 1, ud_fp) != (size_t)1) + if (HDfread(&flags, UD_SIZE_2, 1, ud_fp) != (size_t)1) FAIL_STACK_ERROR; if (flags != expected_flags) @@ -4035,8 +4035,8 @@ error: static void clean_chk_ud_files(char *md_file_path, char *updater_file_path) { - char chk_name[FILE_NAME_LEN]; /* Checksum file name */ - char ud_name[FILE_NAME_LEN]; /* Updater file name */ + char chk_name[FILE_NAME_LEN]; /* Checksum file name */ + char ud_name[FILE_NAME_LEN]; /* Updater file name */ uint64_t i; /* Name of the checksum file: <md_file_path>.chk */ @@ -4084,15 +4084,15 @@ clean_chk_ud_files(char *md_file_path, char *updater_file_path) static herr_t verify_ud_chk(char *md_file_path, char *ud_file_path) { - char chk_name[FILE_NAME_LEN]; /* Checksum file name */ - char ud_name[FILE_NAME_LEN]; /* Updater file name */ - FILE * chk_fp = NULL; /* Checksum file pointer */ - FILE * ud_fp = NULL; /* Updater file pointer */ - uint64_t ud_seq_num = 0; /* Sequence number in the updater file */ - uint64_t chk_ud_seq_num = 0; /* Updater sequence number in the checksum file */ - uint64_t i; /* Local index variable */ - long size = 0; /* Size of the file */ - size_t change_list_len = 0; /* change_list_len in the updater file header */ + char chk_name[FILE_NAME_LEN]; /* Checksum file name */ + char ud_name[FILE_NAME_LEN]; /* Updater file name */ + FILE * chk_fp = NULL; /* Checksum file pointer */ + FILE * ud_fp = NULL; /* Updater file pointer */ + uint64_t ud_seq_num = 0; /* Sequence number in the updater file */ + uint64_t chk_ud_seq_num = 0; /* Updater sequence number in the checksum file */ + uint64_t i; /* Local index variable */ + long size = 0; /* Size of the file */ + size_t change_list_len = 0; /* change_list_len in the updater file header */ uint32_t num_change_list_entries = 0; /* num_change_list_entries in the updater change list header */ /* Open the checksum file */ @@ -4199,13 +4199,13 @@ error: static herr_t md_ck_cb(char *md_file_path, uint64_t updater_seq_num) { - FILE * md_fp = NULL; /* Metadata file pointer */ - FILE * chk_fp = NULL; /* Checksum file pointer */ - long size = 0; /* File size returned from HDftell() */ - void * buf = NULL; /* Buffer for holding the metadata file content */ - uint32_t chksum = 0; /* The checksum generated for the metadata file */ - char chk_name[FILE_NAME_LEN]; /* Buffer for the checksum file name */ - size_t ret; /* Return value */ + FILE * md_fp = NULL; /* Metadata file pointer */ + FILE * chk_fp = NULL; /* Checksum file pointer */ + long size = 0; /* File size returned from HDftell() */ + void * buf = NULL; /* Buffer for holding the metadata file content */ + uint32_t chksum = 0; /* The checksum generated for the metadata file */ + char chk_name[FILE_NAME_LEN]; /* Buffer for the checksum file name */ + size_t ret; /* Return value */ /* Open the metadata file */ if ((md_fp = HDfopen(md_file_path, "r")) == NULL) @@ -4332,20 +4332,21 @@ test_updater_generate_md_checksums(hbool_t file_create) cb_info.func = md_ck_cb; /* Activate private property to generate checksums for updater's metadata file */ - if(H5Pset(fapl, H5F_ACS_GENERATE_MD_CK_CB_NAME, &cb_info) < 0) + if (H5Pset(fapl, H5F_ACS_GENERATE_MD_CK_CB_NAME, &cb_info) < 0) FAIL_STACK_ERROR; /* Use file creation or file open for testing */ if (file_create) { - if((fid = H5Fcreate(FILENAME4, H5F_ACC_TRUNC, fcpl, fapl)) < 0) + if ((fid = H5Fcreate(FILENAME4, H5F_ACC_TRUNC, fcpl, fapl)) < 0) FAIL_STACK_ERROR; - } else { - if((fid = H5Fcreate(FILENAME4, H5F_ACC_TRUNC, fcpl, H5P_DEFAULT)) < 0) + } + else { + if ((fid = H5Fcreate(FILENAME4, H5F_ACC_TRUNC, fcpl, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR; - if(H5Fclose(fid) < 0) + if (H5Fclose(fid) < 0) FAIL_STACK_ERROR; - if((fid = H5Fopen(FILENAME4, H5F_ACC_RDWR, fapl)) < 0) + if ((fid = H5Fopen(FILENAME4, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR; } diff --git a/test/vfd_swmr_common.c b/test/vfd_swmr_common.c index f314304..9b711dd 100644 --- a/test/vfd_swmr_common.c +++ b/test/vfd_swmr_common.c @@ -344,7 +344,7 @@ await_signal(hid_t fid) #endif /* H5_HAVE_WIN32_API */ /* Revised support routines that can be used for all VFD SWMR integration tests - * NOTE: For tests that call this common routine, md_file_path needs to be set + * NOTE: For tests that call this common routine, md_file_path needs to be set * regardless of whether maintain_metadata_file is true or false. */ void -- cgit v0.12 From ae5680405d6440fd2fe92687dac05a6437429269 Mon Sep 17 00:00:00 2001 From: vchoi <vchoi@jelly.ad.hdfgroup.org> Date: Tue, 7 Dec 2021 12:01:38 -0600 Subject: Trying to fix the PR's window test failures. --- test/vfd_swmr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/vfd_swmr.c b/test/vfd_swmr.c index cfead39..7cddc47 100644 --- a/test/vfd_swmr.c +++ b/test/vfd_swmr.c @@ -4363,7 +4363,7 @@ test_updater_generate_md_checksums(hbool_t file_create) if (verify_ud_chk(config.md_file_path, config.updater_file_path) < 0) TEST_ERROR; - /* It's important to clean up the chechsum and updater files. */ + /* It's important to clean up the checksum and updater files. */ clean_chk_ud_files(config.md_file_path, config.updater_file_path); PASSED(); @@ -4449,8 +4449,10 @@ main(void) if (use_file_locking) { nerrors += test_updater_flags(); nerrors += test_updater_flags_same_file_opens(); +#ifndef H5_HAVE_WIN32_API nerrors += test_updater_generate_md_checksums(TRUE); nerrors += test_updater_generate_md_checksums(FALSE); +#endif nerrors += test_shadow_index_lookup(); -- cgit v0.12 From b78f393d80d3bf6904920787a5e289bbffa05167 Mon Sep 17 00:00:00 2001 From: myang6 <myang6@hdfgroup.org> Date: Tue, 7 Dec 2021 12:27:31 -0600 Subject: Revise comments to address the PR review. --- test/vfd_swmr_indep_rw_writer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/vfd_swmr_indep_rw_writer.c b/test/vfd_swmr_indep_rw_writer.c index 2ab756b..73fa805 100644 --- a/test/vfd_swmr_indep_rw_writer.c +++ b/test/vfd_swmr_indep_rw_writer.c @@ -517,8 +517,9 @@ vrfy_dset(const state_t *s, mat_t *mat) unsigned int which = 0; herr_t status; - /* A failure to read the data may indicate the data isn't ready yet. Instead of displaying the error - * stack, simply return false and let the caller repeat this step. + /* The approach is adapted from the big set test. A failure to read the data may indicate the data isn't ready yet. + * For this case, we will not display the error stack, instead sleeping for one tenth of a second, + * call H5Drefresh and try to call H5Dread again. After NUM_ATTEMPTS times, issue an error. */ for (i = 0; i < NUM_ATTEMPTS; i++) { -- cgit v0.12 From 4b4c7c4b73038545e29de1608a82cee551b97d82 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 7 Dec 2021 18:29:24 +0000 Subject: Committing clang-format changes --- test/vfd_swmr_indep_rw_writer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/vfd_swmr_indep_rw_writer.c b/test/vfd_swmr_indep_rw_writer.c index 73fa805..678ccb2 100644 --- a/test/vfd_swmr_indep_rw_writer.c +++ b/test/vfd_swmr_indep_rw_writer.c @@ -517,9 +517,9 @@ vrfy_dset(const state_t *s, mat_t *mat) unsigned int which = 0; herr_t status; - /* The approach is adapted from the big set test. A failure to read the data may indicate the data isn't ready yet. - * For this case, we will not display the error stack, instead sleeping for one tenth of a second, - * call H5Drefresh and try to call H5Dread again. After NUM_ATTEMPTS times, issue an error. + /* The approach is adapted from the big set test. A failure to read the data may indicate the data isn't + * ready yet. For this case, we will not display the error stack, instead sleeping for one tenth of a + * second, call H5Drefresh and try to call H5Dread again. After NUM_ATTEMPTS times, issue an error. */ for (i = 0; i < NUM_ATTEMPTS; i++) { -- cgit v0.12 From ca8180f21ab60b2a19936341eeeca24abcac3f9f Mon Sep 17 00:00:00 2001 From: vchoi <vchoi@jelly.ad.hdfgroup.org> Date: Tue, 7 Dec 2021 13:08:24 -0600 Subject: Add comments about the window test failure. --- test/vfd_swmr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/test/vfd_swmr.c b/test/vfd_swmr.c index 7cddc47..630b25d 100644 --- a/test/vfd_swmr.c +++ b/test/vfd_swmr.c @@ -4450,6 +4450,7 @@ main(void) nerrors += test_updater_flags(); nerrors += test_updater_flags_same_file_opens(); #ifndef H5_HAVE_WIN32_API + /* VFD SWMR: Fails on windows due to error from generate_md_ck_cb(). */ nerrors += test_updater_generate_md_checksums(TRUE); nerrors += test_updater_generate_md_checksums(FALSE); #endif -- cgit v0.12 From 0247538fc5226b0899f00c45adab2a454627de02 Mon Sep 17 00:00:00 2001 From: Dana Robinson <43805+derobins@users.noreply.github.com> Date: Wed, 8 Dec 2021 09:40:30 -0800 Subject: VFD SWMR: Normalization with develop (#1270) Brings many October-November changes from develop --- .github/workflows/main.yml | 8 +- .github/workflows/pr-check.yml | 8 +- CMakeInstallation.cmake | 10 +- MANIFEST | 35 +- Makefile.am | 4 +- README.txt | 2 +- bin/trace | 3 +- c++/src/H5PredType.cpp | 46 +- c++/src/cpp_doc_config | 2 +- config/clang-cxxflags | 9 +- config/clang-flags | 9 +- config/clang-warnings/noerror-general | 82 -- config/cmake/ConfigureChecks.cmake | 11 +- config/cmake/FindCIRCLE.cmake | 49 + config/cmake/FindDTCMP.cmake | 48 + config/cmake/FindMFU.cmake | 100 ++ config/cmake/H5pubconf.h.in | 11 +- config/cmake/HDF5UseFortran.cmake | 77 +- config/cmake/HDF5_Examples.cmake.in | 4 +- config/cmake/HDFCXXCompilerFlags.cmake | 35 +- config/cmake/HDFCompilerFlags.cmake | 25 +- config/cmake/HDFFortranCompilerFlags.cmake | 10 +- config/cmake/hdf5-config.cmake.in | 6 +- config/cmake/jrunTest.cmake | 7 +- config/cmake/jvolTest.cmake | 301 ----- config/cmake/libhdf5.settings.cmake.in | 51 +- config/cmake/scripts/HDF5config.cmake | 4 +- config/cmake_ext_mod/HDFLibMacros.cmake | 8 +- config/cmake_ext_mod/HDFMacros.cmake | 3 + config/gnu-cxxflags | 15 +- config/gnu-fflags | 8 +- config/gnu-flags | 11 +- config/gnu-warnings/cxx-developer-4.8 | 16 + config/gnu-warnings/cxx-noerror-5 | 11 - config/gnu-warnings/cxx-noerror-general | 32 - config/gnu-warnings/developer-gfort-5 | 1 + config/gnu-warnings/error-5 | 1 + config/gnu-warnings/error-8 | 5 +- config/gnu-warnings/error-general | 1 + config/gnu-warnings/gfort-5 | 1 - config/gnu-warnings/no-cxx-developer-4.8 | 9 + config/gnu-warnings/noerror-5 | 12 - config/gnu-warnings/noerror-8 | 25 - config/gnu-warnings/noerror-general | 92 -- config/sanitizer/code-coverage.cmake | 18 +- config/sanitizer/sanitizers.cmake | 2 +- configure.ac | 126 +- doc/library-init-shutdown.md | 56 + doxygen/CMakeLists.txt | 1 + doxygen/Doxyfile.in | 3 +- doxygen/aliases | 16 +- doxygen/dox/About.dox | 120 +- doxygen/dox/FTS.dox | 8 + doxygen/dox/FileFormatSpec.dox | 23 - doxygen/dox/OtherSpecs.dox | 11 - doxygen/dox/RFC.dox | 11 + doxygen/dox/Specifications.dox | 38 +- doxygen/dox/TechnicalNotes.dox | 28 + doxygen/examples/DebuggingHDF5Applications.html | 392 ++++++ doxygen/examples/FileFormat.html | 1275 ++++++++++++++++++ doxygen/examples/Filters.html | 450 +++++++ doxygen/examples/IOFlow.html | 137 ++ doxygen/hdf5doxy_layout.xml | 1 + doxygen/img/IOFlow.gif | Bin 0 -> 57285 bytes doxygen/img/IOFlow2.gif | Bin 0 -> 29805 bytes doxygen/img/IOFlow3.gif | Bin 0 -> 21442 bytes fortran/src/H5_f.c | 8 - fortran/test/tH5A.F90 | 4 +- hl/CMakeLists.txt | 8 + hl/fortran/src/H5LTfc.c | 4 - hl/src/H5DS.c | 900 +++++++++---- hl/src/H5DSprivate.h | 8 +- hl/src/H5DSpublic.h | 2 + hl/src/H5LD.c | 70 +- hl/src/H5LT.c | 64 +- hl/test/CMakeTests.cmake | 2 + hl/test/gen_test_ds.c | 6 +- hl/test/test_ds.c | 71 +- hl/test/test_ds_be_new_ref-32bit.h5 | Bin 0 -> 13480 bytes hl/test/test_ds_be_new_ref.h5 | Bin 0 -> 16040 bytes hl/test/test_ds_le_new_ref.h5 | Bin 0 -> 16040 bytes hl/test/test_packet_vlen.c | 4 +- java/src/hdf/hdf5lib/CMakeLists.txt | 22 +- java/src/hdf/hdf5lib/H5.java | 55 +- java/src/hdf/hdf5lib/callbacks/package-info.java | 27 + java/src/hdf/hdf5lib/exceptions/package-info.java | 31 + java/src/hdf/hdf5lib/package-info.java | 174 +++ java/src/hdf/hdf5lib/structs/package-info.java | 17 + java/src/jni/h5util.c | 12 +- java/test/CMakeLists.txt | 22 +- java/test/TestH5.java | 4 +- m4/aclocal_fc.f90 | 21 +- m4/aclocal_fc.m4 | 150 +-- release_docs/RELEASE.txt | 1347 ++++++++++---------- src/CMakeLists.txt | 44 +- src/H5ACprivate.h | 18 +- src/H5B2int.c | 33 +- src/H5B2pkg.h | 12 +- src/H5Dchunk.c | 43 +- src/H5ESpublic.h | 10 +- src/H5HF.c | 19 +- src/H5HFcache.c | 12 +- src/H5HFman.c | 10 +- src/H5HGprivate.h | 2 +- src/H5M.c | 4 +- src/H5Pfapl.c | 8 +- src/H5Pocpl.c | 4 + src/H5Ppublic.h | 8 +- src/H5RS.c | 12 +- src/H5Rint.c | 16 +- src/H5Rpkg.h | 2 +- src/H5SL.c | 666 +++------- src/H5SLprivate.h | 4 - src/H5T.c | 218 ++-- src/H5Tconv.c | 8 - src/H5Tnative.c | 23 +- src/H5Tpkg.h | 6 - src/H5Tpublic.h | 4 - src/H5Tref.c | 24 +- src/H5VL.c | 33 + src/H5VLpublic.h | 13 + src/H5Zscaleoffset.c | 66 +- src/H5Ztrans.c | 64 - src/H5detect.c | 2 +- src/H5private.h | 4 +- src/H5public.h | 6 +- src/H5trace.c | 2 - src/libhdf5.settings.in | 51 +- src/uthash.h | 30 +- test/cache_api.c | 2 +- test/cork.c | 137 +- test/dsets.c | 26 +- test/dt_arith.c | 160 +-- test/dtransform.c | 4 - test/dtypes.c | 2 - test/filter_plugin.c | 99 ++ test/objcopy.c | 6 +- test/swmr.c | 4 +- test/tconfig.c | 16 - test/testmeta.c | 2 +- test/tskiplist.c | 208 --- test/tunicode.c | 2 +- test/tvlstr.c | 6 +- tools/lib/h5diff_array.c | 47 +- tools/lib/h5diff_util.c | 2 - tools/lib/h5tools.c | 14 +- tools/lib/h5tools_str.c | 2 - tools/lib/h5tools_utils.c | 1 + tools/src/h5dump/h5dump.c | 3 - tools/src/h5import/h5import.c | 38 +- tools/test/h5diff/h5diffgentest.c | 2 - tools/test/h5dump/CMakeTests.cmake | 2 +- tools/test/h5import/h5importtest.c | 28 +- tools/test/h5repack/CMakeTests.cmake | 6 +- tools/test/h5repack/h5repack.sh.in | 17 +- .../h5repack_layout.h5-plugin_version_test.ddl | 14 +- 156 files changed, 5730 insertions(+), 3558 deletions(-) delete mode 100644 config/clang-warnings/noerror-general create mode 100644 config/cmake/FindCIRCLE.cmake create mode 100644 config/cmake/FindDTCMP.cmake create mode 100644 config/cmake/FindMFU.cmake delete mode 100644 config/cmake/jvolTest.cmake create mode 100644 config/gnu-warnings/cxx-developer-4.8 delete mode 100644 config/gnu-warnings/cxx-noerror-5 delete mode 100644 config/gnu-warnings/cxx-noerror-general create mode 100644 config/gnu-warnings/developer-gfort-5 delete mode 100644 config/gnu-warnings/gfort-5 create mode 100644 config/gnu-warnings/no-cxx-developer-4.8 delete mode 100644 config/gnu-warnings/noerror-5 delete mode 100644 config/gnu-warnings/noerror-8 delete mode 100644 config/gnu-warnings/noerror-general create mode 100644 doc/library-init-shutdown.md create mode 100644 doxygen/dox/FTS.dox delete mode 100644 doxygen/dox/FileFormatSpec.dox delete mode 100644 doxygen/dox/OtherSpecs.dox create mode 100644 doxygen/examples/DebuggingHDF5Applications.html create mode 100644 doxygen/examples/FileFormat.html create mode 100644 doxygen/examples/Filters.html create mode 100644 doxygen/examples/IOFlow.html create mode 100644 doxygen/img/IOFlow.gif create mode 100644 doxygen/img/IOFlow2.gif create mode 100644 doxygen/img/IOFlow3.gif create mode 100644 hl/test/test_ds_be_new_ref-32bit.h5 create mode 100644 hl/test/test_ds_be_new_ref.h5 create mode 100644 hl/test/test_ds_le_new_ref.h5 create mode 100644 java/src/hdf/hdf5lib/callbacks/package-info.java create mode 100644 java/src/hdf/hdf5lib/exceptions/package-info.java create mode 100644 java/src/hdf/hdf5lib/package-info.java create mode 100644 java/src/hdf/hdf5lib/structs/package-info.java diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b0ebed0..c3ed6b2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,7 +21,7 @@ jobs: include: - name: "Windows Latest MSVC" artifact: "Windows-MSVC.tar.xz" - os: windows-latest + os: windows-2022 build_type: "Release" toolchain: "" cpp: ON @@ -30,7 +30,7 @@ jobs: ts: OFF hl: ON parallel: OFF - generator: "-G \"Visual Studio 16 2019\" -A x64" + generator: "-G \"Visual Studio 17 2022\" -A x64" - name: "Ubuntu Latest GCC" artifact: "Linux.tar.xz" os: ubuntu-latest @@ -82,7 +82,7 @@ jobs: # Threadsafe runs - name: "Windows TS MSVC" artifact: "Windows-MSVCTS.tar.xz" - os: windows-2016 + os: windows-2019 build_type: "Release" toolchain: "" cpp: OFF @@ -91,7 +91,7 @@ jobs: ts: ON hl: OFF parallel: OFF - generator: "-G \"Visual Studio 15 2017 Win64\"" + generator: "-G \"Visual Studio 16 2019\" -A x64" - name: "Ubuntu TS GCC" artifact: "LinuxTS.tar.xz" os: ubuntu-latest diff --git a/.github/workflows/pr-check.yml b/.github/workflows/pr-check.yml index d6081f4..33608b5 100644 --- a/.github/workflows/pr-check.yml +++ b/.github/workflows/pr-check.yml @@ -16,7 +16,7 @@ jobs: include: - name: "Windows Latest MSVC" artifact: "Windows-MSVC.tar.xz" - os: windows-latest + os: windows-2022 build_type: "Release" toolchain: "" cpp: ON @@ -25,7 +25,7 @@ jobs: ts: OFF hl: ON parallel: OFF - generator: "-G \"Visual Studio 16 2019\" -A x64" + generator: "-G \"Visual Studio 17 2022\" -A x64" - name: "Ubuntu Latest GCC" artifact: "Linux.tar.xz" os: ubuntu-latest @@ -77,7 +77,7 @@ jobs: # Threadsafe runs - name: "Windows TS MSVC" artifact: "Windows-MSVCTS.tar.xz" - os: windows-2016 + os: windows-2019 build_type: "Release" toolchain: "" cpp: OFF @@ -86,7 +86,7 @@ jobs: ts: ON hl: OFF parallel: OFF - generator: "-G \"Visual Studio 15 2017 Win64\"" + generator: "-G \"Visual Studio 16 2019\" -A x64" - name: "Ubuntu TS GCC" artifact: "LinuxTS.tar.xz" os: ubuntu-latest diff --git a/CMakeInstallation.cmake b/CMakeInstallation.cmake index d811ea5..b506f05 100644 --- a/CMakeInstallation.cmake +++ b/CMakeInstallation.cmake @@ -31,7 +31,7 @@ if (NOT HDF5_EXTERNALLY_CONFIGURED) if (HDF5_EXPORTED_TARGETS) install ( EXPORT ${HDF5_EXPORTED_TARGETS} - DESTINATION ${HDF5_INSTALL_CMAKE_DIR}/hdf5 + DESTINATION ${HDF5_INSTALL_CMAKE_DIR} FILE ${HDF5_PACKAGE}${HDF_PACKAGE_EXT}-targets.cmake NAMESPACE ${HDF_PACKAGE_NAMESPACE} COMPONENT configinstall @@ -72,7 +72,7 @@ set (CURRENT_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}" ) configure_package_config_file ( ${HDF_RESOURCES_DIR}/hdf5-config.cmake.in "${HDF5_BINARY_DIR}/${HDF5_PACKAGE}${HDF_PACKAGE_EXT}-config.cmake" - INSTALL_DESTINATION "${HDF5_INSTALL_CMAKE_DIR}/hdf5" + INSTALL_DESTINATION "${HDF5_INSTALL_CMAKE_DIR}" PATH_VARS INCLUDE_INSTALL_DIR SHARE_INSTALL_DIR CURRENT_BUILD_DIR INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}" ) @@ -86,14 +86,14 @@ set (CURRENT_BUILD_DIR "${CMAKE_INSTALL_PREFIX}" ) configure_package_config_file ( ${HDF_RESOURCES_DIR}/hdf5-config.cmake.in "${HDF5_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${HDF5_PACKAGE}${HDF_PACKAGE_EXT}-config.cmake" - INSTALL_DESTINATION "${HDF5_INSTALL_CMAKE_DIR}/hdf5" + INSTALL_DESTINATION "${HDF5_INSTALL_CMAKE_DIR}" PATH_VARS INCLUDE_INSTALL_DIR SHARE_INSTALL_DIR CURRENT_BUILD_DIR ) if (NOT HDF5_EXTERNALLY_CONFIGURED) install ( FILES ${HDF5_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${HDF5_PACKAGE}${HDF_PACKAGE_EXT}-config.cmake - DESTINATION ${HDF5_INSTALL_CMAKE_DIR}/hdf5 + DESTINATION ${HDF5_INSTALL_CMAKE_DIR} COMPONENT configinstall ) endif () @@ -113,7 +113,7 @@ if (NOT HDF5_EXTERNALLY_CONFIGURED) #) install ( FILES ${HDF5_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${HDF5_PACKAGE}${HDF_PACKAGE_EXT}-config-version.cmake - DESTINATION ${HDF5_INSTALL_CMAKE_DIR}/hdf5 + DESTINATION ${HDF5_INSTALL_CMAKE_DIR} COMPONENT configinstall ) endif () diff --git a/MANIFEST b/MANIFEST index 75a7aca..cbb4a32 100644 --- a/MANIFEST +++ b/MANIFEST @@ -160,7 +160,6 @@ ./config/clang-warnings/error-general ./config/clang-warnings/general ./config/clang-warnings/no-developer-general -./config/clang-warnings/noerror-general ./config/gnu-warnings/4.8-4.last ./config/gnu-warnings/4.8 ./config/gnu-warnings/4.9 @@ -175,10 +174,9 @@ ./config/gnu-warnings/cxx-4.9 ./config/gnu-warnings/cxx-5 ./config/gnu-warnings/cxx-9 +./config/gnu-warnings/cxx-developer-4.8 ./config/gnu-warnings/cxx-error-5 ./config/gnu-warnings/cxx-error-general -./config/gnu-warnings/cxx-noerror-5 -./config/gnu-warnings/cxx-noerror-general ./config/gnu-warnings/developer-4.8 ./config/gnu-warnings/developer-7 ./config/gnu-warnings/developer-8 @@ -190,15 +188,13 @@ ./config/gnu-warnings/general ./config/gnu-warnings/gfort-general ./config/gnu-warnings/gfort-4.8 -./config/gnu-warnings/gfort-5 +./config/gnu-warnings/developer-gfort-5 ./config/gnu-warnings/gfort-6 ./config/gnu-warnings/gfort-8 +./config/gnu-warnings/no-cxx-developer-4.8 ./config/gnu-warnings/no-developer-4.8 ./config/gnu-warnings/no-developer-8 ./config/gnu-warnings/no-developer-general -./config/gnu-warnings/noerror-5 -./config/gnu-warnings/noerror-8 -./config/gnu-warnings/noerror-general ./config/intel-warnings/15 ./config/intel-warnings/18 ./config/intel-warnings/developer-general @@ -207,6 +203,10 @@ ./config/intel-warnings/win-general ./config/intel-warnings/ifort-general +./config/cmake/FindMFU.cmake +./config/cmake/FindDTCMP.cmake +./config/cmake/FindCIRCLE.cmake + ./config/site-specific/BlankForm ./doc/branches-explained.md @@ -219,7 +219,7 @@ ./doc/vfd-swmr-user-guide.md ./doc/code-conventions.md ./doc/contributing.md - +./doc/library-init-shutdown.md ./doxygen/aliases ./doxygen/CMakeLists.txt ./doxygen/Doxyfile.in @@ -228,11 +228,10 @@ ./doxygen/dox/Cookbook.dox ./doxygen/dox/DDLBNF110.dox ./doxygen/dox/DDLBNF112.dox -./doxygen/dox/FileFormatSpec.dox +./doxygen/dox/FTS.dox ./doxygen/dox/GettingStarted.dox ./doxygen/dox/H5AC_cache_config_t.dox ./doxygen/dox/MetadataCachingInHDF5.dox -./doxygen/dox/OtherSpecs.dox ./doxygen/dox/Overview.dox ./doxygen/dox/ReferenceManual.dox ./doxygen/dox/RFC.dox @@ -248,9 +247,12 @@ ./doxygen/dox/cookbook/Files.c ./doxygen/dox/cookbook/Files.dox ./doxygen/dox/cookbook/Performance.dox +./doxygen/examples/DebuggingHDF5Applications.html ./doxygen/examples/FF-IH_FileGroup.gif ./doxygen/examples/FF-IH_FileObject.gif +./doxygen/examples/FileFormat.html ./doxygen/examples/FileFormatSpecChunkDiagram.jpg +./doxygen/examples/Filters.html ./doxygen/examples/H5Pset_metadata_read_attempts.c ./doxygen/examples/H5Pset_object_flush_cb.c ./doxygen/examples/H5.format.1.0.html @@ -279,6 +281,7 @@ ./doxygen/examples/H5Z_examples.c ./doxygen/examples/H5_examples.c ./doxygen/examples/ImageSpec.html +./doxygen/examples/IOFlow.html ./doxygen/examples/PaletteExample1.gif ./doxygen/examples/Palettes.fm.anc.gif ./doxygen/examples/TableSpec.html @@ -294,6 +297,9 @@ ./doxygen/img/FF-IH_FileObject.gif ./doxygen/img/FileFormatSpecChunkDiagram.jpg ./doxygen/img/HDFG-logo.png +./doxygen/img/IOFlow.gif +./doxygen/img/IOFlow2.gif +./doxygen/img/IOFlow3.gif ./doxygen/img/PaletteExample1.gif ./doxygen/img/Palettes.fm.anc.gif ./doxygen/img/ftv2node.png @@ -3114,7 +3120,10 @@ ./hl/test/sepia.pal ./hl/test/test_ds.c ./hl/test/test_ds_be.h5 +./hl/test/test_ds_be_new_ref.h5 +./hl/test/test_ds_be_new_ref-32bit.h5 ./hl/test/test_ds_le.h5 +./hl/test/test_ds_le_new_ref.h5 ./hl/test/test_dset_append.c ./hl/test/test_file_image.c ./hl/test/test_h5do_compat.c @@ -3337,6 +3346,7 @@ ./java/src/hdf/hdf5lib/callbacks/H5P_prp_set_func_cb.java ./java/src/hdf/hdf5lib/callbacks/H5P_iterate_cb.java ./java/src/hdf/hdf5lib/callbacks/H5P_iterate_t.java +./java/src/hdf/hdf5lib/callbacks/package-info.java ./java/src/hdf/hdf5lib/exceptions/HDF5AttributeException.java ./java/src/hdf/hdf5lib/exceptions/HDF5BtreeException.java @@ -3362,6 +3372,7 @@ ./java/src/hdf/hdf5lib/exceptions/HDF5ReferenceException.java ./java/src/hdf/hdf5lib/exceptions/HDF5ResourceUnavailableException.java ./java/src/hdf/hdf5lib/exceptions/HDF5SymbolTableException.java +./java/src/hdf/hdf5lib/exceptions/package-info.java ./java/src/hdf/hdf5lib/structs/H5_ih_info_t.java ./java/src/hdf/hdf5lib/structs/H5A_info_t.java @@ -3376,12 +3387,14 @@ ./java/src/hdf/hdf5lib/structs/H5O_info_t.java ./java/src/hdf/hdf5lib/structs/H5O_native_info_t.java ./java/src/hdf/hdf5lib/structs/H5O_token_t.java +./java/src/hdf/hdf5lib/structs/package-info.java ./java/src/hdf/hdf5lib/H5.java ./java/src/hdf/hdf5lib/HDF5Constants.java ./java/src/hdf/hdf5lib/HDF5GroupInfo.java ./java/src/hdf/hdf5lib/HDFArray.java ./java/src/hdf/hdf5lib/HDFNativeData.java +./java/src/hdf/hdf5lib/package-info.java ./java/examples/Makefile.am ./java/examples/CMakeLists.txt @@ -3632,7 +3645,6 @@ ./config/cmake/HDF5UseFortran.cmake ./config/cmake/javaTargets.cmake.in ./config/cmake/jrunTest.cmake -./config/cmake/jvolTest.cmake ./config/cmake/libh5cc.in ./config/cmake/libhdf5.settings.cmake.in ./config/cmake/mccacheinit.cmake @@ -3874,6 +3886,7 @@ ./tools/src/h5import/Makefile.in ./tools/src/h5jam/Makefile.in ./tools/src/h5ls/Makefile.in +./tools/src/h5perf/Makefile.in ./tools/src/h5repack/Makefile.in ./tools/src/h5stat/Makefile.in ./tools/src/misc/Makefile.in diff --git a/Makefile.am b/Makefile.am index 8518114..2a544f4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -88,9 +88,9 @@ else TOOLS_DIR= endif -SUBDIRS = src $(TESTSERIAL_DIR) $(TESTPARALLEL_DIR) bin utils $(TOOLS_DIR) . \ +SUBDIRS = src $(TESTSERIAL_DIR) $(TESTPARALLEL_DIR) bin $(TOOLS_DIR) utils . \ $(CXX_DIR) $(FORTRAN_DIR) $(JAVA_DIR) $(HDF5_HL_DIR) -DIST_SUBDIRS = src test testpar utils tools . c++ fortran hl examples java +DIST_SUBDIRS = src test testpar tools utils . c++ fortran hl examples java # Some files generated during configure that should be cleaned DISTCLEANFILES=config/stamp1 config/stamp2 diff --git a/README.txt b/README.txt index fb027aa..b9cfe8a 100644 --- a/README.txt +++ b/README.txt @@ -1,4 +1,4 @@ -HDF5 version 1.13.0 currently under development +HDF5 version 1.13.1-1 currently under development ------------------------------------------------------------------------------ Please refer to the release_docs/INSTALL file for installation instructions. diff --git a/bin/trace b/bin/trace index cc26f86..7afc3e7 100755 --- a/bin/trace +++ b/bin/trace @@ -53,6 +53,7 @@ $Source = ""; "H5D_scatter_func_t" => "DS", "H5FD_mpio_xfer_t" => "Dt", "H5D_vds_view_t" => "Dv", + "H5FD_class_value_t" => "DV", "H5D_chunk_iter_op_t" => "x", "herr_t" => "e", "H5E_auto1_t" => "Ea", @@ -497,7 +498,7 @@ for $file (@ARGV) { $file_args = 0; # Ignore some files that do not need tracing macros - unless ($file eq "H5FDmulti.c" or $file eq "src/H5FDmulti.c" or $file eq "H5FDstdio.c" or $file eq "src/H5FDstdio.c" or $file eq "src/H5TS.c") { + unless ($file eq "H5FDmulti.c" or $file eq "src/H5FDmulti.c" or $file eq "H5FDstdio.c" or $file eq "src/H5FDstdio.c" or $file eq "src/H5TS.c" or $file eq "src/H5FDperform.c") { # Snarf up the entire file open SOURCE, $file or die "$file: $!\n"; diff --git a/c++/src/H5PredType.cpp b/c++/src/H5PredType.cpp index 72d560d..c407c33 100644 --- a/c++/src/H5PredType.cpp +++ b/c++/src/H5PredType.cpp @@ -406,31 +406,29 @@ PredType::makePredTypes() MIPS_F32_ = new PredType(H5T_MIPS_F32); MIPS_F64_ = new PredType(H5T_MIPS_F64); - NATIVE_CHAR_ = new PredType(H5T_NATIVE_CHAR); - NATIVE_INT_ = new PredType(H5T_NATIVE_INT); - NATIVE_FLOAT_ = new PredType(H5T_NATIVE_FLOAT); - NATIVE_SCHAR_ = new PredType(H5T_NATIVE_SCHAR); - NATIVE_UCHAR_ = new PredType(H5T_NATIVE_UCHAR); - NATIVE_SHORT_ = new PredType(H5T_NATIVE_SHORT); - NATIVE_USHORT_ = new PredType(H5T_NATIVE_USHORT); - NATIVE_UINT_ = new PredType(H5T_NATIVE_UINT); - NATIVE_LONG_ = new PredType(H5T_NATIVE_LONG); - NATIVE_ULONG_ = new PredType(H5T_NATIVE_ULONG); - NATIVE_LLONG_ = new PredType(H5T_NATIVE_LLONG); - NATIVE_ULLONG_ = new PredType(H5T_NATIVE_ULLONG); - NATIVE_DOUBLE_ = new PredType(H5T_NATIVE_DOUBLE); -#if H5_SIZEOF_LONG_DOUBLE != 0 + NATIVE_CHAR_ = new PredType(H5T_NATIVE_CHAR); + NATIVE_INT_ = new PredType(H5T_NATIVE_INT); + NATIVE_FLOAT_ = new PredType(H5T_NATIVE_FLOAT); + NATIVE_SCHAR_ = new PredType(H5T_NATIVE_SCHAR); + NATIVE_UCHAR_ = new PredType(H5T_NATIVE_UCHAR); + NATIVE_SHORT_ = new PredType(H5T_NATIVE_SHORT); + NATIVE_USHORT_ = new PredType(H5T_NATIVE_USHORT); + NATIVE_UINT_ = new PredType(H5T_NATIVE_UINT); + NATIVE_LONG_ = new PredType(H5T_NATIVE_LONG); + NATIVE_ULONG_ = new PredType(H5T_NATIVE_ULONG); + NATIVE_LLONG_ = new PredType(H5T_NATIVE_LLONG); + NATIVE_ULLONG_ = new PredType(H5T_NATIVE_ULLONG); + NATIVE_DOUBLE_ = new PredType(H5T_NATIVE_DOUBLE); NATIVE_LDOUBLE_ = new PredType(H5T_NATIVE_LDOUBLE); -#endif - NATIVE_B8_ = new PredType(H5T_NATIVE_B8); - NATIVE_B16_ = new PredType(H5T_NATIVE_B16); - NATIVE_B32_ = new PredType(H5T_NATIVE_B32); - NATIVE_B64_ = new PredType(H5T_NATIVE_B64); - NATIVE_OPAQUE_ = new PredType(H5T_NATIVE_OPAQUE); - NATIVE_HSIZE_ = new PredType(H5T_NATIVE_HSIZE); - NATIVE_HSSIZE_ = new PredType(H5T_NATIVE_HSSIZE); - NATIVE_HERR_ = new PredType(H5T_NATIVE_HERR); - NATIVE_HBOOL_ = new PredType(H5T_NATIVE_HBOOL); + NATIVE_B8_ = new PredType(H5T_NATIVE_B8); + NATIVE_B16_ = new PredType(H5T_NATIVE_B16); + NATIVE_B32_ = new PredType(H5T_NATIVE_B32); + NATIVE_B64_ = new PredType(H5T_NATIVE_B64); + NATIVE_OPAQUE_ = new PredType(H5T_NATIVE_OPAQUE); + NATIVE_HSIZE_ = new PredType(H5T_NATIVE_HSIZE); + NATIVE_HSSIZE_ = new PredType(H5T_NATIVE_HSSIZE); + NATIVE_HERR_ = new PredType(H5T_NATIVE_HERR); + NATIVE_HBOOL_ = new PredType(H5T_NATIVE_HBOOL); NATIVE_INT8_ = new PredType(H5T_NATIVE_INT8); NATIVE_UINT8_ = new PredType(H5T_NATIVE_UINT8); diff --git a/c++/src/cpp_doc_config b/c++/src/cpp_doc_config index 71db7f6..3eb7645 100644 --- a/c++/src/cpp_doc_config +++ b/c++/src/cpp_doc_config @@ -38,7 +38,7 @@ PROJECT_NAME = # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = "1.13.0" +PROJECT_NUMBER = "1.13.1-1, currently under development" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/config/clang-cxxflags b/config/clang-cxxflags index c585ce7..76f095f 100644 --- a/config/clang-cxxflags +++ b/config/clang-cxxflags @@ -20,15 +20,15 @@ # # For now, do not promote any warnings to errors. # -PROMOTE_ERRORS_DFLT=no +WARNINGS_AS_ERRORS_DFLT=no # # This filter rewrites -Werror= as -W, in that way demoting warnings -# promoted to errors back to warnings, if PROMOTE_ERRORS is no. +# promoted to errors back to warnings, if WARNINGS_AS_ERRORS is no. # demote_errors() { - if [ ${PROMOTE_ERRORS:-${PROMOTE_ERRORS_DFLT}} = no ]; then + if [ ${WARNINGS_AS_ERRORS:-${WARNINGS_AS_ERRORS_DFLT}} = no ]; then sed 's,-Werror=,-W,g' else cat @@ -44,7 +44,7 @@ demote_errors() load_clang_arguments() { set -- $(for arg; do - sed 's,#.*$,,' $srcdir/config/clang-warnings/${arg} + sed 's,#.*$,,' $srcdir/config/clang-warnings/${arg} | demote_errors done) IFS=' ' echo "$*" } @@ -161,7 +161,6 @@ if test "X-clang" = "X-$cxx_vendor" -o "X-Apple LLVM" = "X-$cxx_vendor"; then H5_CXXFLAGS="$H5_CXXFLAGS $(load_clang_arguments general)" H5_ECXXFLAGS="$H5_ECXXFLAGS $(load_clang_arguments error-general)" - H5_NECXXFLAGS="$H5_NECXXFLAGS $(load_clang_arguments noerror-general)" ###################### # Developer warnings # diff --git a/config/clang-flags b/config/clang-flags index 92a8973..5c377ed 100644 --- a/config/clang-flags +++ b/config/clang-flags @@ -20,15 +20,15 @@ # # For now, do not promote any warnings to errors. # -PROMOTE_ERRORS_DFLT=no +WARNINGS_AS_ERRORS_DFLT=no # # This filter rewrites -Werror= as -W, in that way demoting warnings -# promoted to errors back to warnings, if PROMOTE_ERRORS is no. +# promoted to errors back to warnings, if WARNINGS_AS_ERRORS is no. # demote_errors() { - if [ ${PROMOTE_ERRORS:-${PROMOTE_ERRORS_DFLT}} = no ]; then + if [ ${WARNINGS_AS_ERRORS:-${WARNINGS_AS_ERRORS_DFLT}} = no ]; then sed 's,-Werror=,-W,g' else cat @@ -44,7 +44,7 @@ demote_errors() load_clang_arguments() { set -- $(for arg; do - sed 's,#.*$,,' $srcdir/config/clang-warnings/${arg} + sed 's,#.*$,,' $srcdir/config/clang-warnings/${arg} | demote_errors done) IFS=' ' echo "$*" } @@ -183,7 +183,6 @@ if test "X-clang" = "X-$cc_vendor" -o "X-Apple LLVM" = "X-$cc_vendor"; then H5_CFLAGS="$H5_CFLAGS $(load_clang_arguments general)" H5_ECFLAGS="$H5_ECFLAGS $(load_clang_arguments error-general)" - H5_NECFLAGS="$H5_NECFLAGS $(load_clang_arguments noerror-general)" ###################### # Developer warnings # diff --git a/config/clang-warnings/noerror-general b/config/clang-warnings/noerror-general deleted file mode 100644 index 4690ebd..0000000 --- a/config/clang-warnings/noerror-general +++ /dev/null @@ -1,82 +0,0 @@ -# -# These warnings will be treated as errors, using the error-general file, -# when HDF5_ENABLE_WARNINGS_AS_ERRORS is set to true for CMake or -# the --enable-warnings-as-errors option is specified for configure. -# Otherwise this file will be used to treat them as warnings. -# --Wbad-function-cast --Wimplicit-function-declaration --Wincompatible-pointer-types --Wmissing-declarations --Wpacked --Wshadow --Wswitch -# -# NOTE: Following files are not compatible with incompatible-pointer-types as errors -# src/H5Dchunk.c,src/H5Dint.c,src/H5Gint.c,src/H5HFcache.c,src/H5I.c,src/H5T.c --Wno-error=incompatible-pointer-types-discards-qualifiers -# -# -# NOTE: File Driver files are not compatible with these warnings as errors -# H5FDdirect.c,H5FDmpio.c,H5FDros3.c, -# -Werror=unused-function -# --Wunused-function -# -# H5FDdrvr_module.h -# -Werror=unused-variable -# --Wunused-variable -# -# H5VLpassthru.c -# -Werror=unused-parameter -# --Wunused-parameter -# -# -# -# NOTE: Tools files are not compatible with these warnings as errors -# lib/h5tools.c -# -Werror=cast-align -# --Wcast-align -# -# lib/h5tools_utils.c -# -Werror=unused-parameter -# -# -# NOTE: JNI files are not compatible with these warnings as errors -# jni/h5pDCPLImp.c,jni/nativeData.c,jni/h5util.c,jni/h5rImp.c -# jni/h5sImp.c,jni/h5tImp.c -# -Werror=cast-align -# jni/h5util.c -# -Werror=format(-overflow) -# --Wformat -# -# -#Examples and tests do not use the same set of extensive warning flags as libraries -# Here is a list of tests and examples that have issues with the stricter warnings as error -# -# NOTE: Test files are not compatible with these warnings as errors -# thread_id.c, -# -Werror=unused-function -# dsets.c -# -Werror=unused-parameter -# -# -# NOTE: Examples files are not compatible with these warnings as errors -# h5_vds-eiger.c,h5_vds-exclim.c,h5_vds.c,h5_vds-exc.c,h5_vds-percival-unlim-maxmin.c -# h5_vds-percival.c,h5_read.c,h5_rdwt.c,h5_mount.c,h5_extend.c,h5_extend_write.c -# h5_write.c,h5_vds-simpleIO.c,h5_ref2reg_deprec.c,h5_crtgrp.c,h5_select.c -# h5_vds-percival-unlim.c,h5_crtatt.c,h5_group.c,h5_attribute.c,h5_crtdat.c -# h5_reference_deprec.c -# h5_rdwt.c,h5_crtgrp.c,h5_crtatt.c,h5_crtdat.c -# -Werror=strict-prototypes -# h5_rdwt.c,h5_crtgrp.c,h5_crtatt.c,h5_crtdat.c -# -Werror=old-style-definition -# h5_vds-exclim.c,h5_vds.c,h5_vds-exc.c, -# -Werror=unused-variable -# h5_elink_unix2win.c,h5_extlink.c,h5_attribute.c -# -Werror=unused-parameter - diff --git a/config/cmake/ConfigureChecks.cmake b/config/cmake/ConfigureChecks.cmake index 263cedf..483e551 100644 --- a/config/cmake/ConfigureChecks.cmake +++ b/config/cmake/ConfigureChecks.cmake @@ -195,7 +195,7 @@ endif () # Header-check flags set in config/cmake_ext_mod/ConfigureChecks.cmake # ---------------------------------------------------------------------- option (HDF5_ENABLE_MIRROR_VFD "Build the Mirror Virtual File Driver" OFF) -if (H5FD_ENABLE_MIRROR_VFD) +if (HDF5_ENABLE_MIRROR_VFD) if ( ${HDF_PREFIX}_HAVE_NETINET_IN_H AND ${HDF_PREFIX}_HAVE_NETDB_H AND ${HDF_PREFIX}_HAVE_ARPA_INET_H AND @@ -232,7 +232,7 @@ endif () # so this one is used. #----------------------------------------------------------------------------- set (RUN_OUTPUT_PATH_DEFAULT ${CMAKE_BINARY_DIR}) -macro (C_RUN FUNCTION_NAME SOURCE_CODE RETURN_VAR) +macro (C_RUN FUNCTION_NAME SOURCE_CODE RETURN_VAR RETURN_OUTPUT_VAR) if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") message (VERBOSE "Detecting C ${FUNCTION_NAME}") endif () @@ -248,7 +248,7 @@ macro (C_RUN FUNCTION_NAME SOURCE_CODE RETURN_VAR) RUN_OUTPUT_VARIABLE OUTPUT_VAR ) - set (${RETURN_VAR} ${OUTPUT_VAR}) + set (${RETURN_OUTPUT_VAR} ${OUTPUT_VAR}) if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") message (VERBOSE "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ") @@ -304,12 +304,11 @@ set (PROG_SRC #define C_LDBL_DIG DECIMAL_DIG\n\ #else\n\ #define C_LDBL_DIG LDBL_DIG\n\ -#endif\n\nint main() {\nFILE *pFile = fopen(\"pac_Cconftest.out\",\"w\")\\\;\nfprintf(pFile, \"\\%d\\\;\\%d\\\;\", C_LDBL_DIG, C_FLT128_DIG)\\\;\n\nreturn 0\\\;\n}\n +#endif\n\nint main() {\nprintf(\"\\%d\\\;\\%d\\\;\", C_LDBL_DIG, C_FLT128_DIG)\\\;\n\nreturn 0\\\;\n}\n " ) -C_RUN ("maximum decimal precision for C" ${PROG_SRC} PROG_RES) -file (READ "${RUN_OUTPUT_PATH_DEFAULT}/pac_Cconftest.out" PROG_OUTPUT4) +C_RUN ("maximum decimal precision for C" ${PROG_SRC} PROG_RES PROG_OUTPUT4) message (STATUS "Testing maximum decimal precision for C - ${PROG_OUTPUT4}") # dnl The output from the above program will be: diff --git a/config/cmake/FindCIRCLE.cmake b/config/cmake/FindCIRCLE.cmake new file mode 100644 index 0000000..b36d76c --- /dev/null +++ b/config/cmake/FindCIRCLE.cmake @@ -0,0 +1,49 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindCIRCLE +-------- + +Find the native CIRCLE includes and library + +This module defines + +:: + + CIRCLE_INCLUDE_DIR, where to find CIRCLE.h, etc. + CIRCLE_LIBRARIES, the libraries required to use CIRCLE. + CIRCLE_FOUND, If false, do not try to use CIRCLE. + +also defined, but not for general use are + +:: + + CIRCLE_LIBRARY, where to find the CIRCLE library. +#]=======================================================================] + +if(DEFINED ENV{MFU_ROOT}) + set(ENV{MFU_INCLUDE} "$ENV{MFU_ROOT}/include") + set(ENV{MFU_LIB} "$ENV{MFU_ROOT}/lib") + set(ENV{MFU_LIB64} "$ENV{MFU_ROOT}/lib64") +else() + message("CIRCLE_LIBRARY: If you have problems building this library,\nconsider setting the MFU_ROOT environment variable to indicate\nwhere to find the support libraries and header files!") +endif() + +find_path(CIRCLE_INCLUDE_DIR + NAMES libcircle.h + HINTS ENV MFU_INCLUDE) + +find_library(CIRCLE_LIBRARY + NAMES circle + HINTS ENV MFU_LIB ENV MFU_LIB64 + ) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(CIRCLE REQUIRED_VARS CIRCLE_LIBRARY CIRCLE_INCLUDE_DIR) + +if(CIRCLE_FOUND) + set(CIRCLE_LIBRARIES ${CIRCLE_LIBRARY} ) +endif() + +mark_as_advanced(CIRCLE_INCLUDE_DIR CIRCLE_LIBRARY) diff --git a/config/cmake/FindDTCMP.cmake b/config/cmake/FindDTCMP.cmake new file mode 100644 index 0000000..b95ef20 --- /dev/null +++ b/config/cmake/FindDTCMP.cmake @@ -0,0 +1,48 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindDTCMP +-------- + +Find the native DTCMP includes and library + +This module defines + +:: + + DTCMP_INCLUDE_DIR, where to find DTCMP.h, etc. + DTCMP_LIBRARIES, the libraries required to use DTCMP. + DTCMP_FOUND, If false, do not try to use DTCMP. + +also defined, but not for general use are + +:: + + DTCMP_LIBRARY, where to find the DTCMP library. +#]=======================================================================] + +if(DEFINED ENV{MFU_ROOT}) + set(ENV{MFU_INCLUDE} "$ENV{MFU_ROOT}/include") + set(ENV{MFU_LIB} "$ENV{MFU_ROOT}/lib") + set(ENV{MFU_LIB64} "$ENV{MFU_ROOT}/lib64") +else() + message("DTCMP_LIBRARY: If you have problems building this library,\nconsider setting the MFU_ROOT environment variable to indicate\nwhere to find the support libraries and header files!") +endif() + +find_path(DTCMP_INCLUDE_DIR + NAMES dtcmp.h + HINTS ENV MFU_INCLUDE) + +find_library(DTCMP_LIBRARY + NAMES dtcmp + HINTS ENV MFU_LIB ENV MFU_LIB64) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(DTCMP REQUIRED_VARS DTCMP_LIBRARY DTCMP_INCLUDE_DIR) + +if(DTCMP_FOUND) + set(DTCMP_LIBRARIES ${DTCMP_LIBRARY} ) +endif() + +mark_as_advanced(DTCMP_INCLUDE_DIR DTCMP_LIBRARY) diff --git a/config/cmake/FindMFU.cmake b/config/cmake/FindMFU.cmake new file mode 100644 index 0000000..37699e2 --- /dev/null +++ b/config/cmake/FindMFU.cmake @@ -0,0 +1,100 @@ +# +# 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. +# +######################################################################### + +# - Derived from the FindTiff.cmake and FindJPEG.cmake that is included with cmake +# FindMFU + +# Find the native MFU includes and library + +# Imported targets +################## + +# This module defines the following :prop_tgt:`IMPORTED` targets: +# +# MFU::MFU +# The MFU library, if found. +# +# Result variables +################### + +# This module will set the following variables in your project: + +# MFU_FOUND, true if the MFU headers and libraries were found. +# MFU_INCLUDE_DIR, the directory containing the MFU headers. +# MFU_INCLUDE_DIRS, the directory containing the MFU headers. +# MFU_LIBRARIES, libraries to link against to use MFU. + +# Cache variables +################# + +# The following variables may also be set: + +# MFU_LIBRARY, where to find the MFU library. +# message (STATUS "Finding MFU library and headers..." ) +######################################################################### + + + +FIND_PATH(MFU_INCLUDE_DIR + NAMES mfu.h + HINTS "$ENV{MFU_ROOT}/include" +) +FIND_LIBRARY(MFU_LIBRARY + NAMES mfu + HINTS "$ENV{MFU_ROOT}/lib64" +) + +if(NOT MFU_LIBRARY) + set(mfu_names ${MFU_NAMES} mfu libmfu) + find_library(MFU_LIBRARY NAMES ${mfu_names}) + include(SelectLibraryConfigurations) + select_library_configurations(MFU) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(MFU + REQUIRED_VARS MFU_LIBRARY MFU_INCLUDE_DIR) + +if(MFU_FOUND) + set(MFU_LIBRARIES "${MFU_LIBRARY}") + set(MFU_INCLUDE_DIRS "${MFU_INCLUDE_DIR}") + set(LL_PATH "$ENV{MFU_ROOT}/lib64:$ENV{MFU_ROOT}/lib") + if(NOT TARGET MFU::MFU) + add_library(MFU::MFU UNKNOWN IMPORTED) + if(MFU_INCLUDE_DIRS) + set_target_properties(MFU::MFU PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${MFU_INCLUDE_DIRS}") + endif() + if(EXISTS "${MFU_LIBRARY}") + set_target_properties(MFU::MFU PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${MFU_LIBRARY}") + endif() + endif() +endif() + +# Report the results. +if (NOT MFU_FOUND) + set (MFU_DIR_MESSAGE + "Mfu was not found. Make sure MFU_LIBRARY and MFU_INCLUDE_DIR are set or set the MFU_INSTALL environment variable." + ) + if (NOT MFU_FIND_QUIETLY) + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") + message (VERBOSE "${MFU_DIR_MESSAGE}") + endif () + else () + if (MFU_FIND_REQUIRED) + message (FATAL_ERROR "Mfu was NOT found and is Required by this project") + endif () + endif () +endif () diff --git a/config/cmake/H5pubconf.h.in b/config/cmake/H5pubconf.h.in index 8fd1331..ae5a8c6 100644 --- a/config/cmake/H5pubconf.h.in +++ b/config/cmake/H5pubconf.h.in @@ -71,13 +71,13 @@ /* Define Fortran compiler ID */ #define H5_Fortran_COMPILER_ID @CMAKE_Fortran_COMPILER_ID@ +/* Define number of valid Fortran INTEGER KINDs (must be defined before F_IKIND)*/ +#cmakedefine H5_H5CONFIG_F_NUM_IKIND @H5_H5CONFIG_F_NUM_IKIND@ + /* Define valid Fortran INTEGER KINDs */ #cmakedefine H5_H5CONFIG_F_IKIND @H5_H5CONFIG_F_IKIND@ -/* Define number of valid Fortran INTEGER KINDs */ -#cmakedefine H5_H5CONFIG_F_NUM_IKIND @H5_H5CONFIG_F_NUM_IKIND@ - -/* Define number of valid Fortran REAL KINDs */ +/* Define number of valid Fortran REAL KINDs (must be defined before F_RKIND) */ #cmakedefine H5_H5CONFIG_F_NUM_RKIND @H5_H5CONFIG_F_NUM_RKIND@ /* Define valid Fortran REAL KINDs */ @@ -412,6 +412,9 @@ /* Define if the high-level library headers should be included in hdf5.h */ #cmakedefine H5_INCLUDE_HL @H5_INCLUDE_HL@ +/* Define if new-style references should be used with dimension scales */ +#cmakedefine H5_DIMENSION_SCALES_WITH_NEW_REF @H5_DIMENSION_SCALES_WITH_NEW_REF@ + /* Define if your system can convert long double to (unsigned) long long values correctly. */ #cmakedefine H5_LDOUBLE_TO_LLONG_ACCURATE @H5_LDOUBLE_TO_LLONG_ACCURATE@ diff --git a/config/cmake/HDF5UseFortran.cmake b/config/cmake/HDF5UseFortran.cmake index e192ec4..0d05e20 100644 --- a/config/cmake/HDF5UseFortran.cmake +++ b/config/cmake/HDF5UseFortran.cmake @@ -32,15 +32,10 @@ macro (READ_SOURCE SOURCE_START SOURCE_END RETURN_VAR) endmacro () set (RUN_OUTPUT_PATH_DEFAULT ${CMAKE_BINARY_DIR}) -if (NOT CMAKE_VERSION VERSION_LESS "3.14.0") - if (HDF5_REQUIRED_LIBRARIES) - set (CMAKE_REQUIRED_LIBRARIES "${HDF5_REQUIRED_LIBRARIES}") - endif () -else () # The provided CMake Fortran macros don't provide a general compile/run function # so this one is used. #----------------------------------------------------------------------------- -macro (FORTRAN_RUN FUNCTION_NAME SOURCE_CODE RUN_RESULT_VAR1 COMPILE_RESULT_VAR1 RETURN_VAR) +macro (FORTRAN_RUN FUNCTION_NAME SOURCE_CODE RUN_RESULT_VAR1 COMPILE_RESULT_VAR1 RETURN_VAR RETURN_OUTPUT_VAR) if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") message (VERBOSE "Detecting Fortran ${FUNCTION_NAME}") endif () @@ -52,7 +47,9 @@ macro (FORTRAN_RUN FUNCTION_NAME SOURCE_CODE RUN_RESULT_VAR1 COMPILE_RESULT_VAR1 ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompiler1.f90 LINK_LIBRARIES "${HDF5_REQUIRED_LIBRARIES}" + RUN_OUTPUT_VARIABLE OUTPUT_VAR ) + set (${RETURN_OUTPUT_VAR} ${OUTPUT_VAR}) if (${COMPILE_RESULT_VAR}) set(${RETURN_VAR} ${RUN_RESULT_VAR}) @@ -81,7 +78,6 @@ macro (FORTRAN_RUN FUNCTION_NAME SOURCE_CODE RUN_RESULT_VAR1 COMPILE_RESULT_VAR1 set(${RETURN_VAR} ${COMPILE_RESULT_VAR}) endif () endmacro () -endif () #----------------------------------------------------------------------------- # Check to see C_LONG_DOUBLE is available @@ -130,27 +126,22 @@ endif () #----------------------------------------------------------------------------- READ_SOURCE ("PROGRAM FC_AVAIL_KINDS" "END PROGRAM FC_AVAIL_KINDS" SOURCE_CODE) -if (NOT CMAKE_VERSION VERSION_LESS "3.14.0") - check_fortran_source_runs (${SOURCE_CODE} FC_AVAIL_KINDS_RESULT SRC_EXT f90) -else () FORTRAN_RUN ("REAL and INTEGER KINDs" "${SOURCE_CODE}" XX YY FC_AVAIL_KINDS_RESULT + PROG_OUTPUT ) -endif () - # dnl The output from the above program will be: # dnl -- LINE 1 -- valid integer kinds (comma seperated list) # dnl -- LINE 2 -- valid real kinds (comma seperated list) # dnl -- LINE 3 -- max decimal precision for reals # dnl -- LINE 4 -- number of valid integer kinds # dnl -- LINE 5 -- number of valid real kinds - -file (READ "${RUN_OUTPUT_PATH_DEFAULT}/pac_fconftest.out" PROG_OUTPUT) +# # Convert the string to a list of strings by replacing the carriage return with a semicolon -string (REGEX REPLACE "\n" ";" PROG_OUTPUT "${PROG_OUTPUT}") +string (REGEX REPLACE "[\r\n]+" ";" PROG_OUTPUT "${PROG_OUTPUT}") list (GET PROG_OUTPUT 0 pac_validIntKinds) list (GET PROG_OUTPUT 1 pac_validRealKinds) @@ -196,21 +187,15 @@ foreach (KIND ${VAR}) " PROGRAM main USE ISO_C_BINDING + USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : stderr=>ERROR_UNIT IMPLICIT NONE INTEGER (KIND=${KIND}) a - OPEN(8,FILE='pac_validIntKinds.${KIND}.out',FORM='formatted') - WRITE(8,'(I0)') ${FC_SIZEOF_A} - CLOSE(8) + WRITE(stderr,'(I0)') ${FC_SIZEOF_A} END " ) - if (NOT CMAKE_VERSION VERSION_LESS "3.14.0") - check_fortran_source_runs (${PROG_SRC_${KIND}} VALIDINTKINDS_RESULT_${KIND} SRC_EXT f90) - else () - FORTRAN_RUN("INTEGER KIND SIZEOF" ${PROG_SRC_${KIND}} XX YY VALIDINTKINDS_RESULT_${KIND}) - endif () - file (READ "${RUN_OUTPUT_PATH_DEFAULT}/pac_validIntKinds.${KIND}.out" PROG_OUTPUT1) - string (REGEX REPLACE "\n" "" PROG_OUTPUT1 "${PROG_OUTPUT1}") + FORTRAN_RUN("INTEGER KIND SIZEOF" ${PROG_SRC_${KIND}} XX YY VALIDINTKINDS_RESULT_${KIND} PROG_OUTPUT1) + string (REGEX REPLACE "[\r\n]+" "" PROG_OUTPUT1 "${PROG_OUTPUT1}") set (pack_int_sizeof "${pack_int_sizeof} ${PROG_OUTPUT1},") endforeach () @@ -245,22 +230,16 @@ foreach (KIND ${VAR} ) " PROGRAM main USE ISO_C_BINDING + USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : stderr=>ERROR_UNIT IMPLICIT NONE REAL (KIND=${KIND}) a - OPEN(8,FILE='pac_validRealKinds.${KIND}.out',FORM='formatted') - WRITE(8,'(I0)') ${FC_SIZEOF_A} - CLOSE(8) + WRITE(stderr,'(I0)') ${FC_SIZEOF_A} END " ) - if (NOT CMAKE_VERSION VERSION_LESS "3.14.0") - check_fortran_source_runs (${PROG_SRC2_${KIND}} VALIDREALKINDS_RESULT_${KIND} SRC_EXT f90) - else () - FORTRAN_RUN ("REAL KIND SIZEOF" ${PROG_SRC2_${KIND}} XX YY VALIDREALKINDS_RESULT_${KIND}) - endif () - file (READ "${RUN_OUTPUT_PATH_DEFAULT}/pac_validRealKinds.${KIND}.out" PROG_OUTPUT1) - string (REGEX REPLACE "\n" "" PROG_OUTPUT1 "${PROG_OUTPUT1}") - set (pack_real_sizeof "${pack_real_sizeof} ${PROG_OUTPUT1},") + FORTRAN_RUN ("REAL KIND SIZEOF" ${PROG_SRC2_${KIND}} XX YY VALIDREALKINDS_RESULT_${KIND} PROG_OUTPUT2) + string (REGEX REPLACE "[\r\n]+" "" PROG_OUTPUT2 "${PROG_OUTPUT2}") + set (pack_real_sizeof "${pack_real_sizeof} ${PROG_OUTPUT2},") endforeach () if (pack_real_sizeof STREQUAL "") @@ -293,27 +272,21 @@ set (PROG_SRC3 " PROGRAM main USE ISO_C_BINDING + USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : stderr=>ERROR_UNIT IMPLICIT NONE INTEGER a REAL b DOUBLE PRECISION c - OPEN(8,FILE='pac_sizeof_native_kinds.out',FORM='formatted') - WRITE(8,*) ${FC_SIZEOF_A} - WRITE(8,*) kind(a) - WRITE(8,*) ${FC_SIZEOF_B} - WRITE(8,*) kind(b) - WRITE(8,*) ${FC_SIZEOF_C} - WRITE(8,*) kind(c) - CLOSE(8) + WRITE(stderr,*) ${FC_SIZEOF_A} + WRITE(stderr,*) kind(a) + WRITE(stderr,*) ${FC_SIZEOF_B} + WRITE(stderr,*) kind(b) + WRITE(stderr,*) ${FC_SIZEOF_C} + WRITE(stderr,*) kind(c) END " ) -if (NOT CMAKE_VERSION VERSION_LESS "3.14.0") - check_fortran_source_runs (${PROG_SRC3} PAC_SIZEOF_NATIVE_KINDS_RESULT SRC_EXT f90) -else () - FORTRAN_RUN ("SIZEOF NATIVE KINDs" ${PROG_SRC3} XX YY PAC_SIZEOF_NATIVE_KINDS_RESULT) -endif () -file (READ "${RUN_OUTPUT_PATH_DEFAULT}/pac_sizeof_native_kinds.out" PROG_OUTPUT3) +FORTRAN_RUN ("SIZEOF NATIVE KINDs" ${PROG_SRC3} XX YY PAC_SIZEOF_NATIVE_KINDS_RESULT PROG_OUTPUT3) # dnl The output from the above program will be: # dnl -- LINE 1 -- sizeof INTEGER # dnl -- LINE 2 -- kind of INTEGER @@ -321,9 +294,9 @@ file (READ "${RUN_OUTPUT_PATH_DEFAULT}/pac_sizeof_native_kinds.out" PROG_OUTPUT3 # dnl -- LINE 4 -- kind of REAL # dnl -- LINE 5 -- sizeof DOUBLE PRECISION # dnl -- LINE 6 -- kind of DOUBLE PRECISION - +# # Convert the string to a list of strings by replacing the carriage return with a semicolon -string (REGEX REPLACE "\n" ";" PROG_OUTPUT3 "${PROG_OUTPUT3}") +string (REGEX REPLACE "[\r\n]+" ";" PROG_OUTPUT3 "${PROG_OUTPUT3}") list (GET PROG_OUTPUT3 0 PAC_FORTRAN_NATIVE_INTEGER_SIZEOF) list (GET PROG_OUTPUT3 1 PAC_FORTRAN_NATIVE_INTEGER_KIND) diff --git a/config/cmake/HDF5_Examples.cmake.in b/config/cmake/HDF5_Examples.cmake.in index 2d8dc58..db638fd 100644 --- a/config/cmake/HDF5_Examples.cmake.in +++ b/config/cmake/HDF5_Examples.cmake.in @@ -83,7 +83,7 @@ set(ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DSITE:STRING=${CTEST_SITE} -DBUILDN ############################################################################################################### if(WIN32) set(SITE_OS_NAME "Windows") - set(ENV{HDF5_DIR} "${INSTALLDIR}/cmake") + set(ENV{HDF5_DIR} "${INSTALLDIR}/share/cmake") set(CTEST_BINARY_NAME ${CTEST_SOURCE_NAME}\\build) set(CTEST_SOURCE_DIRECTORY "${CTEST_DASHBOARD_ROOT}\\${CTEST_SOURCE_NAME}") set(CTEST_BINARY_DIRECTORY "${CTEST_DASHBOARD_ROOT}\\${CTEST_BINARY_NAME}") @@ -94,6 +94,8 @@ else() set(CTEST_SOURCE_DIRECTORY "${CTEST_DASHBOARD_ROOT}/${CTEST_SOURCE_NAME}") set(CTEST_BINARY_DIRECTORY "${CTEST_DASHBOARD_ROOT}/${CTEST_BINARY_NAME}") endif() +### default HDF5_PLUGIN_PATH to where the filter libraries are located +set(ENV{HDF5_PLUGIN_PATH} "${INSTALLDIR}/lib/plugin") if(${CDASH_LOCAL}) set(ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DCDASH_LOCAL:BOOL=ON") endif() diff --git a/config/cmake/HDFCXXCompilerFlags.cmake b/config/cmake/HDFCXXCompilerFlags.cmake index a121d0a..a5af43c 100644 --- a/config/cmake/HDFCXXCompilerFlags.cmake +++ b/config/cmake/HDFCXXCompilerFlags.cmake @@ -27,15 +27,14 @@ if (WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL "Intel") set (_INTEL_WINDOWS 1) endif () -if (WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang" - AND "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") +if (WIN32 AND CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang" AND "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") set (_CLANG_MSVC_WINDOWS 1) endif() # MSVC 14.28 enables C5105, but the Windows SDK 10.0.18362.0 triggers it. -if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND CMAKE_CXX_COMPILER_LOADED) +if ((_CLANG_MSVC_WINDOWS OR CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") AND CMAKE_CXX_COMPILER_LOADED) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc") - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.28) + if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.28) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -wd5105") endif () endif () @@ -134,13 +133,9 @@ else () AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) # add the general CXX flags for g++ compiler versions 4.8 and above. ADD_H5_FLAGS (HDF5_CMAKE_CXX_FLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-general") - if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-error-general") - else () - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-noerror-general") - endif () + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-error-general") endif () - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + elseif (CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") ADD_H5_FLAGS (HDF5_CMAKE_CXX_FLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/general") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "PGI") list (APPEND HDF5_CMAKE_CXX_FLAGS "-Minform=inform") @@ -161,14 +156,14 @@ if (HDF5_ENABLE_DEV_WARNINGS) elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") # Use the C warnings as CXX warnings are the same ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-general") - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + elseif (CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/developer-general") endif () else () if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") # Use the C warnings as CXX warnings are the same ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-general") - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + elseif (CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/no-developer-general") endif () endif () @@ -186,9 +181,9 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-4.8") if (HDF5_ENABLE_DEV_WARNINGS) # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-4.8") + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-developer-4.8") else () - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-4.8") + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-cxx-developer-4.8") endif () endif () @@ -202,11 +197,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) # autotools always add the C flags with the CXX flags ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-5") - if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-error-5") - else () - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-noerror-5") - endif () + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-error-5") endif () # Append more extra warning flags that only gcc 6.x+ knows about @@ -231,11 +222,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0) # Use the C warnings as CXX warnings are the same ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/8") - if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-8") - else () - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/noerror-8") - endif () + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-8") if (HDF5_ENABLE_DEV_WARNINGS) # Use the C warnings as CXX warnings are the same ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-8") diff --git a/config/cmake/HDFCompilerFlags.cmake b/config/cmake/HDFCompilerFlags.cmake index de5b563..eb43b73 100644 --- a/config/cmake/HDFCompilerFlags.cmake +++ b/config/cmake/HDFCompilerFlags.cmake @@ -24,8 +24,7 @@ if(WIN32 AND CMAKE_C_COMPILER_ID STREQUAL "Intel") set(_INTEL_WINDOWS 1) endif() -if(WIN32 AND CMAKE_C_COMPILER_ID STREQUAL "Clang" - AND "x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC") +if(WIN32 AND CMAKE_C_COMPILER_ID MATCHES "[Cc]lang" AND "x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC") set(_CLANG_MSVC_WINDOWS 1) endif() @@ -154,22 +153,14 @@ else () # Add general CFlags for GCC versions 4.8 and above if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) ADD_H5_FLAGS (HDF5_CMAKE_C_FLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/general") - if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-general") - else () - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/noerror-general") - endif () + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-general") endif () # gcc automatically inlines based on the optimization level # this is just a failsafe list (APPEND H5_CFLAGS "-finline-functions") elseif (CMAKE_C_COMPILER_ID MATCHES "[Cc]lang") ADD_H5_FLAGS (HDF5_CMAKE_C_FLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/general") - if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/error-general") - else () - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/noerror-general") - endif () + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/error-general") elseif (CMAKE_C_COMPILER_ID STREQUAL "PGI") list (APPEND HDF5_CMAKE_C_FLAGS "-Minform=inform") endif () @@ -229,11 +220,7 @@ if (CMAKE_C_COMPILER_ID STREQUAL "GNU") # Append more extra warning flags that only gcc 5.x+ knows about if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0) ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/5") - if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-5") - else () - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-5") - endif () + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-5") endif () # Append more extra warning flags that only gcc 6.x+ knows about @@ -254,9 +241,7 @@ if (CMAKE_C_COMPILER_ID STREQUAL "GNU") # Append more extra warning flags that only gcc 8.x+ knows about if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.0) ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/8") - if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-8") - endif () + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-8") if (HDF5_ENABLE_DEV_WARNINGS) ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-8") else () diff --git a/config/cmake/HDFFortranCompilerFlags.cmake b/config/cmake/HDFFortranCompilerFlags.cmake index 94c40aa..754259e 100644 --- a/config/cmake/HDFFortranCompilerFlags.cmake +++ b/config/cmake/HDFFortranCompilerFlags.cmake @@ -79,7 +79,6 @@ if (NOT MSVC AND NOT MINGW) endif () if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") - # Append more extra warning flags that only gcc 4.8+ knows about if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 4.8) ADD_H5_FLAGS (HDF5_CMAKE_Fortran_FLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/gfort-4.8") @@ -91,10 +90,11 @@ if (NOT MSVC AND NOT MINGW) #endif () # Append more extra warning flags that only gcc 5.x+ knows about - # do not include -Wuse-without-only - #if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 5.0) - # ADD_H5_FLAGS (HDF5_CMAKE_Fortran_FLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/gfort-5") - #endif () + if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 5.0) + if (HDF5_ENABLE_DEV_WARNINGS) + ADD_H5_FLAGS (HDF5_CMAKE_Fortran_FLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-gfort-5") + endif () + endif () # Append more extra warning flags that only gcc 6.x+ knows about if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 6.0) diff --git a/config/cmake/hdf5-config.cmake.in b/config/cmake/hdf5-config.cmake.in index 8faa2fe..eab09ba 100644 --- a/config/cmake/hdf5-config.cmake.in +++ b/config/cmake/hdf5-config.cmake.in @@ -113,12 +113,12 @@ set (${HDF5_PACKAGE_NAME}_VERSION_MINOR @HDF5_VERSION_MINOR@) #----------------------------------------------------------------------------- if (NOT TARGET "@HDF5_PACKAGE@") if (${HDF5_PACKAGE_NAME}_ENABLE_Z_LIB_SUPPORT AND ${HDF5_PACKAGE_NAME}_PACKAGE_EXTLIBS) - include (@PACKAGE_SHARE_INSTALL_DIR@/@ZLIB_PACKAGE_NAME@/@ZLIB_PACKAGE_NAME@@HDF_PACKAGE_EXT@-targets.cmake) + include (@PACKAGE_SHARE_INSTALL_DIR@/@ZLIB_PACKAGE_NAME@@HDF_PACKAGE_EXT@-targets.cmake) endif () if (${HDF5_PACKAGE_NAME}_ENABLE_SZIP_SUPPORT AND ${HDF5_PACKAGE_NAME}_PACKAGE_EXTLIBS) - include (@PACKAGE_SHARE_INSTALL_DIR@/@SZ_PACKAGE_NAME@/@SZ_PACKAGE_NAME@@HDF_PACKAGE_EXT@-targets.cmake) + include (@PACKAGE_SHARE_INSTALL_DIR@/@SZ_PACKAGE_NAME@@HDF_PACKAGE_EXT@-targets.cmake) endif () - include (@PACKAGE_SHARE_INSTALL_DIR@/@HDF5_PACKAGE@/@HDF5_PACKAGE@@HDF_PACKAGE_EXT@-targets.cmake) + include (@PACKAGE_SHARE_INSTALL_DIR@/@HDF5_PACKAGE@@HDF_PACKAGE_EXT@-targets.cmake) endif () # Handle default component(static) : diff --git a/config/cmake/jrunTest.cmake b/config/cmake/jrunTest.cmake index 2ca1b75..13e50dd 100644 --- a/config/cmake/jrunTest.cmake +++ b/config/cmake/jrunTest.cmake @@ -47,7 +47,12 @@ else () set (LOG_LEVEL "${TEST_LOG_LEVEL}") endif () -message (STATUS "COMMAND: ${TEST_TESTER} -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=${LOG_LEVEL} -Djava.library.path=\"${TEST_LIBRARY_DIRECTORY}\" -cp \"${TEST_CLASSPATH}\" ${TEST_ARGS} ${TEST_PROGRAM} ${ARGN}") +if (NOT TEST_VOL) + message (STATUS "COMMAND: ${TEST_TESTER} -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=${LOG_LEVEL} -Djava.library.path=\"${TEST_LIBRARY_DIRECTORY}\" -cp \"${TEST_CLASSPATH}\" ${TEST_ARGS} ${TEST_PROGRAM} ${ARGN}") +else () + message (STATUS "USING ${TEST_VOL} ON COMMAND: ${TEST_TESTER} -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=${LOG_LEVEL} -Djava.library.path=\"${TEST_LIBRARY_DIRECTORY}\" -cp \"${TEST_CLASSPATH}\" ${TEST_ARGS} ${TEST_PROGRAM} ${ARGN}") + set (ENV{HDF5_VOL_CONNECTOR} "${TEST_VOL}") +endif () if (WIN32) set (ENV{PATH} "$ENV{PATH}\\;${TEST_LIBRARY_DIRECTORY}") diff --git a/config/cmake/jvolTest.cmake b/config/cmake/jvolTest.cmake deleted file mode 100644 index b12c358..0000000 --- a/config/cmake/jvolTest.cmake +++ /dev/null @@ -1,301 +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. -# -# jrunTest.cmake executes a command and captures the output in a file. File is then compared -# against a reference file. Exit status of command can also be compared. -cmake_policy(SET CMP0007 NEW) - -# arguments checking -if (NOT TEST_TESTER) - message (FATAL_ERROR "Require TEST_TESTER to be defined") -endif () -if (NOT TEST_PROGRAM) - message (FATAL_ERROR "Require TEST_PROGRAM to be defined") -endif () -if (NOT TEST_LIBRARY_DIRECTORY) - message (STATUS "Require TEST_LIBRARY_DIRECTORY to be defined") -endif () -if (NOT TEST_FOLDER) - message (FATAL_ERROR "Require TEST_FOLDER to be defined") -endif () -if (NOT TEST_OUTPUT) - message (FATAL_ERROR "Require TEST_OUTPUT to be defined") -endif () -if (NOT TEST_CLASSPATH) - message (STATUS "Require TEST_CLASSPATH to be defined") -endif () -if (NOT TEST_VOL) - message (FATAL_ERROR "Require TEST_VOL to be defined") -endif () - -if (EXISTS "${TEST_FOLDER}/${TEST_OUTPUT}") - file (REMOVE ${TEST_FOLDER}/${TEST_OUTPUT}) -endif () - -if (EXISTS "${TEST_FOLDER}/${TEST_OUTPUT}.err") - file (REMOVE ${TEST_FOLDER}/${TEST_OUTPUT}.err) -endif () - -if (NOT TEST_LOG_LEVEL) - set (LOG_LEVEL "info") -else () - set (LOG_LEVEL "${TEST_LOG_LEVEL}") -endif () - -message (STATUS "USING ${TEST_VOL} ON COMMAND: ${TEST_TESTER} -Xmx1024M -Dorg.slf4j.simpleLogger.defaultLog=${LOG_LEVEL} -Djava.library.path=\"${TEST_LIBRARY_DIRECTORY}\" -cp \"${TEST_CLASSPATH}\" ${TEST_ARGS} ${TEST_PROGRAM} ${ARGN}") - -set (ENV{HDF5_VOL_CONNECTOR} "${TEST_VOL}") - -if (WIN32) - set (ENV{PATH} "$ENV{PATH}\\;${TEST_LIBRARY_DIRECTORY}") -else () - set (ENV{LD_LIBRARY_PATH} "$ENV{LD_LIBRARY_PATH}:${TEST_LIBRARY_DIRECTORY}") -endif () - -# run the test program, capture the stdout/stderr and the result var -execute_process ( - COMMAND ${TEST_TESTER} -Xmx1024M - -Dorg.slf4j.simpleLogger.defaultLogLevel=${LOG_LEVEL} - -Djava.library.path=${TEST_LIBRARY_DIRECTORY} - -cp "${TEST_CLASSPATH}" ${TEST_ARGS} ${TEST_PROGRAM} - ${ARGN} - WORKING_DIRECTORY ${TEST_FOLDER} - RESULT_VARIABLE TEST_RESULT - OUTPUT_FILE ${TEST_OUTPUT} - ERROR_FILE ${TEST_OUTPUT}.err - OUTPUT_VARIABLE TEST_OUT - ERROR_VARIABLE TEST_ERROR -) - -message (STATUS "COMMAND Result: ${TEST_RESULT}") - -# if the .err file exists and ERRROR_APPEND is enabled -if (EXISTS "${TEST_FOLDER}/${TEST_OUTPUT}.err") - file (READ ${TEST_FOLDER}/${TEST_OUTPUT}.err TEST_STREAM) - list(LENGTH TEST_STREAM test_len) - if (test_len GREATER 0) - if (TEST_MASK_FILE) - STRING(REGEX REPLACE "CurrentDir is [^\n]+\n" "CurrentDir is (dir name)\n" TEST_STREAM "${TEST_STREAM}") - endif () - - if (NOT ERROR_APPEND) - # write back to original .err file - file (WRITE ${TEST_FOLDER}/${TEST_OUTPUT}.err "${TEST_STREAM}") - else () - # append error output to the stdout output file - file (APPEND ${TEST_FOLDER}/${TEST_OUTPUT} "${TEST_STREAM}") - endif () - endif () -endif () - -# if the output file or the .err file needs to mask out error stack info -if (TEST_MASK_ERROR) - if (NOT TEST_ERRREF) - # the error stack has been appended to the output file - file (READ ${TEST_FOLDER}/${TEST_OUTPUT} TEST_STREAM) - else () - # the error stack remains in the .err file - file (READ ${TEST_FOLDER}/${TEST_OUTPUT}.err TEST_STREAM) - endif () - string (REGEX REPLACE "Time:[^\n]+\n" "Time: XXXX\n" TEST_STREAM "${TEST_STREAM}") - string (REGEX REPLACE "thread [0-9]*:" "thread (IDs):" TEST_STREAM "${TEST_STREAM}") - string (REGEX REPLACE ": ([^\n]*)[.]c " ": (file name) " TEST_STREAM "${TEST_STREAM}") - string (REGEX REPLACE " line [0-9]*" " line (number)" TEST_STREAM "${TEST_STREAM}") - #string (REGEX REPLACE "v[1-9]*[.][0-9]*[.]" "version (number)." TEST_STREAM "${TEST_STREAM}") - string (REGEX REPLACE "HDF5 .[1-9]*[.][0-9]*[.][0-9]*[^)]*" "HDF5 (version (number)" TEST_STREAM "${TEST_STREAM}") - string (REGEX REPLACE "H5Eget_auto[1-2]*" "H5Eget_auto(1 or 2)" TEST_STREAM "${TEST_STREAM}") - string (REGEX REPLACE "H5Eset_auto[1-2]*" "H5Eset_auto(1 or 2)" TEST_STREAM "${TEST_STREAM}") - # write back the changes to the original files - if (NOT TEST_ERRREF) - file (WRITE ${TEST_FOLDER}/${TEST_OUTPUT} "${TEST_STREAM}") - else () - file (WRITE ${TEST_FOLDER}/${TEST_OUTPUT}.err "${TEST_STREAM}") - endif () -endif () - -# if the return value is !=expected bail out -if (NOT TEST_RESULT EQUAL TEST_EXPECT) - message (STATUS "ERROR OUTPUT: ${TEST_STREAM}") - message (FATAL_ERROR "Failed: Test program ${TEST_PROGRAM} exited != 0.\n${TEST_ERROR}") -endif () - -message (STATUS "COMMAND Error: ${TEST_ERROR}") - -# compare output files to references unless this must be skipped -set (TEST_COMPARE_RESULT 0) -if (NOT TEST_SKIP_COMPARE) - if (EXISTS "${TEST_FOLDER}/${TEST_REFERENCE}") - file (READ ${TEST_FOLDER}/${TEST_REFERENCE} TEST_STREAM) - list(LENGTH TEST_STREAM test_len) - if (test_len GREATER 0) - if (WIN32) - configure_file(${TEST_FOLDER}/${TEST_REFERENCE} ${TEST_FOLDER}/${TEST_REFERENCE}.tmp NEWLINE_STYLE CRLF) - if (EXISTS "${TEST_FOLDER}/${TEST_REFERENCE}.tmp") - file(RENAME ${TEST_FOLDER}/${TEST_REFERENCE}.tmp ${TEST_FOLDER}/${TEST_REFERENCE}) - endif () - #file (READ ${TEST_FOLDER}/${TEST_REFERENCE} TEST_STREAM) - #file (WRITE ${TEST_FOLDER}/${TEST_REFERENCE} "${TEST_STREAM}") - endif () - - if (NOT TEST_SORT_COMPARE) - # now compare the output with the reference - execute_process ( - COMMAND ${CMAKE_COMMAND} -E compare_files ${TEST_FOLDER}/${TEST_OUTPUT} ${TEST_FOLDER}/${TEST_REFERENCE} - RESULT_VARIABLE TEST_COMPARE_RESULT - ) - else () - file (STRINGS ${TEST_FOLDER}/${TEST_OUTPUT} v1) - file (STRINGS ${TEST_FOLDER}/${TEST_REFERENCE} v2) - list (SORT v1) - list (SORT v2) - if (NOT v1 STREQUAL v2) - set(TEST_COMPARE_RESULT 1) - endif () - endif () - - if (TEST_COMPARE_RESULT) - set (TEST_COMPARE_RESULT 0) - file (STRINGS ${TEST_FOLDER}/${TEST_OUTPUT} test_act) - list (LENGTH test_act len_act) - file (STRINGS ${TEST_FOLDER}/${TEST_REFERENCE} test_ref) - list (LENGTH test_ref len_ref) - if (len_act GREATER 0 AND len_ref GREATER 0) - math (EXPR _FP_LEN "${len_ref} - 1") - foreach (line RANGE 0 ${_FP_LEN}) - list (GET test_act ${line} str_act) - list (GET test_ref ${line} str_ref) - if (NOT str_act STREQUAL str_ref) - if (str_act) - set (TEST_COMPARE_RESULT 1) - message (STATUS "line = ${line}\n***ACTUAL: ${str_act}\n****REFER: ${str_ref}\n") - endif () - endif () - endforeach () - else () - if (len_act EQUAL 0) - message (STATUS "COMPARE Failed: ${TEST_FOLDER}/${TEST_OUTPUT} is empty") - endif () - if (len_ref EQUAL 0) - message (STATUS "COMPARE Failed: ${TEST_FOLDER}/${TEST_REFERENCE} is empty") - endif () - endif () - if (NOT len_act EQUAL len_ref) - set (TEST_COMPARE_RESULT 1) - endif () - endif () - endif () - - message (STATUS "COMPARE Result: ${TEST_COMPARE_RESULT}") - - # again, if return value is !=0 scream and shout - if (TEST_COMPARE_RESULT) - message (FATAL_ERROR "Failed: The output of ${TEST_OUTPUT} did not match ${TEST_REFERENCE}") - endif () - endif () - - # now compare the .err file with the error reference, if supplied - set (TEST_ERRREF_RESULT 0) - if (TEST_ERRREF) - file (READ ${TEST_FOLDER}/${TEST_ERRREF} TEST_STREAM) - list(LENGTH TEST_STREAM test_len) - if (test_len GREATER 0) - if (WIN32) - configure_file(${TEST_FOLDER}/${TEST_ERRREF} ${TEST_FOLDER}/${TEST_ERRREF}.tmp NEWLINE_STYLE CRLF) - if (EXISTS "${TEST_FOLDER}/${TEST_ERRREF}.tmp") - file(RENAME ${TEST_FOLDER}/${TEST_ERRREF}.tmp ${TEST_FOLDER}/${TEST_ERRREF}) - endif () - #file (READ ${TEST_FOLDER}/${TEST_ERRREF} TEST_STREAM) - #file (WRITE ${TEST_FOLDER}/${TEST_ERRREF} "${TEST_STREAM}") - endif () - - # now compare the error output with the error reference - execute_process ( - COMMAND ${CMAKE_COMMAND} -E compare_files ${TEST_FOLDER}/${TEST_OUTPUT}.err ${TEST_FOLDER}/${TEST_ERRREF} - RESULT_VARIABLE TEST_ERRREF_RESULT - ) - if (TEST_ERRREF_RESULT) - set (TEST_ERRREF_RESULT 0) - file (STRINGS ${TEST_FOLDER}/${TEST_OUTPUT}.err test_act) - list (LENGTH test_act len_act) - file (STRINGS ${TEST_FOLDER}/${TEST_ERRREF} test_ref) - list (LENGTH test_ref len_ref) - math (EXPR _FP_LEN "${len_ref} - 1") - if (len_act GREATER 0 AND len_ref GREATER 0) - math (EXPR _FP_LEN "${len_ref} - 1") - foreach (line RANGE 0 ${_FP_LEN}) - list (GET test_act ${line} str_act) - list (GET test_ref ${line} str_ref) - if (NOT str_act STREQUAL str_ref) - if (str_act) - set (TEST_ERRREF_RESULT 1) - message (STATUS "line = ${line}\n***ACTUAL: ${str_act}\n****REFER: ${str_ref}\n") - endif () - endif () - endforeach () - else () - if (len_act EQUAL 0) - message (STATUS "COMPARE Failed: ${TEST_FOLDER}/${TEST_OUTPUT}.err is empty") - endif () - if (len_ref EQUAL 0) - message (STATUS "COMPARE Failed: ${TEST_FOLDER}/${TEST_ERRREF} is empty") - endif () - endif () - if (NOT len_act EQUAL len_ref) - set (TEST_ERRREF_RESULT 1) - endif () - endif () - endif () - - message (STATUS "COMPARE Result: ${TEST_ERRREF_RESULT}") - - # again, if return value is !=0 scream and shout - if (TEST_ERRREF_RESULT) - message (FATAL_ERROR "Failed: The error output of ${TEST_OUTPUT}.err did not match ${TEST_ERRREF}") - endif () - endif () -endif () - -set (TEST_GREP_RESULT 0) -if (TEST_GREP_COMPARE) - # now grep the output with the reference - file (READ ${TEST_FOLDER}/${TEST_OUTPUT} TEST_STREAM) - list(LENGTH TEST_STREAM test_len) - if (test_len GREATER 0) - # TEST_REFERENCE should always be matched - string (REGEX MATCH "${TEST_REFERENCE}" TEST_MATCH ${TEST_STREAM}) - string (COMPARE EQUAL "${TEST_REFERENCE}" "${TEST_MATCH}" TEST_GREP_RESULT) - if (NOT TEST_GREP_RESULT) - message (FATAL_ERROR "Failed: The output of ${TEST_PROGRAM} did not contain ${TEST_REFERENCE}") - endif () - - string (REGEX MATCH "${TEST_FILTER}" TEST_MATCH ${TEST_STREAM}) - if (TEST_EXPECT) - # TEST_EXPECT (1) interprets TEST_FILTER as; NOT to match - string (LENGTH "${TEST_MATCH}" TEST_GREP_RESULT) - if (TEST_GREP_RESULT) - message (FATAL_ERROR "Failed: The output of ${TEST_PROGRAM} did contain ${TEST_FILTER}") - endif () - endif () - endif () -endif () - -# dump the output unless nodisplay option is set -if (TEST_SKIP_COMPARE AND NOT TEST_NO_DISPLAY) - file (READ ${TEST_FOLDER}/${TEST_OUTPUT} TEST_STREAM) - execute_process ( - COMMAND ${CMAKE_COMMAND} -E echo ${TEST_STREAM} - RESULT_VARIABLE TEST_RESULT - ) -endif () - -# everything went fine... -message (STATUS "${TEST_PROGRAM} program used vol ${TEST_VOL} Passed") - diff --git a/config/cmake/libhdf5.settings.cmake.in b/config/cmake/libhdf5.settings.cmake.in index eb83c3a..d80b0f8 100644 --- a/config/cmake/libhdf5.settings.cmake.in +++ b/config/cmake/libhdf5.settings.cmake.in @@ -64,28 +64,29 @@ Languages: Features: --------- - Parallel HDF5: @HDF5_ENABLE_PARALLEL@ -Parallel Filtered Dataset Writes: @PARALLEL_FILTERED_WRITES@ - Large Parallel I/O: @LARGE_PARALLEL_IO@ - High-level library: @HDF5_BUILD_HL_LIB@ - Build HDF5 Tests: @BUILD_TESTING@ - Build HDF5 Tools: @HDF5_BUILD_TOOLS@ - Build High-level HDF5 Tools: @HDF5_BUILD_HL_TOOLS@ - Threadsafety: @HDF5_ENABLE_THREADSAFE@ - Default API mapping: @DEFAULT_API_VERSION@ - With deprecated public symbols: @HDF5_ENABLE_DEPRECATED_SYMBOLS@ - I/O filters (external): @EXTERNAL_FILTERS@ - MPE: @H5_HAVE_LIBLMPE@ - Direct VFD: @H5_HAVE_DIRECT@ - Mirror VFD: @H5_HAVE_MIRROR_VFD@ - (Read-Only) S3 VFD: @H5_HAVE_ROS3_VFD@ - (Read-Only) HDFS VFD: @H5_HAVE_LIBHDFS@ - dmalloc: @H5_HAVE_LIBDMALLOC@ - Packages w/ extra debug output: @INTERNAL_DEBUG_OUTPUT@ - API Tracing: @HDF5_ENABLE_TRACE@ - Using memory checker: @HDF5_ENABLE_USING_MEMCHECKER@ - Memory allocation sanity checks: @HDF5_MEMORY_ALLOC_SANITY_CHECK@ - Function Stack Tracing: @HDF5_ENABLE_CODESTACK@ - Use file locking: @HDF5_FILE_LOCKING_SETTING@ - Strict File Format Checks: @HDF5_STRICT_FORMAT_CHECKS@ - Optimization Instrumentation: @HDF5_Enable_Instrument@ + Parallel HDF5: @HDF5_ENABLE_PARALLEL@ + Parallel Filtered Dataset Writes: @PARALLEL_FILTERED_WRITES@ + Large Parallel I/O: @LARGE_PARALLEL_IO@ + High-level library: @HDF5_BUILD_HL_LIB@ +Dimension scales w/ new references: @DIMENSION_SCALES_WITH_NEW_REF@ + Build HDF5 Tests: @BUILD_TESTING@ + Build HDF5 Tools: @HDF5_BUILD_TOOLS@ + Build High-level HDF5 Tools: @HDF5_BUILD_HL_TOOLS@ + Threadsafety: @HDF5_ENABLE_THREADSAFE@ + Default API mapping: @DEFAULT_API_VERSION@ + With deprecated public symbols: @HDF5_ENABLE_DEPRECATED_SYMBOLS@ + I/O filters (external): @EXTERNAL_FILTERS@ + MPE: @H5_HAVE_LIBLMPE@ + Direct VFD: @H5_HAVE_DIRECT@ + Mirror VFD: @H5_HAVE_MIRROR_VFD@ + (Read-Only) S3 VFD: @H5_HAVE_ROS3_VFD@ + (Read-Only) HDFS VFD: @H5_HAVE_LIBHDFS@ + dmalloc: @H5_HAVE_LIBDMALLOC@ + Packages w/ extra debug output: @INTERNAL_DEBUG_OUTPUT@ + API Tracing: @HDF5_ENABLE_TRACE@ + Using memory checker: @HDF5_ENABLE_USING_MEMCHECKER@ + Memory allocation sanity checks: @HDF5_MEMORY_ALLOC_SANITY_CHECK@ + Function Stack Tracing: @HDF5_ENABLE_CODESTACK@ + Use file locking: @HDF5_FILE_LOCKING_SETTING@ + Strict File Format Checks: @HDF5_STRICT_FORMAT_CHECKS@ + Optimization Instrumentation: @HDF5_Enable_Instrument@ diff --git a/config/cmake/scripts/HDF5config.cmake b/config/cmake/scripts/HDF5config.cmake index 8df7dd4..2f5af77 100644 --- a/config/cmake/scripts/HDF5config.cmake +++ b/config/cmake/scripts/HDF5config.cmake @@ -37,8 +37,8 @@ cmake_minimum_required (VERSION 3.12) # CTEST_SOURCE_NAME - source folder ############################################################################## -set (CTEST_SOURCE_VERSION "1.13.0") -set (CTEST_SOURCE_VERSEXT "") +set (CTEST_SOURCE_VERSION "1.13.1") +set (CTEST_SOURCE_VERSEXT "-1") ############################################################################## # handle input parameters to script. diff --git a/config/cmake_ext_mod/HDFLibMacros.cmake b/config/cmake_ext_mod/HDFLibMacros.cmake index a60d09f..2af3229 100644 --- a/config/cmake_ext_mod/HDFLibMacros.cmake +++ b/config/cmake_ext_mod/HDFLibMacros.cmake @@ -158,7 +158,11 @@ macro (EXTERNAL_SZIP_LIBRARY compress_type encoding) set (SZIP_LIBRARIES ${SZIP_STATIC_LIBRARY}) set (SZIP_INCLUDE_DIR_GEN "${BINARY_DIR}") - set (SZIP_INCLUDE_DIR "${SOURCE_DIR}/src") + if (USE_LIBAEC) + set (SZIP_INCLUDE_DIR "${SOURCE_DIR}/include") + else () + set (SZIP_INCLUDE_DIR "${SOURCE_DIR}/src") + endif () set (SZIP_FOUND 1) set (SZIP_INCLUDE_DIRS ${SZIP_INCLUDE_DIR_GEN} ${SZIP_INCLUDE_DIR}) endmacro () @@ -167,6 +171,8 @@ endmacro () macro (PACKAGE_SZIP_LIBRARY compress_type) set (SZIP_HDR "SZconfig") if (USE_LIBAEC) + set (SZIP_HDR "aec_config") + else () set (SZIP_HDR "libaec_Export") endif () add_custom_target (SZIP-GenHeader-Copy ALL diff --git a/config/cmake_ext_mod/HDFMacros.cmake b/config/cmake_ext_mod/HDFMacros.cmake index ae0ebca..6da2b74 100644 --- a/config/cmake_ext_mod/HDFMacros.cmake +++ b/config/cmake_ext_mod/HDFMacros.cmake @@ -464,6 +464,9 @@ macro (ADD_H5_FLAGS h5_flag_var infile) list (GET TEST_FLAG_STREAM ${line} str_flag) string (REGEX REPLACE "^#.*" "" str_flag "${str_flag}") #message (TRACE "str_flag=${str_flag}") + if (NOT HDF5_ENABLE_WARNINGS_AS_ERRORS) + string (REGEX REPLACE "-Werror=" "-W" str_flag "${str_flag}") + endif () if (str_flag) list (APPEND ${h5_flag_var} "${str_flag}") endif () diff --git a/config/gnu-cxxflags b/config/gnu-cxxflags index 9f11406..56e89bc 100644 --- a/config/gnu-cxxflags +++ b/config/gnu-cxxflags @@ -20,15 +20,15 @@ # # For now, do not promote any warnings to errors. # -PROMOTE_ERRORS_DFLT=no +WARNINGS_AS_ERRORS_DFLT=no # # This filter rewrites -Werror= as -W, in that way demoting warnings -# promoted to errors back to warnings, if PROMOTE_ERRORS is no. +# promoted to errors back to warnings, if WARNINGS_AS_ERRORS is no. # demote_errors() { - if [ ${PROMOTE_ERRORS:-${PROMOTE_ERRORS_DFLT}} = no ]; then + if [ ${WARNINGS_AS_ERRORS:-${WARNINGS_AS_ERRORS_DFLT}} = no ]; then sed 's,-Werror=,-W,g' else cat @@ -44,7 +44,7 @@ demote_errors() load_gnu_arguments() { set -- $(for arg; do - sed 's,#.*$,,' $srcdir/config/gnu-warnings/${arg} + sed 's,#.*$,,' $srcdir/config/gnu-warnings/${arg} | demote_errors done) IFS=' ' echo "$*" } @@ -192,7 +192,6 @@ if test "X-g++" = "X-$cxx_vendor"; then if test $cxx_vers_major -eq 4 -a $cxx_vers_minor -ge 8 -o $cxx_vers_major -ge 5; then H5_CXXFLAGS="$H5_CXXFLAGS $(load_gnu_arguments cxx-general)" H5_ECXXFLAGS="$H5_ECXXFLAGS $(load_gnu_arguments cxx-error-general)" - H5_NECXXFLAGS="$H5_NECXXFLAGS $(load_gnu_arguments cxx-noerror-general)" ###################### # Developer warnings # @@ -222,8 +221,8 @@ if test "X-g++" = "X-$cxx_vendor"; then if test $cxx_vers_major -ge 5 -o $cxx_vers_major -eq 4 -a $cxx_vers_minor -ge 8; then H5_CXXFLAGS="$H5_CXXFLAGS $(load_gnu_arguments cxx-4.8)" # Use the C warnings as CXX warnings are the same - DEVELOPER_WARNING_CXXFLAGS="$DEVELOPER_WARNING_CXXFLAGS $(load_gnu_arguments developer-4.8)" - NO_DEVELOPER_WARNING_CXXFLAGS="$NO_DEVELOPER_WARNING_CXXFLAGS $(load_gnu_arguments no-developer-4.8)" + DEVELOPER_WARNING_CXXFLAGS="$DEVELOPER_WARNING_CXXFLAGS $(load_gnu_arguments cxx-developer-4.8)" + NO_DEVELOPER_WARNING_CXXFLAGS="$NO_DEVELOPER_WARNING_CXXFLAGS $(load_gnu_arguments no-cxx-developer-4.8)" fi # gcc >= 4.9 @@ -235,7 +234,6 @@ if test "X-g++" = "X-$cxx_vendor"; then if test $cxx_vers_major -ge 5; then H5_CXXFLAGS="$H5_CXXFLAGS $(load_gnu_arguments cxx-5)" H5_ECXXFLAGS="$H5_ECXXFLAGS $(load_gnu_arguments cxx-error-5)" - H5_NECXXFLAGS="$H5_NECXXFLAGS $(load_gnu_arguments cxx-noerror-5)" fi # gcc >= 6 @@ -256,7 +254,6 @@ if test "X-g++" = "X-$cxx_vendor"; then # Use the C warnings as CXX warnings are the same H5_CXXFLAGS="$H5_CXXFLAGS $(load_gnu_arguments 8)" #H5_ECXXFLAGS="$H5_ECXXFLAGS $(load_gnu_arguments error-8)" - #H5_NECXXFLAGS="$H5_NECXXFLAGS $(load_gnu_arguments noerror-8)" # Use the C warnings as CXX warnings are the same DEVELOPER_WARNING_CXXFLAGS="$DEVELOPER_WARNING_CXXFLAGS $(load_gnu_arguments developer-8)" NO_DEVELOPER_WARNING_CXXFLAGS="$NO_DEVELOPER_WARNING_CXXFLAGS $(load_gnu_arguments no-developer-8)" diff --git a/config/gnu-fflags b/config/gnu-fflags index ce12561..1333ce5 100644 --- a/config/gnu-fflags +++ b/config/gnu-fflags @@ -161,10 +161,10 @@ if test "X-gfortran" = "X-$f9x_vendor"; then # gfortran 4.9 (nothing new) - # gfortran >= 5 (do not include -Wuse-without-only) - #if test $f9x_vers_major -ge 5; then - # H5_FCFLAGS="$H5_FCFLAGS $(load_gnu_arguments gfort-5)" - #fi + # gfortran >= 5 + if test $f9x_vers_major -ge 5; then + DEVELOPER_WARNING_FCFLAGS="$DEVELOPER_WARNING_FCFLAGS $(load_gnu_arguments developer-gfort-5)" + fi # gfortran >= 6 if test $f9x_vers_major -ge 6; then diff --git a/config/gnu-flags b/config/gnu-flags index 3e4ceb2..89239df 100644 --- a/config/gnu-flags +++ b/config/gnu-flags @@ -20,15 +20,15 @@ # # For now, do not promote any warnings to errors. # -PROMOTE_ERRORS_DFLT=no +WARNINGS_AS_ERRORS_DFLT=no # # This filter rewrites -Werror= as -W, in that way demoting warnings -# promoted to errors back to warnings, if PROMOTE_ERRORS is no. +# promoted to errors back to warnings, if WARNINGS_AS_ERRORS is no. # demote_errors() { - if [ ${PROMOTE_ERRORS:-${PROMOTE_ERRORS_DFLT}} = no ]; then + if [ ${WARNINGS_AS_ERRORS:-${WARNINGS_AS_ERRORS_DFLT}} = no ]; then sed 's,-Werror=,-W,g' else cat @@ -44,7 +44,7 @@ demote_errors() load_gnu_arguments() { set -- $(for arg; do - sed 's,#.*$,,' $srcdir/config/gnu-warnings/${arg} + sed 's,#.*$,,' $srcdir/config/gnu-warnings/${arg} | demote_errors done) IFS=' ' echo "$*" } @@ -205,7 +205,6 @@ if test "X-gcc" = "X-$cc_vendor"; then if test $cc_vers_major -eq 4 -a $cc_vers_minor -ge 8 -o $cc_vers_major -gt 4; then H5_CFLAGS="$H5_CFLAGS $(load_gnu_arguments general)" H5_ECFLAGS="$H5_ECFLAGS $(load_gnu_arguments error-general)" - H5_NECFLAGS="$H5_NECFLAGS $(load_gnu_arguments noerror-general)" ###################### # Developer warnings # @@ -245,7 +244,6 @@ if test "X-gcc" = "X-$cc_vendor"; then if test $cc_vers_major -ge 5; then H5_CFLAGS="$H5_CFLAGS $(load_gnu_arguments 5)" H5_ECFLAGS="$H5_ECFLAGS $(load_gnu_arguments error-5)" - H5_NECFLAGS="$H5_NECFLAGS $(load_gnu_arguments noerror-5)" fi # gcc >= 6 @@ -263,7 +261,6 @@ if test "X-gcc" = "X-$cc_vendor"; then if test $cc_vers_major -ge 8; then H5_CFLAGS="$H5_CFLAGS $(load_gnu_arguments 8)" H5_ECFLAGS="$H5_ECFLAGS $(load_gnu_arguments error-8)" - H5_NECFLAGS="$H5_NECFLAGS $(load_gnu_arguments noerror-8)" DEVELOPER_WARNING_CFLAGS="$DEVELOPER_WARNING_CFLAGS $(load_gnu_arguments developer-8)" NO_DEVELOPER_WARNING_CFLAGS="$NO_DEVELOPER_WARNING_CFLAGS $(load_gnu_arguments no-developer-8)" fi diff --git a/config/gnu-warnings/cxx-developer-4.8 b/config/gnu-warnings/cxx-developer-4.8 new file mode 100644 index 0000000..e0d975f --- /dev/null +++ b/config/gnu-warnings/cxx-developer-4.8 @@ -0,0 +1,16 @@ +# developer warning flags added for GCC >= 4.5 +# +# developer warning flag added for GCC >= 4.6 +-Wsuggest-attribute=const + +# developer warning flags added for GCC >= 4.7 +-Wsuggest-attribute=noreturn +-Wsuggest-attribute=pure +# +# It's not clear that -Wvector-operation-performance warnings are +# actionable, so they are demoted to "developer" warnings. +# +-Wvector-operation-performance + +# developer warning flag added for GCC >= 4.8 +-Wsuggest-attribute=format diff --git a/config/gnu-warnings/cxx-noerror-5 b/config/gnu-warnings/cxx-noerror-5 deleted file mode 100644 index 7bce3e8..0000000 --- a/config/gnu-warnings/cxx-noerror-5 +++ /dev/null @@ -1,11 +0,0 @@ -# -# In GCC 4.4.7, the compiler gripes about shadowed global -# declarations when a local variable uses the name of a -# function that's in a system header file. For some reason, -# later versions of GCC (e.g., 5.2.0) don't complain about -# the shadowed globals. Maybe later versions are less fussy? -# Anyway, the shadowing seems to be harmless, and GCC 4.4.7 -# is not a supported compiler, so let us promote shadowed globals -# warnings to errors only for GCC 5 and later. -# --Wshadow diff --git a/config/gnu-warnings/cxx-noerror-general b/config/gnu-warnings/cxx-noerror-general deleted file mode 100644 index 8cc1d94..0000000 --- a/config/gnu-warnings/cxx-noerror-general +++ /dev/null @@ -1,32 +0,0 @@ -# -# HDF5 code should not trigger the following warnings under any -# circumstances, so ask the compiler to treat them as errors: -# -# NOTE: c++/test files are not compatible with these warnings as errors -# c++/test/tcompound.cpp -# -Werror=cast-align --Wcast-align -# NOTE: c++/src files are not compatible with these warnings as errors -# c++/src/H5Object.cpp -# -Werror=missing-declarations --Wmissing-declarations --Wpacked --Wredundant-decls --Wswitch -# NOTE: c++/test files are not compatible with these warnings as errors -# c++/test/tattr.cpp -# -Werror=unused-but-set-variable --Wunused-but-set-variable --Wunused-function --Wunused-variable -# NOTE: c++/src files are not compatible with these warnings as errors -# c++/src/H5Object.cpp,c++/src/H5StrType.cpp,c++/src/H5PredType.cpp -# -Werror=unused-parameter --Wunused-parameter -# -# Other files not compatible -# NOTE: c++/test files are not compatible with these warnings as errors -# c++/test/titerate.cpp,c++/test/tarray.cpp -# -Werror=missing-declarations -# c++/test/titerate.cpp,c++/test/tarray.cpp,c++/test/tlinks.cpp,c++/test/ttypes.cpp,c++/test/dsets.cpp -# -Werror=unused-parameter diff --git a/config/gnu-warnings/developer-gfort-5 b/config/gnu-warnings/developer-gfort-5 new file mode 100644 index 0000000..c5d3850 --- /dev/null +++ b/config/gnu-warnings/developer-gfort-5 @@ -0,0 +1 @@ +-Wuse-without-only diff --git a/config/gnu-warnings/error-5 b/config/gnu-warnings/error-5 index f7e1138..282ee3f 100644 --- a/config/gnu-warnings/error-5 +++ b/config/gnu-warnings/error-5 @@ -1,4 +1,5 @@ -Werror=incompatible-pointer-types +-Werror=int-conversion # # In GCC 4.4.7, the compiler gripes about shadowed global # declarations when a local variable uses the name of a diff --git a/config/gnu-warnings/error-8 b/config/gnu-warnings/error-8 index 2f54a4d..cbb25f6 100644 --- a/config/gnu-warnings/error-8 +++ b/config/gnu-warnings/error-8 @@ -1,7 +1,4 @@ -# NOTE: src/ files are not compatible with these warnings as errors -# src/H5Dchunk.c -# -Werror=cast-function-type --Wcast-function-type +-Werror=cast-function-type # # For GCC 8, promote maybe-initialized warnings to an error. GCC 8 # reports 0 maybe-uninitialized warnings where earlier versions diff --git a/config/gnu-warnings/error-general b/config/gnu-warnings/error-general index 8405c40..a66d284 100644 --- a/config/gnu-warnings/error-general +++ b/config/gnu-warnings/error-general @@ -11,6 +11,7 @@ -Werror=packed -Werror=pointer-sign -Werror=pointer-to-int-cast +-Werror=int-to-pointer-cast -Werror=redundant-decls -Werror=strict-prototypes -Werror=switch diff --git a/config/gnu-warnings/gfort-5 b/config/gnu-warnings/gfort-5 deleted file mode 100644 index c5d3850..0000000 --- a/config/gnu-warnings/gfort-5 +++ /dev/null @@ -1 +0,0 @@ --Wuse-without-only diff --git a/config/gnu-warnings/no-cxx-developer-4.8 b/config/gnu-warnings/no-cxx-developer-4.8 new file mode 100644 index 0000000..3c3de93 --- /dev/null +++ b/config/gnu-warnings/no-cxx-developer-4.8 @@ -0,0 +1,9 @@ +# no-developer warning flag added for GCC >= 4.6 +-Wno-suggest-attribute=const + +# no-developer warning flags added for GCC >= 4.7 +-Wno-suggest-attribute=noreturn +-Wno-suggest-attribute=pure + +# no-developer warning flag added for GCC >= 4.8 +-Wno-suggest-attribute=format diff --git a/config/gnu-warnings/noerror-5 b/config/gnu-warnings/noerror-5 deleted file mode 100644 index a7d40dd..0000000 --- a/config/gnu-warnings/noerror-5 +++ /dev/null @@ -1,12 +0,0 @@ --Wincompatible-pointer-types -# -# In GCC 4.4.7, the compiler gripes about shadowed global -# declarations when a local variable uses the name of a -# function that's in a system header file. For some reason, -# later versions of GCC (e.g., 5.2.0) don't complain about -# the shadowed globals. Maybe later versions are less fussy? -# Anyway, the shadowing seems to be harmless, and GCC 4.4.7 -# is not a supported compiler, so let us promote shadowed globals -# warnings to errors only for GCC 5 and later. -# --Wshadow diff --git a/config/gnu-warnings/noerror-8 b/config/gnu-warnings/noerror-8 deleted file mode 100644 index 2f54a4d..0000000 --- a/config/gnu-warnings/noerror-8 +++ /dev/null @@ -1,25 +0,0 @@ -# NOTE: src/ files are not compatible with these warnings as errors -# src/H5Dchunk.c -# -Werror=cast-function-type --Wcast-function-type -# -# For GCC 8, promote maybe-initialized warnings to an error. GCC 8 -# reports 0 maybe-uninitialized warnings where earlier versions -# make many false reports. GCC 8 seems to analyze calls to static -# in order to detect initializations that occur there. It's possible -# that GCC 8 only performs that analysis at -O3, though. -# -# -# NOTE: File Driver files are not compatible with these warnings as errors -# H5FDlog.c, -# -Werror=maybe-uninitialized --Wmaybe-uninitialized -# NOTE: src/ files are not compatible with these warnings as errors -# src/H5Shyper.c,src/H5SL.c,src/H5Shyper.c -# -Werror=maybe-uninitialized -# NOTE: Test files are not compatible with these warnings as errors -# test/cache_common.c, -# -Werror=maybe-uninitialized -# NOTE: hl/src/ files are not compatible with these warnings as errors -# hl/src/H5DS.c, -# -Werror=maybe-uninitialized diff --git a/config/gnu-warnings/noerror-general b/config/gnu-warnings/noerror-general deleted file mode 100644 index f49d89a..0000000 --- a/config/gnu-warnings/noerror-general +++ /dev/null @@ -1,92 +0,0 @@ -# -# These warnings will be treated as errors, using the error-general file, -# when HDF5_ENABLE_WARNINGS_AS_ERRORS is set to true for CMake or -# the --enable-warnings-as-errors option is specified for configure. -# Otherwise this file will be used to treat them as warnings. -# --Wbad-function-cast --Wimplicit-function-declaration --Wmissing-declarations --Wmissing-prototypes --Wnested-externs --Wold-style-definition --Wpacked --Wpointer-sign --Wpointer-to-int-cast --Wredundant-decls --Wstrict-prototypes --Wswitch -# -#-Werror=discarded-qualifiers -# -# -# NOTE: File Driver files are not compatible with these warnings as errors -# H5FDdirect.c,H5FDmpio.c,H5FDros3.c, -# -Werror=unused-function -# --Wunused-function -# -# H5FDdrvr_module.h -# -Werror=unused-variable -# --Wunused-variable -# -# H5VLpassthru.c -# -Werror=unused-parameter -# --Wunused-parameter -# -# -# -# NOTE: Tools files are not compatible with these warnings as errors -# lib/h5tools.c -# -Werror=cast-align -# --Wcast-align -# -# lib/h5diff_array.c -# -Werror=unused-but-set-variable -# --Wunused-but-set-variable -# -# lib/h5tools_utils.c -# -Werror=unused-parameter -# -# -# NOTE: JNI files are not compatible with these warnings as errors -# jni/h5pDCPLImp.c,jni/nativeData.c,jni/h5util.c,jni/h5rImp.c -# jni/h5sImp.c,jni/h5tImp.c -# -Werror=cast-align -# jni/h5util.c -# -Werror=format(-overflow) -# --Wformat -# -# -#Examples and tests do not use the same set of extensive warning flags as libraries -# Here is a list of tests and examples that have issues with the stricter warnings as error -# -# NOTE: Test files are not compatible with these warnings as errors -# thread_id.c, -# -Werror=unused-function -# dsets.c -# -Werror=unused-parameter -# external.c,perform/sio_engine.c -# -Werror=format(-truncation) -# -# -# NOTE: Examples files are not compatible with these warnings as errors -# h5_vds-eiger.c,h5_vds-exclim.c,h5_vds.c,h5_vds-exc.c,h5_vds-percival-unlim-maxmin.c -# h5_vds-percival.c,h5_read.c,h5_rdwt.c,h5_mount.c,h5_extend.c,h5_extend_write.c -# h5_write.c,h5_vds-simpleIO.c,h5_ref2reg_deprec.c,h5_crtgrp.c,h5_select.c -# h5_vds-percival-unlim.c,h5_crtatt.c,h5_group.c,h5_attribute.c,h5_crtdat.c -# h5_reference_deprec.c -# h5_rdwt.c,h5_crtgrp.c,h5_crtatt.c,h5_crtdat.c -# -Werror=strict-prototypes -# h5_rdwt.c,h5_crtgrp.c,h5_crtatt.c,h5_crtdat.c -# -Werror=old-style-definition -# h5_vds-exclim.c,h5_vds.c,h5_vds-exc.c, -# -Werror=unused-variable -# h5_elink_unix2win.c,h5_extlink.c,h5_attribute.c -# -Werror=unused-parameter - diff --git a/config/sanitizer/code-coverage.cmake b/config/sanitizer/code-coverage.cmake index 8d765f7..c79aeac 100644 --- a/config/sanitizer/code-coverage.cmake +++ b/config/sanitizer/code-coverage.cmake @@ -99,8 +99,7 @@ if(CODE_COVERAGE AND NOT CODE_COVERAGE_ADDED) ${CMAKE_COVERAGE_OUTPUT_DIRECTORY} DEPENDS ccov-clean) - if(CMAKE_C_COMPILER_ID MATCHES "[Cc]lang" - OR CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") + if(CMAKE_C_COMPILER_ID MATCHES "[Cc]lang" OR CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") # Messages message(STATUS "Building with llvm Code Coverage Tools") @@ -206,8 +205,7 @@ function(target_code_coverage TARGET_NAME) if(CODE_COVERAGE) # Add code coverage instrumentation to the target's linker command - if(CMAKE_C_COMPILER_ID MATCHES "[Cc]lang" - OR CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") + if(CMAKE_C_COMPILER_ID MATCHES "[Cc]lang" OR CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") target_compile_options(${TARGET_NAME} PRIVATE -fprofile-instr-generate -fcoverage-mapping) set_property( @@ -229,8 +227,7 @@ function(target_code_coverage TARGET_NAME) # Add shared library to processing for 'all' targets if(target_type STREQUAL "SHARED_LIBRARY" AND target_code_coverage_ALL) - if(CMAKE_C_COMPILER_ID MATCHES "[Cc]lang" - OR CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") + if(CMAKE_C_COMPILER_ID MATCHES "[Cc]lang" OR CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") add_custom_target( ccov-run-${TARGET_NAME} COMMAND echo "-object=$<TARGET_FILE:${TARGET_NAME}>" >> @@ -250,8 +247,7 @@ function(target_code_coverage TARGET_NAME) # For executables add targets to run and produce output if(target_type STREQUAL "EXECUTABLE") - if(CMAKE_C_COMPILER_ID MATCHES "[Cc]lang" - OR CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?Cc]lang") + if(CMAKE_C_COMPILER_ID MATCHES "[Cc]lang" OR CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?Cc]lang") # If there are shared objects to also work with, generate the string to # add them here @@ -409,8 +405,7 @@ endfunction() # any subdirectories. To add coverage instrumentation to only specific targets, # use `target_code_coverage`. function(add_code_coverage) - if(CMAKE_C_COMPILER_ID MATCHES "[Cc]lang" - OR CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") + if(CMAKE_C_COMPILER_ID MATCHES "[Cc]lang" OR CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") add_compile_options(-fprofile-instr-generate -fcoverage-mapping) add_link_options(-fprofile-instr-generate -fcoverage-mapping) elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") @@ -435,8 +430,7 @@ function(add_code_coverage_all_targets) "${multi_value_keywords}" ${ARGN}) if(CODE_COVERAGE) - if(CMAKE_C_COMPILER_ID MATCHES "[Cc]lang" - OR CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") + if(CMAKE_C_COMPILER_ID MATCHES "[Cc]lang" OR CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") # Merge the profile data for all of the run executables add_custom_target( diff --git a/config/sanitizer/sanitizers.cmake b/config/sanitizer/sanitizers.cmake index 58c4050..8bf1d5b 100644 --- a/config/sanitizer/sanitizers.cmake +++ b/config/sanitizer/sanitizers.cmake @@ -30,7 +30,7 @@ endfunction() message(STATUS "USE_SANITIZER=${USE_SANITIZER}, CMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}") if(USE_SANITIZER) - if(INTEL_CLANG OR "${CMAKE_C_COMPILER_ID}" MATCHES "Clang") + if(INTEL_CLANG OR CMAKE_C_COMPILER_ID MATCHES "[Cc]lang") set(CMAKE_EXPORT_COMPILE_COMMANDS ON) if(UNIX) diff --git a/configure.ac b/configure.ac index 3290de4..ab55f3e 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ AC_PREREQ([2.69]) ## NOTE: Do not forget to change the version number here when we do a ## release!!! ## -AC_INIT([HDF5], [1.13.0], [help@hdfgroup.org]) +AC_INIT([HDF5], [1.13.1-1], [help@hdfgroup.org]) AC_CONFIG_SRCDIR([src/H5.c]) AC_CONFIG_HEADERS([src/H5config.h]) @@ -237,6 +237,41 @@ elif test $hdf5_cv_host != $host; then fi ## ---------------------------------------------------------------------- +## Check if we should consider certain compiler warnings as errors +## +## We have to set WARNINGS_AS_ERRORS before sourcing a $host_config +## file, below. +## +## These should NOT be on by default as the risk of breakage is high +## when compiling HDF5 on new (or new versions) of platforms and +## compilers. It can also cause failures when header files we have no +## control over (e.g. MPI, HDFS) raise warnings. +## +AC_MSG_CHECKING([enable warnings as errors]) +AC_ARG_ENABLE([warnings-as-errors], + [AS_HELP_STRING([--enable-warnings-as-errors], + [Determines whether certain warnings will be + considered errors. This is mainly for use + by HDF5 library developers. + [default=no] + ])], + [WARNINGS_AS_ERRORS=$enableval]) + +## Set default +if test "X-$WARNINGS_AS_ERRORS" = X- ; then + WARNINGS_AS_ERRORS=no +fi + +case "X-$WARNINGS_AS_ERRORS" in + X-yes|X-no) + AC_MSG_RESULT([$WARNINGS_AS_ERRORS]) + ;; + *) + AC_MSG_ERROR([Unrecognized value: $WARNINGS_AS_ERRORS]) + ;; +esac + +## ---------------------------------------------------------------------- ## Source any special files that we need. These files normally aren't ## present but can be used by the maintainers to fine tune things like ## turning on debug or profiling flags for the compiler. The search order @@ -788,11 +823,14 @@ AC_LANG_POP(C++) AC_SUBST([HDF5_HL]) AC_SUBST([HDF5_HL_TOOLS]) -## The high-level library is enabled unless the build mode is clean. +## The high-level library and high-level tools are enabled unless the build mode +## is clean. if test "X-$BUILD_MODE" = "X-clean" ; then HDF5_HL=no + HDF5_HL_TOOLS=no else HDF5_HL=yes + HDF5_HL_TOOLS=yes fi ## high-level library directories (set when needed, blank until then) @@ -841,6 +879,38 @@ fi ## ---------------------------------------------------------------------- +## Enable new references for dimension scales +## +AC_SUBST([DIMENSION_SCALES_WITH_NEW_REF]) +AC_MSG_CHECKING([whether to use new references with dimension scales]); +AC_ARG_ENABLE([dimension-scales-with-new-ref], + [AS_HELP_STRING([--enable-dimension-scales-with-new-ref], + [Use new references when creating dimension scales. + [default=no] + ])], + [DIMENSION_SCALES_WITH_NEW_REF=$enableval]) + +## Set the default value to use old references. +if test "X-$DIMENSION_SCALES_WITH_NEW_REF" = X- ; then + DIMENSION_SCALES_WITH_NEW_REF=no +fi + +case "X-$DIMENSION_SCALES_WITH_NEW_REF" in + X-yes) + AC_MSG_RESULT([yes]) + AC_DEFINE([DIMENSION_SCALES_WITH_NEW_REF], [1], + [Define if new references for dimension scales were requested]) + + ;; + X-no) + AC_MSG_RESULT([no]) + ;; + *) + AC_MSG_ERROR([Unrecognized value: $DIMENSION_SCALES_WITH_NEW_REF]) + ;; +esac + +## ---------------------------------------------------------------------- ## Check which archiving tool to use. This needs to be done before ## the AM_PROG_LIBTOOL macro. ## @@ -1126,6 +1196,7 @@ if test "X$HDF5_DOXYGEN" = "Xyes"; then AC_SUBST([DOXYGEN_EXTERNAL_SEARCH]) AC_SUBST([DOXYGEN_SEARCHENGINE_URL]) AC_SUBST([DOXYGEN_STRIP_FROM_PATH]) + AC_SUBST([DOXYGEN_STRIP_FROM_INC_PATH]) AC_SUBST([DOXYGEN_PREDEFINED]) # SRCDIR Environment variables used inside doxygen macro for the source location: @@ -1133,7 +1204,7 @@ if test "X$HDF5_DOXYGEN" = "Xyes"; then DOXYGEN_VERSION_STRING=${PACKAGE_VERSION} DOXYGEN_INCLUDE_ALIASES='$(SRCDIR)/doxygen/aliases' DOXYGEN_PROJECT_LOGO='$(SRCDIR)/doxygen/img/HDFG-logo.png' - DOXYGEN_PROJECT_BRIEF='C-API Reference' + DOXYGEN_PROJECT_BRIEF='' DOXYGEN_INPUT_DIRECTORY='$(SRCDIR) $(SRCDIR)/doxygen/dox' DOXYGEN_OPTIMIZE_OUTPUT_FOR_C=YES DOXYGEN_MACRO_EXPANSION=YES @@ -1149,6 +1220,7 @@ if test "X$HDF5_DOXYGEN" = "Xyes"; then DOXYGEN_EXTERNAL_SEARCH=NO DOXYGEN_SEARCHENGINE_URL= DOXYGEN_STRIP_FROM_PATH='$(SRCDIR)' + DOXYGEN_STRIP_FROM_INC_PATH='$(SRCDIR)' DOXYGEN_PREDEFINED='H5_HAVE_DIRECT H5_HAVE_LIBHDFS H5_HAVE_MAP_API H5_HAVE_PARALLEL H5_HAVE_ROS3_VFD' DX_INIT_DOXYGEN([HDF5], [./doxygen/Doxyfile], [hdf5lib_docs]) @@ -1505,6 +1577,7 @@ case "X-$withval" in ;; esac + ## ---------------------------------------------------------------------- ## Make the external filters list available to *.in files ## At this point it's unset (no external filters by default) but it @@ -2230,6 +2303,13 @@ case "X-$ASSERTS" in ;; esac +## Incorporate the potentially warning-to-error promoting flags after +## feature tests. Some of the tests (e.g., `off_t`) generate compilation +## errors with the flags we chose for the HDF5 library and tools. +## +H5_CFLAGS="$H5_CFLAGS $H5_ECFLAGS" +H5_CXXFLAGS="$H5_CXXFLAGS $H5_ECXXFLAGS" + ## ---------------------------------------------------------------------- ## Check if developer warnings should be turned on ## These are warnings that provide suggestions like gcc's -Wsuggest-attribute. @@ -2257,6 +2337,7 @@ fi case "X-$DEV_WARNINGS" in X-yes) H5_CFLAGS="$H5_CFLAGS $DEVELOPER_WARNING_CFLAGS" + H5_FCFLAGS="$H5_FCFLAGS $DEVELOPER_WARNING_FCFLAGS" AC_MSG_RESULT([yes]) ;; X-no) @@ -2269,45 +2350,6 @@ case "X-$DEV_WARNINGS" in esac ## ---------------------------------------------------------------------- -## Check if we should consider certain compiler warnings as errors -## -## These should NOT be on by default as the risk of breakage is high -## when compiling HDF5 on new (or new versions) of platforms and -## compilers. It can also cause failures when header files we have no -## control over (e.g. MPI, HDFS) raise warnings. -## -AC_MSG_CHECKING([enable warnings as errors]) -AC_ARG_ENABLE([warnings-as-errors], - [AS_HELP_STRING([--enable-warnings-as-errors], - [Determines whether certain warnings will be - considered errors. This is mainly for use - by HDF5 library developers. - [default=no] - ])], - [WARNINGS_AS_ERRORS=$enableval]) - -## Set default -if test "X-$WARNINGS_AS_ERRORS" = X- ; then - WARNINGS_AS_ERRORS=no -fi - -case "X-$WARNINGS_AS_ERRORS" in - X-yes) - H5_CFLAGS="$H5_CFLAGS $H5_ECFLAGS" - H5_CXXFLAGS="$H5_CXXFLAGS $H5_ECXXFLAGS" - AC_MSG_RESULT([yes]) - ;; - X-no) - H5_CFLAGS="$H5_CFLAGS $H5_NECFLAGS" - H5_CXXFLAGS="$H5_CXXFLAGS $H5_NECXXFLAGS" - AC_MSG_RESULT([no]) - ;; - *) - AC_MSG_ERROR([Unrecognized value: $WARNINGS_AS_ERRORS]) - ;; -esac - -## ---------------------------------------------------------------------- ## Check if the compiler should use profiling flags/settings ## AC_MSG_CHECKING([profiling]) diff --git a/doc/library-init-shutdown.md b/doc/library-init-shutdown.md new file mode 100644 index 0000000..917d213 --- /dev/null +++ b/doc/library-init-shutdown.md @@ -0,0 +1,56 @@ +# HDF5 Library initialization and shutdown + +## Application perspective + +### Implicit initialization and shutdown + +When a developer exports a new symbol as part of the HDF5 library, +they should make sure that an application cannot enter the library in an +uninitialized state through a new API function, or read an uninitialized +value from a non-function HDF5 symbol. + +The HDF5 library initializes itself when an application either enters +the library through an API function call such as `H5Fopen`, or when +an application evaluates an HDF5 symbol that represents either a +property-list identifier such as `H5F_ACC_RDONLY` or `H5F_ACC_RDWR`, +a property-list class identifier such as `H5P_FILE_ACCESS`, a VFD +identifier such as `H5FD_FAMILY` or `H5FD_SEC2`, or a type identifier +such as `H5T_NATIVE_INT64`. + +The library sets a flag when initialization occurs and as long as the +flag is set, skips initialization. + +The library provides a couple of macros that initialize the library +as necessary. The library is initialized as a side-effect of the +`FUNC_ENTER_API*` macros used at the top of most API functions. HDF5 +library symbols other than functions are provided through `#define`s +that use `H5OPEN` to introduce a library-initialization call (`H5open`) +at each site where a non-function symbol is used. + +Ordinarily the library registers an `atexit(3)` handler to shut itself +down when the application exits. + +### Explicit initialization and shutdown + +An application may use an API call, `H5open`, to explicitly initialize +the library. `H5close` explicitly shuts down the library. + +## Library internals perspective + +No matter how library initializion begins, eventually the internal +function `H5_init_library` will be called. `H5_init_library` is +responsible for calling the initializers for every internal HDF5 +library module (aka "package") in the correct order so that no module is +initialized before its prerequisite modules. A table in `H5_init_library` +establishes the order of initialization. If a developer adds a +module to the library that it is appropriate to initialize with the rest +of the library, then they should insert its initializer into the right +place in the table. + +`H5_term_library` drives library shutdown. Library shutdown is +table-driven, too. If a developer adds a module that needs to release +resources during library shutdown, then they should add a call at the +right place to the shutdown table. Note that some entries in the shutdown +table are marked as "barriers," and if a new module should only be +shutdown *strictly after* the preceding modules, then it should be marked +as a barrier. See the comments in `H5_term_library` for more information. diff --git a/doxygen/CMakeLists.txt b/doxygen/CMakeLists.txt index 36ce590..3462d50 100644 --- a/doxygen/CMakeLists.txt +++ b/doxygen/CMakeLists.txt @@ -27,6 +27,7 @@ if (DOXYGEN_FOUND) set (DOXYGEN_EXTERNAL_SEARCH NO) set (DOXYGEN_SEARCHENGINE_URL) set (DOXYGEN_STRIP_FROM_PATH ${HDF5_SOURCE_DIR}) + set (DOXYGEN_STRIP_FROM_INC_PATH ${HDF5_SOURCE_DIR}) set (DOXYGEN_PREDEFINED "H5_HAVE_DIRECT H5_HAVE_LIBHDFS H5_HAVE_MAP_API H5_HAVE_PARALLEL H5_HAVE_ROS3_VFD") # This configure and individual custom targets work together diff --git a/doxygen/Doxyfile.in b/doxygen/Doxyfile.in index 44d9974..8c871de 100644 --- a/doxygen/Doxyfile.in +++ b/doxygen/Doxyfile.in @@ -179,7 +179,7 @@ STRIP_FROM_PATH = @DOXYGEN_STRIP_FROM_PATH@ # specify the list of include paths that are normally passed to the compiler # using the -I flag. -STRIP_FROM_INC_PATH = +STRIP_FROM_INC_PATH = @DOXYGEN_STRIP_FROM_INC_PATH@ # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't @@ -856,6 +856,7 @@ INPUT_ENCODING = UTF-8 FILE_PATTERNS = H5*public.h \ H5*module.h \ H5FDcore.h \ + H5FDdevelop.h \ H5FDdirect.h \ H5FDfamily.h \ H5FDhdfs.h \ diff --git a/doxygen/aliases b/doxygen/aliases index 06c3445..f83a875 100644 --- a/doxygen/aliases +++ b/doxygen/aliases @@ -24,6 +24,7 @@ ALIASES += htri_t="Returns zero (false), a positive (true) or a negative (failur ALIASES += api_vers_2{3}="\1() is a macro that is mapped to either \2() or \3().\n\see \ref api-compat-macros" ALIASES += api_vers_3{4}="\1() is a macro that is mapped to either \2() or \3() or \4().\n\see \ref api-compat-macros" +ALIASES += api_vers_4{5}="\1() is a macro that is mapped to either \2() or \3() or \4() or \5().\n\see \ref api-compat-macros" ALIASES += deprecation_note{1}="\deprecated Superseded by \1." @@ -252,10 +253,17 @@ ALIASES += ref_vol_doc="VOL documentation" ################################################################################ ALIASES += ref_rfc20210528="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_multi_thread.pdf\">Multi-Thread HDF5</a>" +ALIASES += ref_rfc20210219="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/selection_io_RFC_210610.pdf\">Selection I/O</a>" +ALIASES += ref_rfc20200213="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_VFD_subfiling_200424.pdf\">VFD Sub-filing</a>" +ALIASES += ref_rfc20200210="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/Onion_VFD_RFC_211122.pdf\">Onion VFD</a>" ALIASES += ref_rfc20190923="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/2019-09-23-RFC_VOL_feature_flags.pdf\">Virtual Object Layer (VOL) API Compatibility</a>" +ALIASES += ref_rfc20190715="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/var_len_data_sketch_design_190715.pdf\">Variable-Length Data in HDF5 Sketch Design</a>" ALIASES += ref_rfc20190410="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_VFD_Plugin.docx.pdf\">A Plugin Interface for HDF5 Virtual File Drivers</a>" ALIASES += ref_rfc20181231="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_Min_Obj_Headers_181231.pdf\">Dataset Object Header Size</a>" ALIASES += ref_rfc20181220="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/3.2.1_3.2.2_deliverable_181220_v4.pdf\">MS 3.2 – Addressing Scalability: Scalability of open, close, flush CASE STUDY: CGNS Hotspot analysis of CGNS cgp_open</a>" +ALIASES += ref_rfc20180830="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_Sparse_Chunks180830.pdf\">Sparse Chunks</a>" +ALIASES += ref_rfc20180829="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/mirror_VFD_RFC_2018-10-05.pdf\">H5FD_MIRROR Virtual File Driver</a>" +ALIASES += ref_rfc20180815="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/splitter_VFD_RFC_180830.pdf\">Splitter_VFD</a>" ALIASES += ref_rfc20180620="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-Chunking%20Functions-2018-06-20-v3.docx.pdf\">Chunk query functionality in HDF5</a>" ALIASES += ref_rfc20180610="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/VFD_SWMR_RFC_200916.pdf\">VFD SWMR</a>" ALIASES += ref_rfc20180321="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-API_Contexts-2018-03-21.docx.pdf\">API Contexts</a>" @@ -298,7 +306,7 @@ ALIASES += ref_rfc20120305="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC%20P ALIASES += ref_rfc20120220="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/h5repack_improve_hyperslab_over_chunked_dataset_v1.pdf\"><tt>h5repack</tt>: Improved Hyperslab selections for Large Chunked Datasets</a>" ALIASES += ref_rfc20120120="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/2012-1-25-Maintainers-guide-for-datatype.docx.pdf\">A Maintainer’s Guide for the Datatype Module in HDF5 Library</a>" ALIASES += ref_rfc20120104="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_actual_io_v4-1_done.docx.pdf\">Actual I/O Mode</a>" -ALIASES += ref_rfc20111119="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-H5Ocompare-review_v6.pdf\">New public functions to handle comparison</a>" +ALIASES += ref_rfc20111119="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-H5Ocompare-review_v6.pdf\">New public functions to handle comparison</a>" ALIASES += ref_rfc20110825="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/2011-08-31-RFC_H5Ocopy_Named_DT_v2.docx.pdf\">Merging Named Datatypes in H5Ocopy()</a>" ALIASES += ref_rfc20110811="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_Enhancement_Hyperslab_Selection-1.4.docx.pdf\">Expanding the HDF5 Hyperslab Selection Interface</a>" ALIASES += ref_rfc20110726="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/metadata_aggregation_RFC_v03.docx.pdf\">HDF5 File Space Allocation and Aggregation</a>" @@ -318,8 +326,12 @@ ALIASES += ref_rfc20091218="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RCF_h5d ALIASES += ref_rfc20090907="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_Tools_Lib_v2.pdf\">HDF5 Tools Library Functions</a>" ALIASES += ref_rfc20090612="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_h5diff_default_epsilon.pdf\">Default EPSILON values for comparing floating point data</a>" ALIASES += ref_rfc20081218="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_h5diff_NonComparable.pdf\">Reporting of Non-Comparable Datasets by <tt>h5diff</tt></a>" +ALIASES += ref_rfc20081205="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_elink_callback.pdf\">External Link Traversal Callback</a>" +ALIASES += ref_rfc20081030="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_chunk_cache_functions.pdf\">Setting Raw Data Chunk Cache Parameters in HDF5</a>" ALIASES += ref_rfc20080915="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/FileFreeSpacePerformance.pdf\">Performance Report for Free-space Manager</a>" ALIASES += ref_rfc20080904="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/ExternalLinkFileAccessProperty.pdf\">Setting File Access Property List for accessing External Link</a>" +ALIASES += ref_rfc20080728="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_Native_Time_Types.pdf\">Native Time Types in HDF5</a>" +ALIASES += ref_rfc20080723="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_Special_Values_in_HDF5.pdf\">Special Values in HDF5</a>" ALIASES += ref_rfc20080301="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/DynamicTransformations_RFC.pdf\">Dynamic Transformations to HDF5 Data</a>" ALIASES += ref_rfc20080209="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-Using-SVN-branching-Feb9.pdf\">Using SVN branching to improve software development process at THG</a>" ALIASES += ref_rfc20080206="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-HIS-REL-1.8_Feb6.pdf\">Maintaining the <tt>HISTORY.txt</tt> and <tt>RELEASE.txt</tt> files in HDF5</a>" @@ -327,7 +339,7 @@ ALIASES += ref_rfc20071111="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/AURA-co ALIASES += ref_rfc20071018="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_NaNsHDF5.pdf\"><tt>NaN</tt> detection in HDF5</a>" ALIASES += ref_rfc20070801="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/Metadata_Journaling_RFC.pdf\">Metadata Journaling to Improve Crash Survivability</a>" ALIASES += ref_rfc20070413="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/API_Compatibility_RFC.txt.pdf\">API Compatibility Strategies for HDF5</a>" -ALIASES += ref_rfc20070115="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/PrivateHeap.pdf\">A 'Private' Heap for HDF5</a>" +ALIASES += ref_rfc20070115="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/PrivateHeap.pdf\">A \"Private\" Heap for HDF5</a>" ALIASES += ref_rfc20060623="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/coll_ind_dd6.pdf\">Performance Comparison of Collective I/O and Independent I/O with Derived Datatypes</a>" ALIASES += ref_rfc20060604="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/h5stat_spec_v3_2006-06-04.pdf\"><tt>h5stat</tt> tool</a>" ALIASES += ref_rfc20060505="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/Simple%20Performance%20Test%20on%20Fletcher32%20Filter.pdf\">Simple Performance Test on Fletcher32 Filter</a>" diff --git a/doxygen/dox/About.dox b/doxygen/dox/About.dox index d315566..9000a78 100644 --- a/doxygen/dox/About.dox +++ b/doxygen/dox/About.dox @@ -12,12 +12,118 @@ of <em>documentation done right</em>. \section about_documentation Documentation about Documentation -\li \todo Describe how to add a reference or a new RFC -\li \todo Describe how to add an example -\li \todo Describe how to include plain HTML -\li \todo Describe how to add an API macro -\li \todo Describe the custom commands -\li \todo Describe the S3 bucket layout and update routine -\li \todo Link the RM template +In this section, we describe common documentation maintenance tasks. + +\subsection plain_html Including Plain HTML Pages + +The most common use case for this is the inclusion of older documentation. +New documentation should, whenever possible, be created using Doxygen markdown! + +Use Doxygen's <a href="https://www.doxygen.nl/manual/commands.html#cmdhtmlinclude"><code>htmlinclude</code></a> +special command to include existing plain HTML pages. + +An example from this documentation set can be seen +<a href="https://github.com/HDFGroup/hdf5/blob/develop/doxygen/dox/FileFormatSpec.dox">here</a>. + +\subsection new_rm_entry Creating a New Reference Manual Entry + +Please refer to the \ref RMT for guidance on how to create a new reference manual entry. + +\subsubsection new_example Adding and Referencing API Examples + +For each HDF5 module, such as \Code{H5F}, there is an examples source file called +\Code{H5*_examples.c}. For example, the \Code{H5F} API examples are located in +<a href="https://github.com/HDFGroup/hdf5/blob/develop/doxygen/examples/H5F_examples.c"> +<code>H5F_examples.c</code></a>. Examples are code blocks marked as Doxygen +<a href="https://www.doxygen.nl/manual/commands.html#cmdsnippet">snippets</a>. +For example, the source code for the H5Fcreate() API sample is located between +the +\verbatim +//! <!-- [create] --> +... +//! <!-- [create] --> +\endverbatim +comments in +<a href="https://github.com/HDFGroup/hdf5/blob/develop/doxygen/examples/H5F_examples.c"> +<code>H5F_examples.c</code></a>. + +Add a new API example by adding a new code block enclosed between matching +snippet tags. The name of the tag is usually the function name stripped of +the module prefix. + +The inclusion of such a block of code can then be triggered via Doxygen's +<a href="https://www.doxygen.nl/manual/commands.html#cmdsnippet"><code>snippet</code></a> +special command. For example, the following markup +\verbatim +* \snippet H5F_examples.c create +\endverbatim +yields +\snippet H5F_examples.c create + +\subsubsection api_macro Adding an API Macro + +API macros are handled by the <code>api_vers_2, api_vers_3, api_vers_4</code> +custom commands. The numbers indicate the number of potential API function +mappings. For example, H5Acreate() has two potential mappings, H5Acreate1() and +H5Acreate2(). To trigger the creation of a reference manual entry for H5Acreate() +use the following markup: +\verbatim +\api_vers_2{H5Acreate,H5Acreate1,H5Acreate2} +\endverbatim +This yields: + +\api_vers_2{H5Acreate,H5Acreate1,H5Acreate2} + +\subsection custom_commands Creating Custom Commands + +See Doxygen's <a href="https://www.doxygen.nl/manual/custcmd.html">Custom Commands documentation</a> +as a general reference. + +All custom commands for this project are located in the +<a href="https://github.com/HDFGroup/hdf5/blob/develop/doxygen/aliases"><tt>aliases</tt></a> +file in the <a href="https://github.com/HDFGroup/hdf5/tree/develop/doxygen"><tt>doxygen</tt></a> +subdirectory of the <a href="https://github.com/HDFGroup/hdf5">main HDF5 repo</a>. + +The custom commands are grouped in sections. Find a suitable section for your command or +ask for help if unsure! + +\subsection new_rfc Adding a New RFC or Referencing an Existing RFC + +For ease of reference, we define custom commands for each RFC in the <tt>RFCs</tt> section +of the +<a href="https://github.com/HDFGroup/hdf5/blob/develop/doxygen/aliases"><tt>aliases</tt></a> +file. For example the custom command \Code{ref_rfc20141210} can be used to insert a +reference to "RFC: Virtual Object Layer". In other words, the markup +\verbatim +\ref_rfc20141210 +\endverbatim +yields a clickable link: + +\ref_rfc20141210 + +To add a new RFC, add a custom command for the RFC to the +<a href="https://github.com/HDFGroup/hdf5/blob/develop/doxygen/aliases"><tt>aliases</tt></a> +file. The naming convention for the custom command is \Code{ref_rfcYYYYMMDD}, +where \Code{YYYYMMDD} is the ID of the RFC. The URL is composed of the prefix +\verbatim +https://docs.hdfgroup.org/hdf5/rfc/ +\endverbatim +and the name of your RFC file, typically, a PDF file, i.e., the full URL would +be +\verbatim +https://docs.hdfgroup.org/hdf5/rfc/my_great_rfc_name.pdf +\endverbatim + +\subsection hosting How Do Updates and Changes Get Published? + +Currently, the files underlying this documentation website are stored in an +bucket on AWS S3. The top-level bucket is <pre>s3://docs.hdfgroup.org/hdf5/</pre> +There are folders for the <tt>development</tt> branch and all supported release +version. + +Talk to your friendly IT-team if you need write access, or you need someone to +push an updated version for you! + +\todo Make the publication a GitHub action! */ diff --git a/doxygen/dox/FTS.dox b/doxygen/dox/FTS.dox new file mode 100644 index 0000000..9dae7c1 --- /dev/null +++ b/doxygen/dox/FTS.dox @@ -0,0 +1,8 @@ +/** \page FTS Full-Text Search + +\htmlonly +<script async src="https://cse.google.com/cse.js?cx=75c754173f9b90804"></script> +<div class="gcse-search"></div> +\endhtmlonly + +*/ \ No newline at end of file diff --git a/doxygen/dox/FileFormatSpec.dox b/doxygen/dox/FileFormatSpec.dox deleted file mode 100644 index fc10574..0000000 --- a/doxygen/dox/FileFormatSpec.dox +++ /dev/null @@ -1,23 +0,0 @@ -/** \page FMT3 HDF5 File Format Specification Version 3.0 - -\htmlinclude H5.format.html - -*/ - -/** \page FMT2 HDF5 File Format Specification Version 2.0 - -\htmlinclude H5.format.2.0.html - -*/ - -/** \page FMT11 HDF5 File Format Specification Version 1.1 - -\htmlinclude H5.format.1.1.html - -*/ - -/** \page FMT1 HDF5 File Format Specification Version 1.0 - -\htmlinclude H5.format.1.0.html - -*/ \ No newline at end of file diff --git a/doxygen/dox/OtherSpecs.dox b/doxygen/dox/OtherSpecs.dox deleted file mode 100644 index e53f26e..0000000 --- a/doxygen/dox/OtherSpecs.dox +++ /dev/null @@ -1,11 +0,0 @@ -/** \page IMG HDF5 Image and Palette Specification Version 1.2 - -\htmlinclude ImageSpec.html - -*/ - -/** \page TBL HDF5 Table Specification Version 1.0 - -\htmlinclude TableSpec.html - -*/ diff --git a/doxygen/dox/RFC.dox b/doxygen/dox/RFC.dox index c16dcea..c2562b0 100644 --- a/doxygen/dox/RFC.dox +++ b/doxygen/dox/RFC.dox @@ -3,10 +3,17 @@ <table> <tr><th>RFC ID</th><th>Title</th><th>Comments</th></tr> <tr> <td>2021-05-28</td> <td>\ref_rfc20210528</td> <td></td></tr> +<tr> <td>2021-02-19</td> <td>\ref_rfc20210219</td> <td></td></tr> +<tr> <td>2020-02-13</td> <td>\ref_rfc20200213</td> <td></td></tr> +<tr> <td>2020-02-10</td> <td>\ref_rfc20200210</td> <td></td></tr> <tr> <td>2019-09-23</td> <td>\ref_rfc20190923</td> <td></td></tr> +<tr> <td>2019-07-15</td> <td>\ref_rfc20190715</td> <td></td> </tr> <tr> <td>2019-04-10</td> <td>\ref_rfc20190410</td> <td></td> </tr> <tr> <td>2018-12-31</td> <td>\ref_rfc20181231</td> <td></td> </tr> <tr> <td>2018-12-20</td> <td>\ref_rfc20181220</td> <td></td> </tr> +<tr> <td>2018-08-30</td> <td>\ref_rfc20180830</td> <td></td> </tr> +<tr> <td>2018-08-29</td> <td>\ref_rfc20180829</td> <td></td> </tr> +<tr> <td>2018-08-15</td> <td>\ref_rfc20180815</td> <td></td> </tr> <tr> <td>2018-06-20</td> <td>\ref_rfc20180620</td> <td></td> </tr> <tr> <td>2018-06-10</td> <td>\ref_rfc20180610</td> <td></td> </tr> <tr> <td>2018-03-21</td> <td>\ref_rfc20180321</td> <td></td> </tr> @@ -69,8 +76,12 @@ <tr> <td>2009-09-07</td> <td>\ref_rfc20090907</td> <td></td> </tr> <tr> <td>2009-06-12</td> <td>\ref_rfc20090612</td> <td></td> </tr> <tr> <td>2008-12-18</td> <td>\ref_rfc20081218</td> <td></td> </tr> +<tr> <td>2008-12-05</td> <td>\ref_rfc20081205</td> <td></td> </tr> +<tr> <td>2008-10-30</td> <td>\ref_rfc20081030</td> <td></td> </tr> <tr> <td>2008-09-15</td> <td>\ref_rfc20080915</td> <td></td> </tr> <tr> <td>2008-09-04</td> <td>\ref_rfc20080904</td> <td></td> </tr> +<tr> <td>2008-07-28</td> <td>\ref_rfc20080728</td> <td></td> </tr> +<tr> <td>2008-07-23</td> <td>\ref_rfc20080723</td> <td></td> </tr> <tr> <td>2008-03-01</td> <td>\ref_rfc20080301</td> <td></td> </tr> <tr> <td>2008-02-09</td> <td>\ref_rfc20080209</td> <td></td> </tr> <tr> <td>2008-02-06</td> <td>\ref_rfc20080206</td> <td></td> </tr> diff --git a/doxygen/dox/Specifications.dox b/doxygen/dox/Specifications.dox index 4ae48d0..5a36d61 100644 --- a/doxygen/dox/Specifications.dox +++ b/doxygen/dox/Specifications.dox @@ -19,4 +19,40 @@ \li <a href="https://support.hdfgroup.org/HDF5/doc/HL/H5DS_Spec.pdf"> HDF5 Dimension Scale Specification</a> -*/ \ No newline at end of file +*/ + +/** \page FMT3 HDF5 File Format Specification Version 3.0 + +\htmlinclude H5.format.html + +*/ + +/** \page FMT2 HDF5 File Format Specification Version 2.0 + +\htmlinclude H5.format.2.0.html + +*/ + +/** \page FMT11 HDF5 File Format Specification Version 1.1 + +\htmlinclude H5.format.1.1.html + +*/ + +/** \page FMT1 HDF5 File Format Specification Version 1.0 + +\htmlinclude H5.format.1.0.html + +*/ + +/** \page IMG HDF5 Image and Palette Specification Version 1.2 + +\htmlinclude ImageSpec.html + +*/ + +/** \page TBL HDF5 Table Specification Version 1.0 + +\htmlinclude TableSpec.html + +*/ diff --git a/doxygen/dox/TechnicalNotes.dox b/doxygen/dox/TechnicalNotes.dox index 2bda175..9bd2802 100644 --- a/doxygen/dox/TechnicalNotes.dox +++ b/doxygen/dox/TechnicalNotes.dox @@ -1,6 +1,10 @@ /** \page TN Technical Notes \li \link api-compat-macros API Compatibility Macros \endlink +\li \ref APPDBG "Debugging HDF5 Applications" +\li \ref FMTDISC "File Format Walkthrough" +\li \ref FILTER "Filters" +\li \ref IOFLOW "HDF5 Raw I/O Flow Notes" \li \ref TNMDC "Metadata Caching in HDF5" \li \ref MT "Thread Safe library" \li \ref VFL "Virtual File Layer" @@ -13,8 +17,32 @@ */ +/** \page IOFLOW HDF5 Raw I/O Flow Notes + +\htmlinclude IOFlow.html + +*/ + /** \page VFL HDF5 Virtual File Layer \htmlinclude VFL.html */ + +/** \page FMTDISC HDF5 File Format Discussion + +\htmlinclude FileFormat.html + +*/ + +/** \page FILTER HDF5 Filters + +\htmlinclude Filters.html + +*/ + +/** \page APPDBG Debugging HDF5 Applications + +\htmlinclude DebuggingHDF5Applications.html + +*/ \ No newline at end of file diff --git a/doxygen/examples/DebuggingHDF5Applications.html b/doxygen/examples/DebuggingHDF5Applications.html new file mode 100644 index 0000000..c6aaf74 --- /dev/null +++ b/doxygen/examples/DebuggingHDF5Applications.html @@ -0,0 +1,392 @@ +<html> + <head> + <title>Debugging HDF5 Applications + +

Introduction

+ +

The HDF5 library contains a number of debugging features to + make programmers' lives easier including the ability to print + detailed error messages, check invariant conditions, display + timings and other statistics, and trace API function calls and + return values. + +

+
Error Messages +
Error messages are normally displayed automatically on the + standard error stream and include a stack trace of the library + including file names, line numbers, and function names. The + application has complete control over how error messages are + displayed and can disable the display on a permanent or + temporary basis. Refer to the documentation for the H5E error + handling package. + +

+
Invariant Conditions +
Unless NDEBUG is defined during compiling, the + library will include code to verify that invariant conditions + have the expected values. When a problem is detected the + library will display the file and line number within the + library and the invariant condition that failed. A core dump + may be generated for post mortem debugging. The code to + perform these checks can be included on a per-package bases. + +

+
Timings and Statistics +
The library can be configured to accumulate certain + statistics about things like cache performance, datatype + conversion, data space conversion, and data filters. The code + is included on a per-package basis and enabled at runtime by + an environment variable. + +

+
API Tracing +
All API calls made by an application can be displayed and + include formal argument names and actual values and the + function return value. This code is also conditionally + included at compile time and enabled at runtime. +
+ +

The statistics and tracing can be displayed on any output + stream (including streams opened by the shell) with output from + different packages even going to different streams. + +

Error Messages

+ +

By default any API function that fails will print an error + stack to the standard error stream. + +

+

+ + + + +
+


+HDF5-DIAG: Error detected in thread 0.  Back trace follows.
+  #000: H5F.c line 1245 in H5Fopen(): unable to open file
+    major(04): File interface
+    minor(10): Unable to open file
+  #001: H5F.c line 846 in H5F_open(): file does not exist
+    major(04): File interface
+    minor(10): Unable to open file
+	      
+
+
+ +

The error handling package (H5E) is described + elsewhere. + +

Invariant Conditions

+ +

To include checks for invariant conditions the library should + be configured with --disable-production, the + default for versions before 1.2. The library designers have made + every attempt to handle error conditions gracefully but an + invariant condition assertion may fail in certain cases. The + output from a failure usually looks something like this: + +

+

+ + + + +
+


+Assertion failed: H5.c:123: i<NELMTS(H5_debug_g)
+IOT Trap, core dumped.
+	      
+
+
+ +

Timings and Statistics

+ +

Code to accumulate statistics is included at compile time by + using the --enable-debug configure switch. The + switch can be followed by an equal sign and a comma-separated + list of package names or else a default list is used. + +

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDefaultDescription
aNoAttributes
acYesMeta data cache
bYesB-Trees
dYesDatasets
eYesError handling
fYesFiles
gYesGroups
hgYesGlobal heap
hlNoLocal heaps
iYesInterface abstraction
mfNoFile memory management
mmYesLibrary memory managment
oNoObject headers and messages
pYesProperty lists
sYesData spaces
tYesDatatypes
vYesVectors
zYesRaw data filters
+
+ +

In addition to including the code at compile time the + application must enable each package at runtime. This is done + by listing the package names in the HDF5_DEBUG + environment variable. That variable may also contain file + descriptor numbers (the default is `2') which control the output + for all following packages up to the next file number. The + word all refers to all packages. Any word my be + preceded by a minus sign to turn debugging off for the package. + +

+

+ + + + + + + + + + + + + + +
Sample debug specifications
allThis causes debugging output from all packages to be + sent to the standard error stream.
all -t -sDebugging output for all packages except datatypes + and data spaces will appear on the standard error + stream.
-all ac 255 t,sThis disables all debugging even if the default was to + debug something, then output from the meta data cache is + send to the standard error stream and output from data + types and spaces is sent to file descriptor 255 which + should be redirected by the shell.
+
+ +

The components of the HDF5_DEBUG value may be + separated by any non-lowercase letter. + +

API Tracing

+ +

The HDF5 library can trace API calls by printing the + function name, the argument names and their values, and the + return value. Some people like to see lots of output during + program execution instead of using a good symbolic debugger, and + this feature is intended for their consumption. For example, + the output from h5ls foo after turning on tracing, + includes: + +

+

+ + + + +
+
+H5Tcopy(type=184549388) = 184549419 (type);
+H5Tcopy(type=184549392) = 184549424 (type);
+H5Tlock(type=184549424) = SUCCEED;
+H5Tcopy(type=184549393) = 184549425 (type);
+H5Tlock(type=184549425) = SUCCEED;
+H5Fopen(filename="foo", flags=0, access=H5P_DEFAULT) = FAIL;
+HDF5-DIAG: Error detected in thread 0.  Back trace follows.
+  #000: H5F.c line 1245 in H5Fopen(): unable to open file
+    major(04): File interface
+    minor(10): Unable to open file
+  #001: H5F.c line 846 in H5F_open(): file does not exist
+    major(04): File interface
+    minor(10): Unable to open file
+	      
+
+
+ +

The code that performs the tracing must be included in the + library by specifying the --enable-trace + configuration switch (the default for versions before 1.2). Then + the word trace must appear in the value of the + HDF5_DEBUG variable. The output will appear on the + last file descriptor before the word trace or two + (standard error) by default. + +

+

+ + + + + + + +
To display the trace on the standard error stream: +
$ env HDF5_DEBUG=trace a.out
+	      
+
To send the trace to a file: +
$ env HDF5_DEBUG="55 trace" a.out 55>trace-output
+	      
+
+
+ +

Performance

+ +

If the library was not configured for tracing then there is no + unnecessary overhead since all tracing code is excluded. + However, if tracing is enabled but not used there is a small + penalty. First, code size is larger because of extra + statically-declared character strings used to store argument + types and names and extra auto variable pointer in each + function. Also, execution is slower because each function sets + and tests a local variable and each API function calls the + H5_trace() function. + +

If tracing is enabled and turned on then the penalties from the + previous paragraph apply plus the time required to format each + line of tracing information. There is also an extra call to + H5_trace() for each API function to print the return value. + +

Safety

+ +

The tracing mechanism is invoked for each API function before + arguments are checked for validity. If bad arguments are passed + to an API function it could result in a segmentation fault. + However, the tracing output is line-buffered so all previous + output will appear. + +

Completeness

+ +

There are two API functions that don't participate in + tracing. They are H5Eprint() and + H5Eprint_cb() because their participation would + mess up output during automatic error reporting. + +

On the other hand, a number of API functions are called during + library initialization and they print tracing information. + +

Implementation

+ +

For those interested in the implementation here is a + description. Each API function should have a call to one of the + H5TRACE() macros immediately after the + FUNC_ENTER() macro. The first argument is the + return type encoded as a string. The second argument is the + types of all the function arguments encoded as a string. The + remaining arguments are the function arguments. This macro was + designed to be as terse and unobtrousive as possible. + +

In order to keep the H5TRACE() calls synchronized + with the source code we've written a perl script which gets + called automatically just before Makefile dependencies are + calculated for the file. However, this only works when one is + using GNU make. To reinstrument the tracing explicitly, invoke + the trace program from the hdf5 bin directory with + the names of the source files that need to be updated. If any + file needs to be modified then a backup is created by appending + a tilde to the file name. + +

+

+ + + + + +
Explicit Instrumentation
+
+$ ../bin/trace *.c
+H5E.c: in function `H5Ewalk_cb':
+H5E.c:336: warning: trace info was not inserted
+	      
+
+
+ +

Note: The warning message is the result of a comment of the + form /*NO TRACE*/ somewhere in the function + body. Tracing information will not be updated or inserted if + such a comment exists. + +

Error messages have the same format as a compiler so that they + can be parsed from program development environments like + Emacs. Any function which generates an error will not be + modified.

+ + diff --git a/doxygen/examples/FileFormat.html b/doxygen/examples/FileFormat.html new file mode 100644 index 0000000..fc35357 --- /dev/null +++ b/doxygen/examples/FileFormat.html @@ -0,0 +1,1275 @@ + + + + HDF5 File Format Discussion + + + + + + + + + + +

HDF5 File Format Discussion

+

Quincey Koziol
+ koziol@ncsa.uiuc.edu
+ May 15, 2003 +

+ +
    + +
  1. Document's Audience:

    + +
      +
    • Current H5 library designers and knowledgable external developers.
    • +
    + +
  2. Background Reading:

    + +
    +
    HDF5 File Format Specification +
    This describes the current HDF5 file format. +
    + +
  3. Introduction:

    + +
    +
    What is this document about?
    +
    This document attempts to explain the HDF5 file format + specification with a few examples and describes some potential + improvements to the format specification. +

    +
    + +
  4. File Format Examples:

    + +

    This section has several small programs and describes the format of a file +created with each of them. +

    + +

    Example program one - Create an empty file: +

     
    +#include "hdf5.h"
    +#include 
    +
    +int main()
    +{
    +    hid_t fid;      /* File ID */
    +    herr_t ret;     /* Generic return value */
    +
    +    /* Create the file */
    +    fid=H5Fcreate("example1.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    +    assert(fid>=0);
    +
    +    /* Close the file */
    +    ret=H5Fclose(fid);
    +    assert(ret>=0);
    +
    +    return(0);
    +}
    + 
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Super Block +
    bytebytebytebyte
    \211'H''D''F'
    \r\n\032\n
    0000
    0880
    416
    0x00000003
    0

    0xffffffffffffffff

    ?

    0xffffffffffffffff

    + + + + + + + + + + + + + + + + + + + + +
    0

    928

    H5G_CACHED_STAB (1)
    0
    + + + + + + + +

    384


    96

    +
    +
    +
    +
    +
     
    +%h5debug example1.h5
    +
    +Reading signature at address 0 (rel)
    +File Super Block...
    +File name:                                         example1.h5
    +File access flags                                  0x00000000
    +File open reference count:                         1
    +Address of super block:                            0 (abs)
    +Size of user block:                                0 bytes
    +Super block version number:                        0
    +Free list version number:                          0
    +Root group symbol table entry version number:      0
    +Shared header version number:                      0
    +Size of file offsets (haddr_t type):               8 bytes
    +Size of file lengths (hsize_t type):               8 bytes
    +Symbol table leaf node 1/2 rank:                   4
    +Symbol table internal node 1/2 rank:               16
    +File consistency flags:                            0x00000003
    +Base address:                                      0 (abs)
    +Free list address:                                 UNDEF (rel)
    +Address of driver information block:               UNDEF (rel)
    +Root group symbol table entry:
    +   Name offset into private heap:                  0
    +   Object header address:                          928
    +   Dirty:                                          Yes
    +   Cache info type:                                Symbol Table
    +   Cached information:
    +      B-tree address:                              384
    +      Heap address:                                96
    + 
    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Root Group Object Header +
    bytebytebytebyte
    102
    1
    32
    0x001116
    0x010
    + + + + + + + +

    384


    96

    +
    00
    0x000
    +
    +
    +
     
    +%h5debug example1.h5 928
    +
    +New address: 928
    +Reading signature at address 928 (rel)
    +Object Header...
    +Dirty:                                             0
    +Version:                                           1
    +Header size (in bytes):                            16
    +Number of links:                                   1
    +Number of messages (allocated):                    2 (32)
    +Number of chunks (allocated):                      1 (8)
    +Chunk 0...
    +   Dirty:                                          0
    +   Address:                                        944
    +   Size in bytes:                                  32
    +Message 0...
    +   Message ID (sequence number):                   0x0011 stab(0)
    +   Shared message:                                 No
    +   Constant:                                       Yes
    +   Raw size in obj header:                         16 bytes
    +   Chunk number:                                   0
    +   Message Information:
    +      B-tree address:                              384
    +      Name heap address:                           96
    +Message 1...
    +   Message ID (sequence number):                   0x0000 null(0)
    +   Shared message:                                 No
    +   Constant:                                       No
    +   Raw size in obj header:                         0 bytes
    +   Chunk number:                                   0
    +   Message Information:
    +      
    + 
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Root Group Local Heap +
    bytebytebytebyte
    'H''E''A''P'
    0
    256
    8
    128
    +
    +
    + +
     
    +%h5debug example1.h5 96
    +
    +New address: 96
    +Reading signature at address 96 (rel)
    +Local Heap...
    +Dirty:                                             0
    +Header size (in bytes):                            32
    +Address of heap data:                              128
    +Data bytes allocated on disk:                      256
    +Data bytes allocated in core:                      256
    +Free Blocks (offset, size):
    +   Block #0:                                        8,      248
    +Percent of heap used:                              3.12%
    +Data follows (`__' indicates free region)...
    +     0: 00 00 00 00 00 00 00 00  __ __ __ __ __ __ __ __ ........
    +    16: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +    32: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +    48: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +    64: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +    80: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +    96: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +   112: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +   128: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +   144: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +   160: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +   176: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +   192: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +   208: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +   224: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +   240: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +
    + 
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Root Group B-tree +
    bytebytebytebyte
    'T''R''E''E'
    000

    0xffffffffffffffff


    0xffffffffffffffff

    +
    +
    +
     
    +%h5debug example1.h5 384 96
    +
    +New address: 384
    +Reading signature at address 384 (rel)
    +Tree type ID:                                      H5B_SNODE_ID
    +Size of node:                                      544
    +Size of raw (disk) key:                            8
    +Dirty flag:                                        False
    +Number of initial dirty children:                  0
    +Level:                                             0
    +Address of left sibling:                           UNDEF
    +Address of right sibling:                          UNDEF
    +Number of children (max):                          0 (32)
    +
    + 
    + +

    + +

    Example program two - Create a file with a single dataset in it: +

     
    +#include "hdf5.h"
    +#include 
    +
    +int main()
    +{
    +    hid_t fid;      /* File ID */
    +    hid_t sid;      /* Dataspace ID */
    +    hid_t did;      /* Dataset ID */
    +    herr_t ret;     /* Generic return value */
    +
    +    /* Create the file */
    +    fid=H5Fcreate("example2.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    +    assert(fid>=0);
    +
    +    /* Create a scalar dataspace for the dataset */
    +    sid=H5Screate(H5S_SCALAR);
    +    assert(sid>=0);
    +
    +    /* Create a trivial dataset */
    +    did=H5Dcreate(fid, "Dataset", H5T_NATIVE_INT, sid, H5P_DEFAULT);
    +    assert(did>=0);
    +
    +    /* Close the dataset */
    +    ret=H5Dclose(did);
    +    assert(ret>=0);
    +
    +    /* Close the dataspace */
    +    ret=H5Sclose(sid);
    +    assert(ret>=0);
    +
    +    /* Close the file */
    +    ret=H5Fclose(fid);
    +    assert(ret>=0);
    +
    +    return(0);
    +}
    + 
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Super Block +
    bytebytebytebyte
    \211'H''D''F'
    \r\n\032\n
    0000
    0880
    416
    0x00000003
    0

    0xffffffffffffffff

    ?

    0xffffffffffffffff

    + + + + + + + + + + + + + + + + + + + + +
    0

    928

    H5G_CACHED_STAB (1)
    0
    + + + + + + + +

    384


    96

    +
    +
    +
    +
    +
     
    +%h5debug example2.h5
    +
    +Reading signature at address 0 (rel)
    +File Super Block...
    +File name:                                         example2.h5
    +File access flags                                  0x00000000
    +File open reference count:                         1
    +Address of super block:                            0 (abs)
    +Size of user block:                                0 bytes
    +Super block version number:                        0
    +Free list version number:                          0
    +Root group symbol table entry version number:      0
    +Shared header version number:                      0
    +Size of file offsets (haddr_t type):               8 bytes
    +Size of file lengths (hsize_t type):               8 bytes
    +Symbol table leaf node 1/2 rank:                   4
    +Symbol table internal node 1/2 rank:               16
    +File consistency flags:                            0x00000003
    +Base address:                                      0 (abs)
    +Free list address:                                 UNDEF (rel)
    +Address of driver information block:               UNDEF (rel)
    +Root group symbol table entry:
    +   Name offset into private heap:                  0
    +   Object header address:                          928
    +   Dirty:                                          Yes
    +   Cache info type:                                Symbol Table
    +   Cached entry information:
    +      B-tree address:                              384
    +      Heap address:                                96
    + 
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Root Group Object Header +
    bytebytebytebyte
    102
    1
    32
    0x001116
    0x010
    + + + + + + + +

    384


    96

    +
    00
    0x000
    +
    +
    +
     
    +%h5debug example2.h5 928
    +
    +New address: 928
    +Reading signature at address 928 (rel)
    +Object Header...
    +Dirty:                                             0
    +Version:                                           1
    +Header size (in bytes):                            16
    +Number of links:                                   1
    +Number of messages (allocated):                    2 (32)
    +Number of chunks (allocated):                      1 (8)
    +Chunk 0...
    +   Dirty:                                          0
    +   Address:                                        944
    +   Size in bytes:                                  32
    +Message 0...
    +   Message ID:                                     0x0011 stab(0)
    +   Shared message:                                 No
    +   Constant:                                       Yes
    +   Raw size in obj header:                         16 bytes
    +   Chunk number:                                   0
    +   Message Information:
    +      B-tree address:                              384
    +      Name heap address:                           96
    +Message 1...
    +   Message ID:                                     0x0000 null(0)
    +   Shared message:                                 No
    +   Constant:                                       No
    +   Raw size in obj header:                         0 bytes
    +   Chunk number:                                   0
    +   Message Information:
    +      
    + 
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Root Group Local Heap +
    bytebytebytebyte
    'H''E''A''P'
    0
    256
    16
    128
    +
    +
    + +
     
    +%h5debug example2.h5 96
    +
    +New address: 96
    +Reading signature at address 96 (rel)
    +Local Heap...
    +Dirty:                                             0
    +Header size (in bytes):                            32
    +Address of heap data:                              128
    +Data bytes allocated on disk:                      256
    +Data bytes allocated in core:                      256
    +Free Blocks (offset, size):
    +   Block #0:                                       16,      240
    +Percent of heap used:                              6.25%
    +Data follows (`__' indicates free region)...
    +      0: 00 00 00 00 00 00 00 00  44 61 74 61 73 65 74 00 ........Dataset.
    +     16: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +     32: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +     48: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +     64: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +     80: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +     96: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +    112: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +    128: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +    144: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +    160: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +    176: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +    192: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +    208: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +    224: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    +    240: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    + 
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Root Group B-tree +
    bytebytebytebyte
    'T''R''E''E'
    001

    0xffffffffffffffff


    0xffffffffffffffff


    0


    1248


    8

    +
    +
    +
     
    +%h5debug example2.h5 384 96
    +
    +New address: 384
    +Reading signature at address 384 (rel)
    +Tree type ID:                                      H5B_SNODE_ID
    +Size of node:                                      544
    +Size of raw (disk) key:                            8
    +Dirty flag:                                        False
    +Number of initial dirty children:                  0
    +Level:                                             0
    +Address of left sibling:                           UNDEF
    +Address of right sibling:                          UNDEF
    +Number of children (max):                          1 (32)
    +Child 0...
    +   Address:                                        1248
    +   Left Key:
    +      Heap offset:                                 0
    +      Name :
    +   Right Key:
    +      Heap offset:                                 8
    +      Name :                                       Dataset
    + 
    + +
    + + + + + + + + + + + + + + + + + + + + + + + +
    + Root Group B-tree Symbol Table Node +
    bytebytebytebyte
    'S''N''O''D'
    101
    + + + + + + + + + + + + + + + + + + + + +
    8

    976

    0
    0


    0


    +
    +
    +
    +
     
    +%h5debug example2.h5 1248 96
    +
    +New address: 1248
    +Reading signature at address 1248 (rel)
    +Symbol Table Node...
    +Dirty:                                             No
    +Size of Node (in bytes):                           328
    +Number of Symbols:                                 1 of 8
    +Symbol 0:
    +   Name:                                           `Dataset'
    +   Name offset into private heap:                  8
    +   Object header address:                          976
    +   Dirty:                                          No
    +   Cache info type:                                Nothing Cached
    + 
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + '/Dataset' Object Header +
    bytebytebytebyte
    Version: 1Reserved: 0Number of Header Messages: 6
    Object Reference Count: 1
    Total Object Header Size: 256
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Fill Value Header Message +
    Message Type: 0x0005Message Data Size: 8
    Flags: 0x01Reserved: 0
    Version: 1Space Allocation Time: 2 (Late)Fill Value Writing Time: 0 (At allocation)Fill Value Defined: 0 (Undefined)
    Fill Value Datatype Size: 0 (Use dataset's datatype for fill-value datatype)
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Datatype Header Message +
    Message Type: 0x0003Message Data Size: 16
    Flags: 0x01Reserved: 0
    + + + + + +
    Version: 0x1Class: 0x0 (Fixed-Point)
    +
    Fixed-Point Bit-Field: 0x08 (Little-endian, No padding, Signed)
    Size: 4
    Bit Offset: 0Bit Precision: 32
    Message Alignment Filler: -
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Dataspace Header Message +
    Message Type: 0x0001Message Data Size: 8
    Flags: 0x00Reserved: 0
    Version: 1Rank: 0 (Scalar)Flags: 0x00 (No maximum dimensions, no permutation information)Reserved: 0
    Reserved: 0
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Layout Header Message +
    Message Type: 0x0008Message Data Size: 24
    Flags: 0x00Reserved: 0
    Version: 1Rank: 1 (Dataspace rank+1)Class: 1 (Contiguous)Reserved: 0
    Reserved: 0

    Address: 0xffffffffffffffff (Undefined)

    Dimension 0 Size: 4 (Datatype size)
    Message Alignment Filler: -
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Modification Date & Time Header Message +
    Message Type: 0x0012Message Data Size: 8
    Flags: 0x00Reserved: 0
    Version: 1Reserved: 0
    Seconds Since Epoch: 1052401700 (2003-05-08 08:48:20 CDT)
    +
    + + + + + + + + + + + + + + + + + +
    + Null Header Message +
    Message Type: 0x0000Message Data Size: 144
    Flags: 0x00Reserved: 0
    +
    +
    +
    +
     
    +%h5debug example2.h5 976
    +
    +New address: 976
    +Reading signature at address 976 (rel)
    +Object Header...
    +Dirty:                                             0
    +Version:                                           1
    +Header size (in bytes):                            16
    +Number of links:                                   1
    +Number of messages (allocated):                    6 (32)
    +Number of chunks (allocated):                      1 (8)
    +Chunk 0...
    +   Dirty:                                          0
    +   Address:                                        992
    +   Size in bytes:                                  256
    +Message 0...
    +   Message ID (sequence number):                   0x0005 `fill_new' (0)
    +   Shared:                                         No
    +   Constant:                                       Yes
    +   Raw size in obj header:                         8 bytes
    +   Chunk number:                                   0
    +   Message Information:
    +      Version:                                     1
    +      Space Allocation Time:                       Late
    +      Fill Time:                                   On Allocation
    +      Fill Value Defined:                          Undefined
    +      Size:                                        0
    +      Data type:                                   
    +Message 1...
    +   Message ID (sequence number):                   0x0003 data_type(0)
    +   Shared message:                                 No
    +   Constant:                                       Yes
    +   Raw size in obj header:                         16 bytes
    +   Chunk number:                                   0
    +   Message Information:
    +      Type class:                                  integer
    +      Size:                                        4 bytes
    +      Byte order:                                  little endian
    +      Precision:                                   32 bits
    +      Offset:                                      0 bits
    +      Low pad type:                                zero
    +      High pad type:                               zero
    +      Sign scheme:                                 2's comp
    +Message 2...
    +   Message ID (sequence number):                   0x0001 simple_dspace(0)
    +   Shared message:                                 No
    +   Constant:                                       No
    +   Raw size in obj header:                         8 bytes
    +   Chunk number:                                   0
    +   Message Information:
    +      Rank:                                        0
    +Message 3...
    +   Message ID (sequence number):                   0x0008 layout(0)
    +   Shared message:                                 No
    +   Constant:                                       No
    +   Raw size in obj header:                         24 bytes
    +   Chunk number:                                   0
    +   Message Information:
    +      Data address:                                UNDEF
    +      Number of dimensions:                        1
    +      Size:                                        {4}
    +Message 4...
    +   Message ID (sequence number):                   0x0012 mtime_new(0)
    +   Shared message:                                 No
    +   Constant:                                       No
    +   Raw size in obj header:                         8 bytes
    +   Chunk number:                                   0
    +   Message Information:
    +      Time:                                        2003-03-05 14:52:00 CST
    +Message 5...
    +   Message ID (sequence number):                   0x0000 null(0)
    +   Shared message:                                 No
    +   Constant:                                       No
    +   Raw size in obj header:                         144 bytes
    +   Chunk number:                                   0
    +   Message Information:
    +      
    + 
    + +

    + +
+ + + + diff --git a/doxygen/examples/Filters.html b/doxygen/examples/Filters.html new file mode 100644 index 0000000..2d5bc5e --- /dev/null +++ b/doxygen/examples/Filters.html @@ -0,0 +1,450 @@ + + + Filters +

Filters in HDF5

+ + Note: Transient pipelines described in this document have not + been implemented. + +

Introduction

+ +

HDF5 allows chunked data to pass through user-defined filters + on the way to or from disk. The filters operate on chunks of an + H5D_CHUNKED dataset can be arranged in a pipeline + so output of one filter becomes the input of the next filter. + +

Each filter has a two-byte identification number (type + H5Z_filter_t) allocated by The HDF Group and can also be + passed application-defined integer resources to control its + behavior. Each filter also has an optional ASCII comment + string. + +

+ + + + + + + + + + + + + + + + + + + +
Values for H5Z_filter_tDescription
0-255These values are reserved for filters predefined and + registered by the HDF5 library and of use to the general + public. They are described in a separate section + below.
256-511Filter numbers in this range are used for testing only + and can be used temporarily by any organization. No + attempt is made to resolve numbering conflicts since all + definitions are by nature temporary.
512-65535Reserved for future assignment. Please contact the + HDF5 development team + to reserve a value or range of values for + use by your filters.
+ +

Defining and Querying the Filter Pipeline

+ +

Two types of filters can be applied to raw data I/O: permanent + filters and transient filters. The permanent filter pipeline is + defned when the dataset is created while the transient pipeline + is defined for each I/O operation. During an + H5Dwrite() the transient filters are applied first + in the order defined and then the permanent filters are applied + in the order defined. For an H5Dread() the + opposite order is used: permanent filters in reverse order, then + transient filters in reverse order. An H5Dread() + must result in the same amount of data for a chunk as the + original H5Dwrite(). + +

The permanent filter pipeline is defined by calling + H5Pset_filter() for a dataset creation property + list while the transient filter pipeline is defined by calling + that function for a dataset transfer property list. + +

+
herr_t H5Pset_filter (hid_t plist, + H5Z_filter_t filter, unsigned int flags, + size_t cd_nelmts, const unsigned int + cd_values[]) +
This function adds the specified filter and + corresponding properties to the end of the transient or + permanent output filter pipeline (depending on whether + plist is a dataset creation or dataset transfer + property list). The flags argument specifies certain + general properties of the filter and is documented below. The + cd_values is an array of cd_nelmts integers + which are auxiliary data for the filter. The integer values + will be stored in the dataset object header as part of the + filter information. +
int H5Pget_nfilters (hid_t plist) +
This function returns the number of filters defined in the + permanent or transient filter pipeline depending on whether + plist is a dataset creation or dataset transfer + property list. In each pipeline the filters are numbered from + 0 through N-1 where N is the value returned + by this function. During output to the file the filters of a + pipeline are applied in increasing order (the inverse is true + for input). Zero is returned if there are no filters in the + pipeline and a negative value is returned for errors. +
H5Z_filter_t H5Pget_filter (hid_t plist, + int filter_number, unsigned int *flags, + size_t *cd_nelmts, unsigned int + *cd_values, size_t namelen, char name[]) +
This is the query counterpart of + H5Pset_filter() and returns information about a + particular filter number in a permanent or transient pipeline + depending on whether plist is a dataset creation or + dataset transfer property list. On input, cd_nelmts + indicates the number of entries in the cd_values + array allocated by the caller while on exit it contains the + number of values defined by the filter. The + filter_number should be a value between zero and + N-1 as described for H5Pget_nfilters() + and the function will return failure (a negative value) if the + filter number is out of range. If name is a pointer + to an array of at least namelen bytes then the filter + name will be copied into that array. The name will be null + terminated if the namelen is large enough. The + filter name returned will be the name appearing in the file or + else the name registered for the filter or else an empty string. +
+ +

The flags argument to the functions above is a bit vector of + the following fields: + +

+ + + + + + + + + + +
Values for flagsDescription
H5Z_FLAG_OPTIONALIf this bit is set then the filter is optional. If + the filter fails (see below) during an + H5Dwrite() operation then the filter is + just excluded from the pipeline for the chunk for which + it failed; the filter will not participate in the + pipeline during an H5Dread() of the chunk. + This is commonly used for compression filters: if the + compression result would be larger than the input then + the compression filter returns failure and the + uncompressed data is stored in the file. If this bit is + clear and a filter fails then the + H5Dwrite() or H5Dread() also + fails.
+ +

Defining Filters

+ +

Each filter is bidirectional, handling both input and output to + the file, and a flag is passed to the filter to indicate the + direction. In either case the filter reads a chunk of data from + a buffer, usually performs some sort of transformation on the + data, places the result in the same or new buffer, and returns + the buffer pointer and size to the caller. If something goes + wrong the filter should return zero to indicate a failure. + +

During output, a filter that fails or isn't defined and is + marked as optional is silently excluded from the pipeline and + will not be used when reading that chunk of data. A required + filter that fails or isn't defined causes the entire output + operation to fail. During input, any filter that has not been + excluded from the pipeline during output and fails or is not + defined will cause the entire input operation to fail. + +

Filters are defined in two phases. The first phase is to + define a function to act as the filter and link the function + into the application. The second phase is to register the + function, associating the function with an + H5Z_filter_t identification number and a comment. + +

+
typedef size_t (*H5Z_func_t)(unsigned int + flags, size_t cd_nelmts, const unsigned int + cd_values[], size_t nbytes, size_t + *buf_size, void **buf) +
The flags, cd_nelmts, and + cd_values are the same as for the + H5Pset_filter() function with the additional flag + H5Z_FLAG_REVERSE which is set when the filter is + called as part of the input pipeline. The input buffer is + pointed to by *buf and has a total size of + *buf_size bytes but only nbytes are valid + data. The filter should perform the transformation in place if + possible and return the number of valid bytes or zero for + failure. If the transformation cannot be done in place then + the filter should allocate a new buffer with + malloc() and assign it to *buf, + assigning the allocated size of that buffer to + *buf_size. The old buffer should be freed + by calling free(). + +

+
herr_t H5Zregister (H5Z_filter_t filter_id, + const char *comment, H5Z_func_t + filter) +
The filter function is associated with a filter + number and a short ASCII comment which will be stored in the + hdf5 file if the filter is used as part of a permanent + pipeline during dataset creation. +
+ +

Predefined Filters

+ +

If zlib version 1.1.2 or later was found + during configuration then the library will define a filter whose + H5Z_filter_t number is + H5Z_FILTER_DEFLATE. Since this compression method + has the potential for generating compressed data which is larger + than the original, the H5Z_FLAG_OPTIONAL flag + should be turned on so such cases can be handled gracefully by + storing the original data instead of the compressed data. The + cd_nvalues should be one with cd_value[0] + being a compression agression level between zero and nine, + inclusive (zero is the fastest compression while nine results in + the best compression ratio). + +

A convenience function for adding the + H5Z_FILTER_DEFLATE filter to a pipeline is: + +

+
herr_t H5Pset_deflate (hid_t plist, unsigned + aggression) +
The deflate compression method is added to the end of the + permanent or transient filter pipeline depending on whether + plist is a dataset creation or dataset transfer + property list. The aggression is a number between + zero and nine (inclusive) to indicate the tradeoff between + speed and compression ratio (zero is fastest, nine is best + ratio). +
+ +

Even if the zlib isn't detected during + configuration the application can define + H5Z_FILTER_DEFLATE as a permanent filter. If the + filter is marked as optional (as with + H5Pset_deflate()) then it will always fail and be + automatically removed from the pipeline. Applications that read + data will fail only if the data is actually compressed; they + won't fail if H5Z_FILTER_DEFLATE was part of the + permanent output pipeline but was automatically excluded because + it didn't exist when the data was written. + +

zlib can be acquired from + + http://www.cdrom.com/pub/infozip/zlib/. + +

Example

+ +

This example shows how to define and register a simple filter + that adds a checksum capability to the data stream. + +

The function that acts as the filter always returns zero + (failure) if the md5() function was not detected at + configuration time (left as an excercise for the reader). + Otherwise the function is broken down to an input and output + half. The output half calculates a checksum, increases the size + of the output buffer if necessary, and appends the checksum to + the end of the buffer. The input half calculates the checksum + on the first part of the buffer and compares it to the checksum + already stored at the end of the buffer. If the two differ then + zero (failure) is returned, otherwise the buffer size is reduced + to exclude the checksum. + +

+ + + + +
+


+                  size_t
+                  md5_filter(unsigned int flags, size_t cd_nelmts,
+                  const unsigned int cd_values[], size_t nbytes,
+                  size_t *buf_size, void **buf)
+                  {
+                  #ifdef HAVE_MD5
+                  unsigned char       cksum[16];
+
+                  if (flags & H5Z_REVERSE) {
+                  /* Input */
+                  assert(nbytes>=16);
+                  md5(nbytes-16, *buf, cksum);
+
+                  /* Compare */
+                  if (memcmp(cksum, (char*)(*buf)+nbytes-16, 16)) {
+                  return 0; /*fail*/
+                  }
+
+                  /* Strip off checksum */
+                  return nbytes-16;
+
+                  } else {
+                  /* Output */
+                  md5(nbytes, *buf, cksum);
+
+                  /* Increase buffer size if necessary */
+                  if (nbytes+16>*buf_size) {
+                  *buf_size = nbytes + 16;
+                  *buf = realloc(*buf, *buf_size);
+                  }
+
+                  /* Append checksum */
+                  memcpy((char*)(*buf)+nbytes, cksum, 16);
+                  return nbytes+16;
+                  }
+                  #else
+                  return 0; /*fail*/
+                  #endif
+                  }
+	          
+
+ +

Once the filter function is defined it must be registered so + the HDF5 library knows about it. Since we're testing this + filter we choose one of the H5Z_filter_t numbers + from the reserved range. We'll randomly choose 305. + +

+

+ + + + +
+


+                  #define FILTER_MD5 305
+                  herr_t status = H5Zregister(FILTER_MD5, "md5 checksum", md5_filter);
+	          
+
+ +

Now we can use the filter in a pipeline. We could have added + the filter to the pipeline before defining or registering the + filter as long as the filter was defined and registered by time + we tried to use it (if the filter is marked as optional then we + could have used it without defining it and the library would + have automatically removed it from the pipeline for each chunk + written before the filter was defined and registered). + +

+

+ + + + +
+


+                  hid_t dcpl = H5Pcreate(H5P_DATASET_CREATE);
+                  hsize_t chunk_size[3] = {10,10,10};
+                  H5Pset_chunk(dcpl, 3, chunk_size);
+                  H5Pset_filter(dcpl, FILTER_MD5, 0, 0, NULL);
+                  hid_t dset = H5Dcreate(file, "dset", H5T_NATIVE_DOUBLE, space, dcpl);
+	          
+
+ +

6. Filter Diagnostics

+ +

If the library is compiled with debugging turned on for the H5Z + layer (usually as a result of configure + --enable-debug=z) then filter statistics are printed when + the application exits normally or the library is closed. The + statistics are written to the standard error stream and include + two lines for each filter that was used: one for input and one + for output. The following fields are displayed: + +

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field NameDescription
MethodThis is the name of the method as defined with + H5Zregister() with the charaters + "< or ">" prepended to indicate + input or output.
TotalThe total number of bytes processed by the filter + including errors. This is the maximum of the + nbytes argument or the return value. +
ErrorsThis field shows the number of bytes of the Total + column which can be attributed to errors.
User, System, ElapsedThese are the amount of user time, system time, and + elapsed time in seconds spent in the filter function. + Elapsed time is sensitive to system load. These times + may be zero on operating systems that don't support the + required operations.
BandwidthThis is the filter bandwidth which is the total + number of bytes processed divided by elapsed time. + Since elapsed time is subject to system load the + bandwidth numbers cannot always be trusted. + Furthermore, the bandwidth includes bytes attributed to + errors which may significanly taint the value if the + function is able to detect errors without much + expense.
+ +

+

+ + + + + +
+ Example: Filter Statistics +
+

H5Z: filter statistics accumulated ov=
+                  er life of library:
+                  Method     Total  Errors  User  System  Elapsed Bandwidth
+                  ------     -----  ------  ----  ------  ------- ---------
+                  >deflate  160000   40000  0.62    0.74     1.33 117.5 kBs
+                  <deflate  120000       0  0.11    0.00     0.12 1.000 MBs
+	          
+
+ +
+ + +

Footnote 1: Dataset chunks can be compressed + through the use of filters. Developers should be aware that + reading and rewriting compressed chunked data can result in holes + in an HDF5 file. In time, enough such holes can increase the + file size enough to impair application or library performance + when working with that file. See + + Freespace Management + in the chapter + + Performance Analysis and Issues.

+ diff --git a/doxygen/examples/IOFlow.html b/doxygen/examples/IOFlow.html new file mode 100644 index 0000000..6b2c27e --- /dev/null +++ b/doxygen/examples/IOFlow.html @@ -0,0 +1,137 @@ + + + + HDF5 Raw I/O Flow Notes + + + + + + + + +

HDF5 Raw I/O Flow Notes

+

Quincey Koziol
+ koziol@ncsa.uiuc.edu
+ August 20, 2003 +

+ +
    + +
  1. Document's Audience:

    + +
      +
    • Current H5 library designers and knowledgable external developers.
    • +
    + +
  2. Background Reading:

    + +
  3. Introduction:

    + +
    +
    What is this document about?
    +
    This document attempts to supplement the flow charts describing + the flow of control for raw data I/O in the library. +

    +
    + +
  4. Figures:

    +

    The following figures provide the main information:

    + + + + +
    High-Level View of Writing Raw Data
    Perform Serial or Parallel I/O
    Gather/Convert/Scatter
    + +
  5. Notes From Accompanying Figures:

    + +

    This section provides notes to augment the information in the accompanying + figures. +

    + +
      +
    1. Validate Parameters - Resolve any H5S_ALL parameters + for dataspace selections to actual dataspaces, allocate + conversion buffers, etc. +
    2. + +
    3. Space Allocated in File? - Space may not have been allocated + in the file to store the dataset data, if "late allocation" was chosen + for the allocation time when the dataset was created. +
    4. + +
    5. Allocate & Fill Space - These operations allocate both contiguous + and chunked dataset's space in the file. The chunked dataset space + allocation iterates through all the chunks in the file and allocates + both the B-tree information and the raw data in the file. Because of + the way filters work, fill-values are written out for chunked datasets + as they are allocated, instead of as a separate step. + In parallel + I/O, the chunked dataset allocation can potentially be time-consuming, + since all the raw data in the dataset is allocated from one process. +
    6. + +
    7. Datatype Conversion Needed? - This currently is the deciding + factor between doing "direct I/O" (in serial or parallel) and needing + to perform gather/convert/scatter operations. I believe that MPI + is capable of performing a limited range of type conversions and if so, + we should add support to detect when they can be used. This will + allow more I/O operations to be performed collectively. +
    8. + +
    9. Collective I/O Requested/Allowed? - A user has to both request + that collective I/O occur and also their I/O operation must meet the + requirements that the library sets for supporting collective parallel + I/O: +
        +
      • The dataspace must be scalar or simple (which is a no-op really, + since we don't support "complex" dataspaces in the library + currently). +
      • +
      • The selection must be regular. "all" selections + and hyperslab selections that were + made with only one call to H5Sselect_hyperslab() (i.e. not a + hyperslab selection that has been aggregated over multiple + selection calls) are regular. Supporting point and + irregular hyperslab selections are on the "to do" list. +
      • +
      • The dataset must be stored contiguously on disk (as shown in the + figure also). Supporting chunked dataset storage is also + on the "to do" list. +
      • +
      +
    10. + +
    11. Build "chunk map" - This step still has some scalability issues + as it creates a data structure that is proportional to the number of + chunks which will be written to, which could potentially be very large. + Building the "chunk map" information incrementally is on the "to do" + list also. +
    12. + +
    13. Perform Chunked I/O - As the figure shows, there is no support + for collective parallel I/O on chunked datasets currently. As noted + earlier, this is on the "to do" list. +
    14. + +
    15. Perform "Direct" Serial I/O - "Direct" serial I/O writes data + from the application's buffer, without any intervening buffer or memory + copies. For maximum efficiency and performance, the elements in the + selections should be adjoining. +
    16. + +
    17. Perform Collective Parallel I/O - This step also writes data + directly from an application buffer, but additionally uses collective + MPI I/O operations to combine the data from each process in the parallel + application in an efficient manner. +
    18. +
    + +
+ + + + diff --git a/doxygen/hdf5doxy_layout.xml b/doxygen/hdf5doxy_layout.xml index fc20aa1..6efa690 100644 --- a/doxygen/hdf5doxy_layout.xml +++ b/doxygen/hdf5doxy_layout.xml @@ -12,6 +12,7 @@ + diff --git a/doxygen/img/IOFlow.gif b/doxygen/img/IOFlow.gif new file mode 100644 index 0000000..3e79030 Binary files /dev/null and b/doxygen/img/IOFlow.gif differ diff --git a/doxygen/img/IOFlow2.gif b/doxygen/img/IOFlow2.gif new file mode 100644 index 0000000..c75ca79 Binary files /dev/null and b/doxygen/img/IOFlow2.gif differ diff --git a/doxygen/img/IOFlow3.gif b/doxygen/img/IOFlow3.gif new file mode 100644 index 0000000..316cd1e Binary files /dev/null and b/doxygen/img/IOFlow3.gif differ diff --git a/fortran/src/H5_f.c b/fortran/src/H5_f.c index d245cae..0277e5c 100644 --- a/fortran/src/H5_f.c +++ b/fortran/src/H5_f.c @@ -118,24 +118,20 @@ h5init_types_c(hid_t_f *types, hid_t_f *floatingtypes, hid_t_f *integertypes) if ((types[6] = (hid_t_f)H5Tcopy(H5T_NATIVE_DOUBLE)) < 0) return ret_value; } /* end if */ -#if H5_SIZEOF_LONG_DOUBLE != 0 else if (sizeof(real_f) == sizeof(long double)) { if ((types[6] = (hid_t_f)H5Tcopy(H5T_NATIVE_LDOUBLE)) < 0) return ret_value; } /* end else */ -#endif /* Find appropriate size to store Fortran DOUBLE */ if (sizeof(double_f) == sizeof(double)) { if ((types[7] = (hid_t_f)H5Tcopy(H5T_NATIVE_DOUBLE)) < 0) return ret_value; } /*end if */ -#if H5_SIZEOF_LONG_DOUBLE != 0 else if (sizeof(double_f) == sizeof(long double)) { if ((types[7] = (hid_t_f)H5Tcopy(H5T_NATIVE_LDOUBLE)) < 0) return ret_value; } /*end else */ -#endif #ifdef H5_HAVE_FLOAT128 else if (sizeof(double_f) == sizeof(__float128)) { if ((types[7] = H5Tcopy(H5T_NATIVE_FLOAT)) < 0) @@ -169,12 +165,10 @@ h5init_types_c(hid_t_f *types, hid_t_f *floatingtypes, hid_t_f *integertypes) if ((types[11] = (hid_t_f)H5Tcopy(H5T_NATIVE_DOUBLE)) < 0) return ret_value; } /*end if */ -#if H5_SIZEOF_LONG_DOUBLE != 0 else if (sizeof(real_C_FLOAT_f) == sizeof(long double)) { if ((types[11] = (hid_t_f)H5Tcopy(H5T_NATIVE_LDOUBLE)) < 0) return ret_value; } /*end else */ -#endif /* * FIND H5T_NATIVE_REAL_C_DOUBLE */ @@ -186,12 +180,10 @@ h5init_types_c(hid_t_f *types, hid_t_f *floatingtypes, hid_t_f *integertypes) if ((types[12] = (hid_t_f)H5Tcopy(H5T_NATIVE_DOUBLE)) < 0) return ret_value; } /*end if */ -#if H5_SIZEOF_LONG_DOUBLE != 0 else if (sizeof(real_C_DOUBLE_f) == sizeof(long double)) { if ((types[12] = (hid_t_f)H5Tcopy(H5T_NATIVE_LDOUBLE)) < 0) return ret_value; } /*end else */ -#endif /* * FIND H5T_NATIVE_REAL_C_LONG_DOUBLE */ diff --git a/fortran/test/tH5A.F90 b/fortran/test/tH5A.F90 index 4d56bed..d5ce9a2 100644 --- a/fortran/test/tH5A.F90 +++ b/fortran/test/tH5A.F90 @@ -408,13 +408,13 @@ CONTAINS !open the INTEGER attrbute by name ! CALL h5aopen_name_f(dset_id, aname5, attr5_id, error) - CALL check("h5aopen_idx_f",error,total_error) + CALL check("h5aopen_name_f",error,total_error) ! !open the NULL attrbute by name ! CALL h5aopen_name_f(dset_id, aname6, attr6_id, error) - CALL check("h5aopen_idx_f",error,total_error) + CALL check("h5aopen_name_f",error,total_error) ! !get the attrbute name diff --git a/hl/CMakeLists.txt b/hl/CMakeLists.txt index 5061c6c..9391231 100644 --- a/hl/CMakeLists.txt +++ b/hl/CMakeLists.txt @@ -2,6 +2,14 @@ cmake_minimum_required (VERSION 3.12) project (HDF5_HL C) #----------------------------------------------------------------------------- +# Option to use new-style references with dimension scale APIs +#----------------------------------------------------------------------------- +option (HDF5_DIMENSION_SCALES_NEW_REF "Use new-style references with dimension scale APIs" OFF) +if (HDF5_DIMENSION_SCALES_NEW_REF) + set (H5_DIMENSION_SCALES_WITH_NEW_REF 1) +endif () + +#----------------------------------------------------------------------------- # List Source files #----------------------------------------------------------------------------- diff --git a/hl/fortran/src/H5LTfc.c b/hl/fortran/src/H5LTfc.c index e87a9d3..4cb9265 100644 --- a/hl/fortran/src/H5LTfc.c +++ b/hl/fortran/src/H5LTfc.c @@ -319,11 +319,9 @@ h5ltset_attribute_c(hid_t_f *loc_id, size_t_f *namelen, _fcd dsetname, size_t_f else if ((size_t)*sizeof_val == sizeof(double)) ret = H5LT_set_attribute_numerical(c_loc_id, c_name, c_attrname, c_size, H5T_NATIVE_DOUBLE, (const double *)buf); -#if H5_SIZEOF_LONG_DOUBLE != 0 else if ((size_t)*sizeof_val == sizeof(long double)) ret = H5LT_set_attribute_numerical(c_loc_id, c_name, c_attrname, c_size, H5T_NATIVE_LDOUBLE, (const long double *)buf); -#endif else goto done; } @@ -413,10 +411,8 @@ h5ltget_attribute_c(hid_t_f *loc_id, size_t_f *namelen, _fcd dsetname, size_t_f ret = H5LTget_attribute(c_loc_id, c_name, c_attrname, H5T_NATIVE_FLOAT, buf); else if ((size_t)*sizeof_val == sizeof(double)) ret = H5LTget_attribute(c_loc_id, c_name, c_attrname, H5T_NATIVE_DOUBLE, buf); -#if H5_SIZEOF_LONG_DOUBLE != 0 else if ((size_t)*sizeof_val == sizeof(long double)) ret = H5LTget_attribute(c_loc_id, c_name, c_attrname, H5T_NATIVE_LDOUBLE, buf); -#endif else goto done; } diff --git a/hl/src/H5DS.c b/hl/src/H5DS.c index 2bd4046..c947d16 100644 --- a/hl/src/H5DS.c +++ b/hl/src/H5DS.c @@ -18,7 +18,40 @@ /* Local routines */ static herr_t H5DS_is_reserved(hid_t did); -static hid_t H5DS_get_REFLIST_type(void); + +/*------------------------------------------------------------------------- + * Function: H5DSwith_new_ref + * + * Purpose: Determines if new references are used with dimension scales. + * The function H5DSwith_new_ref takes any object identifier and checks + * if new references are used for dimension scales. Currently, + * new references are used when non-native VOL connector is used or when + * H5_DIMENSION_SCALES_WITH_NEW_REF is set up via configure option. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5DSwith_new_ref(hid_t obj_id, hbool_t *with_new_ref) +{ + hbool_t config_flag = FALSE; + hbool_t native = FALSE; + + if (!with_new_ref) + return FAIL; + + if (H5VLobject_is_native(obj_id, &native) < 0) + return FAIL; + +#ifdef H5_DIMENSION_SCALES_WITH_NEW_REF + config_flag = TRUE; +#endif + + *with_new_ref = (config_flag || !native); + + return SUCCEED; +} /*------------------------------------------------------------------------- * Function: H5DSset_scale @@ -106,22 +139,34 @@ H5DSset_scale(hid_t dsid, const char *dimname) herr_t H5DSattach_scale(hid_t did, hid_t dsid, unsigned int idx) { - int has_dimlist; - int has_reflist; - int is_ds; - hssize_t nelmts; - hid_t sid; /* space ID */ - hid_t tid = -1; /* attribute type ID */ - hid_t ntid = -1; /* attribute native type ID */ - hid_t aid = -1; /* attribute ID */ - int rank; /* rank of dataset */ - hsize_t dims[1]; /* dimension of the "REFERENCE_LIST" array */ - ds_list_t dsl; /* attribute data in the DS pointing to the dataset */ - ds_list_t * dsbuf = NULL; /* array of attribute data in the DS pointing to the dataset */ - hobj_ref_t ref_to_ds; /* reference to the DS */ - hobj_ref_t ref_j; /* iterator reference */ - hvl_t * buf = NULL; /* VL buffer to store in the attribute */ - hid_t dsid_j; /* DS dataset ID in DIMENSION_LIST */ + int has_dimlist; + int has_reflist; + int is_ds; + hssize_t nelmts; + hid_t sid, sid_w; /* space ID */ + hid_t tid = H5I_INVALID_HID; /* attribute type ID */ + hid_t ntid = H5I_INVALID_HID; /* attribute native type ID */ + hid_t aid = H5I_INVALID_HID; /* attribute ID */ + int rank; /* rank of dataset */ + hsize_t dims[1]; /* dimension of the "REFERENCE_LIST" array */ + + ds_list_t dsl; /* attribute data in the DS pointing to the dataset */ + ds_list_t *dsbuf = NULL; /* array of attribute data in the DS pointing to the dataset */ + ds_list_t *dsbuf_w = + NULL; /* array of "REFERENCE_LIST" attribute data to write when adding new reference to a dataset */ + hobj_ref_t ref_to_ds; /* reference to the DS */ + hobj_ref_t ref_j; /* iterator reference */ + + /* Variables to be used when new references are used */ + nds_list_t ndsl; + nds_list_t *ndsbuf = NULL; + nds_list_t *ndsbuf_w = NULL; + H5R_ref_t nref_to_ds; + H5R_ref_t nref_j; + hbool_t is_new_ref; + + hvl_t * buf = NULL; /* VL buffer to store in the attribute */ + hid_t dsid_j; /* DS dataset ID in DIMENSION_LIST */ H5O_info2_t oi1, oi2; H5I_type_t it1, it2; int i; @@ -159,6 +204,14 @@ H5DSattach_scale(hid_t did, hid_t dsid, unsigned int idx) return FAIL; } /* end if */ + /*------------------------------------------------------------------------- + * determine if old or new references should be used + *------------------------------------------------------------------------- + */ + + if (H5DSwith_new_ref(did, &is_new_ref) < 0) + return FAIL; + /* get ID type */ if ((it1 = H5Iget_type(did)) < 0) return FAIL; @@ -209,14 +262,23 @@ H5DSattach_scale(hid_t did, hid_t dsid, unsigned int idx) * and one to the dataset, saved in "REFERENCE_LIST" *------------------------------------------------------------------------- */ - /* create a reference for the >>DS<< dataset */ - if (H5Rcreate(&ref_to_ds, dsid, ".", H5R_OBJECT, (hid_t)-1) < 0) - return FAIL; - - /* create a reference for the >>data<< dataset */ - if (H5Rcreate(&dsl.ref, did, ".", H5R_OBJECT, (hid_t)-1) < 0) - return FAIL; + if (is_new_ref) { + /* create a reference for the >>DS<< dataset */ + if (H5Rcreate_object(dsid, ".", H5P_DEFAULT, &nref_to_ds) < 0) + return FAIL; + /* create a reference for the >>data<< dataset */ + if (H5Rcreate_object(did, ".", H5P_DEFAULT, &ndsl.ref) < 0) + return FAIL; + } + else { + /* create a reference for the >>DS<< dataset */ + if (H5Rcreate(&ref_to_ds, dsid, ".", H5R_OBJECT, (hid_t)-1) < 0) + return FAIL; + /* create a reference for the >>data<< dataset */ + if (H5Rcreate(&dsl.ref, did, ".", H5R_OBJECT, (hid_t)-1) < 0) + return FAIL; + } /* try to find the attribute "DIMENSION_LIST" on the >>data<< dataset */ if ((has_dimlist = H5LT_find_attribute(did, DIMENSION_LIST)) < 0) return FAIL; @@ -234,9 +296,14 @@ H5DSattach_scale(hid_t did, hid_t dsid, unsigned int idx) return FAIL; /* create the type for the attribute "DIMENSION_LIST" */ - if ((tid = H5Tvlen_create(H5T_STD_REF_OBJ)) < 0) - goto out; - + if (is_new_ref) { + if ((tid = H5Tvlen_create(H5T_STD_REF)) < 0) + goto out; + } + else { + if ((tid = H5Tvlen_create(H5T_STD_REF_OBJ)) < 0) + goto out; + } /* create the attribute */ if ((aid = H5Acreate2(did, DIMENSION_LIST, tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto out; @@ -252,24 +319,32 @@ H5DSattach_scale(hid_t did, hid_t dsid, unsigned int idx) } /* store the REF information in the index of the dataset that has the DS */ - buf[idx].len = 1; - buf[idx].p = HDmalloc(1 * sizeof(hobj_ref_t)); - ((hobj_ref_t *)buf[idx].p)[0] = ref_to_ds; - + buf[idx].len = 1; + if (is_new_ref) { + buf[idx].p = HDmalloc(1 * sizeof(H5R_ref_t)); + ((H5R_ref_t *)buf[idx].p)[0] = nref_to_ds; + } + else { + buf[idx].p = HDmalloc(1 * sizeof(hobj_ref_t)); + ((hobj_ref_t *)buf[idx].p)[0] = ref_to_ds; + } /* write the attribute with the reference */ if (H5Awrite(aid, tid, buf) < 0) goto out; /* close */ - if (H5Treclaim(tid, sid, H5P_DEFAULT, buf) < 0) - goto out; + if (is_new_ref) { + if (H5Rdestroy(&nref_to_ds) < 0) + goto out; + } if (H5Sclose(sid) < 0) goto out; if (H5Tclose(tid) < 0) goto out; if (H5Aclose(aid) < 0) goto out; - + HDfree(buf[idx].p); + buf[idx].p = NULL; HDfree(buf); buf = NULL; } @@ -302,12 +377,20 @@ H5DSattach_scale(hid_t did, hid_t dsid, unsigned int idx) /* iterate all the REFs in this dimension IDX */ for (i = 0; i < (int)buf[idx].len; i++) { /* get the reference */ - ref_j = ((hobj_ref_t *)buf[idx].p)[i]; + if (is_new_ref) { + nref_j = ((H5R_ref_t *)buf[idx].p)[i]; - /* get the scale id for this REF */ - if ((dsid_j = H5Rdereference2(did, H5P_DEFAULT, H5R_OBJECT, &ref_j)) < 0) - goto out; + /* get the scale id for this REF */ + if ((dsid_j = H5Ropen_object(&nref_j, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto out; + } + else { + ref_j = ((hobj_ref_t *)buf[idx].p)[i]; + /* get the scale id for this REF */ + if ((dsid_j = H5Rdereference2(did, H5P_DEFAULT, H5R_OBJECT, &ref_j)) < 0) + goto out; + } /* get info for DS in the parameter list */ if (H5Oget_info3(dsid, &oi1, H5O_INFO_BASIC) < 0) goto out; @@ -335,17 +418,33 @@ H5DSattach_scale(hid_t did, hid_t dsid, unsigned int idx) /* we are adding one more DS to this dimension */ if (buf[idx].len > 0) { buf[idx].len++; - len = buf[idx].len; - buf[idx].p = HDrealloc(buf[idx].p, len * sizeof(hobj_ref_t)); - ((hobj_ref_t *)buf[idx].p)[len - 1] = ref_to_ds; + len = buf[idx].len; + if (is_new_ref) { + buf[idx].p = HDrealloc(buf[idx].p, len * sizeof(H5R_ref_t)); + ((H5R_ref_t *)buf[idx].p)[len - 1] = nref_to_ds; + } + else { + buf[idx].p = HDrealloc(buf[idx].p, len * sizeof(hobj_ref_t)); + ((hobj_ref_t *)buf[idx].p)[len - 1] = ref_to_ds; + } } /* end if */ else { /* store the REF information in the index of the dataset that has the DS */ - buf[idx].len = 1; - buf[idx].p = HDmalloc(sizeof(hobj_ref_t)); - ((hobj_ref_t *)buf[idx].p)[0] = ref_to_ds; + buf[idx].len = 1; + if (is_new_ref) { + buf[idx].p = HDmalloc(sizeof(H5R_ref_t)); + ((H5R_ref_t *)buf[idx].p)[0] = nref_to_ds; + } + else { + buf[idx].p = HDmalloc(sizeof(hobj_ref_t)); + ((hobj_ref_t *)buf[idx].p)[0] = ref_to_ds; + } } /* end else */ } /* end if */ + else { + if (is_new_ref && H5Rdestroy(&nref_to_ds) < 0) + goto out; + } /* write the attribute with the new references */ if (H5Awrite(aid, tid, buf) < 0) @@ -385,29 +484,40 @@ H5DSattach_scale(hid_t did, hid_t dsid, unsigned int idx) goto out; /* create the compound datatype for the attribute "REFERENCE_LIST" */ - if ((tid = H5Tcreate(H5T_COMPOUND, sizeof(ds_list_t))) < 0) - goto out; - - /* insert reference field */ - if (H5Tinsert(tid, "dataset", HOFFSET(ds_list_t, ref), H5T_STD_REF_OBJ) < 0) - goto out; - - /* insert dimension idx of the dataset field */ - if (H5Tinsert(tid, "dimension", HOFFSET(ds_list_t, dim_idx), H5T_NATIVE_INT) < 0) - goto out; + if (is_new_ref) { + if ((tid = H5Tcreate(H5T_COMPOUND, sizeof(nds_list_t))) < 0) + goto out; + if (H5Tinsert(tid, "dataset", HOFFSET(nds_list_t, ref), H5T_STD_REF) < 0) + goto out; + if (H5Tinsert(tid, "dimension", HOFFSET(nds_list_t, dim_idx), H5T_NATIVE_UINT) < 0) + goto out; + } + else { + if ((tid = H5Tcreate(H5T_COMPOUND, sizeof(ds_list_t))) < 0) + goto out; + if (H5Tinsert(tid, "dataset", HOFFSET(ds_list_t, ref), H5T_STD_REF_OBJ) < 0) + goto out; + if (H5Tinsert(tid, "dimension", HOFFSET(ds_list_t, dim_idx), H5T_NATIVE_UINT) < 0) + goto out; + } /* create the attribute */ if ((aid = H5Acreate2(dsid, REFERENCE_LIST, tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto out; /* store the IDX information */ - dsl.dim_idx = idx; - - /* write the attribute with the reference */ - if (H5Awrite(aid, tid, &dsl) < 0) - goto out; - - /* close */ + if (is_new_ref) { + ndsl.dim_idx = idx; + if (H5Awrite(aid, tid, &ndsl) < 0) + goto out; + if (H5Rdestroy(&ndsl.ref) < 0) + goto out; + } + else { + dsl.dim_idx = idx; + if (H5Awrite(aid, tid, &dsl) < 0) + goto out; + } if (H5Sclose(sid) < 0) goto out; if (H5Tclose(tid) < 0) @@ -421,6 +531,9 @@ H5DSattach_scale(hid_t did, hid_t dsid, unsigned int idx) *------------------------------------------------------------------------- */ else if (has_reflist == 1) { + hid_t tmp_id; /* Temporary DS dataset ID to recreate reference */ + int j; + if ((aid = H5Aopen(dsid, REFERENCE_LIST, H5P_DEFAULT)) < 0) goto out; @@ -428,7 +541,7 @@ H5DSattach_scale(hid_t did, hid_t dsid, unsigned int idx) goto out; /* get native type to read attribute REFERENCE_LIST */ - if ((ntid = H5DS_get_REFLIST_type()) < 0) + if ((ntid = H5Tget_native_type(tid, H5T_DIR_ASCEND)) < 0) goto out; /* get and save the old reference(s) */ @@ -439,17 +552,22 @@ H5DSattach_scale(hid_t did, hid_t dsid, unsigned int idx) goto out; nelmts++; - - dsbuf = (ds_list_t *)HDmalloc((size_t)nelmts * sizeof(ds_list_t)); - if (dsbuf == NULL) - goto out; - - if (H5Aread(aid, ntid, dsbuf) < 0) - goto out; + if (is_new_ref) { + ndsbuf = (nds_list_t *)HDmalloc((size_t)nelmts * sizeof(nds_list_t)); + if (ndsbuf == NULL) + goto out; + if (H5Aread(aid, ntid, ndsbuf) < 0) + goto out; + } + else { + dsbuf = (ds_list_t *)HDmalloc((size_t)nelmts * sizeof(ds_list_t)); + if (dsbuf == NULL) + goto out; + if (H5Aread(aid, ntid, dsbuf) < 0) + goto out; + } /* close */ - if (H5Sclose(sid) < 0) - goto out; if (H5Aclose(aid) < 0) goto out; @@ -458,40 +576,93 @@ H5DSattach_scale(hid_t did, hid_t dsid, unsigned int idx) *------------------------------------------------------------------------- */ + /* Allocate new buffer to copy old references and add new one */ + + if (is_new_ref) { + ndsbuf_w = (nds_list_t *)HDmalloc((size_t)nelmts * sizeof(nds_list_t)); + if (ndsbuf_w == NULL) + goto out; + } + else { + dsbuf_w = (ds_list_t *)HDmalloc((size_t)nelmts * sizeof(ds_list_t)); + if (dsbuf_w == NULL) + goto out; + } + /* Recreate the references we read from the existing "REFERENCE_LIST" attribute */ + for (j = 0; j < nelmts - 1; j++) { + if (is_new_ref) { + ndsbuf_w[j].dim_idx = ndsbuf[j].dim_idx; + tmp_id = H5Ropen_object(&ndsbuf[j].ref, H5P_DEFAULT, H5P_DEFAULT); + if (tmp_id < 0) + goto out; + if (H5Rcreate_object(tmp_id, ".", H5P_DEFAULT, &ndsbuf_w[j].ref) < 0) { + H5Dclose(tmp_id); + goto out; + } + } + else { + dsbuf_w[j] = dsbuf[j]; + } + } + /* store the IDX information (index of the dataset that has the DS) */ + if (is_new_ref) { + ndsl.dim_idx = idx; + ndsbuf_w[nelmts - 1] = ndsl; + } + else { + dsl.dim_idx = idx; + dsbuf_w[nelmts - 1] = dsl; + } + /* the attribute must be deleted, in order to the new one can reflect the changes*/ if (H5Adelete(dsid, REFERENCE_LIST) < 0) goto out; - /* store the IDX information (index of the dataset that has the DS) */ - dsl.dim_idx = idx; - dsbuf[nelmts - 1] = dsl; - /* create a new data space for the new references array */ dims[0] = (hsize_t)nelmts; - if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + if ((sid_w = H5Screate_simple(1, dims, NULL)) < 0) goto out; /* create the attribute again with the changes of space */ - if ((aid = H5Acreate2(dsid, REFERENCE_LIST, tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) + if ((aid = H5Acreate2(dsid, REFERENCE_LIST, tid, sid_w, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto out; /* write the attribute with the new references */ - if (H5Awrite(aid, ntid, dsbuf) < 0) - goto out; - - /* close */ + if (is_new_ref) { + if (H5Awrite(aid, ntid, ndsbuf_w) < 0) + goto out; + if (H5Treclaim(tid, sid, H5P_DEFAULT, ndsbuf_w) < 0) + goto out; + } + else { + if (H5Awrite(aid, ntid, dsbuf_w) < 0) + goto out; + if (H5Treclaim(tid, sid, H5P_DEFAULT, dsbuf_w) < 0) + goto out; + } if (H5Sclose(sid) < 0) goto out; + if (H5Sclose(sid_w) < 0) + goto out; if (H5Tclose(tid) < 0) goto out; if (H5Aclose(aid) < 0) goto out; if (H5Tclose(ntid) < 0) goto out; - - HDfree(dsbuf); - dsbuf = NULL; + if (is_new_ref) { + HDfree(ndsbuf); + dsbuf = NULL; + HDfree(ndsbuf_w); + dsbuf = NULL; + } + else { + HDfree(dsbuf); + dsbuf = NULL; + HDfree(dsbuf_w); + dsbuf = NULL; + } } /* has_reflist */ /*------------------------------------------------------------------------- @@ -515,6 +686,8 @@ out: HDfree(buf); if (dsbuf) HDfree(dsbuf); + if (dsbuf_w) + HDfree(dsbuf_w); H5E_BEGIN_TRY { @@ -554,27 +727,35 @@ out: herr_t H5DSdetach_scale(hid_t did, hid_t dsid, unsigned int idx) { - int has_dimlist; - int has_reflist; - hssize_t nelmts; - hid_t dsid_j; /* DS dataset ID in DIMENSION_LIST */ - hid_t did_i; /* dataset ID in REFERENCE_LIST */ - hid_t sid; /* space ID */ - hid_t tid = -1; /* attribute type ID */ - hid_t ntid = -1; /* attribute native type ID */ - hid_t aid = -1; /* attribute ID */ - int rank; /* rank of dataset */ - ds_list_t * dsbuf = NULL; /* array of attribute data in the DS pointing to the dataset */ - hsize_t dims[1]; /* dimension of the "REFERENCE_LIST" array */ - hobj_ref_t ref; /* reference to the DS */ - hvl_t * buf = NULL; /* VL buffer to store in the attribute */ - int i; - size_t j; - hssize_t ii; - H5O_info2_t did_oi, dsid_oi, tmp_oi; - int found_dset = 0, found_ds = 0; - int have_ds = 0; - htri_t is_scale; + int has_dimlist; + int has_reflist; + hssize_t nelmts; + hid_t dsid_j; /* DS dataset ID in DIMENSION_LIST */ + hid_t did_i; /* dataset ID in REFERENCE_LIST */ + hid_t sid = H5I_INVALID_HID; /* space ID */ + hid_t sid_w = H5I_INVALID_HID; /* space ID */ + hid_t tid = H5I_INVALID_HID; /* attribute type ID */ + hid_t ntid = H5I_INVALID_HID; /* attribute native type ID */ + hid_t aid = H5I_INVALID_HID; /* attribute ID */ + int rank; /* rank of dataset */ + nds_list_t * ndsbuf = NULL; /* array of attribute data in the DS pointing to the dataset */ + nds_list_t * ndsbuf_w = NULL; /* array of attribute data in the DS pointing to the dataset to write*/ + ds_list_t * dsbuf = NULL; /* array of attribute data in the DS pointing to the dataset */ + ds_list_t * dsbuf_w = NULL; /* array of attribute data in the DS pointing to the dataset to write*/ + hsize_t dims[1]; /* dimension of the "REFERENCE_LIST" array */ + H5R_ref_t nref; + hobj_ref_t ref; /* reference to the DS */ + hvl_t * buf = NULL; /* VL buffer to store in the attribute */ + int i; + size_t j; + hssize_t ii; + H5O_info2_t did_oi, dsid_oi, tmp_oi; + int found_dset = 0, found_ds = 0; + int have_ds = 0; + htri_t is_scale; + hbool_t is_new_ref; + unsigned int tmp_idx; + hid_t tmp_id; /*------------------------------------------------------------------------- * parameter checking @@ -612,9 +793,17 @@ H5DSdetach_scale(hid_t did, hid_t dsid, unsigned int idx) } /* end if */ /*------------------------------------------------------------------------- - * Find "DIMENSION_LIST" + * determine if old or new references should be used + *------------------------------------------------------------------------- + */ + if (H5DSwith_new_ref(did, &is_new_ref) < 0) + return FAIL; + + /*------------------------------------------------------------------------- + * find "DIMENSION_LIST" *------------------------------------------------------------------------- */ + /* try to find the attribute "DIMENSION_LIST" on the >>data<< dataset */ if ((has_dimlist = H5LT_find_attribute(did, DIMENSION_LIST)) < 0) return FAIL; @@ -676,13 +865,22 @@ H5DSdetach_scale(hid_t did, hid_t dsid, unsigned int idx) /* reset */ if (buf[idx].len > 0) { for (j = 0; j < buf[idx].len; j++) { - /* get the reference */ - ref = ((hobj_ref_t *)buf[idx].p)[j]; + if (is_new_ref) { + /* get the reference */ + nref = ((H5R_ref_t *)buf[idx].p)[j]; - /* get the DS id */ - if ((dsid_j = H5Rdereference2(did, H5P_DEFAULT, H5R_OBJECT, &ref)) < 0) - goto out; + /* get the scale id for this REF */ + if ((dsid_j = H5Ropen_object(&nref, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto out; + } + else { + /* get the reference */ + ref = ((hobj_ref_t *)buf[idx].p)[j]; + /* get the DS id */ + if ((dsid_j = H5Rdereference2(did, H5P_DEFAULT, H5R_OBJECT, &ref)) < 0) + goto out; + } /* get info for this DS */ if (H5Oget_info3(dsid_j, &tmp_oi, H5O_INFO_BASIC) < 0) goto out; @@ -708,8 +906,14 @@ H5DSdetach_scale(hid_t did, hid_t dsid, unsigned int idx) size_t len = buf[idx].len; - if (j < len - 1) - ((hobj_ref_t *)buf[idx].p)[j] = ((hobj_ref_t *)buf[idx].p)[len - 1]; + if (j < len - 1) { + if (is_new_ref) { + ((H5R_ref_t *)buf[idx].p)[j] = ((H5R_ref_t *)buf[idx].p)[len - 1]; + } + else { + ((hobj_ref_t *)buf[idx].p)[j] = ((hobj_ref_t *)buf[idx].p)[len - 1]; + } + } len = --buf[idx].len; if (len == 0) { HDfree(buf[idx].p); @@ -770,7 +974,7 @@ H5DSdetach_scale(hid_t did, hid_t dsid, unsigned int idx) goto out; /* get native type to read attribute REFERENCE_LIST */ - if ((ntid = H5DS_get_REFLIST_type()) < 0) + if ((ntid = H5Tget_native_type(tid, H5T_DIR_ASCEND)) < 0) goto out; /* get and save the old reference(s) */ @@ -780,22 +984,65 @@ H5DSdetach_scale(hid_t did, hid_t dsid, unsigned int idx) if ((nelmts = H5Sget_simple_extent_npoints(sid)) < 0) goto out; - dsbuf = (ds_list_t *)HDmalloc((size_t)nelmts * sizeof(ds_list_t)); - if (dsbuf == NULL) - goto out; - - if (H5Aread(aid, ntid, dsbuf) < 0) - goto out; - + if (is_new_ref) { + ndsbuf = (nds_list_t *)HDmalloc((size_t)nelmts * sizeof(nds_list_t)); + if (ndsbuf == NULL) + goto out; + if (H5Aread(aid, ntid, ndsbuf) < 0) + goto out; + ndsbuf_w = (nds_list_t *)HDmalloc((size_t)nelmts * sizeof(nds_list_t)); + if (ndsbuf_w == NULL) + goto out; + } + else { + dsbuf = (ds_list_t *)HDmalloc((size_t)nelmts * sizeof(ds_list_t)); + if (dsbuf == NULL) + goto out; + if (H5Aread(aid, ntid, dsbuf) < 0) + goto out; + dsbuf_w = (ds_list_t *)HDmalloc((size_t)nelmts * sizeof(ds_list_t)); + if (dsbuf_w == NULL) + goto out; + } + /* Recreate the references we read from the existing "REFERENCE_LIST" attribute */ + for (i = 0; i < nelmts; i++) { + if (is_new_ref) { + ndsbuf_w[i].dim_idx = ndsbuf[i].dim_idx; + tmp_id = H5Ropen_object(&ndsbuf[i].ref, H5P_DEFAULT, H5P_DEFAULT); + if (tmp_id < 0) + goto out; + if (H5Rcreate_object(tmp_id, ".", H5P_DEFAULT, &ndsbuf_w[i].ref) < 0) { + H5Dclose(tmp_id); + goto out; + } + H5Dclose(tmp_id); + } + else { + dsbuf_w[i] = dsbuf[i]; + } + } for (ii = 0; ii < nelmts; ii++) { /* First check if we have the same dimension index */ - if (idx == dsbuf[ii].dim_idx) { + if (is_new_ref) { + tmp_idx = ndsbuf_w[ii].dim_idx; + } + else { + tmp_idx = dsbuf_w[ii].dim_idx; + } + if (idx == tmp_idx) { /* get the reference to the dataset */ - ref = dsbuf[ii].ref; - - /* get the dataset id */ - if ((did_i = H5Rdereference2(did, H5P_DEFAULT, H5R_OBJECT, &ref)) < 0) - goto out; + if (is_new_ref) { + /* get the dataset id */ + nref = ndsbuf_w[ii].ref; + if ((did_i = H5Ropen_object(&nref, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto out; + } + else { + /* get the dataset id */ + ref = dsbuf_w[ii].ref; + if ((did_i = H5Rdereference2(did, H5P_DEFAULT, H5R_OBJECT, &ref)) < 0) + goto out; + } /* get info for this dataset */ if (H5Oget_info3(did_i, &tmp_oi, H5O_INFO_BASIC) < 0) @@ -813,7 +1060,12 @@ H5DSdetach_scale(hid_t did, hid_t dsid, unsigned int idx) goto out; if (!token_cmp) { /* copy the last one to replace the one which is found */ - dsbuf[ii] = dsbuf[nelmts - 1]; + if (is_new_ref) { + ndsbuf_w[ii] = ndsbuf_w[nelmts - 1]; + } + else { + dsbuf_w[ii] = dsbuf_w[nelmts - 1]; + } nelmts--; found_dset = 1; break; @@ -822,9 +1074,7 @@ H5DSdetach_scale(hid_t did, hid_t dsid, unsigned int idx) } /* if we have the same dimension index */ } /* ii */ - /* close space and attribute */ - if (H5Sclose(sid) < 0) - goto out; + /* close attribute */ if (H5Aclose(aid) < 0) goto out; @@ -851,32 +1101,69 @@ H5DSdetach_scale(hid_t did, hid_t dsid, unsigned int idx) /* create a new data space for the new references array */ dims[0] = (hsize_t)nelmts; - if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + if ((sid_w = H5Screate_simple(1, dims, NULL)) < 0) goto out; /* create the attribute again with the changes of space */ - if ((aid = H5Acreate2(dsid, REFERENCE_LIST, tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) + if ((aid = H5Acreate2(dsid, REFERENCE_LIST, tid, sid_w, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto out; /* write the new attribute with the new references */ - if (H5Awrite(aid, ntid, dsbuf) < 0) - goto out; + if (is_new_ref) { + if (H5Awrite(aid, ntid, ndsbuf_w) < 0) + goto out; + } + else { + if (H5Awrite(aid, ntid, dsbuf_w) < 0) + goto out; + } - /* close space and attribute */ - if (H5Sclose(sid) < 0) - goto out; if (H5Aclose(aid) < 0) goto out; } /* nelmts */ + /* Free refrences */ + if (is_new_ref) { + if (H5Treclaim(tid, sid, H5P_DEFAULT, ndsbuf) < 0) + goto out; + if (H5Sclose(sid) < 0) + goto out; + if (sid_w > 0) { + if (H5Treclaim(tid, sid_w, H5P_DEFAULT, ndsbuf_w) < 0) + goto out; + if (H5Sclose(sid_w) < 0) + goto out; + } + } + else { + if (H5Treclaim(tid, sid, H5P_DEFAULT, dsbuf) < 0) + goto out; + if (H5Sclose(sid) < 0) + goto out; + if (sid_w > 0) { + if (H5Treclaim(tid, sid_w, H5P_DEFAULT, dsbuf_w) < 0) + goto out; + if (H5Sclose(sid_w) < 0) + goto out; + } + } /* close type */ if (H5Tclose(tid) < 0) goto out; if (H5Tclose(ntid) < 0) goto out; - - HDfree(dsbuf); - dsbuf = NULL; + if (is_new_ref) { + HDfree(ndsbuf); + HDfree(ndsbuf_w); + ndsbuf = NULL; + ndsbuf_w = NULL; + } + else { + HDfree(dsbuf); + HDfree(dsbuf_w); + dsbuf = NULL; + dsbuf_w = NULL; + } return SUCCEED; @@ -889,6 +1176,14 @@ out: H5Tclose(ntid); H5Tclose(tid); + if (ndsbuf) { + HDfree(ndsbuf); + ndsbuf = NULL; + } + if (ndsbuf_w) { + HDfree(ndsbuf_w); + ndsbuf_w = NULL; + } if (dsbuf) { HDfree(dsbuf); dsbuf = NULL; @@ -936,21 +1231,24 @@ H5DSis_attached(hid_t did, hid_t dsid, unsigned int idx) int has_dimlist; int has_reflist; hssize_t nelmts; - hid_t sid; /* space ID */ - hid_t tid = -1; /* attribute type ID */ - hid_t ntid = -1; /* attribute native type ID */ - hid_t aid = -1; /* attribute ID */ - int rank; /* rank of dataset */ - ds_list_t * dsbuf = NULL; /* array of attribute data in the DS pointing to the dataset */ - hobj_ref_t ref; /* reference to the DS */ - hvl_t * buf = NULL; /* VL buffer to store in the attribute */ - hid_t dsid_j; /* DS dataset ID in DIMENSION_LIST */ - hid_t did_i; /* dataset ID in REFERENCE_LIST */ + hid_t sid; /* space ID */ + hid_t tid = H5I_INVALID_HID; /* attribute type ID */ + hid_t ntid = H5I_INVALID_HID; /* attribute native type ID */ + hid_t aid = H5I_INVALID_HID; /* attribute ID */ + int rank; /* rank of dataset */ + nds_list_t *ndsbuf = NULL; /* array of attribute data in the DS pointing to the dataset */ + ds_list_t * dsbuf = NULL; /* array of attribute data in the DS pointing to the dataset */ + H5R_ref_t nref; /* reference to the DS */ + hobj_ref_t ref; /* reference to the DS */ + hvl_t * buf = NULL; /* VL buffer to store in the attribute */ + hid_t dsid_j; /* DS dataset ID in DIMENSION_LIST */ + hid_t did_i; /* dataset ID in REFERENCE_LIST */ H5O_info2_t oi1, oi2, oi3, oi4; H5I_type_t it1, it2; int i; int found_dset = 0, found_ds = 0; htri_t is_scale; + hbool_t is_new_ref; /*------------------------------------------------------------------------- * parameter checking @@ -982,6 +1280,14 @@ H5DSis_attached(hid_t did, hid_t dsid, unsigned int idx) return FAIL; } /* end if */ + /*------------------------------------------------------------------------- + * determine if old or new references should be used + *------------------------------------------------------------------------- + */ + + if (H5DSwith_new_ref(did, &is_new_ref) < 0) + return FAIL; + /* get ID type */ if ((it1 = H5Iget_type(did)) < 0) return FAIL; @@ -1042,12 +1348,22 @@ H5DSis_attached(hid_t did, hid_t dsid, unsigned int idx) /* iterate all the REFs in this dimension IDX */ for (i = 0; i < (int)buf[idx].len; i++) { - /* get the reference */ - ref = ((hobj_ref_t *)buf[idx].p)[i]; + if (is_new_ref) { + /* get the reference */ + nref = ((H5R_ref_t *)buf[idx].p)[i]; - /* get the scale id for this REF */ - if ((dsid_j = H5Rdereference2(did, H5P_DEFAULT, H5R_OBJECT, &ref)) < 0) - goto out; + /* get the scale id for this REF */ + if ((dsid_j = H5Ropen_object(&nref, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto out; + } + else { + /* get the reference */ + ref = ((hobj_ref_t *)buf[idx].p)[i]; + + /* get the scale id for this REF */ + if ((dsid_j = H5Rdereference2(did, H5P_DEFAULT, H5R_OBJECT, &ref)) < 0) + goto out; + } /* get info for DS in the parameter list */ if (H5Oget_info3(dsid, &oi1, H5O_INFO_BASIC) < 0) @@ -1107,7 +1423,7 @@ H5DSis_attached(hid_t did, hid_t dsid, unsigned int idx) goto out; /* get native type to read REFERENCE_LIST attribute */ - if ((ntid = H5DS_get_REFLIST_type()) < 0) + if ((ntid = H5Tget_native_type(tid, H5T_DIR_ASCEND)) < 0) goto out; /* get and save the old reference(s) */ @@ -1117,13 +1433,20 @@ H5DSis_attached(hid_t did, hid_t dsid, unsigned int idx) if ((nelmts = H5Sget_simple_extent_npoints(sid)) < 0) goto out; - dsbuf = (ds_list_t *)HDmalloc((size_t)nelmts * sizeof(ds_list_t)); - - if (dsbuf == NULL) - goto out; - - if (H5Aread(aid, ntid, dsbuf) < 0) - goto out; + if (is_new_ref) { + ndsbuf = (nds_list_t *)HDmalloc((size_t)nelmts * sizeof(nds_list_t)); + if (ndsbuf == NULL) + goto out; + if (H5Aread(aid, ntid, ndsbuf) < 0) + goto out; + } + else { + dsbuf = (ds_list_t *)HDmalloc((size_t)nelmts * sizeof(ds_list_t)); + if (dsbuf == NULL) + goto out; + if (H5Aread(aid, ntid, dsbuf) < 0) + goto out; + } /*------------------------------------------------------------------------- * iterate @@ -1131,40 +1454,58 @@ H5DSis_attached(hid_t did, hid_t dsid, unsigned int idx) */ for (i = 0; i < nelmts; i++) { - /* get the reference */ - ref = dsbuf[i].ref; - /* the reference was not deleted */ - if (ref) { + if (is_new_ref) { + nref = ndsbuf[i].ref; + /* get the dataset id */ + if ((did_i = H5Ropen_object(&nref, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto out; + } + else { + ref = dsbuf[i].ref; /* get the dataset id */ if ((did_i = H5Rdereference2(did, H5P_DEFAULT, H5R_OBJECT, &ref)) < 0) goto out; + } - /* get info for dataset in the parameter list */ - if (H5Oget_info3(did, &oi3, H5O_INFO_BASIC) < 0) - goto out; + /* get info for dataset in the parameter list */ + if (H5Oget_info3(did, &oi3, H5O_INFO_BASIC) < 0) + goto out; - /* get info for this dataset */ - if (H5Oget_info3(did_i, &oi4, H5O_INFO_BASIC) < 0) - goto out; + /* get info for this dataset */ + if (H5Oget_info3(did_i, &oi4, H5O_INFO_BASIC) < 0) + goto out; - /* same object */ - if (oi3.fileno == oi4.fileno) { - int token_cmp; + /* same object */ + if (oi3.fileno == oi4.fileno) { + int token_cmp; - if (H5Otoken_cmp(did, &oi3.token, &oi4.token, &token_cmp) < 0) - goto out; + if (H5Otoken_cmp(did, &oi3.token, &oi4.token, &token_cmp) < 0) + goto out; + if (is_new_ref) { + if (!token_cmp && (idx == ndsbuf[i].dim_idx)) + found_dset = 1; + } + else { if (!token_cmp && (idx == dsbuf[i].dim_idx)) found_dset = 1; - } /* end if */ + } + } /* end if */ - /* close the dereferenced dataset */ - if (H5Dclose(did_i) < 0) - goto out; - } /* if */ - } /* i */ + /* close the dereferenced dataset */ + if (H5Dclose(did_i) < 0) + goto out; + } /* for */ /* close */ + if (is_new_ref) { + if (H5Treclaim(ntid, sid, H5P_DEFAULT, ndsbuf) < 0) + goto out; + } + else { + if (H5Treclaim(ntid, sid, H5P_DEFAULT, dsbuf) < 0) + goto out; + } if (H5Sclose(sid) < 0) goto out; if (H5Tclose(ntid) < 0) @@ -1174,8 +1515,14 @@ H5DSis_attached(hid_t did, hid_t dsid, unsigned int idx) if (H5Aclose(aid) < 0) goto out; - HDfree(dsbuf); - dsbuf = NULL; + if (ndsbuf) { + HDfree(ndsbuf); + ndsbuf = NULL; + } + if (dsbuf) { + HDfree(dsbuf); + dsbuf = NULL; + } } /* has_reflist */ if (found_ds && found_dset) @@ -1198,6 +1545,10 @@ out: HDfree(buf); buf = NULL; } + if (ndsbuf) { + HDfree(ndsbuf); + ndsbuf = NULL; + } if (dsbuf) { HDfree(dsbuf); dsbuf = NULL; @@ -1249,17 +1600,19 @@ H5DSiterate_scales(hid_t did, unsigned int dim, int *ds_idx, H5DS_iterate_t visi { hid_t scale_id; int rank; - hobj_ref_t ref; /* reference to the DS */ - hid_t sid; /* space ID */ - hid_t tid = -1; /* attribute type ID */ - hid_t aid = -1; /* attribute ID */ - hvl_t * buf = NULL; /* VL buffer to store in the attribute */ - H5I_type_t it; /* ID type */ + H5R_ref_t nref; /* reference to the DS */ + hobj_ref_t ref; /* reference to the DS */ + hid_t sid; /* space ID */ + hid_t tid = H5I_INVALID_HID; /* attribute type ID */ + hid_t aid = H5I_INVALID_HID; /* attribute ID */ + hvl_t * buf = NULL; /* VL buffer to store in the attribute */ + H5I_type_t it; /* ID type */ herr_t ret_value = 0; int j_idx; int nscales; int has_dimlist; int i; + hbool_t is_new_ref; /*------------------------------------------------------------------------- * parameter checking @@ -1272,6 +1625,14 @@ H5DSiterate_scales(hid_t did, unsigned int dim, int *ds_idx, H5DS_iterate_t visi if (H5I_DATASET != it) return FAIL; + /*------------------------------------------------------------------------- + * determine if old or new references should be used + *------------------------------------------------------------------------- + */ + + if (H5DSwith_new_ref(did, &is_new_ref) < 0) + return FAIL; + /* get the number of scales assotiated with this DIM */ if ((nscales = H5DSget_num_scales(did, dim)) < 0) return FAIL; @@ -1330,17 +1691,32 @@ H5DSiterate_scales(hid_t did, unsigned int dim, int *ds_idx, H5DS_iterate_t visi /* iterate */ for (i = j_idx; i < nscales; i++) { - /* get the reference */ - ref = ((hobj_ref_t *)buf[dim].p)[i]; - - /* disable error reporting, the ID might refer to a deleted dataset */ - H5E_BEGIN_TRY - { - /* get the DS id */ - if ((scale_id = H5Rdereference2(did, H5P_DEFAULT, H5R_OBJECT, &ref)) < 0) - goto out; + if (is_new_ref) { + /* get the reference */ + nref = ((H5R_ref_t *)buf[dim].p)[i]; + + /* disable error reporting, the ID might refer to a deleted dataset */ + H5E_BEGIN_TRY + { + /* get the DS id */ + if ((scale_id = H5Ropen_object(&nref, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto out; + } + H5E_END_TRY; + } + else { + /* get the reference */ + ref = ((hobj_ref_t *)buf[dim].p)[i]; + + /* disable error reporting, the ID might refer to a deleted dataset */ + H5E_BEGIN_TRY + { + /* get the DS id */ + if ((scale_id = H5Rdereference2(did, H5P_DEFAULT, H5R_OBJECT, &ref)) < 0) + goto out; + } + H5E_END_TRY; } - H5E_END_TRY; /* set the return IDX OUT value at current scale index */ if (ds_idx != NULL) { @@ -1413,12 +1789,12 @@ herr_t H5DSset_label(hid_t did, unsigned int idx, const char *label) { int has_labels; - hid_t sid = -1; /* space ID */ - hid_t tid = -1; /* attribute type ID */ - hid_t aid = -1; /* attribute ID */ - int rank; /* rank of dataset */ - hsize_t dims[1]; /* dimensions of dataset */ - H5I_type_t it; /* ID type */ + hid_t sid = H5I_INVALID_HID; /* space ID */ + hid_t tid = H5I_INVALID_HID; /* attribute type ID */ + hid_t aid = H5I_INVALID_HID; /* attribute ID */ + int rank; /* rank of dataset */ + hsize_t dims[1]; /* dimensions of dataset */ + H5I_type_t it; /* ID type */ unsigned int i; union { /* union is needed to eliminate compiler warnings about */ char ** buf; /* discarding the 'const' qualifier in the free */ @@ -1616,12 +1992,12 @@ ssize_t H5DSget_label(hid_t did, unsigned int idx, char *label, size_t size) { int has_labels; - hid_t sid = -1; /* space ID */ - hid_t tid = -1; /* attribute type ID */ - hid_t aid = -1; /* attribute ID */ - int rank; /* rank of dataset */ - char ** buf = NULL; /* buffer to store in the attribute */ - H5I_type_t it; /* ID type */ + hid_t sid = H5I_INVALID_HID; /* space ID */ + hid_t tid = H5I_INVALID_HID; /* attribute type ID */ + hid_t aid = H5I_INVALID_HID; /* attribute ID */ + int rank; /* rank of dataset */ + char ** buf = NULL; /* buffer to store in the attribute */ + H5I_type_t it; /* ID type */ size_t nbytes = 0; size_t copy_len; int i; @@ -1764,10 +2140,10 @@ out: ssize_t H5DSget_scale_name(hid_t did, char *name, size_t size) { - hid_t aid; /* attribute ID */ - hid_t tid = -1; /* attribute type ID */ - hid_t sid; /* space ID */ - H5I_type_t it; /* ID type */ + hid_t aid = H5I_INVALID_HID; /* attribute ID */ + hid_t tid = H5I_INVALID_HID; /* attribute type ID */ + hid_t sid = H5I_INVALID_HID; /* space ID */ + H5I_type_t it; /* ID type */ size_t nbytes; size_t copy_len; int has_name; @@ -1881,13 +2257,13 @@ out: htri_t H5DSis_scale(hid_t did) { - hid_t tid = -1; /* attribute type ID */ - hid_t aid = -1; /* attribute ID */ - herr_t attr_class; /* has the "CLASS" attribute */ - htri_t is_ds = -1; /* set to "not a dimension scale" */ - H5I_type_t it; /* type of identifier */ - char * buf = NULL; /* buffer to read name of attribute */ - size_t string_size; /* size of storage for the attribute */ + hid_t tid = H5I_INVALID_HID; /* attribute type ID */ + hid_t aid = H5I_INVALID_HID; /* attribute ID */ + herr_t attr_class; /* has the "CLASS" attribute */ + htri_t is_ds = -1; /* set to "not a dimension scale" */ + H5I_type_t it; /* type of identifier */ + char * buf = NULL; /* buffer to read name of attribute */ + size_t string_size; /* size of storage for the attribute */ H5T_class_t type_class; H5T_str_t strpad; @@ -1995,12 +2371,12 @@ int H5DSget_num_scales(hid_t did, unsigned int idx) { int has_dimlist; - hid_t sid; /* space ID */ - hid_t tid = -1; /* attribute type ID */ - hid_t aid = -1; /* attribute ID */ - int rank; /* rank of dataset */ - hvl_t * buf = NULL; /* VL buffer to store in the attribute */ - H5I_type_t it; /* ID type */ + hid_t sid; /* space ID */ + hid_t tid = H5I_INVALID_HID; /* attribute type ID */ + hid_t aid = H5I_INVALID_HID; /* attribute ID */ + int rank; /* rank of dataset */ + hvl_t * buf = NULL; /* VL buffer to store in the attribute */ + H5I_type_t it; /* ID type */ int nscales; /*------------------------------------------------------------------------- @@ -2112,12 +2488,12 @@ out: static herr_t H5DS_is_reserved(hid_t did) { - int has_class; - hid_t tid = -1; - hid_t aid = -1; - char * buf; /* Name of attribute */ - hsize_t storage_size; /* Size of storage for attribute */ - herr_t ret; + int has_class; + hid_t tid = H5I_INVALID_HID; + hid_t aid = H5I_INVALID_HID; + char * buf = NULL; /* Name of attribute */ + size_t string_size; /* Size of storage for attribute */ + herr_t ret; /* try to find the attribute "CLASS" on the dataset */ if ((has_class = H5LT_find_attribute(did, "CLASS")) < 0) @@ -2142,10 +2518,10 @@ H5DS_is_reserved(hid_t did) goto out; /* allocate buffer large enough to hold string */ - if ((storage_size = H5Aget_storage_size(aid)) == 0) + if ((string_size = H5Tget_size(tid)) == 0) goto out; - buf = (char *)HDmalloc((size_t)storage_size * sizeof(char) + 1); + buf = (char *)HDmalloc((size_t)string_size * sizeof(char)); if (buf == NULL) goto out; @@ -2174,51 +2550,11 @@ H5DS_is_reserved(hid_t did) out: H5E_BEGIN_TRY { + if (buf) + HDfree(buf); H5Tclose(tid); H5Aclose(aid); } H5E_END_TRY; return FAIL; } - -/*------------------------------------------------------------------------- - * Function: H5DS_get_REFLIST_type - * - * Purpose: This is a helper function to return a native type for - * the REFERENCE_LIST attribute. - * - * Return: Type identifier on success and negative on failure - * - * Programmer: Elena Pourmal - * - * Date: May 22, 2010 - * - *------------------------------------------------------------------------- - */ -static hid_t -H5DS_get_REFLIST_type(void) -{ - hid_t ntid_t = -1; - - /* Build native type that corresponds to compound datatype - used to store ds_list_t structure in the REFERENCE_LIST - attribute */ - - if ((ntid_t = H5Tcreate(H5T_COMPOUND, sizeof(ds_list_t))) < 0) - goto out; - - if (H5Tinsert(ntid_t, "dataset", HOFFSET(ds_list_t, ref), H5T_STD_REF_OBJ) < 0) - goto out; - - if (H5Tinsert(ntid_t, "dimension", HOFFSET(ds_list_t, dim_idx), H5T_NATIVE_INT) < 0) - goto out; - - return ntid_t; -out: - H5E_BEGIN_TRY - { - H5Tclose(ntid_t); - } - H5E_END_TRY; - return FAIL; -} diff --git a/hl/src/H5DSprivate.h b/hl/src/H5DSprivate.h index 0403a4c..ede0209 100644 --- a/hl/src/H5DSprivate.h +++ b/hl/src/H5DSprivate.h @@ -20,12 +20,18 @@ /* public LT prototypes */ #include "H5DSpublic.h" -/* attribute type of a DS dataset */ +/* attribute type of a DS dataset when old references are used*/ typedef struct ds_list_t { hobj_ref_t ref; /* object reference */ unsigned int dim_idx; /* dimension index of the dataset */ } ds_list_t; +/* attribute type of a DS dataset when new references are used*/ +typedef struct nds_list_t { + H5R_ref_t ref; + unsigned int dim_idx; /* dimension index of the dataset */ +} nds_list_t; + /*------------------------------------------------------------------------- * private functions *------------------------------------------------------------------------- diff --git a/hl/src/H5DSpublic.h b/hl/src/H5DSpublic.h index 7306cbc..979a173 100644 --- a/hl/src/H5DSpublic.h +++ b/hl/src/H5DSpublic.h @@ -25,6 +25,8 @@ typedef herr_t (*H5DS_iterate_t)(hid_t dset, unsigned dim, hid_t scale, void *vi extern "C" { #endif +H5_HLDLL herr_t H5DSwith_new_ref(hid_t obj_id, hbool_t *with_new_ref); + H5_HLDLL herr_t H5DSattach_scale(hid_t did, hid_t dsid, unsigned int idx); H5_HLDLL herr_t H5DSdetach_scale(hid_t did, hid_t dsid, unsigned int idx); diff --git a/hl/src/H5LD.c b/hl/src/H5LD.c index 8bfd0d6..2368127 100644 --- a/hl/src/H5LD.c +++ b/hl/src/H5LD.c @@ -29,9 +29,9 @@ static herr_t H5LD_get_dset_elmts(hid_t did, const hsize_t *prev_dims, const hsi * Function: H5LD_clean_vector * * Purpose: Process the vector of info: - * 1) free the array of pointers to member names in listv[n] - * 2) close the type id of the last member in listv[n] - * 3) free the H5LD_memb_t structure itself as pointed to by listv[n] + * 1) free the array of pointers to member names in listv[n] + * 2) close the type id of the last member in listv[n] + * 3) free the H5LD_memb_t structure itself as pointed to by listv[n] * * Return: void * @@ -69,12 +69,12 @@ H5LD_clean_vector(H5LD_memb_t *listv[]) * Function: H5LD_construct_info() * * Purpose: Get the remaining info for a field: - * 1) Get the type id of the last member in the field - * 2) Get the total offset of all the members in the field - * 3) Get the type size of the last member in the field + * 1) Get the type id of the last member in the field + * 2) Get the total offset of all the members in the field + * 3) Get the type size of the last member in the field * * Return: Success: 0 - * Failure: negative + * Failure: negative * * Programmer: Vailin Choi; Aug 2010 * @@ -129,24 +129,24 @@ done: * Function: H5LD_construct_vector * * Purpose: Process the comma-separated list of fields in "fields" as follows: - * Example: - * "fields": "a.b.c,d" - * listv[0]->tot_offset = total offset of "a" & "b" & "c" - * listv[0]->last_tid = type id of "c" - * listv[0]->last_tsize = type size of "c" - * listv[0]->names[0] = "a" - * listv[0]->names[1] = "b" - * listv[0]->names[2] = "c" - * listv[0]->names[3] = NULL - * - * listv[1]->tot_offset = offset of "d" - * listv[1]->last_tid = type id of "d" - * listv[1]->last_tsize = type size of "d" - * listv[1]->names[0] = "d" - * listv[1]->names[1] = NULL + * Example: + * "fields": "a.b.c,d" + * listv[0]->tot_offset = total offset of "a" & "b" & "c" + * listv[0]->last_tid = type id of "c" + * listv[0]->last_tsize = type size of "c" + * listv[0]->names[0] = "a" + * listv[0]->names[1] = "b" + * listv[0]->names[2] = "c" + * listv[0]->names[3] = NULL + * + * listv[1]->tot_offset = offset of "d" + * listv[1]->last_tid = type id of "d" + * listv[1]->last_tsize = type size of "d" + * listv[1]->names[0] = "d" + * listv[1]->names[1] = NULL * * Return: Success: # of comma-separated fields in "fields" - * Failure: negative value + * Failure: negative value * * Programmer: Vailin Choi; Aug 2010 * @@ -251,8 +251,10 @@ H5LD_construct_vector(char *fields, H5LD_memb_t *listv[] /*OUT*/, hid_t par_tid) goto done; } /* end if */ else { - if (memb) + if (memb) { + HDfree(memb->names); HDfree(memb); + } goto done; } /* end else */ } /* while !end_of_fields */ @@ -272,10 +274,10 @@ done: * Function: H5LD_get_dset_dims * * Purpose: To return the current size for each dimension of the - * dataset's dataspace + * dataset's dataspace * * Return: Success: 0 - * Failure: negative value + * Failure: negative value * * Programmer: Vailin Choi; March 2010 * @@ -316,12 +318,12 @@ done: * Function: H5LD_get_dset_type_size * * Purpose: To return the size of the dataset's datatype in bytes - * null "fields": return the size of the dataset's datatype - * non-null "fields": return the size of the dataset's datatype - * with respect to the selection in "fields" + * null "fields": return the size of the dataset's datatype + * non-null "fields": return the size of the dataset's datatype + * with respect to the selection in "fields" * * Return: Success: size of the dataset's datatype - * Failure: 0 (valid datatypes are never zero size) + * Failure: 0 (valid datatypes are never zero size) * * Programmer: Vailin Choi; March 2010 * @@ -402,7 +404,7 @@ done: * Purpose: To retrieve selected data from the dataset * * Return: Success: 0 - * Failure: negative + * Failure: negative * * Programmer: Vailin Choi; August 2010 * @@ -578,7 +580,7 @@ done: * Purpose: To retrieve the current dimension sizes for a dataset * * Return: Success: 0 - * Failure: negative value + * Failure: negative value * * Programmer: Vailin Choi; March 2010 * @@ -596,7 +598,7 @@ H5LDget_dset_dims(hid_t did, hsize_t *cur_dims) * Purpose: To return the size in bytes of the datatype for the dataset * * Return: Success: size in bytes of the dataset's datatype - * Failure: 0 (valid datatypes are never zero size) + * Failure: 0 (valid datatypes are never zero size) * * Programmer: Vailin Choi; March 2010 * @@ -614,7 +616,7 @@ H5LDget_dset_type_size(hid_t did, const char *fields) * Purpose: To retrieve selected data from the dataset * * Return: Success: 0 - * Failure: negative value + * Failure: negative value * * Programmer: Vailin Choi; March 2010 * diff --git a/hl/src/H5LT.c b/hl/src/H5LT.c index 8f2b33f..238bbf2 100644 --- a/hl/src/H5LT.c +++ b/hl/src/H5LT.c @@ -1856,46 +1856,6 @@ H5LTset_attribute_double(hid_t loc_id, const char *obj_name, const char *attr_na } /*------------------------------------------------------------------------- - * Function: find_attr - * - * Purpose: operator function used by H5LT_find_attribute - * - * Programmer: Pedro Vicente - * - * Date: June 21, 2001 - * - * Comments: - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -find_attr(H5_ATTR_UNUSED hid_t loc_id, const char *name, H5_ATTR_UNUSED const H5A_info_t *ainfo, - void *op_data) -{ - int ret = H5_ITER_CONT; - - /* check the arguments */ - if (name == NULL) - return H5_ITER_CONT; - - /* Shut compiler up */ - (void)loc_id; - (void)ainfo; - - /* Define a positive value for return value if the attribute was found. This will - * cause the iterator to immediately return that positive value, - * indicating short-circuit success - */ - - if (HDstrncmp(name, (char *)op_data, MAX(HDstrlen((char *)op_data), HDstrlen(name))) == 0) - ret = H5_ITER_STOP; - - return ret; -} - -/*------------------------------------------------------------------------- * Function: H5LTfind_attribute * * Purpose: Inquires if an attribute named attr_name exists attached to @@ -1926,32 +1886,22 @@ H5LTfind_attribute(hid_t loc_id, const char *attr_name) * * Date: June 21, 2001 * - * Comments: - * The function uses H5Aiterate2 with the operator function find_attr - * * Return: - * Success: The return value of the first operator that - * returns non-zero, or zero if all members were - * processed with no operator returning non-zero. + * Success: Positive if the attribute exists attached to the + * object loc_id. Zero if the attribute does not + * exist attached to the object loc_id. * * Failure: Negative if something goes wrong within the - * library, or the negative value returned by one - * of the operators. + * library. * *------------------------------------------------------------------------- */ -/* H5Aiterate wants a non-const pointer but we have a const pointer in the API - * call. It's safe to ignore this because we control the callback, don't - * modify the op_data buffer (i.e.: attr_name) during the traversal, and the - * library never modifies that buffer. - */ -H5_GCC_CLANG_DIAG_OFF("cast-qual") herr_t H5LT_find_attribute(hid_t loc_id, const char *attr_name) { - return H5Aiterate2(loc_id, H5_INDEX_NAME, H5_ITER_INC, NULL, find_attr, (void *)attr_name); + htri_t attr_exists = H5Aexists(loc_id, attr_name); + return (attr_exists < 0) ? (herr_t)-1 : (attr_exists) ? (herr_t)1 : (herr_t)0; } -H5_GCC_CLANG_DIAG_ON("cast-qual") /*------------------------------------------------------------------------- * Function: H5LTget_attribute_ndims @@ -2579,11 +2529,9 @@ H5LT_dtype_to_text(hid_t dtype, char *dt_str, H5LT_lang_t lang, size_t *slen, hb } else if (H5Tequal(dtype, H5T_NATIVE_DOUBLE)) { HDsnprintf(dt_str, *slen, "H5T_NATIVE_DOUBLE"); -#if H5_SIZEOF_LONG_DOUBLE != 0 } else if (H5Tequal(dtype, H5T_NATIVE_LDOUBLE)) { HDsnprintf(dt_str, *slen, "H5T_NATIVE_LDOUBLE"); -#endif } else { HDsnprintf(dt_str, *slen, "undefined float"); diff --git a/hl/test/CMakeTests.cmake b/hl/test/CMakeTests.cmake index 44208e3..e532253 100644 --- a/hl/test/CMakeTests.cmake +++ b/hl/test/CMakeTests.cmake @@ -31,7 +31,9 @@ set (HL_REFERENCE_TEST_FILES dslat.txt dslon.txt test_ds_be.h5 + test_ds_be_new_ref.h5 test_ds_le.h5 + test_ds_le_new_ref.h5 test_ld.h5 ) diff --git a/hl/test/gen_test_ds.c b/hl/test/gen_test_ds.c index a56e6cf..d7a9f44 100644 --- a/hl/test/gen_test_ds.c +++ b/hl/test/gen_test_ds.c @@ -63,7 +63,11 @@ static int test_foreign_scaleattached(const char *filename); #define SCALE_4_NAME "scalename_4_" #define FILENAME "test_ds_" -#define FILEEXT ".h5" +#ifdef H5_DIMENSION_SCALES_WITH_NEW_REF +#define FILEEXT "_new_ref.h5" +#else +#define FILEEXT ".h5" +#endif /*------------------------------------------------------------------------- * the main program diff --git a/hl/test/test_ds.c b/hl/test/test_ds.c index 964e13f..c66ef49 100644 --- a/hl/test/test_ds.c +++ b/hl/test/test_ds.c @@ -137,10 +137,15 @@ static int test_attach_detach(void); #define DIM0_LABEL "Latitude" #define DIM1_LABEL "Longitude" +#ifdef H5_DIMENSION_SCALES_WITH_NEW_REF +#define FOREIGN_FILE1 "test_ds_le_new_ref.h5" +#define FOREIGN_FILE2 "test_ds_be_new_ref.h5" +#else #define FOREIGN_FILE1 "test_ds_le.h5" #define FOREIGN_FILE2 "test_ds_be.h5" -#define FILENAME "test_ds" -#define FILEEXT ".h5" +#endif +#define FILENAME "test_ds" +#define FILEEXT ".h5" #define FILE1 "test_ds3.h5" #define FILE2 "test_ds4.h5" @@ -161,10 +166,15 @@ static int test_attach_detach(void); int main(void) { - int nerrors = 0; + hid_t file_id = H5I_INVALID_HID; + int nerrors = 0; /* create file to be used in following tests */ - if (create_test_file("1") < 0) { + if ((file_id = create_test_file("1")) < 0) { + nerrors = 1; + goto error; + } + if (H5Fclose(file_id) < 0) { nerrors = 1; goto error; } @@ -179,7 +189,11 @@ main(void) nerrors += test_long_scalenames("1") < 0 ? 1 : 0; nerrors += test_float_scalenames("1") < 0 ? 1 : 0; nerrors += test_numberofscales("1") < 0 ? 1 : 0; - if (create_test_file("2") < 0) { + if ((file_id = create_test_file("2")) < 0) { + nerrors = 1; + goto error; + } + if (H5Fclose(file_id) < 0) { nerrors = 1; goto error; } @@ -254,10 +268,9 @@ open_test_file(const char *fileext) herr_t create_char_dataset(hid_t fid, const char *dsidx, int fulldims) { - int rank = 3; - int rankds = 1; - hsize_t dims[3] = {DIM1_SIZE, DIM2_SIZE, DIM3_SIZE}; - char buf[DIM1_SIZE * DIM2_SIZE * DIM3_SIZE]; + int rank = 3; + int rankds = 1; + hsize_t dims[3] = {DIM1_SIZE, DIM2_SIZE, DIM3_SIZE}; hsize_t s1_dim[1] = {DIM1_SIZE}; hsize_t s2_dim[1] = {DIM2_SIZE}; hsize_t s3_dim[1] = {DIM3_SIZE}; @@ -275,7 +288,7 @@ create_char_dataset(hid_t fid, const char *dsidx, int fulldims) HDsnprintf(name, sizeof(name), "%s%s", DATASET_NAME, dsidx); /* make a dataset */ - if (H5LTmake_dataset_char(fid, name, rank, dims, buf) >= 0) { + if (H5LTmake_dataset_char(fid, name, rank, dims, NULL) >= 0) { if (fulldims == 0) { /* make a DS dataset for the first dimension */ if (create_DS1_char_datasets(fid, dsidx, rankds, s1_dim, s1_wbuf, NULL) < 0) @@ -309,10 +322,9 @@ create_char_dataset(hid_t fid, const char *dsidx, int fulldims) herr_t create_short_dataset(hid_t fid, const char *dsidx, int fulldims) { - int rank = 3; - int rankds = 1; - hsize_t dims[3] = {DIM1_SIZE, DIM2_SIZE, DIM3_SIZE}; - short buf[DIM1_SIZE * DIM2_SIZE * DIM3_SIZE]; + int rank = 3; + int rankds = 1; + hsize_t dims[3] = {DIM1_SIZE, DIM2_SIZE, DIM3_SIZE}; hsize_t s1_dim[1] = {DIM1_SIZE}; hsize_t s2_dim[1] = {DIM2_SIZE}; hsize_t s3_dim[1] = {DIM3_SIZE}; @@ -330,7 +342,7 @@ create_short_dataset(hid_t fid, const char *dsidx, int fulldims) HDsnprintf(name, sizeof(name), "%s%s", DATASET_NAME, dsidx); /* make a dataset */ - if (H5LTmake_dataset_short(fid, name, rank, dims, buf) >= 0) { + if (H5LTmake_dataset_short(fid, name, rank, dims, NULL) >= 0) { if (fulldims == 0) { /* make a DS dataset for the first dimension */ if (create_DS1_short_datasets(fid, dsidx, rankds, s1_dim, s1_wbuf, NULL) < 0) @@ -364,10 +376,9 @@ create_short_dataset(hid_t fid, const char *dsidx, int fulldims) herr_t create_int_dataset(hid_t fid, const char *dsidx, int fulldims) { - int rank = RANK; - int rankds = 1; - hsize_t dims[RANK] = {DIM1_SIZE, DIM2_SIZE}; - int buf[DIM1_SIZE * DIM2_SIZE]; + int rank = RANK; + int rankds = 1; + hsize_t dims[RANK] = {DIM1_SIZE, DIM2_SIZE}; hsize_t s1_dim[1] = {DIM1_SIZE}; hsize_t s2_dim[1] = {DIM2_SIZE}; int s1_wbuf[DIM1_SIZE] = {10, 20, 30}; @@ -380,7 +391,7 @@ create_int_dataset(hid_t fid, const char *dsidx, int fulldims) HDsnprintf(name, sizeof(name), "%s%s", DATASET_NAME, dsidx); /* make a dataset */ - if (H5LTmake_dataset_int(fid, name, rank, dims, buf) >= 0) { + if (H5LTmake_dataset_int(fid, name, rank, dims, NULL) >= 0) { if (fulldims == 0) { /* make a DS dataset for the first dimension */ if (create_DS1_int_datasets(fid, dsidx, rankds, s1_dim, s1_wbuf, NULL) < 0) @@ -409,7 +420,6 @@ create_long_dataset(hid_t fid, const char *dsname, const char *dsidx, int fulldi int rank = 4; int rankds = 1; hsize_t dims[4] = {DIM1_SIZE, DIM2_SIZE, DIM3_SIZE, DIM4_SIZE}; - long * buf = NULL; hsize_t s1_dim[1] = {DIM1_SIZE}; hsize_t s2_dim[1] = {DIM2_SIZE}; hsize_t s3_dim[1] = {DIM3_SIZE}; @@ -429,12 +439,8 @@ create_long_dataset(hid_t fid, const char *dsname, const char *dsidx, int fulldi long s43_wbuf[DIM4_SIZE] = {180, 180}; long s44_wbuf[DIM4_SIZE] = {280, 280}; - /* Allocate buffer */ - if (NULL == (buf = (long *)HDmalloc(sizeof(long) * DIM1_SIZE * DIM2_SIZE * DIM3_SIZE * DIM4_SIZE))) - goto error; - /* make a dataset */ - if (H5LTmake_dataset_long(fid, dsname, rank, dims, buf) >= 0) { + if (H5LTmake_dataset_long(fid, dsname, rank, dims, NULL) >= 0) { if (fulldims == 0) { /* make a DS dataset for the first dimension */ if (create_DS1_long_datasets(fid, dsidx, rankds, s1_dim, s1_wbuf, NULL) < 0) @@ -471,23 +477,18 @@ create_long_dataset(hid_t fid, const char *dsname, const char *dsidx, int fulldi else goto error; - HDfree(buf); - return SUCCEED; error: - HDfree(buf); - return FAIL; } herr_t create_float_dataset(hid_t fid, const char *dsidx, int fulldims) { - int rank = RANK; - int rankds = 1; - hsize_t dims[RANK] = {DIM1_SIZE, DIM2_SIZE}; - float buf[DIM1_SIZE * DIM2_SIZE]; + int rank = RANK; + int rankds = 1; + hsize_t dims[RANK] = {DIM1_SIZE, DIM2_SIZE}; hsize_t s1_dim[1] = {DIM1_SIZE}; hsize_t s2_dim[1] = {DIM2_SIZE}; float s1_wbuf[DIM1_SIZE] = {10, 20, 30}; @@ -500,7 +501,7 @@ create_float_dataset(hid_t fid, const char *dsidx, int fulldims) HDsnprintf(name, sizeof(name), "%s%s", DATASET_NAME, dsidx); /* make a dataset */ - if (H5LTmake_dataset_float(fid, name, rank, dims, buf) >= 0) { + if (H5LTmake_dataset_float(fid, name, rank, dims, NULL) >= 0) { if (fulldims == 0) { /* make a DS dataset for the first dimension */ if (create_DS1_float_datasets(fid, dsidx, rankds, s1_dim, s1_wbuf, NULL) < 0) diff --git a/hl/test/test_ds_be_new_ref-32bit.h5 b/hl/test/test_ds_be_new_ref-32bit.h5 new file mode 100644 index 0000000..ee327e9 Binary files /dev/null and b/hl/test/test_ds_be_new_ref-32bit.h5 differ diff --git a/hl/test/test_ds_be_new_ref.h5 b/hl/test/test_ds_be_new_ref.h5 new file mode 100644 index 0000000..eddfa02 Binary files /dev/null and b/hl/test/test_ds_be_new_ref.h5 differ diff --git a/hl/test/test_ds_le_new_ref.h5 b/hl/test/test_ds_le_new_ref.h5 new file mode 100644 index 0000000..8625d77 Binary files /dev/null and b/hl/test/test_ds_le_new_ref.h5 differ diff --git a/hl/test/test_packet_vlen.c b/hl/test/test_packet_vlen.c index c668a07..6d6bf34 100644 --- a/hl/test/test_packet_vlen.c +++ b/hl/test/test_packet_vlen.c @@ -539,8 +539,8 @@ test_VLof_VLtype(void) HDfprintf(stderr, "Cannot allocate memory for VL data! uu=%u\n", uu); goto error; } - t1->len = vv * 1; - for (ww = 0; ww < (vv * 1); ww++) + t1->len = vv + 1; + for (ww = 0; ww < (vv + 1); ww++) ((unsigned int *)t1->p)[ww] = uu * 100 + vv * 10 + ww; } /* end for */ } /* end for */ diff --git a/java/src/hdf/hdf5lib/CMakeLists.txt b/java/src/hdf/hdf5lib/CMakeLists.txt index 5651031..a26e117 100644 --- a/java/src/hdf/hdf5lib/CMakeLists.txt +++ b/java/src/hdf/hdf5lib/CMakeLists.txt @@ -40,6 +40,11 @@ set (HDF5_JAVA_HDF_HDF5_CALLBACKS_SOURCES callbacks/Callbacks.java ) +set (HDF5_JAVADOC_HDF_HDF5_CALLBACKS_SOURCES + ${HDF5_JAVA_HDF_HDF5_CALLBACKS_SOURCES} + callbacks/package-info.java +) + set (HDF5_JAVA_HDF_HDF5_EXCEPTIONS_SOURCES exceptions/HDF5Exception.java exceptions/HDF5IdException.java @@ -67,6 +72,11 @@ set (HDF5_JAVA_HDF_HDF5_EXCEPTIONS_SOURCES exceptions/HDF5SymbolTableException.java ) +set (HDF5_JAVADOC_HDF_HDF5_EXCEPTIONS_SOURCES + ${HDF5_JAVA_HDF_HDF5_EXCEPTIONS_SOURCES} + exceptions/package-info.java +) + set (HDF5_JAVA_HDF_HDF5_STRUCTS_SOURCES structs/H5_ih_info_t.java structs/H5A_info_t.java @@ -83,6 +93,11 @@ set (HDF5_JAVA_HDF_HDF5_STRUCTS_SOURCES structs/H5O_token_t.java ) +set (HDF5_JAVADOC_HDF_HDF5_STRUCTS_SOURCES + ${HDF5_JAVA_HDF_HDF5_STRUCTS_SOURCES} + structs/package-info.java +) + set (HDF5_JAVA_HDF_HDF5_SOURCES HDFArray.java HDF5Constants.java @@ -91,6 +106,11 @@ set (HDF5_JAVA_HDF_HDF5_SOURCES H5.java ) +set (HDF5_JAVADOC_HDF_HDF5_SOURCES + ${HDF5_JAVA_HDF_HDF5_SOURCES} + package-info.java +) + set (CMAKE_JNI_TARGET TRUE) file (WRITE ${PROJECT_BINARY_DIR}/Manifest.txt @@ -114,7 +134,7 @@ add_dependencies (${HDF5_JAVA_HDF5_LIB_TARGET} ${HDF5_JAVA_JNI_LIB_TARGET}) set_target_properties (${HDF5_JAVA_HDF5_LIB_TARGET} PROPERTIES FOLDER libraries/java) create_javadoc(hdf5_java_doc - FILES ${HDF5_JAVA_HDF_HDF5_CALLBACKS_SOURCES} ${HDF5_JAVA_HDF_HDF5_EXCEPTIONS_SOURCES} ${HDF5_JAVA_HDF_HDF5_STRUCTS_SOURCES} ${HDF5_JAVA_HDF_HDF5_SOURCES} + FILES ${HDF5_JAVADOC_HDF_HDF5_CALLBACKS_SOURCES} ${HDF5_JAVADOC_HDF_HDF5_EXCEPTIONS_SOURCES} ${HDF5_JAVADOC_HDF_HDF5_STRUCTS_SOURCES} ${HDF5_JAVADOC_HDF_HDF5_SOURCES} OVERVIEW ${HDF5_JAVA_HDF5_SRC_DIR}/overview.html CLASSPATH ${CMAKE_JAVA_INCLUDE_PATH} WINDOWTITLE "HDF5 Java" diff --git a/java/src/hdf/hdf5lib/H5.java b/java/src/hdf/hdf5lib/H5.java index 63547df..4129f50 100644 --- a/java/src/hdf/hdf5lib/H5.java +++ b/java/src/hdf/hdf5lib/H5.java @@ -64,8 +64,8 @@ import hdf.hdf5lib.structs.H5O_token_t; * This code is the called by Java programs to access the entry points of the HDF5 library. Each routine wraps a single * HDF5 entry point, generally with the arguments and return codes analogous to the C interface. *

- * For details of the HDF5 library, see the HDF5 Documentation at: http://hdfgroup.org/HDF5/ + * For details of the HDF5 library, see the HDF5 Documentation at: + * http://hdfgroup.org/HDF5/ *


*

* Mapping of arguments for Java @@ -162,8 +162,8 @@ import hdf.hdf5lib.structs.H5O_token_t; *

* For Java, this ``ANY'' is a problem, as the type of data must always be declared. Furthermore, multidimensional * arrays are definitely not layed out contiguously in memory. It would be infeasible to declare a separate - * routine for every combination of number type and dimensionality. For that reason, the HDFArray class is used to discover the type, shape, and size of the + * routine for every combination of number type and dimensionality. For that reason, the + * HDFArray class is used to discover the type, shape, and size of the * data array at run time, and to convert to and from a contiguous array of bytes in synchronized static native C order. *

* The upshot is that any Java array of numbers (either primitive or sub-classes of type Number) can be passed as @@ -187,8 +187,8 @@ import hdf.hdf5lib.structs.H5O_token_t; * H5F_ACC_RDWR and H5P_DEFAULT. *

* The HDF-5 API defines a set of values that describe number types and sizes, such as "H5T_NATIVE_INT" and "hsize_t". - * These values are determined at run time by the HDF-5 C library. To support these parameters, the Java class HDF5CDataTypes looks up the values when initiated. The values + * These values are determined at run time by the HDF-5 C library. To support these parameters, the Java class + * HDF5CDataTypes looks up the values when initiated. The values * can be accessed as public variables of the Java class, such as: * *

@@ -204,8 +204,8 @@ import hdf.hdf5lib.structs.H5O_token_t;
  * JHI5. Errors are converted into Java exceptions. This is totally different from the C interface, but is very natural
  * for Java programming.
  * 

- * The exceptions of the JHI5 are organized as sub-classes of the class HDF5Exception. There are two subclasses of + * The exceptions of the JHI5 are organized as sub-classes of the class + * HDF5Exception. There are two subclasses of * HDF5Exception, HDF5LibraryException * and HDF5JavaException. The sub-classes of the * former represent errors from the HDF-5 C library, while sub-classes of the latter represent errors in the JHI5 @@ -216,7 +216,7 @@ import hdf.hdf5lib.structs.H5O_token_t; * exception handlers to print out the HDF-5 error stack. *


* - * @version HDF5 1.13.0
+ * @version HDF5 1.13.1
* See also: hdf.hdf5lib.HDFArray
* hdf.hdf5lib.HDF5Constants
* hdf.hdf5lib.HDF5CDataTypes
@@ -239,7 +239,7 @@ public class H5 implements java.io.Serializable { * * Make sure to update the versions number when a different library is used. */ - public final static int LIB_VERSION[] = { 1, 13, 0 }; + public final static int LIB_VERSION[] = { 1, 13, 1 }; /** * add system property to load library by path @@ -12776,8 +12776,11 @@ public class H5 implements java.io.Serializable { * IN: Field name of the field index to retrieve. * * @return if field is defined, the index; else negative. + * + * @exception HDF5LibraryException + * - Error from the HDF-5 Library. **/ - public synchronized static native int H5Tget_member_index(long type_id, String field_name); + public synchronized static native int H5Tget_member_index(long type_id, String field_name) throws HDF5LibraryException; /** * H5Tget_member_name retrieves the name of a field of a compound datatype or an element of an enumeration datatype. @@ -12788,8 +12791,11 @@ public class H5 implements java.io.Serializable { * IN: Field index (0-based) of the field name to retrieve. * * @return a valid pointer to the name if successful; otherwise null. + * + * @exception HDF5LibraryException + * - Error from the HDF-5 Library. **/ - public synchronized static native String H5Tget_member_name(long type_id, int field_idx); + public synchronized static native String H5Tget_member_name(long type_id, int field_idx) throws HDF5LibraryException; /** * H5Tget_member_offset returns the byte offset of the specified member of the compound datatype. This is the byte @@ -12801,11 +12807,8 @@ public class H5 implements java.io.Serializable { * IN: Field index (0-based) of the field type to retrieve. * * @return the offset of the member. - * - * @exception HDF5LibraryException - * - Error from the HDF-5 Library. **/ - public synchronized static native long H5Tget_member_offset(long type_id, int membno) throws HDF5LibraryException; + public synchronized static native long H5Tget_member_offset(long type_id, int membno); /** * H5Tget_member_type returns the datatype of the specified member. @@ -13460,7 +13463,7 @@ public class H5 implements java.io.Serializable { * @exception HDF5LibraryException * - Error from the HDF-5 Library. **/ - public synchronized static native long H5VLregister_connector_by_name(String connector_name, long vipl_id); + public synchronized static native long H5VLregister_connector_by_name(String connector_name, long vipl_id) throws HDF5LibraryException; /** * H5VLregister_connector_by_value registers a new VOL connector as a member of the virtual object layer class. * @@ -13475,7 +13478,7 @@ public class H5 implements java.io.Serializable { * @exception HDF5LibraryException * - Error from the HDF-5 Library. **/ - public synchronized static native long H5VLregister_connector_by_value(int connector_value, long vipl_id); + public synchronized static native long H5VLregister_connector_by_value(int connector_value, long vipl_id) throws HDF5LibraryException; /** * H5VLis_connector_registered_by_name tests whether a VOL class has been registered. * @@ -13487,7 +13490,7 @@ public class H5 implements java.io.Serializable { * @exception HDF5LibraryException * - Error from the HDF-5 Library. **/ - public synchronized static native boolean H5VLis_connector_registered_by_name(String name); + public synchronized static native boolean H5VLis_connector_registered_by_name(String name) throws HDF5LibraryException; /** * H5VLis_connector_registered_by_value tests whether a VOL class has been registered. * @@ -13499,7 +13502,7 @@ public class H5 implements java.io.Serializable { * @exception HDF5LibraryException * - Error from the HDF-5 Library. **/ - public synchronized static native boolean H5VLis_connector_registered_by_value(int connector_value); + public synchronized static native boolean H5VLis_connector_registered_by_value(int connector_value) throws HDF5LibraryException; /** * H5VLget_connector_id retrieves the ID for a registered VOL connector for a given object. * @@ -13511,7 +13514,7 @@ public class H5 implements java.io.Serializable { * @exception HDF5LibraryException * - Error from the HDF-5 Library. **/ - public synchronized static native long H5VLget_connector_id(long object_id); + public synchronized static native long H5VLget_connector_id(long object_id) throws HDF5LibraryException; /** * H5VLget_connector_id_by_name retrieves the ID for a registered VOL connector. * @@ -13523,7 +13526,7 @@ public class H5 implements java.io.Serializable { * @exception HDF5LibraryException * - Error from the HDF-5 Library. **/ - public synchronized static native long H5VLget_connector_id_by_name(String name); + public synchronized static native long H5VLget_connector_id_by_name(String name) throws HDF5LibraryException; /** * H5VLget_connector_id_by_value retrieves the ID for a registered VOL connector. * @@ -13535,7 +13538,7 @@ public class H5 implements java.io.Serializable { * @exception HDF5LibraryException * - Error from the HDF-5 Library. **/ - public synchronized static native long H5VLget_connector_id_by_value(int connector_value); + public synchronized static native long H5VLget_connector_id_by_value(int connector_value) throws HDF5LibraryException; /** * H5VLget_connector_name returns the connector name for the VOL associated with the * object or file ID. @@ -13548,7 +13551,7 @@ public class H5 implements java.io.Serializable { * @exception HDF5LibraryException * - Error from the HDF-5 Library. **/ - public synchronized static native String H5VLget_connector_name(long object_id); + public synchronized static native String H5VLget_connector_name(long object_id) throws HDF5LibraryException; /** * H5VLclose closes a VOL connector ID. * @@ -13558,7 +13561,7 @@ public class H5 implements java.io.Serializable { * @exception HDF5LibraryException * - Error from the HDF-5 Library. **/ - public synchronized static native void H5VLclose(long connector_id); + public synchronized static native void H5VLclose(long connector_id) throws HDF5LibraryException; /** * H5VLunregister_connector removes a VOL connector ID from the library. * @@ -13568,7 +13571,7 @@ public class H5 implements java.io.Serializable { * @exception HDF5LibraryException * - Error from the HDF-5 Library. **/ - public synchronized static native void H5VLunregister_connector(long connector_id); + public synchronized static native void H5VLunregister_connector(long connector_id) throws HDF5LibraryException; // /////// unimplemented //////// // hid_t H5VLregister_connector(const H5VL_class_t *cls, hid_t vipl_id); diff --git a/java/src/hdf/hdf5lib/callbacks/package-info.java b/java/src/hdf/hdf5lib/callbacks/package-info.java new file mode 100644 index 0000000..0833162 --- /dev/null +++ b/java/src/hdf/hdf5lib/callbacks/package-info.java @@ -0,0 +1,27 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/** All callback definitions must derive from the Callbacks interface. Any + * derived interfaces must define a single public method named "callback". + * You are responsible for deregistering your callback (if necessary) + * in its {@link Object#finalize} method. If native code attempts to call + * a callback which has been GC'd, you will likely crash the VM. If + * there is no method to deregister the callback (e.g. atexit + * in the C library), you must ensure that you always keep a live reference + * to the callback object.

+ * A callback should generally never throw an exception, since it doesn't + * necessarily have an encompassing Java environment to catch it. Any + * exceptions thrown will be passed to the default callback exception + * handler. + */ +package hdf.hdf5lib.callbacks; diff --git a/java/src/hdf/hdf5lib/exceptions/package-info.java b/java/src/hdf/hdf5lib/exceptions/package-info.java new file mode 100644 index 0000000..8640ccb --- /dev/null +++ b/java/src/hdf/hdf5lib/exceptions/package-info.java @@ -0,0 +1,31 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/** + *

+ * The package exceptions contains error classes for the Java HDF5 Interface. + *

+ * There are two sub-classes of exceptions defined: + *

    + *
  1. + * HDF5LibraryException -- errors raised the HDF5 library code + *
  2. + * HDF5JavaException -- errors raised the HDF5 Java wrapper code + *
+ *

+ * The HDF5LibraryException is the base class for the classes that represent specific error conditions. + * In particular, HDF5LibraryException has a sub-class for each major + * error code returned by the HDF5 library. + * + */ +package hdf.hdf5lib.exceptions; \ No newline at end of file diff --git a/java/src/hdf/hdf5lib/package-info.java b/java/src/hdf/hdf5lib/package-info.java new file mode 100644 index 0000000..838a266 --- /dev/null +++ b/java/src/hdf/hdf5lib/package-info.java @@ -0,0 +1,174 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * This package is the Java interface for the HDF5 library. + *

+ * This code is the called by Java programs to access the entry points of the HDF5 library. Each routine wraps a single + * HDF5 entry point, generally with the arguments and return codes analogous to the C interface. + *

+ * For details of the HDF5 library, see the HDF5 Documentation at: + * http://hdfgroup.org/HDF5/ + *


+ *

+ * Mapping of arguments for Java + * + *

+ * In general, arguments to the HDF Java API are straightforward translations from the 'C' API described in the HDF + * Reference Manual. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
HDF-5 C types to Java types
HDF-5Java
H5T_NATIVE_INTint, Integer
H5T_NATIVE_SHORTshort, Short
H5T_NATIVE_FLOATfloat, Float
H5T_NATIVE_DOUBLEdouble, Double
H5T_NATIVE_CHARbyte, Byte
H5T_C_S1java.lang.String
void *
+ * (i.e., pointer to `Any')
Special -- see HDFArray
+ * General Rules for Passing Arguments and Results + *

+ * In general, arguments passed IN to Java are the analogous basic types, as above. The exception is for arrays, + * which are discussed below. + *

+ * The return value of Java methods is also the analogous type, as above. A major exception to that rule is that + * all HDF functions that return SUCCEED/FAIL are declared boolean in the Java version, rather than int as + * in the C. Functions that return a value or else FAIL are declared the equivalent to the C function. However, in most + * cases the Java method will raise an exception instead of returning an error code. + * See Errors and Exceptions below. + *

+ * Java does not support pass by reference of arguments, so arguments that are returned through OUT parameters + * must be wrapped in an object or array. The Java API for HDF consistently wraps arguments in arrays. + *

+ * For instance, a function that returns two integers is declared: + * + *

+ *       h_err_t HDF5dummy( int *a1, int *a2)
+ * 
+ * + * For the Java interface, this would be declared: + * + *
+ * public synchronized static native void HDF5dummy(int args[]);
+ * 
+ * + * where a1 is args[0] and a2 is args[1], and would be invoked: + * + *
+ * H5.HDF5dummy(a);
+ * 
+ * + *

+ * All the routines where this convention is used will have specific documentation of the details, given below. + *

+ * Arrays + *

+ * HDF5 needs to read and write multi-dimensional arrays of any number type (and records). The HDF5 API describes the + * layout of the source and destination, and the data for the array passed as a block of bytes, for instance, + * + *

+ *      herr_t H5Dread(long fid, long filetype, long memtype, long memspace, void *data);
+ * 
+ * + *

+ * where ``void *'' means that the data may be any valid numeric type, and is a contiguous block of bytes that is the + * data for a multi-dimensional array. The other parameters describe the dimensions, rank, and datatype of the array on + * disk (source) and in memory (destination). + *

+ * For Java, this ``ANY'' is a problem, as the type of data must always be declared. Furthermore, multidimensional + * arrays are definitely not layed out contiguously in memory. It would be infeasible to declare a separate + * routine for every combination of number type and dimensionality. For that reason, the + * HDFArray class is used to discover the type, shape, and size of the + * data array at run time, and to convert to and from a contiguous array of bytes in synchronized static native C order. + *

+ * The upshot is that any Java array of numbers (either primitive or sub-classes of type Number) can be passed as + * an ``Object'', and the Java API will translate to and from the appropriate packed array of bytes needed by the C + * library. So the function above would be declared: + * + *

+ * public synchronized static native int H5Dread(long fid, long filetype, long memtype, long memspace, Object data);
+ * 
+ * OPEN_IDS.addElement(id); + + * and the parameter data can be any multi-dimensional array of numbers, such as float[][], or int[][][], or + * Double[][]. + *

+ * HDF-5 Constants + *

+ * The HDF-5 API defines a set of constants and enumerated values. Most of these values are available to Java programs + * via the class HDF5Constants. For example, the parameters for + * the h5open() call include two numeric values, HDFConstants.H5F_ACC_RDWR and + * HDF5Constants.H5P_DEFAULT. As would be expected, these numbers correspond to the C constants + * H5F_ACC_RDWR and H5P_DEFAULT. + *

+ * The HDF-5 API defines a set of values that describe number types and sizes, such as "H5T_NATIVE_INT" and "hsize_t". + * These values are determined at run time by the HDF-5 C library. To support these parameters, the Java class + * HDF5CDataTypes looks up the values when initiated. The values + * can be accessed as public variables of the Java class, such as: + * + *

+ * long data_type = HDF5CDataTypes.JH5T_NATIVE_INT;
+ * 
+ * + * The Java application uses both types of constants the same way, the only difference is that the + * HDF5CDataTypes may have different values on different platforms. + *

+ * Error handling and Exceptions + *

+ * The HDF5 error API (H5E) manages the behavior of the error stack in the HDF-5 library. This API is available from the + * JHI5. Errors are converted into Java exceptions. This is totally different from the C interface, but is very natural + * for Java programming. + *

+ * The exceptions of the JHI5 are organized as sub-classes of the class + * HDF5Exception. There are two subclasses of + * HDF5Exception, HDF5LibraryException + * and HDF5JavaException. The sub-classes of the + * former represent errors from the HDF-5 C library, while sub-classes of the latter represent errors in the JHI5 + * wrapper and support code. + *

+ * The super-class HDF5LibraryException implements the method 'printStackTrace()', which + * prints out the HDF-5 error stack, as described in the HDF-5 C API H5Eprint(). This may be used by Java + * exception handlers to print out the HDF-5 error stack. + *


+ * + * See also: http://hdfgroup.org/HDF5" + **/ +package hdf.hdf5lib; \ No newline at end of file diff --git a/java/src/hdf/hdf5lib/structs/package-info.java b/java/src/hdf/hdf5lib/structs/package-info.java new file mode 100644 index 0000000..8a9d97d --- /dev/null +++ b/java/src/hdf/hdf5lib/structs/package-info.java @@ -0,0 +1,17 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/** All structure definitions define java equivalents of the C structures needed + * by the C API calls. See the C API for information about the structures. + */ +package hdf.hdf5lib.structs; diff --git a/java/src/jni/h5util.c b/java/src/jni/h5util.c index 4272205..7313c28 100644 --- a/java/src/jni/h5util.c +++ b/java/src/jni/h5util.c @@ -237,7 +237,7 @@ h5str_convert(JNIEnv *env, char **in_str, hid_t container, hid_t tid, void *out_ HDmemcpy(cptr, &tmp_double, sizeof(double)); break; } -#if H5_SIZEOF_LONG_DOUBLE != 0 && H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE +#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE case sizeof(long double): { long double tmp_ldouble = 0.0; @@ -658,8 +658,6 @@ h5str_sprint_reference(JNIEnv *env, h5str_t *out_str, void *ref_p) int ret_value = FAIL; - if (!h5str_append(out_str, " \"")) - H5_ASSERTION_ERROR(ENVONLY, "Unable to append string."); buf_size = H5Rget_file_name(ref_vp, NULL, 0); if (buf_size) { ref_name = (char *)HDmalloc(sizeof(char) * (size_t)buf_size + 1); @@ -697,8 +695,6 @@ h5str_sprint_reference(JNIEnv *env, h5str_t *out_str, void *ref_p) ref_name = NULL; } } - if (!h5str_append(out_str, "\"")) - H5_ASSERTION_ERROR(ENVONLY, "Unable to append string."); ret_value = SUCCEED; done: @@ -725,6 +721,10 @@ h5str_region_dataset(JNIEnv *env, h5str_t *out_str, H5R_ref_t *ref_vp, int expan if ((new_obj_sid = H5Ropen_region(ref_vp, H5P_DEFAULT, H5P_DEFAULT)) < 0) H5_LIBRARY_ERROR(ENVONLY); + if (expand_data == 0) + if (h5str_sprint_reference(ENVONLY, out_str, ref_vp) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + if ((region_type = H5Sget_select_type(new_obj_sid)) > H5S_SEL_ERROR) { if (H5S_SEL_POINTS == region_type) { if (h5str_dump_region_points(ENVONLY, out_str, new_obj_sid, new_obj_id, expand_data) < 0) @@ -816,7 +816,7 @@ h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *i break; } -#if H5_SIZEOF_LONG_DOUBLE != 0 && H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE +#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE case sizeof(long double): { long double tmp_ldouble = 0.0; diff --git a/java/test/CMakeLists.txt b/java/test/CMakeLists.txt index ffaf5f5..c6cf607 100644 --- a/java/test/CMakeLists.txt +++ b/java/test/CMakeLists.txt @@ -113,14 +113,14 @@ endif () get_property (target_name TARGET ${HDF5_JAVA_JNI_LIB_TARGET} PROPERTY OUTPUT_NAME) set (CMD_ARGS "-Dhdf.hdf5lib.H5.loadLibraryName=${target_name}$<$:${CMAKE_DEBUG_POSTFIX}>;") +set (CMAKE_JAVA_CLASSPATH ".") +foreach (CMAKE_INCLUDE_PATH ${CMAKE_JAVA_INCLUDE_PATH}) + set (CMAKE_JAVA_CLASSPATH "${CMAKE_JAVA_CLASSPATH}${CMAKE_JAVA_INCLUDE_FLAG_SEP}${CMAKE_INCLUDE_PATH}") +endforeach () if (HDF5_TEST_JAVA AND HDF5_TEST_SERIAL) foreach (test_file ${HDF5_JAVA_TEST_SOURCES}) - set (CMAKE_JAVA_CLASSPATH ".") - foreach (CMAKE_INCLUDE_PATH ${CMAKE_JAVA_INCLUDE_PATH}) - set (CMAKE_JAVA_CLASSPATH "${CMAKE_JAVA_CLASSPATH}${CMAKE_JAVA_INCLUDE_FLAG_SEP}${CMAKE_INCLUDE_PATH}") - endforeach () - set (CMAKE_JAVA_CLASSPATH "${CMAKE_JAVA_CLASSPATH}${CMAKE_JAVA_INCLUDE_FLAG_SEP}${${HDF5_JAVA_TEST_LIB_TARGET}_${test_file}_JAR_FILE}") + set (TEST_JAVA_CLASSPATH "${CMAKE_JAVA_CLASSPATH}${CMAKE_JAVA_INCLUDE_FLAG_SEP}${${HDF5_JAVA_TEST_LIB_TARGET}_${test_file}_JAR_FILE}") add_test ( NAME JUnit-${test_file}-clearall-objects @@ -132,7 +132,7 @@ if (HDF5_TEST_JAVA AND HDF5_TEST_SERIAL) NAME JUnit-${test_file} COMMAND "${CMAKE_COMMAND}" -D "TEST_TESTER=${CMAKE_Java_RUNTIME};${CMAKE_Java_RUNTIME_FLAGS}" - -D "TEST_CLASSPATH:STRING=${CMAKE_JAVA_CLASSPATH}" + -D "TEST_CLASSPATH:STRING=${TEST_JAVA_CLASSPATH}" -D "TEST_ARGS:STRING=${CMD_ARGS}-ea;org.junit.runner.JUnitCore" -D "TEST_PROGRAM=test.${test_file}" -D "TEST_LIBRARY_DIRECTORY=${CMAKE_TEST_OUTPUT_DIRECTORY}" @@ -184,7 +184,7 @@ if (HDF5_TEST_JAVA AND HDF5_TEST_SERIAL) -D "TEST_MASK_ERROR=TRUE" # -D "TEST_FILTER:STRING=${testfilter}" -D "TEST_REFERENCE=JUnit-${volname}-${voltest}.txt" - -P "${HDF_RESOURCES_DIR}/jvolTest.cmake" + -P "${HDF_RESOURCES_DIR}/jrunTest.cmake" ) set_tests_properties (JUnit-VOL-${volname}-${voltest} PROPERTIES ENVIRONMENT "HDF5_PLUGIN_PATH=${CMAKE_BINARY_DIR}/testdir2" @@ -228,12 +228,8 @@ if (HDF5_TEST_JAVA AND HDF5_TEST_SERIAL) foreach (volinfo IN LISTS ${voltest}) foreach (h5_file ${HDF5_JAVA_TEST_SOURCES}) - set (CMAKE_JAVA_CLASSPATH ".") - foreach (CMAKE_INCLUDE_PATH ${CMAKE_JAVA_INCLUDE_PATH}) - set (CMAKE_JAVA_CLASSPATH "${CMAKE_JAVA_CLASSPATH}${CMAKE_JAVA_INCLUDE_FLAG_SEP}${CMAKE_INCLUDE_PATH}") - endforeach () - set (CMAKE_JAVA_CLASSPATH "${CMAKE_JAVA_CLASSPATH}${CMAKE_JAVA_INCLUDE_FLAG_SEP}${${HDF5_JAVA_TEST_LIB_TARGET}_${h5_file}_JAR_FILE}") - DO_VOL_TEST (${h5_file} ${voltest} "${volinfo}" ${CMAKE_JAVA_CLASSPATH}) + set (VOL_JAVA_CLASSPATH "${CMAKE_JAVA_CLASSPATH}${CMAKE_JAVA_INCLUDE_FLAG_SEP}${${HDF5_JAVA_TEST_LIB_TARGET}_${h5_file}_JAR_FILE}") + DO_VOL_TEST (${h5_file} ${voltest} "${volinfo}" "${VOL_JAVA_CLASSPATH}") endforeach () endforeach () endforeach () diff --git a/java/test/TestH5.java b/java/test/TestH5.java index 1f298f3..1f81f09 100644 --- a/java/test/TestH5.java +++ b/java/test/TestH5.java @@ -287,7 +287,7 @@ public class TestH5 { */ @Test public void testH5get_libversion() { - int libversion[] = { 1, 13, 0 }; + int libversion[] = { 1, 13, 1 }; try { H5.H5get_libversion(libversion); @@ -326,7 +326,7 @@ public class TestH5 { */ @Test public void testH5check_version() { - int majnum = 1, minnum = 13, relnum = 0; + int majnum = 1, minnum = 13, relnum = 1; try { H5.H5check_version(majnum, minnum, relnum); diff --git a/m4/aclocal_fc.f90 b/m4/aclocal_fc.f90 index e9a11c0..240a768 100644 --- a/m4/aclocal_fc.f90 +++ b/m4/aclocal_fc.f90 @@ -82,6 +82,7 @@ END PROGRAM PROG_FC_C_LONG_DOUBLE_EQ_C_DOUBLE !---- START ----- Determine the available KINDs for REALs and INTEGERs PROGRAM FC_AVAIL_KINDS + USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : stderr=>ERROR_UNIT IMPLICIT NONE INTEGER :: ik, jk, k, kk, max_decimal_prec INTEGER :: prev_rkind, num_rkinds = 1, num_ikinds = 1 @@ -89,8 +90,6 @@ PROGRAM FC_AVAIL_KINDS INTEGER, DIMENSION(1:10) :: list_rkinds = -1 LOGICAL :: new_kind - OPEN(8, FILE='pac_fconftest.out', FORM='formatted') - ! Find integer KINDs list_ikinds(num_ikinds)=SELECTED_INT_KIND(1) DO ik = 2, 36 @@ -103,11 +102,11 @@ PROGRAM FC_AVAIL_KINDS ENDDO DO k = 1, num_ikinds - WRITE(8,'(I0)', ADVANCE='NO') list_ikinds(k) + WRITE(stderr,'(I0)', ADVANCE='NO') list_ikinds(k) IF(k.NE.num_ikinds)THEN - WRITE(8,'(A)',ADVANCE='NO') ',' + WRITE(stderr,'(A)',ADVANCE='NO') ',' ELSE - WRITE(8,'()') + WRITE(stderr,'()') ENDIF ENDDO @@ -140,17 +139,17 @@ PROGRAM FC_AVAIL_KINDS ENDDO prec DO k = 1, num_rkinds - WRITE(8,'(I0)', ADVANCE='NO') list_rkinds(k) + WRITE(stderr,'(I0)', ADVANCE='NO') list_rkinds(k) IF(k.NE.num_rkinds)THEN - WRITE(8,'(A)',ADVANCE='NO') ',' + WRITE(stderr,'(A)',ADVANCE='NO') ',' ELSE - WRITE(8,'()') + WRITE(stderr,'()') ENDIF ENDDO - WRITE(8,'(I0)') max_decimal_prec - WRITE(8,'(I0)') num_ikinds - WRITE(8,'(I0)') num_rkinds + WRITE(stderr,'(I0)') max_decimal_prec + WRITE(stderr,'(I0)') num_ikinds + WRITE(stderr,'(I0)') num_rkinds END PROGRAM FC_AVAIL_KINDS !---- END ----- Determine the available KINDs for REALs and INTEGERs diff --git a/m4/aclocal_fc.m4 b/m4/aclocal_fc.m4 index e5d664d..49ff485 100644 --- a/m4/aclocal_fc.m4 +++ b/m4/aclocal_fc.m4 @@ -68,7 +68,7 @@ AC_DEFUN([PAC_PROG_FC_ISO_FORTRAN_ENV],[ AC_MSG_CHECKING([if Fortran compiler supports intrinsic module ISO_FORTRAN_ENV]) TEST_SRC="`sed -n '/PROGRAM PROG_FC_ISO_FORTRAN_ENV/,/END PROGRAM PROG_FC_ISO_FORTRAN_ENV/p' $srcdir/m4/aclocal_fc.f90`" AC_LINK_IFELSE([$TEST_SRC],[AC_MSG_RESULT([yes]) - HAVE_ISO_FORTRAN_ENV="yes"], + HAVE_ISO_FORTRAN_ENV="yes"], [AC_MSG_RESULT([no])]) ]) @@ -79,7 +79,7 @@ AC_DEFUN([PAC_PROG_FC_SIZEOF],[ AC_MSG_CHECKING([if Fortran compiler supports intrinsic SIZEOF]) TEST_SRC="`sed -n '/PROGRAM PROG_FC_SIZEOF/,/END PROGRAM PROG_FC_SIZEOF/p' $srcdir/m4/aclocal_fc.f90`" AC_LINK_IFELSE([$TEST_SRC],[AC_MSG_RESULT([yes]) - HAVE_SIZEOF_FORTRAN="yes"], + HAVE_SIZEOF_FORTRAN="yes"], [AC_MSG_RESULT([no])]) ]) @@ -90,7 +90,7 @@ AC_DEFUN([PAC_PROG_FC_C_SIZEOF],[ AC_MSG_CHECKING([if Fortran compiler supports intrinsic C_SIZEOF]) TEST_SRC="`sed -n '/PROGRAM PROG_FC_C_SIZEOF/,/END PROGRAM PROG_FC_C_SIZEOF/p' $srcdir/m4/aclocal_fc.f90`" AC_LINK_IFELSE([$TEST_SRC], [AC_MSG_RESULT([yes]) - HAVE_C_SIZEOF_FORTRAN="yes"], + HAVE_C_SIZEOF_FORTRAN="yes"], [AC_MSG_RESULT([no])]) ]) @@ -101,7 +101,7 @@ AC_DEFUN([PAC_PROG_FC_STORAGE_SIZE],[ AC_MSG_CHECKING([if Fortran compiler supports intrinsic STORAGE_SIZE]) TEST_SRC="`sed -ne '/PROGRAM PROG_FC_STORAGE_SIZE/,/END PROGRAM PROG_FC_STORAGE_SIZE/p' $srcdir/m4/aclocal_fc.f90`" AC_LINK_IFELSE([$TEST_SRC], [AC_MSG_RESULT([yes]) - HAVE_STORAGE_SIZE_FORTRAN="yes"], + HAVE_STORAGE_SIZE_FORTRAN="yes"], [AC_MSG_RESULT([no])]) ]) @@ -114,7 +114,7 @@ AC_DEFUN([PAC_PROG_FC_HAVE_C_LONG_DOUBLE],[ TEST_SRC="" TEST_SRC="`sed -n '/PROGRAM PROG_FC_HAVE_C_LONG_DOUBLE/,/END PROGRAM PROG_FC_HAVE_C_LONG_DOUBLE/p' $srcdir/m4/aclocal_fc.f90`" AC_LINK_IFELSE([$TEST_SRC], [AC_MSG_RESULT([yes]) - HAVE_C_LONG_DOUBLE_FORTRAN="yes"], + HAVE_C_LONG_DOUBLE_FORTRAN="yes"], [AC_MSG_RESULT([no])]) ]) @@ -146,8 +146,8 @@ AC_DEFUN([PAC_PROG_FC_HAVE_F2003_REQUIREMENTS],[ dnl ------------------------------------------------------------------------- dnl AC_F9X_MODS() dnl -dnl Check how F9X handles modules. This macro also checks which -dnl command-line option to use to include the module once it's built. +dnl Check how F9X handles modules. This macro also checks which +dnl command-line option to use to include the module once it's built. dnl AC_DEFUN([AC_F9X_MODS], [AC_MSG_CHECKING(what $FC does with modules) @@ -223,7 +223,6 @@ else fi AC_SUBST(F9XMODFLAG) AC_SUBST(F9XMODEXT) -rm -rf conftest* AC_LANG_POP(Fortran) ]) @@ -241,9 +240,9 @@ dnl Change to the Fortran 90 language dnl Try link a simple MPI program. AC_MSG_CHECKING([whether a simple MPI-IO Fortran program can be linked]) AC_LINK_IFELSE([$TEST_SRC], - [AC_MSG_RESULT([yes])], - [AC_MSG_RESULT([no]) - AC_MSG_ERROR([unable to link a simple MPI-IO Fortran program])]) + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + AC_MSG_ERROR([unable to link a simple MPI-IO Fortran program])]) dnl Change to the C language AC_LANG_POP(Fortran) @@ -257,51 +256,43 @@ dnl This is a runtime test. dnl AC_DEFUN([PAC_FC_AVAIL_KINDS],[ AC_LANG_PUSH([Fortran]) -rm -f pac_fconftest.out TEST_SRC="`sed -n '/PROGRAM FC_AVAIL_KINDS/,/END PROGRAM FC_AVAIL_KINDS/p' $srcdir/m4/aclocal_fc.f90`" AC_RUN_IFELSE([$TEST_SRC], [ - if test -s pac_fconftest.out ; then - - dnl The output from the above program will be: - dnl -- LINE 1 -- valid integer kinds (comma seperated list) - dnl -- LINE 2 -- valid real kinds (comma seperated list) - dnl -- LINE 3 -- max decimal precision for reals - dnl -- LINE 4 -- number of valid integer kinds - dnl -- LINE 5 -- number of valid real kinds - - pac_validIntKinds="`sed -n '1p' pac_fconftest.out`" - pac_validRealKinds="`sed -n '2p' pac_fconftest.out`" - PAC_FC_MAX_REAL_PRECISION="`sed -n '3p' pac_fconftest.out`" + dnl The output from the above program will be: + dnl -- LINE 1 -- valid integer kinds (comma seperated list) + dnl -- LINE 2 -- valid real kinds (comma seperated list) + dnl -- LINE 3 -- max decimal precision for reals + dnl -- LINE 4 -- number of valid integer kinds + dnl -- LINE 5 -- number of valid real kinds + + pac_validIntKinds=$(./conftest$EXEEXT 2>&1 | sed -n '1p') + pac_validRealKinds=$(./conftest$EXEEXT 2>&1 | sed -n '2p') + PAC_FC_MAX_REAL_PRECISION=$(./conftest$EXEEXT 2>&1 | sed -n '3p') AC_DEFINE_UNQUOTED([PAC_FC_MAX_REAL_PRECISION], $PAC_FC_MAX_REAL_PRECISION, [Define Fortran Maximum Real Decimal Precision]) PAC_FC_ALL_INTEGER_KINDS="{`echo $pac_validIntKinds`}" PAC_FC_ALL_REAL_KINDS="{`echo $pac_validRealKinds`}" - PAC_FORTRAN_NUM_INTEGER_KINDS="`sed -n '4p' pac_fconftest.out`" - H5CONFIG_F_NUM_IKIND="INTEGER, PARAMETER :: num_ikinds = `echo $PAC_FORTRAN_NUM_INTEGER_KINDS`" - H5CONFIG_F_IKIND="INTEGER, DIMENSION(1:num_ikinds) :: ikind = (/`echo $pac_validIntKinds`/)" - H5CONFIG_F_NUM_RKIND="INTEGER, PARAMETER :: num_rkinds = `sed -n '5p' pac_fconftest.out`" - H5CONFIG_F_RKIND="INTEGER, DIMENSION(1:num_rkinds) :: rkind = (/`echo $pac_validRealKinds`/)" + PAC_FORTRAN_NUM_INTEGER_KINDS=$(./conftest$EXEEXT 2>&1 | sed -n '4p') + H5CONFIG_F_NUM_IKIND="INTEGER, PARAMETER :: num_ikinds = `echo $PAC_FORTRAN_NUM_INTEGER_KINDS`" + H5CONFIG_F_IKIND="INTEGER, DIMENSION(1:num_ikinds) :: ikind = (/`echo $pac_validIntKinds`/)" + H5CONFIG_F_NUM_RKIND="INTEGER, PARAMETER :: num_rkinds = $(./conftest$EXEEXT 2>&1 | sed -n '5p')" + H5CONFIG_F_RKIND="INTEGER, DIMENSION(1:num_rkinds) :: rkind = (/`echo $pac_validRealKinds`/)" - AC_DEFINE_UNQUOTED([H5CONFIG_F_NUM_RKIND], $H5CONFIG_F_NUM_RKIND, [Define number of valid Fortran REAL KINDs]) - AC_DEFINE_UNQUOTED([H5CONFIG_F_NUM_IKIND], $H5CONFIG_F_NUM_IKIND, [Define number of valid Fortran INTEGER KINDs]) - AC_DEFINE_UNQUOTED([H5CONFIG_F_RKIND], $H5CONFIG_F_RKIND, [Define valid Fortran REAL KINDs]) - AC_DEFINE_UNQUOTED([H5CONFIG_F_IKIND], $H5CONFIG_F_IKIND, [Define valid Fortran INTEGER KINDs]) + AC_DEFINE_UNQUOTED([H5CONFIG_F_NUM_RKIND], $H5CONFIG_F_NUM_RKIND, [Define number of valid Fortran REAL KINDs]) + AC_DEFINE_UNQUOTED([H5CONFIG_F_NUM_IKIND], $H5CONFIG_F_NUM_IKIND, [Define number of valid Fortran INTEGER KINDs]) + AC_DEFINE_UNQUOTED([H5CONFIG_F_RKIND], $H5CONFIG_F_RKIND, [Define valid Fortran REAL KINDs]) + AC_DEFINE_UNQUOTED([H5CONFIG_F_IKIND], $H5CONFIG_F_IKIND, [Define valid Fortran INTEGER KINDs]) AC_MSG_CHECKING([for Number of Fortran INTEGER KINDs]) AC_MSG_RESULT([$PAC_FORTRAN_NUM_INTEGER_KINDS]) AC_MSG_CHECKING([for Fortran INTEGER KINDs]) AC_MSG_RESULT([$PAC_FC_ALL_INTEGER_KINDS]) - AC_MSG_CHECKING([for Fortran REAL KINDs]) - AC_MSG_RESULT([$PAC_FC_ALL_REAL_KINDS]) - AC_MSG_CHECKING([for Fortran REALs maximum decimal precision]) - AC_MSG_RESULT([$PAC_FC_MAX_REAL_PRECISION]) - else - AC_MSG_RESULT([Error]) - AC_MSG_ERROR([No output from Fortran test program!]) - fi - rm -f pac_fconftest.out + AC_MSG_CHECKING([for Fortran REAL KINDs]) + AC_MSG_RESULT([$PAC_FC_ALL_REAL_KINDS]) + AC_MSG_CHECKING([for Fortran REALs maximum decimal precision]) + AC_MSG_RESULT([$PAC_FC_MAX_REAL_PRECISION]) ],[ AC_MSG_RESULT([Error]) AC_MSG_ERROR([Failed to run Fortran program to determine available KINDs]) @@ -314,29 +305,22 @@ AC_REQUIRE([PAC_FC_AVAIL_KINDS]) AC_MSG_CHECKING([sizeof of available INTEGER KINDs]) AC_LANG_PUSH([Fortran]) pack_int_sizeof="" -rm -f pac_fconftest.out for kind in `echo $pac_validIntKinds | sed -e 's/,/ /g'`; do AC_LANG_CONFTEST([ AC_LANG_SOURCE([ PROGRAM main USE ISO_C_BINDING + USE ISO_FORTRAN_ENV, ONLY : stderr=>ERROR_UNIT IMPLICIT NONE INTEGER (KIND=$kind) a - OPEN(8, FILE='pac_fconftest.out', FORM='formatted') - WRITE(8,'(I0)') $FC_SIZEOF_A - CLOSE(8) + WRITE(stderr,'(I0)') $FC_SIZEOF_A END ]) ]) AC_RUN_IFELSE([],[ - if test -s pac_fconftest.out ; then - sizes="`cat pac_fconftest.out`" - pack_int_sizeof="$pack_int_sizeof $sizes," - else - AC_MSG_ERROR([No output from Fortran test program!]) - fi - rm -f pac_fconftest.out + sizes=$(./conftest$EXEEXT 2>&1) + pack_int_sizeof="$pack_int_sizeof $sizes," ],[ AC_MSG_ERROR([Fortran program fails to build or run!]) ],[ @@ -359,22 +343,16 @@ for kind in `echo $pac_validRealKinds | sed -e 's/,/ /g'`; do AC_LANG_SOURCE([ PROGRAM main USE ISO_C_BINDING + USE ISO_FORTRAN_ENV, ONLY : stderr=>ERROR_UNIT IMPLICIT NONE REAL (KIND=$kind) :: a - OPEN(8, FILE='pac_fconftest.out', FORM='formatted') - WRITE(8,'(I0)') $FC_SIZEOF_A - CLOSE(8) + WRITE(stderr,'(I0)') $FC_SIZEOF_A END ]) ]) AC_RUN_IFELSE([],[ - if test -s pac_fconftest.out ; then - sizes="`cat pac_fconftest.out`" - pack_real_sizeof="$pack_real_sizeof $sizes," - else - AC_MSG_ERROR([No output from Fortran test program!]) - fi - rm -f pac_fconftest.out + sizes=$(./conftest$EXEEXT 2>&1) + pack_real_sizeof="$pack_real_sizeof $sizes," ],[ AC_MSG_ERROR([Fortran program fails to build or run!]) ],[ @@ -396,33 +374,27 @@ rm -f pac_fconftest.out AC_LANG_SOURCE([ PROGRAM main USE ISO_C_BINDING + USE ISO_FORTRAN_ENV, ONLY : stderr=>ERROR_UNIT IMPLICIT NONE INTEGER a REAL b DOUBLE PRECISION c - OPEN(8, FILE='pac_fconftest.out', FORM='formatted') - WRITE(8,*) $FC_SIZEOF_A - WRITE(8,*) KIND(a) - WRITE(8,*) $FC_SIZEOF_B - WRITE(8,*) KIND(b) - WRITE(8,*) $FC_SIZEOF_C - WRITE(8,*) KIND(c) - CLOSE(8) + WRITE(stderr,*) $FC_SIZEOF_A + WRITE(stderr,*) KIND(a) + WRITE(stderr,*) $FC_SIZEOF_B + WRITE(stderr,*) KIND(b) + WRITE(stderr,*) $FC_SIZEOF_C + WRITE(stderr,*) KIND(c) END ]) ]) AC_RUN_IFELSE([],[ - if test -s pac_fconftest.out ; then - PAC_FORTRAN_NATIVE_INTEGER_SIZEOF="`sed -n '1p' pac_fconftest.out`" - PAC_FORTRAN_NATIVE_INTEGER_KIND="`sed -n '2p' pac_fconftest.out`" - PAC_FORTRAN_NATIVE_REAL_SIZEOF="`sed -n '3p' pac_fconftest.out`" - PAC_FORTRAN_NATIVE_REAL_KIND="`sed -n '4p' pac_fconftest.out`" - PAC_FORTRAN_NATIVE_DOUBLE_SIZEOF="`sed -n '5p' pac_fconftest.out`" - PAC_FORTRAN_NATIVE_DOUBLE_KIND="`sed -n '6p' pac_fconftest.out`" - else - AC_MSG_ERROR([No output from Fortran test program!]) - fi - rm -f pac_fconftest.out + PAC_FORTRAN_NATIVE_INTEGER_SIZEOF=$(./conftest$EXEEXT 2>&1 | sed -n '1p') + PAC_FORTRAN_NATIVE_INTEGER_KIND=$(./conftest$EXEEXT 2>&1 | sed -n '2p') + PAC_FORTRAN_NATIVE_REAL_SIZEOF=$(./conftest$EXEEXT 2>&1 | sed -n '3p') + PAC_FORTRAN_NATIVE_REAL_KIND=$(./conftest$EXEEXT 2>&1 | sed -n '4p') + PAC_FORTRAN_NATIVE_DOUBLE_SIZEOF=$(./conftest$EXEEXT 2>&1 | sed -n '5p') + PAC_FORTRAN_NATIVE_DOUBLE_KIND=$(./conftest$EXEEXT 2>&1 | sed -n '6p') ],[ AC_MSG_ERROR([Fortran program fails to build or run!]) ],[ @@ -434,7 +406,6 @@ AC_LANG_POP([Fortran]) AC_DEFUN([PAC_FC_LDBL_DIG],[ AC_MSG_CHECKING([maximum decimal precision for C]) -rm -f pac_Cconftest.out AC_LANG_CONFTEST([ AC_LANG_PROGRAM([ #include @@ -458,19 +429,12 @@ rm -f pac_Cconftest.out #define C_LDBL_DIG LDBL_DIG #endif ],[[ - FILE * pFile; - pFile = fopen("pac_Cconftest.out","w"); - fprintf(pFile, "%d\n%d\n", C_LDBL_DIG, C_FLT128_DIG); + fprintf(stderr, "%d\n%d\n", C_LDBL_DIG, C_FLT128_DIG); ]]) ]) AC_RUN_IFELSE([],[ - if test -s pac_Cconftest.out ; then - LDBL_DIG="`sed -n '1p' pac_Cconftest.out`" - FLT128_DIG="`sed -n '2p' pac_Cconftest.out`" - else - AC_MSG_ERROR([No output from C decimal precision program!]) - fi - rm -f pac_Cconftest.out + LDBL_DIG=$(./conftest$EXEEXT 2>&1 | sed -n '1p') + FLT128_DIG=$(./conftest$EXEEXT 2>&1 | sed -n '2p') ],[ AC_MSG_ERROR([C program fails to build or run!]) ],[]) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index ed12c5e..c21217f 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -1,4 +1,4 @@ -HDF5 version 1.13.0 currently under development +HDF5 version 1.13.1-1 currently under development ================================================================================ @@ -37,9 +37,7 @@ CONTENTS - New Features - Support for new platforms and languages - Bug Fixes since HDF5-1.12.0 -- Supported Platforms -- Tested Configuration Features Summary -- More Tested Platforms +- Platforms Tested - Known Problems - CMake vs. Autotools installations @@ -49,11 +47,48 @@ New Features Configuration: ------------- + - Added new configure option to support building parallel tools. + See Tools below (autotools - CMake): + --enable-parallel-tools HDF5_BUILD_PARALLEL_TOOLS + + (RAW - 2021/10/25) + + - Added new configure options to enable dimension scales APIs (H5DS*) to + use new object references with the native VOL connector (aka native HDF5 + library). New references are always used for non-native terminal VOL + connectors (e.g., DAOS). + + Autotools --enable-dimension-scales-with-new-ref + CMake HDF5_DIMENSION_SCALES_NEW_REF=ON + + (EIP - 2021/10/25, HDFFV-11180) + + - Refactored the utils folder. + + Added subfolder test and moved the 'swmr_check_compat_vfd.c file' + from test into utils/test. Deleted the duplicate swmr_check_compat_vfd.c + file in hl/tools/h5watch folder. Also fixed vfd check options. + + (ADB - 2021/10/18) + + - Changed autotools and CMake configurations to derive both + compilation warnings-as-errors and warnings-only-warn configurations + from the same files, 'config/*/*error*'. Removed redundant files + 'config/*/*noerror*'. + + (DCY - 2021/09/29) + - Added new option to control the build of High-Level tools that default ON/enabled. Add configure options (autotools - CMake): - enable-hltools HDF5_BUILD_HL_TOOLS + --enable-hltools HDF5_BUILD_HL_TOOLS + + Disabling this option prevents building the gif tool which + contains the following CVEs: + HDFFV-10592 CVE-2018-17433 + HDFFV-10593 CVE-2018-17436 + HDFFV-11048 CVE-2020-10809 (ADB - 2021/09/16, HDFFV-11266) @@ -164,19 +199,19 @@ New Features - CMake option to build the HDF filter plugins project as an external project - The HDF filter plugins project is a collection of registered compression - filters that can be dynamically loaded when needed to access data stored - in a hdf5 file. This CMake-only option allows the plugins to be built and - distributed with the hdf5 library and tools. Like the options for szip and - zlib, either a tgz file or a git repository can be specified for the source. + The HDF filter plugins project is a collection of registered compression + filters that can be dynamically loaded when needed to access data stored + in a hdf5 file. This CMake-only option allows the plugins to be built and + distributed with the hdf5 library and tools. Like the options for szip and + zlib, either a tgz file or a git repository can be specified for the source. - The option was refactored to use the CMake FetchContent process. This allows - more control over the filter targets, but required external project command - options to be moved to a CMake include file, HDF5PluginCache.cmake. Also - enabled the filter examples to be used as tests for operation of the - filter plugins. + The option was refactored to use the CMake FetchContent process. This allows + more control over the filter targets, but required external project command + options to be moved to a CMake include file, HDF5PluginCache.cmake. Also + enabled the filter examples to be used as tests for operation of the + filter plugins. - (ADB - 2020/12/10, OESS-98) + (ADB - 2020/12/10, OESS-98) - FreeBSD Autotools configuration now defaults to 'cc' and 'c++' compilers @@ -229,244 +264,244 @@ New Features - Autotools and CMake target added to produce doxygen generated documentation - The default is OFF or disabled. - Autoconf option is '--enable-doxygen' - autotools make target is 'doxygen' and will build all doxygen targets - CMake configure option is 'HDF5_BUILD_DOC'. - CMake target is 'doxygen' for all available doxygen targets - CMake target is 'hdf5lib_doc' for the src subdirectory + The default is OFF or disabled. + Autoconf option is '--enable-doxygen' + autotools make target is 'doxygen' and will build all doxygen targets + CMake configure option is 'HDF5_BUILD_DOC'. + CMake target is 'doxygen' for all available doxygen targets + CMake target is 'hdf5lib_doc' for the src subdirectory - (ADB - 2020/11/03) + (ADB - 2020/11/03) - CMake option to use MSVC naming conventions with MinGW - HDF5_MSVC_NAMING_CONVENTION option enable to use MSVC naming conventions - when using a MinGW toolchain + HDF5_MSVC_NAMING_CONVENTION option enable to use MSVC naming conventions + when using a MinGW toolchain - (xan - 2020/10/30) + (xan - 2020/10/30) - CMake option to statically link gcc libs with MinGW - HDF5_MINGW_STATIC_GCC_LIBS allows to statically link libg/libstdc++ - with the MinGW toolchain + HDF5_MINGW_STATIC_GCC_LIBS allows to statically link libg/libstdc++ + with the MinGW toolchain - (xan - 2020/10/30) + (xan - 2020/10/30) - CMake option to build the HDF filter plugins project as an external project - The HDF filter plugins project is a collection of registered compression - filters that can be dynamically loaded when needed to access data stored - in a hdf5 file. This CMake-only option allows the plugins to be built and - distributed with the hdf5 library and tools. Like the options for szip and - zlib, either a tgz file or a git repository can be specified for the source. + The HDF filter plugins project is a collection of registered compression + filters that can be dynamically loaded when needed to access data stored + in a hdf5 file. This CMake-only option allows the plugins to be built and + distributed with the hdf5 library and tools. Like the options for szip and + zlib, either a tgz file or a git repository can be specified for the source. - The necessary options are (see the INSTALL_CMake.txt file): - HDF5_ENABLE_PLUGIN_SUPPORT - PLUGIN_TGZ_NAME or PLUGIN_GIT_URL - There are more options necessary for various filters and the plugin project - documents should be referenced. + The necessary options are (see the INSTALL_CMake.txt file): + HDF5_ENABLE_PLUGIN_SUPPORT + PLUGIN_TGZ_NAME or PLUGIN_GIT_URL + There are more options necessary for various filters and the plugin project + documents should be referenced. - (ADB - 2020/09/27, OESS-98) + (ADB - 2020/09/27, OESS-98) - Added CMake option to format source files - HDF5_ENABLE_FORMATTERS option will enable creation of targets using the - pattern - HDF5_*_SRC_FORMAT - where * corresponds to the source folder - or tool folder. All sources can be formatted by executing the format target; - make format + HDF5_ENABLE_FORMATTERS option will enable creation of targets using the + pattern - HDF5_*_SRC_FORMAT - where * corresponds to the source folder + or tool folder. All sources can be formatted by executing the format target; + make format - (ADB - 2020/08/24) + (ADB - 2020/08/24) - Add file locking configure and CMake options - HDF5 1.10.0 introduced a file locking scheme, primarily to help - enforce SWMR setup. Formerly, the only user-level control of the scheme - was via the HDF5_USE_FILE_LOCKING environment variable. + HDF5 1.10.0 introduced a file locking scheme, primarily to help + enforce SWMR setup. Formerly, the only user-level control of the scheme + was via the HDF5_USE_FILE_LOCKING environment variable. - This change introduces configure-time options that control whether - or not file locking will be used and whether or not the library - ignores errors when locking has been disabled on the file system - (useful on some HPC Lustre installations). + This change introduces configure-time options that control whether + or not file locking will be used and whether or not the library + ignores errors when locking has been disabled on the file system + (useful on some HPC Lustre installations). - In both the Autotools and CMake, the settings have the effect of changing - the default property list settings (see the H5Pset/get_file_locking() - entry, below). + In both the Autotools and CMake, the settings have the effect of changing + the default property list settings (see the H5Pset/get_file_locking() + entry, below). - The yes/no/best-effort file locking configure setting has also been - added to the libhdf5.settings file. + The yes/no/best-effort file locking configure setting has also been + added to the libhdf5.settings file. - Autotools: + Autotools: - An --enable-file-locking=(yes|no|best-effort) option has been added. + An --enable-file-locking=(yes|no|best-effort) option has been added. - yes: Use file locking. - no: Do not use file locking. - best-effort: Use file locking and ignore "disabled" errors. + yes: Use file locking. + no: Do not use file locking. + best-effort: Use file locking and ignore "disabled" errors. - CMake: + CMake: - Two self-explanatory options have been added: + Two self-explanatory options have been added: - HDF5_USE_FILE_LOCKING - HDF5_IGNORE_DISABLED_FILE_LOCKS + HDF5_USE_FILE_LOCKING + HDF5_IGNORE_DISABLED_FILE_LOCKS - Setting both of these to ON is the equivalent to the Autotools' - best-effort setting. + Setting both of these to ON is the equivalent to the Autotools' + best-effort setting. - NOTE: - The precedence order of the various file locking control mechanisms is: + NOTE: + The precedence order of the various file locking control mechanisms is: - 1) HDF5_USE_FILE_LOCKING environment variable (highest) + 1) HDF5_USE_FILE_LOCKING environment variable (highest) - 2) H5Pset_file_locking() + 2) H5Pset_file_locking() - 3) configure/CMake options (which set the property list defaults) + 3) configure/CMake options (which set the property list defaults) - 4) library defaults (currently best-effort) + 4) library defaults (currently best-effort) - (DER - 2020/07/30, HDFFV-11092) + (DER - 2020/07/30, HDFFV-11092) - CMake option to link the generated Fortran MOD files into the include directory. - The Fortran generation of MOD files by a Fortran compile can produce - different binary files between SHARED and STATIC compiles with different - compilers and/or different platforms. Note that it has been found that - different versions of Fortran compilers will produce incompatible MOD - files. Currently, CMake will locate these MOD files in subfolders of - the include directory and add that path to the Fortran library target - in the CMake config file, which can be used by the CMake find library - process. For other build systems using the binary from a CMake install, - a new CMake configuration can be used to copy the pre-chosen version - of the Fortran MOD files into the install include directory. - - The default will depend on the configuration of - BUILD_STATIC_LIBS and BUILD_SHARED_LIBS: - YES YES Default to SHARED - YES NO Default to STATIC - NO YES Default to SHARED - NO NO Default to SHARED - The defaults can be overridden by setting the config option - HDF5_INSTALL_MOD_FORTRAN to one of NO, SHARED, or STATIC - - (ADB - 2020/07/09, HDFFV-11116) + The Fortran generation of MOD files by a Fortran compile can produce + different binary files between SHARED and STATIC compiles with different + compilers and/or different platforms. Note that it has been found that + different versions of Fortran compilers will produce incompatible MOD + files. Currently, CMake will locate these MOD files in subfolders of + the include directory and add that path to the Fortran library target + in the CMake config file, which can be used by the CMake find library + process. For other build systems using the binary from a CMake install, + a new CMake configuration can be used to copy the pre-chosen version + of the Fortran MOD files into the install include directory. + + The default will depend on the configuration of + BUILD_STATIC_LIBS and BUILD_SHARED_LIBS: + YES YES Default to SHARED + YES NO Default to STATIC + NO YES Default to SHARED + NO NO Default to SHARED + The defaults can be overridden by setting the config option + HDF5_INSTALL_MOD_FORTRAN to one of NO, SHARED, or STATIC + + (ADB - 2020/07/09, HDFFV-11116) - CMake option to use AEC (open source SZip) library instead of SZip - The open source AEC library is a replacement library for SZip. In - order to use it for hdf5 the libaec CMake source was changed to add - "-fPIC" and exclude test files. Autotools does not build the - compression libraries within hdf5 builds. New option USE_LIBAEC is - required to compensate for the different files produced by AEC build. + The open source AEC library is a replacement library for SZip. In + order to use it for hdf5 the libaec CMake source was changed to add + "-fPIC" and exclude test files. Autotools does not build the + compression libraries within hdf5 builds. New option USE_LIBAEC is + required to compensate for the different files produced by AEC build. - (ADB - 2020/04/22, OESS-65) + (ADB - 2020/04/22, OESS-65) - CMake ConfigureChecks.cmake file now uses CHECK_STRUCT_HAS_MEMBER - Some handcrafted tests in HDFTests.c has been removed and the CMake - CHECK_STRUCT_HAS_MEMBER module has been used. + Some handcrafted tests in HDFTests.c has been removed and the CMake + CHECK_STRUCT_HAS_MEMBER module has been used. - (ADB - 2020/03/24, TRILAB-24) + (ADB - 2020/03/24, TRILAB-24) - Both build systems use same set of warnings flags - GNU C, C++ and gfortran warnings flags were moved to files in a config - sub-folder named gnu-warnings. Flags that only are available for a specific - version of the compiler are in files named with that version. - Clang C warnings flags were moved to files in a config sub-folder - named clang-warnings. - Intel C, Fortran warnings flags were moved to files in a config sub-folder - named intel-warnings. + GNU C, C++ and gfortran warnings flags were moved to files in a config + sub-folder named gnu-warnings. Flags that only are available for a specific + version of the compiler are in files named with that version. + Clang C warnings flags were moved to files in a config sub-folder + named clang-warnings. + Intel C, Fortran warnings flags were moved to files in a config sub-folder + named intel-warnings. - There are flags in named "error-xxx" files with warnings that may - be promoted to errors. Some source files may still need fixes. + There are flags in named "error-xxx" files with warnings that may + be promoted to errors. Some source files may still need fixes. - There are also pairs of files named "developer-xxx" and "no-developer-xxx" - that are chosen by the CMake option:HDF5_ENABLE_DEV_WARNINGS or the - configure option:--enable-developer-warnings. + There are also pairs of files named "developer-xxx" and "no-developer-xxx" + that are chosen by the CMake option:HDF5_ENABLE_DEV_WARNINGS or the + configure option:--enable-developer-warnings. - In addition, CMake no longer applies these warnings for examples. + In addition, CMake no longer applies these warnings for examples. - (ADB - 2020/03/24, TRILAB-192) + (ADB - 2020/03/24, TRILAB-192) - Added test script for file size compare - If CMake minimum version is at least 3.14, the fileCompareTest.cmake - script will compare file sizes. + If CMake minimum version is at least 3.14, the fileCompareTest.cmake + script will compare file sizes. - (ADB - 2020/02/24, HDFFV-11036) + (ADB - 2020/02/24, HDFFV-11036) - Update CMake minimum version to 3.12 - Updated CMake minimum version to 3.12 and added version checks - for Windows features. + Updated CMake minimum version to 3.12 and added version checks + for Windows features. - (ADB - 2020/02/05, TRILABS-142) + (ADB - 2020/02/05, TRILABS-142) - Fixed CMake include properties for Fortran libraries - Corrected the library properties for Fortran to use the - correct path for the Fortran module files. + Corrected the library properties for Fortran to use the + correct path for the Fortran module files. - (ADB - 2020/02/04, HDFFV-11012) + (ADB - 2020/02/04, HDFFV-11012) - Added common warnings files for gnu and intel - Added warnings files to use one common set of flags - during configure for both autotools and CMake build - systems. The initial implementation only affects a - general set of flags for gnu and intel compilers. + Added warnings files to use one common set of flags + during configure for both autotools and CMake build + systems. The initial implementation only affects a + general set of flags for gnu and intel compilers. - (ADB - 2020/01/17) + (ADB - 2020/01/17) - Added new options to CMake for control of testing - Added CMake options (default ON); - HDF5_TEST_SERIAL AND/OR HDF5_TEST_PARALLEL - combined with: - HDF5_TEST_TOOLS - HDF5_TEST_EXAMPLES - HDF5_TEST_SWMR - HDF5_TEST_FORTRAN - HDF5_TEST_CPP - HDF5_TEST_JAVA + Added CMake options (default ON); + HDF5_TEST_SERIAL AND/OR HDF5_TEST_PARALLEL + combined with: + HDF5_TEST_TOOLS + HDF5_TEST_EXAMPLES + HDF5_TEST_SWMR + HDF5_TEST_FORTRAN + HDF5_TEST_CPP + HDF5_TEST_JAVA - (ADB - 2020/01/15, HDFFV-11001) + (ADB - 2020/01/15, HDFFV-11001) - Added Clang sanitizers to CMake for analyzer support if compiler is clang. - Added CMake code and files to execute the Clang sanitizers if - HDF5_ENABLE_SANITIZERS is enabled and the USE_SANITIZER option - is set to one of the following: - Address - Memory - MemoryWithOrigins - Undefined - Thread - Leak - 'Address;Undefined' + Added CMake code and files to execute the Clang sanitizers if + HDF5_ENABLE_SANITIZERS is enabled and the USE_SANITIZER option + is set to one of the following: + Address + Memory + MemoryWithOrigins + Undefined + Thread + Leak + 'Address;Undefined' - (ADB - 2019/12/12, TRILAB-135) + (ADB - 2019/12/12, TRILAB-135) - Update CMake for VS2019 support - CMake added support for VS2019 in version 3.15. Changes to the CMake - generator setting required changes to scripts. Also updated version - references in CMake files as necessary. + CMake added support for VS2019 in version 3.15. Changes to the CMake + generator setting required changes to scripts. Also updated version + references in CMake files as necessary. - (ADB - 2019/11/18, HDFFV-10962) + (ADB - 2019/11/18, HDFFV-10962) - Update CMake options to match new autotools options - Add configure options (autotools - CMake): - enable-asserts HDF5_ENABLE_ASSERTS - enable-symbols HDF5_ENABLE_SYMBOLS - enable-profiling HDF5_ENABLE_PROFILING - enable-optimization HDF5_ENABLE_OPTIMIZATION - In addition NDEBUG is no longer forced defined and relies on the CMake - process. + Add configure options (autotools - CMake): + enable-asserts HDF5_ENABLE_ASSERTS + enable-symbols HDF5_ENABLE_SYMBOLS + enable-profiling HDF5_ENABLE_PROFILING + enable-optimization HDF5_ENABLE_OPTIMIZATION + In addition NDEBUG is no longer forced defined and relies on the CMake + process. - (ADB - 2019/10/07, HDFFV-100901, HDFFV-10637, TRILAB-97) + (ADB - 2019/10/07, HDFFV-100901, HDFFV-10637, TRILAB-97) Library: @@ -488,7 +523,7 @@ New Features which case the release part of version, in major.minor.release, must be exact. An environment variable still controls the logic. - (ADB - 2021/07/27) + (ADB - 2021/07/27) - gcc warning suppression macros were moved out of H5public.h @@ -501,7 +536,7 @@ New Features VFD refactoring, the macros have been duplicated in H5FDmulti.c to suppress the format string warnings there. - (DER - 2021/06/03) + (DER - 2021/06/03) - H5Gcreate1() now rejects size_hint parameters larger than UINT32_MAX @@ -518,7 +553,7 @@ New Features The Doxygen documentation has been updated and passing values larger than UINT32_MAX for size_hint will now produce a normal HDF5 error. - (DER - 2021/04/29, HDFFV-11241) + (DER - 2021/04/29, HDFFV-11241) - H5Pset_fapl_log() no longer crashes when passed an invalid fapl ID @@ -532,7 +567,7 @@ New Features The pointer is now correctly initialized and the API call now produces a normal HDF5 error when fed an invalid fapl ID. - (DER - 2021/04/28, HDFFV-11240) + (DER - 2021/04/28, HDFFV-11240) - Fixes a segfault when H5Pset_mdc_log_options() is called multiple times @@ -544,7 +579,7 @@ New Features The string is now handled properly and the segfault no longer occurs. - (DER - 2021/04/27, HDFFV-11239) + (DER - 2021/04/27, HDFFV-11239) - HSYS_GOTO_ERROR now emits the results of GetLastError() on Windows @@ -563,15 +598,15 @@ New Features The format string on Windows has been changed from: - "%s, errno = %d, error message = '%s'" + "%s, errno = %d, error message = '%s'" to: - "%s, errno = %d, error message = '%s', Win32 GetLastError() = %"PRIu32"" + "%s, errno = %d, error message = '%s', Win32 GetLastError() = %"PRIu32"" for those inclined to parse it for error values. - (DER - 2021/03/21) + (DER - 2021/03/21) - File locking now works on Windows @@ -587,26 +622,26 @@ New Features same scheme as POSIX systems. We lock the entire file when we set up the locks (by passing DWORDMAX as both size parameters to LockFileEx()). - (DER - 2021/03/19, HDFFV-10191) + (DER - 2021/03/19, HDFFV-10191) - H5Epush_ret() now requires a trailing semicolon - H5Epush_ret() is a function-like macro that has been changed to - contain a `do {} while(0)` loop. Consequently, a trailing semicolon - is now required to end the `while` statement. Previously, a trailing - semi would work, but was not mandatory. This change was made to allow - clang-format to correctly format the source code. + H5Epush_ret() is a function-like macro that has been changed to + contain a `do {} while(0)` loop. Consequently, a trailing semicolon + is now required to end the `while` statement. Previously, a trailing + semi would work, but was not mandatory. This change was made to allow + clang-format to correctly format the source code. - (SAM - 2021/03/03) + (SAM - 2021/03/03) - Improved performance of H5Sget_select_elem_pointlist - Modified library to cache the point after the last block of points - retrieved by H5Sget_select_elem_pointlist, so a subsequent call to the - same function to retrieve the next block of points from the list can - proceed immediately without needing to iterate over the point list. + Modified library to cache the point after the last block of points + retrieved by H5Sget_select_elem_pointlist, so a subsequent call to the + same function to retrieve the next block of points from the list can + proceed immediately without needing to iterate over the point list. - (NAF - 2021/01/19) + (NAF - 2021/01/19) - Replaced H5E_ATOM with H5E_ID in H5Epubgen.h @@ -620,130 +655,130 @@ New Features - Add a new public function H5Ssel_iter_reset - This function resets a dataspace selection iterator back to an - initial state so that it may be used for iteration once more. - This can be useful when needing to iterate over a selection - multiple times without having to repeatedly create/destroy - a selection iterator for that dataspace selection. + This function resets a dataspace selection iterator back to an + initial state so that it may be used for iteration once more. + This can be useful when needing to iterate over a selection + multiple times without having to repeatedly create/destroy + a selection iterator for that dataspace selection. - (JTH - 2020/09/18) + (JTH - 2020/09/18) - Remove HDFS VFD stubs - The original implementation of the HDFS VFD included non-functional - versions of the following public API calls when the HDFS VFD is - not built as a part of the HDF5 library: + The original implementation of the HDFS VFD included non-functional + versions of the following public API calls when the HDFS VFD is + not built as a part of the HDF5 library: - * H5FD_hdfs_init() - * H5Pget_fapl_hdfs() - * H5Pset_fapl_hdfs() + * H5FD_hdfs_init() + * H5Pget_fapl_hdfs() + * H5Pset_fapl_hdfs() - They will remain present in HDF5 1.10 and HDF5 1.12 releases - for binary compatibility purposes but have been removed as of 1.14.0. + They will remain present in HDF5 1.10 and HDF5 1.12 releases + for binary compatibility purposes but have been removed as of 1.14.0. - Note that this has nothing to do with the real HDFS VFD API calls - that are fully functional when the HDFS VFD is configured and built. + Note that this has nothing to do with the real HDFS VFD API calls + that are fully functional when the HDFS VFD is configured and built. - We simply changed: + We simply changed: - #ifdef LIBHDFS - - #else - - #endif + #ifdef LIBHDFS + + #else + + #endif - to: + to: - #ifdef LIBHDFS - - #endif + #ifdef LIBHDFS + + #endif - Which is how the other optional VFDs are handled. + Which is how the other optional VFDs are handled. - (DER - 2020/08/27) + (DER - 2020/08/27) - Add Mirror VFD - Use TCP/IP sockets to perform write-only (W/O) file I/O on a remote - machine. Must be used in conjunction with the Splitter VFD. + Use TCP/IP sockets to perform write-only (W/O) file I/O on a remote + machine. Must be used in conjunction with the Splitter VFD. - (JOS - 2020/03/13, TBD) + (JOS - 2020/03/13, TBD) - Add Splitter VFD - Maintain separate R/W and W/O channels for "concurrent" file writes - to two files using a single HDF5 file handle. + Maintain separate R/W and W/O channels for "concurrent" file writes + to two files using a single HDF5 file handle. - (JOS - 2020/03/13, TBD) + (JOS - 2020/03/13, TBD) - Refactored public exposure of haddr_t type in favor of "object tokens" - To better accommodate HDF5 VOL connectors where "object addresses in a file" - may not make much sense, the following changes were made to the library: - - * Introduced new H5O_token_t "object token" type, which represents a - unique and permanent identifier for referencing an HDF5 object within - a container; these "object tokens" are meant to replace object addresses. - Along with the new type, a new H5Oopen_by_token API call was introduced - to open an object by a token, similar to how object addresses were - previously used with H5Oopen_by_addr. - - * Introduced new H5Lget_info2, H5Lget_info_by_idx2, H5Literate2, H5Literate_by_name2, - H5Lvisit2 and H5Lvisit_by_name2 API calls, along with their associated H5L_info2_t - struct and H5L_iterate2_t callback function, which work with the newly-introduced - object tokens, instead of object addresses. The original functions have been - renamed to version 1 functions and are deprecated in favor of the new version 2 - functions. The H5L_info_t and H5L_iterate_t types have been renamed to version 1 - types and are now deprecated in favor of their version 2 counterparts. For each of - the functions and types, compatibility macros take place of the original symbols. - - * Introduced new H5Oget_info3, H5Oget_info_by_name3, H5Oget_info_by_idx3, - H5Ovisit3 and H5Ovisit_by_name3 API calls, along with their associated H5O_info2_t - struct and H5O_iterate2_t callback function, which work with the newly-introduced - object tokens, instead of object addresses. The version 2 functions are now - deprecated in favor of the version 3 functions. The H5O_info_t and H5O_iterate_t - types have been renamed to version 1 types and are now deprecated in favor of their - version 2 counterparts. For each, compatibility macros take place of the original - symbols. - - * Introduced new H5Oget_native_info, H5Oget_native_info_by_name and - H5Oget_native_info_by_idx API calls, along with their associated H5O_native_info_t - struct, which are used to retrieve the native HDF5 file format-specific information - about an object. This information (such as object header info and B-tree/heap info) - has been removed from the new H5O_info2_t struct so that the more generic - H5Oget_info(_by_name/_by_idx)3 routines will not try to retrieve it for non-native - VOL connectors. - - * Added new H5Otoken_cmp, H5Otoken_to_str and H5Otoken_from_str routines to compare - two object tokens, convert an object token into a nicely-readable string format and - to convert an object token string back into a real object token, respectively. - - (DER, QAK, JTH - 2020/01/16) + To better accommodate HDF5 VOL connectors where "object addresses in a file" + may not make much sense, the following changes were made to the library: + + * Introduced new H5O_token_t "object token" type, which represents a + unique and permanent identifier for referencing an HDF5 object within + a container; these "object tokens" are meant to replace object addresses. + Along with the new type, a new H5Oopen_by_token API call was introduced + to open an object by a token, similar to how object addresses were + previously used with H5Oopen_by_addr. + + * Introduced new H5Lget_info2, H5Lget_info_by_idx2, H5Literate2, H5Literate_by_name2, + H5Lvisit2 and H5Lvisit_by_name2 API calls, along with their associated H5L_info2_t + struct and H5L_iterate2_t callback function, which work with the newly-introduced + object tokens, instead of object addresses. The original functions have been + renamed to version 1 functions and are deprecated in favor of the new version 2 + functions. The H5L_info_t and H5L_iterate_t types have been renamed to version 1 + types and are now deprecated in favor of their version 2 counterparts. For each of + the functions and types, compatibility macros take place of the original symbols. + + * Introduced new H5Oget_info3, H5Oget_info_by_name3, H5Oget_info_by_idx3, + H5Ovisit3 and H5Ovisit_by_name3 API calls, along with their associated H5O_info2_t + struct and H5O_iterate2_t callback function, which work with the newly-introduced + object tokens, instead of object addresses. The version 2 functions are now + deprecated in favor of the version 3 functions. The H5O_info_t and H5O_iterate_t + types have been renamed to version 1 types and are now deprecated in favor of their + version 2 counterparts. For each, compatibility macros take place of the original + symbols. + + * Introduced new H5Oget_native_info, H5Oget_native_info_by_name and + H5Oget_native_info_by_idx API calls, along with their associated H5O_native_info_t + struct, which are used to retrieve the native HDF5 file format-specific information + about an object. This information (such as object header info and B-tree/heap info) + has been removed from the new H5O_info2_t struct so that the more generic + H5Oget_info(_by_name/_by_idx)3 routines will not try to retrieve it for non-native + VOL connectors. + + * Added new H5Otoken_cmp, H5Otoken_to_str and H5Otoken_from_str routines to compare + two object tokens, convert an object token into a nicely-readable string format and + to convert an object token string back into a real object token, respectively. + + (DER, QAK, JTH - 2020/01/16) - Add new public function H5Sselect_adjust. - This function shifts a dataspace selection by a specified logical offset - within the dataspace extent. This can be useful for VOL developers to - implement chunked datasets. + This function shifts a dataspace selection by a specified logical offset + within the dataspace extent. This can be useful for VOL developers to + implement chunked datasets. - (NAF - 2019/11/18) + (NAF - 2019/11/18) - Add new public function H5Sselect_project_intersection. - This function computes the intersection between two dataspace selections - and projects that intersection into a third selection. This can be useful - for VOL developers to implement chunked or virtual datasets. + This function computes the intersection between two dataspace selections + and projects that intersection into a third selection. This can be useful + for VOL developers to implement chunked or virtual datasets. - (NAF - 2019/11/13, ID-148) + (NAF - 2019/11/13, ID-148) - Add new public function H5VLget_file_type. - This function returns a datatype equivalent to the supplied datatype but - with the location set to be in the file. This datatype can then be used - with H5Tconvert to convert data between file and in-memory representation. - This function is intended for use only by VOL connector developers. + This function returns a datatype equivalent to the supplied datatype but + with the location set to be in the file. This datatype can then be used + with H5Tconvert to convert data between file and in-memory representation. + This function is intended for use only by VOL connector developers. - (NAF - 2019/11/08, ID-127) + (NAF - 2019/11/08, ID-127) Parallel Library: @@ -763,10 +798,10 @@ New Features h5pget_file_locking_f() h5pset_file_locking_f() - See the configure option discussion for HDFFV-11092 (above) for more - information on the file locking feature and how it's controlled. + See the configure option discussion for HDFFV-11092 (above) for more + information on the file locking feature and how it's controlled. - (DER - 2020/07/30, HDFFV-11092) + (DER - 2020/07/30, HDFFV-11092) C++ Library: ------------ @@ -775,10 +810,10 @@ New Features FileAccPropList::setFileLocking() FileAccPropList::getFileLocking() - See the configure option discussion for HDFFV-11092 (above) for more - information on the file locking feature and how it's controlled. + See the configure option discussion for HDFFV-11092 (above) for more + information on the file locking feature and how it's controlled. - (DER - 2020/07/30, HDFFV-11092) + (DER - 2020/07/30, HDFFV-11092) Java Library: @@ -795,12 +830,12 @@ New Features - Added new H5S functions. - H5Sselect_copy, H5Sselect_shape_same, H5Sselect_adjust, - H5Sselect_intersect_block, H5Sselect_project_intersection, - H5Scombine_hyperslab, H5Smodify_select, H5Scombine_select - wrapper functions added. + H5Sselect_copy, H5Sselect_shape_same, H5Sselect_adjust, + H5Sselect_intersect_block, H5Sselect_project_intersection, + H5Scombine_hyperslab, H5Smodify_select, H5Scombine_select + wrapper functions added. - (ADB - 2020/10/27, HDFFV-10868) + (ADB - 2020/10/27, HDFFV-10868) - Add wrappers for H5Pset/get_file_locking() API calls @@ -808,120 +843,120 @@ New Features H5Pget_use_file_locking() H5Pget_ignore_disabled_file_locking() - Unlike the C++ and Fortran wrappers, there are separate getters for the - two file locking settings, each of which returns a boolean value. + Unlike the C++ and Fortran wrappers, there are separate getters for the + two file locking settings, each of which returns a boolean value. - See the configure option discussion for HDFFV-11092 (above) for more - information on the file locking feature and how it's controlled. + See the configure option discussion for HDFFV-11092 (above) for more + information on the file locking feature and how it's controlled. - (DER - 2020/07/30, HDFFV-11092) + (DER - 2020/07/30, HDFFV-11092) - Added ability to test java library with VOLs. - Created a new CMake script that combines the java and vol test scripts. + Created a new CMake script that combines the java and vol test scripts. - (ADB - 2020/02/03, HDFFV-10996) + (ADB - 2020/02/03, HDFFV-10996) - Tests fail for non-English locales. - In the JUnit tests with a non-English locale, only the part before - the decimal comma is replaced by XXXX and this leads to a comparison - error. Changed the regex for the Time substitution. + In the JUnit tests with a non-English locale, only the part before + the decimal comma is replaced by XXXX and this leads to a comparison + error. Changed the regex for the Time substitution. - (ADB - 2020/01/09, HDFFV-10995) + (ADB - 2020/01/09, HDFFV-10995) Tools: ------ - Refactored the perform tools and removed depends on test library. - Moved the perf and h5perf tools from tools/test/perform to - tools/src/h5perf so that they can be installed. This required - that the test library dependency be removed by copying the - needed functions from h5test.c. - The standalone scripts and other perform tools remain in the - tools/test/perform folder. + Moved the perf and h5perf tools from tools/test/perform to + tools/src/h5perf so that they can be installed. This required + that the test library dependency be removed by copying the + needed functions from h5test.c. + The standalone scripts and other perform tools remain in the + tools/test/perform folder. - (ADB - 2021/08/10) + (ADB - 2021/08/10) - Removed partial long exceptions - Some of the tools accepted shortened versions of the long options - (ex: --datas instead of --dataset). These were implemented inconsistently, - are difficult to maintian, and occasionally block useful long option - names. These partial long options have been removed from all the tools. + Some of the tools accepted shortened versions of the long options + (ex: --datas instead of --dataset). These were implemented inconsistently, + are difficult to maintian, and occasionally block useful long option + names. These partial long options have been removed from all the tools. - (DER - 2021/08/03) + (DER - 2021/08/03) - h5repack added help text for user-defined filters. - Added help text line that states the valid values of the filter flag - for user-defined filters; - filter_flag: 1 is OPTIONAL or 0 is MANDATORY + Added help text line that states the valid values of the filter flag + for user-defined filters; + filter_flag: 1 is OPTIONAL or 0 is MANDATORY - (ADB - 2021/01/14, HDFFV-11099) + (ADB - 2021/01/14, HDFFV-11099) - Added h5delete tool - Deleting HDF5 storage when using the VOL can be tricky when the VOL - does not create files. The h5delete tool is a simple wrapper around - the H5Fdelete() API call that uses the VOL specified in the - HDF5_VOL_CONNECTOR environment variable to delete a "file". If - the call to H5Fdelete() fails, the tool will attempt to use - the POSIX remove(3) call to remove the file. + Deleting HDF5 storage when using the VOL can be tricky when the VOL + does not create files. The h5delete tool is a simple wrapper around + the H5Fdelete() API call that uses the VOL specified in the + HDF5_VOL_CONNECTOR environment variable to delete a "file". If + the call to H5Fdelete() fails, the tool will attempt to use + the POSIX remove(3) call to remove the file. - Note that the HDF5 library does currently have support for - H5Fdelete() in the native VOL connector. + Note that the HDF5 library does currently have support for + H5Fdelete() in the native VOL connector. - (DER - 2020/12/16) + (DER - 2020/12/16) - h5repack added options to control how external links are handled. - Currently h5repack preserves external links and cannot copy and merge - data from the external files. Two options, merge and prune, were added to - control how to merge data from an external link into the resulting file. - --merge Follow external soft link recursively and merge data. - --prune Do not follow external soft links and remove link. - --merge --prune Follow external link, merge data and remove dangling link. + Currently h5repack preserves external links and cannot copy and merge + data from the external files. Two options, merge and prune, were added to + control how to merge data from an external link into the resulting file. + --merge Follow external soft link recursively and merge data. + --prune Do not follow external soft links and remove link. + --merge --prune Follow external link, merge data and remove dangling link. - (ADB - 2020/08/05, HDFFV-9984) + (ADB - 2020/08/05, HDFFV-9984) - h5repack was fixed to repack the reference attributes properly. - The code line that checks if the update of reference inside a compound - datatype is misplaced outside the code block loop that carries out the - check. In consequence, the next attribute that is not the reference - type was repacked again as the reference type and caused the failure of - repacking. The fix is to move the corresponding code line to the correct - code block. + The code line that checks if the update of reference inside a compound + datatype is misplaced outside the code block loop that carries out the + check. In consequence, the next attribute that is not the reference + type was repacked again as the reference type and caused the failure of + repacking. The fix is to move the corresponding code line to the correct + code block. - (KY -2020/02/07, HDFFV-11014) + (KY -2020/02/07, HDFFV-11014) - h5diff was updated to use the new reference APIs. - h5diff uses the new reference APIs to compare references. - Attribute references can also be compared. + h5diff uses the new reference APIs to compare references. + Attribute references can also be compared. - (ADB - 2019/12/19, HDFFV-10980) + (ADB - 2019/12/19, HDFFV-10980) - h5dump and h5ls were updated to use the new reference APIs. - The tools library now use the new reference APIs to inspect a - file. Also the DDL spec was updated to reflect the format - changes produced with the new APIs. The export API and support - functions in the JNI were updated to match. + The tools library now use the new reference APIs to inspect a + file. Also the DDL spec was updated to reflect the format + changes produced with the new APIs. The export API and support + functions in the JNI were updated to match. - (ADB - 2019/12/06, HDFFV-10876 and HDFFV-10877) + (ADB - 2019/12/06, HDFFV-10876 and HDFFV-10877) High-Level APIs: ---------------- - added set/get for unsigned long long attributes - the attribute writing high-level API has been expanded to include - public set/get functions for ULL attributes, analogously to the - existing set/get for other types. + The attribute writing high-level API has been expanded to include + public set/get functions for ULL attributes, analogously to the + existing set/get for other types. - (AF - 2021/09/08) + (AF - 2021/09/08) C Packet Table API: ------------------- @@ -943,210 +978,262 @@ Bug Fixes since HDF5-1.12.0 release =================================== Library ------- + - Fixed an H5Pget_filter_by_id1/2() assert w/ out of range filter IDs + + Both H5Pget_filter_by_id1 and 2 did not range check the filter ID, which + could trip as assert in debug versions of the library. The library now + returns a normal HDF5 error when the filter ID is out of range. + + (DER - 2021/11/23, HDFFV-11286) + + - Fixed an issue with collective metadata reads being permanently disabled + after a dataset chunk lookup operation. This would usually cause a + mismatched MPI_Bcast and MPI_ERR_TRUNCATE issue in the library for + simple cases of H5Dcreate() -> H5Dwrite() -> H5Dcreate(). + + (JTH - 2021/11/08, HDFFV-11090) + + - Fixed cross platform incompatibility of references within variable length + types + + Reference types within variable length types previously could not be + read on a platform with different endianness from where they were + written. Fixed so cross platform portability is restored. + + (NAF - 2021/09/30) + - Detection of simple data transform function "x" - In the case of the simple data transform function "x" the (parallel) - library recognizes this is the same as not applying this data transform - function. This improves the I/O performance. In the case of the parallel - library, it also avoids breaking to independent I/O, which makes it - possible to apply a filter when writing or reading data to or from - teh HDF5 file. + In the case of the simple data transform function "x" the (parallel) + library recognizes this is the same as not applying this data transform + function. This improves the I/O performance. In the case of the parallel + library, it also avoids breaking to independent I/O, which makes it + possible to apply a filter when writing or reading data to or from + the HDF5 file. - (JWSB - 2021/09/13) + (JWSB - 2021/09/13) - Fixed an invalid read and memory leak when parsing corrupt file space info messages - When the corrupt file from CVE-2020-10810 was parsed by the library, - the code that imports the version 0 file space info object header - message to the version 1 struct could read past the buffer read from - the disk, causing an invalid memory read. Not catching this error would - cause downstream errors that eventually resulted in a previously - allocated buffer to be unfreed when the library shut down. In builds - where the free lists are in use, this could result in an infinite loop - and SIGABRT when the library shuts down. + When the corrupt file from CVE-2020-10810 was parsed by the library, + the code that imports the version 0 file space info object header + message to the version 1 struct could read past the buffer read from + the disk, causing an invalid memory read. Not catching this error would + cause downstream errors that eventually resulted in a previously + allocated buffer to be unfreed when the library shut down. In builds + where the free lists are in use, this could result in an infinite loop + and SIGABRT when the library shuts down. - We now track the buffer size and raise an error on attempts to read - past the end of it. + We now track the buffer size and raise an error on attempts to read + past the end of it. - (DER - 2021/08/12, HDFFV-11053) + (DER - 2021/08/12, HDFFV-11053) - Fixed CVE-2018-14460 - The tool h5repack produced a segfault when the rank in dataspace - message was corrupted, causing invalid read while decoding the - dimension sizes. + The tool h5repack produced a segfault when the rank in dataspace + message was corrupted, causing invalid read while decoding the + dimension sizes. - The problem was fixed by ensuring that decoding the dimension sizes - and max values will not go beyong the end of the buffer. + The problem was fixed by ensuring that decoding the dimension sizes + and max values will not go beyong the end of the buffer. - (BMR - 2021/05/12, HDFFV-11223) + (BMR - 2021/05/12, HDFFV-11223) - Fixed CVE-2018-11206 - The tool h5dump produced a segfault when the size of a fill value - message was corrupted and caused a buffer overflow. + The tool h5dump produced a segfault when the size of a fill value + message was corrupted and caused a buffer overflow. - The problem was fixed by verifying the fill value's size - against the buffer size before attempting to access the buffer. + The problem was fixed by verifying the fill value's size + against the buffer size before attempting to access the buffer. - (BMR - 2021/03/15, HDFFV-10480) + (BMR - 2021/03/15, HDFFV-10480) - Fixed CVE-2018-14033 (same issue as CVE-2020-10811) - The tool h5dump produced a segfault when the storage size message - was corrupted and caused a buffer overflow. + The tool h5dump produced a segfault when the storage size message + was corrupted and caused a buffer overflow. - The problem was fixed by verifying the storage size against the - buffer size before attempting to access the buffer. + The problem was fixed by verifying the storage size against the + buffer size before attempting to access the buffer. - (BMR - 2021/03/15, HDFFV-11159/HDFFV-11049) + (BMR - 2021/03/15, HDFFV-11159/HDFFV-11049) - Remove underscores on header file guards - Header file guards used a variety of underscores at the beginning of the define. + Header file guards used a variety of underscores at the beginning of the define. + + Removed all leading (some trailing) underscores from header file guards. + + (ADB - 2021/03/03, #361) - Removed all leading (some trailing) underscores from header file guards. + - Fixed a segmentation fault - (ADB - 2021/03/03, #361) + A segmentation fault occurred with a Mathworks corrupted file. + + A detection of accessing a null pointer was added to prevent the problem. + + (BMR - 2021/02/19, HDFFV-11150) - Fixed issue with MPI communicator and info object not being copied into new FAPL retrieved from H5F_get_access_plist - Added logic to copy the MPI communicator and info object into - the output FAPL. MPI communicator is retrieved from the VFD, while - the MPI info object is retrieved from the file's original FAPL. + Added logic to copy the MPI communicator and info object into + the output FAPL. MPI communicator is retrieved from the VFD, while + the MPI info object is retrieved from the file's original FAPL. - (JTH - 2021/02/15, HDFFV-11109) + (JTH - 2021/02/15, HDFFV-11109) - Fixed problems with vlens and refs inside compound using H5VLget_file_type() - Modified library to properly ref count H5VL_object_t structs and only - consider file vlen and reference types to be equal if their files are - the same. + Modified library to properly ref count H5VL_object_t structs and only + consider file vlen and reference types to be equal if their files are + the same. + + (NAF - 2021/01/22) + + - Fixed CVE-2018-17432 - (NAF - 2021/01/22) + The tool h5repack produced a segfault on a corrupted file which had + invalid rank for scalar or NULL datatype. + + The problem was fixed by modifying the dataspace encode and decode + functions to detect and report invalid rank. h5repack now fails + with an error message for the corrupted file. + + (BMR - 2020/10/26, HDFFV-10590) - Creation of dataset with optional filter - When the combination of type, space, etc doesn't work for filter - and the filter is optional, it was supposed to be skipped but it was - not skipped and the creation failed. + When the combination of type, space, etc doesn't work for filter + and the filter is optional, it was supposed to be skipped but it was + not skipped and the creation failed. - Allowed the creation of the dataset in such a situation. + Allowed the creation of the dataset in such a situation. - (BMR - 2020/08/13, HDFFV-10933) + (BMR - 2020/08/13, HDFFV-10933) - Explicitly declared dlopen to use RTLD_LOCAL - dlopen documentation states that if neither RTLD_GLOBAL nor - RTLD_LOCAL are specified, then the default behavior is unspecified. - The default on linux is usually RTLD_LOCAL while macos will default - to RTLD_GLOBAL. + dlopen documentation states that if neither RTLD_GLOBAL nor + RTLD_LOCAL are specified, then the default behavior is unspecified. + The default on linux is usually RTLD_LOCAL while macos will default + to RTLD_GLOBAL. - (ADB - 2020/08/12, HDFFV-11127) + (ADB - 2020/08/12, HDFFV-11127) - H5Sset_extent_none() sets the dataspace class to H5S_NO_CLASS which causes asserts/errors when passed to other dataspace API calls. - H5S_NO_CLASS is an internal class value that should not have been - exposed via a public API call. + H5S_NO_CLASS is an internal class value that should not have been + exposed via a public API call. - In debug builds of the library, this can cause assert() function to - trip. In non-debug builds, it will produce normal library errors. + In debug builds of the library, this can cause assert() function to + trip. In non-debug builds, it will produce normal library errors. - The new library behavior is for H5Sset_extent_none() to convert - the dataspace into one of type H5S_NULL, which is better handled - by the library and easier for developers to reason about. + The new library behavior is for H5Sset_extent_none() to convert + the dataspace into one of type H5S_NULL, which is better handled + by the library and easier for developers to reason about. - (DER - 2020/07/27, HDFFV-11027) + (DER - 2020/07/27, HDFFV-11027) - Fixed issues CVE-2018-13870 and CVE-2018-13869 - When a buffer overflow occurred because a name length was corrupted - and became very large, h5dump crashed on memory access violation. + When a buffer overflow occurred because a name length was corrupted + and became very large, h5dump crashed on memory access violation. - A check for reading pass the end of the buffer was added to multiple - locations to prevent the crashes and h5dump now simply fails with an - error message when this error condition occurs. + A check for reading pass the end of the buffer was added to multiple + locations to prevent the crashes and h5dump now simply fails with an + error message when this error condition occurs. - (BMR - 2020/07/22, HDFFV-11120 and HDFFV-11121) + (BMR - 2020/07/22, HDFFV-11120 and HDFFV-11121) - Fixed the segmentation fault when reading attributes with multiple threads - It was reported that the reading of attributes with variable length string - datatype will crash with segmentation fault particularly when the number of - threads is high (>16 threads). The problem was due to the file pointer that - was set in the variable length string datatype for the attribute. That file - pointer was already closed when the attribute was accessed. + It was reported that the reading of attributes with variable length string + datatype will crash with segmentation fault particularly when the number of + threads is high (>16 threads). The problem was due to the file pointer that + was set in the variable length string datatype for the attribute. That file + pointer was already closed when the attribute was accessed. - The problem was fixed by setting the file pointer to the current opened file pointer - when the attribute was accessed. Similar patch up was done before when reading - dataset with variable length string datatype. + The problem was fixed by setting the file pointer to the current opened file pointer + when the attribute was accessed. Similar patch up was done before when reading + dataset with variable length string datatype. - (VC - 2020/07/13, HDFFV-11080) + (VC - 2020/07/13, HDFFV-11080) - Fixed CVE-2020-10810 - The tool h5clear produced a segfault during an error recovery in - the superblock decoding. An internal pointer was reset to prevent - further accessing when it is not assigned with a value. + The tool h5clear produced a segfault during an error recovery in + the superblock decoding. An internal pointer was reset to prevent + further accessing when it is not assigned with a value. - (BMR - 2020/06/29, HDFFV-11053) + (BMR - 2020/06/29, HDFFV-11053) - Fixed CVE-2018-17435 - The tool h52gif produced a segfault when the size of an attribute - message was corrupted and caused a buffer overflow. + The tool h52gif produced a segfault when the size of an attribute + message was corrupted and caused a buffer overflow. - The problem was fixed by verifying the attribute message's size - against the buffer size before accessing the buffer. h52gif was - also fixed to display the failure instead of silently exiting - after the segfault was eliminated. + The problem was fixed by verifying the attribute message's size + against the buffer size before accessing the buffer. h52gif was + also fixed to display the failure instead of silently exiting + after the segfault was eliminated. - (BMR - 2020/06/19, HDFFV-10591) + (BMR - 2020/06/19, HDFFV-10591) Java Library ------------ - JNI utility function does not handle new references. - The JNI utility function for converting reference data to string did - not use the new APIs. In addition to fixing that function, added new - java tests for using the new APIs. + The JNI utility function for converting reference data to string did + not use the new APIs. In addition to fixing that function, added new + java tests for using the new APIs. - (ADB - 2021/02/16, HDFFV-11212) + (ADB - 2021/02/16, HDFFV-11212) - The H5FArray.java class, in which virtually the entire execution time - is spent using the HDFNativeData method that converts from an array - of bytes to an array of the destination Java type. + is spent using the HDFNativeData method that converts from an array + of bytes to an array of the destination Java type. 1. Convert the entire byte array into a 1-d array of the desired type, rather than performing 1 conversion per row; 2. Use the Java Arrays method copyOfRange to grab the section of the array from (1) that is desired to be inserted into the destination array. - (PGT,ADB - 2020/12/13, HDFFV-10865) + (PGT,ADB - 2020/12/13, HDFFV-10865) - Added ability to test java library with VOLs. - Created a new CMake script that combines the java and vol test scripts. + Created a new CMake script that combines the java and vol test scripts. - (ADB - 2020/02/03, HDFFV-10996) + (ADB - 2020/02/03, HDFFV-10996) - Tests fail for non-English locales. - In the JUnit tests with a non-English locale, only the part before - the decimal comma is replaced by XXXX and this leads to a comparison - error. Changed the regex for the Time substitution. + In the JUnit tests with a non-English locale, only the part before + the decimal comma is replaced by XXXX and this leads to a comparison + error. Changed the regex for the Time substitution. - (ADB - 2020/01/09, HDFFV-10995) + (ADB - 2020/01/09, HDFFV-10995) Configuration ------------- + - Corrected path searched by CMake find_package command + + The install path for cmake find_package files had been changed to use + "share/cmake" + for all platforms. However the trailing "hdf5" directory was not removed. + This "hdf5" additional directory has been removed. + + (ADB - 2021/09/27) + - Corrected pkg-config compile script It was discovered that the position of the "$@" argument for the command @@ -1251,88 +1338,88 @@ Bug Fixes since HDF5-1.12.0 release ----- - Changed how h5dump and h5ls identify long double. - Long double support is not consistent across platforms. Tools will always - identify long double as 128-bit [little/big]-endian float nn-bit precision. - New test file created for datasets with attributes for float, double and - long double. In addition any unknown integer or float datatype will now - also show the number of bits for precision. - These files are also used in the java tests. + Long double support is not consistent across platforms. Tools will always + identify long double as 128-bit [little/big]-endian float nn-bit precision. + New test file created for datasets with attributes for float, double and + long double. In addition any unknown integer or float datatype will now + also show the number of bits for precision. + These files are also used in the java tests. - (ADB - 2021/03/24, HDFFV-11229,HDFFV-11113) + (ADB - 2021/03/24, HDFFV-11229,HDFFV-11113) - Fixed tools argument parsing. - Tools parsing used the length of the option from the long array to match - the option from the command line. This incorrectly matched a shorter long - name option that happened to be a subset of another long option. - Changed to match whole names. + Tools parsing used the length of the option from the long array to match + the option from the command line. This incorrectly matched a shorter long + name option that happened to be a subset of another long option. + Changed to match whole names. - (ADB - 2021/01/19, HDFFV-11106) + (ADB - 2021/01/19, HDFFV-11106) - The tools library was updated by standardizing the error stack process. - General sequence is: - h5tools_setprogname(PROGRAMNAME); - h5tools_setstatus(EXIT_SUCCESS); - h5tools_init(); - ... process the command-line (check for error-stack enable) ... - h5tools_error_report(); - ... (do work) ... - h5diff_exit(ret); + General sequence is: + h5tools_setprogname(PROGRAMNAME); + h5tools_setstatus(EXIT_SUCCESS); + h5tools_init(); + ... process the command-line (check for error-stack enable) ... + h5tools_error_report(); + ... (do work) ... + h5diff_exit(ret); - (ADB - 2020/07/20, HDFFV-11066) + (ADB - 2020/07/20, HDFFV-11066) - h5diff fixed a command line parsing error. - h5diff would ignore the argument to -d (delta) if it is smaller than DBL_EPSILON. - The macro H5_DBL_ABS_EQUAL was removed and a direct value comparision was used. + h5diff would ignore the argument to -d (delta) if it is smaller than DBL_EPSILON. + The macro H5_DBL_ABS_EQUAL was removed and a direct value comparision was used. - (ADB - 2020/07/20, HDFFV-10897) + (ADB - 2020/07/20, HDFFV-10897) - h5diff added a command line option to ignore attributes. - h5diff would ignore all objects with a supplied path if the exclude-path argument is used. - Adding the exclude-attribute argument will only exclude attributes, with the supplied path, - from comparison. + h5diff would ignore all objects with a supplied path if the exclude-path argument is used. + Adding the exclude-attribute argument will only exclude attributes, with the supplied path, + from comparison. - (ADB - 2020/07/20, HDFFV-5935) + (ADB - 2020/07/20, HDFFV-5935) - h5diff added another level to the verbose argument to print filenames. - Added verbose level 3 that is level 2 plus the filenames. The levels are: - 0 : Identical to '-v' or '--verbose' - 1 : All level 0 information plus one-line attribute status summary - 2 : All level 1 information plus extended attribute status report - 3 : All level 2 information plus file names + Added verbose level 3 that is level 2 plus the filenames. The levels are: + 0 : Identical to '-v' or '--verbose' + 1 : All level 0 information plus one-line attribute status summary + 2 : All level 1 information plus extended attribute status report + 3 : All level 2 information plus file names - (ADB - 2020/07/20, HDFFV-1005) + (ADB - 2020/07/20, HDFFV-1005) - h5repack was fixed to repack the reference attributes properly. - The code line that checks if the update of reference inside a compound - datatype is misplaced outside the code block loop that carries out the - check. In consequence, the next attribute that is not the reference - type was repacked again as the reference type and caused the failure of - repacking. The fix is to move the corresponding code line to the correct - code block. + The code line that checks if the update of reference inside a compound + datatype is misplaced outside the code block loop that carries out the + check. In consequence, the next attribute that is not the reference + type was repacked again as the reference type and caused the failure of + repacking. The fix is to move the corresponding code line to the correct + code block. - (KY -2020/02/10, HDFFV-11014) + (KY -2020/02/10, HDFFV-11014) - h5diff was updated to use the new reference APIs. - h5diff uses the new reference APIs to compare references. - Attribute references can also be compared. + h5diff uses the new reference APIs to compare references. + Attribute references can also be compared. - (ADB - 2019/12/19, HDFFV-10980) + (ADB - 2019/12/19, HDFFV-10980) - h5dump and h5ls were updated to use the new reference APIs. - The tools library now use the new reference APIs to inspect a - file. Also the DDL spec was updated to reflect the format - changes produced with the new APIs. The export API and support - functions in the JNI were updated to match. + The tools library now use the new reference APIs to inspect a + file. Also the DDL spec was updated to reflect the format + changes produced with the new APIs. The export API and support + functions in the JNI were updated to match. - (ADB - 2019/12/06, HDFFV-10876 and HDFFV-10877) + (ADB - 2019/12/06, HDFFV-10876 and HDFFV-10877) Performance @@ -1344,12 +1431,16 @@ Bug Fixes since HDF5-1.12.0 release ----------- - Corrected INTERFACE INTENT(IN) to INTENT(OUT) for buf_size in h5fget_file_image_f. - (MSB - 2020/02/18, HDFFV-11029) + (MSB - 2020/02/18, HDFFV-11029) High-Level Library ------------------ - - + - Fixed HL_test_packet, test for packet table vlen of vlen. + + Incorrect length assignment. + + (ADB - 2021/10/14) Fortran High-Level APIs @@ -1371,172 +1462,128 @@ Bug Fixes since HDF5-1.12.0 release -------- - Added DataSet::operator= - Some compilers complain if the copy constructor is given explicitly - but the assignment operator is implicitly set to default. + Some compilers complain if the copy constructor is given explicitly + but the assignment operator is implicitly set to default. - (2021/05/19) + (2021/05/19) Testing ------- - Stopped java/test/junit.sh.in installing libs for testing under ${prefix} - Lib files needed are now copied to a subdirectory in the java/test - directory, and on Macs the loader path for libhdf5.xxxs.so is changed - in the temporary copy of libhdf5_java.dylib. + Lib files needed are now copied to a subdirectory in the java/test + directory, and on Macs the loader path for libhdf5.xxxs.so is changed + in the temporary copy of libhdf5_java.dylib. - (LRK, 2020/07/02, HDFFV-11063) + (LRK, 2020/07/02, HDFFV-11063) -Supported Platforms +Platforms Tested =================== - Linux 2.6.32-696.16.1.el6.ppc64 gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18) - #1 SMP ppc64 GNU/Linux g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18) - (ostrich) GNU Fortran (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18) - IBM XL C/C++ V13.1 - IBM XL Fortran V15.1 - - Linux 3.10.0-327.10.1.el7 GNU C (gcc), Fortran (gfortran), C++ (g++) - #1 SMP x86_64 GNU/Linux compilers: - (kituo/moohan) Version 4.8.5 20150623 (Red Hat 4.8.5-4) - Version 4.9.3, Version 5.2.0, - Intel(R) C (icc), C++ (icpc), Fortran (icc) - compilers: - Version 17.0.0.098 Build 20160721 - MPICH 3.1.4 compiled with GCC 4.9.3 - - SunOS 5.11 32- and 64-bit Sun C 5.12 SunOS_sparc - (emu) Sun Fortran 95 8.6 SunOS_sparc - Sun C++ 5.12 SunOS_sparc - - Windows 10 x64 Visual Studio 2015 w/ Intel Fortran 18 (cmake) - Visual Studio 2017 w/ Intel Fortran 19 (cmake) - Visual Studio 2019 w/ Intel Fortran 19 (cmake) - Visual Studio 2019 w/ MSMPI 10.1 (cmake) - - Mac OS X Yosemite 10.10.5 Apple clang/clang++ version 6.1 from Xcode 7.0 - 64-bit gfortran GNU Fortran (GCC) 4.9.2 - (osx1010dev/osx1010test) Intel icc/icpc/ifort version 15.0.3 - - Mac OS X El Capitan 10.11.6 Apple clang/clang++ version 7.3.0 from Xcode 7.3 - 64-bit gfortran GNU Fortran (GCC) 5.2.0 - (osx1011dev/osx1011test) Intel icc/icpc/ifort version 16.0.2 - - Mac OS Sierra 10.12.6 Apple LLVM version 8.1.0 (clang/clang++-802.0.42) - 64-bit gfortran GNU Fortran (GCC) 7.1.0 - (swallow/kite) Intel icc/icpc/ifort version 17.0.2 - - -Tested Configuration Features Summary -===================================== - - In the tables below - y = tested - n = not tested in this release - C = Cluster - W = Workstation - x = not working in this release - dna = does not apply - ( ) = footnote appears below second table - = testing incomplete on this feature or platform - -Platform C F90/ F90 C++ zlib SZIP - parallel F2003 parallel -Solaris2.11 32-bit n y/y n y y y -Solaris2.11 64-bit n y/n n y y y -Windows 10 y y/y n y y y -Windows 10 x64 y y/y n y y y -Mac OS X Mountain Lion 10.8.5 64-bit n y/y n y y y -Mac OS X Mavericks 10.9.5 64-bit n y/y n y y ? -Mac OS X Yosemite 10.10.5 64-bit n y/y n y y ? -Mac OS X El Capitan 10.11.6 64-bit n y/y n y y ? -CentOS 6.7 Linux 2.6.18 x86_64 GNU n y/y n y y y -CentOS 6.7 Linux 2.6.18 x86_64 Intel n y/y n y y y -CentOS 6.7 Linux 2.6.32 x86_64 PGI n y/y n y y y -CentOS 7.2 Linux 2.6.32 x86_64 GNU y y/y y y y y -CentOS 7.2 Linux 2.6.32 x86_64 Intel n y/y n y y y -Linux 2.6.32-573.18.1.el6.ppc64 n y/n n y y y - - -Platform Shared Shared Shared Thread- - C libs F90 libs C++ libs safe -Solaris2.11 32-bit y y y y -Solaris2.11 64-bit y y y y -Windows 10 y y y y -Windows 10 x64 y y y y -Mac OS X Mountain Lion 10.8.5 64-bit y n y y -Mac OS X Mavericks 10.9.5 64-bit y n y y -Mac OS X Yosemite 10.10.5 64-bit y n y y -Mac OS X El Capitan 10.11.6 64-bit y n y y -CentOS 6.7 Linux 2.6.18 x86_64 GNU y y y y -CentOS 6.7 Linux 2.6.18 x86_64 Intel y y y n -CentOS 6.7 Linux 2.6.32 x86_64 PGI y y y n -CentOS 7.2 Linux 2.6.32 x86_64 GNU y y y n -CentOS 7.2 Linux 2.6.32 x86_64 Intel y y y n -Linux 2.6.32-573.18.1.el6.ppc64 y y y n - -Compiler versions for each platform are listed in the preceding -"Supported Platforms" table. - - -More Tested Platforms -===================== -The following platforms are not supported but have been tested for this release. - - Linux 2.6.32-573.22.1.el6 GNU C (gcc), Fortran (gfortran), C++ (g++) - #1 SMP x86_64 GNU/Linux compilers: - (mayll/platypus) Version 4.4.7 20120313 - Version 4.9.3, 5.3.0, 6.2.0 - PGI C, Fortran, C++ for 64-bit target on - x86-64; - Version 17.10-0 - Intel(R) C (icc), C++ (icpc), Fortran (icc) - compilers: - Version 17.0.4.196 Build 20170411 - MPICH 3.1.4 compiled with GCC 4.9.3 - - Linux 3.10.0-327.18.2.el7 GNU C (gcc) and C++ (g++) compilers - #1 SMP x86_64 GNU/Linux Version 4.8.5 20150623 (Red Hat 4.8.5-4) - (jelly) with NAG Fortran Compiler Release 6.1(Tozai) - GCC Version 7.1.0 - OpenMPI 3.0.0-GCC-7.2.0-2.29 - Intel(R) C (icc) and C++ (icpc) compilers - Version 17.0.0.098 Build 20160721 - with NAG Fortran Compiler Release 6.1(Tozai) - - Linux 3.10.0-327.10.1.el7 MPICH 3.2 compiled with GCC 5.3.0 - #1 SMP x86_64 GNU/Linux - (moohan) - - Linux 2.6.32-573.18.1.el6.ppc64 MPICH mpich 3.1.4 compiled with - #1 SMP ppc64 GNU/Linux IBM XL C/C++ for Linux, V13.1 - (ostrich) and IBM XL Fortran for Linux, V15.1 - - Fedora33 5.11.18-200.fc33.x86_64 - #1 SMP x86_64 GNU/Linux GNU gcc (GCC) 10.3.1 20210422 (Red Hat 10.3.1-1) - GNU Fortran (GCC) 10.3.1 20210422 (Red Hat 10.3.1-1) - clang version 11.0.0 (Fedora 11.0.0-2.fc33) + Linux 5.13.14-200.fc34 GNU gcc (GCC) 11.2.1 2021078 (Red Hat 11.2.1-1) + #1 SMP x86_64 GNU/Linux GNU Fortran (GCC) 11.2.1 2021078 (Red Hat 11.2.1-1) + Fedora34 clang version 12.0.1 (Fedora 12.0.1-1.fc34) (cmake and autotools) - Ubuntu20.04 5.8.0-53-generic-x86_64 - #60~20.04-Ubuntu SMP x86_64 GNU/Linux GNU gcc (GCC) 9.3.0-17ubuntu1 - GNU Fortran (GCC) 9.3.0-17ubuntu1 - clang version 10.0.0-4ubuntu1 + Linux 5.11.0-34-generic GNU gcc (GCC) 9.3.0-17ubuntu1 + #36-Ubuntu SMP x86_64 GNU/Linux GNU Fortran (GCC) 9.3.0-17ubuntu1 + Ubuntu 20.04 Ubuntu clang version 10.0.0-4 (cmake and autotools) - Ubuntu20.10 5.8.0-53-generic-x86_64 - #60-Ubuntu SMP x86_64 GNU/Linux GNU gcc (GCC) 10.2.0-13ubuntu1 - GNU Fortran (GCC) 10.2.0-13ubuntu1 - Ubuntu clang version 11.0.0-2 + Linux 5.8.0-63-generic GNU gcc (GCC) 10.3.0-1ubuntu1 + #71-Ubuntu SMP x86_64 GNU/Linux GNU Fortran (GCC) 10.3.0-1ubuntu1 + Ubuntu20.10 Ubuntu clang version 11.0.0-2 (cmake and autotools) - SUSE15sp2 5.3.18-22-default - #1 SMP x86_64 GNU/Linux GNU gcc (SUSE Linux) 7.5.0 - GNU Fortran (SUSE Linux) 7.5.0 - clang version 7.0.1 (tags/RELEASE_701/final 349238) + Linux 5.3.18-22-default GNU gcc (SUSE Linux) 7.5.0 + #1 SMP x86_64 GNU/Linux GNU Fortran (SUSE Linux) 7.5.0 + SUSE15sp2 clang version 7.0.1 (tags/RELEASE_701/final 349238) (cmake and autotools) + Linux-4.14.0-115.21.2 spectrum-mpi/rolling-release + #1 SMP ppc64le GNU/Linux clang 8.0.1, 11.0.1 + (lassen) GCC 7.3.1 + XL 16.1.1.2 + (cmake) + + Linux-4.12.14-150.75-default cray-mpich/7.7.10 + #1 SMP x86_64 GNU/Linux GCC 7.3.0, 8.2.0 + (cori) Intel (R) Version 19.0.3.199 + (cmake) + + Linux-4.12.14-197.86-default cray-mpich/7.7.6 + # 1SMP x86_64 GNU/Linux GCC 7.3.0, 9.3.0, 10.2.0 + (mutrino) Intel (R) Version 17.0.4, 18.0.5, 19.1.3 + (cmake) + + Linux 3.10.0-1160.36.2.el7.ppc64 gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39) + #1 SMP ppc64be GNU/Linux g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39) + Power8 (echidna) GNU Fortran (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39) + + Linux 3.10.0-1160.24.1.el7 GNU C (gcc), Fortran (gfortran), C++ (g++) + #1 SMP x86_64 GNU/Linux compilers: + Centos7 Version 4.8.5 20150623 (Red Hat 4.8.5-4) + (jelly/kituo/moohan) Version 4.9.3, Version 5.3.0, Version 6.3.0, + Version 7.2.0, Version 8.3.0, Version 9.1.0 + Intel(R) C (icc), C++ (icpc), Fortran (icc) + compilers: + Version 17.0.0.098 Build 20160721 + GNU C (gcc) and C++ (g++) 4.8.5 compilers + with NAG Fortran Compiler Release 6.1(Tozai) + Intel(R) C (icc) and C++ (icpc) 17.0.0.098 compilers + with NAG Fortran Compiler Release 6.1(Tozai) + MPICH 3.1.4 compiled with GCC 4.9.3 + MPICH 3.3 compiled with GCC 7.2.0 + OpenMPI 2.1.6 compiled with icc 18.0.1 + OpenMPI 3.1.3 and 4.0.0 compiled with GCC 7.2.0 + PGI C, Fortran, C++ for 64-bit target on + x86_64; + Version 19.10-0 + + Linux-3.10.0-1127.0.0.1chaos openmpi-4.0.0 + #1 SMP x86_64 GNU/Linux clang 6.0.0, 11.0.1 + (quartz) GCC 7.3.0, 8.1.0 + Intel 16.0.4, 18.0.2, 19.0.4 + + macOS Apple M1 11.6 Apple clang version 12.0.5 (clang-1205.0.22.11) + Darwin 20.6.0 arm64 gfortran GNU Fortran (Homebrew GCC 11.2.0) 11.1.0 + (macmini-m1) Intel icc/icpc/ifort version 2021.3.0 202106092021.3.0 20210609 + + macOS Big Sur 11.3.1 Apple clang version 12.0.5 (clang-1205.0.22.9) + Darwin 20.4.0 x86_64 gfortran GNU Fortran (Homebrew GCC 10.2.0_3) 10.2.0 + (bigsur-1) Intel icc/icpc/ifort version 2021.2.0 20210228 + + macOS High Sierra 10.13.6 Apple LLVM version 10.0.0 (clang-1000.10.44.4) + 64-bit gfortran GNU Fortran (GCC) 6.3.0 + (bear) Intel icc/icpc/ifort version 19.0.4.233 20190416 + + macOS Sierra 10.12.6 Apple LLVM version 9.0.0 (clang-900.39.2) + 64-bit gfortran GNU Fortran (GCC) 7.4.0 + (kite) Intel icc/icpc/ifort version 17.0.2 + + Mac OS X El Capitan 10.11.6 Apple clang version 7.3.0 from Xcode 7.3 + 64-bit gfortran GNU Fortran (GCC) 5.2.0 + (osx1011test) Intel icc/icpc/ifort version 16.0.2 + + + Linux 2.6.32-573.22.1.el6 GNU C (gcc), Fortran (gfortran), C++ (g++) + #1 SMP x86_64 GNU/Linux compilers: + Centos6 Version 4.4.7 20120313 + (platypus) Version 4.9.3, 5.3.0, 6.2.0 + MPICH 3.1.4 compiled with GCC 4.9.3 + PGI C, Fortran, C++ for 64-bit target on + x86_64; + Version 19.10-0 + + Windows 10 x64 Visual Studio 2015 w/ Intel C/C++/Fortran 18 (cmake) + Visual Studio 2017 w/ Intel C/C++/Fortran 19 (cmake) + Visual Studio 2019 w/ clang 12.0.0 + with MSVC-like command-line (C/C++ only - cmake) + Visual Studio 2019 w/ Intel Fortran 19 (cmake) + Visual Studio 2019 w/ MSMPI 10.1 (C only - cmake) + Known Problems ============== @@ -1599,3 +1646,11 @@ The share folder will have the most differences because CMake builds include a number of CMake specific files for support of CMake's find_package and support for the HDF5 Examples CMake project. +The issues with the gif tool are: + HDFFV-10592 CVE-2018-17433 + HDFFV-10593 CVE-2018-17436 + HDFFV-11048 CVE-2020-10809 +These CVE issues have not yet been addressed and can be avoided by not building +the gif tool. Disable building the High-Level tools with these options: + autotools: --disable-hltools + cmake: HDF5_BUILD_HL_TOOLS=OFF diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 955a394..33d31fb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1418,36 +1418,6 @@ endif () # Option to build documentation #----------------------------------------------------------------------------- if (DOXYGEN_FOUND) - set (DOXYGEN_PACKAGE ${HDF5_PACKAGE_NAME}) - set (DOXYGEN_VERSION_STRING ${HDF5_PACKAGE_VERSION_STRING}) - set (DOXYGEN_INCLUDE_ALIASES_PATH ${HDF5_DOXYGEN_DIR}) - set (DOXYGEN_INCLUDE_ALIASES aliases) - set (DOXYGEN_VERBATIM_VARS DOXYGEN_INCLUDE_ALIASES) - set (DOXYGEN_PROJECT_LOGO ${HDF5_DOXYGEN_DIR}/img/HDFG-logo.png) - set (DOXYGEN_PROJECT_BRIEF "C-API Reference") - set (DOXYGEN_INPUT_DIRECTORY "${HDF5_SRC_DIR} ${HDF5_DOXYGEN_DIR}/dox ${HDF5_GENERATED_SOURCE_DIR}") - set (DOXYGEN_OPTIMIZE_OUTPUT_FOR_C YES) - set (DOXYGEN_MACRO_EXPANSION YES) - set (DOXYGEN_OUTPUT_DIRECTORY ${HDF5_BINARY_DIR}/hdf5lib_docs) - set (DOXYGEN_EXAMPLES_DIRECTORY "${HDF5_DOXYGEN_DIR}/examples ${HDF5_SRC_DIR} ${HDF5_SOURCE_DIR}/examples ${HDF5_TEST_SRC_DIR}") - set (DOXYGEN_LAYOUT_FILE ${HDF5_DOXYGEN_DIR}/hdf5doxy_layout.xml) - set (DOXYGEN_HTML_HEADER ${HDF5_DOXYGEN_DIR}/hdf5_header.html) - set (DOXYGEN_HTML_FOOTER ${HDF5_DOXYGEN_DIR}/hdf5_footer.html) - set (DOXYGEN_HTML_EXTRA_STYLESHEET ${HDF5_DOXYGEN_DIR}/hdf5doxy.css) - set (DOXYGEN_HTML_EXTRA_FILES "${HDF5_DOXYGEN_DIR}/hdf5_navtree_hacks.js ${HDF5_DOXYGEN_DIR}/img/ftv2node.png ${HDF5_DOXYGEN_DIR}/img/ftv2pnode.png") - set (DOXYGEN_SERVER_BASED_SEARCH NO) - set (DOXYGEN_EXTERNAL_SEARCH NO) - set (DOXYGEN_SEARCHENGINE_URL) - -# This configure and custom target work together - # Replace variables inside @@ with the current values - configure_file (${HDF5_DOXYGEN_DIR}/Doxyfile.in ${HDF5_BINARY_DIR}/Doxyfile @ONLY) - add_custom_target (hdf5lib_doc ALL - COMMAND ${DOXYGEN_EXECUTABLE} ${HDF5_BINARY_DIR}/Doxyfile - DEPENDS ${HDF5_GENERATED_SOURCE_DIR}/H5Tinit.c ${HDF5_SRC_BINARY_DIR}/H5lib_settings.c - WORKING_DIRECTORY ${HDF5_SRC_DIR} - COMMENT "Generating HDF5 library Source API documentation with Doxygen" - VERBATIM ) # This cmake function requires that the non-default doxyfile settings are provided with set (DOXYGEN_xxx) commands # In addition the doxyfile aliases @INCLUDE option is not supported and would need to be provided in a set (DOXYGEN_ALIASES) command. # doxygen_add_docs (hdf5lib_doc @@ -1457,11 +1427,15 @@ if (DOXYGEN_FOUND) # WORKING_DIRECTORY ${HDF5_SRC_DIR} # COMMENT "Generating HDF5 library Source Documentation" # ) - install ( - DIRECTORY ${HDF5_BINARY_DIR}/hdf5lib_docs/html - DESTINATION ${HDF5_INSTALL_DATA_DIR} - COMPONENT Documents - ) + +# This custom target and doxygen/configure work together + # Replace variables inside @@ with the current values + add_custom_target (hdf5lib_doc ALL + COMMAND ${DOXYGEN_EXECUTABLE} ${HDF5_BINARY_DIR}/Doxyfile + DEPENDS ${HDF5_GENERATED_SOURCE_DIR}/H5Tinit.c ${HDF5_SRC_BINARY_DIR}/H5lib_settings.c + WORKING_DIRECTORY ${HDF5_SRC_DIR} + COMMENT "Generating HDF5 library Source API documentation with Doxygen" + VERBATIM ) if (NOT TARGET doxygen) add_custom_target (doxygen) diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h index a4e6d60..f7bed0c 100644 --- a/src/H5ACprivate.h +++ b/src/H5ACprivate.h @@ -234,27 +234,27 @@ typedef struct H5AC_proxy_entry_t { /* hbool_t evictions_enabled = */ TRUE, \ /* hbool_t set_initial_size = */ TRUE, \ /* size_t initial_size = */ ( 2 * 1024 * 1024), \ - /* double min_clean_fraction = */ 0.3f, \ + /* double min_clean_fraction = */ 0.3, \ /* size_t max_size = */ (32 * 1024 * 1024), \ /* size_t min_size = */ (1 * 1024 * 1024), \ /* long int epoch_length = */ 50000, \ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, \ - /* double lower_hr_threshold = */ 0.9f, \ - /* double increment = */ 2.0f, \ + /* double lower_hr_threshold = */ 0.9, \ + /* double increment = */ 2.0, \ /* hbool_t apply_max_increment = */ TRUE, \ /* size_t max_increment = */ (4 * 1024 * 1024), \ /* enum H5C_cache_flash_incr_mode */ \ /* flash_incr_mode = */ H5C_flash_incr__add_space, \ - /* double flash_multiple = */ 1.0f, \ - /* double flash_threshold = */ 0.25f, \ + /* double flash_multiple = */ 1.0, \ + /* double flash_threshold = */ 0.25, \ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, \ - /* double upper_hr_threshold = */ 0.999f, \ - /* double decrement = */ 0.9f, \ + /* double upper_hr_threshold = */ 0.999, \ + /* double decrement = */ 0.9, \ /* hbool_t apply_max_decrement = */ TRUE, \ /* size_t max_decrement = */ (1 * 1024 * 1024), \ /* int epochs_before_eviction = */ 3, \ /* hbool_t apply_empty_reserve = */ TRUE, \ - /* double empty_reserve = */ 0.1f, \ + /* double empty_reserve = */ 0.1, \ /* size_t dirty_bytes_threshold = */ (256 * 1024), \ /* int metadata_write_strategy = */ \ H5AC__DEFAULT_METADATA_WRITE_STRATEGY \ @@ -270,7 +270,7 @@ typedef struct H5AC_proxy_entry_t { /* hbool_t evictions_enabled = */ TRUE, \ /* hbool_t set_initial_size = */ TRUE, \ /* size_t initial_size = */ ( 2 * 1024 * 1024), \ - /* double min_clean_fraction = */ 0.01f, \ + /* double min_clean_fraction = */ 0.01, \ /* size_t max_size = */ (32 * 1024 * 1024), \ /* size_t min_size = */ ( 1 * 1024 * 1024), \ /* long int epoch_length = */ 50000, \ diff --git a/src/H5B2int.c b/src/H5B2int.c index 610da6c..ab43a5a 100644 --- a/src/H5B2int.c +++ b/src/H5B2int.c @@ -52,9 +52,9 @@ /********************/ /* Local Prototypes */ /********************/ -static herr_t H5B2__update_child_flush_depends(H5B2_hdr_t *hdr, unsigned depth, - const H5B2_node_ptr_t *node_ptrs, unsigned start_idx, - unsigned end_idx, void *old_parent, void *new_parent); +static herr_t H5B2__update_child_flush_depends(H5B2_hdr_t *hdr, unsigned depth, H5B2_node_ptr_t *node_ptrs, + unsigned start_idx, unsigned end_idx, void *old_parent, + void *new_parent); /*********************/ /* Package Variables */ @@ -1617,7 +1617,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2__iterate_node(H5B2_hdr_t *hdr, uint16_t depth, const H5B2_node_ptr_t *curr_node, void *parent, +H5B2__iterate_node(H5B2_hdr_t *hdr, uint16_t depth, H5B2_node_ptr_t *curr_node, void *parent, H5B2_operator_t op, void *op_data) { const H5AC_class_t *curr_node_class = NULL; /* Pointer to current node's class info */ @@ -1642,8 +1642,7 @@ H5B2__iterate_node(H5B2_hdr_t *hdr, uint16_t depth, const H5B2_node_ptr_t *curr_ /* Lock the current B-tree node */ if (NULL == - (internal = H5B2__protect_internal(hdr, parent, (H5B2_node_ptr_t *)curr_node, depth, FALSE, - H5AC__READ_ONLY_FLAG))) /* Casting away const OK -QAK */ + (internal = H5B2__protect_internal(hdr, parent, curr_node, depth, FALSE, H5AC__READ_ONLY_FLAG))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect B-tree internal node") /* Set up information about current node */ @@ -1739,8 +1738,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2__delete_node(H5B2_hdr_t *hdr, uint16_t depth, const H5B2_node_ptr_t *curr_node, void *parent, - H5B2_remove_t op, void *op_data) +H5B2__delete_node(H5B2_hdr_t *hdr, uint16_t depth, H5B2_node_ptr_t *curr_node, void *parent, H5B2_remove_t op, + void *op_data) { const H5AC_class_t *curr_node_class = NULL; /* Pointer to current node's class info */ void * node = NULL; /* Pointers to current node */ @@ -1759,8 +1758,7 @@ H5B2__delete_node(H5B2_hdr_t *hdr, uint16_t depth, const H5B2_node_ptr_t *curr_n /* Lock the current B-tree node */ if (NULL == - (internal = H5B2__protect_internal(hdr, parent, (H5B2_node_ptr_t *)curr_node, depth, FALSE, - H5AC__NO_FLAGS_SET))) /* Casting away const OK -QAK */ + (internal = H5B2__protect_internal(hdr, parent, curr_node, depth, FALSE, H5AC__NO_FLAGS_SET))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect B-tree internal node") /* Set up information about current node */ @@ -1824,7 +1822,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2__node_size(H5B2_hdr_t *hdr, uint16_t depth, const H5B2_node_ptr_t *curr_node, void *parent, +H5B2__node_size(H5B2_hdr_t *hdr, uint16_t depth, H5B2_node_ptr_t *curr_node, void *parent, hsize_t *btree_size) { H5B2_internal_t *internal = NULL; /* Pointer to internal node */ @@ -1839,8 +1837,8 @@ H5B2__node_size(H5B2_hdr_t *hdr, uint16_t depth, const H5B2_node_ptr_t *curr_nod HDassert(depth > 0); /* Lock the current B-tree node */ - if (NULL == (internal = H5B2__protect_internal(hdr, parent, (H5B2_node_ptr_t *)curr_node, depth, FALSE, - H5AC__READ_ONLY_FLAG))) /* Casting away const OK -QAK */ + if (NULL == + (internal = H5B2__protect_internal(hdr, parent, curr_node, depth, FALSE, H5AC__READ_ONLY_FLAG))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect B-tree internal node") /* Recursively descend into child nodes, if we are above the "twig" level in the B-tree */ @@ -1910,7 +1908,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5B2__update_flush_depend(H5B2_hdr_t *hdr, unsigned depth, const H5B2_node_ptr_t *node_ptr, void *old_parent, +H5B2__update_flush_depend(H5B2_hdr_t *hdr, unsigned depth, H5B2_node_ptr_t *node_ptr, void *old_parent, void *new_parent) { const H5AC_class_t *child_class; /* Pointer to child node's class info */ @@ -1941,9 +1939,8 @@ H5B2__update_flush_depend(H5B2_hdr_t *hdr, unsigned depth, const H5B2_node_ptr_t H5B2_internal_t *child_int; /* Protect child */ - if (NULL == (child_int = H5B2__protect_internal( - hdr, new_parent, (H5B2_node_ptr_t *)node_ptr, (uint16_t)(depth - 1), FALSE, - H5AC__NO_FLAGS_SET))) /* Casting away const OK -QAK */ + if (NULL == (child_int = H5B2__protect_internal(hdr, new_parent, node_ptr, (uint16_t)(depth - 1), + FALSE, H5AC__NO_FLAGS_SET))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect B-tree internal node") child_class = H5AC_BT2_INT; child = child_int; @@ -2010,7 +2007,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5B2__update_child_flush_depends(H5B2_hdr_t *hdr, unsigned depth, const H5B2_node_ptr_t *node_ptrs, +H5B2__update_child_flush_depends(H5B2_hdr_t *hdr, unsigned depth, H5B2_node_ptr_t *node_ptrs, unsigned start_idx, unsigned end_idx, void *old_parent, void *new_parent) { unsigned u; /* Local index variable */ diff --git a/src/H5B2pkg.h b/src/H5B2pkg.h index 8d620cc..66d04fa 100644 --- a/src/H5B2pkg.h +++ b/src/H5B2pkg.h @@ -321,7 +321,7 @@ extern const H5B2_class_t *const H5B2_client_class_g[H5B2_NUM_BTREE_ID]; /* Generic routines */ H5_DLL herr_t H5B2__create_flush_depend(H5AC_info_t *parent_entry, H5AC_info_t *child_entry); -H5_DLL herr_t H5B2__update_flush_depend(H5B2_hdr_t *hdr, unsigned depth, const H5B2_node_ptr_t *node_ptr, +H5_DLL herr_t H5B2__update_flush_depend(H5B2_hdr_t *hdr, unsigned depth, H5B2_node_ptr_t *node_ptr, void *old_parent, void *new_parent); H5_DLL herr_t H5B2__destroy_flush_depend(H5AC_info_t *parent_entry, H5AC_info_t *child_entry); @@ -390,9 +390,9 @@ H5_DLL herr_t H5B2__update_leaf(H5B2_hdr_t *hdr, H5B2_node_ptr_t *curr_node_ptr, void *op_data); /* Routines for iterating over nodes/records */ -H5_DLL herr_t H5B2__iterate_node(H5B2_hdr_t *hdr, uint16_t depth, const H5B2_node_ptr_t *curr_node, - void *parent, H5B2_operator_t op, void *op_data); -H5_DLL herr_t H5B2__node_size(H5B2_hdr_t *hdr, uint16_t depth, const H5B2_node_ptr_t *curr_node, void *parent, +H5_DLL herr_t H5B2__iterate_node(H5B2_hdr_t *hdr, uint16_t depth, H5B2_node_ptr_t *curr_node, void *parent, + H5B2_operator_t op, void *op_data); +H5_DLL herr_t H5B2__node_size(H5B2_hdr_t *hdr, uint16_t depth, H5B2_node_ptr_t *curr_node, void *parent, hsize_t *op_data); /* Routines for locating records */ @@ -423,8 +423,8 @@ H5_DLL herr_t H5B2__remove_leaf_by_idx(H5B2_hdr_t *hdr, H5B2_node_ptr_t *curr_no void *op_data); /* Routines for deleting nodes */ -H5_DLL herr_t H5B2__delete_node(H5B2_hdr_t *hdr, uint16_t depth, const H5B2_node_ptr_t *curr_node, - void *parent, H5B2_remove_t op, void *op_data); +H5_DLL herr_t H5B2__delete_node(H5B2_hdr_t *hdr, uint16_t depth, H5B2_node_ptr_t *curr_node, void *parent, + H5B2_remove_t op, void *op_data); /* Debugging routines for dumping file structures */ H5_DLL herr_t H5B2__hdr_debug(H5F_t *f, haddr_t addr, FILE *stream, int indent, int fwidth, diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index 71a15b0..cd54c3a 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -1403,6 +1403,19 @@ H5D__chunk_mem_xfree(void *chk, const void *_pline) } /* H5D__chunk_mem_xfree() */ /*------------------------------------------------------------------------- + * Function: H5D__chunk_mem_free + * + * Purpose: Wrapper with H5MM_free_t-compatible signature that just + * calls H5D__chunk_mem_xfree and discards the return value. + *------------------------------------------------------------------------- + */ +static void +H5D__chunk_mem_free(void *chk, const void *_pline) +{ + (void)H5D__chunk_mem_xfree(chk, _pline); +} + +/*------------------------------------------------------------------------- * Function: H5D__chunk_mem_realloc * * Purpose: Reallocate space for a chunk in memory. This routine allocates @@ -3193,11 +3206,14 @@ H5D__chunk_hash_val(const H5D_shared_t *shared, const hsize_t *scaled) herr_t H5D__chunk_lookup(const H5D_t *dset, const hsize_t *scaled, H5D_chunk_ud_t *udata) { - H5D_rdcc_ent_t * ent = NULL; /* Cache entry */ - H5O_storage_chunk_t *sc = &(dset->shared->layout.storage.u.chunk); - unsigned idx = 0; /* Index of chunk in cache, if present */ - hbool_t found = FALSE; /* In cache? */ - herr_t ret_value = SUCCEED; /* Return value */ + H5D_rdcc_ent_t * ent = NULL; /* Cache entry */ + H5O_storage_chunk_t *sc = &(dset->shared->layout.storage.u.chunk); + unsigned idx = 0; /* Index of chunk in cache, if present */ + hbool_t found = FALSE; /* In cache? */ +#ifdef H5_HAVE_PARALLEL + hbool_t reenable_coll_md_reads = FALSE; +#endif + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -3268,8 +3284,13 @@ H5D__chunk_lookup(const H5D_t *dset, const hsize_t *scaled, H5D_chunk_ud_t *udat * highly unlikely that users would read the same chunks from all * processes. */ - if (H5F_HAS_FEATURE(idx_info.f, H5FD_FEAT_HAS_MPI)) - H5CX_set_coll_metadata_read(FALSE); + if (H5F_HAS_FEATURE(idx_info.f, H5FD_FEAT_HAS_MPI)) { + hbool_t do_coll_md_reads = H5CX_get_coll_metadata_read(); + if (do_coll_md_reads) { + H5CX_set_coll_metadata_read(FALSE); + reenable_coll_md_reads = TRUE; + } + } #endif /* H5_HAVE_PARALLEL */ /* Go get the chunk information */ @@ -3312,6 +3333,12 @@ H5D__chunk_lookup(const H5D_t *dset, const hsize_t *scaled, H5D_chunk_ud_t *udat } /* end else */ done: +#ifdef H5_HAVE_PARALLEL + /* Re-enable collective metadata reads if we disabled them */ + if (reenable_coll_md_reads) + H5CX_set_coll_metadata_read(TRUE); +#endif /* H5_HAVE_PARALLEL */ + FUNC_LEAVE_NOAPI(ret_value) } /* H5D__chunk_lookup() */ @@ -4427,7 +4454,7 @@ H5D__chunk_allocate(const H5D_io_info_t *io_info, hbool_t full_overwrite, const /* (delay allocating fill buffer for VL datatypes until refilling) */ /* (casting away const OK - QAK) */ if (H5D__fill_init(&fb_info, NULL, (H5MM_allocate_t)H5D__chunk_mem_alloc, (void *)pline, - (H5MM_free_t)H5D__chunk_mem_xfree, (void *)pline, &dset->shared->dcpl_cache.fill, + (H5MM_free_t)H5D__chunk_mem_free, (void *)pline, &dset->shared->dcpl_cache.fill, dset->shared->type, dset->shared->type_id, (size_t)0, orig_chunk_size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize fill buffer info") fb_info_init = TRUE; diff --git a/src/H5ESpublic.h b/src/H5ESpublic.h index 4cf71c5..c8696b3 100644 --- a/src/H5ESpublic.h +++ b/src/H5ESpublic.h @@ -51,13 +51,13 @@ typedef enum H5ES_status_t { /* Information about operations in an event set */ typedef struct H5ES_op_info_t { /* API call info */ - char *api_name; /* Name of HDF5 API routine called */ - char *api_args; /* "Argument string" for arguments to HDF5 API routine called */ + const char *api_name; /* Name of HDF5 API routine called */ + char * api_args; /* "Argument string" for arguments to HDF5 API routine called */ /* Application info */ - char * app_file_name; /* Name of source file where the HDF5 API routine was called */ - char * app_func_name; /* Name of function where the HDF5 API routine was called */ - unsigned app_line_num; /* Line # of source file where the HDF5 API routine was called */ + const char *app_file_name; /* Name of source file where the HDF5 API routine was called */ + const char *app_func_name; /* Name of function where the HDF5 API routine was called */ + unsigned app_line_num; /* Line # of source file where the HDF5 API routine was called */ /* Operation info */ uint64_t op_ins_count; /* Counter of operation's insertion into event set */ diff --git a/src/H5HF.c b/src/H5HF.c index 1f4cc26..6c6b101 100644 --- a/src/H5HF.c +++ b/src/H5HF.c @@ -117,8 +117,14 @@ H5HF__op_write(const void *obj, size_t obj_len, void *op_data) { FUNC_ENTER_PACKAGE_NOERR - /* Perform "write", using memcpy() */ - H5MM_memcpy((void *)obj, op_data, obj_len); /* Casting away const OK -QAK */ + /* Perform "write", using memcpy() + * + * We cast away const here because no obj pointer that was originally + * const should ever arrive here. + */ + H5_GCC_CLANG_DIAG_OFF("cast-qual") + H5MM_memcpy((void *)obj, op_data, obj_len); + H5_GCC_CLANG_DIAG_ON("cast-qual") FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5HF__op_write() */ @@ -350,10 +356,15 @@ H5HF_insert(H5HF_t *fh, size_t size, const void *obj, void *id /*out*/) /* Check for 'huge' object */ if (size > hdr->max_man_size) { - /* Store 'huge' object in heap */ - /* (Casting away const OK - QAK) */ + /* Store 'huge' object in heap + * + * Although not ideal, we can quiet the const warning here becuase no + * obj pointer that was originally const should ever arrive here. + */ + H5_GCC_CLANG_DIAG_OFF("cast-qual") if (H5HF__huge_insert(hdr, size, (void *)obj, id) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "can't store 'huge' object in fractal heap") + H5_GCC_CLANG_DIAG_ON("cast-qual") } /* end if */ /* Check for 'tiny' object */ else if (size <= hdr->tiny_max_len) { diff --git a/src/H5HFcache.c b/src/H5HFcache.c index ea5e730..654fa36 100644 --- a/src/H5HFcache.c +++ b/src/H5HFcache.c @@ -1658,9 +1658,15 @@ H5HF__cache_dblock_verify_chksum(const void *_image, size_t len, void *_udata) /* Update info about direct block */ udata->decompressed = TRUE; len = nbytes; - } /* end if */ - else - read_buf = (void *)image; /* Casting away const OK - QAK */ + } + else { + /* If the data are unfiltered, we just point to the image, which we + * never modify. Casting away const is okay here. + */ + H5_GCC_CLANG_DIAG_OFF("cast-qual") + read_buf = (void *)image; + H5_GCC_CLANG_DIAG_OFF("cast-qual") + } /* Decode checksum */ chk_size = (size_t)(H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr) - H5HF_SIZEOF_CHKSUM); diff --git a/src/H5HFman.c b/src/H5HFman.c index 427be00..a362d99 100644 --- a/src/H5HFman.c +++ b/src/H5HFman.c @@ -487,10 +487,16 @@ H5HF__man_write(H5HF_hdr_t *hdr, const uint8_t *id, const void *obj) HDassert(id); HDassert(obj); - /* Call the internal 'op' routine routine */ - /* (Casting away const OK - QAK) */ + /* Call the internal 'op' routine routine + * + * In this case, the callback operation needs to modify the obj buffer that + * was passed in as const. We quiet the warning here because an obj pointer + * that was originally const should *never* arrive here. + */ + H5_GCC_CLANG_DIAG_OFF("cast-qual") if (H5HF__man_op_real(hdr, id, H5HF__op_write, (void *)obj, H5HF_OP_MODIFY) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTOPERATE, FAIL, "unable to operate on heap object") + H5_GCC_CLANG_DIAG_ON("cast-qual") done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5HGprivate.h b/src/H5HGprivate.h index d8e6b46..5deae88 100644 --- a/src/H5HGprivate.h +++ b/src/H5HGprivate.h @@ -50,7 +50,7 @@ typedef struct H5HG_heap_t H5HG_heap_t; /* Size of encoded global heap ID */ /* (size of file address + 32-bit integer) */ -#define H5HG_HEAP_ID_SIZE(F) ((size_t)H5F_SIZEOF_ADDR(F) + H5_SIZEOF_UINT32_T) +#define H5HG_HEAP_ID_SIZE(F) ((size_t)H5F_SIZEOF_ADDR(F) + sizeof(uint32_t)) /* Main global heap routines */ H5_DLL herr_t H5HG_insert(H5F_t *f, size_t size, const void *obj, H5HG_t *hobj /*out*/); diff --git a/src/H5M.c b/src/H5M.c index b890a5c..845c054 100644 --- a/src/H5M.c +++ b/src/H5M.c @@ -533,7 +533,7 @@ H5M__open_api_common(hid_t loc_id, const char *name, hid_t mapl_id, void **token /* Open the map */ if (H5VL_optional(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open map") - map = map_args.create.map; + map = map_args.open.map; /* Register an ID for the map */ if ((ret_value = H5VL_register(H5I_MAP, map, (*vol_obj_ptr)->connector, TRUE)) < 0) @@ -1360,6 +1360,7 @@ H5Miterate(hid_t map_id, hsize_t *idx, hid_t key_mem_type_id, H5M_iterate_t op, map_args.specific.args.iterate.loc_params.type = H5VL_OBJECT_BY_SELF; map_args.specific.args.iterate.loc_params.obj_type = H5I_get_type(map_id); map_args.specific.args.iterate.idx = (idx ? *idx : 0); + map_args.specific.args.iterate.key_mem_type_id = key_mem_type_id; map_args.specific.args.iterate.op = op; map_args.specific.args.iterate.op_data = op_data; vol_cb_args.op_type = H5VL_MAP_SPECIFIC; @@ -1450,6 +1451,7 @@ H5Miterate_by_name(hid_t loc_id, const char *map_name, hsize_t *idx, hid_t key_m map_args.specific.args.iterate.loc_params.loc_data.loc_by_name.name = map_name; map_args.specific.args.iterate.loc_params.loc_data.loc_by_name.lapl_id = lapl_id; map_args.specific.args.iterate.idx = (idx ? *idx : 0); + map_args.specific.args.iterate.key_mem_type_id = key_mem_type_id; map_args.specific.args.iterate.op = op; map_args.specific.args.iterate.op_data = op_data; vol_cb_args.op_type = H5VL_MAP_SPECIFIC; diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index 0c2686a..ff9ff8a 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -74,7 +74,7 @@ #define H5F_ACS_DATA_CACHE_BYTE_SIZE_DEC H5P__decode_size_t /* Definition for preemption read chunks first */ #define H5F_ACS_PREEMPT_READ_CHUNKS_SIZE sizeof(double) -#define H5F_ACS_PREEMPT_READ_CHUNKS_DEF 0.75f +#define H5F_ACS_PREEMPT_READ_CHUNKS_DEF 0.75 #define H5F_ACS_PREEMPT_READ_CHUNKS_ENC H5P__encode_double #define H5F_ACS_PREEMPT_READ_CHUNKS_DEC H5P__decode_double /* Definition for threshold for alignment */ @@ -4947,8 +4947,7 @@ H5Pset_all_coll_metadata_ops(hid_t plist_id, hbool_t is_collective) /* (Dataset, group, attribute, and named datype access property lists * are sub-classes of link access property lists -QAK) */ - if (TRUE != H5P_isa_class(plist_id, H5P_LINK_ACCESS) && - TRUE != H5P_isa_class(plist_id, H5P_FILE_ACCESS) && TRUE != H5P_isa_class(plist_id, H5P_DATASET_XFER)) + if (TRUE != H5P_isa_class(plist_id, H5P_LINK_ACCESS) && TRUE != H5P_isa_class(plist_id, H5P_FILE_ACCESS)) HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "property list is not an access plist") /* set property to either TRUE if > 0, or FALSE otherwise */ @@ -4999,8 +4998,7 @@ H5Pget_all_coll_metadata_ops(hid_t plist_id, hbool_t *is_collective /*out*/) /* (Dataset, group, attribute, and named datype access property lists * are sub-classes of link access property lists -QAK) */ - if (TRUE != H5P_isa_class(plist_id, H5P_LINK_ACCESS) && - TRUE != H5P_isa_class(plist_id, H5P_FILE_ACCESS) && TRUE != H5P_isa_class(plist_id, H5P_DATASET_XFER)) + if (TRUE != H5P_isa_class(plist_id, H5P_LINK_ACCESS) && TRUE != H5P_isa_class(plist_id, H5P_FILE_ACCESS)) HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "property list is not an access plist") /* Get value */ diff --git a/src/H5Pocpl.c b/src/H5Pocpl.c index edb0cca..e442030 100644 --- a/src/H5Pocpl.c +++ b/src/H5Pocpl.c @@ -940,6 +940,8 @@ H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t id, unsigned int *flags /*out* H5TRACE8("e", "iZfx*zxzxx", plist_id, id, flags, cd_nelmts, cd_values, namelen, name, filter_config); /* Check args */ + if (id < 0 || id > H5Z_FILTER_MAX) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "filter ID value out of range") if (cd_nelmts || cd_values) { /* * It's likely that users forget to initialize this on input, so @@ -1838,6 +1840,8 @@ H5Pget_filter_by_id1(hid_t plist_id, H5Z_filter_t id, unsigned int *flags /*out* H5TRACE7("e", "iZfx*zxzx", plist_id, id, flags, cd_nelmts, cd_values, namelen, name); /* Check args */ + if (id < 0 || id > H5Z_FILTER_MAX) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "filter ID value out of range") if (cd_nelmts || cd_values) { /* * It's likely that users forget to initialize this on input, so diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index cba7e03..ed61646 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -6402,10 +6402,10 @@ H5_DLL herr_t H5Pset_layout(hid_t plist_id, H5D_layout_t layout); * byte 0 * * - * ???????? - * ????SPPP - * PPPPPPPP - * PPPP???? + * ???????? + * ????SPPP + * PPPPPPPP + * PPPP???? * * * Note: S - sign bit, P - significant bit, ? - padding bit; For diff --git a/src/H5RS.c b/src/H5RS.c index d9915f2..65cfd38 100644 --- a/src/H5RS.c +++ b/src/H5RS.c @@ -316,8 +316,16 @@ H5RS_wrap(const char *s) if (NULL == (ret_value = H5FL_MALLOC(H5RS_str_t))) HGOTO_ERROR(H5E_RS, H5E_CANTALLOC, NULL, "memory allocation failed") - /* Set the internal fields */ - ret_value->s = (char *)s; + /* Set the internal fields + * + * We ignore warnings about storing a const char pointer in the struct + * since we never modify or free the string when the wrapped struct + * field is set to TRUE. + */ + H5_GCC_CLANG_DIAG_OFF("cast-qual") + ret_value->s = (char *)s; + H5_GCC_CLANG_DIAG_ON("cast-qual") + ret_value->len = HDstrlen(s); ret_value->end = ret_value->s + ret_value->len; diff --git a/src/H5Rint.c b/src/H5Rint.c index e1a5dcd..7ee4ecc 100644 --- a/src/H5Rint.c +++ b/src/H5Rint.c @@ -1150,7 +1150,7 @@ H5R__encode_obj_token(const H5O_token_t *obj_token, size_t token_size, unsigned /* Encode token */ H5MM_memcpy(p, obj_token, token_size); } - *nalloc = token_size + H5_SIZEOF_UINT8_T; + *nalloc = token_size + sizeof(uint8_t); FUNC_LEAVE_NOAPI(ret_value) } /* end H5R__encode_obj_token() */ @@ -1178,7 +1178,7 @@ H5R__decode_obj_token(const unsigned char *buf, size_t *nbytes, H5O_token_t *obj HDassert(token_size); /* Don't decode if buffer size isn't big enough */ - if (*nbytes < H5_SIZEOF_UINT8_T) + if (*nbytes < sizeof(uint8_t)) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small") /* Get token size */ @@ -1192,7 +1192,7 @@ H5R__decode_obj_token(const unsigned char *buf, size_t *nbytes, H5O_token_t *obj /* Decode token */ H5MM_memcpy(obj_token, p, *token_size); - *nbytes = (size_t)(*token_size + H5_SIZEOF_UINT8_T); + *nbytes = (size_t)(*token_size + sizeof(uint8_t)); done: FUNC_LEAVE_NOAPI(ret_value) @@ -1225,7 +1225,7 @@ H5R__encode_region(H5S_t *space, unsigned char *buf, size_t *nalloc) "Cannot determine amount of space needed for serializing selection") /* Don't encode if buffer size isn't big enough or buffer is empty */ - if (buf && *nalloc >= ((size_t)buf_size + 2 * H5_SIZEOF_UINT32_T)) { + if (buf && *nalloc >= ((size_t)buf_size + 2 * sizeof(uint32_t))) { int rank; p = (uint8_t *)buf; @@ -1241,7 +1241,7 @@ H5R__encode_region(H5S_t *space, unsigned char *buf, size_t *nalloc) if (H5S_SELECT_SERIALIZE(space, (unsigned char **)&p) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "can't serialize selection") } /* end if */ - *nalloc = (size_t)buf_size + 2 * H5_SIZEOF_UINT32_T; + *nalloc = (size_t)buf_size + 2 * sizeof(uint32_t); done: FUNC_LEAVE_NOAPI(ret_value) @@ -1272,16 +1272,16 @@ H5R__decode_region(const unsigned char *buf, size_t *nbytes, H5S_t **space_ptr) HDassert(space_ptr); /* Don't decode if buffer size isn't big enough */ - if (*nbytes < (2 * H5_SIZEOF_UINT32_T)) + if (*nbytes < (2 * sizeof(uint32_t))) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small") /* Decode the selection size */ UINT32DECODE(p, buf_size); - buf_size += H5_SIZEOF_UINT32_T; + buf_size += sizeof(uint32_t); /* Decode the extent rank */ UINT32DECODE(p, rank); - buf_size += H5_SIZEOF_UINT32_T; + buf_size += sizeof(uint32_t); /* Don't decode if buffer size isn't big enough */ if (*nbytes < buf_size) diff --git a/src/H5Rpkg.h b/src/H5Rpkg.h index ee5fb71..09144f9 100644 --- a/src/H5Rpkg.h +++ b/src/H5Rpkg.h @@ -43,7 +43,7 @@ #define H5R_REF_ATTRNAME(x) ((x)->info.attr.name) /* Header size */ -#define H5R_ENCODE_HEADER_SIZE (2 * H5_SIZEOF_UINT8_T) +#define H5R_ENCODE_HEADER_SIZE (2 * sizeof(uint8_t)) /****************************/ /* Package Private Typedefs */ diff --git a/src/H5SL.c b/src/H5SL.c index ba9721c..b4fbf99 100644 --- a/src/H5SL.c +++ b/src/H5SL.c @@ -36,13 +36,6 @@ * skip list. The implementation in that document hurts * performance, at least for integer keys. -NAF) * - * (Also, this implementation has a couple of home-grown - * optimizations, including setting the "update" vector to the - * actual 'forward' pointer to update, instead of the node - * containing the forward pointer -QAK - * -No longer uses update vector, as insertions/deletions are now - * always at level 0. -NAF) - * * (Note: This implementation does not have the information for * implementing the "Linear List Operations" (like insert/delete/ * search by position) in section 3.4 of "A Skip List Cookbook", @@ -71,25 +64,14 @@ /* Define the code template for searches for the "OP" in the H5SL_LOCATE macro */ #define H5SL_LOCATE_SEARCH_FOUND(SLIST, X, I) \ { \ - HDassert(!X->removed); \ - HGOTO_DONE(X->item); \ - } /* end block */ - -/* Define the code template for deferred removals for the "OP" in the - * H5SL_LOCATE macro */ -#define H5SL_LOCATE_SEARCH_DEFER_REMOVE_FOUND(SLIST, X, I) \ - { \ - HDassert(!X->removed); \ - X->removed = TRUE; \ HGOTO_DONE(X->item); \ - } /* end block */ + } /* Define the code template for finds for the "OP" in the H5SL_LOCATE macro */ #define H5SL_LOCATE_FIND_FOUND(SLIST, X, I) \ { \ - HDassert(!X->removed); \ HGOTO_DONE(X); \ - } /* end block */ + } /* Define a code template for comparing scalar keys for the "CMP" in the H5SL_LOCATE macro */ #define H5SL_LOCATE_SCALAR_CMP(SLIST, TYPE, PNODE, PKEY, HASHVAL) (*(TYPE *)((PNODE)->key) < *(TYPE *)PKEY) @@ -155,51 +137,19 @@ H5_GLUE3(H5SL_LOCATE_, CMP, _CMP)(SLIST, TYPE, X->forward[_i], KEY, HASHVAL)) { \ X = X->forward[_i]; \ _count++; \ - } /* end while */ \ - } /* end for */ \ + } \ + } \ X = X->forward[0]; \ if (X != NULL && H5_GLUE3(H5SL_LOCATE_, CMP, _EQ)(SLIST, TYPE, X, KEY, HASHVAL)) { \ /* What to do when a node is found */ \ H5_GLUE3(H5SL_LOCATE_, OP, _FOUND)(SLIST, X, _i) \ - } /* end if */ \ - } - -/* Macro used to find node for operation, if there may be "removed" nodes in the - * list (whose keys cannot be read) */ -#define H5SL_LOCATE_SAFE(OP, CMP, SLIST, X, TYPE, KEY, HASHVAL) \ - { \ - int _i; /* Local index variable */ \ - H5SL_node_t *_low = X; \ - H5SL_node_t *_high = NULL; \ - \ - H5_GLUE3(H5SL_LOCATE_, CMP, _HASHINIT) \ - (KEY, HASHVAL) for (_i = (int)SLIST->curr_level; _i >= 0; _i--) \ - { \ - X = _low->forward[_i]; \ - while (X != _high) { \ - if (!X->removed) { \ - if (H5_GLUE3(H5SL_LOCATE_, CMP, _CMP)(SLIST, TYPE, X, KEY, HASHVAL)) \ - _low = X; \ - else \ - break; \ - } /* end if */ \ - X = X->forward[_i]; \ - } /* end while */ \ - _high = X; \ - if (X != NULL && H5_GLUE3(H5SL_LOCATE_, CMP, _EQ)(SLIST, TYPE, X, KEY, HASHVAL)) { \ - /* What to do when a node is found */ \ - H5_GLUE3(H5SL_LOCATE_, OP, _FOUND)(SLIST, X, _i) break; \ - } /* end if */ \ - } /* end for */ \ + } \ } /* Macro used to find node for operation */ #define H5SL_LOCATE(OP, CMP, SLIST, X, TYPE, KEY, HASHVAL) \ { \ - if ((SLIST)->safe_iterating) \ - H5SL_LOCATE_SAFE(OP, CMP, SLIST, X, TYPE, KEY, HASHVAL) \ - else \ - H5SL_LOCATE_OPT(OP, CMP, SLIST, X, TYPE, KEY, HASHVAL) \ + H5SL_LOCATE_OPT(OP, CMP, SLIST, X, TYPE, KEY, HASHVAL) \ } /* Macro used to grow a node by 1. Does not update pointers. LVL is the current @@ -225,13 +175,13 @@ if (NULL == (H5SL_fac_g = (H5FL_fac_head_t **)H5MM_realloc( \ (void *)H5SL_fac_g, H5SL_fac_nalloc_g * sizeof(H5FL_fac_head_t *)))) \ HGOTO_ERROR(H5E_SLIST, H5E_CANTALLOC, ERR, "memory allocation failed") \ - } /* end if */ \ + } \ \ /* Create the new factory */ \ H5SL_fac_g[H5SL_fac_nused_g] = \ H5FL_fac_init((1u << H5SL_fac_nused_g) * sizeof(H5SL_node_t *)); \ H5SL_fac_nused_g++; \ - } /* end if */ \ + } \ \ /* Allocate space for new forward pointers */ \ if (NULL == (_tmp = (H5SL_node_t **)H5FL_FAC_MALLOC(H5SL_fac_g[X->log_nalloc]))) \ @@ -239,7 +189,7 @@ H5MM_memcpy((void *)_tmp, (const void *)X->forward, (LVL + 1) * sizeof(H5SL_node_t *)); \ X->forward = (H5SL_node_t **)H5FL_FAC_FREE(H5SL_fac_g[X->log_nalloc - 1], (void *)X->forward); \ X->forward = _tmp; \ - } /* end if */ \ + } \ \ X->level++; \ } @@ -260,7 +210,7 @@ H5MM_memcpy((void *)_tmp, (const void *)X->forward, (LVL) * sizeof(H5SL_node_t *)); \ X->forward = (H5SL_node_t **)H5FL_FAC_FREE(H5SL_fac_g[X->log_nalloc + 1], (void *)X->forward); \ X->forward = _tmp; \ - } /* end if */ \ + } \ \ X->level--; \ } @@ -284,7 +234,7 @@ else { \ HDassert(_lvl < (size_t)SLIST->curr_level); \ X->forward[_lvl + 1] = PREV->forward[_lvl + 1]; \ - } /* end else */ \ + } \ PREV->forward[_lvl + 1] = X; \ } @@ -322,7 +272,7 @@ if (!_drop) \ _drop = X; \ break; \ - } /* end if */ \ + } \ \ /* Check if this node is the start of the next gap */ \ if (!_drop && !H5_GLUE3(H5SL_LOCATE_, CMP, _CMP)(SLIST, TYPE, X->forward[_i], KEY, HASHVAL)) \ @@ -337,7 +287,7 @@ break; \ } \ X = X->forward[_i]; \ - } /* end for */ \ + } \ HDassert(!_drop->forward[_i] || \ !H5_GLUE3(H5SL_LOCATE_, CMP, _CMP)(SLIST, TYPE, _drop->forward[_i], KEY, HASHVAL)); \ \ @@ -350,7 +300,7 @@ /* Prepare to drop down */ \ X = _last = _drop; \ _next = _drop->forward[_i]; \ - } /* end for */ \ + } \ \ if (_next && H5_GLUE3(H5SL_LOCATE_, CMP, _EQ)(SLIST, TYPE, _next, KEY, HASHVAL)) \ HGOTO_ERROR(H5E_SLIST, H5E_CANTINSERT, NULL, "can't insert duplicate key") \ @@ -359,172 +309,167 @@ /* Macro used to remove node */ #define H5SL_REMOVE(CMP, SLIST, X, TYPE, KEY, HASHVAL) \ { \ - /* Check for deferred removal */ \ - if (SLIST->safe_iterating) \ - H5SL_LOCATE(SEARCH_DEFER_REMOVE, CMP, SLIST, X, TYPE, KEY, HASHVAL) \ - else { \ - H5SL_node_t *_last = X; /* Lowest node in the current gap */ \ - H5SL_node_t *_llast = X; /* Lowest node in the previous gap */ \ - H5SL_node_t *_next = NULL; /* Highest node in the currect gap */ \ - H5SL_node_t *_drop = NULL; /* Low node of the gap to drop into */ \ - H5SL_node_t *_ldrop = NULL; /* Low node of gap before the one to drop into */ \ - H5SL_node_t *_head = SLIST->header; /* Head of the skip list */ \ - int _count; /* Number of nodes in the current gap */ \ - int _i = (int)SLIST->curr_level; \ + H5SL_node_t *_last = X; /* Lowest node in the current gap */ \ + H5SL_node_t *_llast = X; /* Lowest node in the previous gap */ \ + H5SL_node_t *_next = NULL; /* Highest node in the currect gap */ \ + H5SL_node_t *_drop = NULL; /* Low node of the gap to drop into */ \ + H5SL_node_t *_ldrop = NULL; /* Low node of gap before the one to drop into */ \ + H5SL_node_t *_head = SLIST->header; /* Head of the skip list */ \ + int _count; /* Number of nodes in the current gap */ \ + int _i = (int)SLIST->curr_level; \ \ - if (_i < 0) \ - HGOTO_DONE(NULL); \ + if (_i < 0) \ + HGOTO_DONE(NULL); \ \ - H5_GLUE3(H5SL_LOCATE_, CMP, _HASHINIT) \ - (KEY, HASHVAL) \ + H5_GLUE3(H5SL_LOCATE_, CMP, _HASHINIT) \ + (KEY, HASHVAL) \ \ - /* Find the gap to drop in to at the highest level */ \ - while (X && (!X->key || H5_GLUE3(H5SL_LOCATE_, CMP, _CMP)(SLIST, TYPE, X, KEY, HASHVAL))) \ - { \ - _llast = _last; \ - _last = X; \ - X = X->forward[_i]; \ - } \ - _next = X; \ + /* Find the gap to drop in to at the highest level */ \ + while (X && (!X->key || H5_GLUE3(H5SL_LOCATE_, CMP, _CMP)(SLIST, TYPE, X, KEY, HASHVAL))) \ + { \ + _llast = _last; \ + _last = X; \ + X = X->forward[_i]; \ + } \ + _next = X; \ \ - /* Main loop */ \ - for (_i--; _i >= 0; _i--) { \ - /* Search for the node to drop into, also count the number of */ \ - /* nodes of height _i in this gap and keep track of of the node */ \ - /* before the one to drop into (_ldrop will become _llast, */ \ - /* _drop will become _last). */ \ - X = _ldrop = _last; \ - _drop = NULL; \ - for (_count = 0;; _count++) { \ - /* Terminate if this is the last node in the gap */ \ - if (X->forward[_i] == _next) { \ - if (!_drop) \ - _drop = X; \ - break; \ - } /* end if */ \ + /* Main loop */ \ + for (_i--; _i >= 0; _i--) { \ + /* Search for the node to drop into, also count the number of */ \ + /* nodes of height _i in this gap and keep track of of the node */ \ + /* before the one to drop into (_ldrop will become _llast, */ \ + /* _drop will become _last). */ \ + X = _ldrop = _last; \ + _drop = NULL; \ + for (_count = 0;; _count++) { \ + /* Terminate if this is the last node in the gap */ \ + if (X->forward[_i] == _next) { \ + if (!_drop) \ + _drop = X; \ + break; \ + } \ \ - /* If we have already found the node to drop into and there */ \ - /* is more than one node in this gap, we can stop searching */ \ - if (_drop) { \ - HDassert(_count >= 1); \ - _count = 2; \ - break; \ + /* If we have already found the node to drop into and there */ \ + /* is more than one node in this gap, we can stop searching */ \ + if (_drop) { \ + HDassert(_count >= 1); \ + _count = 2; \ + break; \ + } \ + else { /* !_drop */ \ + /* Check if this node is the start of the next gap */ \ + if (!H5_GLUE3(H5SL_LOCATE_, CMP, _CMP)(SLIST, TYPE, X->forward[_i], KEY, HASHVAL)) { \ + _drop = X; \ + /* Again check if we can stop searching */ \ + if (_count) { \ + _count = 2; \ + break; \ + } \ } \ - else { /* !_drop */ \ - /* Check if this node is the start of the next gap */ \ - if (!H5_GLUE3(H5SL_LOCATE_, CMP, _CMP)(SLIST, TYPE, X->forward[_i], KEY, HASHVAL)) { \ - _drop = X; \ - /* Again check if we can stop searching */ \ - if (_count) { \ - _count = 2; \ - break; \ - } /* end if */ \ - } /* end if */ \ - else \ - _ldrop = X; \ - } /* end else */ \ + else \ + _ldrop = X; \ + } \ \ - /* No need to check the last node in the gap if there are */ \ - /* 3, as there cannot be a fourth */ \ - if (_count == 2) { \ - if (!_drop) \ - _drop = X->forward[_i]; \ - break; \ - } /* end if */ \ - X = X->forward[_i]; \ - } /* end for */ \ - HDassert(_count >= 1 && _count <= 3); \ - HDassert(!_drop->forward[_i] || \ - !H5_GLUE3(H5SL_LOCATE_, CMP, _CMP)(SLIST, TYPE, _drop->forward[_i], KEY, HASHVAL)); \ + /* No need to check the last node in the gap if there are */ \ + /* 3, as there cannot be a fourth */ \ + if (_count == 2) { \ + if (!_drop) \ + _drop = X->forward[_i]; \ + break; \ + } \ + X = X->forward[_i]; \ + } \ + HDassert(_count >= 1 && _count <= 3); \ + HDassert(!_drop->forward[_i] || \ + !H5_GLUE3(H5SL_LOCATE_, CMP, _CMP)(SLIST, TYPE, _drop->forward[_i], KEY, HASHVAL)); \ \ - /* Check if we need to adjust node heights */ \ - if (_count == 1) { \ - /* Check if we are in the first gap */ \ - if (_llast == _last) { \ - /* We are in the first gap, count the number of nodes */ \ - /* of height _i in the next gap. We need only check */ \ - /* onenode to see if we should promote the first node */ \ - /* in the next gap */ \ - _llast = _next->forward[_i + 1]; \ + /* Check if we need to adjust node heights */ \ + if (_count == 1) { \ + /* Check if we are in the first gap */ \ + if (_llast == _last) { \ + /* We are in the first gap, count the number of nodes */ \ + /* of height _i in the next gap. We need only check */ \ + /* onenode to see if we should promote the first node */ \ + /* in the next gap */ \ + _llast = _next->forward[_i + 1]; \ \ - /* Demote the separator node */ \ - H5SL_DEMOTE(_next, _last) \ + /* Demote the separator node */ \ + H5SL_DEMOTE(_next, _last) \ \ - /* If there are 2 or more nodes, promote the first */ \ - if (_next->forward[_i]->forward[_i] != _llast) { \ - X = _next->forward[_i]; \ - H5SL_PROMOTE(SLIST, X, _last, NULL) \ - } \ - else if (!_head->forward[_i + 1]) { \ - /* shrink the header */ \ - HDassert(_i == SLIST->curr_level - 1); \ - HDassert((size_t)SLIST->curr_level == _head->level); \ + /* If there are 2 or more nodes, promote the first */ \ + if (_next->forward[_i]->forward[_i] != _llast) { \ + X = _next->forward[_i]; \ + H5SL_PROMOTE(SLIST, X, _last, NULL) \ + } \ + else if (!_head->forward[_i + 1]) { \ + /* shrink the header */ \ + HDassert(_i == SLIST->curr_level - 1); \ + HDassert((size_t)SLIST->curr_level == _head->level); \ \ - H5SL_SHRINK(_head, (size_t)(_i + 1)) \ - SLIST->curr_level--; \ - } /* end else */ \ + H5SL_SHRINK(_head, (size_t)(_i + 1)) \ + SLIST->curr_level--; \ } \ - else { \ - /* We are not in the first gap, count the number of */ \ - /* nodes of height _i in the previous gap. Note we */ \ - /* "look ahead" in this loop so X has the value of the */ \ - /* last node in the previous gap. */ \ - X = _llast->forward[_i]; \ - for (_count = 1; _count < 3 && X->forward[_i] != _last; _count++) \ - X = X->forward[_i]; \ - HDassert(X->forward[_i] == _last); \ + } \ + else { \ + /* We are not in the first gap, count the number of */ \ + /* nodes of height _i in the previous gap. Note we */ \ + /* "look ahead" in this loop so X has the value of the */ \ + /* last node in the previous gap. */ \ + X = _llast->forward[_i]; \ + for (_count = 1; _count < 3 && X->forward[_i] != _last; _count++) \ + X = X->forward[_i]; \ + HDassert(X->forward[_i] == _last); \ \ - /* Demote the separator node */ \ - H5SL_DEMOTE(_last, _llast) \ + /* Demote the separator node */ \ + H5SL_DEMOTE(_last, _llast) \ \ - /* If there are 2 or more nodes, promote the last */ \ - if (_count >= 2) \ - H5SL_PROMOTE(SLIST, X, _llast, NULL) \ - else if (!_head->forward[_i + 1]) { \ - /* shrink the header */ \ - HDassert(_i == SLIST->curr_level - 1); \ - HDassert((size_t)SLIST->curr_level == _head->level); \ + /* If there are 2 or more nodes, promote the last */ \ + if (_count >= 2) \ + H5SL_PROMOTE(SLIST, X, _llast, NULL) \ + else if (!_head->forward[_i + 1]) { \ + /* shrink the header */ \ + HDassert(_i == SLIST->curr_level - 1); \ + HDassert((size_t)SLIST->curr_level == _head->level); \ \ - H5SL_SHRINK(_head, (size_t)(_i + 1)) \ - SLIST->curr_level--; \ - } /* end else */ \ - } /* end else */ \ - } /* end if */ \ + H5SL_SHRINK(_head, (size_t)(_i + 1)) \ + SLIST->curr_level--; \ + } \ + } \ + } \ \ - /* Prepare to drop down */ \ - _llast = _ldrop; \ - _last = _drop; \ - _next = _drop->forward[_i]; \ - } /* end for */ \ + /* Prepare to drop down */ \ + _llast = _ldrop; \ + _last = _drop; \ + _next = _drop->forward[_i]; \ + } \ \ - /* Check if we've found the node */ \ - if (_next && H5_GLUE3(H5SL_LOCATE_, CMP, _EQ)(SLIST, TYPE, _next, KEY, HASHVAL)) { \ - void *tmp = _next->item; \ - X = _next; \ + /* Check if we've found the node */ \ + if (_next && H5_GLUE3(H5SL_LOCATE_, CMP, _EQ)(SLIST, TYPE, _next, KEY, HASHVAL)) { \ + void *tmp = _next->item; \ + X = _next; \ \ - /* If the node has a height > 0, swap it with its (lower) */ \ - /* neighbor */ \ - if (X->level) { \ - X = X->backward; \ - _next->key = X->key; \ - _next->item = X->item; \ - _next->hashval = X->hashval; \ - } /* end if */ \ - HDassert(!X->level); \ + /* If the node has a height > 0, swap it with its (lower) */ \ + /* neighbor */ \ + if (X->level) { \ + X = X->backward; \ + _next->key = X->key; \ + _next->item = X->item; \ + _next->hashval = X->hashval; \ + } \ + HDassert(!X->level); \ \ - /* Remove the node */ \ - X->backward->forward[0] = X->forward[0]; \ - if (SLIST->last == X) \ - SLIST->last = X->backward; \ - else \ - X->forward[0]->backward = X->backward; \ - SLIST->nobjs--; \ - X->forward = (H5SL_node_t **)H5FL_FAC_FREE(H5SL_fac_g[0], X->forward); \ - X = H5FL_FREE(H5SL_node_t, X); \ + /* Remove the node */ \ + X->backward->forward[0] = X->forward[0]; \ + if (SLIST->last == X) \ + SLIST->last = X->backward; \ + else \ + X->forward[0]->backward = X->backward; \ + SLIST->nobjs--; \ + X->forward = (H5SL_node_t **)H5FL_FAC_FREE(H5SL_fac_g[0], X->forward); \ + X = H5FL_FREE(H5SL_node_t, X); \ \ - HGOTO_DONE(tmp); \ - } /* end if */ \ - } /* end else */ \ + HGOTO_DONE(tmp); \ + } \ } /* Macro used to search for node */ @@ -542,7 +487,6 @@ struct H5SL_node_t { size_t level; /* The level of this node */ size_t log_nalloc; /* log2(Number of slots allocated in forward) */ uint32_t hashval; /* Hash value for key (only for strings, currently) */ - hbool_t removed; /* Whether the node is "removed" (actual removal deferred) */ struct H5SL_node_t **forward; /* Array of forward pointers from this node */ struct H5SL_node_t * backward; /* Backward pointer from this node */ }; @@ -558,8 +502,6 @@ struct H5SL_t { size_t nobjs; /* Number of active objects in skip list */ H5SL_node_t *header; /* Header for nodes in skip list */ H5SL_node_t *last; /* Pointer to last node in skip list */ - hbool_t safe_iterating; /* Whether a routine is "safely" iterating over the list and removals should be - deferred */ }; /* Static functions */ @@ -651,11 +593,11 @@ H5SL_term_package(void) for (i = 0; i < H5SL_fac_nused_g; i++) { ret = H5FL_fac_term(H5SL_fac_g[i]); HDassert(ret >= 0); - } /* end if */ + } H5SL_fac_nused_g = 0; n++; - } /* end if */ + } /* Free the list of factories */ if (H5SL_fac_g) { @@ -663,12 +605,12 @@ H5SL_term_package(void) H5SL_fac_nalloc_g = 0; n++; - } /* end if */ + } /* Mark the interface as uninitialized */ if (0 == n) H5_PKG_INIT_VAR = FALSE; - } /* end if */ + } FUNC_LEAVE_NOAPI(n) } /* H5SL_term_package() */ @@ -711,11 +653,10 @@ H5SL__new_node(void *item, const void *key, uint32_t hashval) ret_value->item = item; ret_value->level = 0; ret_value->hashval = hashval; - ret_value->removed = FALSE; if (NULL == (ret_value->forward = (H5SL_node_t **)H5FL_FAC_MALLOC(H5SL_fac_g[0]))) { ret_value = H5FL_FREE(H5SL_node_t, ret_value); HGOTO_ERROR(H5E_SLIST, H5E_NOSPACE, NULL, "memory allocation failed") - } /* end if */ + } ret_value->log_nalloc = 0; done: @@ -805,7 +746,7 @@ H5SL__insert_common(H5SL_t *slist, void *item, const void *key) default: HDassert(0 && "Unknown skiplist type!"); - } /* end switch */ + } /* 'key' must not have been found in existing list, if we get here */ @@ -880,15 +821,22 @@ H5SL__release_common(H5SL_t *slist, H5SL_operator_t op, void *op_data) while (node) { next_node = node->forward[0]; - /* Call callback, if one is given */ + /* Call callback, if one is given. + * + * Ignoring const here is fine as we only need the value to be const + * with respect to the list code, which should never modify the + * elements. The library code that is making use of the skip list + * container can do what it likes with the elements. + */ + H5_GCC_CLANG_DIAG_OFF("cast-qual") if (op) - /* Casting away const OK -QAK */ (void)(op)(node->item, (void *)node->key, op_data); + H5_GCC_CLANG_DIAG_ON("cast-qual") node->forward = (H5SL_node_t **)H5FL_FAC_FREE(H5SL_fac_g[node->log_nalloc], node->forward); node = H5FL_FREE(H5SL_node_t, node); node = next_node; - } /* end while */ + } /* Reset the header pointers */ slist->header->forward = @@ -1001,9 +949,8 @@ H5SL_create(H5SL_type_t type, H5SL_cmp_t cmp) new_slist->cmp = cmp; /* Set the dynamic internal fields */ - new_slist->curr_level = -1; - new_slist->nobjs = 0; - new_slist->safe_iterating = FALSE; + new_slist->curr_level = -1; + new_slist->nobjs = 0; /* Allocate the header node */ if (NULL == (header = H5SL__new_node(NULL, NULL, (uint32_t)ULONG_MAX))) @@ -1027,7 +974,7 @@ done: if (ret_value == NULL) { if (new_slist != NULL) new_slist = H5FL_FREE(H5SL_t, new_slist); - } /* end if */ + } FUNC_LEAVE_NOAPI(ret_value) } /* end H5SL_create() */ @@ -1058,9 +1005,6 @@ H5SL_count(H5SL_t *slist) /* Check args */ HDassert(slist); - /* Not currently supported */ - HDassert(!slist->safe_iterating); - /* Check internal consistency */ /* (Pre-condition) */ @@ -1099,9 +1043,6 @@ H5SL_insert(H5SL_t *slist, void *item, const void *key) HDassert(slist); HDassert(key); - /* Not currently supported */ - HDassert(!slist->safe_iterating); - /* Check internal consistency */ /* (Pre-condition) */ @@ -1148,9 +1089,6 @@ H5SL_add(H5SL_t *slist, void *item, const void *key) HDassert(slist); HDassert(key); - /* Not currently supported */ - HDassert(!slist->safe_iterating); - /* Check internal consistency */ /* (Pre-condition) */ @@ -1242,7 +1180,7 @@ H5SL_remove(H5SL_t *slist, const void *key) default: HDassert(0 && "Unknown skiplist type!"); - } /* end switch */ + } done: FUNC_LEAVE_NOAPI(ret_value) @@ -1281,9 +1219,6 @@ H5SL_remove_first(H5SL_t *slist) /* Check args */ HDassert(slist); - /* Not currently supported */ - HDassert(!slist->safe_iterating); - /* Assign level */ H5_CHECK_OVERFLOW(slist->curr_level, int, size_t); level = (size_t)slist->curr_level; @@ -1345,12 +1280,12 @@ H5SL_remove_first(H5SL_t *slist) H5SL_SHRINK(head, level) slist->curr_level--; - } /* end else */ + } } else break; - } /* end for */ - } /* end if */ + } + } done: FUNC_LEAVE_NOAPI(ret_value) @@ -1436,7 +1371,7 @@ H5SL_search(H5SL_t *slist, const void *key) default: HDassert(0 && "Unknown skiplist type!"); - } /* end switch */ + } /* 'key' must not have been found in list, if we get here */ ret_value = NULL; @@ -1480,9 +1415,6 @@ H5SL_less(H5SL_t *slist, const void *key) HDassert(slist); HDassert(key); - /* Not currently supported */ - HDassert(!slist->safe_iterating); - /* Check internal consistency */ /* (Pre-condition) */ @@ -1531,7 +1463,7 @@ H5SL_less(H5SL_t *slist, const void *key) default: HDassert(0 && "Unknown skiplist type!"); - } /* end switch */ + } /* An exact match for 'key' must not have been found in list, if we get here */ /* Check for a node with a key that is less than the given 'key' */ @@ -1541,13 +1473,13 @@ H5SL_less(H5SL_t *slist, const void *key) ret_value = slist->last->item; else ret_value = NULL; - } /* end if */ + } else { if (x->backward != slist->header) ret_value = x->backward->item; else ret_value = NULL; - } /* end else */ + } done: FUNC_LEAVE_NOAPI(ret_value) @@ -1588,9 +1520,6 @@ H5SL_greater(H5SL_t *slist, const void *key) HDassert(slist); HDassert(key); - /* Not currently supported */ - HDassert(!slist->safe_iterating); - /* Check internal consistency */ /* (Pre-condition) */ @@ -1639,7 +1568,7 @@ H5SL_greater(H5SL_t *slist, const void *key) default: HDassert(0 && "Unknown skiplist type!"); - } /* end switch */ + } /* An exact match for 'key' must not have been found in list, if we get here */ /* ('x' must be the next node with a key greater than the 'key', or NULL) */ @@ -1734,7 +1663,7 @@ H5SL_find(H5SL_t *slist, const void *key) default: HDassert(0 && "Unknown skiplist type!"); - } /* end switch */ + } /* 'key' must not have been found in list, if we get here */ ret_value = NULL; @@ -1826,7 +1755,7 @@ H5SL_below(H5SL_t *slist, const void *key) default: HDassert(0 && "Unknown skiplist type!"); - } /* end switch */ + } /* An exact match for 'key' must not have been found in list, if we get here */ /* Check for a node with a key that is less than the given 'key' */ @@ -1836,13 +1765,13 @@ H5SL_below(H5SL_t *slist, const void *key) ret_value = slist->last; else ret_value = NULL; - } /* end if */ + } else { if (x->backward != slist->header) ret_value = x->backward; else ret_value = NULL; - } /* end else */ + } done: FUNC_LEAVE_NOAPI(ret_value) @@ -1931,7 +1860,7 @@ H5SL_above(H5SL_t *slist, const void *key) default: HDassert(0 && "Unknown skiplist type!"); - } /* end switch */ + } /* An exact match for 'key' must not have been found in list, if we get here */ /* ('x' must be the next node with a key greater than the 'key', or NULL) */ @@ -1971,9 +1900,6 @@ H5SL_first(H5SL_t *slist) /* Check args */ HDassert(slist); - /* Not currently supported */ - HDassert(!slist->safe_iterating); - /* Check internal consistency */ /* (Pre-condition) */ @@ -2007,9 +1933,6 @@ H5SL_next(H5SL_node_t *slist_node) /* Check args */ HDassert(slist_node); - /* Not currently supported */ - HDassert(!slist_node->removed); - /* Check internal consistency */ /* (Pre-condition) */ @@ -2043,9 +1966,6 @@ H5SL_prev(H5SL_node_t *slist_node) /* Check args */ HDassert(slist_node); - /* Not currently supported */ - HDassert(!slist_node->removed); - /* Check internal consistency */ /* (Pre-condition) */ @@ -2080,9 +2000,6 @@ H5SL_last(H5SL_t *slist) /* Check args */ HDassert(slist); - /* Not currently supported */ - HDassert(!slist->safe_iterating); - /* Check internal consistency */ /* (Pre-condition) */ @@ -2116,9 +2033,6 @@ H5SL_item(H5SL_node_t *slist_node) /* Check args */ HDassert(slist_node); - /* Not currently supported */ - HDassert(!slist_node->removed); - /* Check internal consistency */ /* (Pre-condition) */ @@ -2179,15 +2093,21 @@ H5SL_iterate(H5SL_t *slist, H5SL_operator_t op, void *op_data) /* Protect against the node being deleted by the callback */ next = node->forward[0]; - /* Call the iterator callback */ - /* Casting away const OK -QAK */ - if (!node->removed) - if ((ret_value = (op)(node->item, (void *)node->key, op_data)) != 0) - break; + /* Call the iterator callback + * + * Ignoring const here is fine as we only need the value to be const + * with respect to the list code, which should never modify the + * elements. The library code that is making use of the skip list + * container can do what it likes with the elements. + */ + H5_GCC_CLANG_DIAG_OFF("cast-qual") + if ((ret_value = (op)(node->item, (void *)node->key, op_data)) != 0) + break; + H5_GCC_CLANG_DIAG_ON("cast-qual") /* Advance to next node */ node = next; - } /* end while */ + } FUNC_LEAVE_NOAPI(ret_value) } /* end H5SL_iterate() */ @@ -2222,9 +2142,6 @@ H5SL_release(H5SL_t *slist) /* Check args */ HDassert(slist); - /* Not currently supported */ - HDassert(!slist->safe_iterating); - /* Check internal consistency */ /* (Pre-condition) */ @@ -2274,9 +2191,6 @@ H5SL_free(H5SL_t *slist, H5SL_operator_t op, void *op_data) /* Check args */ HDassert(slist); - /* Not currently supported */ - HDassert(!slist->safe_iterating); - /* Check internal consistency */ /* (Pre-condition) */ @@ -2290,186 +2204,6 @@ done: /*-------------------------------------------------------------------------- NAME - H5SL_try_free_safe - PURPOSE - Makes the supplied callback on all nodes in the skip list, freeing each - node that the callback returns TRUE for. - USAGE - herr_t PURPOSE(slist,op,opdata) - H5SL_t *slist; IN/OUT: Pointer to skip list to release nodes - H5SL_try_free_op_t op; IN: Callback function to try to free item & key - void *op_data; IN/OUT: Pointer to application data for callback - - RETURNS - Returns non-negative on success, negative on failure. - DESCRIPTION - Makes the supplied callback on all nodes in the skip list, freeing each - node that the callback returns TRUE for. The iteration is performed in - a safe manner, such that the callback can call H5SL_remove(), - H5SL_search(), H5SL_find(), and H5SL_iterate() on nodes in this - skiplist, except H5SL_remove() may not be call on *this* node. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - This function is written to be most efficient when most nodes are - removed from the skiplist, as it rebuilds the nodes afterwards. - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -herr_t -H5SL_try_free_safe(H5SL_t *slist, H5SL_try_free_op_t op, void *op_data) -{ - H5SL_node_t *node, *next_node, *last_node; /* Pointers to skip list nodes */ - htri_t op_ret; - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI_NOINIT - - /* Check args */ - HDassert(slist); - HDassert(op); - - /* Not currently supported */ - HDassert(!slist->safe_iterating); - - /* Check internal consistency */ - /* (Pre-condition) */ - - /* Mark skip list as safe iterating, so nodes aren't freed out from under - * us */ - slist->safe_iterating = TRUE; - - /* Iterate over skip list nodes, making the callback for each and marking - * them as removed if requested by the callback */ - node = slist->header->forward[0]; - while (node) { - /* Check if the node was already removed */ - if (!node->removed) { - /* Call callback */ - /* Casting away const OK -NAF */ - if ((op_ret = (op)(node->item, (void *)node->key, op_data)) < 0) - HGOTO_ERROR(H5E_SLIST, H5E_CALLBACK, FAIL, "callback operation failed") - - /* Check if op indicated that the node should be removed */ - if (op_ret) - /* Mark the node as removed */ - node->removed = TRUE; - } /* end if */ - - /* Advance node */ - node = node->forward[0]; - } /* end while */ - - /* Reset safe_iterating */ - slist->safe_iterating = FALSE; - - /* Iterate over nodes, freeing ones marked as removed */ - node = slist->header->forward[0]; - last_node = slist->header; - while (node) { - /* Save next node */ - next_node = node->forward[0]; - - /* Check if the node was marked as removed */ - if (node->removed) { - /* Remove the node */ - node->forward = (H5SL_node_t **)H5FL_FAC_FREE(H5SL_fac_g[node->log_nalloc], node->forward); - node = H5FL_FREE(H5SL_node_t, node); - slist->nobjs--; - } /* end if */ - else { - /* Update backwards and forwards[0] pointers, and set the level to - * 0. Since the list is flattened we must rebuild the skiplist - * afterwards. */ - /* Set level to 0. Note there is no need to preserve - * node->forward[0] since it was cached above and will always be - * updated later. */ - if (node->level > 0) { - node->forward = - (H5SL_node_t **)H5FL_FAC_FREE(H5SL_fac_g[node->log_nalloc], (void *)node->forward); - if (NULL == (node->forward = (H5SL_node_t **)H5FL_FAC_MALLOC(H5SL_fac_g[0]))) - HGOTO_ERROR(H5E_SLIST, H5E_CANTALLOC, FAIL, "memory allocation failed") - node->log_nalloc = 0; - node->level = 0; - } /* end if */ - - /* Update pointers */ - last_node->forward[0] = node; - node->backward = last_node; - last_node = node; - } /* end else */ - - /* Advance node */ - node = next_node; - } /* end while */ - - /* Final pointer update */ - last_node->forward[0] = NULL; - slist->last = last_node; - - /* Demote skip list to level 0 */ - if (slist->curr_level > 0) { - HDassert(slist->header->level == (size_t)slist->curr_level); - - node = slist->header->forward[0]; - slist->header->forward = (H5SL_node_t **)H5FL_FAC_FREE(H5SL_fac_g[slist->header->log_nalloc], - (void *)slist->header->forward); - if (NULL == (slist->header->forward = (H5SL_node_t **)H5FL_FAC_MALLOC(H5SL_fac_g[0]))) - HGOTO_ERROR(H5E_SLIST, H5E_CANTALLOC, FAIL, "memory allocation failed") - slist->header->forward[0] = node; - slist->header->log_nalloc = 0; - slist->header->level = 0; - } /* end if */ - - /* Check if there are any nodes left */ - if (slist->nobjs > 0) { - int i; - - HDassert(slist->header->forward[0]); - - /* Set skiplist level to 0 */ - slist->curr_level = 0; - - /* Rebuild the forward arrays */ - for (i = 0; slist->curr_level >= i; i++) { - HDassert(slist->curr_level == i); - - /* Promote every third node this level until we run out of nodes */ - node = last_node = slist->header; - while (1) { - /* Check second node in gap, if not present, no need to promote - * further this level. */ - HDassert(node->forward[i]); - node = node->forward[i]->forward[i]; - if (!node) - break; - - /* Check third and fourth node in gap, if either is not present, - * no need to promote further this level. */ - node = node->forward[i]; - if (!node || !node->forward[i]) - break; - - /* Promote the third node in the gap */ - H5SL_PROMOTE(slist, node, last_node, FAIL) - last_node = node; - } /* end while */ - } /* end for */ - } /* end if */ - else { - HDassert(!slist->header->forward[0]); - HDassert(slist->last == slist->header); - HDassert(slist->nobjs == 0); - - /* Reset the skiplist level */ - slist->curr_level = -1; - } /* end else */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5SL_try_free_safe() */ - -/*-------------------------------------------------------------------------- - NAME H5SL_destroy PURPOSE Close a skip list, deallocating it and freeing all its nodes. diff --git a/src/H5SLprivate.h b/src/H5SLprivate.h index c9e1147..be6f7b6 100644 --- a/src/H5SLprivate.h +++ b/src/H5SLprivate.h @@ -60,9 +60,6 @@ typedef int (*H5SL_cmp_t)(const void *key1, const void *key2); /* Typedef for iteration operations */ typedef herr_t (*H5SL_operator_t)(void *item, void *key, void *operator_data /*in,out*/); -/* Typedef for H5SL_try_free_safe operation callback */ -typedef htri_t (*H5SL_try_free_op_t)(void *item, void *key, void *operator_data /*in,out*/); - /********************/ /* Private routines */ /********************/ @@ -86,7 +83,6 @@ H5_DLL void * H5SL_item(H5SL_node_t *slist_node); H5_DLL herr_t H5SL_iterate(H5SL_t *slist, H5SL_operator_t op, void *op_data); H5_DLL herr_t H5SL_release(H5SL_t *slist); H5_DLL herr_t H5SL_free(H5SL_t *slist, H5SL_operator_t op, void *op_data); -H5_DLL herr_t H5SL_try_free_safe(H5SL_t *slist, H5SL_try_free_op_t op, void *op_data); H5_DLL herr_t H5SL_close(H5SL_t *slist); H5_DLL herr_t H5SL_destroy(H5SL_t *slist, H5SL_operator_t op, void *op_data); H5_DLL int H5SL_term_interface(void); diff --git a/src/H5T.c b/src/H5T.c index 19a3d39..461e6b9 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -423,31 +423,29 @@ hid_t H5T_C_S1_g = FAIL; hid_t H5T_FORTRAN_S1_g = FAIL; -hid_t H5T_NATIVE_SCHAR_g = FAIL; -hid_t H5T_NATIVE_UCHAR_g = FAIL; -hid_t H5T_NATIVE_SHORT_g = FAIL; -hid_t H5T_NATIVE_USHORT_g = FAIL; -hid_t H5T_NATIVE_INT_g = FAIL; -hid_t H5T_NATIVE_UINT_g = FAIL; -hid_t H5T_NATIVE_LONG_g = FAIL; -hid_t H5T_NATIVE_ULONG_g = FAIL; -hid_t H5T_NATIVE_LLONG_g = FAIL; -hid_t H5T_NATIVE_ULLONG_g = FAIL; -hid_t H5T_NATIVE_FLOAT_g = FAIL; -hid_t H5T_NATIVE_DOUBLE_g = FAIL; -#if H5_SIZEOF_LONG_DOUBLE != 0 +hid_t H5T_NATIVE_SCHAR_g = FAIL; +hid_t H5T_NATIVE_UCHAR_g = FAIL; +hid_t H5T_NATIVE_SHORT_g = FAIL; +hid_t H5T_NATIVE_USHORT_g = FAIL; +hid_t H5T_NATIVE_INT_g = FAIL; +hid_t H5T_NATIVE_UINT_g = FAIL; +hid_t H5T_NATIVE_LONG_g = FAIL; +hid_t H5T_NATIVE_ULONG_g = FAIL; +hid_t H5T_NATIVE_LLONG_g = FAIL; +hid_t H5T_NATIVE_ULLONG_g = FAIL; +hid_t H5T_NATIVE_FLOAT_g = FAIL; +hid_t H5T_NATIVE_DOUBLE_g = FAIL; hid_t H5T_NATIVE_LDOUBLE_g = FAIL; -#endif -hid_t H5T_NATIVE_B8_g = FAIL; -hid_t H5T_NATIVE_B16_g = FAIL; -hid_t H5T_NATIVE_B32_g = FAIL; -hid_t H5T_NATIVE_B64_g = FAIL; -hid_t H5T_NATIVE_OPAQUE_g = FAIL; -hid_t H5T_NATIVE_HADDR_g = FAIL; -hid_t H5T_NATIVE_HSIZE_g = FAIL; -hid_t H5T_NATIVE_HSSIZE_g = FAIL; -hid_t H5T_NATIVE_HERR_g = FAIL; -hid_t H5T_NATIVE_HBOOL_g = FAIL; +hid_t H5T_NATIVE_B8_g = FAIL; +hid_t H5T_NATIVE_B16_g = FAIL; +hid_t H5T_NATIVE_B32_g = FAIL; +hid_t H5T_NATIVE_B64_g = FAIL; +hid_t H5T_NATIVE_OPAQUE_g = FAIL; +hid_t H5T_NATIVE_HADDR_g = FAIL; +hid_t H5T_NATIVE_HSIZE_g = FAIL; +hid_t H5T_NATIVE_HSSIZE_g = FAIL; +hid_t H5T_NATIVE_HERR_g = FAIL; +hid_t H5T_NATIVE_HBOOL_g = FAIL; hid_t H5T_NATIVE_INT8_g = FAIL; hid_t H5T_NATIVE_UINT8_g = FAIL; @@ -483,21 +481,19 @@ hid_t H5T_NATIVE_UINT_FAST64_g = FAIL; * datatype or C structures, which are different from the alignments for memory * address below this group of variables. */ -size_t H5T_NATIVE_SCHAR_COMP_ALIGN_g = 0; -size_t H5T_NATIVE_UCHAR_COMP_ALIGN_g = 0; -size_t H5T_NATIVE_SHORT_COMP_ALIGN_g = 0; -size_t H5T_NATIVE_USHORT_COMP_ALIGN_g = 0; -size_t H5T_NATIVE_INT_COMP_ALIGN_g = 0; -size_t H5T_NATIVE_UINT_COMP_ALIGN_g = 0; -size_t H5T_NATIVE_LONG_COMP_ALIGN_g = 0; -size_t H5T_NATIVE_ULONG_COMP_ALIGN_g = 0; -size_t H5T_NATIVE_LLONG_COMP_ALIGN_g = 0; -size_t H5T_NATIVE_ULLONG_COMP_ALIGN_g = 0; -size_t H5T_NATIVE_FLOAT_COMP_ALIGN_g = 0; -size_t H5T_NATIVE_DOUBLE_COMP_ALIGN_g = 0; -#if H5_SIZEOF_LONG_DOUBLE != 0 +size_t H5T_NATIVE_SCHAR_COMP_ALIGN_g = 0; +size_t H5T_NATIVE_UCHAR_COMP_ALIGN_g = 0; +size_t H5T_NATIVE_SHORT_COMP_ALIGN_g = 0; +size_t H5T_NATIVE_USHORT_COMP_ALIGN_g = 0; +size_t H5T_NATIVE_INT_COMP_ALIGN_g = 0; +size_t H5T_NATIVE_UINT_COMP_ALIGN_g = 0; +size_t H5T_NATIVE_LONG_COMP_ALIGN_g = 0; +size_t H5T_NATIVE_ULONG_COMP_ALIGN_g = 0; +size_t H5T_NATIVE_LLONG_COMP_ALIGN_g = 0; +size_t H5T_NATIVE_ULLONG_COMP_ALIGN_g = 0; +size_t H5T_NATIVE_FLOAT_COMP_ALIGN_g = 0; +size_t H5T_NATIVE_DOUBLE_COMP_ALIGN_g = 0; size_t H5T_NATIVE_LDOUBLE_COMP_ALIGN_g = 0; -#endif size_t H5T_POINTER_COMP_ALIGN_g = 0; size_t H5T_HVL_COMP_ALIGN_g = 0; @@ -509,21 +505,19 @@ size_t H5T_REF_COMP_ALIGN_g = 0; * Alignment constraints for native types. These are initialized at run time * in H5Tinit.c */ -size_t H5T_NATIVE_SCHAR_ALIGN_g = 0; -size_t H5T_NATIVE_UCHAR_ALIGN_g = 0; -size_t H5T_NATIVE_SHORT_ALIGN_g = 0; -size_t H5T_NATIVE_USHORT_ALIGN_g = 0; -size_t H5T_NATIVE_INT_ALIGN_g = 0; -size_t H5T_NATIVE_UINT_ALIGN_g = 0; -size_t H5T_NATIVE_LONG_ALIGN_g = 0; -size_t H5T_NATIVE_ULONG_ALIGN_g = 0; -size_t H5T_NATIVE_LLONG_ALIGN_g = 0; -size_t H5T_NATIVE_ULLONG_ALIGN_g = 0; -size_t H5T_NATIVE_FLOAT_ALIGN_g = 0; -size_t H5T_NATIVE_DOUBLE_ALIGN_g = 0; -#if H5_SIZEOF_LONG_DOUBLE != 0 +size_t H5T_NATIVE_SCHAR_ALIGN_g = 0; +size_t H5T_NATIVE_UCHAR_ALIGN_g = 0; +size_t H5T_NATIVE_SHORT_ALIGN_g = 0; +size_t H5T_NATIVE_USHORT_ALIGN_g = 0; +size_t H5T_NATIVE_INT_ALIGN_g = 0; +size_t H5T_NATIVE_UINT_ALIGN_g = 0; +size_t H5T_NATIVE_LONG_ALIGN_g = 0; +size_t H5T_NATIVE_ULONG_ALIGN_g = 0; +size_t H5T_NATIVE_LLONG_ALIGN_g = 0; +size_t H5T_NATIVE_ULLONG_ALIGN_g = 0; +size_t H5T_NATIVE_FLOAT_ALIGN_g = 0; +size_t H5T_NATIVE_DOUBLE_ALIGN_g = 0; size_t H5T_NATIVE_LDOUBLE_ALIGN_g = 0; -#endif /* * Alignment constraints for C9x types. These are initialized at run time in @@ -760,42 +754,40 @@ DESCRIPTION herr_t H5T__init_package(void) { - H5T_t *native_schar = NULL; /* Datatype structure for native signed char */ - H5T_t *native_uchar = NULL; /* Datatype structure for native unsigned char */ - H5T_t *native_short = NULL; /* Datatype structure for native short */ - H5T_t *native_ushort = NULL; /* Datatype structure for native unsigned short */ - H5T_t *native_int = NULL; /* Datatype structure for native int */ - H5T_t *native_uint = NULL; /* Datatype structure for native unsigned int */ - H5T_t *native_long = NULL; /* Datatype structure for native long */ - H5T_t *native_ulong = NULL; /* Datatype structure for native unsigned long */ - H5T_t *native_llong = NULL; /* Datatype structure for native long long */ - H5T_t *native_ullong = NULL; /* Datatype structure for native unsigned long long */ - H5T_t *native_float = NULL; /* Datatype structure for native float */ - H5T_t *native_double = NULL; /* Datatype structure for native double */ -#if H5_SIZEOF_LONG_DOUBLE != 0 - H5T_t *native_ldouble = NULL; /* Datatype structure for native long double */ -#endif - H5T_t * std_u8le = NULL; /* Datatype structure for unsigned 8-bit little-endian integer */ - H5T_t * std_u8be = NULL; /* Datatype structure for unsigned 8-bit big-endian integer */ - H5T_t * std_u16le = NULL; /* Datatype structure for unsigned 16-bit little-endian integer */ - H5T_t * std_u16be = NULL; /* Datatype structure for unsigned 16-bit big-endian integer */ - H5T_t * std_u32le = NULL; /* Datatype structure for unsigned 32-bit little-endian integer */ - H5T_t * std_u32be = NULL; /* Datatype structure for unsigned 32-bit big-endian integer */ - H5T_t * std_u64le = NULL; /* Datatype structure for unsigned 64-bit little-endian integer */ - H5T_t * std_u64be = NULL; /* Datatype structure for unsigned 64-bit big-endian integer */ - H5T_t * dt = NULL; - H5T_t * fixedpt = NULL; /* Datatype structure for native int */ - H5T_t * floatpt = NULL; /* Datatype structure for native float */ - H5T_t * string = NULL; /* Datatype structure for C string */ - H5T_t * bitfield = NULL; /* Datatype structure for bitfield */ - H5T_t * compound = NULL; /* Datatype structure for compound objects */ - H5T_t * enum_type = NULL; /* Datatype structure for enum objects */ - H5T_t * vlen = NULL; /* Datatype structure for vlen objects */ - H5T_t * array = NULL; /* Datatype structure for array objects */ - H5T_t * objref = NULL; /* Datatype structure for deprecated reference objects */ - H5T_t * regref = NULL; /* Datatype structure for deprecated region references */ - H5T_t * ref = NULL; /* Datatype structure for opaque references */ - hsize_t dim[1] = {1}; /* Dimension info for array datatype */ + H5T_t * native_schar = NULL; /* Datatype structure for native signed char */ + H5T_t * native_uchar = NULL; /* Datatype structure for native unsigned char */ + H5T_t * native_short = NULL; /* Datatype structure for native short */ + H5T_t * native_ushort = NULL; /* Datatype structure for native unsigned short */ + H5T_t * native_int = NULL; /* Datatype structure for native int */ + H5T_t * native_uint = NULL; /* Datatype structure for native unsigned int */ + H5T_t * native_long = NULL; /* Datatype structure for native long */ + H5T_t * native_ulong = NULL; /* Datatype structure for native unsigned long */ + H5T_t * native_llong = NULL; /* Datatype structure for native long long */ + H5T_t * native_ullong = NULL; /* Datatype structure for native unsigned long long */ + H5T_t * native_float = NULL; /* Datatype structure for native float */ + H5T_t * native_double = NULL; /* Datatype structure for native double */ + H5T_t * native_ldouble = NULL; /* Datatype structure for native long double */ + H5T_t * std_u8le = NULL; /* Datatype structure for unsigned 8-bit little-endian integer */ + H5T_t * std_u8be = NULL; /* Datatype structure for unsigned 8-bit big-endian integer */ + H5T_t * std_u16le = NULL; /* Datatype structure for unsigned 16-bit little-endian integer */ + H5T_t * std_u16be = NULL; /* Datatype structure for unsigned 16-bit big-endian integer */ + H5T_t * std_u32le = NULL; /* Datatype structure for unsigned 32-bit little-endian integer */ + H5T_t * std_u32be = NULL; /* Datatype structure for unsigned 32-bit big-endian integer */ + H5T_t * std_u64le = NULL; /* Datatype structure for unsigned 64-bit little-endian integer */ + H5T_t * std_u64be = NULL; /* Datatype structure for unsigned 64-bit big-endian integer */ + H5T_t * dt = NULL; + H5T_t * fixedpt = NULL; /* Datatype structure for native int */ + H5T_t * floatpt = NULL; /* Datatype structure for native float */ + H5T_t * string = NULL; /* Datatype structure for C string */ + H5T_t * bitfield = NULL; /* Datatype structure for bitfield */ + H5T_t * compound = NULL; /* Datatype structure for compound objects */ + H5T_t * enum_type = NULL; /* Datatype structure for enum objects */ + H5T_t * vlen = NULL; /* Datatype structure for vlen objects */ + H5T_t * array = NULL; /* Datatype structure for array objects */ + H5T_t * objref = NULL; /* Datatype structure for deprecated reference objects */ + H5T_t * regref = NULL; /* Datatype structure for deprecated region references */ + H5T_t * ref = NULL; /* Datatype structure for opaque references */ + hsize_t dim[1] = {1}; /* Dimension info for array datatype */ herr_t status; hbool_t copied_dtype = TRUE; /* Flag to indicate whether datatype was copied or allocated (for error cleanup) */ @@ -843,10 +835,8 @@ H5T__init_package(void) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object") if (NULL == (native_double = (H5T_t *)H5I_object(H5T_NATIVE_DOUBLE_g))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object") -#if H5_SIZEOF_LONG_DOUBLE != 0 if (NULL == (native_ldouble = (H5T_t *)H5I_object(H5T_NATIVE_LDOUBLE_g))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object") -#endif /*------------------------------------------------------------ * Derived native types @@ -1116,7 +1106,6 @@ H5T__init_package(void) H5T__register_int(H5T_PERS_HARD, "flt_dbl", native_float, native_double, H5T__conv_float_double); status |= H5T__register_int(H5T_PERS_HARD, "dbl_flt", native_double, native_float, H5T__conv_double_float); -#if H5_SIZEOF_LONG_DOUBLE != 0 status |= H5T__register_int(H5T_PERS_HARD, "flt_ldbl", native_float, native_ldouble, H5T__conv_float_ldouble); status |= @@ -1125,7 +1114,6 @@ H5T__init_package(void) H5T__register_int(H5T_PERS_HARD, "ldbl_flt", native_ldouble, native_float, H5T__conv_ldouble_float); status |= H5T__register_int(H5T_PERS_HARD, "ldbl_dbl", native_ldouble, native_double, H5T__conv_ldouble_double); -#endif /* H5_SIZEOF_LONG_DOUBLE != 0 */ /* from long long */ status |= @@ -1663,31 +1651,29 @@ H5T_top_term_package(void) H5T_FORTRAN_S1_g = FAIL; - H5T_NATIVE_SCHAR_g = FAIL; - H5T_NATIVE_UCHAR_g = FAIL; - H5T_NATIVE_SHORT_g = FAIL; - H5T_NATIVE_USHORT_g = FAIL; - H5T_NATIVE_INT_g = FAIL; - H5T_NATIVE_UINT_g = FAIL; - H5T_NATIVE_LONG_g = FAIL; - H5T_NATIVE_ULONG_g = FAIL; - H5T_NATIVE_LLONG_g = FAIL; - H5T_NATIVE_ULLONG_g = FAIL; - H5T_NATIVE_FLOAT_g = FAIL; - H5T_NATIVE_DOUBLE_g = FAIL; -#if H5_SIZEOF_LONG_DOUBLE != 0 + H5T_NATIVE_SCHAR_g = FAIL; + H5T_NATIVE_UCHAR_g = FAIL; + H5T_NATIVE_SHORT_g = FAIL; + H5T_NATIVE_USHORT_g = FAIL; + H5T_NATIVE_INT_g = FAIL; + H5T_NATIVE_UINT_g = FAIL; + H5T_NATIVE_LONG_g = FAIL; + H5T_NATIVE_ULONG_g = FAIL; + H5T_NATIVE_LLONG_g = FAIL; + H5T_NATIVE_ULLONG_g = FAIL; + H5T_NATIVE_FLOAT_g = FAIL; + H5T_NATIVE_DOUBLE_g = FAIL; H5T_NATIVE_LDOUBLE_g = FAIL; -#endif - H5T_NATIVE_B8_g = FAIL; - H5T_NATIVE_B16_g = FAIL; - H5T_NATIVE_B32_g = FAIL; - H5T_NATIVE_B64_g = FAIL; - H5T_NATIVE_OPAQUE_g = FAIL; - H5T_NATIVE_HADDR_g = FAIL; - H5T_NATIVE_HSIZE_g = FAIL; - H5T_NATIVE_HSSIZE_g = FAIL; - H5T_NATIVE_HERR_g = FAIL; - H5T_NATIVE_HBOOL_g = FAIL; + H5T_NATIVE_B8_g = FAIL; + H5T_NATIVE_B16_g = FAIL; + H5T_NATIVE_B32_g = FAIL; + H5T_NATIVE_B64_g = FAIL; + H5T_NATIVE_OPAQUE_g = FAIL; + H5T_NATIVE_HADDR_g = FAIL; + H5T_NATIVE_HSIZE_g = FAIL; + H5T_NATIVE_HSSIZE_g = FAIL; + H5T_NATIVE_HERR_g = FAIL; + H5T_NATIVE_HBOOL_g = FAIL; H5T_NATIVE_INT8_g = FAIL; H5T_NATIVE_UINT8_g = FAIL; diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 18cbcf1..c06c895 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -7009,14 +7009,12 @@ H5T__conv_float_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne * *------------------------------------------------------------------------- */ -#if H5_SIZEOF_LONG_DOUBLE != 0 herr_t H5T__conv_float_ldouble(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { H5T_CONV_fF(FLOAT, LDOUBLE, float, long double, -, -); } -#endif /* H5_SIZEOF_LONG_DOUBLE != 0 */ /*------------------------------------------------------------------------- * Function: H5T__conv_double_float @@ -7051,14 +7049,12 @@ H5T__conv_double_float(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne * *------------------------------------------------------------------------- */ -#if H5_SIZEOF_LONG_DOUBLE != 0 herr_t H5T__conv_double_ldouble(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { H5T_CONV_fF(DOUBLE, LDOUBLE, double, long double, -, -); } -#endif /* H5_SIZEOF_LONG_DOUBLE != 0 */ /*------------------------------------------------------------------------- * Function: H5T__conv_ldouble_float @@ -7073,14 +7069,12 @@ H5T__conv_double_ldouble(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t * *------------------------------------------------------------------------- */ -#if H5_SIZEOF_LONG_DOUBLE != 0 herr_t H5T__conv_ldouble_float(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { H5T_CONV_Ff(LDOUBLE, FLOAT, long double, float, -FLT_MAX, FLT_MAX); } -#endif /* H5_SIZEOF_LONG_DOUBLE != 0 */ /*------------------------------------------------------------------------- * Function: H5T__conv_ldouble_double @@ -7095,14 +7089,12 @@ H5T__conv_ldouble_float(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n * *------------------------------------------------------------------------- */ -#if H5_SIZEOF_LONG_DOUBLE != 0 herr_t H5T__conv_ldouble_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { H5T_CONV_Ff(LDOUBLE, DOUBLE, long double, double, -DBL_MAX, DBL_MAX); } -#endif /* H5_SIZEOF_LONG_DOUBLE != 0 */ /*------------------------------------------------------------------------- * Function: H5T__conv_schar_float diff --git a/src/H5Tnative.c b/src/H5Tnative.c index 2688b23..c9a2907 100644 --- a/src/H5Tnative.c +++ b/src/H5Tnative.c @@ -718,9 +718,7 @@ H5T__get_native_float(size_t size, H5T_direction_t direction, size_t *struct_ali enum match_type { /* The different kinds of floating point types we can match */ H5T_NATIVE_FLOAT_MATCH_FLOAT, H5T_NATIVE_FLOAT_MATCH_DOUBLE, -#if H5_SIZEOF_LONG_DOUBLE != 0 H5T_NATIVE_FLOAT_MATCH_LDOUBLE, -#endif H5T_NATIVE_FLOAT_MATCH_UNKNOWN } match = H5T_NATIVE_FLOAT_MATCH_UNKNOWN; H5T_t *ret_value = NULL; /* Return value */ @@ -738,24 +736,16 @@ H5T__get_native_float(size_t size, H5T_direction_t direction, size_t *struct_ali match = H5T_NATIVE_FLOAT_MATCH_DOUBLE; native_size = sizeof(double); } -#if H5_SIZEOF_LONG_DOUBLE != 0 else if (size <= sizeof(long double)) { match = H5T_NATIVE_FLOAT_MATCH_LDOUBLE; native_size = sizeof(long double); } -#endif else { /* If not match, return the biggest datatype */ -#if H5_SIZEOF_LONG_DOUBLE != 0 match = H5T_NATIVE_FLOAT_MATCH_LDOUBLE; native_size = sizeof(long double); -#else - match = H5T_NATIVE_FLOAT_MATCH_DOUBLE; - native_size = sizeof(double); -#endif } } else { -#if H5_SIZEOF_LONG_DOUBLE != 0 if (size > sizeof(double)) { match = H5T_NATIVE_FLOAT_MATCH_LDOUBLE; native_size = sizeof(long double); @@ -768,16 +758,6 @@ H5T__get_native_float(size_t size, H5T_direction_t direction, size_t *struct_ali match = H5T_NATIVE_FLOAT_MATCH_FLOAT; native_size = sizeof(float); } -#else - if (size > sizeof(float)) { - match = H5T_NATIVE_FLOAT_MATCH_DOUBLE; - native_size = sizeof(double); - } - else { - match = H5T_NATIVE_FLOAT_MATCH_FLOAT; - native_size = sizeof(float); - } -#endif } /* Set the appropriate native floating point information */ @@ -792,12 +772,11 @@ H5T__get_native_float(size_t size, H5T_direction_t direction, size_t *struct_ali align = H5T_NATIVE_DOUBLE_COMP_ALIGN_g; break; -#if H5_SIZEOF_LONG_DOUBLE != 0 case H5T_NATIVE_FLOAT_MATCH_LDOUBLE: tid = H5T_NATIVE_LDOUBLE; align = H5T_NATIVE_LDOUBLE_COMP_ALIGN_g; break; -#endif + case H5T_NATIVE_FLOAT_MATCH_UNKNOWN: default: HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "Unknown native floating-point match") diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index 51ecaca..19593dd 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -401,9 +401,7 @@ H5_DLLVAR size_t H5T_NATIVE_LONG_COMP_ALIGN_g; H5_DLLVAR size_t H5T_NATIVE_LLONG_COMP_ALIGN_g; H5_DLLVAR size_t H5T_NATIVE_FLOAT_COMP_ALIGN_g; H5_DLLVAR size_t H5T_NATIVE_DOUBLE_COMP_ALIGN_g; -#if H5_SIZEOF_LONG_DOUBLE != 0 H5_DLLVAR size_t H5T_NATIVE_LDOUBLE_COMP_ALIGN_g; -#endif H5_DLLVAR size_t H5T_POINTER_COMP_ALIGN_g; H5_DLLVAR size_t H5T_HVL_COMP_ALIGN_g; @@ -429,9 +427,7 @@ H5_DLLVAR size_t H5T_NATIVE_LLONG_ALIGN_g; H5_DLLVAR size_t H5T_NATIVE_ULLONG_ALIGN_g; H5_DLLVAR size_t H5T_NATIVE_FLOAT_ALIGN_g; H5_DLLVAR size_t H5T_NATIVE_DOUBLE_ALIGN_g; -#if H5_SIZEOF_LONG_DOUBLE != 0 H5_DLLVAR size_t H5T_NATIVE_LDOUBLE_ALIGN_g; -#endif /* C9x alignment constraints */ H5_DLLVAR size_t H5T_NATIVE_INT8_ALIGN_g; @@ -468,10 +464,8 @@ H5_DLLVAR float H5T_NATIVE_FLOAT_POS_INF_g; H5_DLLVAR float H5T_NATIVE_FLOAT_NEG_INF_g; H5_DLLVAR double H5T_NATIVE_DOUBLE_POS_INF_g; H5_DLLVAR double H5T_NATIVE_DOUBLE_NEG_INF_g; -#if H5_SIZEOF_LONG_DOUBLE != 0 H5_DLLVAR double H5T_NATIVE_LDOUBLE_POS_INF_g; H5_DLLVAR double H5T_NATIVE_LDOUBLE_NEG_INF_g; -#endif /* Declare extern the free lists for H5T_t's and H5T_shared_t's */ H5FL_EXTERN(H5T_t); diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h index bb5b0ef..911efdf 100644 --- a/src/H5Tpublic.h +++ b/src/H5Tpublic.h @@ -803,13 +803,11 @@ H5_DLLVAR hid_t H5T_VAX_F64_g; * C-style \Code{double} */ #define H5T_NATIVE_DOUBLE (H5OPEN H5T_NATIVE_DOUBLE_g) -#if H5_SIZEOF_LONG_DOUBLE != 0 /** * \ingroup PDTNAT * C-style \Code{long double} */ #define H5T_NATIVE_LDOUBLE (H5OPEN H5T_NATIVE_LDOUBLE_g) -#endif /** * \ingroup PDTNAT * HDF5 8-bit bitfield based on native types @@ -872,9 +870,7 @@ H5_DLLVAR hid_t H5T_NATIVE_LLONG_g; H5_DLLVAR hid_t H5T_NATIVE_ULLONG_g; H5_DLLVAR hid_t H5T_NATIVE_FLOAT_g; H5_DLLVAR hid_t H5T_NATIVE_DOUBLE_g; -#if H5_SIZEOF_LONG_DOUBLE != 0 H5_DLLVAR hid_t H5T_NATIVE_LDOUBLE_g; -#endif H5_DLLVAR hid_t H5T_NATIVE_B8_g; H5_DLLVAR hid_t H5T_NATIVE_B16_g; H5_DLLVAR hid_t H5T_NATIVE_B32_g; diff --git a/src/H5Tref.c b/src/H5Tref.c index cac8cf6..511c531 100644 --- a/src/H5Tref.c +++ b/src/H5Tref.c @@ -309,8 +309,8 @@ H5T__ref_set_loc(H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't get encode size") /* Size on disk, memory size is different */ - dt->shared->size = MAX(H5_SIZEOF_UINT32_T + H5R_ENCODE_HEADER_SIZE + cont_info.blob_id_size, - ref_encode_size); + dt->shared->size = + MAX(sizeof(uint32_t) + H5R_ENCODE_HEADER_SIZE + cont_info.blob_id_size, ref_encode_size); dt->shared->u.atomic.prec = 8 * dt->shared->size; /* Set up the function pointers to access the information on @@ -778,7 +778,7 @@ H5T__ref_disk_isnull(const H5VL_object_t *src_file, const void *src_buf, hbool_t H5VL_blob_specific_args_t vol_cb_args; /* Arguments to VOL callback */ /* Skip the size / header */ - p = (const uint8_t *)src_buf + H5R_ENCODE_HEADER_SIZE + H5_SIZEOF_UINT32_T; + p = (const uint8_t *)src_buf + H5R_ENCODE_HEADER_SIZE + sizeof(uint32_t); /* Set up VOL callback arguments */ vol_cb_args.op_type = H5VL_BLOB_ISNULL; @@ -819,7 +819,7 @@ H5T__ref_disk_setnull(H5VL_object_t *dst_file, void *dst_buf, void *bg_buf) /* TODO Should get rid of bg stuff */ if (p_bg) { /* Skip the size / header */ - p_bg += (H5_SIZEOF_UINT32_T + H5R_ENCODE_HEADER_SIZE); + p_bg += (sizeof(uint32_t) + H5R_ENCODE_HEADER_SIZE); /* Set up VOL callback arguments */ vol_cb_args.op_type = H5VL_BLOB_DELETE; @@ -929,8 +929,8 @@ H5T__ref_disk_read(H5VL_object_t *src_file, const void *src_buf, size_t H5_ATTR_ blob_size -= H5R_ENCODE_HEADER_SIZE; /* Skip the size */ - p += H5_SIZEOF_UINT32_T; - HDassert(src_size > (H5R_ENCODE_HEADER_SIZE + H5_SIZEOF_UINT32_T)); + p += sizeof(uint32_t); + HDassert(src_size > (H5R_ENCODE_HEADER_SIZE + sizeof(uint32_t))); /* Retrieve blob */ if (H5VL_blob_get(src_file, p, q, blob_size, NULL) < 0) @@ -974,9 +974,9 @@ H5T__ref_disk_write(H5VL_object_t H5_ATTR_UNUSED *src_file, const void *src_buf, size_t p_buf_size_left = dst_size; /* Skip the size / header */ - p_bg += (H5_SIZEOF_UINT32_T + H5R_ENCODE_HEADER_SIZE); - HDassert(p_buf_size_left > (H5_SIZEOF_UINT32_T + H5R_ENCODE_HEADER_SIZE)); - p_buf_size_left -= (H5_SIZEOF_UINT32_T + H5R_ENCODE_HEADER_SIZE); + p_bg += (sizeof(uint32_t) + H5R_ENCODE_HEADER_SIZE); + HDassert(p_buf_size_left > (sizeof(uint32_t) + H5R_ENCODE_HEADER_SIZE)); + p_buf_size_left -= (sizeof(uint32_t) + H5R_ENCODE_HEADER_SIZE); /* Set up VOL callback arguments */ vol_cb_args.op_type = H5VL_BLOB_DELETE; @@ -991,12 +991,12 @@ H5T__ref_disk_write(H5VL_object_t H5_ATTR_UNUSED *src_file, const void *src_buf, p += H5R_ENCODE_HEADER_SIZE; q += H5R_ENCODE_HEADER_SIZE; src_size -= H5R_ENCODE_HEADER_SIZE; - buf_size_left -= H5_SIZEOF_UINT32_T; + buf_size_left -= sizeof(uint32_t); /* Set the size */ UINT32ENCODE(q, src_size); - HDassert(buf_size_left > H5_SIZEOF_UINT32_T); - buf_size_left -= H5_SIZEOF_UINT32_T; + HDassert(buf_size_left > sizeof(uint32_t)); + buf_size_left -= sizeof(uint32_t); /* Store blob */ if (H5VL_blob_put(dst_file, p, src_size, q, NULL) < 0) diff --git a/src/H5VL.c b/src/H5VL.c index 2cece6d..8c3277c 100644 --- a/src/H5VL.c +++ b/src/H5VL.c @@ -655,6 +655,39 @@ done: FUNC_LEAVE_API(ret_value) } /* H5VLobject() */ +/*--------------------------------------------------------------------------- + * Function: H5VLobject_is_native + * + * Purpose: Determines whether an object ID represents a native VOL + * connector object. + * + * Return: Non-negative on success/Negative on failure + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VLobject_is_native(hid_t obj_id, hbool_t *is_native) +{ + H5VL_object_t *vol_obj = NULL; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "i*b", obj_id, is_native); + + if (!is_native) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "`is_native` argument is NULL") + + /* Get the location object for the ID */ + if (NULL == (vol_obj = H5VL_vol_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + + if (H5VL_object_is_native(vol_obj, is_native) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't determine if object is a native connector object") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5VLobject_is_native() */ + /*------------------------------------------------------------------------- * Function: H5VLget_file_type * diff --git a/src/H5VLpublic.h b/src/H5VLpublic.h index 78e39e3..543c3c8 100644 --- a/src/H5VLpublic.h +++ b/src/H5VLpublic.h @@ -356,6 +356,19 @@ H5_DLL herr_t H5VLunregister_connector(hid_t connector_id); * \since 1.12.0 */ H5_DLL herr_t H5VLquery_optional(hid_t obj_id, H5VL_subclass_t subcls, int opt_type, uint64_t *flags); +/** + * \ingroup H5VL + * \brief Determines whether an object ID represents a native + * VOL connector object. + * + * \param[in] obj_id Object identifier + * \param[in] is_native Boolean determining whether object is a native + * VOL connector object + * \return \herr_t + * + * \since 1.13.0 + */ +H5_DLL herr_t H5VLobject_is_native(hid_t obj_id, hbool_t *is_native); #ifdef __cplusplus } diff --git a/src/H5Zscaleoffset.c b/src/H5Zscaleoffset.c index a8a63bf..48a29cd 100644 --- a/src/H5Zscaleoffset.c +++ b/src/H5Zscaleoffset.c @@ -364,12 +364,12 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ #define H5Z_scaleoffset_max_min_3(i, d_nelmts, buf, filval, max, min, D_val) \ { \ i = 0; \ - while (i < d_nelmts && HDfabs(buf[i] - filval) < HDpow(10.0, -D_val)) \ + while (i < d_nelmts && HDfabs((double)(buf[i] - filval)) < HDpow(10.0, -D_val)) \ i++; \ if (i < d_nelmts) \ min = max = buf[i]; \ for (; i < d_nelmts; i++) { \ - if (HDfabs(buf[i] - filval) < HDpow(10.0, -D_val)) \ + if (HDfabs((double)(buf[i] - filval)) < HDpow(10.0, -D_val)) \ continue; /* ignore fill value */ \ if (buf[i] > max) \ max = buf[i]; \ @@ -425,22 +425,22 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ #define H5Z_scaleoffset_check_3(i, type, pow_fun, round_fun, max, min, minbits, D_val) \ { \ if (sizeof(type) == sizeof(int)) { \ - if (round_fun(max * pow_fun(10.0F, (type)D_val) - min * pow_fun(10.0F, (type)D_val)) > \ - pow_fun(2.0F, (type)(sizeof(int) * 8 - 1))) { \ + if (round_fun(max * pow_fun((type)10, (type)D_val) - min * pow_fun((type)10, (type)D_val)) > \ + pow_fun((type)2, (type)(sizeof(int) * 8 - 1))) { \ *minbits = sizeof(int) * 8; \ goto done; \ } \ } \ else if (sizeof(type) == sizeof(long)) { \ - if (round_fun(max * pow_fun(10.0F, (type)D_val) - min * pow_fun(10.0F, (type)D_val)) > \ - pow_fun(2.0F, (type)(sizeof(long) * 8 - 1))) { \ + if (round_fun(max * pow_fun((type)10, (type)D_val) - min * pow_fun((type)10, (type)D_val)) > \ + pow_fun((type)2, (type)(sizeof(long) * 8 - 1))) { \ *minbits = sizeof(long) * 8; \ goto done; \ } \ } \ else if (sizeof(type) == sizeof(long long)) { \ - if (round_fun(max * pow_fun(10.0F, (type)D_val) - min * pow_fun(10.0F, (type)D_val)) > \ - pow_fun(2.0F, (type)(sizeof(long long) * 8 - 1))) { \ + if (round_fun(max * pow_fun((type)10, (type)D_val) - min * pow_fun((type)10, (type)D_val)) > \ + pow_fun((type)2, (type)(sizeof(long long) * 8 - 1))) { \ *minbits = sizeof(long long) * 8; \ goto done; \ } \ @@ -530,27 +530,27 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ { \ if (sizeof(type) == sizeof(int)) \ for (i = 0; i < d_nelmts; i++) { \ - if (abs_fun(buf[i] - filval) < pow_fun(10.0F, (type)-D_val)) \ + if (abs_fun(buf[i] - filval) < pow_fun((type)10, (type)-D_val)) \ *(int *)((void *)&buf[i]) = (int)(((unsigned int)1 << *minbits) - 1); \ else \ - *(int *)((void *)&buf[i]) = (int)lround_fun(buf[i] * pow_fun(10.0F, (type)D_val) - \ - min * pow_fun(10.0F, (type)D_val)); \ + *(int *)((void *)&buf[i]) = (int)lround_fun(buf[i] * pow_fun((type)10, (type)D_val) - \ + min * pow_fun((type)10, (type)D_val)); \ } \ else if (sizeof(type) == sizeof(long)) \ for (i = 0; i < d_nelmts; i++) { \ - if (abs_fun(buf[i] - filval) < pow_fun(10.0F, (type)-D_val)) \ + if (abs_fun(buf[i] - filval) < pow_fun((type)10, (type)-D_val)) \ *(long *)((void *)&buf[i]) = (long)(((unsigned long)1 << *minbits) - 1); \ else \ - *(long *)((void *)&buf[i]) = lround_fun(buf[i] * pow_fun(10.0F, (type)D_val) - \ - min * pow_fun(10.0F, (type)D_val)); \ + *(long *)((void *)&buf[i]) = lround_fun(buf[i] * pow_fun((type)10, (type)D_val) - \ + min * pow_fun((type)10, (type)D_val)); \ } \ else if (sizeof(type) == sizeof(long long)) \ for (i = 0; i < d_nelmts; i++) { \ - if (abs_fun(buf[i] - filval) < pow_fun(10.0F, (type)-D_val)) \ + if (abs_fun(buf[i] - filval) < pow_fun((type)10, (type)-D_val)) \ *(long long *)((void *)&buf[i]) = (long long)(((unsigned long long)1 << *minbits) - 1); \ else \ - *(long long *)((void *)&buf[i]) = llround_fun(buf[i] * pow_fun(10.0F, (type)D_val) - \ - min * pow_fun(10.0F, (type)D_val)); \ + *(long long *)((void *)&buf[i]) = llround_fun(buf[i] * pow_fun((type)10, (type)D_val) - \ + min * pow_fun((type)10, (type)D_val)); \ } \ else \ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype") \ @@ -561,16 +561,16 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ { \ if (sizeof(type) == sizeof(int)) \ for (i = 0; i < d_nelmts; i++) \ - *(int *)((void *)&buf[i]) = (int)lround_fun(buf[i] * pow_fun(10.0F, (type)D_val) - \ - min * pow_fun(10.0F, (type)D_val)); \ + *(int *)((void *)&buf[i]) = (int)lround_fun(buf[i] * pow_fun((type)10, (type)D_val) - \ + min * pow_fun((type)10, (type)D_val)); \ else if (sizeof(type) == sizeof(long)) \ for (i = 0; i < d_nelmts; i++) \ - *(long *)((void *)&buf[i]) = \ - lround_fun(buf[i] * pow_fun(10.0F, (type)D_val) - min * pow_fun(10.0F, (type)D_val)); \ + *(long *)((void *)&buf[i]) = lround_fun(buf[i] * pow_fun((type)10, (type)D_val) - \ + min * pow_fun((type)10, (type)D_val)); \ else if (sizeof(type) == sizeof(long long)) \ for (i = 0; i < d_nelmts; i++) \ - *(long long *)((void *)&buf[i]) = \ - llround_fun(buf[i] * pow_fun(10.0F, (type)D_val) - min * pow_fun(10.0F, (type)D_val)); \ + *(long long *)((void *)&buf[i]) = llround_fun(buf[i] * pow_fun((type)10, (type)D_val) - \ + min * pow_fun((type)10, (type)D_val)); \ else \ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype") \ } @@ -606,8 +606,8 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ H5Z_scaleoffset_get_filval_2(type, cd_values, filval) \ H5Z_scaleoffset_max_min_3(i, d_nelmts, buf, filval, max, min, D_val) \ H5Z_scaleoffset_check_3(i, type, pow_fun, round_fun, max, min, minbits, D_val) span = \ - (unsigned long long)(llround_fun(max * pow_fun(10.0F, (type)D_val) - \ - min * pow_fun(10.0F, (type)D_val)) + \ + (unsigned long long)(llround_fun(max * pow_fun((type)10, (type)D_val) - \ + min * pow_fun((type)10, (type)D_val)) + \ 1); \ *minbits = H5Z__scaleoffset_log2(span + 1); \ if (*minbits != sizeof(type) * 8) /* change values if minbits != full precision */ \ @@ -617,8 +617,8 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ else { /* fill value undefined */ \ H5Z_scaleoffset_max_min_2(i, d_nelmts, buf, max, min) \ H5Z_scaleoffset_check_3(i, type, pow_fun, round_fun, max, min, minbits, D_val) span = \ - (unsigned long long)(llround_fun(max * pow_fun(10.0F, (type)D_val) - \ - min * pow_fun(10.0F, (type)D_val)) + \ + (unsigned long long)(llround_fun(max * pow_fun((type)10, (type)D_val) - \ + min * pow_fun((type)10, (type)D_val)) + \ 1); \ *minbits = H5Z__scaleoffset_log2(span); \ if (*minbits != sizeof(type) * 8) /* change values if minbits != full precision */ \ @@ -685,19 +685,19 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ buf[i] = \ (type)((*(int *)((void *)&buf[i]) == (int)(((unsigned int)1 << minbits) - 1)) \ ? filval \ - : (type)(*(int *)((void *)&buf[i])) / pow_fun(10.0F, (type)D_val) + min); \ + : (type)(*(int *)((void *)&buf[i])) / pow_fun((type)10, (type)D_val) + min); \ else if (sizeof(type) == sizeof(long)) \ for (i = 0; i < d_nelmts; i++) \ buf[i] = \ (type)((*(long *)((void *)&buf[i]) == (long)(((unsigned long)1 << minbits) - 1)) \ ? filval \ - : (type)(*(long *)((void *)&buf[i])) / pow_fun(10.0F, (type)D_val) + min); \ + : (type)(*(long *)((void *)&buf[i])) / pow_fun((type)10, (type)D_val) + min); \ else if (sizeof(type) == sizeof(long long)) \ for (i = 0; i < d_nelmts; i++) \ buf[i] = (type)( \ (*(long long *)((void *)&buf[i]) == (long long)(((unsigned long long)1 << minbits) - 1)) \ ? filval \ - : (type)(*(long long *)((void *)&buf[i])) / pow_fun(10.0F, (type)D_val) + min); \ + : (type)(*(long long *)((void *)&buf[i])) / pow_fun((type)10, (type)D_val) + min); \ else \ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype") \ } @@ -707,13 +707,13 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ { \ if (sizeof(type) == sizeof(int)) \ for (i = 0; i < d_nelmts; i++) \ - buf[i] = ((type)(*(int *)((void *)&buf[i])) / pow_fun(10.0F, (type)D_val) + min); \ + buf[i] = ((type)(*(int *)((void *)&buf[i])) / pow_fun((type)10, (type)D_val) + min); \ else if (sizeof(type) == sizeof(long)) \ for (i = 0; i < d_nelmts; i++) \ - buf[i] = ((type)(*(long *)((void *)&buf[i])) / pow_fun(10.0F, (type)D_val) + min); \ + buf[i] = ((type)(*(long *)((void *)&buf[i])) / pow_fun((type)10, (type)D_val) + min); \ else if (sizeof(type) == sizeof(long long)) \ for (i = 0; i < d_nelmts; i++) \ - buf[i] = ((type)(*(long long *)((void *)&buf[i])) / pow_fun(10.0F, (type)D_val) + min); \ + buf[i] = ((type)(*(long long *)((void *)&buf[i])) / pow_fun((type)10, (type)D_val) + min); \ else \ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype") \ } diff --git a/src/H5Ztrans.c b/src/H5Ztrans.c index ab7e9be..ea532cf 100644 --- a/src/H5Ztrans.c +++ b/src/H5Ztrans.c @@ -150,7 +150,6 @@ static void H5Z__xform_reduce_tree(H5Z_node *tree); HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Unexpected type conversion operation") \ } -#if H5_SIZEOF_LONG_DOUBLE != 0 #if CHAR_MIN >= 0 #define H5Z_XFORM_TYPE_OP(RESL, RESR, TYPE, OP, SIZE) \ { \ @@ -212,65 +211,6 @@ static void H5Z__xform_reduce_tree(H5Z_node *tree); H5Z_XFORM_DO_OP1((RESL), (RESR), long double, OP, (SIZE)) \ } #endif /* CHAR_MIN >= 0 */ -#else -#if CHAR_MIN >= 0 -#define H5Z_XFORM_TYPE_OP(RESL, RESR, TYPE, OP, SIZE) \ - { \ - if ((TYPE) == H5T_NATIVE_CHAR) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), char, OP, (SIZE)) \ - else if ((TYPE) == H5T_NATIVE_SCHAR) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), signed char, OP, (SIZE)) \ - else if ((TYPE) == H5T_NATIVE_SHORT) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), short, OP, (SIZE)) \ - else if ((TYPE) == H5T_NATIVE_USHORT) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), unsigned short, OP, (SIZE)) \ - else if ((TYPE) == H5T_NATIVE_INT) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), int, OP, (SIZE)) \ - else if ((TYPE) == H5T_NATIVE_UINT) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), unsigned int, OP, (SIZE)) \ - else if ((TYPE) == H5T_NATIVE_LONG) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), long, OP, (SIZE)) \ - else if ((TYPE) == H5T_NATIVE_ULONG) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), unsigned long, OP, (SIZE)) \ - else if ((TYPE) == H5T_NATIVE_LLONG) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), long long, OP, (SIZE)) \ - else if ((TYPE) == H5T_NATIVE_ULLONG) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), unsigned long long, OP, (SIZE)) \ - else if ((TYPE) == H5T_NATIVE_FLOAT) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), float, OP, (SIZE)) \ - else if ((TYPE) == H5T_NATIVE_DOUBLE) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), double, OP, (SIZE)) \ - } -#else /* CHAR_MIN >= 0 */ -#define H5Z_XFORM_TYPE_OP(RESL, RESR, TYPE, OP, SIZE) \ - { \ - if ((TYPE) == H5T_NATIVE_CHAR) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), char, OP, (SIZE)) \ - else if ((TYPE) == H5T_NATIVE_UCHAR) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), unsigned char, OP, (SIZE)) \ - else if ((TYPE) == H5T_NATIVE_SHORT) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), short, OP, (SIZE)) \ - else if ((TYPE) == H5T_NATIVE_USHORT) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), unsigned short, OP, (SIZE)) \ - else if ((TYPE) == H5T_NATIVE_INT) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), int, OP, (SIZE)) \ - else if ((TYPE) == H5T_NATIVE_UINT) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), unsigned int, OP, (SIZE)) \ - else if ((TYPE) == H5T_NATIVE_LONG) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), long, OP, (SIZE)) \ - else if ((TYPE) == H5T_NATIVE_ULONG) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), unsigned long, OP, (SIZE)) \ - else if ((TYPE) == H5T_NATIVE_LLONG) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), long long, OP, (SIZE)) \ - else if ((TYPE) == H5T_NATIVE_ULLONG) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), unsigned long long, OP, (SIZE)) \ - else if ((TYPE) == H5T_NATIVE_FLOAT) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), float, OP, (SIZE)) \ - else if ((TYPE) == H5T_NATIVE_DOUBLE) \ - H5Z_XFORM_DO_OP1((RESL), (RESR), double, OP, (SIZE)) \ - } -#endif /* CHAR_MIN >= 0 */ -#endif /*H5_SIZEOF_LONG_DOUBLE */ #define H5Z_XFORM_DO_OP3(OP) \ { \ @@ -1056,10 +996,8 @@ H5Z_xform_eval(H5Z_data_xform_t *data_xform_prop, void *array, size_t array_size H5Z_XFORM_DO_OP5(float, array_size) else if (array_type == H5T_NATIVE_DOUBLE) H5Z_XFORM_DO_OP5(double, array_size) -#if H5_SIZEOF_LONG_DOUBLE != 0 else if (array_type == H5T_NATIVE_LDOUBLE) H5Z_XFORM_DO_OP5(long double, array_size) -#endif } /* end if */ /* Otherwise, do the full data transform */ @@ -1267,11 +1205,9 @@ H5Z__xform_find_type(const H5T_t *type) /* Check for DOUBLE type */ else if ((tmp = (H5T_t *)H5I_object(H5T_NATIVE_DOUBLE)) && 0 == H5T_cmp(type, tmp, FALSE)) HGOTO_DONE(H5T_NATIVE_DOUBLE) -#if H5_SIZEOF_LONG_DOUBLE != 0 /* Check for LONGDOUBLE type */ else if ((tmp = (H5T_t *)H5I_object(H5T_NATIVE_LDOUBLE)) && 0 == H5T_cmp(type, tmp, FALSE)) HGOTO_DONE(H5T_NATIVE_LDOUBLE) -#endif else HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not find matching type") diff --git a/src/H5detect.c b/src/H5detect.c index e8cded7..022cb55 100644 --- a/src/H5detect.c +++ b/src/H5detect.c @@ -1412,7 +1412,7 @@ detect_C99_floats(void) */ DETECT_F(double, LDOUBLE, d_g[nd_g]); nd_g++; -#elif H5_SIZEOF_LONG_DOUBLE != 0 +#else DETECT_F(long double, LDOUBLE, d_g[nd_g]); nd_g++; #endif diff --git a/src/H5private.h b/src/H5private.h index 7c76483..761ad17 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -259,10 +259,10 @@ #define H5_ATTR_NORETURN __attribute__((noreturn)) #define H5_ATTR_CONST __attribute__((const)) #define H5_ATTR_PURE __attribute__((pure)) -#if defined(__GNUC__) && __GNUC__ >= 7 && !defined(__INTEL_COMPILER) +#if defined(__clang__) || defined(__GNUC__) && __GNUC__ >= 7 && !defined(__INTEL_COMPILER) #define H5_ATTR_FALLTHROUGH __attribute__((fallthrough)); #else -#define H5_ATTR_FALLTHROUGH /*void*/ +#define H5_ATTR_FALLTHROUGH /* FALLTHROUGH */ #endif #else #define H5_ATTR_FORMAT(X, Y, Z) /*void*/ diff --git a/src/H5public.h b/src/H5public.h index 65709c6..163deed 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -83,15 +83,15 @@ /** * For tweaks, bug-fixes, or development */ -#define H5_VERS_RELEASE 0 +#define H5_VERS_RELEASE 1 /** * For pre-releases like \c snap0. Empty string for official releases. */ -#define H5_VERS_SUBRELEASE "" +#define H5_VERS_SUBRELEASE "1" /** * Full version string */ -#define H5_VERS_INFO "HDF5 library version: 1.13.0" +#define H5_VERS_INFO "HDF5 library version: 1.13.1-1" #define H5check() H5check_version(H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE) diff --git a/src/H5trace.c b/src/H5trace.c index 3a5d420..8daa17d 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -1563,10 +1563,8 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) H5RS_acat(rs, "H5T_NATIVE_FLOAT"); else if (obj == H5T_NATIVE_DOUBLE_g) H5RS_acat(rs, "H5T_NATIVE_DOUBLE"); -#if H5_SIZEOF_LONG_DOUBLE != 0 else if (obj == H5T_NATIVE_LDOUBLE_g) H5RS_acat(rs, "H5T_NATIVE_LDOUBLE"); -#endif else if (obj == H5T_IEEE_F32BE_g) H5RS_acat(rs, "H5T_IEEE_F32BE"); else if (obj == H5T_IEEE_F32LE_g) diff --git a/src/libhdf5.settings.in b/src/libhdf5.settings.in index 44c1540..7fe1a36 100644 --- a/src/libhdf5.settings.in +++ b/src/libhdf5.settings.in @@ -67,28 +67,29 @@ Languages: Features: --------- - Parallel HDF5: @PARALLEL@ -Parallel Filtered Dataset Writes: @PARALLEL_FILTERED_WRITES@ - Large Parallel I/O: @LARGE_PARALLEL_IO@ - High-level library: @HDF5_HL@ - Build HDF5 Tests: @HDF5_TESTS@ - Build HDF5 Tools: @HDF5_TOOLS@ - Threadsafety: @THREADSAFE@ - Default API mapping: @DEFAULT_API_VERSION@ - With deprecated public symbols: @DEPRECATED_SYMBOLS@ - I/O filters (external): @EXTERNAL_FILTERS@ - MPE: @MPE@ - Map (H5M) API: @MAP_API@ - Direct VFD: @DIRECT_VFD@ - Mirror VFD: @MIRROR_VFD@ - (Read-Only) S3 VFD: @ROS3_VFD@ - (Read-Only) HDFS VFD: @HAVE_LIBHDFS@ - dmalloc: @HAVE_DMALLOC@ - Packages w/ extra debug output: @INTERNAL_DEBUG_OUTPUT@ - API tracing: @TRACE_API@ - Using memory checker: @USINGMEMCHECKER@ - Memory allocation sanity checks: @MEMORYALLOCSANITYCHECK@ - Function stack tracing: @CODESTACK@ - Use file locking: @DESIRED_FILE_LOCKING@ - Strict file format checks: @STRICT_FORMAT_CHECKS@ - Optimization instrumentation: @INSTRUMENT_LIBRARY@ + Parallel HDF5: @PARALLEL@ + Parallel Filtered Dataset Writes: @PARALLEL_FILTERED_WRITES@ + Large Parallel I/O: @LARGE_PARALLEL_IO@ + High-level library: @HDF5_HL@ +Dimension scales w/ new references: @DIMENSION_SCALES_WITH_NEW_REF@ + Build HDF5 Tests: @HDF5_TESTS@ + Build HDF5 Tools: @HDF5_TOOLS@ + Threadsafety: @THREADSAFE@ + Default API mapping: @DEFAULT_API_VERSION@ + With deprecated public symbols: @DEPRECATED_SYMBOLS@ + I/O filters (external): @EXTERNAL_FILTERS@ + MPE: @MPE@ + Map (H5M) API: @MAP_API@ + Direct VFD: @DIRECT_VFD@ + Mirror VFD: @MIRROR_VFD@ + (Read-Only) S3 VFD: @ROS3_VFD@ + (Read-Only) HDFS VFD: @HAVE_LIBHDFS@ + dmalloc: @HAVE_DMALLOC@ + Packages w/ extra debug output: @INTERNAL_DEBUG_OUTPUT@ + API tracing: @TRACE_API@ + Using memory checker: @USINGMEMCHECKER@ + Memory allocation sanity checks: @MEMORYALLOCSANITYCHECK@ + Function stack tracing: @CODESTACK@ + Use file locking: @DESIRED_FILE_LOCKING@ + Strict file format checks: @STRICT_FORMAT_CHECKS@ + Optimization instrumentation: @INSTRUMENT_LIBRARY@ diff --git a/src/uthash.h b/src/uthash.h index 8bdca55..ea99839 100644 --- a/src/uthash.h +++ b/src/uthash.h @@ -714,25 +714,35 @@ typedef unsigned char uint8_t; hashv += (unsigned)(keylen); \ switch (_hj_k) { \ case 11: \ - hashv += ((unsigned)_hj_key[10] << 24); /* FALLTHROUGH */ \ + hashv += ((unsigned)_hj_key[10] << 24); \ + H5_ATTR_FALLTHROUGH \ case 10: \ - hashv += ((unsigned)_hj_key[9] << 16); /* FALLTHROUGH */ \ + hashv += ((unsigned)_hj_key[9] << 16); \ + H5_ATTR_FALLTHROUGH \ case 9: \ - hashv += ((unsigned)_hj_key[8] << 8); /* FALLTHROUGH */ \ + hashv += ((unsigned)_hj_key[8] << 8); \ + H5_ATTR_FALLTHROUGH \ case 8: \ - _hj_j += ((unsigned)_hj_key[7] << 24); /* FALLTHROUGH */ \ + _hj_j += ((unsigned)_hj_key[7] << 24); \ + H5_ATTR_FALLTHROUGH \ case 7: \ - _hj_j += ((unsigned)_hj_key[6] << 16); /* FALLTHROUGH */ \ + _hj_j += ((unsigned)_hj_key[6] << 16); \ + H5_ATTR_FALLTHROUGH \ case 6: \ - _hj_j += ((unsigned)_hj_key[5] << 8); /* FALLTHROUGH */ \ + _hj_j += ((unsigned)_hj_key[5] << 8); \ + H5_ATTR_FALLTHROUGH \ case 5: \ - _hj_j += _hj_key[4]; /* FALLTHROUGH */ \ + _hj_j += _hj_key[4]; \ + H5_ATTR_FALLTHROUGH \ case 4: \ - _hj_i += ((unsigned)_hj_key[3] << 24); /* FALLTHROUGH */ \ + _hj_i += ((unsigned)_hj_key[3] << 24); \ + H5_ATTR_FALLTHROUGH \ case 3: \ - _hj_i += ((unsigned)_hj_key[2] << 16); /* FALLTHROUGH */ \ + _hj_i += ((unsigned)_hj_key[2] << 16); \ + H5_ATTR_FALLTHROUGH \ case 2: \ - _hj_i += ((unsigned)_hj_key[1] << 8); /* FALLTHROUGH */ \ + _hj_i += ((unsigned)_hj_key[1] << 8); \ + H5_ATTR_FALLTHROUGH \ case 1: \ _hj_i += _hj_key[0]; \ } \ diff --git a/test/cache_api.c b/test/cache_api.c index 7858c65..412888e 100644 --- a/test/cache_api.c +++ b/test/cache_api.c @@ -546,7 +546,7 @@ check_file_mdc_api_calls(unsigned paged, hid_t fcpl_id) /* size_t max_decrement = */ (1 * 1024 * 1024 - 1), /* int epochs_before_eviction = */ 4, /* hbool_t apply_empty_reserve = */ TRUE, - /* double empty_reserve = */ 0.05f, + /* double empty_reserve = */ 0.05, /* int dirty_bytes_threshold = */ (256 * 1024), /* int metadata_write_strategy = */ H5AC__DEFAULT_METADATA_WRITE_STRATEGY}; diff --git a/test/cork.c b/test/cork.c index 80934ad..28c0604 100644 --- a/test/cork.c +++ b/test/cork.c @@ -89,10 +89,11 @@ static unsigned verify_old_dset_cork(void) { /* Variable Declarations */ - hid_t fid = -1; /* File ID */ - hid_t did = -1, did2 = -1, did3 = -1; /* Dataset IDs */ - hid_t dcpl = -1, dcpl2 = -1, dcpl3 = -1; /* Dataset creation property lists */ - hid_t sid = -1, sid2 = -1, sid3 = -1; /* Dataspace IDs */ + hid_t fid = H5I_INVALID_HID; /* File ID */ + hid_t did = H5I_INVALID_HID, did2 = H5I_INVALID_HID, did3 = H5I_INVALID_HID; /* Dataset IDs */ + hid_t dcpl = H5I_INVALID_HID, dcpl2 = H5I_INVALID_HID, + dcpl3 = H5I_INVALID_HID; /* Dataset creation property lists */ + hid_t sid = H5I_INVALID_HID, sid2 = H5I_INVALID_HID, sid3 = H5I_INVALID_HID; /* Dataspace IDs */ hsize_t dims[2] = {100, 20}; /* Dataset dimension sizes */ hsize_t max_dims[2] = {100, H5S_UNLIMITED}; /* Dataset maximum dimension sizes */ hsize_t chunk_dims[2] = {2, 5}; /* Dataset chunked dimension sizes */ @@ -295,19 +296,19 @@ static unsigned verify_obj_dset_cork(hbool_t swmr) { /* Variable Declarations */ - hid_t fid = -1; /* File ID */ - hid_t fapl = -1; /* File access property list */ - hid_t aid = -1; /* Attribute ID */ - hid_t sid = -1, sid2 = -1; /* Dataspace IDs */ - hid_t did = -1, did2 = -1; /* Dataset IDs */ - hid_t oid = -1; /* Object ID */ - hid_t dcpl2; /* Dataset creation property list */ - int i = 0; /* Local index variable */ - hsize_t dim[1] = {100}; /* Dataset dimension size */ - hsize_t chunk_dim[1] = {7}; /* Dataset chunk dimension size */ - H5O_info2_t oinfo, oinfo2; /* Object metadata information */ - char attrname[500]; /* Name of attribute */ - unsigned flags; /* File access flags */ + hid_t fid = H5I_INVALID_HID; /* File ID */ + hid_t fapl = H5I_INVALID_HID; /* File access property list */ + hid_t aid = H5I_INVALID_HID; /* Attribute ID */ + hid_t sid = H5I_INVALID_HID, sid2 = H5I_INVALID_HID; /* Dataspace IDs */ + hid_t did = H5I_INVALID_HID, did2 = H5I_INVALID_HID; /* Dataset IDs */ + hid_t oid = H5I_INVALID_HID; /* Object ID */ + hid_t dcpl2 = H5I_INVALID_HID; /* Dataset creation property list */ + int i = 0; /* Local index variable */ + hsize_t dim[1] = {100}; /* Dataset dimension size */ + hsize_t chunk_dim[1] = {7}; /* Dataset chunk dimension size */ + H5O_info2_t oinfo, oinfo2; /* Object metadata information */ + char attrname[500]; /* Name of attribute */ + unsigned flags; /* File access flags */ if (swmr) { TESTING("cork status for dataset objects with attributes (SWMR)"); @@ -500,11 +501,11 @@ static unsigned verify_dset_cork(hbool_t swmr, hbool_t new_format) { /* Variable Declarations */ - hid_t fid = -1; /* File ID */ - hid_t fapl = -1; /* File access property list */ - hid_t did = -1, did2 = -1, did3 = -1; /* Dataset IDs */ - hid_t dcpl = -1; /* Dataset creation property list */ - hid_t sid = -1, sid2 = -1, sid3 = -1; /* Dataspace IDs */ + hid_t fid = H5I_INVALID_HID; /* File ID */ + hid_t fapl = H5I_INVALID_HID; /* File access property list */ + hid_t did = H5I_INVALID_HID, did2 = H5I_INVALID_HID, did3 = H5I_INVALID_HID; /* Dataset IDs */ + hid_t dcpl = H5I_INVALID_HID; /* Dataset creation property list */ + hid_t sid = H5I_INVALID_HID, sid2 = H5I_INVALID_HID, sid3 = H5I_INVALID_HID; /* Dataspace IDs */ hsize_t dims[2] = {100, 20}; /* Dataset dimension sizes */ hsize_t max_dims[2] = {100, H5S_UNLIMITED}; /* Dataset maximum dimension sizes */ hsize_t chunk_dims[2] = {2, 5}; /* Dataset chunked dimension sizes */ @@ -758,15 +759,15 @@ static unsigned verify_group_cork(hbool_t swmr) { /* Variable Declarations */ - hid_t fid = -1; /* File ID */ - hid_t fapl = -1; /* File access property list */ - hid_t gid = -1, gid2 = -1, gid3 = -1; /* Group IDs */ - H5O_info2_t oinfo, oinfo2, oinfo3; /* Object metadata information */ - hid_t aid; /* Attribute ID */ - hid_t sid; /* Dataspace ID */ - char attrname[500]; /* Name of attribute */ - unsigned flags; /* File access flags */ - int i = 0; /* Local index variable */ + hid_t fid = H5I_INVALID_HID; /* File ID */ + hid_t fapl = H5I_INVALID_HID; /* File access property list */ + hid_t gid = H5I_INVALID_HID, gid2 = H5I_INVALID_HID, gid3 = H5I_INVALID_HID; /* Group IDs */ + H5O_info2_t oinfo, oinfo2, oinfo3; /* Object metadata information */ + hid_t aid = H5I_INVALID_HID; /* Attribute ID */ + hid_t sid = H5I_INVALID_HID; /* Dataspace ID */ + char attrname[500]; /* Name of attribute */ + unsigned flags; /* File access flags */ + int i = 0; /* Local index variable */ /* Testing Macro */ if (swmr) { @@ -927,17 +928,17 @@ static unsigned verify_named_cork(hbool_t swmr) { /* Variable Declarations */ - hid_t fid = -1; /* File ID */ - hid_t fapl = -1; /* File access property list */ - hid_t tid = -1, tid2 = -1, tid3 = -1; /* Datatype IDs */ - hid_t gid = -1, gid2 = -1; /* Group IDs */ - H5O_info2_t oinfo, oinfo2, oinfo3, oinfo4; /* Object metadata information */ - hid_t aid = -1; /* Attribute ID */ - hid_t sid; /* Dataspace ID */ - hid_t did; /* Dataset ID */ - char attrname[500]; /* Name of attribute */ - unsigned flags; /* File access flags */ - int i = 0; /* Local index variable */ + hid_t fid = H5I_INVALID_HID; /* File ID */ + hid_t fapl = H5I_INVALID_HID; /* File access property list */ + hid_t tid = H5I_INVALID_HID, tid2 = H5I_INVALID_HID, tid3 = H5I_INVALID_HID; /* Datatype IDs */ + hid_t gid = H5I_INVALID_HID, gid2 = H5I_INVALID_HID; /* Group IDs */ + H5O_info2_t oinfo, oinfo2, oinfo3, oinfo4; /* Object metadata information */ + hid_t aid = H5I_INVALID_HID; /* Attribute ID */ + hid_t sid = H5I_INVALID_HID; /* Dataspace ID */ + hid_t did = H5I_INVALID_HID; /* Dataset ID */ + char attrname[500]; /* Name of attribute */ + unsigned flags; /* File access flags */ + int i = 0; /* Local index variable */ /* Testing Macro */ if (swmr) { @@ -1204,20 +1205,20 @@ static unsigned verify_multiple_cork(hbool_t swmr) { /* Variable Declarations */ - hid_t fid1 = -1, fid2 = -1; /* File ID */ - hid_t fapl = -1; /* File access property list */ - hid_t tid1 = -1, tid2 = -1; /* Datatype IDs */ - hid_t gid1 = -1, gid2 = -1; /* Group IDs */ - hid_t did1 = -1, did2 = -1; /* Dataset ID */ - hid_t aidg1 = -1, aidg2 = -1; /* Attribute ID */ - hid_t aidd1 = -1, aidd2 = -1; /* Attribute ID */ - hid_t aidt1 = -1, aidt2 = -1; /* Attribute ID */ - hid_t sid = -1; /* Dataspace ID */ - H5O_info2_t oinfo1, oinfo2, oinfo3; /* Object metadata information */ - hsize_t dim[1] = {5}; /* Dimension sizes */ - unsigned flags; /* File access flags */ - hbool_t corked; /* Cork status */ - herr_t ret; /* Return value */ + hid_t fid1 = H5I_INVALID_HID, fid2 = H5I_INVALID_HID; /* File ID */ + hid_t fapl = H5I_INVALID_HID; /* File access property list */ + hid_t tid1 = H5I_INVALID_HID, tid2 = H5I_INVALID_HID; /* Datatype IDs */ + hid_t gid1 = H5I_INVALID_HID, gid2 = H5I_INVALID_HID; /* Group IDs */ + hid_t did1 = H5I_INVALID_HID, did2 = H5I_INVALID_HID; /* Dataset ID */ + hid_t aidg1 = H5I_INVALID_HID, aidg2 = H5I_INVALID_HID; /* Attribute ID */ + hid_t aidd1 = H5I_INVALID_HID, aidd2 = H5I_INVALID_HID; /* Attribute ID */ + hid_t aidt1 = H5I_INVALID_HID, aidt2 = H5I_INVALID_HID; /* Attribute ID */ + hid_t sid = H5I_INVALID_HID; /* Dataspace ID */ + H5O_info2_t oinfo1, oinfo2, oinfo3; /* Object metadata information */ + hsize_t dim[1] = {5}; /* Dimension sizes */ + unsigned flags; /* File access flags */ + hbool_t corked; /* Cork status */ + herr_t ret; /* Return value */ /* Testing Macro */ if (swmr) { @@ -1880,18 +1881,18 @@ error: static unsigned test_dset_cork(hbool_t swmr, hbool_t new_format) { - hid_t fid; /* File ID */ - hid_t fapl; /* File access property list */ - hid_t gid; /* Groupd ID */ - hid_t did1, did2; /* Dataset IDs */ - hid_t tid1, tid2; /* Datatype IDs */ - hid_t sid; /* Dataspace ID */ - hid_t dcpl; /* Dataset creation property list */ - hsize_t dims[RANK]; /* Dataset dimensions */ - hsize_t maxdims[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; /* Maximum dataset dimensions */ - hsize_t cdims[RANK] = {2, 2}; /* Chunk dimensions */ - int fillval = 0; /* Fill value */ - int i, j, k = 0; /* Local index variables */ + hid_t fid = H5I_INVALID_HID; /* File ID */ + hid_t fapl; /* File access property list */ + hid_t gid = H5I_INVALID_HID; /* Groupd ID */ + hid_t did1 = H5I_INVALID_HID, did2 = H5I_INVALID_HID; /* Dataset IDs */ + hid_t tid1 = H5I_INVALID_HID, tid2 = H5I_INVALID_HID; /* Datatype IDs */ + hid_t sid = H5I_INVALID_HID; /* Dataspace ID */ + hid_t dcpl = H5I_INVALID_HID; /* Dataset creation property list */ + hsize_t dims[RANK]; /* Dataset dimensions */ + hsize_t maxdims[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; /* Maximum dataset dimensions */ + hsize_t cdims[RANK] = {2, 2}; /* Chunk dimensions */ + int fillval = 0; /* Fill value */ + int i, j, k = 0; /* Local index variables */ int ** wbuf = NULL; /* Data buffer for writes (pointers to fake 2D array) */ int * wbuf_data = NULL; /* Data buffer for writes (real data) */ int * rbuf_data = NULL; /* Data buffer for reads (real data) */ diff --git a/test/dsets.c b/test/dsets.c index 922f370..e2d281a 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -1399,7 +1399,7 @@ test_conv_buffer(hid_t fid) cf->b[j] = 100.0F * (float)(j + 1) + 0.01F * (float)j; for (j = 0; j < DIM3; j++) - cf->c[j] = 100.0F * (float)(j + 1) + 0.02F * (float)j; + cf->c[j] = 100.0 * (double)(j + 1) + 0.02 * (double)j; /* Create data space */ if ((space = H5Screate(H5S_SCALAR)) < 0) @@ -3442,11 +3442,11 @@ test_nbit_double(hid_t file) /* orig_data[] are initialized to be within the range that can be represented by * dataset datatype (no precision loss during datatype conversion) */ - double orig_data[2][5] = {{(double)1.6081706885101836e+60L, -255.32099170994480f, - (double)1.2677579992621376e-61L, 64568.289448797700f, + double orig_data[2][5] = {{(double)1.6081706885101836e+60L, -255.32099170994480, + (double)1.2677579992621376e-61L, 64568.289448797700, (double)-1.0619721778839084e-75L}, - {(double)2.1499497833454840e+56L, 6.6562295504670740e-3f, -1.5747263393432150f, - 1.0711093225222612f, -9.8971679387636870e-1f}}; + {(double)2.1499497833454840e+56L, 6.6562295504670740e-3, -1.5747263393432150, + 1.0711093225222612, -9.8971679387636870e-1}}; double new_data[2][5]; size_t precision, offset; size_t i, j; @@ -5201,7 +5201,7 @@ test_scaleoffset_float(hid_t file) /* Check that the values read are the same as the values written */ for (i = 0; i < (size_t)size[0]; i++) { for (j = 0; j < (size_t)size[1]; j++) { - if (HDfabs(new_data[i][j] - orig_data[i][j]) > HDpow(10.0, -3.0)) { + if (HDfabs((double)(new_data[i][j] - orig_data[i][j])) > HDpow(10.0, -3.0)) { H5_FAILED(); HDprintf(" Read different values than written.\n"); HDprintf(" At index %lu,%lu\n", (unsigned long)i, (unsigned long)j); @@ -5347,7 +5347,7 @@ test_scaleoffset_float_2(hid_t file) /* Check that the values read are the same as the values written */ for (j = 0; j < (size_t)size[1]; j++) { - if (HDfabs(new_data[0][j] - orig_data[0][j]) > HDpow(10.0, -3.0)) { + if (HDfabs((double)(new_data[0][j] - orig_data[0][j])) > HDpow(10.0, -3.0)) { H5_FAILED(); HDprintf(" Read different values than written.\n"); HDprintf(" At index %lu,%lu\n", (unsigned long)0, (unsigned long)j); @@ -5435,7 +5435,7 @@ test_scaleoffset_double(hid_t file) /* Initialize data */ for (i = 0; i < (size_t)size[0]; i++) for (j = 0; j < (size_t)size[1]; j++) { - orig_data[i][j] = (float)(HDrandom() % 10000000) / 10000000.0F; + orig_data[i][j] = (HDrandom() % 10000000) / 10000000.0; /* even-numbered values are negtive */ if ((i * size[1] + j + 1) % 2 == 0) @@ -5544,7 +5544,7 @@ test_scaleoffset_double_2(hid_t file) goto error; /* Set fill value */ - fillval = 10000.0F; + fillval = 10000.0; if (H5Pset_fill_value(dc, H5T_NATIVE_DOUBLE, &fillval) < 0) goto error; @@ -5581,7 +5581,7 @@ test_scaleoffset_double_2(hid_t file) /* Initialize data of hyperslab */ for (j = 0; j < (size_t)size[1]; j++) { - orig_data[0][j] = (float)(HDrandom() % 10000000) / 10000000.0F; + orig_data[0][j] = (HDrandom() % 10000000) / 10000000.0; /* even-numbered values are negtive */ if ((j + 1) % 2 == 0) @@ -5614,7 +5614,7 @@ test_scaleoffset_double_2(hid_t file) /* Check that the values read are the same as the values written */ for (j = 0; j < (size_t)size[1]; j++) { - if (HDfabs(new_data[0][j] - orig_data[0][j]) > HDpow(10.0, -7.0)) { + if (HDfabs((double)(new_data[0][j] - orig_data[0][j])) > HDpow(10.0, -7.0)) { H5_FAILED(); HDprintf(" Read different values than written.\n"); HDprintf(" At index %lu,%lu\n", (unsigned long)0, (unsigned long)j); @@ -6525,7 +6525,7 @@ test_set_local(hid_t fapl) h5_fixname(FILENAME[5], fapl, filename, sizeof filename); /* Initialize the integer & floating-point dataset */ - n = 1.0F; + n = 1.0; for (i = 0; i < DSET_DIM1; i++) for (j = 0; j < DSET_DIM2; j++) { points[i][j] = (int)n++; @@ -9085,7 +9085,7 @@ test_big_chunks_bypass_cache(hid_t fapl) /* Define cache size to be smaller than chunk size */ rdcc_nelmts = BYPASS_CHUNK_DIM / 5; rdcc_nbytes = sizeof(int) * BYPASS_CHUNK_DIM / 5; - if (H5Pset_cache(fapl_local, 0, rdcc_nelmts, rdcc_nbytes, 0.0F) < 0) + if (H5Pset_cache(fapl_local, 0, rdcc_nelmts, rdcc_nbytes, 0.0) < 0) FAIL_STACK_ERROR /* Create file */ diff --git a/test/dt_arith.c b/test/dt_arith.c index 91e31d5..7e96d29 100644 --- a/test/dt_arith.c +++ b/test/dt_arith.c @@ -68,9 +68,7 @@ typedef enum dtype_t { INT_ULLONG, FLT_FLOAT, FLT_DOUBLE, -#if H5_SIZEOF_LONG_DOUBLE != 0 FLT_LDOUBLE, -#endif OTHER } dtype_t; @@ -457,10 +455,8 @@ reset_hdf5(void) SET_ALIGNMENT(ULLONG, H5_SIZEOF_LONG_LONG); SET_ALIGNMENT(FLOAT, H5_SIZEOF_FLOAT); SET_ALIGNMENT(DOUBLE, H5_SIZEOF_DOUBLE); -#if H5_SIZEOF_LONG_DOUBLE != 0 SET_ALIGNMENT(LDOUBLE, H5_SIZEOF_LONG_DOUBLE); #endif -#endif } /*------------------------------------------------------------------------- @@ -2704,10 +2700,10 @@ my_isnan(dtype_t type, void *val) double x = 0.0; HDmemcpy(&x, val, sizeof(double)); retval = (x != x); -#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE && H5_SIZEOF_LONG_DOUBLE != 0 +#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE } else if (FLT_LDOUBLE == type) { - long double x = 0.0; + long double x = 0.0L; HDmemcpy(&x, val, sizeof(long double)); retval = (x != x); #endif @@ -2732,10 +2728,10 @@ my_isnan(dtype_t type, void *val) HDmemcpy(&x, val, sizeof(double)); HDsnprintf(s, sizeof(s), "%g", x); -#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE && H5_SIZEOF_LONG_DOUBLE != 0 +#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE } else if (FLT_LDOUBLE == type) { - long double x = 0.0; + long double x = 0.0L; HDmemcpy(&x, val, sizeof(long double)); HDsnprintf(s, sizeof(s), "%Lg", x); @@ -2898,7 +2894,7 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) else if (H5Tequal(src, H5T_NATIVE_DOUBLE)) { src_type_name = "double"; src_type = FLT_DOUBLE; -#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE && H5_SIZEOF_LONG_DOUBLE != 0 +#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE } else if (H5Tequal(src, H5T_NATIVE_LDOUBLE)) { src_type_name = "long double"; @@ -2917,7 +2913,7 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) else if (H5Tequal(dst, H5T_NATIVE_DOUBLE)) { dst_type_name = "double"; dst_type = FLT_DOUBLE; -#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE && H5_SIZEOF_LONG_DOUBLE != 0 +#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE } else if (H5Tequal(dst, H5T_NATIVE_LDOUBLE)) { dst_type_name = "long double"; @@ -3000,7 +2996,7 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) else if (src_type == FLT_DOUBLE) { INIT_FP_NORM(double, DBL_MAX, DBL_MIN, DBL_MAX_10_EXP, DBL_MIN_10_EXP, src_size, dst_size, buf, saved, nelmts); -#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE && H5_SIZEOF_LONG_DOUBLE != 0 +#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE } else if (src_type == FLT_LDOUBLE) { INIT_FP_NORM(long double, LDBL_MAX, LDBL_MIN, LDBL_MAX_10_EXP, LDBL_MIN_10_EXP, src_size, @@ -3019,7 +3015,7 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) else if (src_type == FLT_DOUBLE) { INIT_FP_DENORM(double, DBL_MANT_DIG, src_size, src_nbits, sendian, dst_size, buf, saved, nelmts); -#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE && H5_SIZEOF_LONG_DOUBLE != 0 +#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE } else if (src_type == FLT_LDOUBLE) { INIT_FP_DENORM(long double, LDBL_MANT_DIG, src_size, src_nbits, sendian, dst_size, buf, saved, @@ -3037,7 +3033,7 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) } else if (src_type == FLT_DOUBLE) { INIT_FP_SPECIAL(src_size, src_nbits, sendian, DBL_MANT_DIG, dst_size, buf, saved, nelmts); -#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE && H5_SIZEOF_LONG_DOUBLE != 0 +#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE } else if (src_type == FLT_LDOUBLE) { INIT_FP_SPECIAL(src_size, src_nbits, sendian, LDBL_MANT_DIG, dst_size, buf, saved, nelmts); @@ -3059,7 +3055,7 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) for (j = 0; j < nelmts; j++) { underflow = 0; hw_f = 911.0F; - hw_d = 911.0F; + hw_d = 911.0; #if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE hw_ld = 911.0L; #endif @@ -3108,14 +3104,14 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) if (FLT_FLOAT == dst_type) { hw_f = (float)*((long double *)aligned); hw = (unsigned char *)&hw_f; - underflow = HDfabsl(*((long double *)aligned)) < FLT_MIN; - overflow = HDfabsl(*((long double *)aligned)) > FLT_MAX; + underflow = HDfabsl(*((long double *)aligned)) < (long double)FLT_MIN; + overflow = HDfabsl(*((long double *)aligned)) > (long double)FLT_MAX; } else if (FLT_DOUBLE == dst_type) { hw_d = (double)*((long double *)aligned); hw = (unsigned char *)&hw_d; - underflow = HDfabsl(*((long double *)aligned)) < DBL_MIN; - overflow = HDfabsl(*((long double *)aligned)) > DBL_MAX; + underflow = HDfabsl(*((long double *)aligned)) < (long double)DBL_MIN; + overflow = HDfabsl(*((long double *)aligned)) > (long double)DBL_MAX; } else { hw_ld = *((long double *)aligned); @@ -3133,7 +3129,6 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) * last few unused bytes may have garbage in them. Clean them out with * 0s before compare the values. */ -#if H5_SIZEOF_LONG_DOUBLE != 0 if (sendian == H5T_ORDER_LE && dst_type == FLT_LDOUBLE) { size_t q; @@ -3142,7 +3137,6 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) hw[q] = 0x00; } } -#endif /* Are the two results the same? */ for (k = (dst_size - (dst_nbits / 8)); k < dst_size; k++) @@ -3163,7 +3157,7 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) else if (FLT_DOUBLE == dst_type && my_isnan(dst_type, buf + j * sizeof(double)) && my_isnan(dst_type, hw)) { continue; -#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE && H5_SIZEOF_LONG_DOUBLE != 0 +#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE } else if (FLT_LDOUBLE == dst_type && my_isnan(dst_type, buf + j * sizeof(long double)) && my_isnan(dst_type, hw)) { @@ -3204,8 +3198,8 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) if (overflow && my_isinf(dendian, buf + j * sizeof(float), dst_size, dst_mpos, dst_msize, dst_epos, dst_esize)) continue; /* all overflowed, no error */ - check_mant[0] = HDfrexpf(x, check_expo + 0); - check_mant[1] = HDfrexpf(hw_f, check_expo + 1); + check_mant[0] = (double)HDfrexpf(x, check_expo + 0); + check_mant[1] = (double)HDfrexpf(hw_f, check_expo + 1); } else if (FLT_DOUBLE == dst_type) { double x = 0.0; @@ -3217,10 +3211,10 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) continue; /* all overflowed, no error */ check_mant[0] = HDfrexp(x, check_expo + 0); check_mant[1] = HDfrexp(hw_d, check_expo + 1); -#if H5_SIZEOF_LONG_DOUBLE != 0 && (H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE) +#if (H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE) } else { - long double x = 0.0; + long double x = 0.0L; HDmemcpy(&x, &buf[j * dst_size], sizeof(long double)); /* dst is largest float, no need to check underflow. */ check_mant[0] = (double)HDfrexpl(x, check_expo + 0); @@ -3278,7 +3272,7 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) #if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE } else { - long double x = 0.0; + long double x = 0.0L; HDmemcpy(&x, &saved[j * src_size], sizeof(long double)); HDfprintf(stdout, " %29.20Le\n", x); #endif @@ -3300,7 +3294,7 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) #if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE } else { - long double x = 0.0; + long double x = 0.0L; HDmemcpy(&x, &buf[j * dst_size], sizeof(long double)); HDfprintf(stdout, " %29.20Le\n", x); #endif @@ -3506,7 +3500,7 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) else if (H5Tequal(src, H5T_NATIVE_DOUBLE)) { src_type_name = "double"; src_type = FLT_DOUBLE; -#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE && H5_SIZEOF_LONG_DOUBLE != 0 +#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE } else if (H5Tequal(src, H5T_NATIVE_LDOUBLE)) { src_type_name = "long double"; @@ -3566,7 +3560,7 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) else if (H5Tequal(dst, H5T_NATIVE_DOUBLE)) { dst_type_name = "double"; dst_type = FLT_DOUBLE; -#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE && H5_SIZEOF_LONG_DOUBLE != 0 +#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE } else if (H5Tequal(dst, H5T_NATIVE_LDOUBLE)) { dst_type_name = "long double"; @@ -3590,11 +3584,7 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) if ((INT_SCHAR == src_type || INT_UCHAR == src_type || INT_SHORT == src_type || INT_USHORT == src_type || INT_INT == src_type || INT_UINT == src_type || INT_LONG == src_type || INT_ULONG == src_type || INT_LLONG == src_type || INT_ULLONG == src_type) && - (FLT_FLOAT != dst_type && FLT_DOUBLE != dst_type -#if H5_SIZEOF_LONG_DOUBLE != 0 - && FLT_LDOUBLE != dst_type -#endif - )) { + (FLT_FLOAT != dst_type && FLT_DOUBLE != dst_type && FLT_LDOUBLE != dst_type)) { HDsnprintf(str, sizeof(str), "Testing %s %s -> %s conversions", name, src_type_name, dst_type_name); HDprintf("%-70s", str); H5_FAILED(); @@ -3602,11 +3592,7 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) goto error; } - if ((FLT_FLOAT == src_type || FLT_DOUBLE == src_type -#if H5_SIZEOF_LONG_DOUBLE != 0 - || FLT_LDOUBLE == src_type -#endif - ) && + if ((FLT_FLOAT == src_type || FLT_DOUBLE == src_type || FLT_LDOUBLE == src_type) && (INT_SCHAR != dst_type && INT_UCHAR != dst_type && INT_SHORT != dst_type && INT_USHORT != dst_type && INT_INT != dst_type && INT_UINT != dst_type && INT_LONG != dst_type && INT_ULONG != dst_type && INT_LLONG != dst_type && INT_ULLONG != dst_type)) { @@ -3738,7 +3724,7 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) else { INIT_FP_SPECIAL(src_size, src_nbits, sendian, DBL_MANT_DIG, dst_size, buf, saved, nelmts); } -#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE && H5_SIZEOF_LONG_DOUBLE != 0 +#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE } else if (src_type == FLT_LDOUBLE) { if (run_test == TEST_NORMAL) { @@ -3763,11 +3749,7 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) /* Check the results from the library against hardware */ for (j = 0; j < nelmts; j++) { - if (FLT_FLOAT == src_type || FLT_DOUBLE == src_type -#if H5_SIZEOF_LONG_DOUBLE != 0 - || FLT_LDOUBLE == src_type -#endif - ) + if (FLT_FLOAT == src_type || FLT_DOUBLE == src_type || FLT_LDOUBLE == src_type) if (my_isnan(src_type, saved + j * src_size)) continue; @@ -3874,7 +3856,6 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) HDassert(0 && "Unknown type"); break; } -#if H5_SIZEOF_LONG_DOUBLE != 0 } else if (FLT_LDOUBLE == dst_type) { hw = (unsigned char *)&hw_ldouble; @@ -3927,7 +3908,6 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) HDassert(0 && "Unknown type"); break; } -#endif } else if (INT_SCHAR == dst_type) { hw = (unsigned char *)&hw_schar; @@ -3940,12 +3920,10 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) HDmemcpy(aligned, saved + j * sizeof(double), sizeof(double)); hw_schar = (signed char)(*((double *)aligned)); break; -#if H5_SIZEOF_LONG_DOUBLE != 0 case FLT_LDOUBLE: HDmemcpy(aligned, saved + j * sizeof(long double), sizeof(long double)); hw_schar = (signed char)(*((long double *)aligned)); break; -#endif case INT_SCHAR: case INT_UCHAR: case INT_SHORT: @@ -3973,12 +3951,10 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) HDmemcpy(aligned, saved + j * sizeof(double), sizeof(double)); hw_uchar = (unsigned char)(*((double *)aligned)); break; -#if H5_SIZEOF_LONG_DOUBLE != 0 case FLT_LDOUBLE: HDmemcpy(aligned, saved + j * sizeof(long double), sizeof(long double)); hw_uchar = (unsigned char)(*((long double *)aligned)); break; -#endif case INT_SCHAR: case INT_UCHAR: case INT_SHORT: @@ -4006,12 +3982,10 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) HDmemcpy(aligned, saved + j * sizeof(double), sizeof(double)); hw_short = (short)(*((double *)aligned)); break; -#if H5_SIZEOF_LONG_DOUBLE != 0 case FLT_LDOUBLE: HDmemcpy(aligned, saved + j * sizeof(long double), sizeof(long double)); hw_short = (short)(*((long double *)aligned)); break; -#endif case INT_SCHAR: case INT_UCHAR: case INT_SHORT: @@ -4039,12 +4013,10 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) HDmemcpy(aligned, saved + j * sizeof(double), sizeof(double)); hw_ushort = (unsigned short)(*((double *)aligned)); break; -#if H5_SIZEOF_LONG_DOUBLE != 0 case FLT_LDOUBLE: HDmemcpy(aligned, saved + j * sizeof(long double), sizeof(long double)); hw_ushort = (unsigned short)(*((long double *)aligned)); break; -#endif case INT_SCHAR: case INT_UCHAR: case INT_SHORT: @@ -4072,12 +4044,10 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) HDmemcpy(aligned, saved + j * sizeof(double), sizeof(double)); hw_int = (int)(*((double *)aligned)); break; -#if H5_SIZEOF_LONG_DOUBLE != 0 case FLT_LDOUBLE: HDmemcpy(aligned, saved + j * sizeof(long double), sizeof(long double)); hw_int = (int)(*((long double *)aligned)); break; -#endif case INT_SCHAR: case INT_UCHAR: case INT_SHORT: @@ -4105,12 +4075,10 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) HDmemcpy(aligned, saved + j * sizeof(double), sizeof(double)); hw_uint = (unsigned int)(*((double *)aligned)); break; -#if H5_SIZEOF_LONG_DOUBLE != 0 case FLT_LDOUBLE: HDmemcpy(aligned, saved + j * sizeof(long double), sizeof(long double)); hw_uint = (unsigned int)(*((long double *)aligned)); break; -#endif case INT_SCHAR: case INT_UCHAR: case INT_SHORT: @@ -4138,12 +4106,10 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) HDmemcpy(aligned, saved + j * sizeof(double), sizeof(double)); hw_long = (long)(*((double *)aligned)); break; -#if H5_SIZEOF_LONG_DOUBLE != 0 case FLT_LDOUBLE: HDmemcpy(aligned, saved + j * sizeof(long double), sizeof(long double)); hw_long = (long)(*((long double *)aligned)); break; -#endif case INT_SCHAR: case INT_UCHAR: case INT_SHORT: @@ -4171,12 +4137,10 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) HDmemcpy(aligned, saved + j * sizeof(double), sizeof(double)); hw_ulong = (unsigned long)(*((double *)aligned)); break; -#if H5_SIZEOF_LONG_DOUBLE != 0 case FLT_LDOUBLE: HDmemcpy(aligned, saved + j * sizeof(long double), sizeof(long double)); hw_ulong = (unsigned long)(*((long double *)aligned)); break; -#endif case INT_SCHAR: case INT_UCHAR: case INT_SHORT: @@ -4204,12 +4168,10 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) HDmemcpy(aligned, saved + j * sizeof(double), sizeof(double)); hw_llong = (long long)(*((double *)aligned)); break; -#if H5_SIZEOF_LONG_DOUBLE != 0 case FLT_LDOUBLE: HDmemcpy(aligned, saved + j * sizeof(long double), sizeof(long double)); hw_llong = (long long)(*((long double *)aligned)); break; -#endif case INT_SCHAR: case INT_UCHAR: case INT_SHORT: @@ -4237,12 +4199,10 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) HDmemcpy(aligned, saved + j * sizeof(double), sizeof(double)); hw_ullong = (unsigned long long)(*((double *)aligned)); break; -#if H5_SIZEOF_LONG_DOUBLE != 0 case FLT_LDOUBLE: HDmemcpy(aligned, saved + j * sizeof(long double), sizeof(long double)); hw_ullong = (unsigned long long)(*((long double *)aligned)); break; -#endif case INT_SCHAR: case INT_UCHAR: case INT_SHORT: @@ -4269,14 +4229,12 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) * bytes may have garbage in them. Clean them out with 0s before compare * the values. */ -#if H5_SIZEOF_LONG_DOUBLE != 0 if (dendian == H5T_ORDER_LE && dst_type == FLT_LDOUBLE) { size_t q; for (q = dst_nbits / 8; q < dst_size; q++) buf[j * dst_size + q] = 0x00; } -#endif /* Are the two results the same? */ for (k = (dst_size - (dst_nbits / 8)); k < dst_size; k++) @@ -4315,11 +4273,7 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) * Try to follow the except_func callback function to check if the * desired value was set. */ - if ((FLT_FLOAT == src_type || FLT_DOUBLE == src_type -#if H5_SIZEOF_LONG_DOUBLE != 0 - || FLT_LDOUBLE == src_type -#endif - ) && + if ((FLT_FLOAT == src_type || FLT_DOUBLE == src_type || FLT_LDOUBLE == src_type) && (INT_SCHAR == dst_type || INT_SHORT == dst_type || INT_INT == dst_type || INT_LONG == dst_type || INT_LLONG == dst_type)) { if (0 == H5T__bit_get_d(src_bits, src_nbits - 1, (size_t)1) && @@ -4359,11 +4313,7 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) } } - if ((FLT_FLOAT == src_type || FLT_DOUBLE == src_type -#if H5_SIZEOF_LONG_DOUBLE != 0 - || FLT_LDOUBLE == src_type -#endif - ) && + if ((FLT_FLOAT == src_type || FLT_DOUBLE == src_type || FLT_LDOUBLE == src_type) && (INT_UCHAR == dst_type || INT_USHORT == dst_type || INT_UINT == dst_type || INT_ULONG == dst_type || INT_ULLONG == dst_type)) { if (H5T__bit_get_d(src_bits, src_nbits - 1, (size_t)1)) { @@ -4462,12 +4412,10 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) HDmemcpy(aligned, saved + j * sizeof(double), sizeof(double)); HDprintf(" %29f\n", *((double *)aligned)); break; -#if H5_SIZEOF_LONG_DOUBLE != 0 case FLT_LDOUBLE: HDmemcpy(aligned, saved + j * sizeof(long double), sizeof(long double)); HDprintf(" %29Lf\n", *((long double *)aligned)); break; -#endif case OTHER: default: HDassert(0 && "Unknown type"); @@ -4527,12 +4475,10 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) HDmemcpy(aligned, buf + j * sizeof(double), sizeof(double)); HDprintf(" %29f\n", *((double *)aligned)); break; -#if H5_SIZEOF_LONG_DOUBLE != 0 case FLT_LDOUBLE: HDmemcpy(aligned, buf + j * sizeof(long double), sizeof(long double)); HDprintf(" %29Lf\n", *((long double *)aligned)); break; -#endif case OTHER: default: HDassert(0 && "Unknown type"); @@ -4580,11 +4526,9 @@ test_conv_int_fp(const char *name, int run_test, hid_t src, hid_t dst) case FLT_DOUBLE: HDprintf(" %29f\n", *((double *)((void *)hw))); break; -#if H5_SIZEOF_LONG_DOUBLE != 0 case FLT_LDOUBLE: HDprintf(" %29Lf\n", *((long double *)((void *)hw))); break; -#endif case OTHER: default: HDassert(0 && "Unknown type"); @@ -4923,16 +4867,14 @@ run_fp_tests(const char *name) if (!HDstrcmp(name, "noop")) { nerrors += test_conv_flt_1("noop", TEST_NOOP, H5T_NATIVE_FLOAT, H5T_NATIVE_FLOAT); nerrors += test_conv_flt_1("noop", TEST_NOOP, H5T_NATIVE_DOUBLE, H5T_NATIVE_DOUBLE); -#if H5_SIZEOF_LONG_DOUBLE != 0 nerrors += test_conv_flt_1("noop", TEST_NOOP, H5T_NATIVE_LDOUBLE, H5T_NATIVE_LDOUBLE); -#endif goto done; } /*Test normalized values. TEST_NORMAL indicates normalized values.*/ nerrors += test_conv_flt_1(name, TEST_NORMAL, H5T_NATIVE_FLOAT, H5T_NATIVE_DOUBLE); nerrors += test_conv_flt_1(name, TEST_NORMAL, H5T_NATIVE_DOUBLE, H5T_NATIVE_FLOAT); -#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE && H5_SIZEOF_LONG_DOUBLE != 0 +#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE nerrors += test_conv_flt_1(name, TEST_NORMAL, H5T_NATIVE_FLOAT, H5T_NATIVE_LDOUBLE); nerrors += test_conv_flt_1(name, TEST_NORMAL, H5T_NATIVE_DOUBLE, H5T_NATIVE_LDOUBLE); nerrors += test_conv_flt_1(name, TEST_NORMAL, H5T_NATIVE_LDOUBLE, H5T_NATIVE_FLOAT); @@ -4942,7 +4884,7 @@ run_fp_tests(const char *name) /*Test denormalized values. TEST_DENORM indicates denormalized values.*/ nerrors += test_conv_flt_1(name, TEST_DENORM, H5T_NATIVE_FLOAT, H5T_NATIVE_DOUBLE); nerrors += test_conv_flt_1(name, TEST_DENORM, H5T_NATIVE_DOUBLE, H5T_NATIVE_FLOAT); -#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE && H5_SIZEOF_LONG_DOUBLE != 0 +#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE nerrors += test_conv_flt_1(name, TEST_DENORM, H5T_NATIVE_FLOAT, H5T_NATIVE_LDOUBLE); nerrors += test_conv_flt_1(name, TEST_DENORM, H5T_NATIVE_DOUBLE, H5T_NATIVE_LDOUBLE); #ifndef H5_DISABLE_SOME_LDOUBLE_CONV @@ -4955,11 +4897,7 @@ run_fp_tests(const char *name) "float"); HDprintf("%-70s", str); SKIPPED(); -#if H5_SIZEOF_LONG_DOUBLE != 0 HDputs(" Test skipped due to the conversion problem on IBM ppc64le cpu."); -#else - HDputs(" Test skipped due to disabled long double."); -#endif } #endif @@ -4969,7 +4907,7 @@ run_fp_tests(const char *name) /*Test special values, +/-0, +/-infinity, +/-QNaN, +/-SNaN.*/ nerrors += test_conv_flt_1(name, TEST_SPECIAL, H5T_NATIVE_FLOAT, H5T_NATIVE_DOUBLE); nerrors += test_conv_flt_1(name, TEST_SPECIAL, H5T_NATIVE_DOUBLE, H5T_NATIVE_FLOAT); -#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE && H5_SIZEOF_LONG_DOUBLE != 0 +#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE nerrors += test_conv_flt_1(name, TEST_SPECIAL, H5T_NATIVE_FLOAT, H5T_NATIVE_LDOUBLE); nerrors += test_conv_flt_1(name, TEST_SPECIAL, H5T_NATIVE_DOUBLE, H5T_NATIVE_LDOUBLE); #ifndef H5_DISABLE_SOME_LDOUBLE_CONV @@ -4983,11 +4921,7 @@ run_fp_tests(const char *name) "float or double"); HDprintf("%-70s", str); SKIPPED(); -#if H5_SIZEOF_LONG_DOUBLE != 0 HDputs(" Test skipped due to the conversion problem on IBM ppc64le cpu."); -#else - HDputs(" Test skipped due to disabled long double."); -#endif } #endif #endif @@ -5068,11 +5002,7 @@ run_int_fp_conv(const char *name) "long double"); HDprintf("%-70s", str); SKIPPED(); -#if H5_SIZEOF_LONG_DOUBLE != 0 HDputs(" Test skipped due to the special algorithm of hardware conversion."); -#else - HDputs(" Test skipped due to disabled long double."); -#endif } #endif #endif /* H5_SIZEOF_LONG!=H5_SIZEOF_INT */ @@ -5193,14 +5123,10 @@ run_fp_int_conv(const char *name) "signed and unsigned char, short, int, long"); HDprintf("%-70s", str); SKIPPED(); -#if H5_SIZEOF_LONG_DOUBLE != 0 HDputs(" Test skipped due to the conversion problem on IBM ppc64le cpu."); -#else - HDputs(" Test skipped due to disabled long double."); -#endif #endif } -#if H5_SIZEOF_LONG != H5_SIZEOF_INT && H5_SIZEOF_LONG_DOUBLE != 0 +#if H5_SIZEOF_LONG != H5_SIZEOF_INT #ifndef H5_LDOUBLE_TO_LONG_SPECIAL if (test_values != TEST_SPECIAL && test_values != TEST_NORMAL) { nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_LONG); @@ -5220,35 +5146,27 @@ run_fp_int_conv(const char *name) "(unsigned) long"); HDprintf("%-70s", str); SKIPPED(); -#if H5_SIZEOF_LONG_DOUBLE != 0 HDputs(" Test skipped due to the special algorithm of hardware conversion."); -#else - HDputs(" Test skipped due to disabled long double."); -#endif } #endif -#endif /*H5_SIZEOF_LONG!=H5_SIZEOF_INT && H5_SIZEOF_LONG_DOUBLE!=0 */ +#endif /*H5_SIZEOF_LONG!=H5_SIZEOF_INT */ -#if H5_SIZEOF_LONG_LONG != H5_SIZEOF_LONG && H5_SIZEOF_LONG_DOUBLE != 0 +#if H5_SIZEOF_LONG_LONG != H5_SIZEOF_LONG #ifdef H5_LDOUBLE_TO_LLONG_ACCURATE nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_LLONG); -#else /*H5_LDOUBLE_TO_LLONG_ACCURATE*/ +#else /*H5_LDOUBLE_TO_LLONG_ACCURATE*/ { char str[256]; /*string */ HDsnprintf(str, sizeof(str), "Testing %s %s -> %s conversions", name, "long double", "long long"); HDprintf("%-70s", str); SKIPPED(); -#if H5_SIZEOF_LONG_DOUBLE != 0 HDputs(" Test skipped due to hardware conversion error."); -#else - HDputs(" Test skipped due to disabled long double."); -#endif } #endif /*H5_LDOUBLE_TO_LLONG_ACCURATE*/ #if defined(H5_LDOUBLE_TO_LLONG_ACCURATE) nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_ULLONG); -#else /*H5_LDOUBLE_TO_LLONG_ACCURATE*/ +#else /*H5_LDOUBLE_TO_LLONG_ACCURATE*/ { char str[256]; /*string */ @@ -5256,11 +5174,7 @@ run_fp_int_conv(const char *name) "unsigned long long"); HDprintf("%-70s", str); SKIPPED(); -#if H5_SIZEOF_LONG_DOUBLE != 0 HDputs(" Test skipped due to hardware conversion error."); -#else - HDputs(" Test skipped due to disabled long double."); -#endif } #endif /*H5_LDOUBLE_TO_LLONG_ACCURATE*/ #endif diff --git a/test/dtransform.c b/test/dtransform.c index 743103f..50c33ee 100644 --- a/test/dtransform.c +++ b/test/dtransform.c @@ -357,9 +357,7 @@ main(void) TEST_TYPE_CONTIG(dxpl_id_utrans_inv, unsigned long long, H5T_NATIVE_ULLONG, "ullong", transformData, 0); TEST_TYPE_CONTIG(dxpl_id_c_to_f, float, H5T_NATIVE_FLOAT, "float", windchillFfloat, 1); TEST_TYPE_CONTIG(dxpl_id_c_to_f, double, H5T_NATIVE_DOUBLE, "double", windchillFfloat, 1); -#if H5_SIZEOF_LONG_DOUBLE != 0 TEST_TYPE_CONTIG(dxpl_id_c_to_f, long double, H5T_NATIVE_LDOUBLE, "ldouble", windchillFfloat, 1); -#endif TEST_TYPE_CHUNK(dxpl_id_utrans_inv, char, H5T_NATIVE_CHAR, "char", transformData, 0); TEST_TYPE_CHUNK(dxpl_id_utrans_inv, unsigned char, H5T_NATIVE_UCHAR, "uchar", transformData, 0); @@ -374,9 +372,7 @@ main(void) TEST_TYPE_CHUNK(dxpl_id_utrans_inv, unsigned long long, H5T_NATIVE_ULLONG, "ullong", transformData, 0); TEST_TYPE_CHUNK(dxpl_id_c_to_f, float, H5T_NATIVE_FLOAT, "float", windchillFfloat, 1); TEST_TYPE_CHUNK(dxpl_id_c_to_f, double, H5T_NATIVE_DOUBLE, "double", windchillFfloat, 1); -#if H5_SIZEOF_LONG_DOUBLE != 0 TEST_TYPE_CHUNK(dxpl_id_c_to_f, long double, H5T_NATIVE_LDOUBLE, "ldouble", windchillFfloat, 1); -#endif if (test_copy(dxpl_id_c_to_f_copy, dxpl_id_polynomial_copy) < 0) TEST_ERROR; diff --git a/test/dtypes.c b/test/dtypes.c index 8b3101c..f9b4e8c 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -160,10 +160,8 @@ reset_hdf5(void) SET_ALIGNMENT(ULLONG, H5_SIZEOF_LONG_LONG); SET_ALIGNMENT(FLOAT, H5_SIZEOF_FLOAT); SET_ALIGNMENT(DOUBLE, H5_SIZEOF_DOUBLE); -#if H5_SIZEOF_LONG_DOUBLE != 0 SET_ALIGNMENT(LDOUBLE, H5_SIZEOF_LONG_DOUBLE); #endif -#endif } /*------------------------------------------------------------------------- diff --git a/test/filter_plugin.c b/test/filter_plugin.c index 276141a..c373b3b 100644 --- a/test/filter_plugin.c +++ b/test/filter_plugin.c @@ -1305,6 +1305,102 @@ error: } /* end test_path_api_calls() */ /*------------------------------------------------------------------------- + * Function: test_filter_numbers + * + * Purpose: Tests the filter numbers are handled correctly + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +test_filter_numbers(void) +{ + hid_t dcpl_id = H5I_INVALID_HID; + H5Z_filter_t id; + herr_t status = SUCCEED; + size_t nelmts = 0; + unsigned int flags; + unsigned int filter_config; + + HDputs("Testing filter number handling"); + + /* Check that out-of-range filter numbers are handled correctly */ + TESTING(" Filter # out of range"); + + /* Create property list */ + if ((dcpl_id = H5Pcreate(H5P_DATASET_CREATE)) < 0) + TEST_ERROR; + + nelmts = 0; + + /* Test id > H5Z_FILTER_MAX and < 0, current version */ + + H5E_BEGIN_TRY + { + id = H5Z_FILTER_MAX + 1; + status = H5Pget_filter_by_id2(dcpl_id, id, &flags, &nelmts, NULL, 0, NULL, &filter_config); + } + H5E_END_TRY; + + /* Should fail */ + if (status != FAIL) + TEST_ERROR; + + H5E_BEGIN_TRY + { + id = -1; + status = H5Pget_filter_by_id2(dcpl_id, id, &flags, &nelmts, NULL, 0, NULL, &filter_config); + } + H5E_END_TRY; + + /* Should fail */ + if (status != FAIL) + TEST_ERROR; + + /* Test id > H5Z_FILTER_MAX and < 0, deprecated version */ + +#ifndef H5_NO_DEPRECATED_SYMBOLS + H5E_BEGIN_TRY + { + id = H5Z_FILTER_MAX + 1; + status = H5Pget_filter_by_id1(dcpl_id, id, &flags, &nelmts, NULL, 0, NULL); + } + H5E_END_TRY; + + /* Should fail */ + if (status != FAIL) + TEST_ERROR; + + H5E_BEGIN_TRY + { + id = -1; + status = H5Pget_filter_by_id1(dcpl_id, id, &flags, &nelmts, NULL, 0, NULL); + } + H5E_END_TRY; + + /* Should fail */ + if (status != FAIL) + TEST_ERROR; +#endif + + if (H5Pclose(dcpl_id) < 0) + TEST_ERROR; + + PASSED(); + + return SUCCEED; + +error: + H5E_BEGIN_TRY + { + H5Pclose(dcpl_id); + } + H5E_END_TRY; + return FAIL; +} /* end test_filter_numbers() */ + +/*------------------------------------------------------------------------- * Function: disable_chunk_cache * * Purpose: Turns the chunk cache off @@ -1523,6 +1619,9 @@ main(void) /* Test the APIs for access to the filter plugin path table */ nerrors += (test_path_api_calls() < 0 ? 1 : 0); + /* Test filter numbers */ + nerrors += (test_filter_numbers() < 0 ? 1 : 0); + if (nerrors) TEST_ERROR; diff --git a/test/objcopy.c b/test/objcopy.c index e01083d..9aae621 100644 --- a/test/objcopy.c +++ b/test/objcopy.c @@ -11092,7 +11092,7 @@ test_copy_dataset_contig_cmpd_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, buf[i].b.p = (int *)HDmalloc(buf[i].b.len * sizeof(int)); for (j = 0; j < buf[i].b.len; j++) ((int *)buf[i].b.p)[j] = (int)(i * 10 + j); - buf[i].c = 1.0F / ((float)i + 1.0F); + buf[i].c = 1.0 / ((double)i + 1.0); } /* end for */ /* Initialize the filenames */ @@ -11268,7 +11268,7 @@ test_copy_dataset_chunked_cmpd_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl buf[i].b.p = (int *)HDmalloc(buf[i].b.len * sizeof(int)); for (j = 0; j < buf[i].b.len; j++) ((int *)buf[i].b.p)[j] = (int)(i * 10 + j); - buf[i].c = 1.0F / ((float)i + 1.0F); + buf[i].c = 1.0 / ((double)i + 1.0); } /* end for */ /* Initialize the filenames */ @@ -11453,7 +11453,7 @@ test_copy_dataset_compact_cmpd_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl buf[i].b.p = (int *)HDmalloc(buf[i].b.len * sizeof(int)); for (j = 0; j < buf[i].b.len; j++) ((int *)buf[i].b.p)[j] = (int)(i * 10 + j); - buf[i].c = 1.0F / ((float)i + 1.0F); + buf[i].c = 1.0 / ((double)i + 1.0); } /* end for */ /* Initialize the filenames */ diff --git a/test/swmr.c b/test/swmr.c index 24a0b7c..9091fe2 100644 --- a/test/swmr.c +++ b/test/swmr.c @@ -5220,7 +5220,7 @@ test_file_lock_swmr_concur(hid_t H5_ATTR_UNUSED in_fapl) static int test_file_lock_swmr_concur(hid_t in_fapl) { - hid_t fid; /* File ID */ + hid_t fid = H5I_INVALID_HID; /* File ID */ hid_t fapl; /* File access property list */ char filename[NAME_BUF_SIZE]; /* file name */ pid_t childpid = 0; /* Child process ID */ @@ -6721,7 +6721,7 @@ test_refresh_concur(hid_t H5_ATTR_UNUSED in_fapl, hbool_t new_format) static int test_refresh_concur(hid_t in_fapl, hbool_t new_format) { - hid_t fid; /* File ID */ + hid_t fid = H5I_INVALID_HID; /* File ID */ hid_t fapl; /* File access property list */ pid_t childpid = 0; /* Child process ID */ pid_t tmppid; /* Child process ID returned by waitpid */ diff --git a/test/tconfig.c b/test/tconfig.c index 101de9a..8bd625f 100644 --- a/test/tconfig.c +++ b/test/tconfig.c @@ -114,30 +114,14 @@ test_config_ctypes(void) vrfy_cint_type(long, unsigned long, H5_SIZEOF_LONG); vrfy_ctype(float, H5_SIZEOF_FLOAT); vrfy_ctype(double, H5_SIZEOF_DOUBLE); -#if H5_SIZEOF_LONG_DOUBLE > 0 vrfy_ctype(long double, H5_SIZEOF_LONG_DOUBLE); -#endif /* standard C99 basic types */ -#if H5_SIZEOF_LONG_LONG > 0 vrfy_cint_type(long long, unsigned long long, H5_SIZEOF_LONG_LONG); -#endif - -#if H5_SIZEOF_INT8_T > 0 vrfy_cint_type(int8_t, uint8_t, H5_SIZEOF_INT8_T); -#endif - -#if H5_SIZEOF_INT16_T > 0 vrfy_cint_type(int16_t, uint16_t, H5_SIZEOF_INT16_T); -#endif - -#if H5_SIZEOF_INT32_T > 0 vrfy_cint_type(int32_t, uint32_t, H5_SIZEOF_INT32_T); -#endif - -#if H5_SIZEOF_INT64_T > 0 vrfy_cint_type(int64_t, uint64_t, H5_SIZEOF_INT64_T); -#endif /* Some vendors have different sizes for the signed and unsigned */ /* fast8_t. Need to check them individually. */ diff --git a/test/testmeta.c b/test/testmeta.c index c59c6cb..7cb3000 100644 --- a/test/testmeta.c +++ b/test/testmeta.c @@ -195,7 +195,7 @@ main(void) start[0] = 0; status = H5Sselect_hyperslab(memspace_id, H5S_SELECT_SET, start, stride, count, NULL); - start[0] = (hssize_t)j; + start[0] = (hsize_t)j; status = H5Sselect_hyperslab(dataspace_id, H5S_SELECT_SET, start, stride, count, NULL); status = H5Dwrite(dataset_id, type_id, memspace_id, dataspace_id, H5P_DEFAULT, &floatval); if (status < 0) { diff --git a/test/tskiplist.c b/test/tskiplist.c index 4bf9b11..31b5cff 100644 --- a/test/tskiplist.c +++ b/test/tskiplist.c @@ -1165,213 +1165,6 @@ test_skiplist_free(void) /**************************************************************** ** -** test_skiplist_try_free_safe(): Test H5SL (skip list) code. -** Tests 'try_free_safe' operation in skip lists. -** -****************************************************************/ -/* Macro definitions */ -#define TEST_TFS_MAX_NOBJS 100 -#define TEST_TFS_MIN_NOBJS 5 -#define TEST_TFS_NITER 50 - -/* Structure to hold the list of objects */ -typedef struct { - H5SL_t * slist; /* Skiplist holding the objects */ - struct test_tfs_obj_t *list; /* Linear list of objects */ - int nobjs; /* Number of objects in list */ - int nobjs_rem; /* Number of objects in list that have not been freed */ -} test_tfs_list_t; - -/* Structure for an object */ -typedef struct test_tfs_obj_t { - int idx; /* Index (key) for this object */ - int nfrees; /* Number of times this object has been freed */ -} test_tfs_obj_t; - -/* op_data struct for H5SL_iterate() */ -typedef struct test_tfs_it_ud_t { - test_tfs_list_t *obj_list; /* List of objects */ - int last_idx; /* Index of last object visited in iteration */ - int ncalls; /* Number of times this callback was called */ -} test_tfs_it_ud_t; - -/* iterate callback */ -static herr_t -test_tfs_iter(void *_obj, void *key, void *_udata) -{ - test_tfs_obj_t * obj = (test_tfs_obj_t *)_obj; - test_tfs_it_ud_t *udata = (test_tfs_it_ud_t *)_udata; - - /* Check consistency */ - CHECK_PTR_EQ((void *)&obj->idx, key, "obj->idx"); - CHECK_PTR_EQ(obj, &udata->obj_list->list[obj->idx], "obj_list->list[obj->idx]"); - - /* Increment number of calls */ - udata->ncalls++; - - /* Verify we were given the correct object */ - do { - udata->last_idx++; - } while (udata->obj_list->list[udata->last_idx].nfrees != 0); - VERIFY(udata->last_idx, obj->idx, "H5SL_iterate"); - - return 0; -} /* end test_tfs_iter() */ - -/* try_free_safe callback */ -static htri_t -test_tfs_free(void *_obj, void *key, void *_obj_list) -{ - test_tfs_obj_t * obj = (test_tfs_obj_t *)_obj; - test_tfs_list_t *obj_list = (test_tfs_list_t *)_obj_list; - test_tfs_it_ud_t iter_ud; - int nrems, rem_idx, i, j; - test_tfs_obj_t * obj_ret; - herr_t ret; /* return value */ - htri_t ret_value; - - /* Check consistency */ - CHECK_PTR_EQ((void *)&obj->idx, key, "obj->idx"); - CHECK_PTR_EQ(obj, &obj_list->list[obj->idx], "obj_list->list[obj->idx]"); - - /* Mark this object as freed (to make sure it isn't recursively freed, that - * is not something we support, we will undo this if we decide later not to - * free the object) */ - obj->nfrees++; - obj_list->nobjs_rem--; - - /* Decide how many objects to remove */ - nrems = (int)(HDrandom() % (long)3); - - /* Remove objects */ - for (i = 0; i < nrems; i++) - /* Check nobjs_rem */ - if (obj_list->nobjs_rem > 0) { - /* Remove a random object from the list */ - rem_idx = (int)(HDrandom() % (long)obj_list->nobjs_rem); - - /* Scan the list, finding the rem_idx'th object that has not been - * freed */ - for (j = 0; j < obj_list->nobjs; j++) - if (obj_list->list[j].nfrees == 0) { - if (rem_idx == 0) - break; - else - rem_idx--; - } /* end if */ - if (j == obj_list->nobjs) - ERROR("invalid obj_list"); - else { - /* Remove the object */ - obj_ret = (test_tfs_obj_t *)H5SL_remove(obj_list->slist, &j); - CHECK_PTR(obj_ret, "H5SL_remove"); - obj_ret->nfrees++; - obj_list->nobjs_rem--; - } /* end else */ - } /* end if */ - - /* Mark this object as not freed so we know to expect it in the iterate call - */ - obj->nfrees--; - obj_list->nobjs_rem++; - - /* Iterate over skip list (maybe) */ - if (HDrandom() % (long)5) { - iter_ud.obj_list = obj_list; - iter_ud.last_idx = -1; - iter_ud.ncalls = 0; - ret = H5SL_iterate(obj_list->slist, test_tfs_iter, &iter_ud); - CHECK(ret, FAIL, "H5SL_iterate"); - VERIFY(iter_ud.ncalls, obj_list->nobjs_rem, "H5SL_iterate"); - } /* end if */ - - /* Verify nobjs_rem is non-negative */ - if (obj_list->nobjs_rem < 0) - ERROR("invalid nobjs_rem"); - - /* Decide whether this object should be freed */ - if (HDrandom() % (long)2) { - /* Free the object */ - ret_value = TRUE; - obj->nfrees++; - obj_list->nobjs_rem--; - } /* end if */ - else - /* Do not free the object */ - ret_value = FALSE; - - return ret_value; -} /* end test_tfs_free() */ - -/* Test function */ -static void -test_skiplist_try_free_safe(void) -{ - test_tfs_list_t obj_list; - test_tfs_obj_t list[TEST_TFS_MAX_NOBJS]; - int i, j; - int nobjs_found; - hsize_t count; - herr_t ret; /* Generic return value */ - - /* Output message about test being performed */ - MESSAGE(7, ("Testing Skip List 'Try Free Safe' Operation\n")); - - /* Create a skip list */ - obj_list.slist = H5SL_create(H5SL_TYPE_INT, NULL); - CHECK_PTR(obj_list.slist, "H5SL_create"); - - /* Init obj_list.list */ - obj_list.list = list; - for (j = 0; j < TEST_TFS_MAX_NOBJS; j++) - list[j].idx = j; - - for (i = 0; i < TEST_TFS_NITER; i++) { - /* Build object list */ - obj_list.nobjs = obj_list.nobjs_rem = - (int)(TEST_TFS_MIN_NOBJS + (HDrandom() % (long)(TEST_TFS_MAX_NOBJS - TEST_TFS_MIN_NOBJS + 1))); - for (j = 0; j < obj_list.nobjs; j++) { - list[j].nfrees = 0; - ret = H5SL_insert(obj_list.slist, &list[j], &list[j].idx); - CHECK(ret, FAIL, "H5SL_insert"); - } /* end for */ - - /* Call H5S_try_free_safe() - free most of the items in the skip list in - * a safe manner */ - ret = H5SL_try_free_safe(obj_list.slist, test_tfs_free, &obj_list); - CHECK(ret, FAIL, "H5SL_try_free_safe"); - - /* Verify list */ - nobjs_found = 0; - for (j = 0; j < obj_list.nobjs; j++) - if (list[j].nfrees == 0) - nobjs_found++; - else - VERIFY(list[j].nfrees, (long)1, "list[j].nfrees"); - - /* Verify number of objects */ - VERIFY(obj_list.nobjs_rem, nobjs_found, "obj_list.nobjs_rem"); - count = H5SL_count(obj_list.slist); - VERIFY(count, (size_t)nobjs_found, "H5SL_count"); - - /* Release the skip list, forcibly freeing all nodes (will not make - * callbacks) */ - ret = H5SL_release(obj_list.slist); - CHECK(ret, FAIL, "H5SL_release"); - - /* Verify number of objects is 0 */ - count = H5SL_count(obj_list.slist); - VERIFY(count, (size_t)0, "H5SL_count"); - } /* end for */ - - /* Close the skip list */ - ret = H5SL_close(obj_list.slist); - CHECK(ret, FAIL, "H5SL_close"); - -} /* end test_skiplist_try_free_safe() */ - -/**************************************************************** -** ** test_skiplist_less(): Test H5SL (skip list) code. ** Tests 'less' operation in skip lists. ** @@ -1796,7 +1589,6 @@ test_skiplist(void) test_skiplist_add(); /* Test 'add' operation */ test_skiplist_destroy(); /* Test 'destroy' operation */ test_skiplist_free(); /* Test 'free' operation */ - test_skiplist_try_free_safe(); /* Test 'try_free_safe' operation */ test_skiplist_less(); /* Test 'less' operation */ test_skiplist_greater(); /* Test 'greater' operation */ test_skiplist_below(); /* Test 'below' operation */ diff --git a/test/tunicode.c b/test/tunicode.c index 1b696ac..7d4dba6 100644 --- a/test/tunicode.c +++ b/test/tunicode.c @@ -34,7 +34,7 @@ #define RANK 1 #define COMP_INT_VAL 7 #define COMP_FLOAT_VAL (-42.0F) -#define COMP_DOUBLE_VAL 42.0F +#define COMP_DOUBLE_VAL 42.0 /* Test function prototypes */ void test_fl_string(hid_t fid, const char *string); diff --git a/test/tvlstr.c b/test/tvlstr.c index 7e47c7b..68f6124 100644 --- a/test/tvlstr.c +++ b/test/tvlstr.c @@ -293,7 +293,7 @@ test_vlstrings_special(void) /* Check data read in */ for (i = 0; i < SPACE1_DIM1; i++) if (rdata[i] != NULL) - TestErrPrintf("VL doesn't match!, rdata[%d]=%p\n", (int)i, rdata[i]); + TestErrPrintf("VL doesn't match!, rdata[%d]=%s\n", (int)i, rdata[i]); /* Write dataset to disk */ ret = H5Dwrite(dataset, tid1, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata); @@ -352,7 +352,7 @@ test_vlstrings_special(void) /* Check data read in */ for (i = 0; i < SPACE1_DIM1; i++) if (rdata[i] != NULL) - TestErrPrintf("VL doesn't match!, rdata[%d]=%p\n", (int)i, rdata[i]); + TestErrPrintf("VL doesn't match!, rdata[%d]=%s\n", (int)i, rdata[i]); /* Try to write nil strings to disk. */ ret = H5Dwrite(dataset, tid1, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata2); @@ -365,7 +365,7 @@ test_vlstrings_special(void) /* Check data read in */ for (i = 0; i < SPACE1_DIM1; i++) if (rdata[i] != NULL) - TestErrPrintf("VL doesn't match!, rdata[%d]=%p\n", (int)i, rdata[i]); + TestErrPrintf("VL doesn't match!, rdata[%d]=%s\n", (int)i, rdata[i]); /* Close Dataset */ ret = H5Dclose(dataset); diff --git a/tools/lib/h5diff_array.c b/tools/lib/h5diff_array.c index 2d6c66c..1b0d36f 100644 --- a/tools/lib/h5diff_array.c +++ b/tools/lib/h5diff_array.c @@ -24,12 +24,8 @@ *------------------------------------------------------------------------- */ -#define F_FORMAT "%-15g %-15g %-15g\n" - -#if H5_SIZEOF_LONG_DOUBLE != 0 -#define LD_FORMAT "%-15Lg %-15Lg %-15Lg\n" -#endif - +#define F_FORMAT "%-15g %-15g %-15g\n" +#define LD_FORMAT "%-15Lg %-15Lg %-15Lg\n" #define I_FORMAT "%-15d %-15d %-15d\n" #define S_FORMAT "%-16s %-17s\n" #define UI_FORMAT "%-15u %-15u %-15u\n" @@ -39,12 +35,8 @@ #define ULLI_FORMAT "%-15" H5_PRINTF_LL_WIDTH "u %-15" H5_PRINTF_LL_WIDTH "u %-15" H5_PRINTF_LL_WIDTH "u\n" /* with -p option */ -#define F_FORMAT_P "%-15.10g %-15.10g %-15.10g %-14.10g\n" - -#if H5_SIZEOF_LONG_DOUBLE != 0 -#define LD_FORMAT_P "%-15.10Lg %-15.10Lg %-15.10Lg %-14.10Lg\n" -#endif - +#define F_FORMAT_P "%-15.10g %-15.10g %-15.10g %-14.10g\n" +#define LD_FORMAT_P "%-15.10Lg %-15.10Lg %-15.10Lg %-14.10Lg\n" #define I_FORMAT_P "%-15d %-15d %-15d %-14f\n" #define UI_FORMAT_P "%-15u %-15u %-15u %-14f\n" #define LI_FORMAT_P "%-15ld %-15ld %-15ld %-14f\n" @@ -56,12 +48,8 @@ #define SPACES " " /* not comparable */ -#define F_FORMAT_P_NOTCOMP "%-15.10g %-15.10g %-15.10g not comparable\n" - -#if H5_SIZEOF_LONG_DOUBLE != 0 -#define LD_FORMAT_P_NOTCOMP "%-15.10Lg %-15.10Lg %-15.10Lg not comparable\n" -#endif - +#define F_FORMAT_P_NOTCOMP "%-15.10g %-15.10g %-15.10g not comparable\n" +#define LD_FORMAT_P_NOTCOMP "%-15.10Lg %-15.10Lg %-15.10Lg not comparable\n" #define I_FORMAT_P_NOTCOMP "%-15d %-15d %-15d not comparable\n" #define UI_FORMAT_P_NOTCOMP "%-15u %-15u %-15u not comparable\n" #define LI_FORMAT_P_NOTCOMP "%-15ld %-15ld %-15ld not comparable\n" @@ -145,9 +133,7 @@ static hsize_t character_compare_opt(unsigned char *mem1, unsigned char *mem2, h diff_opt_t *opts); static hbool_t equal_float(float value, float expected, diff_opt_t *opts); static hbool_t equal_double(double value, double expected, diff_opt_t *opts); -#if H5_SIZEOF_LONG_DOUBLE != 0 static hbool_t equal_ldouble(long double value, long double expected, diff_opt_t *opts); -#endif static int print_data(diff_opt_t *opts); static void print_pos(diff_opt_t *opts, hsize_t elemtno, size_t u); @@ -162,10 +148,8 @@ static hsize_t diff_float_element(unsigned char *mem1, unsigned char *mem2, hsiz diff_opt_t *opts); static hsize_t diff_double_element(unsigned char *mem1, unsigned char *mem2, hsize_t elem_idx, diff_opt_t *opts); -#if H5_SIZEOF_LONG_DOUBLE != 0 static hsize_t diff_ldouble_element(unsigned char *mem1, unsigned char *mem2, hsize_t elem_idx, diff_opt_t *opts); -#endif static hsize_t diff_schar_element(unsigned char *mem1, unsigned char *mem2, hsize_t elem_idx, diff_opt_t *opts); static hsize_t diff_uchar_element(unsigned char *mem1, unsigned char *mem2, hsize_t elem_idx, @@ -191,12 +175,7 @@ static hsize_t diff_ullong_element(unsigned char *mem1, unsigned char *mem2, hsi *------------------------------------------------------------------------- */ -#if H5_SIZEOF_LONG_DOUBLE != 0 typedef enum dtype_t { FLT_FLOAT, FLT_DOUBLE, FLT_LDOUBLE } dtype_t; -#else - -typedef enum dtype_t { FLT_FLOAT, FLT_DOUBLE } dtype_t; -#endif /*------------------------------------------------------------------------- * XCAO, 11/10/2010 @@ -278,7 +257,6 @@ diff_array(void *_mem1, void *_mem2, diff_opt_t *opts, hid_t container1_id, hid_ return nfound; } /* nelmts */ } -#if H5_SIZEOF_LONG_DOUBLE != 0 else if (H5Tequal(opts->m_tid, H5T_NATIVE_LDOUBLE)) { for (i = 0; i < opts->hs_nelmts; i++) { nfound += diff_ldouble_element(mem1, mem2, i, opts); @@ -289,7 +267,6 @@ diff_array(void *_mem1, void *_mem2, diff_opt_t *opts, hid_t container1_id, hid_ return nfound; } /* nelmts */ } -#endif break; case H5T_INTEGER: @@ -1620,6 +1597,9 @@ character_compare_opt(unsigned char *mem1, unsigned char *mem2, hsize_t elemtno, hbool_t both_zero = FALSE; double per; + /* both_zero is set in the PER_UNSIGN macro but not used in this function */ + (void)both_zero; + HDmemcpy(&temp1_uchar, mem1, sizeof(unsigned char)); HDmemcpy(&temp2_uchar, mem2, sizeof(unsigned char)); H5TOOLS_START_DEBUG(" %d=%d", temp1_uchar, temp2_uchar); @@ -2034,7 +2014,6 @@ diff_double_element(unsigned char *mem1, unsigned char *mem2, hsize_t elem_idx, * Return: number of differences found *------------------------------------------------------------------------- */ -#if H5_SIZEOF_LONG_DOUBLE != 0 static hsize_t diff_ldouble_element(unsigned char *mem1, unsigned char *mem2, hsize_t elem_idx, diff_opt_t *opts) @@ -2070,7 +2049,7 @@ diff_ldouble_element(unsigned char *mem1, unsigned char *mem2, hsize_t elem_idx, /* both not NaN, do the comparison */ if (!isnan1 && !isnan2) { - if (ABS(temp1_double - temp2_double) > opts->delta) { + if ((double)ABS(temp1_double - temp2_double) > opts->delta) { opts->print_percentage = 0; print_pos(opts, elem_idx, 0); if (print_data(opts)) { @@ -2163,7 +2142,7 @@ diff_ldouble_element(unsigned char *mem1, unsigned char *mem2, hsize_t elem_idx, } nfound++; } - else if (per > opts->percent && ABS(temp1_double - temp2_double) > opts->delta) { + else if (per > opts->percent && (double)ABS(temp1_double - temp2_double) > opts->delta) { opts->print_percentage = 1; print_pos(opts, elem_idx, 0); if (print_data(opts)) { @@ -2200,7 +2179,6 @@ diff_ldouble_element(unsigned char *mem1, unsigned char *mem2, hsize_t elem_idx, return nfound; } -#endif /* H5_SIZEOF_LONG_DOUBLE */ /*------------------------------------------------------------------------- * Function: diff_schar_element @@ -3203,7 +3181,6 @@ equal_double(double value, double expected, diff_opt_t *opts) *------------------------------------------------------------------------- */ -#if H5_SIZEOF_LONG_DOUBLE != 0 static hbool_t equal_ldouble(long double value, long double expected, diff_opt_t *opts) { @@ -3244,8 +3221,6 @@ equal_ldouble(long double value, long double expected, diff_opt_t *opts) return FALSE; } -#endif /* #if H5_SIZEOF_LONG_DOUBLE !=0 */ - /*------------------------------------------------------------------------- * Function: equal_float * diff --git a/tools/lib/h5diff_util.c b/tools/lib/h5diff_util.c index e487a12..c40de9d 100644 --- a/tools/lib/h5diff_util.c +++ b/tools/lib/h5diff_util.c @@ -133,10 +133,8 @@ print_type(hid_t type) parallel_print("H5T_NATIVE_FLOAT"); else if (H5Tequal(type, H5T_NATIVE_DOUBLE)) parallel_print("H5T_NATIVE_DOUBLE"); -#if H5_SIZEOF_LONG_DOUBLE != 0 else if (H5Tequal(type, H5T_NATIVE_LDOUBLE)) parallel_print("H5T_NATIVE_LDOUBLE"); -#endif else parallel_print("undefined float"); break; diff --git a/tools/lib/h5tools.c b/tools/lib/h5tools.c index 5e60941..78e5c48 100644 --- a/tools/lib/h5tools.c +++ b/tools/lib/h5tools.c @@ -1903,15 +1903,21 @@ render_bin_output(FILE *stream, hid_t container, hid_t tid, void *_mem, hsize_t hid_t region_id = H5I_INVALID_HID; hid_t region_space = H5I_INVALID_HID; H5S_sel_type region_type; + H5R_ref_t tref; + + if (size > sizeof(tref)) + H5TOOLS_THROW((-1), "unexpectedly large ref"); + + HDmemset(&tref, 0, sizeof(tref)); for (block_index = 0; block_index < block_nelmts; block_index++) { mem = ((unsigned char *)_mem) + block_index * size; - if ((region_id = H5Ropen_object((H5R_ref_t *)mem, H5P_DEFAULT, H5P_DEFAULT)) < 0) + HDmemcpy(&tref, mem, size); + if ((region_id = H5Ropen_object(&tref, H5P_DEFAULT, H5P_DEFAULT)) < 0) H5TOOLS_INFO("H5Ropen_object H5T_STD_REF failed"); else { - if ((region_space = H5Ropen_region((H5R_ref_t *)mem, H5P_DEFAULT, H5P_DEFAULT)) >= - 0) { - if (!h5tools_is_zero(mem, H5Tget_size(H5T_STD_REF))) { + if ((region_space = H5Ropen_region(&tref, H5P_DEFAULT, H5P_DEFAULT)) >= 0) { + if (!h5tools_is_zero(&tref, H5Tget_size(H5T_STD_REF))) { region_type = H5Sget_select_type(region_space); if (region_type == H5S_SEL_POINTS) render_bin_output_region_points(region_space, region_id, stream, diff --git a/tools/lib/h5tools_str.c b/tools/lib/h5tools_str.c index abc0058..3cd12bb 100644 --- a/tools/lib/h5tools_str.c +++ b/tools/lib/h5tools_str.c @@ -705,7 +705,6 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai HDmemcpy(&tempdouble, vp, sizeof(double)); h5tools_str_append(str, OPT(info->fmt_double, "%g"), tempdouble); -#if H5_SIZEOF_LONG_DOUBLE != 0 } else if (sizeof(long double) == nsize) { /* if (H5Tequal(type, H5T_NATIVE_LDOUBLE)) */ @@ -713,7 +712,6 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai HDmemcpy(&templdouble, vp, sizeof(long double)); h5tools_str_append(str, "%Lg", templdouble); -#endif } else { size_t i; diff --git a/tools/lib/h5tools_utils.c b/tools/lib/h5tools_utils.c index f2407bf..ea9812b 100644 --- a/tools/lib/h5tools_utils.c +++ b/tools/lib/h5tools_utils.c @@ -450,6 +450,7 @@ free_table(table_t *table) HDfree(table->objs[u].objname); HDfree(table->objs); + HDfree(table); } #ifdef H5DUMP_DEBUG diff --git a/tools/src/h5dump/h5dump.c b/tools/src/h5dump/h5dump.c index 36114ba..2901241 100644 --- a/tools/src/h5dump/h5dump.c +++ b/tools/src/h5dump/h5dump.c @@ -453,11 +453,8 @@ table_list_free(void) /* Free each table */ free_table(table_list.tables[u].group_table); - HDfree(table_list.tables[u].group_table); free_table(table_list.tables[u].dset_table); - HDfree(table_list.tables[u].dset_table); free_table(table_list.tables[u].type_table); - HDfree(table_list.tables[u].type_table); } /* Free the table list */ diff --git a/tools/src/h5import/h5import.c b/tools/src/h5import/h5import.c index 6517e43..7272dff 100644 --- a/tools/src/h5import/h5import.c +++ b/tools/src/h5import/h5import.c @@ -467,14 +467,12 @@ readIntegerData(FILE *strm, struct Input *in) H5DT_INT16 temp16; H5DT_INT32 *in32; H5DT_INT32 temp32; -#ifdef H5_SIZEOF_LONG_LONG H5DT_INT64 *in64; H5DT_INT64 temp64; char buffer[256]; -#endif - hsize_t len = 1; - hsize_t i; - int j; + hsize_t len = 1; + hsize_t i; + int j; const char *err1 = "Unable to get integer value from file.\n"; const char *err2 = "Unrecognized input class type.\n"; @@ -589,7 +587,6 @@ readIntegerData(FILE *strm, struct Input *in) } break; -#ifdef H5_SIZEOF_LONG_LONG case 64: in64 = (H5DT_INT64 *)in->data; switch (in->inputClass) { @@ -626,7 +623,6 @@ readIntegerData(FILE *strm, struct Input *in) return (-1); } break; -#endif /* ifdef H5_SIZEOF_LONG_LONG */ default: (void)HDfprintf(stderr, "%s", err3); @@ -643,17 +639,15 @@ readUIntegerData(FILE *strm, struct Input *in) H5DT_UINT16 temp16; H5DT_UINT32 *in32; H5DT_UINT32 temp32; -#ifdef H5_SIZEOF_LONG_LONG H5DT_UINT64 *in64; H5DT_UINT64 temp64; char buffer[256]; -#endif - hsize_t len = 1; - hsize_t i; - int j; - const char *err1 = "Unable to get unsigned integer value from file.\n"; - const char *err2 = "Unrecognized input class type.\n"; - const char *err3 = "Invalid input size.\n"; + hsize_t len = 1; + hsize_t i; + int j; + const char * err1 = "Unable to get unsigned integer value from file.\n"; + const char * err2 = "Unrecognized input class type.\n"; + const char * err3 = "Invalid input size.\n"; for (j = 0; j < in->rank; j++) len *= in->sizeOfDimension[j]; @@ -760,7 +754,6 @@ readUIntegerData(FILE *strm, struct Input *in) } break; -#ifdef H5_SIZEOF_LONG_LONG case 64: in64 = (H5DT_UINT64 *)in->data; switch (in->inputClass) { @@ -797,7 +790,6 @@ readUIntegerData(FILE *strm, struct Input *in) return (-1); } break; -#endif /* ifdef H5_SIZEOF_LONG_LONG */ default: (void)HDfprintf(stderr, "%s", err3); @@ -2457,9 +2449,6 @@ validateConfigurationParameters(struct Input *in) const char *err4a = "OUTPUT-ARCHITECTURE cannot be STD if OUTPUT-CLASS is floating point (FP).\n"; const char *err4b = "OUTPUT-ARCHITECTURE cannot be IEEE if OUTPUT-CLASS is integer (IN).\n"; const char *err5 = "For OUTPUT-CLASS FP, valid values for OUTPUT-SIZE are (32, 64) .\n"; -#ifndef H5_SIZEOF_LONG_LONG - const char *err6 = "No support for reading 64-bit integer (INPUT-CLASS: IN, TEXTIN, UIN, TEXTUIN files\n"; -#endif /* for class STR other parameters are ignored */ if (in->inputClass == 5) /* STR */ @@ -2505,13 +2494,6 @@ validateConfigurationParameters(struct Input *in) return (-1); } -#ifndef H5_SIZEOF_LONG_LONG - if (in->inputSize == 64 && - (in->inputClass == 0 || in->inputClass == 4 || in->inputClass == 6 || in->inputClass == 7)) { - (void)HDfprintf(stderr, "%s", err6); - return -1; - } -#endif return (0); } @@ -3250,7 +3232,6 @@ getInputClassType(struct Input *in, char *buffer) kindex = 3; } -#if H5_SIZEOF_LONG_DOUBLE != 0 else if (!HDstrcmp(buffer, "H5T_NATIVE_LDOUBLE")) { in->inputSize = H5_SIZEOF_LONG_DOUBLE; in->configOptionVector[INPUT_SIZE] = 1; @@ -3263,7 +3244,6 @@ getInputClassType(struct Input *in, char *buffer) kindex = 3; } -#endif else if (!HDstrcmp(buffer, "H5T_TIME: not yet implemented")) { kindex = -1; } diff --git a/tools/test/h5diff/h5diffgentest.c b/tools/test/h5diff/h5diffgentest.c index 118a3a7..7cefeea 100644 --- a/tools/test/h5diff/h5diffgentest.c +++ b/tools/test/h5diff/h5diffgentest.c @@ -442,7 +442,6 @@ test_basic(const char *fname1, const char *fname2, const char *fname3) write_dset(gid1, 2, dims2, "d2", H5T_NATIVE_DOUBLE, data14); } -#if H5_SIZEOF_LONG_DOUBLE != 0 { /*------------------------------------------------------------------------- @@ -454,7 +453,6 @@ test_basic(const char *fname1, const char *fname2, const char *fname3) write_dset(gid1, 2, dims2, "ld", H5T_NATIVE_LDOUBLE, data15); } -#endif /*------------------------------------------------------------------------- * NaNs in H5T_NATIVE_FLOAT diff --git a/tools/test/h5dump/CMakeTests.cmake b/tools/test/h5dump/CMakeTests.cmake index a8984de..c0f279d 100644 --- a/tools/test/h5dump/CMakeTests.cmake +++ b/tools/test/h5dump/CMakeTests.cmake @@ -412,7 +412,7 @@ # -------------------------------------------------------------------- HDFTEST_COPY_FILE("${HDF5_TOOLS_DIR}/testfiles/tbin1.ddl" "${PROJECT_BINARY_DIR}/testfiles/std/tbin1LE.ddl" "h5dump_std_files") - if (WIN32) + if (WIN32 AND CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION VERSION_LESS 10.0.18362.0) configure_file(${HDF5_TOOLS_DIR}/testfiles/tbinregR.exp ${PROJECT_BINARY_DIR}/testfiles/std/tbinregR.exp NEWLINE_STYLE CRLF) #file (READ ${HDF5_TOOLS_DIR}/testfiles/tbinregR.exp TEST_STREAM) #file (WRITE ${PROJECT_BINARY_DIR}/testfiles/std/tbinregR.exp "${TEST_STREAM}") diff --git a/tools/test/h5import/h5importtest.c b/tools/test/h5import/h5importtest.c index e49125b..7dbf762 100644 --- a/tools/test/h5import/h5importtest.c +++ b/tools/test/h5import/h5importtest.c @@ -46,11 +46,9 @@ main(void) int rowo4i = 11, colo4i = 21, plno4i = 51; int rowi4i = 1, coli4i = 2, plni4i = 5; -#ifdef H5_SIZEOF_LONG_LONG long long row4i64[3], col4i64[4], pln4i64[5]; long long rowo4i64 = (long long)11, colo4i64 = (long long)21, plno4i64 = (long long)51; long long rowi4i64 = (long long)1, coli4i64 = (long long)2, plni4i64 = (long long)5; -#endif short b16i3[5][3][4]; short row4i16[3], col4i16[4], pln4i16[5]; @@ -101,11 +99,9 @@ main(void) col4i[0] = colo4i; pln4i[0] = plno4i; -#ifdef H5_SIZEOF_LONG_LONG row4i64[0] = rowo4i64; col4i64[0] = colo4i64; pln4i64[0] = plno4i64; -#endif row4i16[0] = rowo4i16; col4i16[0] = colo4i16; @@ -116,33 +112,27 @@ main(void) pln4i8[0] = plno4i8; for (i = 1; i < nrow; i++) { - row4[i] = row4[i - 1] + rowi4; - row8[i] = row8[i - 1] + rowi8; - row4i[i] = row4i[i - 1] + rowi4i; -#ifdef H5_SIZEOF_LONG_LONG + row4[i] = row4[i - 1] + rowi4; + row8[i] = row8[i - 1] + rowi8; + row4i[i] = row4i[i - 1] + rowi4i; row4i64[i] = row4i64[i - 1] + rowi4i64; -#endif row4i16[i] = (short)(row4i16[i - 1] + rowi4i16); row4i8[i] = (char)(row4i8[i - 1] + rowi4i8); } for (j = 1; j < ncol; j++) { - col4[j] = col4[j - 1] + coli4; - col8[j] = col8[j - 1] + coli8; - col4i[j] = col4i[j - 1] + coli4i; -#ifdef H5_SIZEOF_LONG_LONG + col4[j] = col4[j - 1] + coli4; + col8[j] = col8[j - 1] + coli8; + col4i[j] = col4i[j - 1] + coli4i; col4i64[j] = col4i64[j - 1] + coli4i64; -#endif col4i16[j] = (short)(col4i16[j - 1] + coli4i16); col4i8[j] = (char)(col4i8[j - 1] + coli4i8); } for (k = 1; k < npln; k++) { - pln4[k] = pln4[k - 1] + plni4; - pln8[k] = pln8[k - 1] + plni8; - pln4i[k] = pln4i[k - 1] + plni4i; -#ifdef H5_SIZEOF_LONG_LONG + pln4[k] = pln4[k - 1] + plni4; + pln8[k] = pln8[k - 1] + plni8; + pln4i[k] = pln4i[k - 1] + plni4i; pln4i64[k] = pln4i64[k - 1] + plni4i64; -#endif pln4i16[k] = (short)(pln4i16[k - 1] + plni4i16); pln4i8[k] = (char)(pln4i8[k - 1] + plni4i8); } diff --git a/tools/test/h5repack/CMakeTests.cmake b/tools/test/h5repack/CMakeTests.cmake index 037287d..397c3ac 100644 --- a/tools/test/h5repack/CMakeTests.cmake +++ b/tools/test/h5repack/CMakeTests.cmake @@ -1544,7 +1544,7 @@ # the references in attribute of compund or vlen datatype ADD_H5_TEST (HDFFV-5932 "TEST" ${FILE_ATTR_REF}) -# Add test for memory leak in attirbute. This test is verified by CTEST. +# Add test for memory leak in attribute. This test is verified by CTEST. # 1. leak from vlen string # 2. leak from compound type without reference member # (HDFFV-7840, ) @@ -1552,12 +1552,12 @@ ADD_H5_TEST (HDFFV-7840 "TEST" h5diff_attr1.h5) # test CVE-2018-17432 fix - set (arg h5repack_CVE-2018-17432.h5 h5repack__CVE-2018-17432_out.h5 --low=1 --high=2 -f GZIP=8 -l dset1:CHUNK=5x6) + set (arg h5repack_CVE-2018-17432.h5 --low=1 --high=2 -f GZIP=8 -l dset1:CHUNK=5x6) set (TESTTYPE "TEST") ADD_H5_FILTER_TEST (HDFFV-10590 "" ${TESTTYPE} 1 ${arg}) # test CVE-2018-14460 fix - set (arg h5repack_CVE-2018-14460.h5 h5repack_CVE-2018-14460_out.h5) + set (arg h5repack_CVE-2018-14460.h5) set (TESTTYPE "TEST") ADD_H5_FILTER_TEST (HDFFV-11223 "" ${TESTTYPE} 1 ${arg}) diff --git a/tools/test/h5repack/h5repack.sh.in b/tools/test/h5repack/h5repack.sh.in index 3756a95..1e54670 100644 --- a/tools/test/h5repack/h5repack.sh.in +++ b/tools/test/h5repack/h5repack.sh.in @@ -885,13 +885,24 @@ TOOLTEST_FAIL() ( cd $TESTDIR $ENVCMD $RUNSERIAL $H5REPACK_BIN "$@" $infile $outfile - ) >$actual + ) >&$actual RET=$? - if [ $RET == 0 ] ; then + + # Normally h5repack of files tested with this function are expected + # to return not 0, but if the command results in "Segmentation fault" + # or "core dumped" it is a failure regardless of the return value. + failure=`grep -e 'Segmentation fault' -e 'core dumped' $actual` + if [ "$failure" != "" ]; then nerrors="`expr $nerrors + 1`" echo " FAILED" + echo " $failure" else - echo " PASSED" + if [ $RET == 0 ] ; then + nerrors="`expr $nerrors + 1`" + echo " FAILED" + else + echo " PASSED" + fi fi rm -f $outfile } diff --git a/tools/test/h5repack/testfiles/h5repack_layout.h5-plugin_version_test.ddl b/tools/test/h5repack/testfiles/h5repack_layout.h5-plugin_version_test.ddl index eeb0f2d..15ae813 100644 --- a/tools/test/h5repack/testfiles/h5repack_layout.h5-plugin_version_test.ddl +++ b/tools/test/h5repack/testfiles/h5repack_layout.h5-plugin_version_test.ddl @@ -11,7 +11,7 @@ GROUP "/" { USER_DEFINED_FILTER { FILTER_ID 260 COMMENT dynlib4 - PARAMS { 9 1 13 0 } + PARAMS { 9 1 13 1 } } } FILLVALUE { @@ -33,7 +33,7 @@ GROUP "/" { USER_DEFINED_FILTER { FILTER_ID 260 COMMENT dynlib4 - PARAMS { 9 1 13 0 } + PARAMS { 9 1 13 1 } } } FILLVALUE { @@ -55,7 +55,7 @@ GROUP "/" { USER_DEFINED_FILTER { FILTER_ID 260 COMMENT dynlib4 - PARAMS { 9 1 13 0 } + PARAMS { 9 1 13 1 } } } FILLVALUE { @@ -77,7 +77,7 @@ GROUP "/" { USER_DEFINED_FILTER { FILTER_ID 260 COMMENT dynlib4 - PARAMS { 9 1 13 0 } + PARAMS { 9 1 13 1 } } } FILLVALUE { @@ -99,7 +99,7 @@ GROUP "/" { USER_DEFINED_FILTER { FILTER_ID 260 COMMENT dynlib4 - PARAMS { 9 1 13 0 } + PARAMS { 9 1 13 1 } } } FILLVALUE { @@ -121,7 +121,7 @@ GROUP "/" { USER_DEFINED_FILTER { FILTER_ID 260 COMMENT dynlib4 - PARAMS { 9 1 13 0 } + PARAMS { 9 1 13 1 } } } FILLVALUE { @@ -143,7 +143,7 @@ GROUP "/" { USER_DEFINED_FILTER { FILTER_ID 260 COMMENT dynlib4 - PARAMS { 9 1 13 0 } + PARAMS { 9 1 13 1 } } } FILLVALUE { -- cgit v0.12 From 57b9935b75bda1d7485e4599d45c8e559da497c6 Mon Sep 17 00:00:00 2001 From: myang6 Date: Wed, 8 Dec 2021 14:16:08 -0600 Subject: update the init_vfd_swmr_config to catch up the latest NFS pull request --- test/vfd_swmr_indep_rw_writer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/vfd_swmr_indep_rw_writer.c b/test/vfd_swmr_indep_rw_writer.c index 678ccb2..c4c8dd7 100644 --- a/test/vfd_swmr_indep_rw_writer.c +++ b/test/vfd_swmr_indep_rw_writer.c @@ -363,8 +363,9 @@ indep_init_vfd_swmr_config_plist(state_t *s, bool writer, const char *mdf_path) H5F_vfd_swmr_config_t config; - /* 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, TRUE, 128, mdf_path); + /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, + * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ + init_vfd_swmr_config(&config, s->tick_len, s->max_lag, writer, TRUE, FALSE, TRUE, 128, mdf_path,NULL); /* Pass the use_vfd_swmr, only_meta_page, page buffer size, config to vfd_swmr_create_fapl().*/ if ((s->fapl = vfd_swmr_create_fapl(true, s->use_vfd_swmr, true, s->pbs, &config)) < 0) { -- cgit v0.12 From 810fb5b601a62196c49f5f3f08ef724574d0dbac Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 8 Dec 2021 20:18:30 +0000 Subject: Committing clang-format changes --- test/vfd_swmr_indep_rw_writer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/vfd_swmr_indep_rw_writer.c b/test/vfd_swmr_indep_rw_writer.c index c4c8dd7..f452e89 100644 --- a/test/vfd_swmr_indep_rw_writer.c +++ b/test/vfd_swmr_indep_rw_writer.c @@ -365,7 +365,7 @@ indep_init_vfd_swmr_config_plist(state_t *s, bool writer, const char *mdf_path) /* config, tick_len, max_lag, writer, maintain_metadata_file, generate_updater_files, * flush_raw_data, md_pages_reserved, md_file_path, updater_file_path */ - init_vfd_swmr_config(&config, s->tick_len, s->max_lag, writer, TRUE, FALSE, TRUE, 128, mdf_path,NULL); + init_vfd_swmr_config(&config, s->tick_len, s->max_lag, writer, TRUE, FALSE, TRUE, 128, mdf_path, NULL); /* Pass the use_vfd_swmr, only_meta_page, page buffer size, config to vfd_swmr_create_fapl().*/ if ((s->fapl = vfd_swmr_create_fapl(true, s->use_vfd_swmr, true, s->pbs, &config)) < 0) { -- cgit v0.12 From 51a3a47bc3807ebf51817ac7f4d16910bb69134d Mon Sep 17 00:00:00 2001 From: vchoi Date: Tue, 14 Dec 2021 13:04:27 -0600 Subject: Fix the failure triggered by running the bigset test with 2D dataset that expands for more than 200 times. It is due to the indexing error for the metadata file index and the change list array. --- src/H5Fvfd_swmr.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index 2ac5e6c..43567ac 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -2251,7 +2251,7 @@ H5F__generate_updater_file(H5F_t *f, uint32_t num_entries, uint16_t flags, uint8 H5FD_t * ud_file = NULL; /* Low-level file struct */ char namebuf[H5F__MAX_VFD_SWMR_FILE_NAME_LEN]; char newname[H5F__MAX_VFD_SWMR_FILE_NAME_LEN]; - unsigned i; + unsigned i, j; hsize_t alloc_size; herr_t ret_value = SUCCEED; /* Return value */ @@ -2337,21 +2337,23 @@ H5F__generate_updater_file(H5F_t *f, uint32_t num_entries, uint16_t flags, uint8 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for ud cl") /* Initialize change list entries */ - for (i = 0; i < num_entries; i++) { + i = 0; + for (j = 0; j < num_entries; j++) { - if (shared->mdf_idx[i].entry_ptr != NULL && - shared->mdf_idx[i].tick_of_last_change == shared->tick_num) { + if (shared->mdf_idx[j].entry_ptr != NULL && + shared->mdf_idx[j].tick_of_last_change == shared->tick_num) { - updater.change_list[i].entry_image_ptr = shared->mdf_idx[i].entry_ptr; + updater.change_list[i].entry_image_ptr = shared->mdf_idx[j].entry_ptr; updater.change_list[i].entry_image_ud_file_page_offset = 0; updater.change_list[i].entry_image_md_file_page_offset = - (uint32_t)shared->mdf_idx[i].md_file_page_offset; + (uint32_t)shared->mdf_idx[j].md_file_page_offset; updater.change_list[i].entry_image_h5_file_page_offset = - (uint32_t)shared->mdf_idx[i].hdf5_page_offset; - updater.change_list[i].entry_image_len = shared->mdf_idx[i].length; - updater.change_list[i].entry_image_checksum = shared->mdf_idx[i].checksum; + (uint32_t)shared->mdf_idx[j].hdf5_page_offset; + updater.change_list[i].entry_image_len = shared->mdf_idx[j].length; + updater.change_list[i].entry_image_checksum = shared->mdf_idx[j].checksum; - shared->mdf_idx[i].entry_ptr = NULL; + shared->mdf_idx[j].entry_ptr = NULL; + i++; } } -- cgit v0.12